首页 > 代码库 > prestashop 1.4代码解析:弱水三千的那一瓢

prestashop 1.4代码解析:弱水三千的那一瓢

代码就不止三千了,但是在prestashop 1.4中最重要的那一瓢,就是FrontController.php。

解析

先来看看prestashop 1.4的文件加载方式,如果你new了一个类,代码首先会在controller中寻找同名的类文件,这点和之前的版本差不多。如果找不到,就去 override这个用户可以自定义类的文件夹去寻找,如果还是找不到,会用exec新建一个请求名称的类文件,然后加载classes下面的类 名+core类。所以说,真正的FrontController.php,你需要在classes下面寻找到,而且类的名称也是 FrontControllerCore。

如果说之前最重要的就是init.php,在prestashop 1.4中的FrontController.php,接管了init的全部工作,并且还替代了之前header.php,index.php和 footer.php的全部工作,甚至包括了分页和商品排序。简而言之,FrontController.php有点像zend framework的dispatch,是开始全部工作的一个信号。

public function run()
	{
		$this->init();
		$this->preProcess();
		$this->setMedia();
		$this->displayHeader();
		$this->process();
		$this->displayContent();
		$this->displayFooter();
	}
if ($this->ssl AND !(isset($_SERVER[‘HTTPS‘]) AND strtolower($_SERVER[‘HTTPS‘]) == ‘on‘) AND Configuration::get(‘PS_SSL_ENABLED‘))
		{
			header(‘HTTP/1.1 301 Moved Permanently‘);
			header(‘Location: ‘.Tools::getShopDomainSsl(true).$_SERVER[‘REQUEST_URI‘]);
			exit();
		}

function init中的自动301,这就是prestashop 1.4新增的功能,我写的那个模块maindomin算是废了。

$page_name = (preg_match(‘/^[0-9]/‘, $page_name)) ? ‘page_‘.$page_name : $page_name;

function init中的$page_name变量,很方便的实现了不同页面不同模板的一个判断。要知道以前的版本里面我还是直接在header.tpl中做判断的。

Tools::addCSS(_THEME_CSS_DIR_.‘global.css‘, ‘all‘);
Tools::addJS(array(_PS_JS_DIR_.‘tools.js‘, _PS_JS_DIR_.‘jquery/jquery-1.4.4.min.js‘, _PS_JS_DIR_.‘jquery/jquery.easing.1.3.js‘));

function setMedia中的,这样的好处是统一管理了css和js,就可以做prestashop的“CCC”了。Combine, Compress and Cache
function productSort和pagination,接管了以前的sort和pagination的工作。
其他没有太大变化,主要的功能还是复制了过去的init.php。甚至变量的命名都还是全局变量,而不是面向对象中该有全局类。

定制

在override/classes文件夹下大家可以发现一个_FrontController.php,这其实就是一个定制 FrontController.php的例子,把”_”删掉再访问页面,就可以看到debug信息了。要注意的是,同文件夹下还有mysql和 module2个文件,如果仅改了FrontController.php,会造成因为报错不能运行下去的问题。需要将 _FrontController.php的148行

error_reporting(E_ALL | E_STRICT);

改成

error_reporting(7);

这个7的意思,如果有不明白的,可以看下手册学习。
要定制FrontController.php,还是在override/classes文件夹下新建一个文件命名为FrontController.php,然后写一个类extends FrontControllerCore就可以了,方法可以覆盖core中的方法。
一个例子:

class FrontController extends FrontControllerCore{
	function setMedia()
	{
		parent::setMedia();
		Tools::addCSS(_THEME_CSS_DIR_.‘addition.css‘);
	} 	public function displayFooter()
	{
		global $cookie, $smarty;
		if (!self::$initialized)
			$this->init(); 		self::$smarty->assign(array(
			‘HOOK_RIGHT_COLUMN‘ => (($smarty->get_template_vars(‘page_name‘) == ‘category‘) ? ‘‘ : Module::hookExec(‘rightColumn‘, array(‘cart‘ => self::$cart))),
			‘HOOK_FOOTER‘ => Module::hookExec(‘footer‘),
			‘content_only‘ => (int)(Tools::getValue(‘content_only‘))));
		self::$smarty->display(_PS_THEME_DIR_.‘footer.tpl‘);
		//live edit
		if ($cookie->live_edit AND $ad = Tools::getValue(‘ad‘))
		{
			self::$smarty->assign(array(‘ad‘ => $ad, ‘live_edit‘ => true));
			self::$smarty->display(_PS_ALL_THEMES_DIR_.‘live_edit.tpl‘);
		}
		else
			Tools::displayError();
	}}

这个例子中,重写了setMedia和displayFooter方法。
重写setMedia的时候,执行了原始FrontController的这个方法,并且在css中加载了一个新的css。
重写displayFooter的时候,是复制原始的代码过来,唯一的改动就是加了一个判断,如果pagename是category,就不输出右边的column。这是为了让category list的空间更大。

prestashop 1.4代码解析:弱水三千的那一瓢