Completed
Pull Request — master (#204)
by Vitor
07:26
created

TelegramInlineView::createDefaultTemplate()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 0
crap 1
1
<?php
2
namespace Pagerfanta\View;
3
use Pagerfanta\View\ViewInterface;
4
use Pagerfanta\PagerfantaInterface;
5
use Pagerfanta\View\Template\TemplateInterface;
6
use TelegramPagerfanta\View\Template\TelegramInlineTemplate;
7
8
class TelegramInlineView implements ViewInterface
9
{
10
    /**
11
     * @var TelegramInlineTemplate
12
     */
13
    private $template;
14
15
    /**
16
     * @var PagerfantaInterface
17
     */
18
    private $pagerfanta;
19
20
    private $currentPage;
21
    private $nbPages;
22
23
    private $startPage;
24
    private $endPage;
25
    private $maxPerPage;
26
    
27
    private $buttons;
28
    
29
    private $maxButtons;
30
31 10
    public function __construct(TemplateInterface $template = null)
32
    {
33 10
        $this->template = $template ?: $this->createDefaultTemplate();
0 ignored issues
show
Documentation Bug introduced by
It seems like $template ?: $this->createDefaultTemplate() of type object<Pagerfanta\View\T...late\TemplateInterface> is incompatible with the declared type object<TelegramPagerfant...TelegramInlineTemplate> of property $template.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
34 10
        $this->buttons = new \stdClass();
35 10
    }
36
37 10
    protected function createDefaultTemplate()
38
    {
39 10
        return new \Pagerfanta\View\Template\TelegramInlineTemplate();
40
    }
41
42 10
    public function render(PagerfantaInterface $pagerfanta, $routeGenerator, array $options = array())
43
    {
44 10
        $this->initializePagerfanta($pagerfanta);
45 10
        $this->initializeOptions($options);
46
47 10
        $this->configureTemplate($routeGenerator, $options);
48
49 10
        return $this->generatePages();
50
    }
51
52 10
    private function initializePagerfanta(PagerfantaInterface $pagerfanta)
53
    {
54 10
        $this->pagerfanta = $pagerfanta;
55
56 10
        $this->currentPage = $pagerfanta->getCurrentPage();
57 10
        $this->nbPages = $pagerfanta->getNbPages();
58 10
        $this->maxPerPage = $pagerfanta->getMaxPerPage();
59 10
    }
60
61 10
    private function initializeOptions($options)
62
    {
63 10
        $this->proximity = isset($options['proximity']) ?
0 ignored issues
show
Bug introduced by
The property proximity does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
64 10
                           (int) $options['proximity'] :
65 9
                           $this->getDefaultProximity();
66 10
    }
67
68 9
    protected function getDefaultProximity()
69
    {
70 9
        $proximityEstimated = floor($this->maxPerPage / 2);
71 9
        if($proximityEstimated < 2) {
72
            $proximity = $proximityEstimated;
73
        } else {
74 9
            $proximity = 2;
75
        }
76 9
        return $proximity;
77
    }
78
79 10
    private function configureTemplate($routeGenerator, $options)
80
    {
81 10
        $this->template->setRouteGenerator($routeGenerator);
82 10
        $this->template->setOptions($options);
83 10
    }
84
85 10
    private function generatePages()
86
    {
87 10
        $this->calculateStartAndEndPage();
88
89 10
        $this->page($this->currentPage);
90 10
        $this->first();
91 10
        $this->last();
92 10
        $this->previous();
93 10
        $this->next();
94 10
        $this->pages();
95 10
        ksort($this->buttons->inline_keyboard[0]);
96 10
        $this->buttons->inline_keyboard[0] = array_values($this->buttons->inline_keyboard[0]);
97 10
        return (string)$this;
98
    }
99
100 10
    private function calculateStartAndEndPage()
101
    {
102 10
        $startPage = $this->currentPage - $this->proximity;
103 10
        $endPage = $this->currentPage + $this->proximity;
104
105 10
        if ($this->startPageUnderflow($startPage)) {
106 2
            $startPage = 1;
107 2
            $endPage = $this->maxPerPage;
108 2
            $endPage = $this->calculateEndPageForStartPageUnderflow($startPage, $endPage);
109 2
        }
110 10
        if ($this->endPageOverflow($endPage)) {
111 1
            $startPage = $this->calculateStartPageForEndPageOverflow($startPage, $endPage);
112 1
            $endPage = $this->nbPages;
113 1
        }
114
115 10
        $this->startPage = $startPage;
116 10
        $this->endPage = $endPage;
117 10
    }
118
119 10
    private function startPageUnderflow($startPage)
120
    {
121 10
        return $startPage < 1;
122
    }
123
124 10
    private function endPageOverflow($endPage)
125
    {
126 10
        return $endPage > $this->nbPages;
127
    }
128
129 2
    private function calculateEndPageForStartPageUnderflow($startPage, $endPage)
130
    {
131 2
        return min($endPage + (1 - $startPage), $this->nbPages);
132
    }
133
134 1
    private function calculateStartPageForEndPageOverflow($startPage, $endPage)
135
    {
136 1
        return max($startPage - ($endPage - $this->nbPages), 1);
137
    }
138
139 10
    private function previous()
140
    {
141 10
        if ($this->currentPage > $this->maxPerPage) {
142 3
            $prev = $this->startPage;
143 3
            if($this->startPage+$this->maxPerPage-1 >= $this->nbPages) {
144 3
                $prev--;
145 3
            }
146 3
            $this->pushNewButton(
147 3
                $this->template->previousEnabled($prev)
148 3
            );
149 3
        }
150 10
    }
151
152 10
    private function first()
153
    {
154 10
        if(!$this->pageExists(1)) {
155 8
            if($this->currentPage > $this->maxPerPage) {
156 3
                $this->pushNewButton(
157 3
                    $this->template->first()
158 3
                );
159 3
            } else {
160 5
                $this->page(1);
161
            }
162 8
        }
163 10
    }
164
165 10
    private function pages()
166
    {
167 10
        foreach (range($this->startPage, $this->endPage) as $page) {
168 10
            if(!$this->pageExists($page)) {
169 10
                if(count($this->buttons->inline_keyboard[0]) < $this->maxButtons) {
170
                    $this->page($page);
171
                }
172 10
            }
173 10
        }
174 10
    }
175
176 10
    private function page($page)
177
    {
178 10
        if ($page == $this->currentPage) {
179 10
            $this->pushNewButton(
180 10
                $this->template->current($page)
181 10
            );
182 10
        } else {
183 5
            $this->pushNewButton(
184 5
                $this->template->page($page)
185 5
            );
186
        }
187 10
    }
188
    
189 10
    private function pushNewButton(array $params) {
190 10
        $params = (object)$params;
191 10
        $page = $params->page;
192 10
        unset($params->page);
193 10
        $this->buttons->inline_keyboard[0][$page] = $params;
194 10
    }
195
    
196
    private function pageOfPreviousButton()
0 ignored issues
show
Unused Code introduced by
This method is not used, and could be removed.
Loading history...
197
    {
198
        $keys = array_keys($this->buttons->inline_keyboard[0]);
199
        array_pop($keys);
200
        return array_pop($keys);
201
    }
202
203 10
    private function pageExists($page) {
204 10
        return isset($this->buttons->inline_keyboard[0][$page]);
205
    }
206
207
    private function toLast($n)
0 ignored issues
show
Unused Code introduced by
This method is not used, and could be removed.
Loading history...
208
    {
209
        return $this->pagerfanta->getNbPages() - ($n - 1);
210
    }
211
212 10
    private function last()
213
    {
214 10
        if ($this->nbPages > $this->endPage) {
215 9
            if($this->nbPages - $this->endPage <= 1) {
216 1
                $this->pushNewButton(
217 1
                    $this->template->page($this->nbPages)
218 1
                );
219 1
            } else {
220 8
                if($this->endPage +2 >= $this->nbPages) {
221 1
                    $this->pushNewButton(
222 1
                        $this->template->page($this->nbPages)
223 1
                    );
224 1
                } else {
225 7
                    $this->pushNewButton(
226 7
                        $this->template->last($this->nbPages)
227 7
                    );
228
                }
229
            }
230 9
        }
231 10
    }
232
233 10
    private function next()
234
    {
235 10
        if ($this->pagerfanta->hasNextPage()) {
236 9
            $next = $this->endPage;
237 9
            if($this->pageExists($next) || $next == $this->maxPerPage) {
238 2
                $next++;
239 2
            }
240 9
            if($next < $this->nbPages) {
241 9
                $this->pushNewButton(
242 9
                    $this->template->nextEnabled($next)
243 9
                );
244 9
            } else {
245
                $this->pushNewButton(
246
                    $this->template->page($next)
247
                );
248
            }
249 9
        }
250 10
    }
251
    
252
    public function setMaxButtons($max)
253
    {
254
        $this->maxButtons = $max;
255
    }
256
257
    /**
258
     * {@inheritdoc}
259
     */
260
    public function getName()
261
    {
262
        return 'TelegramInline';
263
    }
264
    
265
266
    /**
267
     * Convert the collection to its string representation.
268
     *
269
     * @return string
270
     */
271 10
    public function __toString()
272
    {
273 10
        return json_encode($this->buttons, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
274
    }
275
}
276