Completed
Push — develop ( 987c63...2eecbb )
by John
02:47
created

ActiveRecordController   F

Complexity

Total Complexity 97

Size/Duplication

Total Lines 719
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 17

Importance

Changes 4
Bugs 0 Features 0
Metric Value
wmc 97
c 4
b 0
f 0
lcom 1
cbo 17
dl 0
loc 719
rs 1.263

9 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 10 1
F doGET() 0 118 26
D doPOST() 0 82 11
F doPUT() 0 82 12
D doDELETE() 0 80 12
B after_displayPageHead_callback() 0 27 4
A before_displayPageFoot_callback() 0 17 3
C renderPageLinks() 0 72 14
C renderRecord() 0 60 14

How to fix   Complexity   

Complex Class

Complex classes like ActiveRecordController 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. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

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 ActiveRecordController, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace Alpha\Controller;
4
5
use Alpha\Controller\Front\FrontController;
6
use Alpha\Util\Logging\Logger;
7
use Alpha\Util\Config\ConfigProvider;
8
use Alpha\Util\Http\Request;
9
use Alpha\Util\Http\Response;
10
use Alpha\Util\Helper\Validator;
11
use Alpha\View\View;
12
use Alpha\View\ViewState;
13
use Alpha\Exception\IllegalArguementException;
14
use Alpha\Exception\ResourceNotFoundException;
15
use Alpha\Exception\ResourceNotAllowedException;
16
use Alpha\Exception\SecurityException;
17
use Alpha\Exception\AlphaException;
18
use Alpha\Exception\RecordNotFoundException;
19
use Alpha\Exception\ValidationException;
20
use Alpha\Model\ActiveRecord;
21
22
/**
23
 * The main active record CRUD controller for the framework.
24
 *
25
 * @since 2.0
26
 *
27
 * @author John Collins <[email protected]>
28
 * @license http://www.opensource.org/licenses/bsd-license.php The BSD License
29
 * @copyright Copyright (c) 2017, John Collins (founder of Alpha Framework).
30
 * All rights reserved.
31
 *
32
 * <pre>
33
 * Redistribution and use in source and binary forms, with or
34
 * without modification, are permitted provided that the
35
 * following conditions are met:
36
 *
37
 * * Redistributions of source code must retain the above
38
 *   copyright notice, this list of conditions and the
39
 *   following disclaimer.
40
 * * Redistributions in binary form must reproduce the above
41
 *   copyright notice, this list of conditions and the
42
 *   following disclaimer in the documentation and/or other
43
 *   materials provided with the distribution.
44
 * * Neither the name of the Alpha Framework nor the names
45
 *   of its contributors may be used to endorse or promote
46
 *   products derived from this software without specific
47
 *   prior written permission.
48
 *
49
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
50
 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
51
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
52
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
53
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
54
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
55
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
56
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
57
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
58
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
59
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
60
 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
61
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
62
 * </pre>
63
 */
64
class ActiveRecordController extends Controller implements ControllerInterface
65
{
66
    /**
67
     * The start number for list pageination.
68
     *
69
     * @var int
70
     *
71
     * @since 2.0
72
     */
73
    protected $start = 0;
74
75
    /**
76
     * The amount of records to return during pageination.
77
     *
78
     * @var int
79
     *
80
     * @since 2.0
81
     */
82
    protected $limit;
83
84
    /**
85
     * The count of the records of this type in the database (used during pagination).
86
     *
87
     * @var int
88
     *
89
     * @since 2.0
90
     */
91
    protected $recordCount = 0;
92
93
    /**
94
     * The field name to sort the list by (optional, default is ID).
95
     *
96
     * @var string
97
     *
98
     * @since 2.0
99
     */
100
    protected $sort;
101
102
    /**
103
     * The order to sort the list by (optional, should be ASC or DESC, default is ASC).
104
     *
105
     * @var string
106
     *
107
     * @since 2.0
108
     */
109
    protected $order;
110
111
    /**
112
     * The name of the Record field to filter the list by (optional).
113
     *
114
     * @var string
115
     *
116
     * @since 2.0
117
     */
118
    protected $filterField;
119
120
    /**
121
     * The value of the filterField to filter by (optional).
122
     *
123
     * @var string
124
     *
125
     * @since 2.0
126
     */
127
    protected $filterValue;
128
129
    /**
130
     * Trace logger.
131
     *
132
     * @var \Alpha\Util\Logging\Logger
133
     *
134
     * @since 2.0
135
     */
136
    private static $logger = null;
0 ignored issues
show
Comprehensibility introduced by
Consider using a different property name as you override a private property of the parent class.
Loading history...
137
138
    /**
139
     * Constructor to set up the object.
140
     *
141
     * @param string $visibility The name of the rights group that can access this controller.
142
     *
143
     * @since 1.0
144
     */
145
    public function __construct($visibility = 'Admin')
146
    {
147
        self::$logger = new Logger('ActiveRecordController');
148
        self::$logger->debug('>>__construct()');
149
150
        // ensure that the super class constructor is called, indicating the rights group
151
        parent::__construct($visibility);
152
153
        self::$logger->debug('<<__construct');
154
    }
155
156
    /**
157
     * Handle GET requests.
158
     *
159
     * @param \Alpha\Util\Http\Request $request
160
     *
161
     * @throws \Alpha\Exception\ResourceNotFoundException
162
     * @throws \Alpha\Exception\IllegalArguementException
163
     *
164
     * @return \Alpha\Util\Http\Response
165
     *
166
     * @since 2.0
167
     */
168
    public function doGET($request)
169
    {
170
        self::$logger->debug('>>doGET(request=['.var_export($request, true).'])');
171
172
        $params = $request->getParams();
173
        $accept = $request->getAccept();
174
175
        $body = '';
176
177
        try {
178
            // get a single record
179
            if (isset($params['ActiveRecordType']) && isset($params['ActiveRecordID'])) {
180
                $body .= $this->renderRecord($params, $accept);
181
            } elseif (isset($params['ActiveRecordType']) && isset($params['start'])) {
182
                // list all records of this type
183
                $ActiveRecordType = urldecode($params['ActiveRecordType']);
184
185
                if (class_exists($ActiveRecordType)) {
186
                    $record = new $ActiveRecordType();
187
                } else {
188
                    throw new IllegalArguementException('No ActiveRecord available to view!');
189
                }
190
191
                // set up the title and meta details
192
                if (!isset($this->title)) {
193
                    $this->setTitle('Listing all '.$record->getFriendlyClassName());
194
                }
195
                if (!isset($this->description)) {
196
                    $this->setDescription('Listing all '.$record->getFriendlyClassName());
197
                }
198
                if (!isset($this->keywords)) {
199
                    $this->setKeywords('list,all,'.$record->getFriendlyClassName());
200
                }
201
202
                if (isset($this->filterField) && isset($this->filterValue)) {
203
                    if (isset($this->sort) && isset($this->order)) {
204
                        $records = $record->loadAllByAttribute($this->filterField, $this->filterValue, $params['start'], $params['limit'],
205
                            $this->sort, $this->order);
206
                    } else {
207
                        $records = $record->loadAllByAttribute($this->filterField, $this->filterValue, $params['start'], $params['limit']);
208
                    }
209
210
                    $this->recordCount = $record->getCount(array($this->filterField), array($this->filterValue));
211
                } else {
212
                    if (isset($this->sort) && isset($this->order)) {
213
                        $records = $record->loadAll($params['start'], $params['limit'], $this->sort, $this->order);
214
                    } else {
215
                        $records = $record->loadAll($params['start'], $params['limit']);
216
                    }
217
218
                    $this->recordCount = $record->getCount();
219
                }
220
221
                ActiveRecord::disconnect();
222
223
                $view = View::getInstance($record, false, $accept);
224
225
                $body .= View::displayPageHead($this);
226
227
                $message = $this->getStatusMessage();
228
                if (!empty($message)) {
229
                    $body .= $message;
230
                }
231
232
                $body .= View::renderDeleteForm($this->request->getURI());
233
234
                foreach ($records as $record) {
235
                    $view = View::getInstance($record, false, $accept);
236
                    $fields = array('formAction' => $this->request->getURI());
237
                    $body .= $view->listView($fields);
238
                }
239
240
                if ($accept == 'application/json') {
241
                    $body = rtrim($body, ',');
242
                }
243
            } elseif (isset($params['ActiveRecordType'])) {
244
                // create a new record of this type
245
                $ActiveRecordType = urldecode($params['ActiveRecordType']);
246
247
                if (class_exists($ActiveRecordType)) {
248
                    $record = new $ActiveRecordType();
249
                } else {
250
                    throw new IllegalArguementException('No ActiveRecord available to create!');
251
                }
252
253
                // set up the title and meta details
254
                if (!isset($this->title)) {
255
                    $this->setTitle('Create a new '.$record->getFriendlyClassName());
256
                }
257
                if (!isset($this->description)) {
258
                    $this->setDescription('Create a new '.$record->getFriendlyClassName().'.');
259
                }
260
                if (!isset($this->keywords)) {
261
                    $this->setKeywords('create,new,'.$record->getFriendlyClassName());
262
                }
263
264
                $view = View::getInstance($record, false, $accept);
265
266
                $body .= View::displayPageHead($this);
267
                $fields = array('formAction' => $this->request->getURI());
268
                $body .= $view->createView($fields);
269
            } else {
270
                throw new IllegalArguementException('No ActiveRecord available to display!');
271
            }
272
        } catch (IllegalArguementException $e) {
273
            self::$logger->warn($e->getMessage());
274
            throw new ResourceNotFoundException('The record that you have requested cannot be found!');
275
        } catch (RecordNotFoundException $e) {
276
            self::$logger->warn($e->getMessage());
277
            throw new ResourceNotFoundException('The record that you have requested cannot be found!');
278
        }
279
280
        $body .= View::displayPageFoot($this);
281
282
        self::$logger->debug('<<doGET');
283
284
        return new Response(200, $body, array('Content-Type' => ($accept == 'application/json' ? 'application/json' : 'text/html')));
285
    }
286
287
    /**
288
     * Method to handle POST requests.
289
     *
290
     * @param \Alpha\Util\Http\Request $request
291
     *
292
     * @throws \Alpha\Exception\IllegalArguementException
293
     * @throws \Alpha\Exception\SecurityException
294
     *
295
     * @return \Alpha\Util\Http\Response
296
     *
297
     * @since 2.0
298
     */
299
    public function doPOST($request)
300
    {
301
        self::$logger->debug('>>doDPOST(request=['.var_export($request, true).'])');
302
303
        $config = ConfigProvider::getInstance();
304
305
        $params = $request->getParams();
306
        $accept = $request->getAccept();
307
308
        try {
309
            if (isset($params['ActiveRecordType'])) {
310
                $ActiveRecordType = urldecode($params['ActiveRecordType']);
311
            } else {
312
                throw new IllegalArguementException('No ActiveRecord available to create!');
313
            }
314
315
            if (class_exists($ActiveRecordType)) {
316
                $record = new $ActiveRecordType();
317
            } else {
318
                throw new IllegalArguementException('No ActiveRecord ['.$ActiveRecordType.'] available to create!');
319
            }
320
321
            // check the hidden security fields before accepting the form POST data
322
            if (!$this->checkSecurityFields()) {
323
                throw new SecurityException('This page cannot accept post data from remote servers!');
324
            }
325
326
            $record->populateFromArray($params);
327
328
            try {
329
                $record->save();
330
            } catch (ValidationException $e) {
331
                self::$logger->warn($e->getMessage());
332
                $this->setStatusMessage(View::displayErrorMessage($e->getMessage()));
333
            }
334
335
            self::$logger->action('Created new '.$ActiveRecordType.' instance with ID '.$record->getID());
336
337
            if (isset($params['statusMessage'])) {
338
                $this->setStatusMessage(View::displayUpdateMessage($params['statusMessage']));
339
            } else {
340
                $this->setStatusMessage(View::displayUpdateMessage('Created'));
341
            }
342
343
            ActiveRecord::disconnect();
344
345
            if ($accept == 'application/json') {
346
                $view = View::getInstance($record, false, $accept);
347
                $body = $view->detailedView();
348
                $response = new Response(201);
349
                $response->setHeader('Content-Type', 'application/json');
350
                $response->setHeader('Location', $config->get('app.url').'/record/'.$params['ActiveRecordType'].'/'.$record->getID());
351
                $response->setBody($body);
352
353
                self::$logger->debug('<<doPOST');
354
355
                return $response;
356
            } else {
357
                $response = new Response(301);
358
359
                if ($this->getNextJob() != '') {
360
                    $response->redirect($this->getNextJob());
361
                } else {
362
                    if ($this->request->isSecureURI()) {
363
                        $response->redirect(FrontController::generateSecureURL('act=Alpha\\Controller\\ActiveRecordController&ActiveRecordType='.$ActiveRecordType.'&ActiveRecordID='.$record->getID()));
364
                    } else {
365
                        $response->redirect($config->get('app.url').'/record/'.$params['ActiveRecordType'].'/'.$record->getID());
366
                    }
367
                }
368
369
                self::$logger->debug('<<doPOST');
370
371
                return $response;
372
            }
373
        } catch (SecurityException $e) {
374
            self::$logger->warn($e->getMessage());
375
            throw new ResourceNotAllowedException($e->getMessage());
376
        } catch (IllegalArguementException $e) {
377
            self::$logger->warn($e->getMessage());
378
            throw new ResourceNotFoundException('The record that you have requested cannot be found!');
379
        }
380
    }
381
382
    /**
383
     * Method to handle PUT requests.
384
     *
385
     * @param \Alpha\Util\Http\Request $request
386
     *
387
     * @throws \Alpha\Exception\IllegalArguementException
388
     * @throws \Alpha\Exception\SecurityException
389
     *
390
     * @return \Alpha\Util\Http\Response
391
     *
392
     * @since 2.0
393
     */
394
    public function doPUT($request)
395
    {
396
        self::$logger->debug('>>doPUT(request=['.var_export($request, true).'])');
397
398
        $config = ConfigProvider::getInstance();
399
400
        $params = $request->getParams();
401
        $accept = $request->getAccept();
402
403
        try {
404
            if (isset($params['ActiveRecordType'])) {
405
                $ActiveRecordType = urldecode($params['ActiveRecordType']);
406
            } else {
407
                throw new IllegalArguementException('No ActiveRecord available to edit!');
408
            }
409
410
            if (class_exists($ActiveRecordType)) {
411
                $record = new $ActiveRecordType();
412
            } else {
413
                throw new IllegalArguementException('No ActiveRecord ['.$ActiveRecordType.'] available to edit!');
414
            }
415
416
            // check the hidden security fields before accepting the form POST data
417
            if (!$this->checkSecurityFields()) {
418
                throw new SecurityException('This page cannot accept post data from remote servers!');
419
            }
420
421
            $record->load($params['ActiveRecordID']);
422
            $record->populateFromArray($params);
423
424
            try {
425
                $record->save();
426
            } catch (ValidationException $e) {
427
                self::$logger->warn($e->getMessage());
428
                $this->setStatusMessage(View::displayErrorMessage($e->getMessage()));
429
            }
430
431
            self::$logger->action('Saved '.$ActiveRecordType.' instance with ID '.$record->getID());
432
433
            if (isset($params['statusMessage'])) {
434
                $this->setStatusMessage(View::displayUpdateMessage($params['statusMessage']));
435
            } else {
436
                $this->setStatusMessage(View::displayUpdateMessage('Saved'));
437
            }
438
439
            ActiveRecord::disconnect();
440
441
            if ($accept == 'application/json') {
442
                $view = View::getInstance($record, false, $accept);
443
                $body = $view->detailedView();
444
                $response = new Response(200);
445
                $response->setHeader('Content-Type', 'application/json');
446
                $response->setHeader('Location', $config->get('app.url').'/record/'.$params['ActiveRecordType'].'/'.$record->getID());
447
                $response->setBody($body);
448
            } else {
449
                $response = new Response(301);
450
451
                if ($this->getNextJob() != '') {
452
                    $response->redirect($this->getNextJob());
453
                } else {
454
                    if ($this->request->isSecureURI()) {
455
                        $response->redirect(FrontController::generateSecureURL('act=Alpha\\Controller\\ActiveRecordController&ActiveRecordType='.urldecode($params['ActiveRecordType']).'&ActiveRecordID='.$record->getID().'&view=edit'));
456
                    } else {
457
                        $response->redirect($config->get('app.url').'/record/'.$params['ActiveRecordType'].'/'.$record->getID().'/edit');
458
                    }
459
                }
460
            }
461
462
            self::$logger->debug('<<doPUT');
463
464
            return $response;
465
        } catch (SecurityException $e) {
466
            self::$logger->warn($e->getMessage());
467
            throw new ResourceNotAllowedException($e->getMessage());
468
        } catch (IllegalArguementException $e) {
469
            self::$logger->warn($e->getMessage());
470
            throw new ResourceNotFoundException('The record that you have requested cannot be found!');
471
        } catch (RecordNotFoundException $e) {
472
            self::$logger->warn($e->getMessage());
473
            throw new ResourceNotFoundException('The record that you have requested cannot be found!');
474
        }
475
    }
476
477
    /**
478
     * Method to handle DELETE requests.
479
     *
480
     * @param \Alpha\Util\Http\Request $request
481
     *
482
     * @throws \Alpha\Exception\IllegalArguementException
483
     * @throws \Alpha\Exception\SecurityException
484
     * @throws \Alpha\Exception\ResourceNotAllowedException
485
     *
486
     * @return \Alpha\Util\Http\Response
487
     *
488
     * @since 2.0
489
     */
490
    public function doDELETE($request)
491
    {
492
        self::$logger->debug('>>doDELETE(request=['.var_export($request, true).'])');
493
494
        $config = ConfigProvider::getInstance();
495
496
        $params = $request->getParams();
497
        $accept = $request->getAccept();
498
499
        try {
500
            // check the hidden security fields before accepting the form data
501
            if (!$this->checkSecurityFields()) {
502
                throw new SecurityException('This page cannot accept data from remote servers!');
503
            }
504
505
            if (isset($params['ActiveRecordType'])) {
506
                $ActiveRecordType = urldecode($params['ActiveRecordType']);
507
            } else {
508
                throw new IllegalArguementException('No ActiveRecord available to edit!');
509
            }
510
511
            if (class_exists($ActiveRecordType)) {
512
                $record = new $ActiveRecordType();
513
            } else {
514
                throw new IllegalArguementException('No ActiveRecord ['.$ActiveRecordType.'] available to edit!');
515
            }
516
517
            // check the hidden security fields before accepting the form POST data
518
            if (!$this->checkSecurityFields()) {
519
                throw new SecurityException('This page cannot accept post data from remote servers!');
520
            }
521
522
            $record->load($params['ActiveRecordID']);
523
524
            ActiveRecord::begin();
525
            $record->delete();
526
            ActiveRecord::commit();
527
            ActiveRecord::disconnect();
528
529
            self::$logger->action('Deleted '.$ActiveRecordType.' instance with ID '.$params['ActiveRecordID']);
530
531
            if ($accept == 'application/json') {
532
                $response = new Response(200);
533
                $response->setHeader('Content-Type', 'application/json');
534
                $response->setBody(json_encode(array('message' => 'deleted')));
535
            } else {
536
                $response = new Response(301);
537
538
                if (isset($params['statusMessage'])) {
539
                    $this->setStatusMessage(View::displayUpdateMessage($params['statusMessage']));
540
                } else {
541
                    $this->setStatusMessage(View::displayUpdateMessage('Deleted'));
542
                }
543
544
                if ($this->getNextJob() != '') {
545
                    $response->redirect($this->getNextJob());
546
                } else {
547
                    if ($this->request->isSecureURI()) {
548
                        $response->redirect(FrontController::generateSecureURL('act=Alpha\\Controller\\ActiveRecordController&ActiveRecordType='.$ActiveRecordType.'&start=0&limit='.$config->get('app.list.page.amount')));
549
                    } else {
550
                        $response->redirect($config->get('app.url').'/records/'.$params['ActiveRecordType']);
551
                    }
552
                }
553
            }
554
555
            self::$logger->debug('<<doDELETE');
556
557
            return $response;
558
        } catch (SecurityException $e) {
559
            self::$logger->warn($e->getMessage());
560
            throw new ResourceNotAllowedException($e->getMessage());
561
        } catch (RecordNotFoundException $e) {
562
            self::$logger->warn($e->getMessage());
563
            throw new ResourceNotFoundException('The item that you have requested cannot be found!');
564
        } catch (AlphaException $e) {
565
            self::$logger->error($e->getMessage());
566
            ActiveRecord::rollback();
567
            throw new ResourceNotAllowedException($e->getMessage());
568
        }
569
    }
570
571
    /**
572
     * Sets up the pagination start point and limit.
573
     *
574
     * @since 2.0
575
     */
576
    public function after_displayPageHead_callback()
577
    {
578
        $body = parent::after_displayPageHead_callback();
579
580
        // set the start point for the list pagination
581
        if ($this->request->getParam('start') != null) {
582
            $this->start = $this->request->getParam('start');
0 ignored issues
show
Documentation Bug introduced by
The property $start was declared of type integer, but $this->request->getParam('start') is of type string. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
583
584
            $viewState = ViewState::getInstance();
585
            $viewState->set('selectedStart', $this->start);
586
587
            if ($this->request->getParam('limit') != null) {
588
                $this->limit = $this->request->getParam('limit');
0 ignored issues
show
Documentation Bug introduced by
The property $limit was declared of type integer, but $this->request->getParam('limit') is of type string. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
589
            } else {
590
                $config = ConfigProvider::getInstance();
591
                $this->limit = $config->get('app.list.page.amount');
592
            }
593
594
            $accept = $this->request->getAccept();
595
596
            if ($accept == 'application/json') {
597
                $body .= '[';
598
            }
599
        }
600
601
        return $body;
602
    }
603
604
    /**
605
     * Method to display the page footer with pageination links.
606
     *
607
     * @return string
608
     *
609
     * @since 2.0
610
     */
611
    public function before_displayPageFoot_callback()
612
    {
613
        $body = '';
614
615
        if ($this->request->getParam('start') != null) {
616
            $accept = $this->request->getAccept();
617
618
            if ($accept == 'application/json') {
619
                $body .= ']';
620
            } else {
621
                $body .= $this->renderPageLinks();
622
                $body .= '<br>';
623
            }
624
        }
625
626
        return $body;
627
    }
628
629
    /**
630
     * Method for rendering the pagination links.
631
     *
632
     * @return string
633
     *
634
     * @since 2.0
635
     */
636
    protected function renderPageLinks()
637
    {
638
        $config = ConfigProvider::getInstance();
639
640
        $body = '';
641
642
        // the index of the last record displayed on this page
643
        $last = $this->start+$config->get('app.list.page.amount');
644
645
        // ensure that the last index never overruns the total record count
646
        if ($last > $this->recordCount) {
647
            $last = $this->recordCount;
648
        }
649
650
        // render a message for an empty list
651
        if ($this->recordCount > 0) {
652
            $body .= '<ul class="pagination">';
653
        } else {
654
            $body .= '<p align="center">The list is empty.&nbsp;&nbsp;</p>';
655
656
            return $body;
657
        }
658
659
        // render "Previous" link
660
        if ($this->start > 0) {
661
            // handle secure URLs
662
            if ($this->request->getParam('token', null) != null) {
663
                $body .= '<li><a href="'.FrontController::generateSecureURL('act=Alpha\Controller\ActiveRecordController&ActiveRecordType='.$this->request->getParam('ActiveRecordType').'&start='.($this->start-$this->limit).'&limit='.$this->limit).'">&lt;&lt;-Previous</a></li>';
664
            } else {
665
                $body .= '<li><a href="/records/'.urlencode($this->request->getParam('ActiveRecordType')).'/'.($this->start-$this->limit).'/'.$this->limit.'">&lt;&lt;-Previous</a></li>';
666
            }
667
        } elseif ($this->recordCount > $this->limit) {
668
            $body .= '<li class="disabled"><a href="#">&lt;&lt;-Previous</a></li>';
669
        }
670
671
        // render the page index links
672
        if ($this->recordCount > $this->limit) {
673
            $page = 1;
674
675
            for ($i = 0; $i < $this->recordCount; $i += $this->limit) {
676
                if ($i != $this->start) {
677
                    // handle secure URLs
678
                    if ($this->request->getParam('token', null) != null) {
679
                        $body .= '<li><a href="'.FrontController::generateSecureURL('act=Alpha\Controller\ActiveRecordController&ActiveRecordType='.$this->request->getParam('ActiveRecordType').'&start='.$i.'&limit='.$this->limit).'">'.$page.'</a></li>';
680
                    } else {
681
                        $body .= '<li><a href="/records/'.urlencode($this->request->getParam('ActiveRecordType')).'/'.$i.'/'.$this->limit.'">'.$page.'</a></li>';
682
                    }
683
                } elseif ($this->recordCount > $this->limit) { // render an anchor for the current page
684
                    $body .= '<li class="active"><a href="#">'.$page.'</a></li>';
685
                }
686
687
                ++$page;
688
            }
689
        }
690
691
        // render "Next" link
692
        if ($this->recordCount > $last) {
693
            // handle secure URLs
694
            if ($this->request->getParam('token', null) != null) {
695
                $body .= '<li><a href="'.FrontController::generateSecureURL('act=Alpha\Controller\ActiveRecordController&ActiveRecordType='.$this->request->getParam('ActiveRecordType').'&start='.($this->start+$this->limit).'&limit='.$this->limit).'">Next-&gt;&gt;</a></li>';
696
            } else {
697
                $body .= '<li><a href="/records/'.urlencode($this->request->getParam('ActiveRecordType')).'/'.($this->start+$this->limit.'/'.$this->limit).
698
                    '">Next-&gt;&gt;</a></li>';
699
            }
700
        } elseif ($this->recordCount > $this->limit) {
701
            $body .= '<li class="disabled"><a href="#">Next-&gt;&gt;</a></li>';
702
        }
703
704
        $body .= '</ul>';
705
706
        return $body;
707
    }
708
709
    /**
710
     * Load the requested record and render the HTML or JSON for it.
711
     *
712
     * @param array $params The request params
713
     * @param string $accept The HTTP accept heard value
714
     *
715
     * @throws \Alpha\Exception\ResourceNotFoundException
716
     * @throws \Alpha\Exception\IllegalArguementException
717
     *
718
     * @return string The display data for the requested record
719
     *
720
     * @since 3.0
721
     */
722
    private function renderRecord($params, $accept)
723
    {
724
        if (!Validator::isInteger($params['ActiveRecordID'])) {
725
            throw new IllegalArguementException('Invalid oid ['.$params['ActiveRecordID'].'] provided on the request!');
726
        }
727
728
        $ActiveRecordType = urldecode($params['ActiveRecordType']);
729
730
        if (class_exists($ActiveRecordType)) {
731
            $record = new $ActiveRecordType();
732
        } else {
733
            throw new IllegalArguementException('No ActiveRecord available to view!');
734
        }
735
736
        // set up the title and meta details
737
        if (isset($params['view']) && $params['view'] == 'edit') {
738
            if (!isset($this->title)) {
739
                $this->setTitle('Editing a '.$record->getFriendlyClassName());
740
            }
741
            if (!isset($this->description)) {
742
                $this->setDescription('Page to edit a '.$record->getFriendlyClassName().'.');
743
            }
744
            if (!isset($this->keywords)) {
745
                $this->setKeywords('edit,'.$record->getFriendlyClassName());
746
            }
747
        } else {
748
            if (!isset($this->title)) {
749
                $this->setTitle('Viewing a '.$record->getFriendlyClassName());
750
            }
751
            if (!isset($this->description)) {
752
                $this->setDescription('Page to view a '.$record->getFriendlyClassName().'.');
753
            }
754
            if (!isset($this->keywords)) {
755
                $this->setKeywords('view,'.$record->getFriendlyClassName());
756
            }
757
        }
758
759
        $record->load($params['ActiveRecordID']);
760
        ActiveRecord::disconnect();
761
762
        $view = View::getInstance($record, false, $accept);
763
764
        $body = View::displayPageHead($this);
765
766
        $message = $this->getStatusMessage();
767
        if (!empty($message)) {
768
            $body .= $message;
769
        }
770
771
        $body .= View::renderDeleteForm($this->request->getURI());
772
773
        if (isset($params['view']) && $params['view'] == 'edit') {
774
            $fields = array('formAction' => $this->request->getURI());
775
            $body .= $view->editView($fields);
776
        } else {
777
            $body .= $view->detailedView();
778
        }
779
780
        return $body;
781
    }
782
}
783