Passed
Push — master ( 057072...a7e5bc )
by Andreas
19:36
created

org_openpsa_qbpager::parse_variables()   A

Complexity

Conditions 4
Paths 8

Size

Total Lines 17
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 4.9102

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 4
eloc 12
c 1
b 0
f 0
nc 8
nop 0
dl 0
loc 17
ccs 8
cts 13
cp 0.6153
crap 4.9102
rs 9.8666
1
<?php
2
/**
3
 * @package org.openpsa.qbpager
4
 */
5
6
/**
7
 * Pages QB resultsets
8
 *
9
 * @package org.openpsa.qbpager
10
 */
11
class org_openpsa_qbpager extends midcom_core_querybuilder
12
{
13
    use midcom_baseclasses_components_base;
0 ignored issues
show
introduced by
The trait midcom_baseclasses_components_base requires some properties which are not provided by org_openpsa_qbpager: $i18n, $head
Loading history...
14
15
    public $results_per_page = 25;
16
    public $display_pages = 10;
17
    public $string_next = 'next';
18
    public $string_previous = 'previous';
19
    protected $_pager_id;
20
    protected $_prefix = '';
21
    private $_current_page = 1;
22
    private $total;
23
24 13
    public function __construct(string $classname, string $pager_id)
25
    {
26 13
        $this->initialize($pager_id);
27 13
        parent::__construct($classname);
0 ignored issues
show
Unused Code introduced by
The call to midcom_baseclasses_components_base::__construct() has too many arguments starting with $classname. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

27
        parent::/** @scrutinizer ignore-call */ 
28
                __construct($classname);

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
28 13
    }
29
30 14
    protected function initialize(string $pager_id)
31
    {
32 14
        $this->_component = 'org.openpsa.qbpager';
33 14
        if (empty($pager_id)) {
34
            throw new midcom_error('pager_id is not set (needed for distinguishing different instances on same request)');
35
        }
36
37 14
        $this->_pager_id = $pager_id;
38 14
        $this->_prefix = 'org_openpsa_qbpager_' . $pager_id . '_';
39 14
    }
40
41
    /**
42
     * Get the current page number
43
     */
44 5
    public function get_current_page() : int
45
    {
46 5
        return $this->_current_page;
47
    }
48
49
    /**
50
     * Fetch all $_GET variables
51
     */
52
    private function _get_query_string(string $page_var, int $page_number) : string
53
    {
54
        $query = [$page_var => $page_number];
55
56
        foreach ($_GET as $key => $value) {
57
            if (!in_array($key, [$page_var, ''])) {
58
                $query[$key] = $value;
59
            }
60
        }
61
62
        return '?' . http_build_query($query);
63
    }
64
65
    /**
66
     * Displays previous/next selector
67
     */
68 5
    function show_previousnext()
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
69
    {
70 5
        $page_count = $this->count_pages();
71
        //Skip the header in case we only have one page
72 5
        if ($page_count <= 1) {
73 5
            return;
74
        }
75
        //@todo Move to style element
76
        //TODO: "showing results (offset)-(offset+limit)
77
        $page_var = $this->_prefix . 'page';
78
        echo '<div class="org_openpsa_qbpager_previousnext">';
79
80
        if ($this->_current_page > 1) {
81
            $previous = $this->_current_page - 1;
82
            echo "\n<a class=\"previous_page\" href=\"" . $this->_get_query_string($page_var, $previous) . "\" rel=\"prev\">" . $this->_l10n->get($this->string_previous) . "</a>";
83
        }
84
85
        if ($this->_current_page < $page_count) {
86
            $next = $this->_current_page + 1;
87
            echo "\n<a class=\"next_page\" href=\"" . $this->_get_query_string($page_var, $next) . "\" rel=\"next\">" . $this->_l10n->get($this->string_next) . "</a>";
88
        }
89
90
        echo "\n</div>\n";
91
    }
92
93 1
    public function get_pages() : array
94
    {
95 1
        $pages = [];
96 1
        $page_count = $this->count_pages();
97
98 1
        if ($page_count < 1) {
99
            return $pages;
100
        }
101
102 1
        $page_var = $this->_prefix . 'page';
103 1
        $display_start = max(($this->_current_page - ceil($this->display_pages / 2)), 1);
104 1
        $display_end = min(($this->_current_page + ceil($this->display_pages / 2)), $page_count);
105
106 1
        if ($this->_current_page > 1) {
107
            $previous = $this->_current_page - 1;
108
            if ($previous > 1) {
109
                $pages[] = [
110
                    'class' => 'first',
111
                    'href' => $this->_get_query_string($page_var, 1),
112
                    'rel' => 'prev',
113
                    'label' => $this->_l10n->get('first'),
114
                    'number' => 1
115
                ];
116
            }
117
            $pages[] = [
118
                'class' => 'previous',
119
                'href' => $this->_get_query_string($page_var, $previous),
120
                'rel' => 'prev',
121
                'label' => $this->_l10n->get($this->string_previous),
122
                'number' => $previous
123
            ];
124
        }
125 1
        $page = $display_start - 1;
126 1
        while ($page++ < $display_end) {
127 1
            $href = false;
128 1
            if ($page != $this->_current_page) {
129
                $href = $this->_get_query_string($page_var, $page);
130
            }
131 1
            $pages[] = [
132 1
                'class' => 'current',
133 1
                'href' => $href,
134
                'rel' => false,
135 1
                'label' => $page,
136 1
                'number' => $page
137
            ];
138
        }
139
140 1
        if ($this->_current_page < $page_count) {
141
            $next = $this->_current_page + 1;
142
            $pages[] = [
143
                'class' => 'next',
144
                'href' => $this->_get_query_string($page_var, $next),
145
                'rel' => 'next',
146
                'label' => $this->_l10n->get($this->string_next),
147
                'number' => $next
148
            ];
149
150
            if ($next < $page_count) {
151
                $pages[] = [
152
                    'class' => 'last',
153
                    'href' => $this->_get_query_string($page_var, $page_count),
0 ignored issues
show
Bug introduced by
$page_count of type double is incompatible with the type integer expected by parameter $page_number of org_openpsa_qbpager::_get_query_string(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

153
                    'href' => $this->_get_query_string($page_var, /** @scrutinizer ignore-type */ $page_count),
Loading history...
154
                    'rel' => 'next',
155
                    'label' => $this->_l10n->get('last'),
156
                    'number' => $page_count
157
                ];
158
            }
159
        }
160
161 1
        return $pages;
162
    }
163
164 1
    private function show(string $name, array $data)
165
    {
166 1
        $context = midcom_core_context::enter();
167 1
        $context->set_custom_key('request_data', $data);
168 1
        midcom::get()->style->prepend_component_styledir($this->_component);
169 1
        midcom::get()->style->enter_context($context);
170 1
        midcom_show_style('show_' . $name);
171 1
        midcom::get()->style->leave_context();
172 1
        midcom_core_context::leave();
173 1
    }
174
175
    /**
176
     * Displays page selector
177
     */
178 1
    public function show_pages()
179
    {
180 1
        $this->show('pages', ['pages' => $this->get_pages()]);
181 1
    }
182
183
    /**
184
     * Displays page selector as list
185
     */
186
    function show_pages_as_list()
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
187
    {
188
        $this->show('pages_as_list', ['pages' => $this->get_pages()]);
189
    }
190
191
    /**
192
     * Check $_REQUEST for variables and sets LIMIT and OFFSET for requested page
193
     */
194 14
    protected function parse_variables()
195
    {
196 14
        $page_var = $this->_prefix . 'page';
197 14
        if (!empty($_REQUEST[$page_var])) {
198
            debug_add("{$page_var} has value: {$_REQUEST[$page_var]}");
199
            $this->_current_page = max(1, (int) $_REQUEST[$page_var]);
200
        }
201 14
        $results_var = $this->_prefix . 'results';
202 14
        if (!empty($_REQUEST[$results_var])) {
203
            debug_add("{$results_var} has value: {$_REQUEST[$results_var]}");
204
            $this->results_per_page = max(1, (int) $_REQUEST[$results_var]);
205
        }
206 14
        if ($this->results_per_page < 1) {
207
            throw new LogicException('results_per_page is set to ' . $this->results_per_page);
208
        }
209 14
        $this->_offset = ($this->_current_page - 1) * $this->results_per_page;
210 14
        debug_add("set offset to {$this->_offset} and limit to {$this->results_per_page}");
211 14
    }
212
213
    /**
214
     * Returns number of total pages for query
215
     *
216
     * By default returns a number of pages without any ACL checks
217
     */
218 6
    public function count_pages()
219
    {
220 6
        $this->parse_variables();
221 6
        return ceil($this->count_unchecked() / $this->results_per_page);
222
    }
223
224 13
    public function execute() : array
225
    {
226 13
        $this->parse_variables();
227 13
        $this->set_limit($this->results_per_page);
228 13
        $this->set_offset($this->_offset);
229 13
        return parent::execute();
230
    }
231
232
    /**
233
     * Returns total count before pagination
234
     */
235 6
    public function count_unchecked() : int
236
    {
237 6
        if (!$this->total) {
238 6
            $doctrine_qb = $this->_query->get_doctrine();
239 6
            $offset = $doctrine_qb->getFirstResult();
240 6
            $limit = $doctrine_qb->getMaxResults();
241 6
            $doctrine_qb->setFirstResult(null);
242 6
            $doctrine_qb->setMaxResults(null);
243 6
            $this->total = $this->_query->count();
244 6
            $doctrine_qb->setFirstResult($offset);
245 6
            $doctrine_qb->setMaxResults($limit);
246
        }
247 6
        return $this->total;
248
    }
249
}
250