@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.)
hq.recaptime.dev/wiki/Phorge
phorge
phabricator
1<?php
2
3final class AphrontCursorPagerView extends AphrontView {
4
5 private $afterID;
6 private $beforeID;
7
8 private $pageSize = 100;
9
10 private $nextPageID;
11 private $prevPageID;
12 private $moreResults;
13
14 private $uri;
15
16 public function setPageSize($page_size) {
17 $this->pageSize = max(1, $page_size);
18 return $this;
19 }
20
21 public function getPageSize() {
22 return $this->pageSize;
23 }
24
25 public function setURI(PhutilURI $uri) {
26 $this->uri = $uri;
27 return $this;
28 }
29
30 public function readFromRequest(AphrontRequest $request) {
31 $this->uri = $request->getRequestURI();
32 $this->afterID = $request->getStr('after');
33 $this->beforeID = $request->getStr('before');
34 return $this;
35 }
36
37 public function setAfterID($after_id) {
38 $this->afterID = $after_id;
39 return $this;
40 }
41
42 public function getAfterID() {
43 return $this->afterID;
44 }
45
46 public function setBeforeID($before_id) {
47 $this->beforeID = $before_id;
48 return $this;
49 }
50
51 public function getBeforeID() {
52 return $this->beforeID;
53 }
54
55 public function setNextPageID($next_page_id) {
56 $this->nextPageID = $next_page_id;
57 return $this;
58 }
59
60 public function getNextPageID() {
61 return $this->nextPageID;
62 }
63
64 public function setPrevPageID($prev_page_id) {
65 $this->prevPageID = $prev_page_id;
66 return $this;
67 }
68
69 public function getPrevPageID() {
70 return $this->prevPageID;
71 }
72
73 /**
74 * @param T[] $results
75 * @return T[]
76 * @template T
77 */
78 public function sliceResults(array $results) {
79 if (count($results) > $this->getPageSize()) {
80 $page_size = (int)$this->getPageSize();
81 $offset = ($this->beforeID ? count($results) - $page_size : 0);
82 $results = array_slice($results, $offset, $page_size, true);
83 $this->moreResults = true;
84 }
85 return $results;
86 }
87
88 public function getHasMoreResults() {
89 return $this->moreResults;
90 }
91
92 public function willShowPagingControls() {
93 return $this->prevPageID ||
94 $this->nextPageID ||
95 $this->afterID ||
96 ($this->beforeID && $this->moreResults);
97 }
98
99 public function getFirstPageURI() {
100 if (!$this->uri) {
101 throw new PhutilInvalidStateException('setURI');
102 }
103
104 if (!$this->afterID && !($this->beforeID && $this->moreResults)) {
105 return null;
106 }
107
108 return id(clone $this->uri)
109 ->removeQueryParam('after')
110 ->removeQueryParam('before');
111 }
112
113 public function getPrevPageURI() {
114 if (!$this->uri) {
115 throw new PhutilInvalidStateException('getPrevPageURI');
116 }
117
118 if (!$this->prevPageID) {
119 return null;
120 }
121
122 return id(clone $this->uri)
123 ->removeQueryParam('after')
124 ->replaceQueryParam('before', $this->prevPageID);
125 }
126
127 public function getNextPageURI() {
128 if (!$this->uri) {
129 throw new PhutilInvalidStateException('setURI');
130 }
131
132 if (!$this->nextPageID) {
133 return null;
134 }
135
136 return id(clone $this->uri)
137 ->replaceQueryParam('after', $this->nextPageID)
138 ->removeQueryParam('before');
139 }
140
141 public function render() {
142 if (!$this->uri) {
143 throw new PhutilInvalidStateException('setURI');
144 }
145
146 $links = array();
147
148 $first_uri = $this->getFirstPageURI();
149 if ($first_uri) {
150 $icon = id(new PHUIIconView())
151 ->setIcon('fa-fast-backward');
152 $links[] = id(new PHUIButtonView())
153 ->setTag('a')
154 ->setHref($first_uri)
155 ->setIcon($icon)
156 ->addClass('mml')
157 ->setColor(PHUIButtonView::GREY)
158 ->setText(pht('First'));
159 }
160
161 $prev_uri = $this->getPrevPageURI();
162 if ($prev_uri) {
163 $icon = id(new PHUIIconView())
164 ->setIcon('fa-backward');
165 $links[] = id(new PHUIButtonView())
166 ->setTag('a')
167 ->setHref($prev_uri)
168 ->setIcon($icon)
169 ->addClass('mml')
170 ->setColor(PHUIButtonView::GREY)
171 ->setText(pht('Prev'));
172 }
173
174 $next_uri = $this->getNextPageURI();
175 if ($next_uri) {
176 $icon = id(new PHUIIconView())
177 ->setIcon('fa-forward');
178 $links[] = id(new PHUIButtonView())
179 ->setTag('a')
180 ->setHref($next_uri)
181 ->setIcon($icon, false)
182 ->addClass('mml')
183 ->setColor(PHUIButtonView::GREY)
184 ->setText(pht('Next'));
185 }
186
187 return phutil_tag(
188 'div',
189 array(
190 'class' => 'phui-pager-view',
191 ),
192 $links);
193 }
194
195}