Completed
Push — feature/allow-multi-docroots ( 0d353c )
by Matthias
10:05 queued 08:10
created

LegacyController::indexAction()   D

Complexity

Conditions 9
Paths 20

Size

Total Lines 44
Code Lines 22

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 19
CRAP Score 11.107

Importance

Changes 17
Bugs 6 Features 3
Metric Value
c 17
b 6
f 3
dl 0
loc 44
ccs 19
cts 27
cp 0.7037
rs 4.909
cc 9
eloc 22
nc 20
nop 0
crap 11.107
1
<?php
2
3
/**
4
 * @author Matthias Glaub <[email protected]>
5
 * @license http://opensource.org/licenses/BSD-3-Clause BSD-3-Clause
6
 */
7
8
namespace MaglLegacyApplication\Controller;
9
10
use MaglLegacyApplication\Application\MaglLegacy;
11
use MaglLegacyApplication\Options\LegacyControllerOptions;
12
use Zend\Http\Response;
13
use Zend\Mvc\Controller\AbstractActionController;
14
15
class LegacyController extends AbstractActionController
16
{
17
18
    /**
19
     *
20
     * @var LegacyControllerOptions
21
     */
22
    private $options;
23
24
    /**
25
     *
26
     * @var MaglLegacy
27
     */
28
    private $legacy;
29
30 4
    public function __construct(LegacyControllerOptions $options, MaglLegacy $legacy)
31
    {
32 4
        $this->options = $options;
33 4
        $this->legacy = $legacy;
34 4
    }
35
36 4
    public function indexAction()
37
    {
38 4
        $docRoots = $this->options->getDocRoots();
39 4
        foreach($docRoots as $key => $docRoot) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space after FOREACH keyword; 0 found
Loading history...
40 4
            $docRoots[$key] = rtrim(getcwd() . '/' . $docRoot);
41 4
        }
42
43 4
        $scriptName = $this->params('script');
44
45 4
        if (empty($scriptName)) {
46
            $path = $this->params(('path')) ? $this->params('path') : '';
47
            foreach ($this->options->getIndexFiles() as $indexFile) {
48
                foreach($docRoots as $docRoot) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space after FOREACH keyword; 0 found
Loading history...
49
                    if (file_exists($docRoot . '/' . $path . $indexFile)) {
50
                        return $this->runScript($docRoot . '/' . $path . $indexFile);
51
                    }
52
                }
53
            }
54
        }
55
56
57 4
        $scriptUri = '/' . ltrim($scriptName, '/'); // force leading '/'
58 4
        foreach($docRoots as $docRoot) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space after FOREACH keyword; 0 found
Loading history...
59 4
            $legacyScriptFilename = $docRoot . $scriptUri;
60 4
            if(file_exists($legacyScriptFilename)) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space after IF keyword; 0 found
Loading history...
61
                //inform the application about the used script
62 3
                $this->legacy->setLegacyScriptFilename($legacyScriptFilename);
63 3
                $this->legacy->setLegacyScriptName($scriptUri);
64
65
                //inject get and request variables
66 3
                $this->setGetVariables();
67
68 3
                return $this->runScript($legacyScriptFilename);
69
            }
70 2
        }
71
72
        // if we're here, the file doesn't really exist and we do not know what to do
73 1
        $response = $this->getResponse();
74
75
        /* @var $response Response */ //<-- this one for netbeans (WHY, NetBeans, WHY??)
76
        /** @var Response $response */ // <-- this one for other IDEs and code analyzers :)
77 1
        $response->setStatusCode(404);
78 1
        return $response;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $response; (Zend\Stdlib\ResponseInterface) is incompatible with the return type of the parent method Zend\Mvc\Controller\Abst...Controller::indexAction of type Zend\View\Model\ViewModel.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
79
    }
80
81 3
    private function setGetVariables()
82
    {
83 3
        $globals_options = $this->options->getGlobals();
84
85
        // if we should not set any global vars, we can return safely
86 3
        if (!$globals_options['get'] && !$globals_options['request']) {
87
            return;
88
        }
89
90
        // check if $_GET is used at all (ini - variables_order ?)
91
        // check if $_GET is written to $_REQUEST (ini - variables_order / request_order)
92
        // depending on request_order, check if $_REQUEST is already written and decide if we are allowed to override
93
94 3
        $request_order = ini_get('request_order');
95
96 3
        if ($request_order === false) {
97
            $request_order = ini_get('variables_order');
98
        }
99
100 3
        $get_prio = stripos($request_order, 'g');
101 3
        $post_prio = stripos($request_order, 'p');
102
103 3
        $forceOverrideRequest = $get_prio > $post_prio;
104
105 3
        $routeParams = $this->getEvent()->getRouteMatch()->getParams();
106
107 3
        foreach ($routeParams as $paramName => $paramValue) {
0 ignored issues
show
Coding Style introduced by
Blank line found at start of control structure
Loading history...
108
109 3
            if ($globals_options['get'] && !isset($_GET[$paramName])) {
110 3
                $_GET[$paramName] = $paramValue;
111 3
            }
112
113 3
            if ($globals_options['request'] && ($forceOverrideRequest || !isset($_REQUEST[$paramName]))) {
114 3
                $_REQUEST[$paramName] = $paramValue;
115 3
            }
116 3
        }
117 3
    }
118
119 3
    private function runScript($scriptFileName)
120
    {
121 3
        ob_start();
122 3
        include $scriptFileName;
123 3
        $output = ob_get_clean();
124
125 3
        $result = $this->getEventManager()->trigger(MaglLegacy::EVENT_SHORT_CIRCUIT_RESPONSE, $this);
126 3
        if ($result->stopped()) {
127
            return $result->last();
128
        }
129
130 3
        $this->getResponse()->setContent($output);
131 3
        return $this->getResponse();
132
    }
133
}
134