Completed
Push — master ( c971ff...a4e58c )
by Peter
03:32
created

View   A

Complexity

Total Complexity 29

Size/Duplication

Total Lines 190
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Test Coverage

Coverage 96.88%

Importance

Changes 5
Bugs 0 Features 1
Metric Value
wmc 29
c 5
b 0
f 1
lcom 1
cbo 3
dl 0
loc 190
ccs 31
cts 32
cp 0.9688
rs 10

10 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 3 1
A getTotal() 0 4 1
A getFirst() 0 7 3
A getPrev() 0 10 3
A getCurrent() 0 11 2
A getNext() 0 10 3
A getLast() 0 7 3
B getIterator() 0 19 5
A buildLink() 0 12 4
B getNavigateRange() 0 28 4
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;
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
    }
62
63
    /**
64
     * @return int
65
     */
66
    public function getTotal()
67
    {
68
        return $this->config->getTotalPages();
69
    }
70
71
    /**
72
     * @return Node|null
73
     */
74 5
    public function getFirst()
75
    {
76
        if (!$this->first && $this->config->getCurrentPage() > 1) {
77
            $this->first = new Node(1, $this->buildLink(1));
78
        }
79 5
        return $this->first;
80
    }
81
82
    /**
83
     * @return Node|null
84
     */
85 3
    public function getPrev()
86
    {
87
        if (!$this->prev && $this->config->getCurrentPage() > 1) {
88 2
            $this->prev = new Node(
89
                $this->config->getCurrentPage() - 1,
90
                $this->buildLink($this->config->getCurrentPage() - 1)
91
            );
92
        }
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
                $this->buildLink($this->config->getCurrentPage()),
105 10
                true
106
            );
107
        }
108 10
        return $this->current;
109
    }
110
111
    /**
112
     * @return Node|null
113
     */
114 3
    public function getNext()
115
    {
116
        if (!$this->next && $this->config->getCurrentPage() < $this->getTotal()) {
117 2
            $this->next = new Node(
118
                $this->config->getCurrentPage() + 1,
119
                $this->buildLink($this->config->getCurrentPage() + 1)
120
            );
121
        }
122 3
        return $this->next;
123
    }
124
125
    /**
126
     * @return Node|null
127
     */
128 3
    public function getLast()
129
    {
130
        if (!$this->last && $this->config->getCurrentPage() < $this->getTotal()) {
131
            $this->last = new Node($this->getTotal(), $this->buildLink($this->getTotal()));
132
        }
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
            $this->list = new ArrayCollection();
143
144
            if ($this->getTotal() > 1) {
145
                list($page, $page_to) = $this->getNavigateRange();
146
                for (; $page <= $page_to; $page++) {
147
                    if ($page == $this->config->getCurrentPage()) {
148
                        $this->list->add($this->getCurrent());
149
                    } else {
150
                        $this->list->add(new Node($page, $this->buildLink($page)));
151 6
                    }
152
                }
153
            }
154
        }
155
156 7
        return $this->list;
157
    }
158
159
    /**
160
     * @param int $page
161
     *
162
     * @return string
163
     */
164 6
    protected function buildLink($page)
165
    {
166 6
        if ($page == 1 && $this->config->getFirstPageLink()) {
167
            return $this->config->getFirstPageLink();
168
        }
169
170
        if (is_callable($this->config->getPageLink())) {
171
            return call_user_func($this->config->getPageLink(), $page);
172
        } else {
173
            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
        $left_offset = floor(($this->config->getMaxNavigate() - 1) / 2);
184
        $right_offset = ceil(($this->config->getMaxNavigate() - 1) / 2);
185
186
        // adjustment, if the offset is too large left
187
        if ($this->config->getCurrentPage() - $left_offset < 1) {
188
            $offset = abs($this->config->getCurrentPage() - 1 - $left_offset);
189 3
            $left_offset = $left_offset - $offset;
190 3
            $right_offset = $right_offset + $offset;
191
        }
192
193
        // adjustment, if the offset is too large right
194
        if ($this->config->getCurrentPage() + $right_offset > $this->getTotal()) {
195
            $offset = abs($this->getTotal() - $this->config->getCurrentPage() - $right_offset);
196 3
            $left_offset = $left_offset + $offset;
197 3
            $right_offset = $right_offset - $offset;
198
        }
199
200
        // determining the first and last pages in paging based on the current page and offset
201
        $page_from = $this->config->getCurrentPage() - $left_offset;
202
203
        return [
204 6
            $page_from > 1 ? $page_from : 1,
205
            $this->config->getCurrentPage() + $right_offset
206 6
        ];
207
    }
208
}
209