Completed
Push — develop ( efca22...989a9a )
by
unknown
06:29
created

PaginationBuilder::setParameters()   B

Complexity

Conditions 5
Paths 4

Size

Total Lines 20
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 20
rs 8.8571
cc 5
eloc 12
nc 4
nop 1
1
<?php
2
/**
3
 * YAWIK
4
 *
5
 * @filesource
6
 * @license MIT
7
 * @copyright  2013 - 2016 Cross Solution <http://cross-solution.de>
8
 */
9
  
10
/** */
11
namespace Core\Controller\Plugin;
12
13
use Zend\Mvc\Controller\Plugin\AbstractPlugin;
14
use Zend\Stdlib\Parameters;
15
16
/**
17
 * Collects pagination related configuration and passes it to the appropriate
18
 * controller plugin.
19
 *
20
 * In the controller, you only have to call one plugin to do all the YAWIK pagination magic.
21
 *
22
 * @see \Core\Controller\Plugin\PaginationParams
23
 * @see \Core\Controller\Plugin\SearchForm
24
 * @see \Core\Controller\Plugin\CreatePaginator
25
 *
26
 * 
27
 * @author Mathias Gelhausen <[email protected]>
28
 * @since 0.25
29
 */
30
class PaginationBuilder extends AbstractPlugin
31
{
32
33
    /**
34
     * The internal configuration stack.
35
     *
36
     * @var array
37
     */
38
    protected $stack = [];
39
40
    /**
41
     * The generated result array.
42
     *
43
     * @var array
44
     */
45
    protected $result = [];
46
47
    /**
48
     * Internal parameters.
49
     *
50
     * @var Parameters
51
     */
52
    protected $parameters;
53
54
    /**
55
     * Entry point.
56
     *
57
     * if $stack is provided, the internal stack is set to exact that value, so
58
     * please be sure what you're doing.
59
     *
60
     * If you pass a boolean TRUE as $stack, the internal stack is reset.
61
     *
62
     * @param null|array|bool $stack
63
     * @param bool $returnResult Should the result be immediately be returned instead of
64
     *                           self. Only affective when $stack is an array.
65
     *
66
     * @return self|array
67
     * @throws \InvalidArgumentException
68
     */
69
    public function __invoke($stack = null, $returnResult = true)
70
    {
71
        if (true === $stack) {
72
            $this->stack = [];
73
            return $this;
74
        }
75
76
        if (null === $stack) {
77
            return $this;
78
        }
79
80
        if (!is_array($stack)) {
81
            throw new \InvalidArgumentException('Expected argument to be of type array, but received ' . gettype($stack));
82
        }
83
84
        $stack = array_intersect_key($stack, ['params' => true, 'form' => true, 'paginator' => true]);
85
        foreach ($stack as $method => $args) {
86
            if (isset($args['as'])) {
87
                array_push($args, $args['as']);
88
                unset($args['as']);
89
            }
90
            call_user_func_array([$this, $method], $args);
91
        }
92
93
        return $returnResult ? $this->getResult() : $this;
94
    }
95
96
    /**
97
     * Add arguments for the call to the CreatePaginator plugin.
98
     *
99
     * @see \Core\Controller\Plugin\CreatePaginator::__invoke()
100
     *
101
     * @param string       $paginatorName
102
     * @param array  $defaultParams
103
     * @param string $as The name of the key in the result array.
104
     *
105
     * @return self
106
     */
107
    public function paginator($paginatorName, $defaultParams = [], $as = 'paginator')
108
    {
109
        if (is_string($defaultParams)) {
110
            $as = $defaultParams;
111
            $defaultParams = [];
112
        }
113
114
        $this->stack['paginator'] = ['as' => $as, $paginatorName, $defaultParams];
115
        return $this;
116
    }
117
118
    /**
119
     * Add arguments for the call to the SearchForm plugin.
120
     *
121
     * @see \Core\Controller\Plugin\SearchForm::get()
122
     *
123
     * @param        $elementsFieldset
124
     * @param null   $buttonsFieldset
0 ignored issues
show
Bug introduced by
There is no parameter named $buttonsFieldset. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
125
     * @param string $as The name of the key in the result array.
126
     *
127
     * @return self
128
     */
129
    public function form($form, $options = null, $as = 'searchform')
130
    {
131
        if (is_string($options)) {
132
            $as = $options;
133
            $options = null;
134
        }
135
136
        $this->stack['form'] = ['as' => $as, $form, $options];
137
        return $this;
138
    }
139
140
    /**
141
     * Add arguments for the call to the PaginatorParams plugin.
142
     *
143
     * @see \Core\Controller\Plugin\PaginationParams::getParams()
144
     *
145
     * @param       $namespace
146
     * @param array $defaults
147
     *
148
     * @return self
149
     */
150
    public function params($namespace, $defaults = [ 'page' => 1 ])
151
    {
152
        $this->stack['params'] = [$namespace, $defaults];
153
        return $this;
154
    }
155
156
    /**
157
     * Calls the stacked plugins in the right order and returns the result array.
158
     *
159
     * The returned array can directly be returned from the controller or be used to populate a
160
     * view model.
161
     *
162
     * The search form plugin is only called (and thus the form only present in the result array)
163
     * if the request is NOT an ajax request. (as the  form is never rerendered on ajax requests)
164
     *
165
     * @param null|string $paginatorAlias Name of the paginator in the result array
166
     * @param null|string $formAlias Name of the search form in the result array
167
     *
168
     * @return array
169
     */
170
    public function getResult($paginatorAlias = null, $formAlias = null)
171
    {
172 View Code Duplication
        if (null === $paginatorAlias) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
173
            $paginatorAlias = isset($this->stack['paginator']['as'])
174
                            ? $this->stack['paginator']['as']
175
                            : 'paginator';
176
        }
177
178 View Code Duplication
        if (null === $formAlias) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
179
            $formAlias = isset($this->stack['form']['as']) ? $this->stack['form']['as'] : 'searchform';
180
        }
181
182
        /* @var \Zend\Mvc\Controller\AbstractController $controller
183
         * @var \Zend\Http\Request $request */
184
        $result = [];
185
        $controller = $this->getController();
186
        $request = $controller->getRequest();
187
188
        $this->setParameters($request->getQuery());
189
190
        if (isset($this->stack['params'])) {
191
            $this->callPlugin('paginationParams', $this->stack['params']);
192
        }
193
194
        if (isset($this->stack['form'])) {
195
            $form = $this->callPlugin('searchform', $this->stack['form']);
196
            if (!$request->isXmlHttpRequest()) {
197
                $result[$formAlias] = $form;
198
            }
199
        }
200
201
        if (isset($this->stack['paginator'])) {
202
            $result[$paginatorAlias] = $this->callPlugin('paginator', $this->stack['paginator']);
203
        }
204
205
        return $result;
206
    }
207
208
    /**
209
     * Calls an invokable controller plugin.
210
     *
211
     * @param string $name
212
     * @param array $args
213
     *
214
     * @return mixed The return value of the called plugin.
215
     */
216
    protected function callPlugin($name, $args)
217
    {
218
        /* @var \Zend\Mvc\Controller\AbstractController $controller */
219
        $controller = $this->getController();
220
        $plugin = $controller->plugin($name);
221
222
        /* We remove the array entry with the key "as" here.
223
         * because we want to keep it in the stack array */
224
        unset($args['as']);
225
226
        /* Inject the internal parameters as last argument.
227
         * This is needed to prevent messing with the original query params. */
228
        array_push($args, $this->parameters);
229
230
        return call_user_func_array($plugin, $args);
231
    }
232
233
    protected function setParameters($query)
234
    {
235
        $queryArray = $query->toArray();
236
237
        foreach ($queryArray as $key => $value) {
238
            if (preg_match('~^(?<separator>\W)(?<setArrayKeys>\W)?(?<name>.*)$~', $key, $match)) {
239
                $value = explode($match['separator'], $value);
240
                if ('' !== $match['setArrayKeys']) {
241
                    foreach ($value as $v) {
242
                        $queryArray[$match['name']][$v] = 1;
243
                    }
244
                } else {
245
                    $queryArray[ $match[ 'name' ] ] = $value;
246
                }
247
                unset($queryArray[$key]);
248
            }
249
        }
250
251
        $this->parameters = new Parameters($queryArray);
252
    }
253
}
254