PluginProbe
CSS & JavaScript Toolbox / 12.0.3
CSS & JavaScript Toolbox v12.0.3
trunk 0.3 0.8 10 10.1 11 11.2 11.3 11.4 11.5 11.6 11.7 11.8 11.9 11.9.1 12 12.0 12.0.1 12.0.3 12.0.4 12.0.5 12.0.6 12.0.7 6.0 6.0.11 All 60 releases
css-javascript-toolbox / framework / mvc / controller.inc.php

controller.inc.php in CSS & JavaScript Toolbox 12.0.3, at framework/mvc/controller.inc.php

388 lines 9.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * @version controller.inc.php
4 */
5
6 /**
7 * No direct access.
8 */
9 defined('ABSPATH') or die("Access denied");
10
11 /**
12 * CJT controller base class.
13 */
14 abstract class CJTController extends CJTHookableClass {
15
16 /** */
17 const NONCE_ACTION = 'cjtoolbox';
18
19 /**
20 * put your comment there...
21 *
22 * @var mixed
23 */
24 protected $action;
25
26 /**
27 * put your comment there...
28 *
29 * @var mixed
30 */
31 protected $controllerInfo = null;
32
33 /**
34 * put your comment there...
35 *
36 * @var mixed
37 */
38 protected $defaultAction = 'index';
39
40 /**
41 * put your comment there...
42 *
43 * @var mixed
44 */
45 protected $request;
46
47 /**
48 * put your comment there...
49 *
50 * @var mixed
51 */
52 protected $model = null;
53
54 /**
55 * put your comment there...
56 *
57 * @var mixed
58 */
59 protected $oncallback = array('parameters' => array('callback', 'action', 'args'));
60
61 /**
62 * put your comment there...
63 *
64 * @var mixed
65 */
66 protected $ongetactionname = array('parameters' => array('action'));
67
68 /**
69 * put your comment there...
70 *
71 * @var mixed
72 */
73 protected static $ongetclassname = array('parameters' => array('class', 'name', 'type'));
74
75 /**
76 * put your comment there...
77 *
78 * @var mixed
79 */
80 protected $ongetviewname = array('parameters' => array('view'));
81
82 /**
83 * put your comment there...
84 *
85 * @var mixed
86 */
87 protected static $onloadcontroller = array('parameters' => array('file', 'name'));
88
89 /**
90 * put your comment there...
91 *
92 * @var mixed
93 */
94 protected $view = null;
95
96 /**
97 * put your comment there...
98 *
99 * @param mixed $hasView
100 * @param mixed $request
101 * @param mixed $overrideControllerPath
102 * @param mixed $overrideContollerPrefix
103 * @return CJTController
104 */
105 public function __construct($hasView = null,
106 $request = null,
107 $overrideControllerPath = null,
108 $overrideContollerPrefix = null) {
109 // Initialize hookable!
110 parent::__construct();
111 // Read request parameters.
112 $this->request = array_merge(((array) $_REQUEST), ((array) $request));
113
114 $overrideControllerPath = $overrideControllerPath ? null : '';
115 // Create default model.
116 if (isset($this->controllerInfo['model'])) {
117 // E_ALL complain!
118 if (!isset($this->controllerInfo['model_file'])) {
119 $this->controllerInfo['model_file'] = null;
120 }
121 $this->model = CJTModel::create($this->controllerInfo['model'],
122 $this->request,
123 $this->controllerInfo['model_file'],
124 dirname($overrideControllerPath),
125 $overrideContollerPrefix);
126 }
127 // Create default view.
128 if ($hasView === null) { // Default value for $hasView = true
129 // Request/passed parameters has priority over controller default view!
130 $view = $this->ongetviewname(isset($this->request['view']) ? esc_html($this->request['view']) :
131 (isset($this->controllerInfo['view']) ? $this->controllerInfo['view'] : null)
132 );
133 if ($view) {
134 $this->view = self::getView($view,
135 null,
136 dirname($overrideControllerPath),
137 $overrideContollerPrefix)
138 // Push data into view.
139 ->setModel($this->model)
140 ->setRequest($this->request);
141 }
142 }
143 }
144
145 /**
146 * put your comment there...
147 *
148 */
149 public function _doAction() {
150 // Force use of internal action untless its empty
151 // then look for submitted action or get the default!
152 $action = $this->action ? $this->action :
153 (isset($_GET['action']) ? esc_html($_GET['action']) : $this->defaultAction);
154 // filter action name!
155 $action = $this->ongetactionname($action);
156 if ($action) {
157 $actionHandler = "{$action}Action";
158 // filter callback
159 $callback = $this->oncallback(array($this, $actionHandler), $action);
160 // Callback!
161 call_user_func($callback);
162 }
163 }
164
165 /**
166 * put your comment there...
167 *
168 * @param mixed $name
169 * @param mixed $hasView
170 * @param mixed $request
171 * @param mixed $overrideControllersPath
172 * @param mixed $overrideControllersPrefix
173 */
174 public static function create($name,
175 $hasView = null,
176 $request = null,
177 $overrideControllersPath = null,
178 $overrideControllersPrefix = null) {
179 // Validate controller name to prevent path traversal attacks
180 if (!self::isValidControllerName($name)) {
181 throw new Exception('Invalid controller name: ' . esc_html($name));
182 }
183
184 // Import controller file.
185 $pathToControllers = $overrideControllersPath ? $overrideControllersPath : CJTOOLBOX_CONTROLLERS_PATH;
186 $controllerFile = "{$pathToControllers}/{$name}.php";
187 require_once self::trigger('CJTController.loadcontroller', $controllerFile, $name);
188 // Get controller class name.
189 $class = self::getClassName($name, 'Controller', $overrideControllersPrefix);
190 // Instantiate controller class.
191 return new $class($hasView, $request, $overrideControllersPath, $overrideControllersPrefix);
192 }
193
194 /**
195 * Validate controller name to prevent path traversal attacks
196 *
197 * @param string $name Controller name to validate
198 * @return bool True if valid, false otherwise
199 */
200 private static function isValidControllerName($name) {
201 // Check for null or empty string
202 if (empty($name) || !is_string($name)) {
203 return false;
204 }
205
206 // Check for path traversal attempts
207 if (strpos($name, '..') !== false) {
208 return false;
209 }
210
211 // Check for directory separators
212 if (strpos($name, '/') !== false || strpos($name, '\\') !== false) {
213 return false;
214 }
215
216 // Only allow alphanumeric characters, hyphens, and underscores
217 if (!preg_match('/^[a-zA-Z0-9_-]+$/', $name)) {
218 return false;
219 }
220
221 return true;
222 }
223
224 /**
225 * put your comment there...
226 *
227 * @deprecated Use cssJSToolbox::createSecurityToken
228 */
229 public function createSecurityToken() {
230 return wp_create_nonce(self::NONCE_ACTION);
231 }
232
233 /**
234 * put your comment there...
235 *
236 */
237 protected function displayAction() {
238 // Get view layout!
239 $layout = isset($this->request['layout']) ? esc_html($this->request['layout']) : 'default';
240 ob_start();
241 $this->view->display($layout);
242 $content = ob_get_clean();
243 return $content;
244 }
245
246 /**
247 * put your comment there...
248 *
249 * @param mixed $name
250 * @param mixed $hasView
251 * @param mixed $request
252 * @param mixed $overrideControllersPath
253 */
254 public static function getInstance($name,
255 $hasView = null,
256 $request = null,
257 $overrideControllersPath = null,
258 $overrideControllersPrefix = null) {
259 return self::create($name, $hasView, $request, $overrideControllersPath, $overrideControllersPrefix);
260 }
261
262 /**
263 * Use CJTModel::create instead.
264 *
265 * @deprecated No longer used.
266 */
267 public static function getModel($name,
268 $params = array(),
269 $file = null,
270 $overrideModelsPath = null,
271 $overrideModelsPrefix = null) {
272 $model = null;
273 $pathToModels = $overrideModelsPath ? ($overrideModelsPath . DIRECTORY_SEPARATOR . 'models') : CJTOOLBOX_MODELS_PATH;
274 if (!$file) {
275 $file = $name;
276 }
277 // Import model file.
278 $modelFile = "{$pathToModels}/{$file}.php";
279 require_once $modelFile;
280 // Create model object.
281 $modelClass = self::getClassName($name, 'Model', $overrideModelsPrefix);
282 if (!class_exists($modelClass)) {
283 throw new Exception("Model class {$modelClass} doesn't exists!!!");
284 }
285 $model = new $modelClass($params);
286 return $model;
287 }
288
289 /**
290 * @deprecated No longer used.
291 */
292 public static function getClassName($name, $type, $prefix = null) {
293 // Init vars
294 $className = '';
295 // Getting default prefix
296 if (!$prefix) {
297 $prefix = 'CJT';
298 }
299 // Every word start with uppercase character.
300 $sanitizedName = ucfirst(str_replace(array('-', '_'), ' ', "{$name} {$type}"));
301 // Remove spaces.
302 $sanitizedName = str_replace(' ', '', $sanitizedName);
303 // Filter.
304 $className = self::trigger('CJTController.getclassname', "{$prefix}{$sanitizedName}", $name, $type);
305 return $className;
306 }
307
308 /**
309 * put your comment there...
310 *
311 * @param mixed $name
312 */
313 public function getRequestParameter($name) {
314 return isset($this->request[$name]) ? esc_html($this->request[$name]) : null;
315 }
316
317 /**
318 *
319 * Use CJTView:create instrad.
320 *
321 * @deprecated
322 */
323 public static function getView($path,
324 $params = null,
325 $overrideViewsPath = null,
326 $overrideViewsPrefix = null) {
327 $view = null;
328 // Import view file.
329 $viewInfo = self::getViewInfo($path, $overrideViewsPath, $overrideViewsPrefix);
330 require_once $viewInfo['viewFile'];
331 // Create view object.
332 $name = str_replace(' ', '', ucwords(str_replace('/', ' ',$path)));
333 $viewClass = self::getClassName($name, 'view', $overrideViewsPrefix);
334 $view = new $viewClass($viewInfo, $params);
335 return $view;
336 }
337
338 /**
339 * put your comment there...
340 *
341 */
342 public static function getViewInfo($path, $overrideViewsPath = null, $overrideViewsPrefix = null) {
343 // Plugin views Url
344 $viewsUrl = $overrideViewsPath ?
345 WP_PLUGIN_URL . '/' . basename(dirname($overrideViewsPath)) :
346 CJTOOLBOX_VIEWS_URL;
347 // Path to views dir.
348 $pathToViews = $overrideViewsPath ? ($overrideViewsPath . DIRECTORY_SEPARATOR . 'views') : CJTOOLBOX_VIEWS_PATH;
349 // Get view name.
350 $name = basename($path);
351 // View info struct.
352 $viewInfo = array(
353 'name' => $path,
354 'url' => "{$viewsUrl}/{$path}",
355 'path' => "{$pathToViews}/{$path}",
356 'viewsPath' => $pathToViews,
357 'viewsUrl' => $viewsUrl,
358 'viewFile' => "{$pathToViews}/{$path}/view.php",
359 );
360 return $viewInfo;
361 }
362
363 /**
364 * put your comment there...
365 *
366 * @param mixed $action
367 */
368 public function setAction($action) {
369 $this->action = $action;
370 return $this;
371 }
372
373 /**
374 * put your comment there...
375 *
376 * @param mixed $name
377 * @param mixed $value
378 */
379 public function setRequestParameter($name, $value) {
380 $this->request[$name] = $value;
381 return $this;
382 }
383
384 } // End class.
385
386 // Hookable!
387 CJTController::define('CJTController', array('hookType' => CJTWordpressEvents::HOOK_FILTER));
388