Passed
Push — Accessing-and-setting-the-site... ( ba0505...e712c3 )
by Stone
01:56
created

Controller::loadModule()   A

Complexity

Conditions 6
Paths 10

Size

Total Lines 27
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 6
eloc 17
nc 10
nop 1
dl 0
loc 27
rs 9.0777
c 0
b 0
f 0
1
<?php
2
3
namespace Core;
4
5
use Twig\Template;
6
7
/**
8
 * Class Controller
9
 * @package Core
10
 *
11
 * PHP version 7
12
 */
13
abstract class Controller
14
{
15
    /**
16
     * the data that will be pushed to the view
17
     * @var array
18
     */
19
    protected $data = [];
20
21
    /**
22
     * @var Container dependency injector
23
     */
24
    protected $container;
25
26
    /**
27
     * @var Dependency\Session the session handler
28
     */
29
    protected $session;
30
31
    /**
32
     * this will automaticly load all the modules listed and store them as $moduleName in tle class
33
     * Child classes can call aditional modules by calling $this->
34
     * @var array List of modules to load
35
     */
36
    protected $loadModules = [
37
        'Csrf',
38
        'AlertBox'
39
    ];
40
41
    /**
42
     * We need to declare out modules here, else they will be public
43
     * @var object
44
     */
45
    protected $csrf;
46
    protected $alertBox;
47
48
    /**
49
     * Controller constructor.
50
     * We get the module list and construct it. We can also over wright the module in app but sill has to inherit from core module
51
     * @param Container $container
52
     *
53
     * @throws \ErrorException on module loading error
54
     * @throws \ReflectionException should never be thrown since only child classes call this
55
     */
56
    public function __construct(Container $container)
57
    {
58
        $this->container = $container;
59
60
        //removing any duplicates that could have been passed in child classes
61
        $this->loadModules = array_unique($this->loadModules);
62
63
        //We load all our module objects into our object
64
        foreach ($this->loadModules as $loadModule) {
65
            $this->loadModule($loadModule);
66
        }
67
        $this->session = $this->container->getSession();
68
69
        //Setting up csrf token security for all calls
70
        $this->data['csrf_token'] = $this->csrf->getCsrfKey(); //storing the security id into the data array to be sent to the view and added in the meta head
71
    }
72
73
    /**
74
     * load the module to the object
75
     * We loog for module in the namespace, then in app and finaly in the core.
76
     * This enables us to over-ride the core or app module with a custom module for the namespace.
77
     * @param $loadModule string grabbed from the loadmodules array
78
     * @throws \ErrorException if module doesn't exits
79
     * @throws \ReflectionException should never be thrown since only child classes call this
80
     */
81
    private function loadModule($loadModule)
82
    {
83
        $loadModuleName = lcfirst($loadModule);
84
        //checking for module in namespace, app and core.
85
        $childClassNamespace = new \ReflectionClass(get_class($this));
86
        $childClassNamespace = $childClassNamespace->getNamespaceName();
87
        if (class_exists($childClassNamespace . '\\Modules\\' . $loadModule)) {
88
            $loadModuleObj = $childClassNamespace . '\\' . $loadModule;
89
        } elseif (class_exists('App\\Modules\\' . $loadModule)) {
90
            $loadModuleObj = 'App\\Modules\\' . $loadModule;
91
        } elseif (class_exists('Core\\Modules\\' . $loadModule)) {
92
            $loadModuleObj = 'Core\\Modules\\' . $loadModule;
93
        } else {
94
            throw new \ErrorException('module ' . $loadModule . ' does not exist');
95
        }
96
97
        //Modules must be children of the Module template
98
        if (!is_subclass_of($loadModuleObj, 'Core\Modules\Module')) {
99
            throw new \ErrorException('Module ' . $loadModuleName . ' must be a sub class of module');
100
        }
101
102
        $loadedModule = new $loadModuleObj($this->container);
103
        //we are not allowed to create public modules, they must be a placeholder ready
104
        if (!property_exists($this, $loadModuleName)) {
105
            throw new \ErrorException('the protected or private variable of ' . $loadModuleName . ' is not present');
106
        }
107
        $this->$loadModuleName = $loadedModule;
108
    }
109
110
    public function index()
111
    {
112
        //if no index, then redirect to the home page or throw an error if in dev; just for debugging purposes
113
        if (Config::DEV_ENVIRONMENT) {
114
            throw new \ErrorException("no index() available in controller call");
115
        }
116
        $this->container->getResponse()->redirect();
117
    }
118
119
    /**
120
     * Calls the templating engine and returns the rendered view
121
     *
122
     * @param $template string the template file name. .twig will be appended
123
     * @return string the rendered template
124
     * @throws \Twig_Error_Loader
125
     * @throws \Twig_Error_Runtime
126
     * @throws \Twig_Error_Syntax
127
     */
128
    public function getView($template)
129
    {
130
        $twig = $this->container->getTemplate();
131
        return $twig->render($template . '.twig', $this->data);
132
    }
133
134
    /**
135
     * rendering the view
136
     *
137
     * @param $template string the template file
138
     * @throws \Twig_Error_Loader
139
     * @throws \Twig_Error_Runtime
140
     * @throws \Twig_Error_Syntax
141
     */
142
    public function renderView($template): void
143
    {
144
        //checking if any alerts and pas the to the template
145
        if ($this->alertBox->alertsPending()) {
146
            $this->data['alert_messages'] = $this->alertBox->getAlerts();
147
        }
148
        if (Config::DEV_ENVIRONMENT) {
149
            $this->devHelper();
150
        }
151
        $twig = $this->container->getTemplate();
152
        $twig->display($template . '.twig', $this->data);
153
    }
154
155
    protected function devHelper($var = '')
156
    {
157
        if (!isset($this->data['dev_info'])) {
158
            $this->data['dev'] = true;
159
            $classMethods = [];
160
            if ($var != '') {
161
                $classMethods['passed_var'] = $var;
162
            }
163
            $classMethods['class_object_methods'] = get_class_methods(get_class($this));
164
            $classMethods['class_object_vars'] = get_object_vars($this);
165
            $classMethods['session_vars'] = $_SESSION;
166
            $classMethods['namespace'] = __NAMESPACE__;
167
            $childClassNamespace = new \ReflectionClass(get_class($this));
168
            $childClassNamespace = $childClassNamespace->getNamespaceName();
169
            $classMethods['classNamespace'] = $childClassNamespace;
170
171
            $this->data['dev_info'] = $classMethods;
172
        }
173
174
    }
175
}