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