Passed
Pull Request — master (#1700)
by Struan
04:10
created

PAGE::postcode_form()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 23
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
cc 2
eloc 16
c 0
b 0
f 0
nc 2
nop 0
dl 0
loc 23
rs 9.7333
ccs 0
cts 9
cp 0
crap 6
1
<?php
2
3
include_once INCLUDESPATH . '../../commonlib/phplib/gaze.php';
4
include_once INCLUDESPATH . 'easyparliament/member.php';
5
6
class PAGE {
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().
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;
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';
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;
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() . '">' . gettext('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';
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 != '') {
118
    echo ' ' . $extra_class;
119
}
120
?>"<?php
121
        if ($id != '') {
122
            print ' id="' . $id . '"';
123
        }
124
        ?>>
125
            <div class="main">
126
<?php
127
        $this->within_stripe_main = true;
128
        // On most, uncomplicated pages, the first stripe on a page will include
129
        // the page heading. So, if we haven't already printed a heading on this
130
        // page, we do it now...
131
        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...
132
            $this->heading();
133
        }
134
    }
135
136
137
    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

137
    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...
138
        // $contents is an array containing 0 or more hashes.
139
        // Each hash has two values, 'type' and 'content'.
140
        // 'Type' could be one of these:
141
        //  'include' - will include a sidebar named after the value of 'content'.php.
142
        //  'nextprev' - $this->nextprevlinks() is called ('content' currently ignored).
143
        //  'html' - The value of the 'content' is simply displayed.
144
        //  'extrahtml' - The value of the 'content' is displayed after the sidebar has
145
        //                  closed, but within this stripe.
146
147
        // If $contents is empty then '&nbsp;' will be output.
148
149
        /* eg, take this hypothetical array:
150
            $contents = array(
151
                array (
152
                    'type'  => 'include',
153
                    'content'   => 'mp'
154
                ),
155
                array (
156
                    'type'  => 'html',
157
                    'content'   => "<p>This is your MP</p>\n"
158
                ),
159
                array (
160
                    'type'  => 'nextprev'
161
                ),
162
                array (
163
                    'type'  => 'none'
164
                ),
165
                array (
166
                    'extrahtml' => '<a href="blah">Source</a>'
167
                )
168
            );
169
170
            The sidebar div would be opened.
171
            This would first include /includes/easyparliament/templates/sidebars/mp.php.
172
            Then display "<p>This is your MP</p>\n".
173
            Then call $this->nextprevlinks().
174
            The sidebar div would be closed.
175
            '<a href="blah">Source</a>' is displayed.
176
            The stripe div is closed.
177
178
            But in most cases we only have 0 or 1 hashes in $contents.
179
180
        */
181
182
        // $extra is html that will go after the sidebar has closed, but within
183
        // this stripe.
184
        // eg, the 'Source' bit on Hansard pages.
185
        global $DATA, $this_page;
186
187
        $this->within_stripe_main = false;
188
        ?>
189
            </div> <!-- end .main -->
190
            <div class="sidebar">
191
192
        <?php
193
        $this->within_stripe_sidebar = true;
194
        $extrahtml = '';
195
196
        if (count($contents) == 0) {
197
            print "\t\t\t&nbsp;\n";
198
        } else {
199
            #print '<div class="sidebar">';
200
            foreach ($contents as $hash) {
201
                if (isset($hash['type'])) {
202
                    if ($hash['type'] == 'include') {
203
                        $this->include_sidebar_template($hash['content']);
204
205
                    } elseif ($hash['type'] == 'nextprev') {
206
                        $this->nextprevlinks();
207
208
                    } elseif ($hash['type'] == 'html') {
209
                        print $hash['content'];
210
211
                    } elseif ($hash['type'] == 'extrahtml') {
212
                        $extrahtml .= $hash['content'];
213
                    }
214
                }
215
216
            }
217
        }
218
219
        $this->within_stripe_sidebar = false;
220
        ?>
221
            </div> <!-- end .sidebar -->
222
            <div class="break"></div>
223
<?php
224
        if ($extrahtml != '') {
225
            ?>
226
            <div class="extra"><?php echo $extrahtml; ?></div>
227
<?php
228
            }
229
            ?>
230
        </div> <!-- end .stripe-* -->
231
232
<?php
233
    }
234
235
236
237
    public function include_sidebar_template($sidebarname) {
238
        global $this_page, $DATA;
239
240
            $sidebarpath = INCLUDESPATH.'easyparliament/sidebars/'.$sidebarname.'.php';
241
242
            if (file_exists($sidebarpath)) {
243
                include $sidebarpath;
244
            }
245
    }
246
247
248
    public function block_start($data=array()) {
249
        // Starts a 'block' div, used mostly on the home page,
250
        // on the MP page, and in the sidebars.
251
        // $data is a hash like this:
252
        //  'id'    => 'help',
253
        //  'title' => 'What are debates?'
254
        //  'url'   => '/help/#debates'     [if present, will be wrapped round 'title']
255
        //  'body'  => false    [If not present, assumed true. If false, no 'blockbody' div]
256
        // Both items are optional (although it'll look odd without a title).
257
258
        $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...
259
260
        if (isset($data['id']) && $data['id'] != '') {
261
            $id = ' id="' . $data['id'] . '"';
262
        } else {
263
            $id = '';
264
        }
265
266
        $title = isset($data['title']) ? $data['title'] : '';
267
268
        if (isset($data['url'])) {
269
            $title = '<a href="' . $data['url'] . '">' . $title . '</a>';
270
        }
271
        ?>
272
                <div class="block"<?php echo $id; ?>>
273
                    <h4><?php echo $title; ?></h4>
274
<?php
275
        if (!isset($data['body']) || $data['body'] == true) {
276
            ?>
277
                    <div class="blockbody">
278
<?php
279
            $this->blockbody_open = true;
280
            }
281
    }
282
283
    public function block_end() {
284
        if ($this->blockbody_open) {
285
            ?>
286
                    </div>
287
<?php
288
            }
289
            ?>
290
                </div> <!-- end .block -->
291
292
<?php
293
    }
294
295
    public function heading() {
296
        global $this_page, $DATA;
297
298
        // As well as a page's title, we may display that of its parent.
299
        // A page's parent can have a 'title' and a 'heading'.
300
        // The 'title' is always used to create the <title></title>.
301
        // If we have a 'heading' however, we'll use that here, on the page, instead.
302
303
        $parent_page = $DATA->page_metadata($this_page, 'parent');
304
305
        if ($parent_page != '') {
306
            // Not a top-level page, so it has a section heading.
307
            // This is the page title of the parent.
308
            $section_text = $DATA->page_metadata($parent_page, 'title');
309
310
        } else {
311
            // Top level page - no parent, hence no parental title.
312
            $section_text = '';
313
        }
314
315
316
        // A page can have a 'title' and a 'heading'.
317
        // The 'title' is always used to create the <title></title>.
318
        // If we have a 'heading' however, we'll use that here, on the page, instead.
319
320
        $page_text = $DATA->page_metadata($this_page, "heading");
321
322
        if ($page_text == '' && !is_bool($page_text)) {
323
            // If the metadata 'heading' is set, but empty, we display nothing.
324
        } elseif ($page_text == false) {
325
            // But if it just hasn't been set, we use the 'title'.
326
            $page_text = $DATA->page_metadata($this_page, "title");
327
        }
328
329
        if ($page_text == $section_text) {
330
            // We don't want to print both.
331
            $section_text = '';
332
        } elseif (!$page_text && $section_text) {
333
            // Bodge for if we have a section_text but no page_text.
334
            $page_text = $section_text;
335
            $section_text = '';
336
        }
337
338
        # XXX Yucky
339
        if ($this_page != 'home' && $this_page != 'contact') {
340
            if ($section_text && $parent_page != 'help_us_out' && $parent_page != 'home' && $this_page != 'campaign') {
341
                print "\t\t\t\t<h1>$section_text";
342
                if ($page_text) {
343
                    print "\n\t\t\t\t<br><span>$page_text</span>\n";
344
                }
345
                print "</h1>\n";
346
            } elseif ($page_text) {
347
                print "\t\t\t\t<h1>$page_text</h1>\n";
348
            }
349
        }
350
351
        // So we don't print the heading twice by accident from $this->stripe_start().
352
        $this->heading_displayed = true;
353
    }
354
355
    public function postcode_form() {
356
        // Used on the mp (and yourmp) pages.
357
        // And the userchangepc page.
358
        global $THEUSER;
359
360
        echo '<br>';
361
        $this->block_start(array('id'=>'mp', 'title'=>'Find out about your MP/MSPs/MLAs'));
362
        echo '<form action="/postcode/" method="get">';
363
        if ($THEUSER->postcode_is_set()) {
364
            $FORGETURL = new \MySociety\TheyWorkForYou\Url('userchangepc');
365
            $FORGETURL->insert(array('forget'=>'t'));
366
            ?>
367
                        <p><?= gettext('Your current postcode:') ?> <strong><?php echo $THEUSER->postcode(); ?></strong> &nbsp; <small>(<a href="<?php echo $FORGETURL->generate(); ?>" title="<?= gettext('The cookie storing your postcode will be erased') ?>"><?= gettext('Forget this postcode') ?></a>)</small></p>
368
<?php
369
        }
370
        ?>
371
                        <p><strong><?= gettext('Enter your UK postcode:') ?> </strong>
372
373
                        <input type="text" name="pc" value="<?php echo _htmlentities(get_http_var('pc')); ?>" maxlength="10" size="10"> <input type="submit" value="<?= gettext('GO') ?>" class="submit"> <small><?= gettext('(e.g. BS3 1QP)') ?></small>
374
                        </p>
375
                        </form>
376
<?php
377
        $this->block_end();
378
    }
379
380
    public function error_message($message, $fatal = false, $status = 500) {
381
        // If $fatal is true, we exit the page right here.
382
        // $message is like the array used in $this->message()
383
        global $page_errors;
384
385
        // if possible send a 500 error so that google or whatever doesn't
386
        // cache the page. Rely on the fact that an inpage errors will be
387
        // sent after a page_start and hence the headers have been sent
388
        if (!headers_sent()) {
389
            header("HTTP/1.0 $status Internal Server Error");
390
        }
391
392
        if (is_string($message)) {
393
            // Sometimes we're just sending a single line to this function
394
            // rather like the bigger array...
395
            $message = array (
396
                'text' => $message
397
            );
398
        }
399
400
        // if the page has started then we're most likely in an old school page
401
        // so we should just print out the error, otherwise stick it in the error
402
        // global which will then be displayed by the header template
403
        if ( $this->page_started() ) {
404
            $this->message($message, 'error');
405
        } else {
406
            if ( !isset($page_errors) ) {
407
                $page_errors = array();
408
            }
409
            $page_errors[]  = $message;
410
        }
411
412
        if ($fatal) {
413
            if (!$this->page_started()) {
414
                $this->page_start();
415
            }
416
417
            if ($this->within_stripe()) {
418
                $this->stripe_end();
419
            }
420
            $this->page_end();
421
        }
422
423
    }
424
425
426
    public function message($message, $class='') {
427
        // Generates a very simple but common page content.
428
        // Used for when a user logs out, or votes, or any simple thing
429
        // where there's a little message and probably a link elsewhere.
430
        // $message is an array like:
431
        //      'title' => 'You are now logged out'.
432
        //      'text'  => 'Some more text here',
433
        //      'linkurl' => '/debates/',
434
        //      'linktext' => 'Back to previous page'
435
        // All fields optional.
436
        // 'linkurl' should already have htmlentities done on it.
437
        // $class is a class name that will be applied to the message's HTML elements.
438
439
        if ($class != '') {
440
            $class = ' class="' . $class . '"';
441
        }
442
443
        $need_to_close_stripe = false;
444
445
        if (!$this->within_stripe()) {
446
            $this->stripe_start();
447
            $need_to_close_stripe = true;
448
        }
449
450
        if (isset($message['title'])) {
451
            ?>
452
            <h3<?php echo $class; ?>><?php echo $message['title']; ?></h3>
453
<?php
454
        }
455
456
        if (isset($message['text'])) {
457
            ?>
458
            <p<?php echo $class; ?>><?php echo $message['text']; ?></p>
459
<?php
460
        }
461
462
        $linkurl = $message['linkurl'] ?? "";
463
        if (!preg_match('#^/[^/]#', $linkurl)) {
464
            $linkurl = null;
465
        }
466
        if (isset($linkurl) && isset($message['linktext'])) {
467
            ?>
468
            <p><a href="<?php echo _htmlspecialchars($linkurl); ?>"><?php echo _htmlspecialchars($message['linktext']); ?></a></p>
469
<?php
470
        }
471
472
        if ($need_to_close_stripe) {
473
            $this->stripe_end();
474
        }
475
    }
476
477
    public function informational($text) {
478
        print '<div class="informational left">' . $text . '</div>';
479
    }
480
481
    public function set_hansard_headings($info) {
482
        // Called from HANSARDLIST->display().
483
        // $info is the $data['info'] array passed to the template.
484
        // If the page's HTML hasn't already been started, it sets the page
485
        // headings that will be needed later in the page.
486
487
        global $DATA, $this_page;
488
489
        if ($this->page_started()) {
490
            return;
491
        }
492
        // The page's HTML hasn't been started yet, so we'd better do it.
493
494
        // Set the page title (in the <title></title>).
495
        $page_title = '';
496
497
        if (isset($info['text_heading'])) {
498
            $page_title = $info['text_heading'];
499
        } elseif (isset($info['text'])) {
500
            // Use a truncated version of the page's main item's body text.
501
            // trim_words() is in utility.php. Trim to 40 chars.
502
            $page_title = trim_characters($info['text'], 0, 40);
503
        }
504
505
        if ($page_title != '') {
506
            // If page title has been set by now, it is good enough to display
507
            // in the open graph title tag, without the extra date info etc.
508
            $DATA->set_page_metadata($this_page, 'og_title', $page_title);
509
        }
510
511
        if (isset($info['date'])) {
512
            // debatesday and wransday pages.
513
            if ($page_title != '') {
514
                $page_title .= ': ';
515
            }
516
            $page_title .= format_date ($info['date'], SHORTDATEFORMAT);
517
        }
518
519
        if ($page_title != '') {
520
            $DATA->set_page_metadata($this_page, 'title', $page_title);
521
        }
522
523
        if (isset($info['date'])) {
524
            // Set the page heading (displayed on the page).
525
            $page_heading = format_date($info['date'], LONGERDATEFORMAT);
526
            $DATA->set_page_metadata($this_page, 'heading', $page_heading);
527
        }
528
529
    }
530
531
    public function nextprevlinks() {
532
533
        // Generally called from $this->stripe_end();
534
535
        global $DATA, $this_page;
536
537
        // We'll put the html in these and print them out at the end of the function...
538
        $prevlink = '';
539
        $uplink = '';
540
        $nextlink = '';
541
542
        // This data is put in the metadata in hansardlist.php
543
        $nextprev = $DATA->page_metadata($this_page, 'nextprev');
544
        // $nextprev will have three arrays: 'prev', 'up' and 'next'.
545
        // Each should have a 'body', 'title' and 'url' element.
546
547
548
        // PREVIOUS ////////////////////////////////////////////////
549
550
        if (isset($nextprev['prev'])) {
551
552
            $prev = $nextprev['prev'];
553
554
            if (isset($prev['url'])) {
555
                $prevlink = '<a href="' . $prev['url'] . '" title="' . $prev['title'] . '" class="linkbutton">&laquo; ' . $prev['body'] . '</a>';
556
557
            } else {
558
                $prevlink = '&laquo; ' . $prev['body'];
559
            }
560
        }
561
562
        if ($prevlink != '') {
563
            $prevlink = '<span class="prev">' . $prevlink . '</span>';
564
        }
565
566
567
        // UP ////////////////////////////////////////////////
568
569
        if (isset($nextprev['up'])) {
570
571
            $uplink = '<span class="up"><a href="' .  $nextprev['up']['url'] . '" title="' . $nextprev['up']['title'] . '">' . $nextprev['up']['body'] . '</a>';
572
            if (get_http_var('s')) {
573
                $URL = new \MySociety\TheyWorkForYou\Url($this_page);
574
                $uplink .= '<br><a href="' . $URL->generate() . '">' . gettext('Remove highlighting') . '</a>';
575
            }
576
            $uplink .= '</span>';
577
        }
578
579
580
        // NEXT ////////////////////////////////////////////////
581
582
        if (isset($nextprev['next'])) {
583
            $next = $nextprev['next'];
584
585
            if (isset($next['url'])) {
586
                $nextlink = '<a href="' .  $next['url'] . '" title="' . $next['title'] . '" class="linkbutton">' . $next['body'] . ' &raquo;</a>';
587
            } else {
588
                $nextlink = $next['body'] . ' &raquo;';
589
            }
590
        }
591
592
        if ($nextlink != '') {
593
            $nextlink = '<span class="next">' . $nextlink . '</span>';
594
        }
595
596
597
        if ($uplink || $prevlink || $nextlink) {
598
            echo "<p class='nextprev'>$nextlink $prevlink $uplink</p><br class='clear'>";
599
        }
600
    }
601
602
603
    public function search_form($value='') {
604
        global $SEARCHENGINE;
605
        // Search box on the search page.
606
        // If $value is set then it will be displayed in the form.
607
        // Otherwise the value of 's' in the URL will be displayed.
608
609
        $wtt = get_http_var('wtt');
610
611
        $URL = new \MySociety\TheyWorkForYou\Url('search');
612
        $URL->reset(); // no need to pass any query params as a form action. They are not used.
613
614
        if ($value == '') {
615
            if (get_http_var('q') !== '') {
616
                $value = get_http_var('q');
617
            } else {
618
                $value = get_http_var('s');
619
            }
620
        }
621
622
        $person_name = '';
623
        if (preg_match_all('#speaker:(\d+)#', $value, $m) == 1) {
624
            $person_id = $m[1][0];
625
            $member = new MEMBER(array('person_id' => $person_id));
626
            if ($member->valid) {
627
                $value = str_replace("speaker:$person_id", '', $value);
628
                    $person_name = $member->full_name();
629
                }
630
            }
631
632
        echo '<div class="mainsearchbox">';
633
        if ($wtt<2) {
634
                echo '<form action="', $URL->generate(), '" method="get">';
635
                if (get_http_var('o')) {
636
                    echo '<input type="hidden" name="o" value="', _htmlentities(get_http_var('o')), '">';
637
                }
638
                if (get_http_var('house')) {
639
                    echo '<input type="hidden" name="house" value="', _htmlentities(get_http_var('house')), '">';
640
                }
641
                echo '<input type="text" name="q" value="', _htmlentities($value), '" size="50"> ';
642
                echo '<input type="submit" value=" ', ($wtt ? gettext('Modify search') : gettext('Search')), ' ">';
643
                $URL = new \MySociety\TheyWorkForYou\Url('search');
644
            $URL->insert(array('adv' => 1));
645
                echo '&nbsp;&nbsp; <a href="' . $URL->generate() . '">' . gettext('More&nbsp;options') . '</a>';
646
                echo '<br>';
647
                if ($wtt) {
648
                    print '<input type="hidden" name="wtt" value="1">';
649
                }
650
        } else { ?>
651
    <form action="https://www.writetothem.com/lords" method="get">
652
    <input type="hidden" name="pid" value="<?=_htmlentities(get_http_var('pid')) ?>">
653
    <input type="submit" style="font-size: 150%" value=" I want to write to this Lord "><br>
654
<?php
655
        }
656
657
        if (!$wtt && ($value || $person_name)) {
658
            echo '<div style="margin-top: 5px">';
659
            $orderUrl = new \MySociety\TheyWorkForYou\Url('search');
660
            $orderUrl->insert(array('s'=>$value)); # Need the parsed value
661
                $ordering = get_http_var('o');
662
                if ($ordering != 'r' && $ordering != 'd' && $ordering != 'p' && $ordering != 'o') {
663
                    $ordering = 'd';
664
                }
665
666
                if ($ordering=='r') {
667
                print '<strong>' . gettext('Sorted by relevance') . '</strong>';
668
                } else {
669
                printf(gettext("<a href='%s'>Sort by relevance</a>"), $orderUrl->generate('html', array('o'=>'r')));
670
                }
671
672
                print "&nbsp;|&nbsp;";
673
                if ($ordering=='d') {
674
                print '<strong>' . gettext('Sorted by date:') . ' ' . gettext('newest') . '</strong> / <a href="' . $orderUrl->generate('html', array('o'=>'o')) . '">' . gettext('oldest') . '</a>';
675
                } elseif ($ordering=='o') {
676
                print '<strong>' . gettext('Sorted by date:') . '</strong> <a href="' . $orderUrl->generate('html', array('o'=>'d')) . '">' . gettext('newest') . '</a> / <strong>' . gettext('oldest') . '</strong>';
677
                } else {
678
                print gettext("Sort by date:") . ' ';
679
                printf("<a href='%s'>", $orderUrl->generate('html', array('o'=>'d')));
680
                print gettext("newest");
681
                print '</a> / ';
682
                printf("<a href='%s'>", $orderUrl->generate('html', array('o'=>'o')));
683
                print gettext('oldest');
684
                print '</a>';
685
                }
686
687
            print "&nbsp;|&nbsp;";
688
            if ($ordering=='p') {
689
                print '<strong>' . gettext('Use by person') . '</strong>';
690
            } else {
691
                printf('<a href="%s">', $orderUrl->generate('html', array('o'=>'p')));
692
                print gettext('Show use by person') . '</a>';
693
            }
694
            echo '</div>';
695
696
            if ($person_name) {
697
                ?>
698
                    <p>
699
                    <input type="radio" name="pid" value="<?php echo _htmlentities($person_id) ?>" checked><?= sprintf(gettext('Search only %s'), _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...
700
                    <input type="radio" name="pid" value=""><?= gettext('Search all speeches') ?>
701
                    </p>
702
                <?php
703
                }
704
        }
705
706
        echo '</form> </div>';
707
    }
708
709
    public function login_form ($errors = array()) {
710
        // Used for /user/login/ and /user/prompt/
711
        // $errors is a hash of potential errors from a previous log in attempt.
712
        ?>
713
        <form method="post" action="<?php $URL = new \MySociety\TheyWorkForYou\Url('userlogin'); $URL->reset(); echo $URL->generate(); ?>" class="login-form">
714
715
<?php
716
        if (isset($errors["email"])) {
717
            $this->error_message($errors['email']);
718
        }
719
        if (isset($errors["invalidemail"])) {
720
            $this->error_message($errors['invalidemail']);
721
        }
722
?>
723
            <p>
724
                <label for="email"><?= gettext('Email address:') ?></label></span>
725
                <input type="text" name="email" id="email" value="<?php echo _htmlentities(get_http_var("email")); ?>" maxlength="100" class="form-control"></span>
726
            </p>
727
728
<?php
729
        if (isset($errors["password"])) {
730
            $this->error_message($errors['password']);
731
        }
732
        if (isset($errors["invalidpassword"])) {
733
            $this->error_message($errors['invalidpassword']);
734
        }
735
?>
736
            <p>
737
                <label for="password"><?= gettext('Password:') ?></label>
738
                <input type="password" name="password" id="password" maxlength="30" class="form-control">
739
            </p>
740
741
            <p>
742
                <input type="checkbox" name="remember" id="remember" value="true"<?php
743
        $remember = get_http_var("remember");
744
        if (get_http_var("submitted") != "true" || $remember == "true") {
745
            print " checked";
746
        }
747
        ?>>
748
                <label for="remember" class="remember-label"><?= gettext('Keep me signed in on this device') ?></label>
749
            </p>
750
751
            <p>
752
                <input type="submit" value="<?= gettext('Sign in') ?>" class="button">
753
            </p>
754
755
            <input type="hidden" name="submitted" value="true">
756
<?php
757
        // I had to havk about with this a bit to cover glossary login.
758
        // Glossary returl can't be properly formatted until the "add" form
759
        // has been submitted, so we have to do this rubbish:
760
        global $glossary_returl;
761
        if ((get_http_var("ret") != "") || ($glossary_returl != "")) {
762
            // The return url for after the user has logged in.
763
            if (get_http_var("ret") != "") {
764
                $returl = get_http_var("ret");
765
            } else {
766
                $returl = $glossary_returl;
767
            }
768
            ?>
769
            <input type="hidden" name="ret" value="<?php echo _htmlentities($returl); ?>">
770
<?php
771
        }
772
        ?>
773
774
            <p>
775
                <?= gettext('Forgotten your password?') ?>
776
                <a href="<?php
777
                    $URL = new \MySociety\TheyWorkForYou\Url("userpassword");
778
                    $URL->insert(array("email"=>get_http_var("email")));
779
                    echo $URL->generate();
780
                ?>"><?= gettext('Set a new one!') ?></a>
781
            </p>
782
783
            <p>
784
                <?= gettext('Not yet a member?') ?>
785
                <a href="<?php $URL = new \MySociety\TheyWorkForYou\Url("userjoin"); echo $URL->generate(); ?>"><?= gettext('Join now!') ?></a>
786
            </p>
787
788
        </form>
789
<?php
790
    }
791
792
    public function mp_search_form($person_id) {
793
        // Search box on the MP page.
794
795
        $URL = new \MySociety\TheyWorkForYou\Url('search');
796
        $URL->remove(array('s', 'q'));
797
        ?>
798
                <div class="mpsearchbox">
799
                    <form action="<?php echo $URL->generate(); ?>" method="get">
800
                    <p>
801
                    <input name="q" size="12">
802
                    <input type="hidden" name="pid" value="<?=$person_id ?>">
803
                    <input type="submit" class="submit" value="<?= gettext('GO') ?>"></p>
804
                    </form>
805
                </div>
806
<?php
807
    }
808
809
    public function glossary_atoz(&$GLOSSARY) {
810
    // Print out a nice list of lettered links to glossary pages
811
812
        $letters = array ();
813
814
        foreach ($GLOSSARY->alphabet as $letter => $eps) {
815
            // if we're writing out the current letter (list or item)
816
            if ($letter == $GLOSSARY->current_letter) {
817
                // if we're in item view - show the letter as "on" but make it a link
818
                if ($GLOSSARY->current_term != '') {
819
                    $URL = new \MySociety\TheyWorkForYou\Url('glossary');
820
                    $URL->insert(array('az' => $letter));
821
                    $letter_link = $URL->generate('url');
822
823
                    $letters[] = "<li class=\"on\"><a href=\"" . $letter_link . "\">" . $letter . "</a></li>";
824
                }
825
                // otherwise in list view show no link
826
                else {
827
                    $letters[] = "<li class=\"on\">" . $letter . "</li>";
828
                }
829
            } elseif (!empty($GLOSSARY->alphabet[$letter])) {
830
                $URL = new \MySociety\TheyWorkForYou\Url('glossary');
831
                $URL->insert(array('az' => $letter));
832
                $letter_link = $URL->generate('url');
833
834
                $letters[] = "<li><a href=\"" . $letter_link . "\">" . $letter . "</a></li>";
835
            } else {
836
                $letters[] = '<li>' . $letter . '</li>';
837
            }
838
        }
839
        ?>
840
                    <div class="letters">
841
                        <ul>
842
    <?php
843
        for ($n=0; $n<13; $n++) {
844
            print $letters[$n];
845
        }
846
        ?>
847
                        </ul>
848
                        <ul>
849
    <?php
850
        for ($n=13; $n<26; $n++) {
851
            print $letters[$n];
852
        }
853
        ?>
854
                        </ul>
855
                    </div>
856
        <?php
857
    }
858
859
    public function glossary_display_term(&$GLOSSARY) {
860
    // Display a single glossary term
861
        global $this_page;
862
863
        $term = $GLOSSARY->current_term;
864
865
        $term['body'] = $GLOSSARY->glossarise($term['body'], 0, 1);
866
867
        // add some extra controls for the administrators
868
        if ($this_page == "admin_glossary") {
869
            print "<a id=\"gl".$term['glossary_id']."\"></a>";
870
            print "<h3>" . $term['title'] . "</h3>";
871
            $URL = new \MySociety\TheyWorkForYou\Url('admin_glossary');
872
            $URL->insert(array("delete_confirm" => $term['glossary_id']));
873
            $delete_url = $URL->generate();
874
            $admin_links = "<br><small><a href=\"".$delete_url."\">delete</a></small>";
875
        } else {
876
            $admin_links = "";
877
        }
878
879
        if (isset($term['user_id'])) {
880
            $URL = new \MySociety\TheyWorkForYou\Url('userview');
881
            $URL->insert(array('u' => $term['user_id']));
882
            $user_link = $URL->generate('url');
883
884
            $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";
885
        } else {
886
            $user_details = "";
887
        }
888
889
        print "\t\t\t\t<p class=\"glossary-body\">" . $term['body'] . "</p>\n" . $user_details;
890
891
        if ($this_page == "glossary_item") {
892
            // Add a direct search link for current glossary item
893
            $URL = new \MySociety\TheyWorkForYou\Url('search');
894
            // remember to quote the term for phrase matching in search
895
            $URL->insert(array('s' => '"'.$term['title'].'"'));
896
            $search_url = $URL->generate();
897
            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']);
898
        }
899
    }
900
901
    public function glossary_display_match_list(&$GLOSSARY) {
902
            if ($GLOSSARY->num_search_matches > 1) {
903
                $plural = "them";
904
                $definition = "some definitions";
905
            } else {
906
                $plural = "it";
907
                $definition = "a definition";
908
            }
909
            ?>
910
            <h4>Found <?php echo $GLOSSARY->num_search_matches; ?> matches for <em><?php echo $GLOSSARY->query; ?></em></h4>
911
            <p>It seems we already have <?php echo $definition; ?> for that. Would you care to see <?php echo $plural; ?>?</p>
912
            <ul class="glossary"><?php
913
            foreach ($GLOSSARY->search_matches as $match) {
914
                $URL = new \MySociety\TheyWorkForYou\Url('glossary');
915
                $URL->insert(array('gl' => $match['glossary_id']));
916
                $URL->remove(array('g'));
917
                $term_link = $URL->generate('url');
918
                ?><li><a href="<?php echo $term_link ?>"><?php echo $match['title']?></a></li><?php
919
            }
920
            ?></ul>
921
<?php
922
    }
923
924
    public function glossary_link() {
925
        // link to the glossary with no epobject_id - i.e. show all entries
926
        $URL = new \MySociety\TheyWorkForYou\Url('glossary');
927
        $URL->remove(array("g"));
928
        $glossary_link = $URL->generate('url');
929
        print "<small><a href=\"" . $glossary_link . "\">Browse the glossary</a></small>";
930
    }
931
932
    public function glossary_links() {
933
        print "<div>";
934
        $this->glossary_link();
935
        print "</div>";
936
    }
937
938
    public function page_links($pagedata) {
939
        // The next/prev and page links for the search page.
940
        global $this_page;
941
942
        // $pagedata has...
943
        $total_results      = $pagedata['total_results'];
944
        $results_per_page   = $pagedata['results_per_page'];
945
        $page               = $pagedata['page'];
946
947
        if ($total_results > $results_per_page) {
948
949
            $numpages = ceil($total_results / $results_per_page);
950
951
            $pagelinks = array();
952
953
            // How many links are we going to display on the page - don't want to
954
            // display all of them if we have 100s...
955
            if ($page < 10) {
956
                $firstpage = 1;
957
                $lastpage = 10;
958
            } else {
959
                $firstpage = $page - 10;
960
                $lastpage = $page + 9;
961
            }
962
963
            if ($firstpage < 1) {
964
                $firstpage = 1;
965
            }
966
            if ($lastpage > $numpages) {
967
                $lastpage = $numpages;
968
            }
969
970
            // Generate all the page links.
971
            $URL = new \MySociety\TheyWorkForYou\Url($this_page);
972
            $URL->insert( array('wtt' => get_http_var('wtt')) );
973
            if (isset($pagedata['s'])) {
974
                # XXX: Should be taken out in *one* place, not here + search_form etc.
975
                $value = $pagedata['s'];
976
                if (preg_match_all('#speaker:(\d+)#', $value, $m) == 1) {
977
                    $person_id = $m[1][0];
978
                    $value = str_replace('speaker:' . $person_id, '', $value);
979
                    $URL->insert(array('pid' => $person_id));
980
                    }
981
                $URL->insert(array('s' => $value));
982
            }
983
984
            for ($n = $firstpage; $n <= $lastpage; $n++) {
985
986
                if ($n > 1) {
987
                    $URL->insert(array('p'=>$n));
988
                } else {
989
                    // No page number for the first page.
990
                    $URL->remove(array('p'));
991
                }
992
                if (isset($pagedata['pid'])) {
993
                    $URL->insert(array('pid'=>$pagedata['pid']));
994
                }
995
996
                if ($n != $page) {
997
                    $pagelinks[] = '<a href="' . $URL->generate() . '">' . $n . '</a>';
998
                } else {
999
                    $pagelinks[] = "<strong>$n</strong>";
1000
                }
1001
            }
1002
1003
            // Display everything.
1004
1005
            ?>
1006
                <div class="pagelinks">
1007
                    <?= gettext('Result page:') ?>
1008
<?php
1009
1010
            if ($page != 1) {
1011
                $prevpage = $page - 1;
1012
                $URL->insert(array('p'=>$prevpage));
1013
                ?>
1014
                    <big><strong><a href="<?php echo $URL->generate(); ?>"><big>&laquo;</big> <?=gettext('Previous') ?></a></strong></big>
1015
<?php
1016
            }
1017
1018
            echo "\t\t\t\t" . implode(' ', $pagelinks);
1019
1020
            if ($page != $numpages) {
1021
                $nextpage = $page + 1;
1022
                $URL->insert(array('p'=>$nextpage));
1023
                ?>
1024
1025
                    <big><strong><a href="<?php echo $URL->generate(); ?>"><?= gettext('Next') ?> <big>&raquo;</big></a></strong></big> <?php
1026
            }
1027
1028
            ?>
1029
1030
                </div>
1031
<?php
1032
1033
        }
1034
1035
    }
1036
1037
    public function display_commentreport($data) {
1038
        // $data has key value pairs.
1039
        // Called from $COMMENT->display_report().
1040
1041
        if ($data['user_id'] > 0) {
1042
            $USERURL = new \MySociety\TheyWorkForYou\Url('userview');
1043
            $USERURL->insert(array('id'=>$data['user_id']));
1044
            $username = '<a href="' . $USERURL->generate() . '">' . _htmlentities($data['user_name']) . '</a>';
1045
        } else {
1046
            $username = _htmlentities($data['user_name']);
1047
        }
1048
        ?>
1049
                <div class="comment">
1050
                    <p class="credit"><strong>Annotation report</strong><br>
1051
                    <small>Reported by <?php echo $username; ?> on <?php echo $data['reported']; ?></small></p>
1052
1053
                    <p><?php echo _htmlentities($data['body']); ?></p>
1054
                </div>
1055
<?php
1056
        if ($data['resolved'] != 'NULL') {
1057
            ?>
1058
                <p>&nbsp;<br><em>This report has not been resolved.</em></p>
1059
<?php
1060
        } else {
1061
            ?>
1062
                <p><em>This report was resolved on <?php echo $data['resolved']; ?></em></p>
1063
<?php
1064
            // We could link to the person who resolved it with $data['resolvedby'],
1065
            // a user_id. But we don't have their name at the moment.
1066
        }
1067
1068
    }
1069
1070
1071
    public function display_commentreportlist($data) {
1072
        // For the admin section.
1073
        // Gets an array of data from COMMENTLIST->render().
1074
        // Passes it on to $this->display_table().
1075
1076
        if (count($data) > 0) {
1077
1078
            ?>
1079
            <h3>Reported annotations</h3>
1080
<?php
1081
            // Put the data in an array which we then display using $PAGE->display_table().
1082
            $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...
1083
                'Reported by',
1084
                'Begins...',
1085
                'Reported on',
1086
                ''
1087
            );
1088
1089
            $tabledata['rows'] = array();
1090
1091
            $EDITURL = new \MySociety\TheyWorkForYou\Url('admin_commentreport');
1092
1093
            foreach ($data as $n => $report) {
1094
1095
                if (!$report['locked']) {
1096
                    // Yes, we could probably cope if we just passed the report_id
1097
                    // through, but this isn't a public-facing page and life's
1098
                    // easier if we have the comment_id too.
1099
                    $EDITURL->insert(array(
1100
                        'rid' => $report['report_id'],
1101
                        'cid' => $report['comment_id'],
1102
                    ));
1103
                    $editlink = '<a href="' . $EDITURL->generate() . '">View</a>';
1104
                } else {
1105
                    $editlink = 'Locked';
1106
                }
1107
1108
                $body = trim_characters($report['body'], 0, 40);
1109
1110
                $tabledata['rows'][] = array (
1111
                    _htmlentities($report['firstname'] . ' ' . $report['lastname']),
1112
                    _htmlentities($body),
1113
                    $report['reported'],
1114
                    $editlink
1115
                );
1116
1117
            }
1118
1119
            $this->display_table($tabledata);
1120
1121
        } else {
1122
1123
            print "<p>There are no outstanding annotation reports.</p>\n";
1124
        }
1125
1126
    }
1127
1128
    public function display_table($data) {
1129
        /* Pass it data to be displayed in a <table> and it renders it
1130
            with stripes.
1131
1132
        $data is like (for example):
1133
        array (
1134
            'header' => array (
1135
                'ID',
1136
                'name'
1137
            ),
1138
            'rows' => array (
1139
                array (
1140
                    '37',
1141
                    'Guy Fawkes'
1142
                ),
1143
                etc...
1144
            )
1145
        )
1146
        */
1147
1148
        ?>
1149
    <table border="1" cellpadding="3" cellspacing="0" width="90%">
1150
<?php
1151
        if (isset($data['header']) && count($data['header'])) {
1152
            ?>
1153
    <thead>
1154
    <tr><?php
1155
            foreach ($data['header'] as $text) {
1156
                ?><th><?php echo $text; ?></th><?php
1157
            }
1158
            ?></tr>
1159
    </thead>
1160
<?php
1161
        }
1162
1163
        if (isset($data['rows']) && count($data['rows'])) {
1164
            ?>
1165
    <tbody>
1166
<?php
1167
            foreach ($data['rows'] as $row) {
1168
                ?>
1169
    <tr><?php
1170
                foreach ($row as $text) {
1171
                    ?><td><?php echo $text; ?></td><?php
1172
                }
1173
                ?></tr>
1174
<?php
1175
            }
1176
            ?>
1177
    </tbody>
1178
<?php
1179
        }
1180
    ?>
1181
    </table>
1182
<?php
1183
1184
    }
1185
1186
1187
1188
    public function admin_menu() {
1189
        // Returns HTML suitable for putting in the sidebar on Admin pages.
1190
        global $this_page, $DATA;
1191
1192
        $pages = array ('admin_home',
1193
                'admin_comments', 'admin_searchlogs', 'admin_popularsearches', 'admin_failedsearches',
1194
                'alert_stats', 'admin_statistics', 'admin_reportstats',
1195
                'admin_commentreports', 'admin_glossary', 'admin_glossary_pending', 'admin_badusers',
1196
                'admin_profile_message', 'admin_photos', 'admin_mpurls', 'admin_policies', 'admin_banner', 'admin_featured', 'admin_topics',
1197
                'admin_wikipedia',
1198
                );
1199
1200
        $links = array();
1201
1202
        foreach ($pages as $page) {
1203
            $title = $DATA->page_metadata($page, 'title');
1204
1205
            if ($page != $this_page) {
1206
                $URL = new \MySociety\TheyWorkForYou\Url($page);
1207
                $title = '<a href="' . $URL->generate() . '">' . $title . '</a>';
1208
            } else {
1209
                $title = '<strong>' . $title . '</strong>';
1210
            }
1211
1212
            $links[] = $title;
1213
        }
1214
1215
        $html = "<ul>\n";
1216
1217
        $html .= "<li>" . implode("</li>\n<li>", $links) . "</li>\n";
1218
1219
        $html .= "</ul>\n";
1220
1221
        return $html;
1222
    }
1223
}
1224
1225
$PAGE = new PAGE;
1226