Completed
Push — master ( a4e58c...d4ecfc )
by Peter
09:22
created

View::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 3
ccs 3
cts 3
cp 1
rs 10
cc 1
eloc 2
nc 1
nop 1
crap 1
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/MIT
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;
30
31
    /**
32
     * @var Node|null
33
     */
34
    protected $prev;
35
36
    /**
37
     * @var Node
38
     */
39
    protected $current;
40
41
    /**
42
     * @var Node|null
43
     */
44
    protected $next;
45
46
    /**
47
     * @var Node|null
48
     */
49
    protected $last;
50
51
    /**
52
     * @var ArrayCollection|null
53
     */
54
    protected $list;
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
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 6
                list($page, $page_to) = $this->getNavigateRange();
146 6
                for (; $page <= $page_to; $page++) {
147 6
                    if ($page == $this->config->getCurrentPage()) {
148 6
                        $this->list->add($this->getCurrent());
149 6
                    } else {
150 6
                        $this->list->add(new Node($page, $this->buildLink($page)));
151
                    }
152 6
                }
153 6
            }
154 7
        }
155
156 7
        return $this->list;
157
    }
158
159
    /**
160
     * @param int $page
161
     *
162
     * @return string
163
     */
164 20
    protected function buildLink($page)
165
    {
166 20
        if ($page == 1 && $this->config->getFirstPageLink()) {
167 4
            return $this->config->getFirstPageLink();
168
        }
169
170 16
        if (is_callable($this->config->getPageLink())) {
171 6
            return call_user_func($this->config->getPageLink(), $page);
172
        } else {
173 10
            return sprintf($this->config->getPageLink(), $page);
174
        }
175
    }
176
177
    /**
178
     * @return int[]
179
     */
180 6
    protected function getNavigateRange()
181
    {
182
        // definition of offset to the left and to the right of the selected page
183 6
        $left_offset = floor(($this->config->getMaxNavigate() - 1) / 2);
184 6
        $right_offset = ceil(($this->config->getMaxNavigate() - 1) / 2);
185
186
        // adjustment, if the offset is too large left
187 6
        if ($this->config->getCurrentPage() - $left_offset < 1) {
188 3
            $offset = abs($this->config->getCurrentPage() - 1 - $left_offset);
189 3
            $left_offset = $left_offset - $offset;
190 3
            $right_offset = $right_offset + $offset;
191 3
        }
192
193
        // adjustment, if the offset is too large right
194 6
        if ($this->config->getCurrentPage() + $right_offset > $this->getTotal()) {
195 3
            $offset = abs($this->getTotal() - $this->config->getCurrentPage() - $right_offset);
196 3
            $left_offset = $left_offset + $offset;
197 3
            $right_offset = $right_offset - $offset;
198 3
        }
199
200
        // determining the first and last pages in paging based on the current page and offset
201 6
        $page_from = $this->config->getCurrentPage() - $left_offset;
202
203
        return [
204 6
            $page_from > 1 ? $page_from : 1,
205 6
            $this->config->getCurrentPage() + $right_offset
206 6
        ];
207
    }
208
}
209