Origin\View\Exception

MissingViewException 404

View for PagesController action Pages/home could not be found.

1
<?php
2
/**
3
 * OriginPHP Framework
4
 * Copyright 2018 - 2019 Jamiel Sharief.
5
 *
6
 * Licensed under The MIT License
7
 * The above copyright notice and this permission notice shall be included in all copies or substantial
8
 * portions of the Software.
9
 *
10
 * @copyright   Copyright (c) Jamiel Sharief
11
 * @link        https://www.originphp.com
12
 * @license     https://opensource.org/licenses/mit-license.php MIT License
13
 */
14
 
15
namespace Origin\View;
16
 
17
use Origin\Controller\Controller;
18
use Origin\Core\Inflector;
19
use Origin\View\Helper\HelperRegistry;
20
use Origin\View\Exception\MissingViewException;
21
use Origin\View\Exception\MissingElementException;
22
use Origin\View\Exception\MissingLayoutException;
23
use Origin\Exception\Exception;
24
use Origin\Core\Logger;
25
 
26
class View
27
{
28
    /**
29
     * Name of controller that created this view.
30
     */
31
    public $name null;
32
 
33
    /**
34
     * These are the view vars (needed by testing).
35
     *
36
     * @var array
37
     */
38
    public $vars = [];
39
 
40
    /**
41
     * This is the rendered view
42
     *
43
     * @var string
44
     */
45
    protected $content null;
46
 
47
    /**
48
     * Request Object
49
     *
50
     * @var \Origin\Controller\Request
51
     */
52
    public $request null;
53
    /**
54
       * Response Object
55
       *
56
       * @var \Origin\Controller\Response
57
       */
58
    public $response null;
59
 
60
    /**
61
     * Holds the HelperRegistry object.
62
     *
63
     * @var \Origin\View\Helper\HelperRegistry
64
     */
65
    protected $helperRegistry null;
66
 
67
    /**
68
     * There
69
     *
70
     * @var array
71
     */
72
    protected $helpers = [];
73
 
74
    /**
75
     * Root folder for views
76
     * @example /var/www/src/View
77
     * @var string
78
     */
79
    protected $viewPath SRC DS 'View';
80
 
81
    public function __construct(Controller $controller)
82
    {
83
        $this->name $controller->name;
84
 
85
        $this->request =& $controller->request;
86
        $this->response =& $controller->response;
87
        $this->vars =& $controller->viewVars;
88
 
89
        $this->helperRegistry = new HelperRegistry($this);
90
 
91
        $this->helpers $controller->viewHelpers;
92
    }
93
 
94
    /**
95
     * Lazy load helpers.
96
     */
97
    public function __get($name)
98
    {
99
        if (isset($this->helpers[$name])) {
100
            return $this->helperRegistry()->load($name.'Helper'$this->helpers[$name]);
101
        }
102
        throw new Exception(sprintf('%sHelper is not loaded.'$name));
103
    }
104
 
105
    /**
106
     * Loads a helper
107
     *
108
     * @param string $name
109
     * @param array $config
110
     * @return \Origin\View\Helper\Helper
111
     */
112
    public function loadHelper(string $name, array $config = [])
113
    {
114
        list($plugin$helper) = pluginSplit($name); // split so we can name properly
115
        $config array_merge(['className' => $name 'Helper'], $config);
116
        $this->{$helper} = $this->helperRegistry()->load($name$config);
117
        return $this->{$helper};
118
    }
119
 
120
    public function element(string $name, array $vars = [])
121
    {
122
        $element__filename $this->getElementFilename($name);
123
 
124
        $vars array_merge($this->vars$vars);
125
       
126
        extract($vars);
127
 
128
        ob_start();
129
 
130
        include $element__filename;
131
 
132
        return ob_get_clean();
133
    }
134
 
135
    /**
136
     * Returns the rendered view
137
     *
138
     * @return string|null
139
     */
140
    public function content()
141
    {
142
        return $this->content;
143
    }
144
 
145
    /**
146
     * Returns the page title
147
     *
148
     * @return string|null
149
     */
150
    public function title()
151
    {
152
        if (isset($this->vars['title'])) {
153
            return $this->vars['title'];
154
        }
155
        return null;
156
    }
157
    /**
158
     * Gets a property value
159
     *
160
     * @param string $key vars,contents,params
161
     *
162
     * @return
163
     */
164
    public function fetch(string $key)
165
    {
166
        if (isset($this->{$key})) {
167
            return $this->{$key};
168
        }
169
    }
170
 
171
    /**
172
     * Wrapper for testing.
173
     */
174
    protected function fileExists(string $filename)
175
    {
176
        return file_exists($filename);
177
    }
178
 
179
    /**
180
     * Gets a value from the view vars.
181
     *
182
     * @param string $key
183
     *
184
     * @return
185
     */
186
    public function get(string $key)
187
    {
188
        if (isset($this->vars[$key])) {
189
            return $this->vars[$key];
190
        }
191
 
192
        return null;
193
    }
194
 
195
    /**
196
     * Returns the helper registry object
197
     *
198
     * @return HelperRegistry
199
     */
200
    public function helperRegistry()
201
    {
202
        return $this->helperRegistry;
203
    }
204
 
205
    protected function getElementFilename(string $name)
206
    {
207
        $filename $this->getFilename($name'Element');
208
        if ($this->fileExists($filename)) {
209
            return $filename;
210
        }
211
 
212
        throw new MissingElementException($name);
213
    }
214
 
215
    /**
216
     * Gets the view filename.
217
     *
218
     * @param string $name action, /Folder/action
219
     *
220
     * @return string filename
221
     */
222
    protected function getViewFilename(string $name)
223
    {
224
        $path $this->getViewPath();
225
        if ($name[0] === '/') {
226
            $path $this->getViewPath(false); // get without controller folder
227
        }
228
 
229
        $filename $path DS $name '.ctp';
230
 
231
        if ($this->fileExists($filename)) {
232
            return $filename;
233
        }
234
   
235
        throw new MissingViewException([$this->name$name]);
236
    }
237
 
238
    /**
239
     * Gets the view path for the current request
240
     *
241
     * @param boolean $withControllerName
242
     * @return string
243
     */
244
    protected function getViewPath($withControllerName true)
245
    {
246
        $viewPath $this->viewPath;
247
        $plugin $this->request->params('plugin');
248
        if ($plugin) {
249
            $viewPath PLUGINS DS $plugin DS 'src' DS 'View';
250
        }
251
        if ($withControllerName) {
252
            $viewPath $viewPath DS $this->name;
253
        }
254
 
255
        return $viewPath;
256
    }
257
 
258
    /**
259
     * Gets the layout filename for a layout.
260
     *
261
     * @param string $layout default or Plugin.default;
262
     *
263
     * @return string filename
264
     */
265
    protected function getLayoutFilename(string $layout)
266
    {
267
        $filename $this->getFilename($layout'Layout');
268
 
269
        if ($this->fileExists($filename)) {
270
            return $filename;
271
        }
272
 
273
        throw new MissingLayoutException($layout);
274
    }
275
 
276
    /**
277
     * Used for determining layout/element filenames
278
     *
279
     * @param string $name
280
     * @param string $folder
281
     * @return string
282
     */
283
    protected function getFilename(string $namestring $folder)
284
    {
285
        list($plugin$name) = pluginSplit($name);
286
        if ($plugin) {
287
            return PLUGINS .DS $plugin DS 'src' DS 'View' DS $folder DS $name '.ctp';
288
        }
289
        return $this->viewPath DS $folder DS $name '.ctp';
290
    }
291
 
292
    /**
293
     * renders the view.
294
     *
295
     * @param string $path index or Rest/json
296
     * @param array  $vars
297
     *
298
     * @return string $buffer;
299
     */
300
    public function render(string $path$layout null)
301
    {
302
        $view__filename $this->getViewFilename($path);
303
 
304
        extract($this->vars);
305
        ob_start();
306
        require $view__filename;
307
        $buffer $this->content ob_get_clean();
308
 
309
        if ($layout != null) {
310
            $buffer $this->renderLayout($layout);
311
        }
312
 
313
        $this->helperRegistry()->destroy();
314
        unset($this->helperRegistry);
315
 
316
        return $buffer;
317
    }
318
 
319
    protected function renderLayout(string $layout)
320
    {
321
        $layout_filename $this->getLayoutFilename($layout);
322
 
323
        if (!isset($this->vars['title'])) {
324
            $this->vars['title'] = Inflector::humanize(Inflector::underscore($this->name));
325
        }
326
 
327
        extract($this->vars);
328
 
329
        ob_start();
330
        require $layout_filename;
331
        return ob_get_clean();
332
    }
333
 
334
    /**
335
     * Adds a value to view vars.
336
     *
337
     * @param string $key
338
     * @param mixed  $value
339
     */
340
    public function set(string $key$value)
341
    {
342
        $this->vars[$key] = $value;
343
    }
344
 
345
    /**
346
     * Returns a Logger Object
347
     *
348
     * @param string $channel
349
     * @return \Origin\Core\Logger
350
     */
351
    public function logger(string $channel 'View')
352
    {
353
        return new Logger($channel);
354
    }
355
}
356
1
<?php
2
/**
3
 * OriginPHP Framework
4
 * Copyright 2018 - 2019 Jamiel Sharief.
5
 *
6
 * Licensed under The MIT License
7
 * The above copyright notice and this permission notice shall be included in all copies or substantial
8
 * portions of the Software.
9
 *
10
 * @copyright   Copyright (c) Jamiel Sharief
11
 * @link        https://www.originphp.com
12
 * @license     https://opensource.org/licenses/mit-license.php MIT License
13
 */
14
 
15
namespace Origin\View;
16
 
17
use Origin\Controller\Controller;
18
use Origin\Core\Inflector;
19
use Origin\View\Helper\HelperRegistry;
20
use Origin\View\Exception\MissingViewException;
21
use Origin\View\Exception\MissingElementException;
22
use Origin\View\Exception\MissingLayoutException;
23
use Origin\Exception\Exception;
24
use Origin\Core\Logger;
25
 
26
class View
27
{
28
    /**
29
     * Name of controller that created this view.
30
     */
31
    public $name null;
32
 
33
    /**
34
     * These are the view vars (needed by testing).
35
     *
36
     * @var array
37
     */
38
    public $vars = [];
39
 
40
    /**
41
     * This is the rendered view
42
     *
43
     * @var string
44
     */
45
    protected $content null;
46
 
47
    /**
48
     * Request Object
49
     *
50
     * @var \Origin\Controller\Request
51
     */
52
    public $request null;
53
    /**
54
       * Response Object
55
       *
56
       * @var \Origin\Controller\Response
57
       */
58
    public $response null;
59
 
60
    /**
61
     * Holds the HelperRegistry object.
62
     *
63
     * @var \Origin\View\Helper\HelperRegistry
64
     */
65
    protected $helperRegistry null;
66
 
67
    /**
68
     * There
69
     *
70
     * @var array
71
     */
72
    protected $helpers = [];
73
 
74
    /**
75
     * Root folder for views
76
     * @example /var/www/src/View
77
     * @var string
78
     */
79
    protected $viewPath SRC DS 'View';
80
 
81
    public function __construct(Controller $controller)
82
    {
83
        $this->name $controller->name;
84
 
85
        $this->request =& $controller->request;
86
        $this->response =& $controller->response;
87
        $this->vars =& $controller->viewVars;
88
 
89
        $this->helperRegistry = new HelperRegistry($this);
90
 
91
        $this->helpers $controller->viewHelpers;
92
    }
93
 
94
    /**
95
     * Lazy load helpers.
96
     */
97
    public function __get($name)
98
    {
99
        if (isset($this->helpers[$name])) {
100
            return $this->helperRegistry()->load($name.'Helper'$this->helpers[$name]);
101
        }
102
        throw new Exception(sprintf('%sHelper is not loaded.'$name));
103
    }
104
 
105
    /**
106
     * Loads a helper
107
     *
108
     * @param string $name
109
     * @param array $config
110
     * @return \Origin\View\Helper\Helper
111
     */
112
    public function loadHelper(string $name, array $config = [])
113
    {
114
        list($plugin$helper) = pluginSplit($name); // split so we can name properly
115
        $config array_merge(['className' => $name 'Helper'], $config);
116
        $this->{$helper} = $this->helperRegistry()->load($name$config);
117
        return $this->{$helper};
118
    }
119
 
120
    public function element(string $name, array $vars = [])
121
    {
122
        $element__filename $this->getElementFilename($name);
123
 
124
        $vars array_merge($this->vars$vars);
125
       
126
        extract($vars);
127
 
128
        ob_start();
129
 
130
        include $element__filename;
131
 
132
        return ob_get_clean();
133
    }
134
 
135
    /**
136
     * Returns the rendered view
137
     *
138
     * @return string|null
139
     */
140
    public function content()
141
    {
142
        return $this->content;
143
    }
144
 
145
    /**
146
     * Returns the page title
147
     *
148
     * @return string|null
149
     */
150
    public function title()
151
    {
152
        if (isset($this->vars['title'])) {
153
            return $this->vars['title'];
154
        }
155
        return null;
156
    }
157
    /**
158
     * Gets a property value
159
     *
160
     * @param string $key vars,contents,params
161
     *
162
     * @return
163
     */
164
    public function fetch(string $key)
165
    {
166
        if (isset($this->{$key})) {
167
            return $this->{$key};
168
        }
169
    }
170
 
171
    /**
172
     * Wrapper for testing.
173
     */
174
    protected function fileExists(string $filename)
175
    {
176
        return file_exists($filename);
177
    }
178
 
179
    /**
180
     * Gets a value from the view vars.
181
     *
182
     * @param string $key
183
     *
184
     * @return
185
     */
186
    public function get(string $key)
187
    {
188
        if (isset($this->vars[$key])) {
189
            return $this->vars[$key];
190
        }
191
 
192
        return null;
193
    }
194
 
195
    /**
196
     * Returns the helper registry object
197
     *
198
     * @return HelperRegistry
199
     */
200
    public function helperRegistry()
201
    {
202
        return $this->helperRegistry;
203
    }
204
 
205
    protected function getElementFilename(string $name)
206
    {
207
        $filename $this->getFilename($name'Element');
208
        if ($this->fileExists($filename)) {
209
            return $filename;
210
        }
211
 
212
        throw new MissingElementException($name);
213
    }
214
 
215
    /**
216
     * Gets the view filename.
217
     *
218
     * @param string $name action, /Folder/action
219
     *
220
     * @return string filename
221
     */
222
    protected function getViewFilename(string $name)
223
    {
224
        $path $this->getViewPath();
225
        if ($name[0] === '/') {
226
            $path $this->getViewPath(false); // get without controller folder
227
        }
228
 
229
        $filename $path DS $name '.ctp';
230
 
231
        if ($this->fileExists($filename)) {
232
            return $filename;
233
        }
234
   
235
        throw new MissingViewException([$this->name$name]);
236
    }
237
 
238
    /**
239
     * Gets the view path for the current request
240
     *
241
     * @param boolean $withControllerName
242
     * @return string
243
     */
244
    protected function getViewPath($withControllerName true)
245
    {
246
        $viewPath $this->viewPath;
247
        $plugin $this->request->params('plugin');
248
        if ($plugin) {
249
            $viewPath PLUGINS DS $plugin DS 'src' DS 'View';
250
        }
251
        if ($withControllerName) {
252
            $viewPath $viewPath DS $this->name;
253
        }
254
 
255
        return $viewPath;
256
    }
257
 
258
    /**
259
     * Gets the layout filename for a layout.
260
     *
261
     * @param string $layout default or Plugin.default;
262
     *
263
     * @return string filename
264
     */
265
    protected function getLayoutFilename(string $layout)
266
    {
267
        $filename $this->getFilename($layout'Layout');
268
 
269
        if ($this->fileExists($filename)) {
270
            return $filename;
271
        }
272
 
273
        throw new MissingLayoutException($layout);
274
    }
275
 
276
    /**
277
     * Used for determining layout/element filenames
278
     *
279
     * @param string $name
280
     * @param string $folder
281
     * @return string
282
     */
283
    protected function getFilename(string $namestring $folder)
284
    {
285
        list($plugin$name) = pluginSplit($name);
286
        if ($plugin) {
287
            return PLUGINS .DS $plugin DS 'src' DS 'View' DS $folder DS $name '.ctp';
288
        }
289
        return $this->viewPath DS $folder DS $name '.ctp';
290
    }
291
 
292
    /**
293
     * renders the view.
294
     *
295
     * @param string $path index or Rest/json
296
     * @param array  $vars
297
     *
298
     * @return string $buffer;
299
     */
300
    public function render(string $path$layout null)
301
    {
302
        $view__filename $this->getViewFilename($path);
303
 
304
        extract($this->vars);
305
        ob_start();
306
        require $view__filename;
307
        $buffer $this->content ob_get_clean();
308
 
309
        if ($layout != null) {
310
            $buffer $this->renderLayout($layout);
311
        }
312
 
313
        $this->helperRegistry()->destroy();
314
        unset($this->helperRegistry);
315
 
316
        return $buffer;
317
    }
318
 
319
    protected function renderLayout(string $layout)
320
    {
321
        $layout_filename $this->getLayoutFilename($layout);
322
 
323
        if (!isset($this->vars['title'])) {
324
            $this->vars['title'] = Inflector::humanize(Inflector::underscore($this->name));
325
        }
326
 
327
        extract($this->vars);
328
 
329
        ob_start();
330
        require $layout_filename;
331
        return ob_get_clean();
332
    }
333
 
334
    /**
335
     * Adds a value to view vars.
336
     *
337
     * @param string $key
338
     * @param mixed  $value
339
     */
340
    public function set(string $key$value)
341
    {
342
        $this->vars[$key] = $value;
343
    }
344
 
345
    /**
346
     * Returns a Logger Object
347
     *
348
     * @param string $channel
349
     * @return \Origin\Core\Logger
350
     */
351
    public function logger(string $channel 'View')
352
    {
353
        return new Logger($channel);
354
    }
355
}
356
1
<?php
2
/**
3
 * OriginPHP Framework
4
 * Copyright 2018 - 2019 Jamiel Sharief.
5
 *
6
 * Licensed under The MIT License
7
 * The above copyright notice and this permission notice shall be included in all copies or substantial
8
 * portions of the Software.
9
 *
10
 * @copyright   Copyright (c) Jamiel Sharief
11
 * @link        https://www.originphp.com
12
 * @license     https://opensource.org/licenses/mit-license.php MIT License
13
 */
14
 
15
namespace Origin\Controller;
16
 
17
use Origin\Controller\Request;
18
use Origin\Controller\Response;
19
use Origin\Model\ModelRegistry;
20
use Origin\Model\Exception\MissingModelException;
21
use Origin\View\View;
22
use Origin\Controller\Component\ComponentRegistry;
23
use Origin\Core\Inflector;
24
use Origin\Core\Router;
25
use ReflectionClass;
26
use ReflectionMethod;
27
use Origin\Utility\Xml;
28
use Origin\Core\Logger;
29
 
30
class Controller
31
{
32
    /**
33
     * Controller name.
34
     *
35
     * @var string
36
     */
37
    public $name null;
38
 
39
    /**
40
     * Model name for this controller.
41
     *
42
     * @var string
43
     */
44
    public $modelName null;
45
 
46
    /**
47
     * These are vars passed to view.
48
     *
49
     * @var array
50
     */
51
    public $viewVars = [];
52
 
53
    /**
54
     * Automatically renders view.
55
     */
56
    public $autoRender true;
57
 
58
    /**
59
     * Default layout, set to false to not use a layout.
60
     *
61
     * @var string
62
     */
63
    public $layout 'default';
64
 
65
    /**
66
     * Holds the request object.
67
     *
68
     * @var \Origin\Controller\Request
69
     */
70
    public $request null;
71
 
72
    /**
73
     * Holds the response object.
74
     *
75
     * @var \Origin\Controller\Response
76
     */
77
    public $response null;
78
 
79
    /**
80
     * Helpers to load.
81
     */
82
    public $viewHelpers = [];
83
 
84
    /**
85
       * Holds the componentregistry object.
86
       *
87
       * @var \Origin\Controller\Component\ComponentRegistry
88
       */
89
    protected $componentRegistry null;
90
 
91
    /**
92
     * Paginator Settings.
93
     *
94
     * @var array (limit,order,fields,conditions)
95
     */
96
    public $paginate = [];
97
 
98
    public function __construct(Request $requestResponse $response)
99
    {
100
        list($namespace$name) = namespaceSplit(get_class($this));
101
        $this->name substr($name0, -10);
102
 
103
        $this->modelName Inflector::singularize($this->name);
104
 
105
        $this->request $request;
106
        $this->response $response;
107
 
108
        $this->componentRegistry = new ComponentRegistry($this);
109
 
110
        $this->initialize();
111
    }
112
 
113
    /**
114
     * Loads a Component for use with the controller.
115
     *
116
     * @param string $name   Component name e.g. Auth
117
     * @param array  $config array of config to be passed to component. Class name
118
     * @return \Origin\Controller\Component\Component
119
     */
120
    public function loadComponent(string $name, array $config = [])
121
    {
122
        list($plugin$component) = pluginSplit($name);
123
        $config array_merge(['className' => $name.'Component'], $config);
124
        $this->{$component} = $this->componentRegistry()->load($name$config);
125
        return $this->{$component};
126
    }
127
 
128
    /**
129
     * Loads a helper to be used in the View.
130
     *
131
     * @param string $name   Helper name e.g. Form
132
     * @param array  $config array of config to be passed to helper
133
     */
134
    public function loadHelper(string $name, array $config = [])
135
    {
136
        list($plugin$helper) = pluginSplit($name);
137
        $config array_merge(['className' => $name.'Helper'], $config);
138
        $this->viewHelpers[$helper] = $config;
139
    }
140
 
141
    /**
142
     * Lazy load the model for this controler.
143
     */
144
    public function __get($name)
145
    {
146
        if ($name === $this->modelName) {
147
            return $this->loadModel($name);
148
        }
149
 
150
        return null;
151
    }
152
 
153
    /**
154
     * Loads a model, uses from registry or creates a new one.
155
     *
156
     * @param string $model
157
     * @param array $options
158
     * @return \Origin\Model\Model
159
     */
160
    public function loadModel(string $model, array $options=[])
161
    {
162
        list($plugin$alias) = pluginSplit($model);
163
 
164
        if (isset($this->{$alias})) {
165
            return $this->{$alias};
166
        }
167
 
168
        $this->{$alias} = ModelRegistry::get($model$options);
169
 
170
        if ($this->{$alias}) {
171
            return $this->{$alias};
172
        }
173
        throw new MissingModelException($model);
174
    }
175
 
176
    /**
177
     * Checks if an action on this controller is accessible.
178
     *
179
     * @param string $action
180
     * @return bool
181
     */
182
    public function isAccessible(string $action)
183
    {
184
        $controller = new ReflectionClass(Controller::class);
185
        if ($controller->hasMethod($action)) {
186
            return false;
187
        }
188
        if (!method_exists($this$action)) {
189
            return false;
190
        }
191
        $reflection = new ReflectionMethod($this$action);
192
        return $reflection->isPublic();
193
    }
194
 
195
    /**
196
     * This is immediately after construct method. Use this Hook load components,
197
     * helpers or anything that needs to be done when a new controller is created.
198
     */
199
    public function initialize()
200
    {
201
    }
202
 
203
    /**
204
     * Sends a value or array of values to the array.
205
     *
206
     * @param string|array $name key name or array
207
     * @param $value if key is a string set the value for this
208
     */
209
    public function set($name$value null)
210
    {
211
        if (is_array($name)) {
212
            $data $name;
213
        } else {
214
            $data = [$name => $value];
215
        }
216
 
217
        $this->viewVars array_merge($data$this->viewVars);
218
    }
219
 
220
    /**
221
    * Callback before the action in the controller is called.
222
    */
223
    public function beforeFilter()
224
    {
225
    }
226
 
227
    /**
228
     * Callback just prior to redirecting
229
     */
230
    public function beforeRedirect()
231
    {
232
    }
233
    /**
234
     * This is called after the startup, before shutdown
235
     */
236
    public function beforeRender()
237
    {
238
    }
239
 
240
    /**
241
     * Called after the controller action and the component shutdown function.
242
     * Remember to call parent
243
     *
244
     * @return void
245
     */
246
    public function afterFilter()
247
    {
248
    }
249
 
250
    public function startupProcess()
251
    {
252
        $this->beforeFilter();
253
        $this->componentRegistry()->call('startup');
254
    }
255
 
256
    public function shutdownProcess()
257
    {
258
        $this->componentRegistry()->call('shutdown');
259
        $this->afterFilter();
260
 
261
        //# Free Mem for no longer used items
262
        $this->componentRegistry()->destroy();
263
        unset($this->componentRegistry);
264
    }
265
 
266
    /**
267
     * Loads the PaginatorComponent and passes the settings to it.
268
     *
269
     * @param string $model name of the model
270
     * @param array $settings the settings used by PaginatorComponent these are the same settings as in
271
     * find query (fields, joins, order,limit, group, callbacks,contain)
272
     * @return array paginated records
273
     */
274
    public function paginate(string $model null, array $settings = [])
275
    {
276
        if ($model === null) {
277
            $model $this->modelName;
278
        }
279
    
280
        $object $this->loadModel($model);
281
 
282
        $this->loadComponent('Paginator');
283
        if (!isset($this->viewHelpers['Paginator'])) {
284
            $this->loadHelper('Paginator');
285
        }
286
        
287
        $defaults $this->paginate;
288
        if (isset($this->paginate[$model])) {
289
            $defaults $this->paginate[$model];
290
        }
291
 
292
        return $this->Paginator->paginate($object$defaults $settings);
293
    }
294
 
295
    /**
296
     * Renders a view. This is called automatically by the dispatcher.
297
     *
298
     * If the argument is a string it will assume you want to load a standard
299
     * view using a template.
300
     *
301
     * $this->render('action');
302
     * $this->render('Controller/action')
303
     * $this->render('Plugin.Controller/action');
304
     *
305
     * // Set the type to render with data
306
     * $this->render(['xml'=>$array)
307
     * $this->render(['json'=>$array,'status'=>403]);
308
     * $this->render(['text'=>'OK']);
309
     *
310
     *
311
     * ### View Types
312
     * template - standard view
313
     * xml - takes an array and coverts to xml
314
     * json - takes an array of data and converts to json
315
     * text - sends a txt response, this can be handy when dealing with ajax
316
     * file - this loads an external file with file_get_contents, if it is not html then remember to set the content type. This
317
     * does send the file.
318
     *
319
     * ### Options
320
     * type: this is the content type that will be used (default:html). If use the xml or json options then the type will
321
     * be changed automatically. If you use file that is anything other than html then change the type
322
     * status: the status code to send. Most API providers use only a small subset of huge amount of
323
     * http error codes.
324
     *
325
     *  Here is set which should cover everything.
326
     *
327
     *  200 - OK (Success)
328
     *  400 - Bad Request (Failure - client side problem)
329
     *  500 - Internal Error (Failure - server side problem)
330
     *  401 - Unauthorized
331
     *  404 - Not Found
332
     *  403 - Forbidden (For application level permisions)
333
     */
334
    public function render($options=[])
335
    {
336
        $template $this->request->params('action');
337
        if (empty($options)) {
338
            $options $template;
339
        }
340
        if (is_string($options)) {
341
            $options = ['template'=>$options];
342
        }
343
 
344
        $options += [
345
            'status' => $this->response->status(),
346
            'type' => 'html'
347
        ];
348
        $body null;
349
 
350
        if (!empty($options['json'])) {
351
            return $this->renderJson($options['json'], $options['status']);
352
        }
353
        
354
        if (!empty($options['xml'])) {
355
            return $this->renderXml($options['xml'], $options['status']);
356
        }
357
        
358
        if (!empty($options['text'])) {
359
            $options['type'] = 'text';
360
            $body $options['text'];
361
        } elseif (!empty($options['file'])) {
362
            $body file_get_contents($options['file']);
363
        }
364
        if ($body === null) {
365
            if (isset($options['template'])) {
366
                $template =  $options['template'];
367
            }
368
            $viewObject = new View($this);
369
            $body $viewObject->render($template$this->layout);
370
        }
371
    
372
        $this->response->type($options['type']);   // 'json' or application/json
373
        $this->response->status($options['status']); // 200
374
        $this->response->body($body); //
375
    }
376
 
377
    /**
378
     * Renders a json view
379
     *
380
     *  $this->renderJson([
381
     *     'data' => [
382
     *         'id' => 1234,'name'=>'James'
383
     *      ]
384
     *    ]);
385
     *
386
     *  $this->renderJson([
387
     *      'error' =>[
388
     *          'message' => 'Not Found','code' => 404
389
     *       ]
390
     *     ],404);
391
     *
392
     *  Most API providers use only a small subset of massiave amount of http error codes
393
     *
394
     *  These are the most important ones if you don't want to overcomplicate
395
     *
396
     *  200 - OK (Success)
397
     *  400 - Bad Request (Failure - client side problem)
398
     *  500 - Internal Error (Failure - server side problem)
399
     *  401 - Unauthorized
400
     *  404 - Not Found
401
     *  403 - Forbidden (For application level permisions)
402
     *
403
     * @param array|string $data data which will be json encoded
404
     * @return void
405
     */
406
    public function renderJson($dataint $status 200)
407
    {
408
        $this->autoRender false// Only render once
409
        $this->beforeRender();
410
        
411
        if (is_object($data) and method_exists($data'toJson')) {
412
            $body $data->toJson();
413
        } else {
414
            $body json_encode($data);
415
        }
416
        $this->response->type('json');   // 'json' or application/json
417
        $this->response->status($status); // 200
418
        $this->response->body($body); //
419
    }
420
 
421
    /**
422
     * Renders an XML view using an array.
423
     *
424
     *  $this->renderXml([
425
     *       'post' => [
426
     *           '@category' => 'how tos', // to set attribute use @
427
     *           'id' => 12345,
428
     *           'title' => 'How to create an XML block',
429
     *           'body' =>  Xml::cdata('A quick brown fox jumps of a lazy dog.'),
430
     *           'author' => [
431
     *              'name' => 'James'
432
     *            ]
433
     *          ]
434
     *     ]);
435
     *
436
     * @param array $data
437
     * @param integer $status
438
     * @return void
439
     */
440
    public function renderXml($dataint $status 200)
441
    {
442
        $this->autoRender false// Disable for dispatcher
443
        $this->beforeRender();
444
        
445
        if (is_object($data) and method_exists($data'toXml')) {
446
            $body $data->toXml();
447
        } elseif (is_array($data)) {
448
            $body Xml::fromArray($data);
449
        } else {
450
            $body $data;
451
        }
452
        $this->response->type('xml');   // 'xml' or application/xml
453
        $this->response->status($status); // 200
454
        $this->response->body($body);
455
    }
456
 
457
    /**
458
     * Redirects to a url, will disable autoRender but you should always
459
     * return $this->redirect to prevent code from running during tests etc
460
     *
461
     * # Options
462
     * - controller
463
     * - action
464
     * - ? : query
465
     * - # : fragment
466
     *
467
     * @param string|array $url
468
     * @param int status code default 302
469
     * @return void
470
     */
471
    public function redirect($urlint $code 302)
472
    {
473
        $this->autoRender false;
474
        $this->beforeRedirect();
475
 
476
        $this->response->status($code);
477
        $this->response->header('Location'Router::url($url));
478
        $this->response->send();
479
        $this->response->stop();
480
    }
481
 
482
    /**
483
     * Returns the component registry
484
     *
485
     * @return \Origin\Controller\Component\ComponentRegistry
486
     */
487
    public function componentRegistry()
488
    {
489
        return $this->componentRegistry;
490
    }
491
 
492
    /**
493
     * Returns a Logger Object
494
     *
495
     * @param string $channel
496
     * @return \Origin\Core\Logger
497
     */
498
    public function logger(string $channel 'Controller')
499
    {
500
        return new Logger($channel);
501
    }
502
}
503
1
<?php
2
namespace App\Controller;
3
 
4
/**
5
 * This is an optional controller for serving static page content. For example
6
 * /pages/about_us will load the view file View/Pages/about_us.ctp
7
 *
8
 *  Router::add('/pages/*', ['controller'=>'Pages','action'=>'display']);
9
 */
10
use Origin\Controller\Controller;
11
 
12
class PagesController extends Controller
13
{
14
    public $layout false;
15
 
16
    public function display()
17
    {
18
        $args func_get_args();
19
    
20
        $count count($args);
21
        if (!$count) {
22
            return $this->redirect('/');
23
        }
24
   
25
        return $this->render('Pages/'.implode('/'$args));
26
    }
27
}
28
1
<?php
2
/**
3
 * OriginPHP Framework
4
 * Copyright 2018 - 2019 Jamiel Sharief.
5
 *
6
 * Licensed under The MIT License
7
 * The above copyright notice and this permission notice shall be included in all copies or substantial
8
 * portions of the Software.
9
 *
10
 * @copyright   Copyright (c) Jamiel Sharief
11
 * @link        https://www.originphp.com
12
 * @license     https://opensource.org/licenses/mit-license.php MIT License
13
 */
14
 
15
namespace Origin\Core;
16
 
17
use Origin\Controller\Request;
18
use Origin\Controller\Response;
19
use Origin\Controller\Controller;
20
use Origin\Controller\Exception\MissingControllerException;
21
use Origin\Controller\Exception\MissingMethodException;
22
use Origin\Controller\Exception\PrivateMethodException;
23
use Origin\Core\Exception\RouterException;
24
use Origin\Core\Configure;
25
use App\Application;
26
 
27
class Dispatcher
28
{
29
    /**
30
     * Controller object
31
     *
32
     * @var Controller
33
     */
34
    protected $controller null;
35
 
36
    /**
37
     * Starts the disatch process by creating the request and response objects
38
     *
39
     * @param string $url
40
     * @return Controller
41
     */
42
    public function start(string $url null)
43
    {
44
        return $this->dispatch(new Request($url), new Response());
45
    }
46
 
47
    protected function getClass(string $controllerstring $plugin null)
48
    {
49
        $namespace Configure::read('App.namespace');
50
        if ($plugin) {
51
            $namespace $plugin;
52
        }
53
        return $namespace.'\Controller\\'$controller 'Controller';
54
    }
55
 
56
    /**
57
     * This is the dispatch workhorse
58
     *
59
     * @param Request $request
60
     * @param Response $response
61
     * @return Controller
62
     */
63
    public function dispatch(Request $requestResponse $response)
64
    {
65
        if ($request->params()) {
66
            $application = new Application($request$response);
67
    
68
 
69
            $class $this->getClass($request->params('controller'), $request->params('plugin'));
70
            if (!class_exists($class)) {
71
                throw new MissingControllerException($request->params('controller'));
72
            }
73
            
74
            $this->controller $this->buildController($class$request$response);
75
          
76
            $this->invoke($this->controller$request->params('action'), $request->params());
77
      
78
            if ($this->controller->response instanceof Response) {
79
                $this->controller->response->send();
80
            }
81
          
82
            return $this->controller;
83
        }
84
        throw new RouterException('No route found.'404);
85
    }
86
 
87
    /**
88
     * Creates and returns the controller for the request.
89
     *
90
     * @param string $class    Controller name
91
     * @param object $request
92
     * @param object $response
93
     *
94
     * @return Controller
95
     */
96
    protected function buildController(string $classRequest $requestResponse $response)
97
    {
98
        $controller = new $class($request$response);
99
        $action $request->params('action');
100
        if (!method_exists($controller$action)) {
101
            throw new MissingMethodException([$controller->name$action]);
102
        }
103
 
104
        if (!$controller->isAccessible($action)) {
105
            throw new PrivateMethodException([$controller->name$action]);
106
        }
107
 
108
        return $controller;
109
    }
110
 
111
    /**
112
     * Does the whole lifecylce
113
     */
114
    protected function invoke(Controller $controllerstring $action, array $arguments)
115
    {
116
        $controller->startupProcess();
117
       
118
        call_user_func_array(array($controller$action), $arguments['args']);
119
     
120
        if ($controller->autoRender and $controller->response->ready()) {
121
            $controller->render();
122
        }
123
 
124
        $controller->shutdownProcess();
125
    }
126
 
127
    /**
128
     * Gets the controller
129
     *
130
     * @return Controller
131
     */
132
    public function controller()
133
    {
134
        return $this->controller;
135
    }
136
}
137
1
<?php
2
/**
3
 * OriginPHP Framework
4
 * Copyright 2018 - 2019 Jamiel Sharief.
5
 *
6
 * Licensed under The MIT License
7
 * The above copyright notice and this permission notice shall be included in all copies or substantial
8
 * portions of the Software.
9
 *
10
 * @copyright   Copyright (c) Jamiel Sharief
11
 * @link        https://www.originphp.com
12
 * @license     https://opensource.org/licenses/mit-license.php MIT License
13
 */
14
 
15
namespace Origin\Core;
16
 
17
use Origin\Controller\Request;
18
use Origin\Controller\Response;
19
use Origin\Controller\Controller;
20
use Origin\Controller\Exception\MissingControllerException;
21
use Origin\Controller\Exception\MissingMethodException;
22
use Origin\Controller\Exception\PrivateMethodException;
23
use Origin\Core\Exception\RouterException;
24
use Origin\Core\Configure;
25
use App\Application;
26
 
27
class Dispatcher
28
{
29
    /**
30
     * Controller object
31
     *
32
     * @var Controller
33
     */
34
    protected $controller null;
35
 
36
    /**
37
     * Starts the disatch process by creating the request and response objects
38
     *
39
     * @param string $url
40
     * @return Controller
41
     */
42
    public function start(string $url null)
43
    {
44
        return $this->dispatch(new Request($url), new Response());
45
    }
46
 
47
    protected function getClass(string $controllerstring $plugin null)
48
    {
49
        $namespace Configure::read('App.namespace');
50
        if ($plugin) {
51
            $namespace $plugin;
52
        }
53
        return $namespace.'\Controller\\'$controller 'Controller';
54
    }
55
 
56
    /**
57
     * This is the dispatch workhorse
58
     *
59
     * @param Request $request
60
     * @param Response $response
61
     * @return Controller
62
     */
63
    public function dispatch(Request $requestResponse $response)
64
    {
65
        if ($request->params()) {
66
            $application = new Application($request$response);
67
    
68
 
69
            $class $this->getClass($request->params('controller'), $request->params('plugin'));
70
            if (!class_exists($class)) {
71
                throw new MissingControllerException($request->params('controller'));
72
            }
73
            
74
            $this->controller $this->buildController($class$request$response);
75
          
76
            $this->invoke($this->controller$request->params('action'), $request->params());
77
      
78
            if ($this->controller->response instanceof Response) {
79
                $this->controller->response->send();
80
            }
81
          
82
            return $this->controller;
83
        }
84
        throw new RouterException('No route found.'404);
85
    }
86
 
87
    /**
88
     * Creates and returns the controller for the request.
89
     *
90
     * @param string $class    Controller name
91
     * @param object $request
92
     * @param object $response
93
     *
94
     * @return Controller
95
     */
96
    protected function buildController(string $classRequest $requestResponse $response)
97
    {
98
        $controller = new $class($request$response);
99
        $action $request->params('action');
100
        if (!method_exists($controller$action)) {
101
            throw new MissingMethodException([$controller->name$action]);
102
        }
103
 
104
        if (!$controller->isAccessible($action)) {
105
            throw new PrivateMethodException([$controller->name$action]);
106
        }
107
 
108
        return $controller;
109
    }
110
 
111
    /**
112
     * Does the whole lifecylce
113
     */
114
    protected function invoke(Controller $controllerstring $action, array $arguments)
115
    {
116
        $controller->startupProcess();
117
       
118
        call_user_func_array(array($controller$action), $arguments['args']);
119
     
120
        if ($controller->autoRender and $controller->response->ready()) {
121
            $controller->render();
122
        }
123
 
124
        $controller->shutdownProcess();
125
    }
126
 
127
    /**
128
     * Gets the controller
129
     *
130
     * @return Controller
131
     */
132
    public function controller()
133
    {
134
        return $this->controller;
135
    }
136
}
137
1
<?php
2
/**
3
 * OriginPHP Framework
4
 * Copyright 2018 - 2019 Jamiel Sharief.
5
 *
6
 * Licensed under The MIT License
7
 * The above copyright notice and this permission notice shall be included in all copies or substantial
8
 * portions of the Software.
9
 *
10
 * @copyright   Copyright (c) Jamiel Sharief
11
 * @link        https://www.originphp.com
12
 * @license     https://opensource.org/licenses/mit-license.php MIT License
13
 */
14
 
15
namespace Origin\Core;
16
 
17
use Origin\Controller\Request;
18
use Origin\Controller\Response;
19
use Origin\Controller\Controller;
20
use Origin\Controller\Exception\MissingControllerException;
21
use Origin\Controller\Exception\MissingMethodException;
22
use Origin\Controller\Exception\PrivateMethodException;
23
use Origin\Core\Exception\RouterException;
24
use Origin\Core\Configure;
25
use App\Application;
26
 
27
class Dispatcher
28
{
29
    /**
30
     * Controller object
31
     *
32
     * @var Controller
33
     */
34
    protected $controller null;
35
 
36
    /**
37
     * Starts the disatch process by creating the request and response objects
38
     *
39
     * @param string $url
40
     * @return Controller
41
     */
42
    public function start(string $url null)
43
    {
44
        return $this->dispatch(new Request($url), new Response());
45
    }
46
 
47
    protected function getClass(string $controllerstring $plugin null)
48
    {
49
        $namespace Configure::read('App.namespace');
50
        if ($plugin) {
51
            $namespace $plugin;
52
        }
53
        return $namespace.'\Controller\\'$controller 'Controller';
54
    }
55
 
56
    /**
57
     * This is the dispatch workhorse
58
     *
59
     * @param Request $request
60
     * @param Response $response
61
     * @return Controller
62
     */
63
    public function dispatch(Request $requestResponse $response)
64
    {
65
        if ($request->params()) {
66
            $application = new Application($request$response);
67
    
68
 
69
            $class $this->getClass($request->params('controller'), $request->params('plugin'));
70
            if (!class_exists($class)) {
71
                throw new MissingControllerException($request->params('controller'));
72
            }
73
            
74
            $this->controller $this->buildController($class$request$response);
75
          
76
            $this->invoke($this->controller$request->params('action'), $request->params());
77
      
78
            if ($this->controller->response instanceof Response) {
79
                $this->controller->response->send();
80
            }
81
          
82
            return $this->controller;
83
        }
84
        throw new RouterException('No route found.'404);
85
    }
86
 
87
    /**
88
     * Creates and returns the controller for the request.
89
     *
90
     * @param string $class    Controller name
91
     * @param object $request
92
     * @param object $response
93
     *
94
     * @return Controller
95
     */
96
    protected function buildController(string $classRequest $requestResponse $response)
97
    {
98
        $controller = new $class($request$response);
99
        $action $request->params('action');
100
        if (!method_exists($controller$action)) {
101
            throw new MissingMethodException([$controller->name$action]);
102
        }
103
 
104
        if (!$controller->isAccessible($action)) {
105
            throw new PrivateMethodException([$controller->name$action]);
106
        }
107
 
108
        return $controller;
109
    }
110
 
111
    /**
112
     * Does the whole lifecylce
113
     */
114
    protected function invoke(Controller $controllerstring $action, array $arguments)
115
    {
116
        $controller->startupProcess();
117
       
118
        call_user_func_array(array($controller$action), $arguments['args']);
119
     
120
        if ($controller->autoRender and $controller->response->ready()) {
121
            $controller->render();
122
        }
123
 
124
        $controller->shutdownProcess();
125
    }
126
 
127
    /**
128
     * Gets the controller
129
     *
130
     * @return Controller
131
     */
132
    public function controller()
133
    {
134
        return $this->controller;
135
    }
136
}
137
1
<?php
2
/**
3
 * Front Controller.
4
 */
5
 
6
define('START_TIME'microtime(true));
7
 
8
/**
9
 * Start the Origin Bootstrap Process.
10
 */
11
require dirname(__DIR__) . '/origin/src/bootstrap.php';
12
 
13
$Dispatcher = new Origin\Core\Dispatcher();
14
$Dispatcher->start();
15