Completed
Push — master ( c69b4e...cc8f9e )
by Peter
08:59
created

View::getCurrent()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 11
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 11
ccs 8
cts 8
cp 1
rs 9.4285
cc 2
eloc 7
nc 2
nop 0
crap 2
1
<?php
2
/**
3
 * AnimeDb package
4
 *
5
 * @package   AnimeDb
6
 * @author    Peter Gribanov <[email protected]>
7
 * @copyright Copyright (c) 2011, Peter Gribanov
8
 * @license   http://opensource.org/licenses/GPL-3.0 GPL v3
9
 */
10
namespace AnimeDb\Bundle\PaginationBundle\Service;
11
12
use AnimeDb\Bundle\PaginationBundle\Entity\Node;
13
use Doctrine\Common\Collections\ArrayCollection;
14
15
/**
16
 * @package AnimeDb\Bundle\PaginationBundle\Service
17
 * @author Peter Gribanov <[email protected]>
18
 */
19
class View implements \IteratorAggregate
20
{
21
    /**
22
     * @var Configuration
23
     */
24
    protected $config;
25
26
    /**
27
     * @var Node|null
28
     */
29
    protected $first = null;
30
31
    /**
32
     * @var Node|null
33
     */
34
    protected $prev = null;
35
36
    /**
37
     * @var Node
38
     */
39
    protected $current;
40
41
    /**
42
     * @var Node|null
43
     */
44
    protected $next = null;
45
46
    /**
47
     * @var Node|null
48
     */
49
    protected $last = null;
50
51
    /**
52
     * @var ArrayCollection|null
53
     */
54
    protected $list = null;
55
56
    /**
57
     * @param Configuration $config
58
     */
59 27
    public function __construct(Configuration $config) {
60 27
        $this->config = $config;
61 27
    }
62
63
    /**
64
     * @return int
65
     */
66 14
    public function getTotal()
67
    {
68 14
        return $this->config->getTotalPages();
69
    }
70
71
    /**
72
     * @return Node|null
73
     */
74 5
    public function getFirst()
75
    {
76 5
        if (!$this->first && $this->config->getCurrentPage() > 1) {
77 4
            $this->first = new Node(1, $this->buildLink(1));
78 4
        }
79 5
        return $this->first;
80
    }
81
82
    /**
83
     * @return Node|null
84
     */
85 3
    public function getPrev()
86
    {
87 3
        if (!$this->prev && $this->config->getCurrentPage() > 1) {
88 2
            $this->prev = new Node(
89 2
                $this->config->getCurrentPage() - 1,
90 2
                $this->buildLink($this->config->getCurrentPage() - 1)
91 2
            );
92 2
        }
93 3
        return $this->prev;
94
    }
95
96
    /**
97
     * @return Node
98
     */
99 10
    public function getCurrent()
100
    {
101 10
        if (!$this->current) {
102 10
            $this->current = new Node(
103 10
                $this->config->getCurrentPage(),
104 10
                $this->buildLink($this->config->getCurrentPage()),
105
                true
106 10
            );
107 10
        }
108 10
        return $this->current;
109
    }
110
111
    /**
112
     * @return Node|null
113
     */
114 3
    public function getNext()
115
    {
116 3
        if (!$this->next && $this->config->getCurrentPage() < $this->getTotal()) {
117 2
            $this->next = new Node(
118 2
                $this->config->getCurrentPage() + 1,
119 2
                $this->buildLink($this->config->getCurrentPage() + 1)
120 2
            );
121 2
        }
122 3
        return $this->next;
123
    }
124
125
    /**
126
     * @return Node|null
127
     */
128 3
    public function getLast()
129
    {
130 3
        if (!$this->last && $this->config->getCurrentPage() < $this->getTotal()) {
131 2
            $this->last = new Node($this->getTotal(), $this->buildLink($this->getTotal()));
132 2
        }
133 3
        return $this->last;
134
    }
135
136
    /**
137
     * @return ArrayCollection|null
138
     */
139 7
    public function getIterator()
140
    {
141 7
        if (!($this->list instanceof ArrayCollection)) {
142 7
            $this->list = new ArrayCollection();
143
144 7
            if ($this->getTotal() <= 1) {
145 1
                return $this->list;
146
            }
147
148 6
            list($page_from, $page_to) = $this->getNavigateRange();
149
150
            // build list
151 6
            for ($page = $page_from; $page <= $page_to; $page++) {
152 6
                if ($page == $this->config->getCurrentPage()) {
153 6
                    $this->list->add($this->getCurrent());
154 6
                } else {
155 6
                    $this->list->add(new Node($page, $this->buildLink($page)));
156
                }
157 6
            }
158 6
        }
159
160 6
        return $this->list;
161
    }
162
163
    /**
164
     * @param int $page
165
     *
166
     * @return string
167
     */
168 20
    protected function buildLink($page)
169
    {
170 20
        if ($page == 1 && $this->config->getFirstPageLink()) {
171 4
            return $this->config->getFirstPageLink();
172
        }
173
174 16
        if (is_callable($this->config->getPageLink())) {
175 6
            return call_user_func($this->config->getPageLink(), $page);
176
        } else {
177 10
            return sprintf($this->config->getPageLink(), $page);
178
        }
179
    }
180
181
    /**
182
     * @return int[]
183
     */
184 6
    protected function getNavigateRange()
185
    {
186
        // definition of offset to the left and to the right of the selected page
187 6
        $left_offset = floor(($this->config->getMaxNavigate() - 1) / 2);
188 6
        $right_offset = ceil(($this->config->getMaxNavigate() - 1) / 2);
189
        // adjustment, if the offset is too large left
190 6
        if ($this->config->getCurrentPage() - $left_offset < 1) {
191 3
            $offset = abs($this->config->getCurrentPage() - 1 - $left_offset);
192 3
            $left_offset = $left_offset - $offset;
193 3
            $right_offset = $right_offset + $offset;
194 3
        }
195
        // adjustment, if the offset is too large right
196 6
        if ($this->config->getCurrentPage() + $right_offset > $this->getTotal()) {
197 3
            $offset = abs($this->getTotal() - $this->config->getCurrentPage() - $right_offset);
198 3
            $left_offset = $left_offset + $offset;
199 3
            $right_offset = $right_offset - $offset;
200 3
        }
201
        // determining the first and last pages in paging based on the current page and offset
202 6
        $page_from = $this->config->getCurrentPage() - $left_offset;
203 6
        $page_to = $this->config->getCurrentPage() + $right_offset;
204 6
        $page_from = $page_from > 1 ? $page_from : 1;
205
206
        return [
207 6
            $page_from,
208
            $page_to
209 6
        ];
210
    }
211
}
212