Passed
Push — master ( 7f42fd...b622a6 )
by Andreas
32:51 queued 09:01
created

org_openpsa_qbpager::show()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 9
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 7
nc 1
nop 2
dl 0
loc 9
ccs 8
cts 8
cp 1
crap 1
rs 10
c 0
b 0
f 0
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
    public function show_previousnext()
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
    /**
165
     * Displays page selector
166
     */
167 1
    public function show_pages()
168
    {
169 1
        $data = ['pages' => $this->get_pages()];
170 1
        $context = midcom_core_context::enter();
171 1
        $context->set_custom_key('request_data', $data);
172 1
        midcom::get()->style->prepend_component_styledir($this->_component);
173 1
        midcom::get()->style->enter_context($context);
174 1
        midcom_show_style('show_pages');
175 1
        midcom::get()->style->leave_context();
176 1
        midcom_core_context::leave();
177 1
    }
178
179
    /**
180
     * Check $_REQUEST for variables and sets LIMIT and OFFSET for requested page
181
     */
182 14
    protected function parse_variables()
183
    {
184 14
        $page_var = $this->_prefix . 'page';
185 14
        if (!empty($_REQUEST[$page_var])) {
186
            debug_add("{$page_var} has value: {$_REQUEST[$page_var]}");
187
            $this->_current_page = max(1, (int) $_REQUEST[$page_var]);
188
        }
189 14
        $results_var = $this->_prefix . 'results';
190 14
        if (!empty($_REQUEST[$results_var])) {
191
            debug_add("{$results_var} has value: {$_REQUEST[$results_var]}");
192
            $this->results_per_page = max(1, (int) $_REQUEST[$results_var]);
193
        }
194 14
        if ($this->results_per_page < 1) {
195
            throw new LogicException('results_per_page is set to ' . $this->results_per_page);
196
        }
197 14
        $this->_offset = ($this->_current_page - 1) * $this->results_per_page;
198 14
        debug_add("set offset to {$this->_offset} and limit to {$this->results_per_page}");
199 14
    }
200
201
    /**
202
     * Returns number of total pages for query
203
     *
204
     * By default returns a number of pages without any ACL checks
205
     */
206 6
    public function count_pages()
207
    {
208 6
        $this->parse_variables();
209 6
        return ceil($this->count_unchecked() / $this->results_per_page);
210
    }
211
212 13
    public function execute() : array
213
    {
214 13
        $this->parse_variables();
215 13
        $this->set_limit($this->results_per_page);
216 13
        $this->set_offset($this->_offset);
217 13
        return parent::execute();
218
    }
219
220
    /**
221
     * Returns total count before pagination
222
     */
223 6
    public function count_unchecked() : int
224
    {
225 6
        if (!$this->total) {
226 6
            $doctrine_qb = $this->_query->get_doctrine();
227 6
            $offset = $doctrine_qb->getFirstResult();
228 6
            $limit = $doctrine_qb->getMaxResults();
229 6
            $doctrine_qb->setFirstResult(null);
230 6
            $doctrine_qb->setMaxResults(null);
231 6
            $this->total = $this->_query->count();
232 6
            $doctrine_qb->setFirstResult($offset);
233 6
            $doctrine_qb->setMaxResults($limit);
234
        }
235 6
        return $this->total;
236
    }
237
}
238