Completed
Push — master ( 697d04...680e31 )
by Anton
11:14 queued 05:01
created

PaginatorTrait   A

Complexity

Total Complexity 17

Size/Duplication

Total Lines 188
Duplicated Lines 0 %

Coupling/Cohesion

Components 3
Dependencies 3

Importance

Changes 2
Bugs 0 Features 0
Metric Value
wmc 17
c 2
b 0
f 0
lcom 3
cbo 3
dl 0
loc 188
rs 10

12 Methods

Rating   Name   Duplication   Size   Complexity  
count() 0 1 ?
A getLimit() 0 4 1
A getOffset() 0 4 1
A paginator() 0 4 1
A limit() 0 6 1
A offset() 0 6 1
A setPaginator() 0 6 1
A getPaginator() 0 4 1
A isPaginated() 0 4 1
C paginate() 0 40 7
A applyPagination() 0 8 2
container() 0 1 ?
1
<?php
2
/**
3
 * Spiral Framework.
4
 *
5
 * @license   MIT
6
 * @author    Anton Titov (Wolfy-J)
7
 */
8
namespace Spiral\Pagination\Traits;
9
10
use Interop\Container\ContainerInterface;
11
use Psr\Http\Message\ServerRequestInterface;
12
use Spiral\Core\Exceptions\SugarException;
13
use Spiral\Core\FactoryInterface;
14
use Spiral\Pagination\Exceptions\PaginationException;
15
use Spiral\Pagination\Paginator;
16
use Spiral\Pagination\PaginatorInterface;
17
18
/**
19
 * Provides ability to paginate associated instance. Will work with default Paginator or fetch one
20
 * from container.
21
 *
22
 * Compatible with PaginatorAwareInterface.
23
 */
24
trait PaginatorTrait
25
{
26
    /**
27
     * @internal
28
     * @var PaginatorInterface
29
     */
30
    private $paginator = null;
31
32
    /**
33
     * @var int
34
     */
35
    protected $limit = 0;
36
37
    /**
38
     * @var int
39
     */
40
    protected $offset = 0;
41
42
    /**
43
     * Count elements of an object.
44
     *
45
     * @link http://php.net/manual/en/countable.count.php
46
     * @return int
47
     */
48
    abstract public function count();
49
50
    /**
51
     * Set selection limit.
52
     *
53
     * @param int $limit
54
     * @return mixed
55
     */
56
    public function limit($limit = 0)
57
    {
58
        $this->limit = $limit;
59
60
        return $this;
61
    }
62
63
    /**
64
     * @return int
65
     */
66
    public function getLimit()
67
    {
68
        return $this->limit;
69
    }
70
71
    /**
72
     * Set selection offset.
73
     *
74
     * @param int $offset
75
     * @return mixed
76
     */
77
    public function offset($offset = 0)
78
    {
79
        $this->offset = $offset;
80
81
        return $this;
82
    }
83
84
    /**
85
     * @return int
86
     */
87
    public function getOffset()
88
    {
89
        return $this->offset;
90
    }
91
92
    /**
93
     * Manually set paginator instance for specific object.
94
     *
95
     * @param PaginatorInterface $paginator
96
     * @return $this
97
     */
98
    public function setPaginator(PaginatorInterface $paginator)
99
    {
100
        $this->paginator = $paginator;
101
102
        return $this;
103
    }
104
105
    /**
106
     * Get paginator for the current selection. Paginate method should be already called.
107
     *
108
     * @see isPaginated()
109
     * @see paginate()
110
     * @return PaginatorInterface|Paginator|null
111
     */
112
    public function paginator()
113
    {
114
        return $this->paginator;
115
    }
116
117
    /**
118
     * Get paginator for the current selection. Paginate method should be already called.
119
     *
120
     * @see isPaginated()
121
     * @see paginate()
122
     * @return PaginatorInterface|Paginator|null
123
     */
124
    public function getPaginator()
125
    {
126
        return $this->paginator;
127
    }
128
129
    /**
130
     * Indication that object was paginated.
131
     *
132
     * @return bool
133
     */
134
    public function isPaginated()
135
    {
136
        return !empty($this->paginator);
137
    }
138
139
    /**
140
     * Paginate current selection using Paginator class.
141
     *
142
     * @param int                    $limit         Pagination limit.
143
     * @param string                 $pageParameter Name of parameter in request query which is
144
     *                                              used to store the current page number. "page"
145
     *                                              by default.
146
     * @param ServerRequestInterface $request       Has to be specified if no global container set.
147
     * @return $this
148
     * @throws PaginationException
149
     */
150
    public function paginate(
151
        $limit = Paginator::DEFAULT_LIMIT,
152
        $pageParameter = Paginator::DEFAULT_PARAMETER,
153
        ServerRequestInterface $request = null
154
    ) {
155
        //Will be used in two places
156
        $container = $this->container();
157
158
        if (empty($request)) {
159
            if (empty($container) || !$container->has(ServerRequestInterface::class)) {
160
                throw new SugarException(
161
                    "Unable to create pagination without specified request."
162
                );
163
            }
164
165
            //Getting request from container scope
166
            $request = $container->get(ServerRequestInterface::class);
167
        }
168
169
        if (empty($container) || !$container->has(PaginatorInterface::class)) {
170
            //Let's use default paginator
171
            $this->paginator = new Paginator($request, $pageParameter);
172
        } else {
173
            //We need constructor
174
            if ($container instanceof FactoryInterface) {
175
                $constructor = $container;
176
            } else {
177
                $constructor = $container->get(FactoryInterface::class);
178
            }
179
180
            //We can also create paginator using container
181
            $this->paginator = $constructor->make(PaginatorInterface::class, compact(
182
                'request', 'pageParameter'
183
            ));
184
        }
185
186
        $this->paginator->setLimit($limit);
187
188
        return $this;
189
    }
190
191
    /**
192
     * Apply pagination to current object. Will be applied only if internal paginator already
193
     * constructed.
194
     *
195
     * @return $this
196
     * @throws PaginationException
197
     */
198
    protected function applyPagination()
199
    {
200
        if (empty($this->paginator)) {
201
            return $this;
202
        }
203
204
        return $this->paginator->paginate($this);
205
    }
206
207
    /**
208
     * @return ContainerInterface
209
     */
210
    abstract protected function container();
211
}
212