00001 <?php
00002
00003
00004
00005
00006
00007
00008 class Pager implements IDBQueryModifier {
00009
00010
00011
00012 const DONT_INDEX_PAGE_2PP = 1;
00013
00014
00015
00016 const DO_INDEX_PAGE_2PP = 0;
00017
00018 protected $pager_data = array();
00019
00020
00021
00022
00023
00024 protected $adapter = null;
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 public function __construct($page_data, $items_total, $items_per_page = false, $adapter = false) {
00037 $this->adapter = ($adapter instanceof IPagerAdapter) ? $adapter : new PagerDefaultAdapter($page_data, 'page');
00038 if ($items_per_page === false) {
00039 $items_per_page = Config::get_value(Config::ITEMS_PER_PAGE);
00040 }
00041 if ($items_total instanceof ISearchAdapter) {
00042 $items_total = $items_total->count();
00043 }
00044
00045 $this->pager_data['page_data'] = $page_data;
00046 $this->pager_data['policy'] = (is_int($adapter)) ? $adapter : 0;
00047 $this->pager_data['items_per_page'] = $items_per_page;
00048 $this->pager_data['items_total'] = $items_total;
00049
00050 $this->pager_data['previous_link'] = '';
00051 $this->pager_data['next_link'] = '';
00052 $this->pager_data['adapter'] = $this->adapter;
00053
00054
00055 $page_raw = $this->adapter->get_current_page();
00056 $page = Cast::int($page_raw);
00057 if ($page <= 0) {
00058
00059 $page_test = intval($page_raw);
00060
00061 if ($page_test != $page && $page_test > 0) {
00062
00063 $url = $this->adapter->get_url_for_page($page_test);
00064 $url->redirect(Url::PERMANENT);
00065 } else {
00066
00067 $url = $this->adapter->get_url_for_page(1);
00068 $url->redirect(Url::PERMANENT);
00069 }
00070 exit;
00071 } elseif ($page_raw == 1) {
00072 $url = $this->adapter->get_url_for_page(1);
00073 if ($url->build() != Url::current()->build()) {
00074 $url->redirect(Url::PERMANENT);
00075 exit;
00076 }
00077 }
00078
00079 $page_total = 0;
00080 if ($items_per_page > 0) {
00081 $page_total = ceil($items_total / (float)$items_per_page);
00082 }
00083 if ($page_total <= 0) {
00084 $page_total = 1;
00085 }
00086
00087 if ($page > $page_total) {
00088
00089
00090 $url = $this->adapter->get_url_for_page($page_total);
00091 $url->redirect(Url::TEMPORARY);
00092 exit;
00093 }
00094
00095 $this->pager_data['page'] = $page;
00096 $this->pager_data['pages_total'] = $page_total;
00097
00098 $this->pager_data['start_record'] = ($page - 1) * $items_per_page;
00099 }
00100
00101
00102
00103
00104 public function get_start() {
00105 return $this->pager_data['start_record'];
00106 }
00107
00108
00109
00110
00111 public function get_items_per_page() {
00112 return $this->pager_data['items_per_page'];
00113 }
00114
00115
00116
00117
00118 public function prepare_view($view) {
00119 $page = $this->pager_data['page'];
00120 $page_total = $this->pager_data['pages_total'];
00121 if ($page_total > 1) {
00122 if ($page > 1) {
00123 $this->pager_data['first_link'] = $this->get_url_for_page(1);
00124 $this->pager_data['previous_link'] = $this->get_url_for_page($page - 1);
00125 }
00126 if ($page < $page_total) {
00127 $this->pager_data['next_link'] = $this->get_url_for_page($page + 1);
00128 $this->pager_data['last_link'] = $this->get_url_for_page($page_total);
00129 }
00130
00131
00132
00133
00134
00135
00136
00137 }
00138 $view->assign('pager_data', $this->pager_data);
00139 }
00140
00141
00142
00143
00144 protected function get_url_for_page($page) {
00145 $url = $this->adapter->get_url_for_page($page);
00146 return $url->build(Url::RELATIVE);
00147 }
00148
00149
00150
00151
00152 public function apply($query) {
00153 $query->limit($this->get_start(), $this->get_items_per_page());
00154 }
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166 public static function apply_to_url($url, $page) {
00167 PagerDefaultAdapter::apply_to_url($url, $page);
00168 }
00169 }
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179 class PagerDefaultAdapter implements IPagerAdapter {
00180 protected $parameter;
00181 protected $get;
00182
00183 public function __construct(PageData $page_data, $parameter = 'page') {
00184 $this->parameter = $parameter;
00185 $this->get = $page_data->get_get();
00186 }
00187
00188
00189
00190
00191
00192
00193
00194 public function get_current_page() {
00195 return $this->get->get_item($this->parameter, 1);
00196 }
00197
00198
00199
00200
00201
00202
00203 public function get_url_for_page($page) {
00204 $url = Url::current();
00205 self::apply_to_url($url, $page, $this->parameter);
00206 return $url;
00207 }
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217 public static function apply_to_url($url, $page, $parameter = 'page') {
00218 $p = Cast::int($page);
00219 if ($p <= 1) {
00220 $p = '';
00221 }
00222 $url->replace_query_parameter($parameter, $p);
00223 }
00224 }