Completed
Pull Request — develop (#295)
by John
04:45
created

Controller::doTRACE()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 21
Code Lines 12

Duplication

Lines 21
Ratio 100 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 21
loc 21
rs 9.3142
cc 3
eloc 12
nc 3
nop 1
1
<?php
2
3
namespace Alpha\Controller;
4
5
use Alpha\Model\Type\Timestamp;
6
use Alpha\Model\Type\Integer;
7
use Alpha\Model\ActiveRecord;
8
use Alpha\Util\Config\ConfigProvider;
9
use Alpha\Util\Security\SecurityUtils;
10
use Alpha\Util\Helper\Validator;
11
use Alpha\Util\Http\Session\SessionProviderFactory;
12
use Alpha\Util\Http\Request;
13
use Alpha\Util\Http\Response;
14
use Alpha\Util\Logging\Logger;
15
use Alpha\Exception\IllegalArguementException;
16
use Alpha\Exception\FailedUnitCommitException;
17
use Alpha\Exception\FailedSaveException;
18
use Alpha\Exception\LockingException;
19
use Alpha\Exception\AlphaException;
20
use Alpha\Exception\NotImplementedException;
21
use Alpha\View\View;
22
use Alpha\View\ViewState;
23
use ReflectionClass;
24
use Exception;
25
26
/**
27
 * The master controller class for the Alpha Framework.
28
 *
29
 * @since 1.0
30
 *
31
 * @author John Collins <[email protected]>
32
 * @license http://www.opensource.org/licenses/bsd-license.php The BSD License
33
 * @copyright Copyright (c) 2016, John Collins (founder of Alpha Framework).
34
 * All rights reserved.
35
 *
36
 * <pre>
37
 * Redistribution and use in source and binary forms, with or
38
 * without modification, are permitted provided that the
39
 * following conditions are met:
40
 *
41
 * * Redistributions of source code must retain the above
42
 *   copyright notice, this list of conditions and the
43
 *   following disclaimer.
44
 * * Redistributions in binary form must reproduce the above
45
 *   copyright notice, this list of conditions and the
46
 *   following disclaimer in the documentation and/or other
47
 *   materials provided with the distribution.
48
 * * Neither the name of the Alpha Framework nor the names
49
 *   of its contributors may be used to endorse or promote
50
 *   products derived from this software without specific
51
 *   prior written permission.
52
 *
53
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
54
 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
55
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
56
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
57
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
58
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
59
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
60
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
61
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
62
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
63
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
64
 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
65
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
66
 * </pre>
67
 */
68
abstract class Controller
69
{
70
    /**
71
     * The name of the controller.
72
     *
73
     * @var string
74
     *
75
     * @since 1.0
76
     */
77
    protected $name;
78
79
    /**
80
     * Used to set access privileages for the controller to the name of the rights group
81
     * allowed to access it.  'Public' by default.
82
     *
83
     * @var string
84
     *
85
     * @since 1.0
86
     */
87
    protected $visibility = 'Public';
88
89
    /**
90
     * Optionally, the main record object that this controller is currently working with.
91
     *
92
     * @var Alpha\Model\ActiveRecord
93
     *
94
     * @since 1.0
95
     */
96
    protected $record = null;
97
98
    /**
99
     * Used to determine if the controller is part of a unit of work sequence
100
     * (either empty or the name of the unit).
101
     *
102
     * @var string
103
     *
104
     * @since 1.0
105
     */
106
    protected $unitOfWork;
107
108
    /**
109
     * Stores the start time of a unit of work transaction.
110
     *
111
     * @var Alpha\Model\Type\Timestamp
112
     *
113
     * @since 1.0
114
     */
115
    protected $unitStartTime;
116
117
    /**
118
     * Stores the end time of a unit of work transaction.
119
     *
120
     * @var Alpha\Model\Type\Timestamp
121
     *
122
     * @since 1.0
123
     */
124
    protected $unitEndTime;
125
126
    /**
127
     * Stores the maximum allowed time duration (in seconds) of the unit of work.
128
     *
129
     * @var Alpha\Model\Type\Integer
130
     *
131
     * @since 1.0
132
     */
133
    protected $unitMAXDuration;
134
135
    /**
136
     * The name of the first controller that is used in this unit of work.
137
     *
138
     * @var string
139
     *
140
     * @since 1.0
141
     */
142
    protected $firstJob;
143
144
    /**
145
     * The name of the next controller that is used in this unit of work.
146
     *
147
     * @var string
148
     *
149
     * @since 1.0
150
     */
151
    protected $nextJob;
152
153
    /**
154
     * The name of the previous controller that is used in this unit of work.
155
     *
156
     * @var string
157
     *
158
     * @since 1.0
159
     */
160
    protected $previousJob;
161
162
    /**
163
     * The name of the last controller that is used in this unit of work.
164
     *
165
     * @var string
166
     *
167
     * @since 1.0
168
     */
169
    protected $lastJob;
170
171
    /**
172
     * An array for storing dirty record objects in a session (i.e. persistent business
173
     * objects that have not been updated in the database yet).
174
     *
175
     * @var array
176
     *
177
     * @since 1.0
178
     */
179
    protected $dirtyObjects = array();
180
181
    /**
182
     * An array for storing new reord objects in a session (transient business objects that
183
     * have no OID yet).
184
     *
185
     * @var array
186
     *
187
     * @since 1.0
188
     */
189
    protected $newObjects = array();
190
191
    /**
192
     * The title to be displayed on the controller page.
193
     *
194
     * @var string
195
     *
196
     * @since 1.0
197
     */
198
    protected $title;
199
200
    /**
201
     * Meta keywords for the controller page, generally populated from tags.
202
     *
203
     * @var string
204
     *
205
     * @since 1.0
206
     */
207
    protected $keywords;
208
209
    /**
210
     * Meta description for the controller page.
211
     *
212
     * @var string
213
     *
214
     * @since 1.0
215
     */
216
    protected $description;
217
218
    /**
219
     * Used to set status update messages to display to the user (messages stored between requests
220
     * in session).  Useful for when you want to display a message to a user after POSTing a request,
221
     * or when moving from one page to the next.
222
     *
223
     * @var string
224
     *
225
     * @since 1.0
226
     */
227
    protected $statusMessage;
228
229
    /**
230
     * The request that has been passed to this controller for processing.
231
     *
232
     * @var Alpha\Util\Http\Request
233
     *
234
     * @since 2.0
235
     */
236
    protected $request;
237
238
    /**
239
     * Trace logger.
240
     *
241
     * @var Alpha\Util\Logging\Logger
242
     *
243
     * @since 1.0
244
     */
245
    private static $logger = null;
246
247
    /**
248
     * Constructor for the Controller that starts a new session if required, and handles
249
     * the population of new/dirty objects from the session when available.  Accepts the name
250
     * of the rights group that has access to this controller, 'Public' by default.
251
     *
252
     * @param string $visibility The name of the rights group that can access this controller.
253
     *
254
     * @since 1.0
255
     */
256
    public function __construct($visibility = 'Public')
257
    {
258
        self::$logger = new Logger('Controller');
0 ignored issues
show
Documentation Bug introduced by
It seems like new \Alpha\Util\Logging\Logger('Controller') of type object<Alpha\Util\Logging\Logger> is incompatible with the declared type object<Alpha\Controller\...ha\Util\Logging\Logger> of property $logger.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
259
        self::$logger->debug('>>__construct(visibility=['.$visibility.'])');
260
261
        $config = ConfigProvider::getInstance();
262
263
        // set the access rights to the group name indicated
264
        $this->visibility = $visibility;
265
266
        $this->unitStartTime = new Timestamp(date('Y-m-d H:i:s'));
0 ignored issues
show
Documentation Bug introduced by
It seems like new \Alpha\Model\Type\Ti...mp(date('Y-m-d H:i:s')) of type object<Alpha\Model\Type\Timestamp> is incompatible with the declared type object<Alpha\Controller\...a\Model\Type\Timestamp> of property $unitStartTime.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
267
        $this->unitEndTime = new Timestamp();
0 ignored issues
show
Documentation Bug introduced by
It seems like new \Alpha\Model\Type\Timestamp() of type object<Alpha\Model\Type\Timestamp> is incompatible with the declared type object<Alpha\Controller\...a\Model\Type\Timestamp> of property $unitEndTime.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
268
        $this->unitMAXDuration = new Integer();
0 ignored issues
show
Documentation Bug introduced by
It seems like new \Alpha\Model\Type\Integer() of type object<Alpha\Model\Type\Integer> is incompatible with the declared type object<Alpha\Controller\Alpha\Model\Type\Integer> of property $unitMAXDuration.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
269
270
        // uses controller class name as the job name
271
        if ($this->name == '') {
272
            $this->setName(get_class($this));
273
        }
274
275
        $sessionProvider = $config->get('session.provider.name');
276
        $session = SessionProviderFactory::getInstance($sessionProvider);
277
278
        if ($session->get('unitOfWork') !== false && is_array($session->get('unitOfWork'))) {
279
            $this->setUnitOfWork($session->get('unitOfWork'));
280
        }
281
282
        if ($session->get('dirtyObjects') !== false && is_array($session->get('dirtyObjects'))) {
283
            $this->dirtyObjects = $session->get('dirtyObjects');
284
        }
285
286
        if ($session->get('newObjects') && is_array($session->get('newObjects'))) {
287
            $this->newObjects = $session->get('newObjects');
288
        }
289
290
        if ($session->get('statusMessage') !== false) {
291
            $this->setStatusMessage($session->get('statusMessage'));
292
        }
293
294
        self::$logger->debug('<<__construct');
295
    }
296
297
    /**
298
     * Get the record for this controller (if any).
299
     *
300
     * @return mixed
301
     *
302
     * @since 1.0
303
     */
304
    public function getRecord()
305
    {
306
        self::$logger->debug('>>getRecord()');
307
        self::$logger->debug('<<getRecord ['.var_export($this->record, true).']');
308
309
        return $this->record;
310
    }
311
312
    /**
313
     * Setter for the record for this controller.
314
     *
315
     * @param Alpha\Model\ActiveRecord $record
316
     *
317
     * @since 1.0
318
     */
319
    public function setRecord($record)
320
    {
321
        self::$logger->debug('>>setRecord(record=['.var_export($record, true).'])');
322
        $this->record = $record;
323
324
        // if the record has tags, use these as the meta keywords for this controller
325
        if ($this->record->isTagged()) {
326
            $tags = $this->record->getPropObject('tags')->getRelatedObjects();
327
328
            $keywords = '';
329
330
            if (count($tags) > 0) {
331
                foreach ($tags as $tag) {
332
                    $keywords .= ','.$tag->get('content');
333
                }
334
            }
335
336
            $this->setKeywords(mb_substr($keywords, 1));
337
        }
338
339
        self::$logger->debug('<<setRecord');
340
    }
341
342
    /**
343
     * Get the name of the unit of work job.
344
     *
345
     * @return string
346
     *
347
     * @since 1.0
348
     */
349 View Code Duplication
    public function getName()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
350
    {
351
        self::$logger->debug('>>getName()');
352
        self::$logger->debug('<<getName ['.$this->name.']');
353
354
        return $this->name;
355
    }
356
357
    /**
358
     * Setter for the unit of work job name.
359
     *
360
     * @param string $name The fully-qualified controller class name, or an absolute URL.
361
     *
362
     * @since 1.0
363
     */
364
    public function setName($name)
365
    {
366
        self::$logger->debug('>>setName(name=['.$name.'])');
367
        $this->name = $name;
368
        self::$logger->debug('<<setName');
369
    }
370
371
    /**
372
     * Get the name of the rights group that has access to this controller.
373
     *
374
     * @return string
375
     *
376
     * @since 1.0
377
     */
378 View Code Duplication
    public function getVisibility()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
379
    {
380
        self::$logger->debug('>>getVisibility()');
381
        self::$logger->debug('<<getVisibility ['.$this->visibility.']');
382
383
        return $this->visibility;
384
    }
385
386
    /**
387
     * Setter for the name of the rights group that has access to this controller.
388
     *
389
     * @param string $visibility
390
     *
391
     * @since 1.0
392
     */
393
    public function setVisibility($visibility)
394
    {
395
        self::$logger->debug('>>setVisibility(visibility=['.$visibility.'])');
396
        $this->visibility = $visibility;
397
        self::$logger->debug('<<setVisibility');
398
    }
399
400
    /**
401
     * Gets the name of the first job in this unit of work.
402
     *
403
     * @return string The fully-qualified controller class name, or an absolute URL.
404
     *
405
     * @since 1.0
406
     */
407 View Code Duplication
    public function getFirstJob()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
408
    {
409
        self::$logger->debug('>>getFirstJob()');
410
        self::$logger->debug('<<getFirstJob ['.$this->firstJob.']');
411
412
        return $this->firstJob;
413
    }
414
415
    /**
416
     * Gets the name of the next job in this unit of work.
417
     *
418
     * @return string The fully-qualified controller class name, or an absolute URL.
419
     *
420
     * @since 1.0
421
     */
422 View Code Duplication
    public function getNextJob()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
423
    {
424
        self::$logger->debug('>>getNextJob()');
425
        self::$logger->debug('<<getNextJob ['.$this->nextJob.']');
426
427
        return $this->nextJob;
428
    }
429
430
    /**
431
     * Gets the name of the previous job in this unit of work.
432
     *
433
     * @return string The fully-qualified controller class name, or an absolute URL.
434
     *
435
     * @since 1.0
436
     */
437 View Code Duplication
    public function getPreviousJob()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
438
    {
439
        self::$logger->debug('>>getPreviousJob()');
440
        self::$logger->debug('<<getPreviousJob ['.$this->previousJob.']');
441
442
        return $this->previousJob;
443
    }
444
445
    /**
446
     * Gets the name of the last job in this unit of work.
447
     *
448
     * @return string The fully-qualified controller class name, or an absolute URL.
449
     *
450
     * @since 1.0
451
     */
452 View Code Duplication
    public function getLastJob()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
453
    {
454
        self::$logger->debug('>>getLastJob()');
455
        self::$logger->debug('<<getLastJob ['.$this->lastJob.']');
456
457
        return $this->lastJob;
458
    }
459
460
    /**
461
     * Sets the name of the controller job sequence to the values in the supplied
462
     * array (and stores the array in the session).
463
     *
464
     * @param array $jobs The names of the controllers in this unit of work sequence.  Will accept fully-qualified controller class name, or an absolute URL.
465
     *
466
     * @throws Alpha\Exception\IllegalArguementException
467
     *
468
     * @since 1.0
469
     */
470
    public function setUnitOfWork($jobs)
471
    {
472
        self::$logger->debug('>>setUnitOfWork(jobs=['.var_export($jobs, true).'])');
473
474
        if (method_exists($this, 'before_setUnitOfWork_callback')) {
475
            $this->before_setUnitOfWork_callback();
0 ignored issues
show
Bug introduced by
The method before_setUnitOfWork_callback() does not exist on Alpha\Controller\Controller. Did you maybe mean setUnitOfWork()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
476
        }
477
478
        if (!is_array($jobs)) {
479
            throw new IllegalArguementException('Bad $jobs array ['.var_export($jobs, true).'] passed to setUnitOfWork method!');
480
            self::$logger->debug('<<setUnitOfWork');
0 ignored issues
show
Unused Code introduced by
self::$logger->debug('<<setUnitOfWork'); does not seem to be reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
481
482
            return;
483
        }
484
485
        // validate that each controller name in the array actually exists
486
        foreach ($jobs as $job) {
487
            if (!Validator::isURL($job) && !class_exists($job)) {
488
                throw new IllegalArguementException('The controller name ['.$job.'] provided in the jobs array is not defined anywhere!');
489
            }
490
        }
491
492
        // clear out any previous unit of work from the session
493
        $config = ConfigProvider::getInstance();
494
        $sessionProvider = $config->get('session.provider.name');
495
        $session = SessionProviderFactory::getInstance($sessionProvider);
496
        $session->delete('unitOfWork');
497
        $this->firstJob = null;
498
        $this->previousJob = null;
499
        $this->nextJob = null;
500
        $this->lastJob = null;
501
        $this->dirtyObjects = array();
502
        $this->newObjects = array();
503
504
        $numOfJobs = count($jobs);
505
506
        for ($i = 0; $i < $numOfJobs; ++$i) {
507
            // the first job in the sequence
508
            if ($i == 0) {
509
                $this->firstJob = $jobs[$i];
510
                self::$logger->debug('First job ['.$this->firstJob.']');
511
            }
512
            // found the current job
513
            if ($this->name == $jobs[$i]) {
514 View Code Duplication
                if (isset($jobs[$i - 1])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
515
                    // set the previous job if it exists
516
                    $this->previousJob = $jobs[$i - 1];
517
                    self::$logger->debug('Previous job ['.$this->previousJob.']');
518
                }
519 View Code Duplication
                if (isset($jobs[$i + 1])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
520
                    // set the next job if it exists
521
                    $this->nextJob = $jobs[$i + 1];
522
                    self::$logger->debug('Next job ['.$this->nextJob.']');
523
                }
524
            }
525
            // the last job in the sequence
526
            if ($i == ($numOfJobs - 1)) {
527
                $this->lastJob = $jobs[$i];
528
            }
529
        }
530
531
        if ($this->previousJob == null) {
532
            $this->previousJob = $this->firstJob;
533
        }
534
535
        if ($this->nextJob == null) {
536
            $this->nextJob = $this->lastJob;
537
        }
538
539
        $session->set('unitOfWork', $jobs);
540
541
        if (method_exists($this, 'after_setUnitOfWork_callback')) {
542
            $this->after_setUnitOfWork_callback();
0 ignored issues
show
Bug introduced by
The method after_setUnitOfWork_callback() does not exist on Alpha\Controller\Controller. Did you maybe mean setUnitOfWork()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
543
        }
544
545
        self::$logger->debug('<<setUnitOfWork');
546
    }
547
548
    /**
549
     * Getter for the unit start time.
550
     *
551
     * @return Timestamp
552
     *
553
     * @since 1.0
554
     */
555 View Code Duplication
    public function getStartTime()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
556
    {
557
        self::$logger->debug('>>getStartTime()');
558
        self::$logger->debug('<<getStartTime ['.$this->unitStartTime.']');
559
560
        return $this->unitStartTime;
561
    }
562
563
    /**
564
     * Setter for the unit start time (value will be stored in the session as key unitStartTime).
565
     *
566
     * @param int $year
567
     * @param int $month
568
     * @param int $day
569
     * @param int $hour
570
     * @param int $minute
571
     * @param int $second
572
     *
573
     * @since 1.0
574
     */
575 View Code Duplication
    public function setUnitStartTime($year, $month, $day, $hour, $minute, $second)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
576
    {
577
        self::$logger->debug('>>setUnitStartTime(year=['.$year.'], month=['.$month.'], day=['.$day.'], hour=['.$hour.'], minute=['.$minute.'],
578
            second=['.$second.'])');
579
580
        $config = ConfigProvider::getInstance();
581
        $sessionProvider = $config->get('session.provider.name');
582
        $session = SessionProviderFactory::getInstance($sessionProvider);
583
584
        $this->unitStartTime->setTimestampValue($year, $month, $day, $hour, $minute, $second);
585
        $session->set('unitStartTime', $this->unitStartTime->getValue());
586
587
        self::$logger->debug('<<setUnitStartTime');
588
    }
589
590
    /**
591
     * Getter for the unit end time.
592
     *
593
     * @return Alpha\Model\Type\Timestamp
594
     *
595
     * @since 1.0
596
     */
597 View Code Duplication
    public function getEndTime()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
598
    {
599
        self::$logger->debug('>>getEndTime()');
600
        self::$logger->debug('<<getEndTime ['.$this->unitEndTime.']');
601
602
        return $this->unitEndTime;
603
    }
604
605
    /**
606
     * Setter for the unit end time (value will be stored in the session as key unitEndTime).
607
     *
608
     * @param int $year
609
     * @param int $month
610
     * @param int $day
611
     * @param int $hour
612
     * @param int $minute
613
     * @param int $second
614
     *
615
     * @since 1.0
616
     */
617 View Code Duplication
    public function setUnitEndTime($year, $month, $day, $hour, $minute, $second)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
618
    {
619
        self::$logger->debug('>>setUnitEndTime(year=['.$year.'], month=['.$month.'], day=['.$day.'], hour=['.$hour.'], minute=['.$minute.'],
620
         second=['.$second.'])');
621
622
        $config = ConfigProvider::getInstance();
623
        $sessionProvider = $config->get('session.provider.name');
624
        $session = SessionProviderFactory::getInstance($sessionProvider);
625
626
        $this->unitEndTime->setTimestampValue($year, $month, $day, $hour, $minute, $second);
627
        $session->set('unitEndTime', $this->unitEndTime->getValue());
628
629
        self::$logger->debug('<<setUnitEndTime');
630
    }
631
632
    /**
633
     * Getter for the unit of work MAX duration.
634
     *
635
     * @return int
636
     *
637
     * @since 1.0
638
     */
639 View Code Duplication
    public function getMAXDuration()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
640
    {
641
        self::$logger->debug('>>getMAXDuration()');
642
        self::$logger->debug('<<getMAXDuration ['.$this->unitMAXDuration.']');
643
644
        return $this->unitMAXDuration;
645
    }
646
647
    /**
648
     * Setter for the unit MAX duration.
649
     *
650
     * @param int $duration The desired duration in seconds.
651
     *
652
     * @since 1.0
653
     */
654
    public function setUnitMAXDuration($duration)
655
    {
656
        self::$logger->debug('>>setUnitMAXDuration(duration=['.$duration.'])');
657
        $this->unitMAXDuration->setValue($duration);
658
        self::$logger->debug('<<setUnitMAXDuration');
659
    }
660
661
    /**
662
     * Calculates and returns the unit of work current duration in seconds.
663
     *
664
     * @return int
665
     *
666
     * @since 1.0
667
     */
668
    public function getUnitDuration()
669
    {
670
        self::$logger->debug('>>getUnitDuration()');
671
672
        $intStartTime = mktime(
673
            $this->unitStartTime->getHour(),
674
            $this->unitStartTime->getMinute(),
675
            $this->unitStartTime->getSecond(),
676
            $this->unitStartTime->getMonth(),
677
            $this->unitStartTime->getDay(),
678
            $this->unitStartTime->getYear()
679
            );
680
681
        $intEndTime = mktime(
682
            $this->unitEndTime->getHour(),
683
            $this->unitEndTime->getMinute(),
684
            $this->unitEndTime->getSecond(),
685
            $this->unitEndTime->getMonth(),
686
            $this->unitEndTime->getDay(),
687
            $this->unitEndTime->getYear()
688
            );
689
690
        self::$logger->debug('<<getUnitDuration ['.$intEndTime - $intStartTime.']');
691
692
        return $intEndTime - $intStartTime;
693
    }
694
695
    /**
696
     * Adds the supplied business object to the dirtyObjects array in the session.
697
     *
698
     * @param Alpha\Model\ActiveRecord $object
699
     *
700
     * @since 1.0
701
     */
702 View Code Duplication
    public function markDirty($object)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
703
    {
704
        self::$logger->debug('>>markDirty(object=['.var_export($object, true).'])');
705
706
        if (method_exists($this, 'before_markDirty_callback')) {
707
            $this->before_markDirty_callback();
0 ignored issues
show
Bug introduced by
The method before_markDirty_callback() does not exist on Alpha\Controller\Controller. Did you maybe mean markDirty()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
708
        }
709
710
        $this->dirtyObjects[count($this->dirtyObjects)] = $object;
711
712
        $config = ConfigProvider::getInstance();
713
        $sessionProvider = $config->get('session.provider.name');
714
        $session = SessionProviderFactory::getInstance($sessionProvider);
715
716
        $session->set('dirtyObjects', $this->dirtyObjects);
717
718
        if (method_exists($this, 'after_markDirty_callback')) {
719
            $this->after_markDirty_callback();
0 ignored issues
show
Bug introduced by
The method after_markDirty_callback() does not exist on Alpha\Controller\Controller. Did you maybe mean markDirty()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
720
        }
721
722
        self::$logger->debug('<<markDirty');
723
    }
724
725
    /**
726
     * Getter for the dirty objects array.
727
     *
728
     * @return array
729
     *
730
     * @since 1.0
731
     */
732
    public function getDirtyObjects()
733
    {
734
        self::$logger->debug('>>getDirtyObjects()');
735
        self::$logger->debug('<<getDirtyObjects ['.var_export($this->dirtyObjects, true).']');
736
737
        return $this->dirtyObjects;
738
    }
739
740
    /**
741
     * Adds a newly created business object to the newObjects array in the session.
742
     *
743
     * @param Alpha\Model\ActiveRecord $object
744
     *
745
     * @since 1.0
746
     */
747 View Code Duplication
    public function markNew($object)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
748
    {
749
        self::$logger->debug('>>markNew(object=['.var_export($object, true).'])');
750
751
        if (method_exists($this, 'before_markNew_callback')) {
752
            $this->before_markNew_callback();
0 ignored issues
show
Bug introduced by
The method before_markNew_callback() does not exist on Alpha\Controller\Controller. Did you maybe mean markNew()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
753
        }
754
755
        $this->newObjects[count($this->newObjects)] = $object;
756
757
        $config = ConfigProvider::getInstance();
758
        $sessionProvider = $config->get('session.provider.name');
759
        $session = SessionProviderFactory::getInstance($sessionProvider);
760
761
        $session->set('newObjects', $this->newObjects);
762
763
        if (method_exists($this, 'after_markNew_callback')) {
764
            $this->after_markNew_callback();
0 ignored issues
show
Bug introduced by
The method after_markNew_callback() does not exist on Alpha\Controller\Controller. Did you maybe mean markNew()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
765
        }
766
767
        self::$logger->debug('<<markNew');
768
    }
769
770
    /**
771
     * Getter for the new objects array.
772
     *
773
     * @return array
774
     *
775
     * @since 1.0
776
     */
777
    public function getNewObjects()
778
    {
779
        self::$logger->debug('>>getNewObjects()');
780
        self::$logger->debug('<<getNewObjects ['.var_export($this->newObjects, true).']');
781
782
        return $this->newObjects;
783
    }
784
785
    /**
786
     * Commits (saves) all of the new and modified (dirty) objects in the unit of work to the database.
787
     *
788
     * @throws FailedUnitCommitException
789
     *
790
     * @since 1.0
791
     */
792
    public function commit()
793
    {
794
        self::$logger->debug('>>commit()');
795
796
        if (method_exists($this, 'before_commit_callback')) {
797
            $this->before_commit_callback();
0 ignored issues
show
Bug introduced by
The method before_commit_callback() does not exist on Alpha\Controller\Controller. Did you maybe mean commit()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
798
        }
799
800
        ActiveRecord::begin();
801
802
        $newObjects = $this->getNewObjects();
803
804
        $count = count($newObjects);
805
806
        for ($i = 0; $i < $count; ++$i) {
807
            try {
808
                $newObjects[$i]->save();
809
            } catch (FailedSaveException $e) {
810
                throw new FailedUnitCommitException($e->getMessage());
811
                self::$logger->error('Failed to save new object of type ['.get_class($newObjects[$i]).'], aborting...');
0 ignored issues
show
Unused Code introduced by
self::$logger->error('Fa...]) . '], aborting...'); does not seem to be reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
812
                $this->abort();
813
814
                return;
815
            } catch (LockingException $e) {
816
                throw new FailedUnitCommitException($e->getMessage());
817
                self::$logger->error('Failed to save new object of type ['.get_class($newObjects[$i]).'], aborting...');
0 ignored issues
show
Unused Code introduced by
self::$logger->error('Fa...]) . '], aborting...'); does not seem to be reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
818
                $this->abort();
819
820
                return;
821
            }
822
        }
823
824
        $dirtyObjects = $this->getDirtyObjects();
825
826
        $count = count($dirtyObjects);
827
828
        for ($i = 0; $i < $count; ++$i) {
829
            try {
830
                $dirtyObjects[$i]->save();
831
            } catch (FailedSaveException $e) {
832
                throw new FailedUnitCommitException($e->getMessage());
833
                self::$logger->error('Failed to save OID ['.$dirtyObjects[$i]->getID().'] of type ['.get_class($dirtyObjects[$i]).'], aborting...');
0 ignored issues
show
Unused Code introduced by
self::$logger->error('Fa...]) . '], aborting...'); does not seem to be reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
834
                $this->abort();
835
836
                return;
837
            } catch (LockingException $e) {
838
                throw new FailedUnitCommitException($e->getMessage());
839
                self::$logger->error('Failed to save OID ['.$dirtyObjects[$i]->getID().'] of type ['.get_class($dirtyObjects[$i]).'], aborting...');
0 ignored issues
show
Unused Code introduced by
self::$logger->error('Fa...]) . '], aborting...'); does not seem to be reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
840
                $this->abort();
841
842
                return;
843
            }
844
        }
845
846
        try {
847
            ActiveRecord::commit();
848
849
            $this->clearUnitOfWorkAttributes();
850
851
            if (method_exists($this, 'after_commit_callback')) {
852
                $this->after_commit_callback();
0 ignored issues
show
Bug introduced by
The method after_commit_callback() does not exist on Alpha\Controller\Controller. Did you maybe mean commit()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
853
            }
854
855
            self::$logger->debug('<<commit');
856
        } catch (FailedSaveException $e) {
857
            throw new FailedUnitCommitException('Failed to commit the transaction, error is ['.$e->getMessage().']');
858
            self::$logger->debug('<<commit');
0 ignored issues
show
Unused Code introduced by
self::$logger->debug('<<commit'); does not seem to be reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
859
        }
860
    }
861
862
    /**
863
     * Method to clearup a cancelled unit of work.
864
     *
865
     * @throws Alpha\Exception\AlphaException
866
     *
867
     * @since 1.0
868
     */
869
    public function abort()
870
    {
871
        self::$logger->debug('>>abort()');
872
873
        if (method_exists($this, 'before_abort_callback')) {
874
            $this->before_abort_callback();
0 ignored issues
show
Bug introduced by
The method before_abort_callback() does not seem to exist on object<Alpha\Controller\Controller>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
875
        }
876
877
        try {
878
            ActiveRecord::rollback();
879
880
            $this->clearUnitOfWorkAttributes();
881
882
            if (method_exists($this, 'after_abort_callback')) {
883
                $this->after_abort_callback();
0 ignored issues
show
Bug introduced by
The method after_abort_callback() does not seem to exist on object<Alpha\Controller\Controller>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
884
            }
885
886
            self::$logger->debug('<<abort');
887
        } catch (AlphaException $e) {
888
            throw new AlphaException('Failed to rollback the transaction, error is ['.$e->getMessage().']');
889
            self::$logger->debug('<<abort');
0 ignored issues
show
Unused Code introduced by
self::$logger->debug('<<abort'); does not seem to be reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
890
        }
891
    }
892
893
    /**
894
     * Clears the session and object attributes related to unit of work sessions.
895
     *
896
     * @since 1.0
897
     */
898
    public function clearUnitOfWorkAttributes()
899
    {
900
        $config = ConfigProvider::getInstance();
901
        $sessionProvider = $config->get('session.provider.name');
902
        $session = SessionProviderFactory::getInstance($sessionProvider);
903
904
        $session->delete('unitOfWork');
905
        $this->unitOfWork = null;
906
        $session->delete('dirtyObjects');
907
        $this->dirtyObjects = array();
908
        $session->delete('newObjects');
909
        $this->newObjects = array();
910
    }
911
912
    /**
913
     * Getter for the page title.
914
     *
915
     * @return string
916
     *
917
     * @since 1.0
918
     */
919 View Code Duplication
    public function getTitle()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
920
    {
921
        self::$logger->debug('>>getTitle()');
922
        self::$logger->debug('<<getTitle ['.$this->title.']');
923
924
        return $this->title;
925
    }
926
927
    /**
928
     * Setter for the page title.
929
     *
930
     * @param string $title
931
     *
932
     * @since 1.0
933
     */
934
    public function setTitle($title)
935
    {
936
        self::$logger->debug('>>setTitle(title=['.$title.'])');
937
        self::$logger->debug('<<setTitle');
938
        $this->title = $title;
939
    }
940
941
    /**
942
     * Getter for the page description.
943
     *
944
     * @return string
945
     *
946
     * @since 1.0
947
     */
948 View Code Duplication
    public function getDescription()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
949
    {
950
        self::$logger->debug('>>getDescription()');
951
        self::$logger->debug('<<getDescription ['.$this->description.']');
952
953
        return $this->description;
954
    }
955
956
    /**
957
     * Setter for the page description.
958
     *
959
     * @param string $description
960
     *
961
     * @since 1.0
962
     */
963
    public function setDescription($description)
964
    {
965
        self::$logger->debug('>>setDescription(description=['.$description.'])');
966
        self::$logger->debug('<<setDescription');
967
        $this->description = $description;
968
    }
969
970
    /**
971
     * Getter for the page keywords.
972
     *
973
     * @return string
974
     *
975
     * @since 1.0
976
     */
977 View Code Duplication
    public function getKeywords()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
978
    {
979
        self::$logger->debug('>>getKeywords()');
980
        self::$logger->debug('<<getKeywords ['.$this->keywords.']');
981
982
        return $this->keywords;
983
    }
984
985
    /**
986
     * Setter for the page keywords, should pass a comma-seperated list as a string.
987
     *
988
     * @param string $keywords
989
     *
990
     * @since 1.0
991
     */
992
    public function setKeywords($keywords)
993
    {
994
        self::$logger->debug('>>setKeywords(keywords=['.$keywords.'])');
995
        self::$logger->debug('<<setKeywords');
996
        $this->keywords = $keywords;
997
    }
998
999
    /**
1000
     * Method to return an access error for trespassing users.  HTTP response header code will be 403.
1001
     *
1002
     * @return Alpha\Util\Http\Response
1003
     *
1004
     * @since 1.0
1005
     */
1006
    public function accessError()
1007
    {
1008
        self::$logger->debug('>>accessError()');
1009
1010
        if (method_exists($this, 'before_accessError_callback')) {
1011
            $this->before_accessError_callback();
0 ignored issues
show
Bug introduced by
The method before_accessError_callback() does not exist on Alpha\Controller\Controller. Did you maybe mean accessError()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
1012
        }
1013
1014
        $config = ConfigProvider::getInstance();
1015
1016
        $sessionProvider = $config->get('session.provider.name');
1017
        $session = SessionProviderFactory::getInstance($sessionProvider);
1018
1019
        if ($session->get('currentUser') !== false) {
1020
            self::$logger->warn('The user ['.$session->get('currentUser')->get('email').'] attempted to access the resource ['.$this->request->getURI().'] but was denied due to insufficient rights');
1021
        } else {
1022
            self::$logger->warn('An unknown user attempted to access the resource ['.$this->request->getURI().'] but was denied due to insufficient rights');
1023
        }
1024
1025
        $response = new Response(403);
1026
        $response->setBody(View::renderErrorPage(403, 'You do not have the correct access rights to view this page.  If you have not logged in yet, try going back to the home page and logging in from there.'));
1027
1028
        if (method_exists($this, 'after_accessError_callback')) {
1029
            $this->after_accessError_callback();
0 ignored issues
show
Bug introduced by
The method after_accessError_callback() does not exist on Alpha\Controller\Controller. Did you maybe mean accessError()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
1030
        }
1031
1032
        self::$logger->debug('<<accessError');
1033
1034
        return $response;
1035
    }
1036
1037
    /**
1038
     * Checks the user rights of the currently logged-in person against the page
1039
     * visibility set for this controller.  Will return false if the user has
1040
     * not got the correct rights.
1041
     *
1042
     * @return bool
1043
     *
1044
     * @since 1.0
1045
     */
1046
    public function checkRights()
1047
    {
1048
        self::$logger->debug('>>checkRights()');
1049
1050
        $config = ConfigProvider::getInstance();
1051
1052
        $sessionProvider = $config->get('session.provider.name');
1053
        $session = SessionProviderFactory::getInstance($sessionProvider);
1054
1055
        if (method_exists($this, 'before_checkRights_callback')) {
1056
            $this->before_checkRights_callback();
0 ignored issues
show
Bug introduced by
The method before_checkRights_callback() does not exist on Alpha\Controller\Controller. Did you maybe mean checkRights()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
1057
        }
1058
1059
        // firstly if the page is Public then there is no issue
1060
        if ($this->getVisibility() == 'Public') {
1061
            if (method_exists($this, 'after_checkRights_callback')) {
1062
                $this->after_checkRights_callback();
0 ignored issues
show
Bug introduced by
The method after_checkRights_callback() does not exist on Alpha\Controller\Controller. Did you maybe mean checkRights()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
1063
            }
1064
1065
            self::$logger->debug('<<checkRights [true]');
1066
1067
            return true;
1068
        } else {
1069
            // the person is logged in?
1070
            if ($session->get('currentUser') !== false) {
1071
1072
                // if the visibility is 'Session', just being logged in enough
1073 View Code Duplication
                if ($this->getVisibility() == 'Session') {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1074
                    if (method_exists($this, 'after_checkRights_callback')) {
1075
                        $this->after_checkRights_callback();
0 ignored issues
show
Bug introduced by
The method after_checkRights_callback() does not exist on Alpha\Controller\Controller. Did you maybe mean checkRights()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
1076
                    }
1077
1078
                    self::$logger->debug('<<checkRights [true]');
1079
1080
                    return true;
1081
                }
1082
1083
                // checking for admins (can access everything)
1084
                if ($session->get('currentUser')->inGroup('Admin')) {
1085
                    if (method_exists($this, 'after_checkRights_callback')) {
1086
                        $this->after_checkRights_callback();
0 ignored issues
show
Bug introduced by
The method after_checkRights_callback() does not exist on Alpha\Controller\Controller. Did you maybe mean checkRights()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
1087
                    }
1088
1089
                    self::$logger->debug('<<checkRights [true]');
1090
1091
                    return true;
1092 View Code Duplication
                } elseif ($session->get('currentUser')->inGroup($this->getVisibility())) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1093
                    if (method_exists($this, 'after_checkRights_callback')) {
1094
                        $this->after_checkRights_callback();
0 ignored issues
show
Bug introduced by
The method after_checkRights_callback() does not exist on Alpha\Controller\Controller. Did you maybe mean checkRights()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
1095
                    }
1096
1097
                    self::$logger->debug('<<checkRights [true]');
1098
1099
                    return true;
1100
                // the person is editing their own profile which is allowed
1101
                } elseif (get_class($this->record) == 'Alpha\Model\Person' && $session->get('currentUser')->getDisplayName() == $this->record->getDisplayName()) {
1102
                    if (method_exists($this, 'after_checkRights_callback')) {
1103
                        $this->after_checkRights_callback();
0 ignored issues
show
Bug introduced by
The method after_checkRights_callback() does not exist on Alpha\Controller\Controller. Did you maybe mean checkRights()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
1104
                    }
1105
1106
                    self::$logger->debug('<<checkRights [true]');
1107
1108
                    return true;
1109
                } else {
1110
                    self::$logger->debug('<<checkRights [false]');
1111
1112
                    return false;
1113
                }
1114
            } else { // the person is NOT logged in
1115
                self::$logger->debug('<<checkRights [false]');
1116
1117
                return false;
1118
            }
1119
        }
1120
    }
1121
1122
    /**
1123
     * Method to check the validity of the two hidden form security
1124
     * fields which aim to ensure that a post to the controller is being sent from
1125
     * the same server that is hosting it.
1126
     *
1127
     * @return bool
1128
     *
1129
     * @since 1.0
1130
     */
1131
    public function checkSecurityFields()
1132
    {
1133
        self::$logger->debug('>>checkSecurityFields()');
1134
1135
        $host = $this->request->getHost();
1136
        $ip = $this->request->getIP();
1137
1138
        // the server hostname + today's date
1139
        $var1 = rtrim(strtr(base64_encode(SecurityUtils::encrypt($host.date('Ymd'))), '+/', '-_'), '=');
1140
        // the server's IP plus $var1
1141
        $var2 = rtrim(strtr(base64_encode(SecurityUtils::encrypt($ip.$var1)), '+/', '-_'), '=');
1142
1143
        if ($this->request->getParam('var1') === null || $this->request->getParam('var2') === null) {
1144
            self::$logger->warn('The required var1/var2 params where not provided on the HTTP request');
1145
            self::$logger->debug('<<checkSecurityFields [false]');
1146
1147
            return false;
1148
        }
1149
1150
        if ($var1 == $this->request->getParam('var1') && $var2 == $this->request->getParam('var2')) {
1151
            self::$logger->debug('<<checkSecurityFields [true]');
1152
1153
            return true;
1154
        } else {
1155
            /*
1156
             * Here we are implementing a "grace period" of one hour if the time is < 1:00AM, we will accept
1157
             * a match for yesterday's date in the security fields
1158
             *
1159
             */
1160
1161
            // the server hostname + today's date less 1 hour (i.e. yesterday where time is < 1:00AM)
1162
            $var1 = rtrim(strtr(base64_encode(SecurityUtils::encrypt($host.date('Ymd', (time() - 3600)))), '+/', '-_'), '=');
1163
            // the server's IP plus $var1
1164
            $var2 = rtrim(strtr(base64_encode(SecurityUtils::encrypt($ip.$var1)), '+/', '-_'), '=');
1165
1166
            if ($var1 == $this->request->getParam('var1') && $var2 == $this->request->getParam('var2')) {
1167
                self::$logger->debug('<<checkSecurityFields [true]');
1168
1169
                return true;
1170
            } else {
1171
                self::$logger->warn('The var1/var2 params provided are invalid, values: var1=['.$this->request->getParam('var1').'] var2=['.$this->request->getParam('var2').']');
1172
                self::$logger->debug('<<checkSecurityFields [false]');
1173
1174
                return false;
1175
            }
1176
        }
1177
    }
1178
1179
    /**
1180
     * Generates the two security fields to prevent remote form processing.
1181
     *
1182
     * @return array An array containing the two fields
1183
     *
1184
     * @since 1.0
1185
     */
1186
    public static function generateSecurityFields()
1187
    {
1188
        if (self::$logger == null) {
1189
            self::$logger = new Logger('Controller');
0 ignored issues
show
Documentation Bug introduced by
It seems like new \Alpha\Util\Logging\Logger('Controller') of type object<Alpha\Util\Logging\Logger> is incompatible with the declared type object<Alpha\Controller\...ha\Util\Logging\Logger> of property $logger.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
1190
        }
1191
        self::$logger->debug('>>generateSecurityFields()');
1192
1193
        $request = new Request(array('method' => 'GET'));
1194
1195
        $host = $request->getHost();
1196
        $ip = $request->getIP();
1197
1198
        // the server hostname + today's date
1199
        $var1 = rtrim(strtr(base64_encode(SecurityUtils::encrypt($host.date('Ymd'))), '+/', '-_'), '=');
1200
        // the server's IP plus $var1
1201
        $var2 = rtrim(strtr(base64_encode(SecurityUtils::encrypt($ip.$var1)), '+/', '-_'), '=');
1202
1203
        self::$logger->debug('<<generateSecurityFields [array('.$var1.', '.$var2.')]');
1204
1205
        return array($var1, $var2);
1206
    }
1207
1208
    /**
1209
     * Returns the name of a custom controller if one is found, otherwise returns null.
1210
     *
1211
     * @param string $ActiveRecordType The classname of the active record
1212
     *
1213
     * @return string
1214
     *
1215
     * @since 1.0
1216
     */
1217
    public static function getCustomControllerName($ActiveRecordType)
1218
    {
1219
        if (self::$logger == null) {
1220
            self::$logger = new Logger('Controller');
0 ignored issues
show
Documentation Bug introduced by
It seems like new \Alpha\Util\Logging\Logger('Controller') of type object<Alpha\Util\Logging\Logger> is incompatible with the declared type object<Alpha\Controller\...ha\Util\Logging\Logger> of property $logger.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
1221
        }
1222
        self::$logger->debug('>>getCustomControllerName(ActiveRecordType=['.$ActiveRecordType.']');
1223
1224
        $config = ConfigProvider::getInstance();
1225
1226
        try {
1227
            $class = new ReflectionClass($ActiveRecordType);
1228
            $controllerName = $class->getShortname().'Controller';
1229
        } catch (Exception $e) {
1230
            self::$logger->warn('Bad active record name ['.$ActiveRecordType.'] passed to getCustomControllerName()');
1231
1232
            return;
1233
        }
1234
1235
        self::$logger->debug('Custom controller name is ['.$controllerName.']');
1236
1237
        if (file_exists($config->get('app.root').'Controller/'.$controllerName.'.php')) {
1238
            $controllerName = 'Controller\\'.$controllerName;
1239
            self::$logger->debug('<<getCustomControllerName ['.$controllerName.']');
1240
1241
            return $controllerName;
1242 View Code Duplication
        } elseif (file_exists($config->get('app.root').'Alpha/Controller/'.$controllerName.'.php')) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1243
            $controllerName = 'Alpha\Controller\\'.$controllerName;
1244
            self::$logger->debug('<<getCustomControllerName ['.$controllerName.']');
1245
1246
            return $controllerName;
1247
        } else {
1248
            self::$logger->debug('<<getCustomControllerName');
1249
1250
            return;
1251
        }
1252
    }
1253
1254
    /**
1255
     * Set the status message in the session to the value provided.
1256
     *
1257
     * @param string $message
1258
     *
1259
     * @since 1.0
1260
     */
1261 View Code Duplication
    public function setStatusMessage($message)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1262
    {
1263
        $config = ConfigProvider::getInstance();
1264
        $sessionProvider = $config->get('session.provider.name');
1265
        $session = SessionProviderFactory::getInstance($sessionProvider);
1266
1267
        $this->statusMessage = $message;
1268
        $session->set('statusMessage', $message);
1269
    }
1270
1271
    /**
1272
     * Gets the current status message for this controller.  Note that by getting the current
1273
     * status message, you clear out the value stored in the session so this method can only be used
1274
     * to get the status message once for display purposes.
1275
     *
1276
     * @return string
1277
     *
1278
     * @since 1.0
1279
     */
1280 View Code Duplication
    public function getStatusMessage()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1281
    {
1282
        $config = ConfigProvider::getInstance();
1283
        $sessionProvider = $config->get('session.provider.name');
1284
        $session = SessionProviderFactory::getInstance($sessionProvider);
1285
1286
        $session->delete('statusMessage');
1287
1288
        return $this->statusMessage;
1289
    }
1290
1291
    /**
1292
     * Checks that the definition for the controller classname provided exists.  Will also return true
1293
     * if you pass "/" for the root of the web application.
1294
     *
1295
     * @param string $controllerName
1296
     *
1297
     * @return bool
1298
     *
1299
     * @since 1.0
1300
     * @deprecated
1301
     */
1302
    public static function checkControllerDefExists($controllerName)
1303
    {
1304
        if (self::$logger == null) {
1305
            self::$logger = new Logger('Controller');
0 ignored issues
show
Documentation Bug introduced by
It seems like new \Alpha\Util\Logging\Logger('Controller') of type object<Alpha\Util\Logging\Logger> is incompatible with the declared type object<Alpha\Controller\...ha\Util\Logging\Logger> of property $logger.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
1306
        }
1307
        self::$logger->debug('>>checkControllerDefExists(controllerName=['.$controllerName.'])');
1308
1309
        $config = ConfigProvider::getInstance();
1310
1311
        $exists = false;
1312
1313
        if ($controllerName == '/') {
1314
            $exists = true;
1315
        }
1316 View Code Duplication
        if (file_exists($config->get('app.root').'Controller/'.$controllerName.'.php')) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1317
            $exists = true;
1318
        }
1319 View Code Duplication
        if (file_exists($config->get('app.root').'Alpha/Controller/'.$controllerName.'.php')) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1320
            $exists = true;
1321
        }
1322
1323
        self::$logger->debug('<<checkControllerDefExists ['.$exists.']');
1324
1325
        return $exists;
1326
    }
1327
1328
    /**
1329
     * Loads the definition for the controller classname provided.
1330
     *
1331
     * @param string $controllerName
1332
     *
1333
     * @throws Alpha\Exception\IllegalArguementException
1334
     *
1335
     * @since 1.0
1336
     */
1337
    public static function loadControllerDef($controllerName)
1338
    {
1339
        if (self::$logger == null) {
1340
            self::$logger = new Logger('Controller');
0 ignored issues
show
Documentation Bug introduced by
It seems like new \Alpha\Util\Logging\Logger('Controller') of type object<Alpha\Util\Logging\Logger> is incompatible with the declared type object<Alpha\Controller\...ha\Util\Logging\Logger> of property $logger.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
1341
        }
1342
        self::$logger->debug('>>loadControllerDef(controllerName=['.$controllerName.'])');
1343
1344
        $config = ConfigProvider::getInstance();
1345
1346
        if (file_exists($config->get('app.root').'Controller/'.$controllerName.'.php')) {
1347
            require_once $config->get('app.root').'Controller/'.$controllerName.'.php';
1348 View Code Duplication
        } elseif (file_exists($config->get('app.root').'Alpha/Controller/'.$controllerName.'.php')) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1349
            require_once $config->get('app.root').'Alpha/Controller/'.$controllerName.'.php';
1350
        } else {
1351
            throw new IllegalArguementException('The class ['.$controllerName.'] is not defined anywhere!');
1352
        }
1353
1354
        self::$logger->debug('<<loadControllerDef');
1355
    }
1356
1357
    /**
1358
     * Method for determining if the current request URL is a secure one (has a tk string or not).
1359
     *
1360
     * @return bool True if the current URL contains a tk value, false otherwise
1361
     *
1362
     * @since 1.0
1363
     */
1364
    public function checkIfAccessingFromSecureURL()
1365
    {
1366
        if ($this->request->getParam('tk') != null || mb_strpos($this->request->getURI(), '/tk/') !== false) {
1367
            return true;
1368
        } else {
1369
            return false;
1370
        }
1371
    }
1372
1373
    /**
1374
     * Descrypts the HTTP param fieldnames in the array provided and returns the plain version.
1375
     *
1376
     * @param $params array
1377
     *
1378
     * @return array
1379
     * 
1380
     * @since 1.2.2
1381
     */
1382
    private function decryptFieldNames($params)
1383
    {
1384
        $decrypted = array();
1385
1386
        foreach (array_keys($params) as $fieldname) {
1387
1388
            // set request params where fieldnames provided are based64 encoded and encrypted
1389
            if (Validator::isBase64($fieldname)) {
1390
                $decrypted[SecurityUtils::decrypt(base64_decode($fieldname))] = $params[$fieldname];
1391
            }
1392
        }
1393
1394
        return $decrypted;
1395
    }
1396
1397
    /**
1398
     * Converts the supplied string to a "slug" that is URL safe and suitable for SEO.
1399
     *
1400
     * @param string $URLPart     The part of the URL to use as the slug
1401
     * @param string $seperator   The URL seperator to use (default is -)
1402
     * @param array  $filter      An optional array of charactors to filter out
1403
     * @param bool   $crc32Prefix Set to true if you want to prefix the slug with the CRC32 hash of the URLPart supplied
1404
     *
1405
     * @return string A URL slug
1406
     *
1407
     * @since 1.2.4
1408
     */
1409
    public static function generateURLSlug($URLPart, $seperator = '-', $filter = array(), $crc32Prefix = false)
1410
    {
1411
        $URLPart = trim($URLPart);
1412
1413
        if (count($filter) > 0) {
1414
            $URLPart = str_replace($filter, ' ', $URLPart);
1415
        }
1416
1417
        $clean = iconv('UTF-8', 'ASCII//TRANSLIT', $URLPart);
1418
        $clean = preg_replace("/[^a-zA-Z0-9\/\._|+ -]/", '', $clean);
1419
        $clean = strtolower(trim($clean, '-'));
1420
        $clean = preg_replace("/[\.\/_|+ -]+/", $seperator, $clean);
1421
1422
        if ($crc32Prefix) {
1423
            $clean = hexdec(hash('crc32b', $URLPart)).$seperator.$clean;
1424
        }
1425
1426
        return $clean;
1427
    }
1428
1429
    /**
1430
     * {@inheritdoc}
1431
     *
1432
     * @since 2.0
1433
     *
1434
     * @throws Alpha\Exception\NotImplementedException
1435
     */
1436
    public function doHEAD($request)
0 ignored issues
show
Unused Code introduced by
The parameter $request is not used and could be removed.

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

Loading history...
1437
    {
1438
        throw new NotImplementedException('The HEAD method is not supported by this controller');
1439
    }
1440
1441
    /**
1442
     * {@inheritdoc}
1443
     *
1444
     * @since 2.0
1445
     *
1446
     * @throws Alpha\Exception\NotImplementedException
1447
     */
1448
    public function doGET($request)
1449
    {
1450
        throw new NotImplementedException('The GET method is not supported by this controller');
1451
    }
1452
1453
    /**
1454
     * {@inheritdoc}
1455
     *
1456
     * @since 2.0
1457
     *
1458
     * @throws Alpha\Exception\NotImplementedException
1459
     */
1460
    public function doPOST($request)
1461
    {
1462
        throw new NotImplementedException('The POST method is not supported by this controller');
1463
    }
1464
1465
    /**
1466
     * {@inheritdoc}
1467
     *
1468
     * @since 2.0
1469
     *
1470
     * @throws Alpha\Exception\NotImplementedException
1471
     */
1472
    public function doPUT($request)
1473
    {
1474
        throw new NotImplementedException('The PUT method is not supported by this controller');
1475
    }
1476
1477
    /**
1478
     * {@inheritdoc}
1479
     *
1480
     * @since 2.0
1481
     *
1482
     * @throws Alpha\Exception\NotImplementedException
1483
     */
1484
    public function doPATCH($request)
0 ignored issues
show
Unused Code introduced by
The parameter $request is not used and could be removed.

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

Loading history...
1485
    {
1486
        throw new NotImplementedException('The PATCH method is not supported by this controller');
1487
    }
1488
1489
    /**
1490
     * {@inheritdoc}
1491
     *
1492
     * @since 2.0
1493
     *
1494
     * @throws Alpha\Exception\NotImplementedException
1495
     */
1496
    public function doDELETE($request)
1497
    {
1498
        throw new NotImplementedException('The DELETE method is not supported by this controller');
1499
    }
1500
1501
    /**
1502
     * {@inheritdoc}
1503
     *
1504
     * @since 2.0
1505
     */
1506 View Code Duplication
    public function doOPTIONS($request)
0 ignored issues
show
Unused Code introduced by
The parameter $request is not used and could be removed.

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

Loading history...
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1507
    {
1508
        $HTTPMethods = array('HEAD', 'GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS');
1509
        $supported = array();
1510
1511
        foreach ($HTTPMethods as $HTTPMethod) {
1512
            $reflector = new \ReflectionMethod($this, 'do'.$HTTPMethod);
1513
            $isOverridden = ($reflector->getDeclaringClass()->getName() === get_class($this));
0 ignored issues
show
introduced by
Consider using $reflector->class. There is an issue with getName() and APC-enabled PHP versions.
Loading history...
1514
1515
            if ($isOverridden) {
1516
                $supported[] = $HTTPMethod;
1517
            }
1518
        }
1519
1520
        $supported = implode(',', $supported);
1521
1522
        $response = new Response(200);
1523
        $response->setHeader('Allow', $supported);
1524
1525
        return $response;
1526
    }
1527
1528
    /**
1529
     * {@inheritdoc}
1530
     *
1531
     * @since 2.0.2
1532
     */
1533 View Code Duplication
    public function doTRACE($request)
0 ignored issues
show
Unused Code introduced by
The parameter $request is not used and could be removed.

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

Loading history...
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1534
    {
1535
        $HTTPMethods = array('HEAD', 'GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS');
1536
        $supported = array();
1537
1538
        foreach ($HTTPMethods as $HTTPMethod) {
1539
            $reflector = new \ReflectionMethod($this, 'do'.$HTTPMethod);
1540
            $isOverridden = ($reflector->getDeclaringClass()->getName() === get_class($this));
0 ignored issues
show
introduced by
Consider using $reflector->class. There is an issue with getName() and APC-enabled PHP versions.
Loading history...
1541
1542
            if ($isOverridden) {
1543
                $supported[] = $HTTPMethod;
1544
            }
1545
        }
1546
1547
        $supported = implode(',', $supported);
1548
1549
        $response = new Response(405);
1550
        $response->setHeader('Allow', $supported);
1551
1552
        return $response;
1553
    }
1554
1555
    /**
1556
     * Maps the supplied request with the appropiate method to run on this controller, for example
1557
     * GET to doGET(), POST to doPOST() etc.  Returns the response generated by the method called.
1558
     *
1559
     * @param Alpha\Util\Http\Request $request
1560
     *
1561
     * @return Alpha\Util\Http\Response
1562
     *
1563
     * @since 2.0
1564
     */
1565
    public function process($request)
1566
    {
1567
        if (!$request instanceof Request) {
1568
            throw new IllegalArguementException('The request passed to process is not a valid Request object');
1569
        }
1570
1571
        $config = ConfigProvider::getInstance();
1572
1573
        $method = $request->getMethod();
1574
1575
        if (in_array($method, array('POST', 'PUT', 'PATCH'))) {
1576
            if ($config->get('security.encrypt.http.fieldnames')) {
1577
                $decryptedParams = $this->decryptFieldNames($request->getParams());
1578
                $request->addParams($decryptedParams);
1579
1580
                if ($request->getParam('_METHOD') != null) {
1581
                    $request->setMethod($request->getParam('_METHOD'));
1582
                    $method = $request->getMethod();
1583
                }
1584
            }
1585
        }
1586
1587
        $ProviderClassName = $config->get('app.renderer.provider.name');
1588
1589
        if ($ProviderClassName == 'auto' && $request->getAccept() != null) {
1590
            View::setProvider('auto', $request->getAccept());
1591
        }
1592
1593
        $this->request = $request;
1594
1595
        // check the current user's rights on access to the page controller
1596
        if (!$this->checkRights()) {
1597
            return $this->accessError();
1598
        }
1599
1600
        switch ($method) {
1601
            case 'HEAD':
1602
                $response = $this->doHEAD($request);
1603
            break;
1604
            case 'GET':
1605
                $response = $this->doGET($request);
1606
            break;
1607
            case 'POST':
1608
                $response = $this->doPOST($request);
1609
            break;
1610
            case 'PUT':
1611
                $response = $this->doPUT($request);
1612
            break;
1613
            case 'PATCH':
1614
                $response = $this->doPATCH($request);
1615
            break;
1616
            case 'DELETE':
1617
                $response = $this->doDELETE($request);
1618
            break;
1619
            case 'OPTIONS':
1620
                $response = $this->doOPTIONS($request);
1621
            break;
1622
            case 'TRACE':
1623
                $response = $this->doTRACE($request);
1624
            break;
1625
        }
1626
1627
        return $response;
0 ignored issues
show
Bug introduced by
The variable $response does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
1628
    }
1629
1630
    /**
1631
     * Get the request this controller is processing (if any).
1632
     *
1633
     * @return Alpha\Util\Http\Request
1634
     *
1635
     * @since 2.0
1636
     */
1637
    public function getRequest()
1638
    {
1639
        return $this->request;
1640
    }
1641
1642
    /**
1643
     * Set the request this controller is processing.
1644
     *
1645
     * @param Alpha\Util\Http\Request $request
1646
     *
1647
     * @since 2.0
1648
     */
1649
    public function setRequest($request)
1650
    {
1651
        if ($request instanceof Request) {
1652
            $this->request = $request;
1653
        } else {
1654
            throw new IllegalArguementException('Invalid request object ['.print_r($request, true).'] passed');
1655
        }
1656
    }
1657
1658
    /**
1659
     * Use this callback to inject in the admin menu template fragment.
1660
     *
1661
     * @return string
1662
     *
1663
     * @since 1.2
1664
     */
1665
    public function after_displayPageHead_callback()
1666
    {
1667
        $accept = $this->request->getAccept();
1668
1669
        if ($accept != 'application/json' && $this->checkIfAccessingFromSecureURL()) {
1670
            $viewState = ViewState::getInstance();
1671
            if ($viewState->get('renderAdminMenu') === true) {
1672
1673
                $config = ConfigProvider::getInstance();
1674
1675
                $sessionProvider = $config->get('session.provider.name');
1676
                $session = SessionProviderFactory::getInstance($sessionProvider);
1677
1678
                $passwordResetRequired = SecurityUtils::checkAdminPasswordIsDefault($session->get('currentUser')->get('password'));
1679
                $menu = View::loadTemplateFragment('html', 'adminmenu.phtml', array('passwordResetRequired' => $passwordResetRequired));
1680
1681
                return $menu;
1682
            }
1683
        } else {
1684
            return '';
1685
        }
1686
    }
1687
}
1688