PageRenderTime 41ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 1ms

/classes/controller/Controller.php

https://github.com/netplayer/PrestaShop
PHP | 479 lines | 279 code | 62 blank | 138 comment | 78 complexity | e4d1c5b1aca31cee44282d16a2d53640 MD5 | raw file
Possible License(s): CC-BY-SA-3.0, LGPL-2.1, LGPL-3.0
  1. <?php
  2. /*
  3. * 2007-2014 PrestaShop
  4. *
  5. * NOTICE OF LICENSE
  6. *
  7. * This source file is subject to the Open Software License (OSL 3.0)
  8. * that is bundled with this package in the file LICENSE.txt.
  9. * It is also available through the world-wide-web at this URL:
  10. * http://opensource.org/licenses/osl-3.0.php
  11. * If you did not receive a copy of the license and are unable to
  12. * obtain it through the world-wide-web, please send an email
  13. * to license@prestashop.com so we can send you a copy immediately.
  14. *
  15. * DISCLAIMER
  16. *
  17. * Do not edit or add to this file if you wish to upgrade PrestaShop to newer
  18. * versions in the future. If you wish to customize PrestaShop for your
  19. * needs please refer to http://www.prestashop.com for more information.
  20. *
  21. * @author PrestaShop SA <contact@prestashop.com>
  22. * @copyright 2007-2014 PrestaShop SA
  23. * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
  24. * International Registered Trademark & Property of PrestaShop SA
  25. */
  26. /**
  27. * @since 1.5.0
  28. */
  29. abstract class ControllerCore
  30. {
  31. /**
  32. * @var Context
  33. */
  34. protected $context;
  35. /**
  36. * @var array list of css files
  37. */
  38. public $css_files = array();
  39. /**
  40. * @var array list of javascript files
  41. */
  42. public $js_files = array();
  43. /**
  44. * @var array list of php error
  45. */
  46. public static $php_errors = array();
  47. /**
  48. * @var bool check if header will be displayed
  49. */
  50. protected $display_header;
  51. /**
  52. * @var string template name for page content
  53. */
  54. protected $template;
  55. /**
  56. * @var string check if footer will be displayed
  57. */
  58. protected $display_footer;
  59. /**
  60. * @var string check if only content will be displayed
  61. */
  62. protected $content_only = false;
  63. /**
  64. * @var bool If ajax parameter is detected in request, set this flag to true
  65. */
  66. public $ajax = false;
  67. protected $json = false;
  68. protected $status = '';
  69. protected $redirect_after = null;
  70. public $controller_type;
  71. public $php_self;
  72. /**
  73. * check that the controller is available for the current user/visitor
  74. */
  75. abstract public function checkAccess();
  76. /**
  77. * check that the current user/visitor has valid view permissions
  78. */
  79. abstract public function viewAccess();
  80. /**
  81. * Initialize the page
  82. */
  83. public function init()
  84. {
  85. if (_PS_MODE_DEV_ && $this->controller_type == 'admin')
  86. set_error_handler(array(__CLASS__, 'myErrorHandler'));
  87. if (!defined('_PS_BASE_URL_'))
  88. define('_PS_BASE_URL_', Tools::getShopDomain(true));
  89. if (!defined('_PS_BASE_URL_SSL_'))
  90. define('_PS_BASE_URL_SSL_', Tools::getShopDomainSsl(true));
  91. }
  92. /**
  93. * Do the page treatment : post process, ajax process, etc.
  94. */
  95. abstract public function postProcess();
  96. /**
  97. * Display page view
  98. */
  99. abstract public function display();
  100. /**
  101. * Redirect after process if no error
  102. */
  103. abstract protected function redirect();
  104. /**
  105. * Set default media list for controller
  106. */
  107. abstract public function setMedia();
  108. /**
  109. * Get an instance of a controller
  110. *
  111. * @param string $class_name
  112. * @param bool $auth
  113. * @param bool $ssl
  114. */
  115. public static function getController($class_name, $auth = false, $ssl = false)
  116. {
  117. return new $class_name($auth, $ssl);
  118. }
  119. public function __construct()
  120. {
  121. if (is_null($this->display_header))
  122. $this->display_header = true;
  123. if (is_null($this->display_footer))
  124. $this->display_footer = true;
  125. $this->context = Context::getContext();
  126. $this->context->controller = $this;
  127. // Usage of ajax parameter is deprecated
  128. $this->ajax = Tools::getValue('ajax') || Tools::isSubmit('ajax');
  129. if (!headers_sent()
  130. && isset($_SERVER['HTTP_USER_AGENT'])
  131. && (strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE') !== false
  132. || strpos($_SERVER['HTTP_USER_AGENT'], 'Trident') !== false))
  133. header('X-UA-Compatible: IE=edge,chrome=1');
  134. }
  135. /**
  136. * Start controller process (this method shouldn't be overriden !)
  137. */
  138. public function run()
  139. {
  140. $this->init();
  141. if ($this->checkAccess())
  142. {
  143. // setMedia MUST be called before postProcess
  144. if (!$this->content_only && ($this->display_header || (isset($this->className) && $this->className)))
  145. $this->setMedia();
  146. // postProcess handles ajaxProcess
  147. $this->postProcess();
  148. if (!empty($this->redirect_after))
  149. $this->redirect();
  150. if (!$this->content_only && ($this->display_header || (isset($this->className) && $this->className)))
  151. $this->initHeader();
  152. if ($this->viewAccess())
  153. $this->initContent();
  154. else
  155. $this->errors[] = Tools::displayError('Access denied.');
  156. if (!$this->content_only && ($this->display_footer || (isset($this->className) && $this->className)))
  157. $this->initFooter();
  158. // default behavior for ajax process is to use $_POST[action] or $_GET[action]
  159. // then using displayAjax[action]
  160. if ($this->ajax)
  161. {
  162. $action = Tools::toCamelCase(Tools::getValue('action'), true);
  163. if (!empty($action) && method_exists($this, 'displayAjax'.$action))
  164. $this->{'displayAjax'.$action}();
  165. elseif (method_exists($this, 'displayAjax'))
  166. $this->displayAjax();
  167. }
  168. else
  169. $this->display();
  170. }
  171. else
  172. {
  173. $this->initCursedPage();
  174. $this->smartyOutputContent($this->layout);
  175. }
  176. }
  177. public function displayHeader($display = true)
  178. {
  179. $this->display_header = $display;
  180. }
  181. public function displayFooter($display = true)
  182. {
  183. $this->display_footer = $display;
  184. }
  185. public function setTemplate($template)
  186. {
  187. $this->template = $template;
  188. }
  189. /**
  190. * Assign smarty variables for the page header
  191. */
  192. abstract public function initHeader();
  193. /**
  194. * Assign smarty variables for the page main content
  195. */
  196. abstract public function initContent();
  197. /**
  198. * Assign smarty variables when access is forbidden
  199. */
  200. abstract public function initCursedPage();
  201. /**
  202. * Assign smarty variables for the page footer
  203. */
  204. abstract public function initFooter();
  205. /**
  206. * Add a new stylesheet in page header.
  207. *
  208. * @param mixed $css_uri Path to css file, or list of css files like this : array(array(uri => media_type), ...)
  209. * @param string $css_media_type
  210. * @return true
  211. */
  212. public function addCSS($css_uri, $css_media_type = 'all', $offset = null)
  213. {
  214. if (!is_array($css_uri))
  215. $css_uri = array($css_uri);
  216. foreach ($css_uri as $css_file => $media)
  217. {
  218. if (is_string($css_file) && strlen($css_file) > 1)
  219. $css_path = Media::getCSSPath($css_file, $media);
  220. else
  221. $css_path = Media::getCSSPath($media, $css_media_type);
  222. $key = is_array($css_path) ? key($css_path) : $css_path;
  223. if ($css_path && (!isset($this->css_files[$key]) || ($this->css_files[$key] != reset($css_path))))
  224. {
  225. $size = count($this->css_files);
  226. if ($offset === null || $offset > $size || $offset < 0 || !is_numeric($offset))
  227. $offset = $size;
  228. $this->css_files = array_merge(array_slice($this->css_files, 0, $offset), $css_path, array_slice($this->css_files, $offset));
  229. }
  230. }
  231. }
  232. public function removeCSS($css_uri, $css_media_type = 'all')
  233. {
  234. if (!is_array($css_uri))
  235. $css_uri = array($css_uri);
  236. foreach ($css_uri as $css_file => $media)
  237. {
  238. if (is_string($css_file) && strlen($css_file) > 1)
  239. $css_path = Media::getCSSPath($css_file, $media);
  240. else
  241. $css_path = Media::getCSSPath($media, $css_media_type);
  242. if ($css_path && isset($this->css_files[key($css_path)]) && ($this->css_files[key($css_path)] == reset($css_path)))
  243. unset($this->css_files[key($css_path)]);
  244. }
  245. }
  246. /**
  247. * Add a new javascript file in page header.
  248. *
  249. * @param mixed $js_uri
  250. * @return void
  251. */
  252. public function addJS($js_uri)
  253. {
  254. if (is_array($js_uri))
  255. foreach ($js_uri as $js_file)
  256. {
  257. $js_path = Media::getJSPath($js_file);
  258. $key = is_array($js_path) ? key($js_path) : $js_path;
  259. if ($js_path && !in_array($js_path, $this->js_files))
  260. $this->js_files[] = $js_path;
  261. }
  262. else
  263. {
  264. $js_path = Media::getJSPath($js_uri);
  265. if ($js_path && !in_array($js_path, $this->js_files))
  266. $this->js_files[] = $js_path;
  267. }
  268. }
  269. public function removeJS($js_uri)
  270. {
  271. if (is_array($js_uri))
  272. foreach ($js_uri as $js_file)
  273. {
  274. $js_path = Media::getJSPath($js_file);
  275. if ($js_path && in_array($js_path, $this->js_files))
  276. unset($this->js_files[array_search($js_path,$this->js_files)]);
  277. }
  278. else
  279. {
  280. $js_path = Media::getJSPath($js_uri);
  281. if ($js_path)
  282. unset($this->js_files[array_search($js_path,$this->js_files)]);
  283. }
  284. }
  285. /**
  286. * Add a new javascript file in page header.
  287. *
  288. * @param mixed $js_uri
  289. * @return void
  290. */
  291. public function addJquery($version = null, $folder = null, $minifier = true)
  292. {
  293. $this->addJS(Media::getJqueryPath($version, $folder, $minifier));
  294. }
  295. /**
  296. * Add a new javascript file in page header.
  297. *
  298. * @param mixed $js_uri
  299. * @return void
  300. */
  301. public function addJqueryUI($component, $theme = 'base', $check_dependencies = true)
  302. {
  303. $ui_path = array();
  304. if (!is_array($component))
  305. $component = array($component);
  306. foreach ($component as $ui)
  307. {
  308. $ui_path = Media::getJqueryUIPath($ui, $theme, $check_dependencies);
  309. $this->addCSS($ui_path['css']);
  310. $this->addJS($ui_path['js']);
  311. }
  312. }
  313. /**
  314. * Add a new javascript file in page header.
  315. *
  316. * @param $name
  317. * @param null $folder
  318. * @param bool $css
  319. */
  320. public function addJqueryPlugin($name, $folder = null, $css = true)
  321. {
  322. if (!is_array($name))
  323. $name = array($name);
  324. if (is_array($name))
  325. {
  326. foreach ($name as $plugin)
  327. {
  328. $plugin_path = Media::getJqueryPluginPath($plugin, $folder);
  329. if (!empty($plugin_path['js']))
  330. $this->addJS($plugin_path['js']);
  331. if ($css && !empty($plugin_path['css']))
  332. $this->addCSS(key($plugin_path['css']), 'all');
  333. }
  334. }
  335. }
  336. /**
  337. * @since 1.5
  338. * @return bool return true if Controller is called from XmlHttpRequest
  339. */
  340. public function isXmlHttpRequest()
  341. {
  342. return (!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest');
  343. }
  344. protected function smartyOutputContent($content)
  345. {
  346. $this->context->cookie->write();
  347. $js_tag = 'js_def';
  348. $this->context->smarty->assign($js_tag, $js_tag);
  349. if (is_array($content))
  350. foreach ($content as $tpl)
  351. $html = $this->context->smarty->fetch($tpl);
  352. else
  353. $html = $this->context->smarty->fetch($content);
  354. $html = trim($html);
  355. if ($this->controller_type == 'front' && !empty($html) && $this->getLayout())
  356. {
  357. $live_edit_content = '';
  358. if (!$this->useMobileTheme() && $this->checkLiveEditAccess())
  359. $live_edit_content = $this->getLiveEditFooter();
  360. $dom_available = extension_loaded('dom') ? true : false;
  361. $defer = (bool)Configuration::get('PS_JS_DEFER');
  362. if ($defer && $dom_available)
  363. $html = Media::deferInlineScripts($html);
  364. $html = trim(str_replace(array('</body>', '</html>'), '', $html))."\n";
  365. $this->context->smarty->assign(array(
  366. $js_tag => Media::getJsDef(),
  367. 'js_files' => $defer ? array_unique($this->js_files) : array(),
  368. 'js_inline' => ($defer && $dom_available) ? Media::getInlineScript() : array()
  369. ));
  370. $javascript = $this->context->smarty->fetch(_PS_ALL_THEMES_DIR_.'javascript.tpl');
  371. echo ($defer ? $html.$javascript : str_replace($js_tag, $javascript, $html)).$live_edit_content.((!isset($this->ajax) || ! $this->ajax) ? '</body></html>' : '');
  372. }
  373. else
  374. echo $html;
  375. }
  376. protected function isCached($template, $cacheId = null, $compileId = null)
  377. {
  378. Tools::enableCache();
  379. $res = $this->context->smarty->isCached($template, $cacheId, $compileId);
  380. Tools::restoreCacheSettings();
  381. return $res;
  382. }
  383. public static function myErrorHandler($errno, $errstr, $errfile, $errline)
  384. {
  385. if (error_reporting() === 0)
  386. return false;
  387. switch ($errno)
  388. {
  389. case E_USER_ERROR:
  390. case E_ERROR:
  391. $type = 'Fatal error';
  392. die;
  393. break;
  394. case E_USER_WARNING:
  395. case E_WARNING:
  396. $type = 'Warning';
  397. break;
  398. case E_USER_NOTICE:
  399. case E_NOTICE:
  400. $type = 'Notice';
  401. break;
  402. default:
  403. $type = 'Unknow error';
  404. break;
  405. }
  406. Controller::$php_errors[] = array(
  407. 'type' => $type,
  408. 'errline' => (int)$errline,
  409. 'errfile' => str_replace('\\', '\\\\', $errfile), // Hack for Windows paths
  410. 'errno' => (int)$errno,
  411. 'errstr' => $errstr
  412. );
  413. Context::getContext()->smarty->assign('php_errors', Controller::$php_errors);
  414. return true;
  415. }
  416. }
  417. ?>