Failed Conditions
Branch master (3ce7e2)
by Nick
14:43
created

PAGE   F

Complexity

Total Complexity 192

Size/Duplication

Total Lines 1338
Duplicated Lines 0 %

Test Coverage

Coverage 0%

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 1338
rs 0.6314
ccs 0
cts 630
cp 0
wmc 192

35 Methods

Rating   Name   Duplication   Size   Complexity  
A mp_search_form() 0 11 1
B display_table() 0 54 8
A advanced_search_form() 0 2 1
A displayHeader() 0 17 2
A page_start() 0 4 2
C block_start() 0 32 7
C heading() 0 58 16
C login_form() 0 78 10
A page_started() 0 2 2
B display_commentreport() 0 26 3
A page_end() 0 9 2
B admin_menu() 0 33 3
A postcode_form() 0 23 2
A block_end() 0 8 2
A within_stripe() 0 5 3
C set_hansard_headings() 0 38 8
A glossary_display_match_list() 0 20 3
B stripe_start() 0 26 5
A include_sidebar_template() 0 7 2
B checkForAdmin() 0 19 5
A glossary_link() 0 6 1
C glossary_atoz() 0 48 7
C message() 0 44 8
B glossary_display_term() 0 41 4
F search_form() 0 96 22
F page_links() 0 92 13
B display_commentreportlist() 0 53 4
A informational() 0 2 1
D nextprevlinks() 0 68 12
A heading_displayed() 0 2 2
F display_calendar_month() 0 131 11
C error_message() 0 41 8
A glossary_links() 0 4 1
A within_stripe_sidebar() 0 5 2
C stripe_end() 0 94 9

How to fix   Complexity   

Complex Class

Complex classes like PAGE often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use PAGE, and based on these observations, apply Extract Interface, too.

1
<?php
1 ignored issue
show
Coding Style Compatibility introduced by
For compatibility and reusability of your code, PSR1 recommends that a file should introduce either new symbols (like classes, functions, etc.) or have side-effects (like outputting something, or including other files), but not both at the same time. The first symbol is defined on line 6 and the first side effect is on line 3.

The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.

The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.

To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.

Loading history...
2
3
include_once INCLUDESPATH . '../../commonlib/phplib/gaze.php';
1 ignored issue
show
Bug introduced by
The constant INCLUDESPATH was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
4
include_once INCLUDESPATH . 'easyparliament/member.php';
5
6
class PAGE {
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class must be in a namespace of at least one level to avoid collisions.

You can fix this by adding a namespace to your class:

namespace YourVendor;

class YourClass { }

When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.

Loading history...
7
8
    // So we can tell from other places whether we need to output the page_start or not.
9
    // Use the page_started() function to do this.
10
    public $page_start_done = false;
11
    public $supress_heading = false;
12
    public $heading_displayed = false;
13
14
    // We want to know where we are with the stripes, the main structural elements
15
    // of most pages, so that if we output an error message we can wrap it in HTML
16
    // that won't break the rest of the page.
17
    // Changed in $this->stripe_start().
0 ignored issues
show
Unused Code Comprehensibility introduced by
37% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
18
    public $within_stripe_main = false;
19
    public $within_stripe_sidebar = false;
20
21
    public function page_start() {
22
        if ( !$this->page_started() ) {
23
            $this->checkForAdmin();
24
            $this->displayHeader();
25
        }
26
    }
27
28
    private function displayHeader() {
29
        global $page_errors;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
30
        $h = new MySociety\TheyWorkForYou\Renderer\Header();
31
        $u = new MySociety\TheyWorkForYou\Renderer\User();
32
33
        $data = $h->data;
34
        $data = array_merge($u->data, $data);
35
        if ( isset($page_errors) ) {
36
            $data['page_errors'] = $page_errors;
37
        }
38
        $data['banner_text'] = '';
39
        extract($data);
40
        require_once INCLUDESPATH . 'easyparliament/templates/html/header.php';
1 ignored issue
show
Bug introduced by
The constant INCLUDESPATH was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
41
42
        echo '<div class="full-page legacy-page static-page"> <div class="full-page__row"> <div class="panel">';
43
44
        $this->page_start_done = true;
45
    }
46
47
    private function checkForAdmin() {
48
        global $DATA, $this_page, $THEUSER;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
49
        $parent = $DATA->page_metadata($this_page, "parent");
50
        if ($parent == 'admin' && (!$THEUSER->isloggedin() || !$THEUSER->is_able_to('viewadminsection'))) {
51
            if (!$THEUSER->isloggedin()) {
52
                $THISPAGE = new \MySociety\TheyWorkForYou\Url($this_page);
53
54
                $LOGINURL = new \MySociety\TheyWorkForYou\Url('userlogin');
55
                $LOGINURL->insert(array('ret' => $THISPAGE->generate('none') ));
56
57
                $text = "<a href=\"" . $LOGINURL->generate() . "\">You'd better sign in!</a>";
58
            } else {
59
                $text = "That's all folks!";
60
            }
61
            $this_page = 'home';
62
            $this->displayHeader();
63
            echo $text;
64
            $this->page_end();
65
            exit();
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
66
        }
67
    }
68
69
    public function page_end() {
70
        if ( !$this->page_started() ) {
71
            $this->page_start();
72
        }
73
74
        echo '</div></div></div>';
75
        $footer = new MySociety\TheyWorkForYou\Renderer\Footer();
76
        $footer_links = $footer->data;
0 ignored issues
show
Unused Code introduced by
The assignment to $footer_links is dead and can be removed.
Loading history...
77
        require_once INCLUDESPATH . 'easyparliament/templates/html/footer.php';
1 ignored issue
show
Bug introduced by
The constant INCLUDESPATH was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
78
    }
79
80
    public function page_started() {
81
        return $this->page_start_done == true ? true : false;
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
82
    }
83
84
    public function heading_displayed() {
85
        return $this->heading_displayed == true ? true : false;
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
86
    }
87
88
    public function within_stripe() {
89
        if ($this->within_stripe_main == true || $this->within_stripe_sidebar == true) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
90
            return true;
91
        } else {
92
            return false;
93
        }
94
    }
95
96
    public function within_stripe_sidebar() {
97
        if ($this->within_stripe_sidebar == true) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
98
            return true;
99
        } else {
100
            return false;
101
        }
102
    }
103
104
    public function stripe_start($type='side', $id='', $extra_class = '') {
105
        // $type is one of:
106
        //  'full' - a full width div
107
        //  'side' - a white stripe with a coloured sidebar.
108
        //           (Has extra padding at the bottom, often used for whole pages.)
109
        //  'head-1' - used for the page title headings in hansard.
110
        //  'head-2' - used for section/subsection titles in hansard.
111
        //  '1', '2' - For alternating stripes in listings.
112
        //  'time-1', 'time-2' - For displaying the times in hansard listings.
113
        //  'procedural-1', 'procedural-2' - For the proecdures in hansard listings.
114
        //  'foot' - For the bottom stripe on hansard debates/wrans listings.
115
        // $id is the value of an id for this div (if blank, not used).
116
        ?>
117
        <div class="stripe-<?php echo $type; ?><?php if ($extra_class != '') echo ' ' . $extra_class; ?>"<?php
118
        if ($id != '') {
119
            print ' id="' . $id . '"';
120
        }
121
        ?>>
122
            <div class="main">
123
<?php
124
        $this->within_stripe_main = true;
125
        // On most, uncomplicated pages, the first stripe on a page will include
126
        // the page heading. So, if we haven't already printed a heading on this
127
        // page, we do it now...
128
        if (!$this->heading_displayed() && $this->supress_heading != true) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison !== instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
129
            $this->heading();
130
        }
131
    }
132
133
134
    public function stripe_end ($contents = array(), $extra = '') {
0 ignored issues
show
Unused Code introduced by
The parameter $extra is not used and could be removed. ( Ignorable by Annotation )

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

134
    public function stripe_end ($contents = array(), /** @scrutinizer ignore-unused */ $extra = '') {

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
135
        // $contents is an array containing 0 or more hashes.
136
        // Each hash has two values, 'type' and 'content'.
137
        // 'Type' could be one of these:
138
        //  'include' - will include a sidebar named after the value of 'content'.php.
139
        //  'nextprev' - $this->nextprevlinks() is called ('content' currently ignored).
140
        //  'html' - The value of the 'content' is simply displayed.
141
        //  'extrahtml' - The value of the 'content' is displayed after the sidebar has
142
        //                  closed, but within this stripe.
143
144
        // If $contents is empty then '&nbsp;' will be output.
145
146
        /* eg, take this hypothetical array:
147
            $contents = array(
148
                array (
149
                    'type'  => 'include',
150
                    'content'   => 'mp'
151
                ),
152
                array (
153
                    'type'  => 'html',
154
                    'content'   => "<p>This is your MP</p>\n"
155
                ),
156
                array (
157
                    'type'  => 'nextprev'
158
                ),
159
                array (
160
                    'type'  => 'none'
161
                ),
162
                array (
163
                    'extrahtml' => '<a href="blah">Source</a>'
164
                )
165
            );
166
167
            The sidebar div would be opened.
168
            This would first include /includes/easyparliament/templates/sidebars/mp.php.
169
            Then display "<p>This is your MP</p>\n".
170
            Then call $this->nextprevlinks().
171
            The sidebar div would be closed.
172
            '<a href="blah">Source</a>' is displayed.
173
            The stripe div is closed.
174
175
            But in most cases we only have 0 or 1 hashes in $contents.
176
177
        */
178
179
        // $extra is html that will go after the sidebar has closed, but within
180
        // this stripe.
181
        // eg, the 'Source' bit on Hansard pages.
182
        global $DATA, $this_page;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
183
184
        $this->within_stripe_main = false;
185
        ?>
186
            </div> <!-- end .main -->
187
            <div class="sidebar">
188
189
        <?php
190
        $this->within_stripe_sidebar = true;
191
        $extrahtml = '';
192
193
        if (count($contents) == 0) {
194
            print "\t\t\t&nbsp;\n";
195
        } else {
196
            #print '<div class="sidebar">';
197
            foreach ($contents as $hash) {
198
                if (isset($hash['type'])) {
199
                    if ($hash['type'] == 'include') {
200
                        $this->include_sidebar_template($hash['content']);
201
202
                    } elseif ($hash['type'] == 'nextprev') {
203
                        $this->nextprevlinks();
204
205
                    } elseif ($hash['type'] == 'html') {
206
                        print $hash['content'];
207
208
                    } elseif ($hash['type'] == 'extrahtml') {
209
                        $extrahtml .= $hash['content'];
210
                    }
211
                }
212
213
            }
214
        }
215
216
        $this->within_stripe_sidebar = false;
217
        ?>
218
            </div> <!-- end .sidebar -->
219
            <div class="break"></div>
220
<?php
221
        if ($extrahtml != '') {
222
            ?>
223
            <div class="extra"><?php echo $extrahtml; ?></div>
224
<?php
225
            }
226
            ?>
227
        </div> <!-- end .stripe-* -->
228
229
<?php
230
    }
231
232
233
234
    public function include_sidebar_template($sidebarname) {
235
        global $this_page, $DATA;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
236
237
            $sidebarpath = INCLUDESPATH.'easyparliament/sidebars/'.$sidebarname.'.php';
1 ignored issue
show
Bug introduced by
The constant INCLUDESPATH was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
238
239
            if (file_exists($sidebarpath)) {
240
                include $sidebarpath;
241
            }
242
    }
243
244
245
    public function block_start($data=array()) {
246
        // Starts a 'block' div, used mostly on the home page,
247
        // on the MP page, and in the sidebars.
248
        // $data is a hash like this:
249
        //  'id'    => 'help',
0 ignored issues
show
Unused Code Comprehensibility introduced by
58% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
250
        //  'title' => 'What are debates?'
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
251
        //  'url'   => '/help/#debates'     [if present, will be wrapped round 'title']
252
        //  'body'  => false    [If not present, assumed true. If false, no 'blockbody' div]
0 ignored issues
show
Unused Code Comprehensibility introduced by
36% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
253
        // Both items are optional (although it'll look odd without a title).
254
255
        $this->blockbody_open = false;
0 ignored issues
show
Bug Best Practice introduced by
The property blockbody_open does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
256
257
        if (isset($data['id']) && $data['id'] != '') {
258
            $id = ' id="' . $data['id'] . '"';
259
        } else {
260
            $id = '';
261
        }
262
263
        $title = isset($data['title']) ? $data['title'] : '';
264
265
        if (isset($data['url'])) {
266
            $title = '<a href="' . $data['url'] . '">' . $title . '</a>';
267
        }
268
        ?>
269
                <div class="block"<?php echo $id; ?>>
270
                    <h4><?php echo $title; ?></h4>
271
<?php
272
        if (!isset($data['body']) || $data['body'] == true) {
273
            ?>
274
                    <div class="blockbody">
275
<?php
276
            $this->blockbody_open = true;
277
            }
278
    }
279
280
    public function block_end() {
281
        if ($this->blockbody_open) {
282
            ?>
283
                    </div>
284
<?php
285
            }
286
            ?>
287
                </div> <!-- end .block -->
288
289
<?php
290
    }
291
292
    public function heading() {
293
        global $this_page, $DATA;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
294
295
        // As well as a page's title, we may display that of its parent.
296
        // A page's parent can have a 'title' and a 'heading'.
297
        // The 'title' is always used to create the <title></title>.
298
        // If we have a 'heading' however, we'll use that here, on the page, instead.
299
300
        $parent_page = $DATA->page_metadata($this_page, 'parent');
301
302
        if ($parent_page != '') {
303
            // Not a top-level page, so it has a section heading.
304
            // This is the page title of the parent.
305
            $section_text = $DATA->page_metadata($parent_page, 'title');
306
307
        } else {
308
            // Top level page - no parent, hence no parental title.
309
            $section_text = '';
310
        }
311
312
313
        // A page can have a 'title' and a 'heading'.
314
        // The 'title' is always used to create the <title></title>.
315
        // If we have a 'heading' however, we'll use that here, on the page, instead.
316
317
        $page_text = $DATA->page_metadata($this_page, "heading");
318
319
        if ($page_text == '' && !is_bool($page_text)) {
320
            // If the metadata 'heading' is set, but empty, we display nothing.
321
        } elseif ($page_text == false) {
322
            // But if it just hasn't been set, we use the 'title'.
323
            $page_text = $DATA->page_metadata($this_page, "title");
324
        }
325
326
        if ($page_text == $section_text) {
327
            // We don't want to print both.
328
            $section_text = '';
329
        } elseif (!$page_text && $section_text) {
330
            // Bodge for if we have a section_text but no page_text.
331
            $page_text = $section_text;
332
            $section_text = '';
333
        }
334
335
        # XXX Yucky
336
        if ($this_page != 'home' && $this_page != 'contact') {
337
            if ($section_text && $parent_page != 'help_us_out' && $parent_page != 'home' && $this_page != 'campaign') {
338
                print "\t\t\t\t<h1>$section_text";
339
                if ($page_text) {
340
                    print "\n\t\t\t\t<br><span>$page_text</span>\n";
341
                }
342
                print "</h1>\n";
343
            } elseif ($page_text) {
344
                print "\t\t\t\t<h1>$page_text</h1>\n";
345
            }
346
        }
347
348
        // So we don't print the heading twice by accident from $this->stripe_start().
349
        $this->heading_displayed = true;
350
    }
351
352
    public function postcode_form() {
353
        // Used on the mp (and yourmp) pages.
354
        // And the userchangepc page.
355
        global $THEUSER;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
356
357
        echo '<br>';
358
        $this->block_start(array('id'=>'mp', 'title'=>'Find out about your MP/MSPs/MLAs'));
359
        echo '<form action="/postcode/" method="get">';
360
        if ($THEUSER->postcode_is_set()) {
361
            $FORGETURL = new \MySociety\TheyWorkForYou\Url('userchangepc');
362
            $FORGETURL->insert(array('forget'=>'t'));
363
            ?>
364
                        <p>Your current postcode: <strong><?php echo $THEUSER->postcode(); ?></strong> &nbsp; <small>(<a href="<?php echo $FORGETURL->generate(); ?>" title="The cookie storing your postcode will be erased">Forget this postcode</a>)</small></p>
365
<?php
366
        }
367
        ?>
368
                        <p><strong>Enter your UK postcode: </strong>
369
370
                        <input type="text" name="pc" value="<?php echo _htmlentities(get_http_var('pc')); ?>" maxlength="10" size="10"> <input type="submit" value="GO" class="submit"> <small>(e.g. BS3 1QP)</small>
371
                        </p>
372
                        </form>
373
<?php
374
        $this->block_end();
375
    }
376
377
    public function error_message($message, $fatal = false, $status = 500) {
378
        // If $fatal is true, we exit the page right here.
379
        // $message is like the array used in $this->message()
380
        global $page_errors;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
381
382
        // if possible send a 500 error so that google or whatever doesn't
383
        // cache the page. Rely on the fact that an inpage errors will be
384
        // sent after a page_start and hence the headers have been sent
385
        if (!headers_sent()) {
386
            header("HTTP/1.0 $status Internal Server Error");
387
        }
388
389
        if (is_string($message)) {
390
            // Sometimes we're just sending a single line to this function
391
            // rather like the bigger array...
392
            $message = array (
393
                'text' => $message
394
            );
395
        }
396
397
        // if the page has started then we're most likely in an old school page
398
        // so we should just print out the error, otherwise stick it in the error
399
        // global which will then be displayed by the header template
400
        if ( $this->page_started() ) {
401
            $this->message($message, 'error');
402
        } else {
403
            if ( !isset($page_errors) ) {
404
                $page_errors = array();
405
            }
406
            $page_errors[]  = $message;
407
        }
408
409
        if ($fatal) {
410
            if (!$this->page_started()) {
411
                $this->page_start();
412
            }
413
414
            if ($this->within_stripe()) {
415
                $this->stripe_end();
416
            }
417
            $this->page_end();
418
        }
419
420
    }
421
422
423
    public function message($message, $class='') {
424
        // Generates a very simple but common page content.
425
        // Used for when a user logs out, or votes, or any simple thing
426
        // where there's a little message and probably a link elsewhere.
427
        // $message is an array like:
428
        //      'title' => 'You are now logged out'.
0 ignored issues
show
Unused Code Comprehensibility introduced by
43% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
429
        //      'text'  => 'Some more text here',
0 ignored issues
show
Unused Code Comprehensibility introduced by
58% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
430
        //      'linkurl' => 'http://www.easyparliament.org/debates/',
0 ignored issues
show
Unused Code Comprehensibility introduced by
58% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
431
        //      'linktext' => 'Back to previous page'
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
432
        // All fields optional.
433
        // 'linkurl' should already have htmlentities done on it.
434
        // $class is a class name that will be applied to the message's HTML elements.
435
436
        if ($class != '') {
437
            $class = ' class="' . $class . '"';
438
        }
439
440
        $need_to_close_stripe = false;
441
442
        if (!$this->within_stripe()) {
443
            $this->stripe_start();
444
            $need_to_close_stripe = true;
445
        }
446
447
        if (isset($message['title'])) {
448
            ?>
449
            <h3<?php echo $class; ?>><?php echo $message['title']; ?></h3>
450
<?php
451
        }
452
453
        if (isset($message['text'])) {
454
            ?>
455
            <p<?php echo $class; ?>><?php echo $message['text']; ?></p>
456
<?php
457
        }
458
459
        if (isset($message['linkurl']) && isset($message['linktext'])) {
460
            ?>
461
            <p><a href="<?php echo $message['linkurl']; ?>"><?php echo $message['linktext']; ?></a></p>
462
<?php
463
        }
464
465
        if ($need_to_close_stripe) {
466
            $this->stripe_end();
467
        }
468
    }
469
470
    public function informational($text) {
471
        print '<div class="informational left">' . $text . '</div>';
472
    }
473
474
    public function set_hansard_headings($info) {
475
        // Called from HANSARDLIST->display().
476
        // $info is the $data['info'] array passed to the template.
477
        // If the page's HTML hasn't already been started, it sets the page
478
        // headings that will be needed later in the page.
479
480
        global $DATA, $this_page;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
481
482
        if ($this->page_started()) return;
483
        // The page's HTML hasn't been started yet, so we'd better do it.
484
485
        // Set the page title (in the <title></title>).
486
        $page_title = '';
487
488
        if (isset($info['text_heading'])) {
489
            $page_title = $info['text_heading'];
490
        } elseif (isset($info['text'])) {
491
            // Use a truncated version of the page's main item's body text.
492
            // trim_words() is in utility.php. Trim to 40 chars.
493
            $page_title = trim_characters($info['text'], 0, 40);
494
        }
495
496
        if (isset($info['date'])) {
497
            // debatesday and wransday pages.
498
            if ($page_title != '') {
499
                $page_title .= ': ';
500
            }
501
            $page_title .= format_date ($info['date'], SHORTDATEFORMAT);
502
        }
503
504
        if ($page_title != '') {
505
            $DATA->set_page_metadata($this_page, 'title', $page_title);
506
        }
507
508
        if (isset($info['date'])) {
509
            // Set the page heading (displayed on the page).
510
            $page_heading = format_date($info['date'], LONGERDATEFORMAT);
511
            $DATA->set_page_metadata($this_page, 'heading', $page_heading);
512
        }
513
514
    }
515
516
    public function nextprevlinks() {
517
518
        // Generally called from $this->stripe_end();
0 ignored issues
show
Unused Code Comprehensibility introduced by
39% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
519
520
        global $DATA, $this_page;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
521
522
        // We'll put the html in these and print them out at the end of the function...
523
        $prevlink = '';
524
        $uplink = '';
525
        $nextlink = '';
526
527
        // This data is put in the metadata in hansardlist.php
528
        $nextprev = $DATA->page_metadata($this_page, 'nextprev');
529
        // $nextprev will have three arrays: 'prev', 'up' and 'next'.
530
        // Each should have a 'body', 'title' and 'url' element.
531
532
533
        // PREVIOUS ////////////////////////////////////////////////
534
535
        if (isset($nextprev['prev'])) {
536
537
            $prev = $nextprev['prev'];
538
539
            if (isset($prev['url'])) {
540
                $prevlink = '<a href="' . $prev['url'] . '" title="' . $prev['title'] . '" class="linkbutton">&laquo; ' . $prev['body'] . '</a>';
541
542
            } else {
543
                $prevlink = '&laquo; ' . $prev['body'];
544
            }
545
        }
546
547
        if ($prevlink != '') {
548
            $prevlink = '<span class="prev">' . $prevlink . '</span>';
549
        }
550
551
552
        // UP ////////////////////////////////////////////////
553
554
        if (isset($nextprev['up'])) {
555
556
            $uplink = '<span class="up"><a href="' .  $nextprev['up']['url'] . '" title="' . $nextprev['up']['title'] . '">' . $nextprev['up']['body'] . '</a>';
557
            if (get_http_var('s')) {
558
                $URL = new \MySociety\TheyWorkForYou\Url($this_page);
559
                $uplink .= '<br><a href="' . $URL->generate() . '">Remove highlighting</a>';
560
            }
561
            $uplink .= '</span>';
562
        }
563
564
565
        // NEXT ////////////////////////////////////////////////
566
567
        if (isset($nextprev['next'])) {
568
            $next = $nextprev['next'];
569
570
            if (isset($next['url'])) {
571
                $nextlink = '<a href="' .  $next['url'] . '" title="' . $next['title'] . '" class="linkbutton">' . $next['body'] . ' &raquo;</a>';
572
            } else {
573
                $nextlink = $next['body'] . ' &raquo;';
574
            }
575
        }
576
577
        if ($nextlink != '') {
578
            $nextlink = '<span class="next">' . $nextlink . '</span>';
579
        }
580
581
582
        if ($uplink || $prevlink || $nextlink) {
583
            echo "<p class='nextprev'>$nextlink $prevlink $uplink</p><br class='clear'>";
584
        }
585
    }
586
587
588
    public function search_form($value='') {
589
        global $SEARCHENGINE;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
590
        // Search box on the search page.
591
        // If $value is set then it will be displayed in the form.
592
        // Otherwise the value of 's' in the URL will be displayed.
593
594
        $wtt = get_http_var('wtt');
595
596
        $URL = new \MySociety\TheyWorkForYou\Url('search');
597
        $URL->reset(); // no need to pass any query params as a form action. They are not used.
598
599
        if ($value == '') {
600
            if (get_http_var('q') !== '') {
601
                $value = get_http_var('q');
602
            } else {
603
                $value = get_http_var('s');
604
            }
605
        }
606
607
        $person_name = '';
608
        if (preg_match_all('#speaker:(\d+)#', $value, $m) == 1) {
609
            $person_id = $m[1][0];
610
            $member = new MEMBER(array('person_id' => $person_id));
611
            if ($member->valid) {
612
                $value = str_replace("speaker:$person_id", '', $value);
613
                    $person_name = $member->full_name();
614
                }
615
            }
616
617
        echo '<div class="mainsearchbox">';
618
        if ($wtt<2) {
619
                echo '<form action="', $URL->generate(), '" method="get">';
620
                if (get_http_var('o')) {
621
                    echo '<input type="hidden" name="o" value="', _htmlentities(get_http_var('o')), '">';
622
                }
623
                if (get_http_var('house')) {
624
                    echo '<input type="hidden" name="house" value="', _htmlentities(get_http_var('house')), '">';
625
                }
626
                echo '<input type="text" name="q" value="', _htmlentities($value), '" size="50"> ';
627
                echo '<input type="submit" value=" ', ($wtt?'Modify search':'Search'), ' ">';
628
                $URL = new \MySociety\TheyWorkForYou\Url('search');
629
            $URL->insert(array('adv' => 1));
630
                echo '&nbsp;&nbsp; <a href="' . $URL->generate() . '">More&nbsp;options</a>';
631
                echo '<br>';
632
                if ($wtt) print '<input type="hidden" name="wtt" value="1">';
633
        } else { ?>
634
    <form action="http://www.writetothem.com/lords" method="get">
635
    <input type="hidden" name="pid" value="<?=_htmlentities(get_http_var('pid')) ?>">
636
    <input type="submit" style="font-size: 150%" value=" I want to write to this Lord "><br>
637
<?php
638
        }
639
640
        if (!$wtt && ($value || $person_name)) {
641
            echo '<div style="margin-top: 5px">';
642
            $orderUrl = new \MySociety\TheyWorkForYou\Url('search');
643
            $orderUrl->insert(array('s'=>$value)); # Need the parsed value
644
                $ordering = get_http_var('o');
645
                if ($ordering != 'r' && $ordering != 'd' && $ordering != 'p' && $ordering != 'o') {
646
                    $ordering = 'd';
647
                }
648
649
                if ($ordering=='r') {
650
                print '<strong>Sorted by relevance</strong>';
651
                } else {
652
                printf("<a href='%s'>Sort by relevance</a>", $orderUrl->generate('html', array('o'=>'r')));
653
                }
654
655
                print "&nbsp;|&nbsp;";
656
                if ($ordering=='d') {
657
                print '<strong>Sorted by date: newest</strong> / <a href="' . $orderUrl->generate('html', array('o'=>'o')) . '">oldest</a>';
658
                } elseif ($ordering=='o') {
659
                print '<strong>Sorted by date:</strong> <a href="' . $orderUrl->generate('html', array('o'=>'d')) . '">newest</a> / <strong>oldest</strong>';
660
                } else {
661
                printf("Sort by date: <a href='%s'>newest</a> / <a href='%s'>oldest</a>",
662
                    $orderUrl->generate('html', array('o'=>'d')), $orderUrl->generate('html', array('o'=>'o')));
663
                }
664
665
            print "&nbsp;|&nbsp;";
666
            if ($ordering=='p') {
667
                print '<strong>Use by person</strong>';
668
            } else {
669
                printf('<a href="%s">Show use by person</a>', $orderUrl->generate('html', array('o'=>'p')));
670
            }
671
            echo '</div>';
672
673
            if ($person_name) {
674
                ?>
675
                    <p>
676
                    <input type="radio" name="pid" value="<?php echo _htmlentities($person_id) ?>" checked>Search only <?php echo _htmlentities($person_name) ?>
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $person_id does not seem to be defined for all execution paths leading up to this point.
Loading history...
677
                    <input type="radio" name="pid" value="">Search all speeches
678
                    </p>
679
                <?php
680
                }
681
        }
682
683
        echo '</form> </div>';
684
    }
685
686
    public function advanced_search_form() {
687
        include_once INCLUDESPATH . 'easyparliament/templates/html/search_advanced.php';
1 ignored issue
show
Bug introduced by
The constant INCLUDESPATH was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
688
    }
689
690
    public function login_form ($errors = array()) {
691
        // Used for /user/login/ and /user/prompt/
692
        // $errors is a hash of potential errors from a previous log in attempt.
693
        ?>
694
        <form method="post" action="<?php $URL = new \MySociety\TheyWorkForYou\Url('userlogin'); $URL->reset(); echo $URL->generate(); ?>" class="login-form">
695
696
<?php
697
        if (isset($errors["email"])) {
698
            $this->error_message($errors['email']);
699
        }
700
        if (isset($errors["invalidemail"])) {
701
            $this->error_message($errors['invalidemail']);
702
        }
703
?>
704
            <p>
705
                <label for="email">Email address:</label></span>
706
                <input type="text" name="email" id="email" value="<?php echo _htmlentities(get_http_var("email")); ?>" maxlength="100" class="form-control"></span>
707
            </p>
708
709
<?php
710
        if (isset($errors["password"])) {
711
            $this->error_message($errors['password']);
712
        }
713
        if (isset($errors["invalidpassword"])) {
714
            $this->error_message($errors['invalidpassword']);
715
        }
716
?>
717
            <p>
718
                <label for="password">Password:</label>
719
                <input type="password" name="password" id="password" maxlength="30" class="form-control">
720
            </p>
721
722
            <p>
723
                <input type="checkbox" name="remember" id="remember" value="true"<?php
724
        $remember = get_http_var("remember");
725
        if (get_http_var("submitted") != "true" || $remember == "true") {
726
            print " checked";
727
        }
728
        ?>>
729
                <label for="remember">Keep me signed in on this device</label>
730
            </p>
731
732
            <p>
733
                <input type="submit" value="Sign in" class="button">
734
            </p>
735
736
            <input type="hidden" name="submitted" value="true">
737
<?php
738
        // I had to havk about with this a bit to cover glossary login.
739
        // Glossary returl can't be properly formatted until the "add" form
740
        // has been submitted, so we have to do this rubbish:
741
        global $glossary_returl;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
742
        if ((get_http_var("ret") != "") || ($glossary_returl != "")) {
743
            // The return url for after the user has logged in.
744
            if (get_http_var("ret") != "") {
745
                $returl = get_http_var("ret");
746
            }
747
            else {
748
                $returl = $glossary_returl;
749
            }
750
            ?>
751
            <input type="hidden" name="ret" value="<?php echo _htmlentities($returl); ?>">
752
<?php
753
        }
754
        ?>
755
756
            <p>
757
                Forgotten your password?
758
                <a href="<?php
759
                    $URL = new \MySociety\TheyWorkForYou\Url("userpassword");
760
                    $URL->insert(array("email"=>get_http_var("email")));
761
                    echo $URL->generate();
762
                ?>">Set a new one!</a>
763
            </p>
764
765
            <p>
766
                Not yet a member?
767
                <a href="<?php $URL = new \MySociety\TheyWorkForYou\Url("userjoin"); echo $URL->generate(); ?>">Join now!</a>
768
            </p>
769
770
        </form>
771
<?php
772
    }
773
774
    public function mp_search_form($person_id) {
775
        // Search box on the MP page.
776
777
        $URL = new \MySociety\TheyWorkForYou\Url('search');
778
        $URL->remove(array('s', 'q'));
779
        ?>
780
                <div class="mpsearchbox">
781
                    <form action="<?php echo $URL->generate(); ?>" method="get">
782
                    <p>
783
                    <input name="q" size="12">
784
                    <input type="hidden" name="pid" value="<?=$person_id ?>">
785
                    <input type="submit" class="submit" value="GO"></p>
786
                    </form>
787
                </div>
788
<?php
789
    }
790
791
    public function glossary_atoz(&$GLOSSARY) {
792
    // Print out a nice list of lettered links to glossary pages
793
794
        $letters = array ();
795
796
        foreach ($GLOSSARY->alphabet as $letter => $eps) {
797
            // if we're writing out the current letter (list or item)
798
            if ($letter == $GLOSSARY->current_letter) {
799
                // if we're in item view - show the letter as "on" but make it a link
800
                if ($GLOSSARY->current_term != '') {
801
                    $URL = new \MySociety\TheyWorkForYou\Url('glossary');
802
                    $URL->insert(array('az' => $letter));
803
                    $letter_link = $URL->generate('url');
804
805
                    $letters[] = "<li class=\"on\"><a href=\"" . $letter_link . "\">" . $letter . "</a></li>";
806
                }
807
                // otherwise in list view show no link
808
                else {
809
                    $letters[] = "<li class=\"on\">" . $letter . "</li>";
810
                }
811
            }
812
            elseif (!empty($GLOSSARY->alphabet[$letter])) {
813
                $URL = new \MySociety\TheyWorkForYou\Url('glossary');
814
                $URL->insert(array('az' => $letter));
815
                $letter_link = $URL->generate('url');
816
817
                $letters[] = "<li><a href=\"" . $letter_link . "\">" . $letter . "</a></li>";
818
            }
819
            else {
820
                $letters[] = '<li>' . $letter . '</li>';
821
            }
822
        }
823
        ?>
824
                    <div class="letters">
825
                        <ul>
826
    <?php
827
        for ($n=0; $n<13; $n++) {
828
            print $letters[$n];
829
        }
830
        ?>
831
                        </ul>
832
                        <ul>
833
    <?php
834
        for ($n=13; $n<26; $n++) {
835
            print $letters[$n];
836
        }
837
        ?>
838
                        </ul>
839
                    </div>
840
        <?php
841
    }
842
843
    public function glossary_display_term(&$GLOSSARY) {
844
    // Display a single glossary term
845
        global $this_page;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
846
847
        $term = $GLOSSARY->current_term;
848
849
        $term['body'] = $GLOSSARY->glossarise($term['body'], 0, 1);
850
851
        // add some extra controls for the administrators
852
        if ($this_page == "admin_glossary") {
853
            print "<a id=\"gl".$term['glossary_id']."\"></a>";
854
            print "<h3>" . $term['title'] . "</h3>";
855
            $URL = new \MySociety\TheyWorkForYou\Url('admin_glossary');
856
            $URL->insert(array("delete_confirm" => $term['glossary_id']));
857
            $delete_url = $URL->generate();
858
            $admin_links = "<br><small><a href=\"".$delete_url."\">delete</a></small>";
859
        }
860
        else {
861
            $admin_links = "";
862
        }
863
864
        if (isset($term['user_id'])) {
865
            $URL = new \MySociety\TheyWorkForYou\Url('userview');
866
            $URL->insert(array('u' => $term['user_id']));
867
            $user_link = $URL->generate('url');
868
869
            $user_details = "\t\t\t\t<p><small>contributed by user <a href=\"" . $user_link . "\">" . $term['firstname'] . " " . $term['lastname'] . "</a></small>" . $admin_links . "</p>\n";
870
        }
871
        else {
872
            $user_details = "";
873
        }
874
875
        print "\t\t\t\t<p class=\"glossary-body\">" . $term['body'] . "</p>\n" . $user_details;
876
877
        if ($this_page == "glossary_item") {
878
            // Add a direct search link for current glossary item
879
            $URL = new \MySociety\TheyWorkForYou\Url('search');
880
            // remember to quote the term for phrase matching in search
881
            $URL->insert(array('s' => '"'.$term['title'].'"'));
882
            $search_url = $URL->generate();
883
            printf ("\t\t\t\t<p>Search hansard for \"<a href=\"%s\" title=\"View search results for this glossary item\">%s</a>\"</p>", $search_url, $term['title']);
884
        }
885
    }
886
887
    public function glossary_display_match_list(&$GLOSSARY) {
888
            if ($GLOSSARY->num_search_matches > 1) {
889
                $plural = "them";
890
                $definition = "some definitions";
891
            } else {
892
                $plural = "it";
893
                $definition = "a definition";
894
            }
895
            ?>
896
            <h4>Found <?php echo $GLOSSARY->num_search_matches; ?> matches for <em><?php echo $GLOSSARY->query; ?></em></h4>
897
            <p>It seems we already have <?php echo $definition; ?> for that. Would you care to see <?php echo $plural; ?>?</p>
898
            <ul class="glossary"><?php
899
            foreach ($GLOSSARY->search_matches as $match) {
900
                $URL = new \MySociety\TheyWorkForYou\Url('glossary');
901
                $URL->insert(array('gl' => $match['glossary_id']));
902
                $URL->remove(array('g'));
903
                $term_link = $URL->generate('url');
904
                ?><li><a href="<?php echo $term_link ?>"><?php echo $match['title']?></a></li><?php
905
            }
906
            ?></ul>
907
<?php
908
    }
909
910
    public function glossary_link() {
911
        // link to the glossary with no epobject_id - i.e. show all entries
912
        $URL = new \MySociety\TheyWorkForYou\Url('glossary');
913
        $URL->remove(array("g"));
914
        $glossary_link = $URL->generate('url');
915
        print "<small><a href=\"" . $glossary_link . "\">Browse the glossary</a></small>";
916
    }
917
918
    public function glossary_links() {
919
        print "<div>";
920
        $this->glossary_link();
921
        print "</div>";
922
    }
923
924
    public function page_links($pagedata) {
925
        // The next/prev and page links for the search page.
926
        global $this_page;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
927
928
        // $pagedata has...
929
        $total_results      = $pagedata['total_results'];
930
        $results_per_page   = $pagedata['results_per_page'];
931
        $page               = $pagedata['page'];
932
933
        if ($total_results > $results_per_page) {
934
935
            $numpages = ceil($total_results / $results_per_page);
936
937
            $pagelinks = array();
938
939
            // How many links are we going to display on the page - don't want to
940
            // display all of them if we have 100s...
941
            if ($page < 10) {
942
                $firstpage = 1;
943
                $lastpage = 10;
944
            } else {
945
                $firstpage = $page - 10;
946
                $lastpage = $page + 9;
947
            }
948
949
            if ($firstpage < 1) {
950
                $firstpage = 1;
951
            }
952
            if ($lastpage > $numpages) {
953
                $lastpage = $numpages;
954
            }
955
956
            // Generate all the page links.
957
            $URL = new \MySociety\TheyWorkForYou\Url($this_page);
958
            $URL->insert( array('wtt' => get_http_var('wtt')) );
959
            if (isset($pagedata['s'])) {
960
                # XXX: Should be taken out in *one* place, not here + search_form etc.
961
                $value = $pagedata['s'];
962
                if (preg_match_all('#speaker:(\d+)#', $value, $m) == 1) {
963
                    $person_id = $m[1][0];
964
                    $value = str_replace('speaker:' . $person_id, '', $value);
965
                    $URL->insert(array('pid' => $person_id));
966
                    }
967
                $URL->insert(array('s' => $value));
968
            }
969
970
            for ($n = $firstpage; $n <= $lastpage; $n++) {
971
972
                if ($n > 1) {
973
                    $URL->insert(array('p'=>$n));
974
                } else {
975
                    // No page number for the first page.
976
                    $URL->remove(array('p'));
977
                }
978
                if (isset($pagedata['pid'])) {
979
                    $URL->insert(array('pid'=>$pagedata['pid']));
980
                }
981
982
                if ($n != $page) {
983
                    $pagelinks[] = '<a href="' . $URL->generate() . '">' . $n . '</a>';
984
                } else {
985
                    $pagelinks[] = "<strong>$n</strong>";
986
                }
987
            }
988
989
            // Display everything.
990
991
            ?>
992
                <div class="pagelinks">
993
                    Result page:
994
<?php
995
996
            if ($page != 1) {
997
                $prevpage = $page - 1;
998
                $URL->insert(array('p'=>$prevpage));
999
                ?>
1000
                    <big><strong><a href="<?php echo $URL->generate(); ?>"><big>&laquo;</big> Previous</a></strong></big>
1001
<?php
1002
            }
1003
1004
            echo "\t\t\t\t" . implode(' ', $pagelinks);
1005
1006
            if ($page != $numpages) {
1007
                $nextpage = $page + 1;
1008
                $URL->insert(array('p'=>$nextpage));
1009
                ?>
1010
1011
                    <big><strong><a href="<?php echo $URL->generate(); ?>">Next <big>&raquo;</big></a></strong></big> <?php
1012
            }
1013
1014
            ?>
1015
1016
                </div>
1017
<?php
1018
1019
        }
1020
1021
    }
1022
1023
    public function display_commentreport($data) {
1024
        // $data has key value pairs.
1025
        // Called from $COMMENT->display_report().
0 ignored issues
show
Unused Code Comprehensibility introduced by
37% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
1026
1027
        if ($data['user_id'] > 0) {
1028
            $USERURL = new \MySociety\TheyWorkForYou\Url('userview');
1029
            $USERURL->insert(array('id'=>$data['user_id']));
1030
            $username = '<a href="' . $USERURL->generate() . '">' . _htmlentities($data['user_name']) . '</a>';
1031
        } else {
1032
            $username = _htmlentities($data['user_name']);
1033
        }
1034
        ?>
1035
                <div class="comment">
1036
                    <p class="credit"><strong>Annotation report</strong><br>
1037
                    <small>Reported by <?php echo $username; ?> on <?php echo $data['reported']; ?></small></p>
1038
1039
                    <p><?php echo _htmlentities($data['body']); ?></p>
1040
                </div>
1041
<?php
1042
        if ($data['resolved'] != 'NULL') {
1043
            ?>
1044
                <p>&nbsp;<br><em>This report has not been resolved.</em></p>
1045
<?php
1046
        } else {
1047
            ?>
1048
                <p><em>This report was resolved on <?php echo $data['resolved']; ?></em></p>
1049
<?php
1050
            // We could link to the person who resolved it with $data['resolvedby'],
1051
            // a user_id. But we don't have their name at the moment.
1052
        }
1053
1054
    }
1055
1056
1057
    public function display_commentreportlist($data) {
1058
        // For the admin section.
1059
        // Gets an array of data from COMMENTLIST->render().
1060
        // Passes it on to $this->display_table().
1061
1062
        if (count($data) > 0) {
1063
1064
            ?>
1065
            <h3>Reported annotations</h3>
1066
<?php
1067
            // Put the data in an array which we then display using $PAGE->display_table().
1068
            $tabledata['header'] = array(
0 ignored issues
show
Comprehensibility Best Practice introduced by
$tabledata was never initialized. Although not strictly required by PHP, it is generally a good practice to add $tabledata = array(); before regardless.
Loading history...
1069
                'Reported by',
1070
                'Begins...',
1071
                'Reported on',
1072
                ''
1073
            );
1074
1075
            $tabledata['rows'] = array();
1076
1077
            $EDITURL = new \MySociety\TheyWorkForYou\Url('admin_commentreport');
1078
1079
            foreach ($data as $n => $report) {
1080
1081
                if (!$report['locked']) {
1082
                    // Yes, we could probably cope if we just passed the report_id
1083
                    // through, but this isn't a public-facing page and life's
1084
                    // easier if we have the comment_id too.
1085
                    $EDITURL->insert(array(
1086
                        'rid' => $report['report_id'],
1087
                        'cid' => $report['comment_id'],
1088
                    ));
1089
                    $editlink = '<a href="' . $EDITURL->generate() . '">View</a>';
1090
                } else {
1091
                    $editlink = 'Locked';
1092
                }
1093
1094
                $body = trim_characters($report['body'], 0, 40);
1095
1096
                $tabledata['rows'][] = array (
1097
                    _htmlentities($report['firstname'] . ' ' . $report['lastname']),
1098
                    _htmlentities($body),
1099
                    $report['reported'],
1100
                    $editlink
1101
                );
1102
1103
            }
1104
1105
            $this->display_table($tabledata);
1106
1107
        } else {
1108
1109
            print "<p>There are no outstanding annotation reports.</p>\n";
1110
        }
1111
1112
    }
1113
1114
1115
1116
    public function display_calendar_month($month, $year, $dateArray, $page) {
1117
        // From http://www.zend.com/zend/trick/tricks-Oct-2002.php
1118
        // Adjusted for style, putting Monday first, and the URL of the page linked to.
1119
1120
        // Used in templates/html/hansard_calendar.php
1121
1122
        // $month and $year are integers.
1123
        // $dateArray is an array of dates that should be links in this month.
1124
        // $page is the name of the page the dates should link to.
1125
1126
        // Create array containing abbreviations of days of week.
1127
        $daysOfWeek = array('Mon','Tue','Wed','Thu','Fri','Sat','Sun');
1128
1129
        // What is the first day of the month in question?
1130
        $firstDayOfMonth = mktime(0,0,0,$month,1,$year);
1131
1132
        // How many days does this month contain?
1133
        $numberDays = date('t',$firstDayOfMonth);
1134
1135
        // Retrieve some information about the first day of the
1136
        // month in question.
1137
        $dateComponents = getdate($firstDayOfMonth);
1138
1139
        // What is the name of the month in question?
1140
        $monthName = $dateComponents['month'];
1141
1142
        // If this calendar is for this current, real world, month
1143
        // we get the value of today, so we can highlight it.
1144
        $nowDateComponents = getdate();
1145
        if ($nowDateComponents['mon'] == $month && $nowDateComponents['year'] == $year) {
1146
            $toDay = $nowDateComponents['mday'];
1147
        } else {
1148
            $toDay = '';
1149
        }
1150
1151
        // What is the index value (0-6) of the first day of the
1152
        // month in question.
1153
1154
        // Adjusted to cope with the week starting on Monday.
1155
        $dayOfWeek = $dateComponents['wday'] - 1;
1156
1157
        // Adjusted to cope with the week starting on Monday.
1158
        if ($dayOfWeek < 0) {
1159
            $dayOfWeek = 6;
1160
        }
1161
1162
        // Create the table tag opener and day headers
1163
1164
        $calendar  = "\t\t\t\t<div class=\"calendar\">\n";
1165
        $calendar .= "\t\t\t\t<table border=\"0\">\n";
1166
        $calendar .= "\t\t\t\t<caption>$monthName $year</caption>\n";
1167
        $calendar .= "\t\t\t\t<thead>\n\t\t\t\t<tr>";
1168
1169
        // Create the calendar headers
1170
1171
        foreach ($daysOfWeek as $day) {
1172
            $calendar .= "<th>$day</th>";
1173
        }
1174
1175
        // Create the rest of the calendar
1176
1177
        // Initiate the day counter, starting with the 1st.
1178
1179
        $currentDay = 1;
1180
1181
        $calendar .= "</tr>\n\t\t\t\t</thead>\n\t\t\t\t<tbody>\n\t\t\t\t<tr>";
1182
1183
        // The variable $dayOfWeek is used to
1184
        // ensure that the calendar
1185
        // display consists of exactly 7 columns.
1186
1187
        if ($dayOfWeek > 0) {
1188
            $calendar .= "<td colspan=\"$dayOfWeek\">&nbsp;</td>";
1189
        }
1190
1191
        $DAYURL = new \MySociety\TheyWorkForYou\Url($page);
1192
1193
        while ($currentDay <= $numberDays) {
1194
1195
            // Seventh column (Sunday) reached. Start a new row.
1196
1197
            if ($dayOfWeek == 7) {
1198
1199
                $dayOfWeek = 0;
1200
                $calendar .= "</tr>\n\t\t\t\t<tr>";
1201
            }
1202
1203
1204
            // Is this day actually Today in the real world?
1205
            // If so, higlight it.
1206
            if ($currentDay == $toDay) {
1207
                $calendar .= '<td class="on">';
1208
            } else {
1209
                $calendar .= '<td>';
1210
            }
1211
1212
            // Is the $currentDay a member of $dateArray? If so,
1213
            // the day should be linked.
1214
            if (in_array($currentDay,$dateArray)) {
1215
1216
                $date = sprintf("%04d-%02d-%02d", $year, $month, $currentDay);
1217
1218
                $DAYURL->insert(array('d'=>$date));
1219
1220
                $calendar .= "<a href=\"" . $DAYURL->generate() . "\">$currentDay</a></td>";
1221
1222
                // $currentDay is not a member of $dateArray.
1223
1224
            } else {
1225
1226
                $calendar .= "$currentDay</td>";
1227
            }
1228
1229
            // Increment counters
1230
1231
            $currentDay++;
1232
            $dayOfWeek++;
1233
        }
1234
1235
        // Complete the row of the last week in month, if necessary
1236
1237
        if ($dayOfWeek != 7) {
1238
1239
            $remainingDays = 7 - $dayOfWeek;
1240
            $calendar .= "<td colspan=\"$remainingDays\">&nbsp;</td>";
1241
        }
1242
1243
1244
        $calendar .= "</tr>\n\t\t\t\t</tbody>\n\t\t\t\t</table>\n\t\t\t\t</div> <!-- end calendar -->\n\n";
1245
1246
        return $calendar;
1247
1248
    }
1249
1250
1251
    public function display_table($data) {
1252
        /* Pass it data to be displayed in a <table> and it renders it
1253
            with stripes.
1254
1255
        $data is like (for example):
1256
        array (
1257
            'header' => array (
1258
                'ID',
1259
                'name'
1260
            ),
1261
            'rows' => array (
1262
                array (
1263
                    '37',
1264
                    'Guy Fawkes'
1265
                ),
1266
                etc...
1267
            )
1268
        )
1269
        */
1270
1271
        ?>
1272
    <table border="1" cellpadding="3" cellspacing="0" width="90%">
1273
<?php
1274
        if (isset($data['header']) && count($data['header'])) {
1275
            ?>
1276
    <thead>
1277
    <tr><?php
1278
            foreach ($data['header'] as $text) {
1279
                ?><th><?php echo $text; ?></th><?php
1280
            }
1281
            ?></tr>
1282
    </thead>
1283
<?php
1284
        }
1285
1286
        if (isset($data['rows']) && count($data['rows'])) {
1287
            ?>
1288
    <tbody>
1289
<?php
1290
            foreach ($data['rows'] as $row) {
1291
                ?>
1292
    <tr><?php
1293
                foreach ($row as $text) {
1294
                    ?><td><?php echo $text; ?></td><?php
1295
                }
1296
                ?></tr>
1297
<?php
1298
            }
1299
            ?>
1300
    </tbody>
1301
<?php
1302
        }
1303
    ?>
1304
    </table>
1305
<?php
1306
1307
    }
1308
1309
1310
1311
    public function admin_menu() {
1312
        // Returns HTML suitable for putting in the sidebar on Admin pages.
1313
        global $this_page, $DATA;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
1314
1315
        $pages = array ('admin_home',
1316
                'admin_comments','admin_trackbacks', 'admin_searchlogs', 'admin_popularsearches', 'admin_failedsearches',
1317
                'alert_stats', 'admin_statistics', 'admin_reportstats',
1318
                'admin_commentreports', 'admin_glossary', 'admin_glossary_pending', 'admin_badusers',
1319
                'admin_profile_message', 'admin_photos', 'admin_mpurls', 'admin_policies', 'admin_banner', 'admin_featured', 'admin_topics'
1320
                );
1321
1322
        $links = array();
1323
1324
        foreach ($pages as $page) {
1325
            $title = $DATA->page_metadata($page, 'title');
1326
1327
            if ($page != $this_page) {
1328
                $URL = new \MySociety\TheyWorkForYou\Url($page);
1329
                $title = '<a href="' . $URL->generate() . '">' . $title . '</a>';
1330
            } else {
1331
                $title = '<strong>' . $title . '</strong>';
1332
            }
1333
1334
            $links[] = $title;
1335
        }
1336
1337
        $html = "<ul>\n";
1338
1339
        $html .= "<li>" . implode("</li>\n<li>", $links) . "</li>\n";
1340
1341
        $html .= "</ul>\n";
1342
1343
        return $html;
1344
    }
1345
}
1346
1347
$PAGE = new PAGE;
1348