Completed
Push — develop ( bec80e...e58249 )
by
unknown
09:35
created

PaginationBuilder::__invoke()   C

Complexity

Conditions 7
Paths 9

Size

Total Lines 26
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 26
rs 6.7272
c 0
b 0
f 0
cc 7
eloc 15
nc 9
nop 2
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
15
/**
16
 * Collects pagination related configuration and passes it to the appropriate
17
 * controller plugin.
18
 *
19
 * In the controller, you only have to call one plugin to do all the YAWIK pagination magic.
20
 *
21
 * @see \Core\Controller\Plugin\PaginationParams
22
 * @see \Core\Controller\Plugin\SearchForm
23
 * @see \Core\Controller\Plugin\CreatePaginator
24
 *
25
 * 
26
 * @author Mathias Gelhausen <[email protected]>
27
 * @since 0.25
28
 */
29
class PaginationBuilder extends AbstractPlugin
30
{
31
32
    /**
33
     * The internal configuration stack.
34
     *
35
     * @var array
36
     */
37
    protected $stack = [];
38
39
    /**
40
     * The generated result array.
41
     *
42
     * @var array
43
     */
44
    protected $result = [];
45
46
    /**
47
     * Entry point.
48
     *
49
     * if $stack is provided, the internal stack is set to exact that value, so
50
     * please be sure what you're doing.
51
     *
52
     * If you pass a boolean TRUE as $stack, the internal stack is reset.
53
     *
54
     * @param null|array|bool $stack
55
     * @param bool $returnResult Should the result be immediately be returned instead of
56
     *                           self. Only affective when $stack is an array.
57
     *
58
     * @return self|array
59
     * @throws \InvalidArgumentException
60
     */
61
    public function __invoke($stack = null, $returnResult = true)
62
    {
63
        if (true === $stack) {
64
            $this->stack = [];
65
            return $this;
66
        }
67
68
        if (null === $stack) {
69
            return $this;
70
        }
71
72
        if (!is_array($stack)) {
73
            throw new \InvalidArgumentException('Expected argument to be of type array, but received ' . gettype($stack));
74
        }
75
76
        $stack = array_intersect_key($stack, ['params' => true, 'form' => true, 'paginator' => true]);
77
        foreach ($stack as $method => $args) {
78
            if (isset($args['as'])) {
79
                array_push($args, $args['as']);
80
                unset($args['as']);
81
            }
82
            call_user_func_array([$this, $method], $args);
83
        }
84
85
        return $returnResult ? $this->getResult() : $this;
86
    }
87
88
    /**
89
     * Add arguments for the call to the CreatePaginator plugin.
90
     *
91
     * @see \Core\Controller\Plugin\CreatePaginator::__invoke()
92
     *
93
     * @param string       $paginatorName
94
     * @param array  $defaultParams
95
     * @param bool   $usePostParams
96
     * @param string $as The name of the key in the result array.
97
     *
98
     * @return self
99
     */
100
    public function paginator($paginatorName, $defaultParams = [], $usePostParams = false, $as = 'paginator')
101
    {
102
        if (is_string($defaultParams)) {
103
            $as = $defaultParams;
104
            $defaultParams = [];
105
        } else if (is_string($usePostParams)) {
106
            $as = $usePostParams;
107
            $usePostParams = false;
108
        }
109
110
        $this->stack['paginator'] = ['as' => $as, $paginatorName, $defaultParams, $usePostParams];
111
        return $this;
112
    }
113
114
    /**
115
     * Add arguments for the call to the SearchForm plugin.
116
     *
117
     * @see \Core\Controller\Plugin\SearchForm::get()
118
     *
119
     * @param        $elementsFieldset
120
     * @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...
121
     * @param string $as The name of the key in the result array.
122
     *
123
     * @return self
124
     */
125
    public function form($form, $options = null, $as = 'searchform')
126
    {
127
        if (is_string($options)) {
128
            $as = $options;
129
            $options = null;
130
        }
131
132
        $this->stack['form'] = ['as' => $as, $form, $options];
133
        return $this;
134
    }
135
136
    /**
137
     * Add arguments for the call to the PaginatorParams plugin.
138
     *
139
     * @see \Core\Controller\Plugin\PaginationParams::getParams()
140
     *
141
     * @param       $namespace
142
     * @param array $defaults
143
     *
144
     * @return self
145
     */
146
    public function params($namespace, $defaults = [ 'page' => 1 ])
147
    {
148
        $this->stack['params'] = [$namespace, $defaults];
149
        return $this;
150
    }
151
152
    /**
153
     * Calls the stacked plugins in the right order and returns the result array.
154
     *
155
     * The returned array can directly be returned from the controller or be used to populate a
156
     * view model.
157
     *
158
     * The search form plugin is only called (and thus the form only present in the result array)
159
     * if the request is NOT an ajax request. (as the  form is never rerendered on ajax requests)
160
     *
161
     * @param null|string $paginatorAlias Name of the paginator in the result array
162
     * @param null|string $formAlias Name of the search form in the result array
163
     *
164
     * @return array
165
     */
166
    public function getResult($paginatorAlias = null, $formAlias = null)
167
    {
168 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...
169
            $paginatorAlias = isset($this->stack['paginator']['as'])
170
                            ? $this->stack['paginator']['as']
171
                            : 'paginator';
172
        }
173
174 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...
175
            $formAlias = isset($this->stack['form']['as']) ? $this->stack['form']['as'] : 'searchform';
176
        }
177
178
        /* @var \Zend\Mvc\Controller\AbstractController $controller
179
         * @var \Zend\Http\Request $request */
180
        $result = [];
181
        $controller = $this->getController();
182
        $request = $controller->getRequest();
183
184
        $this->filterQueryParameters($request->getQuery());
185
186
        if (isset($this->stack['params'])) {
187
            $this->callPlugin('paginationParams', $this->stack['params']);
188
        }
189
190
        if (isset($this->stack['form']) && !$request->isXmlHttpRequest()) {
191
            $result[$formAlias] = $this->callPlugin('searchform', $this->stack['form']);
192
        }
193
194
        if (isset($this->stack['paginator'])) {
195
            $result[$paginatorAlias] = $this->callPlugin('paginator', $this->stack['paginator']);
196
        }
197
198
        return $result;
199
    }
200
201
    /**
202
     * Calls an invokable controller plugin.
203
     *
204
     * @param string $name
205
     * @param array $args
206
     *
207
     * @return mixed The return value of the called plugin.
208
     */
209
    protected function callPlugin($name, $args)
210
    {
211
        /* @var \Zend\Mvc\Controller\AbstractController $controller */
212
        $controller = $this->getController();
213
        $plugin = $controller->plugin($name);
214
215
        /* We remove the array entry with the key "as" here.
216
         * because we want to keep it in the stack array */
217
        unset($args['as']);
218
219
        return call_user_func_array($plugin, $args);
220
    }
221
222
    protected function filterQueryParameters($query)
223
    {
224
        $queryArray = $query->toArray();
225
226
        foreach ($queryArray as $key => $value) {
227
            if (preg_match('~^(?<separator>\W)(?<name>.*)$~', $key, $match)) {
228
                $value = explode($match['separator'], $value);
229
                $queryArray[$match['name']] = $value;
230
                unset($queryArray[$key]);
231
            }
232
        }
233
234
        $query->fromArray($queryArray);
235
    }
236
}