代码就不止三千了,但是在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的空间更大。