## 访问数据库

### 数据库结构

PrestaShop的数据库表默认带有ps_的前缀,前缀在安装时可以自定义。

所有表名都是小写,以下划线分割。当一个表表示要在两个实体间建立连接时,表名中两个实体的的名称都要出现,比如ps_category_product表示将产品关联到对应的分类。

几点细节:
- 用id_lang字段来存储与一条记录相关的语言
- 用id_shop字段来存储与一条记录相关的店铺
- 以_lang后缀结尾的表表示包含翻译,如ps_product_lang表包含ps_product表的所有翻译
- 以_shop后缀结尾的表表示链接到指定店铺的记录,如ps_category_shop表包含每个分类对应在哪个店铺上

### ObjectModel 类

ObjectModel是一个AR类型的类,它的一个实例对应一条数据库记录。

当你继承了这个类以后,首先要定义模型的基本信息。

<pre class="brush:php">
/**
* Example from the CMS model (CMSCore)
*/
public static $definition = array(
'table' => 'cms',
'primary' => 'id_cms',
'multilang' => true,
'fields' => array(
'id_cms_category' => array('type' => self::TYPE_INT, 'validate' => 'isUnsignedInt'),
'position' => array('type' => self::TYPE_INT),
'active' => array('type' => self::TYPE_BOOL),
// Lang fields
'meta_description' =>
array('type' => self::TYPE_STRING, 'lang' => true, 'validate' => 'isGenericName', 'size' => 255),
'meta_keywords' =>
array('type' => self::TYPE_STRING, 'lang' => true, 'validate' => 'isGenericName', 'size' => 255),
'meta_title' =>
array('type' => self::TYPE_STRING, 'lang' => true, 'validate' => 'isGenericName', 'required' => true, 'size' => 128),
'link_rewrite' =>
array('type' => self::TYPE_STRING, 'lang' => true, 'validate' => 'isLinkRewrite', 'required' => true, 'size' => 128),
'content' =>
array('type' => self::TYPE_HTML, 'lang' => true, 'validate' => 'isString', 'size' => 3999999999999),
),
);

'multilang' => true,
'multishop' => true,
'multilang_shop' => true,
</pre>

主要调用方法:

<table class="confluenceTable tablesorter"><thead><tr class="sortableHeader"><th style="text-align: center;" class="confluenceTh sortableHeader tablesorter-headerSortDown" data-column="0"><div class="tablesorter-header-inner"><span style="color: rgb(0,0,0);"><strong>Method name and parameters</strong></span></div></th><th style="text-align: center;" class="confluenceTh sortableHeader" data-column="1"><div class="tablesorter-header-inner"><span style="color: rgb(0,0,0);"><strong>Description</strong></span></div></th></tr></thead><tbody class=""><tr><td colspan="1" class="confluenceTd"><p>__construct($id = NULL, $id_lang = NULL)</p></td><td colspan="1" class="confluenceTd"><p>Build object.</p></td></tr><tr><td colspan="1" class="confluenceTd"><p>add($autodate = true, $nullValues = false)</p></td><td colspan="1" class="confluenceTd"><p>Save current object to database (add or update).</p></td></tr><tr><td colspan="1" class="confluenceTd">associateTo(integer|array $id_shops)</td><td colspan="1" class="confluenceTd"><p>Associate an item to its context.</p></td></tr><tr><td colspan="1" class="confluenceTd"><p>delete()</p></td><td colspan="1" class="confluenceTd"><p>Delete current object from database.</p></td></tr><tr><td colspan="1" class="confluenceTd">deleteImage(mixed $force_delete = false)</td><td colspan="1" class="confluenceTd"><p>Delete images associated with the object.</p></td></tr><tr><td colspan="1" class="confluenceTd"><p>deleteSelection($selection)</p></td><td colspan="1" class="confluenceTd"><p>Delete several objects from database.</p></td></tr><tr><td colspan="1" class="confluenceTd"><p>getFields()</p></td><td colspan="1" class="confluenceTd"><p>Prepare fields for ObjectModel class (add, update).</p></td></tr><tr><td colspan="1" class="confluenceTd"><p>getValidationRules($className = _CLASS_)</p></td><td colspan="1" class="confluenceTd"><p>Return object validation rules (field validity).</p></td></tr><tr><td colspan="1" class="confluenceTd"><p>save($nullValues = false, $autodate = true)</p></td><td colspan="1" class="confluenceTd"><p>Save current object to database (add or update).</p></td></tr><tr><td colspan="1" class="confluenceTd"><p>toggleStatus()</p></td><td colspan="1" class="confluenceTd"><p>Toggle object's status in database.</p></td></tr><tr><td colspan="1" class="confluenceTd"><p>update($nullValues = false)</p></td><td colspan="1" class="confluenceTd"><p>Update current object to database.</p></td></tr><tr><td colspan="1" class="confluenceTd"><p>validateFields($die = true, $errorReturn = false)</p></td><td colspan="1" class="confluenceTd"><p>Check for field validity before database interaction.</p></td></tr></tbody></table>

### DBQuery类

DBQuery是是一个用于构造SQL 查询语句的助手类。

<pre class="brush: php">
$sql = new DbQuery();
$sql->select('*');
$sql->from('cms', 'c');
$sql->innerJoin('cms_lang', 'l', 'c.id_cms = l.id_cms AND l.id_lang = '.(int)$id_lang);
$sql->where('c.active = 1');
$sql->orderBy('position');
return Db::getInstance()->executeS($sql
</pre>

译注:这个类的方法很基本,跟国产的比差了一截,但一般的应用够了。

## 路由分发

路由分发是v1.5引入的一项特性。

如下,当未启用Url重写时,

<pre>
http://myprestashop.com/index.php?controller=category&id_category=3&id_lang=1
http://myprestashop.com/index.php?controller=product&id_product=1&id_lang=2
</pre>

启用重写后:

<pre>
http://myprestashop.com/en/3-music-ipods
http://myprestashop.com/fr/1-ipod-nano.html
</pre>

路由分发器使用三个抽象类: Controller, FrontController 及d AdminController (后两个继承自第一个)。

可以通过重载loadRoutes()方法来创建新的路由。在后台界面的"Preferences"菜单下访问"SEO & URLs"页面就可以改变控制器的URL。

## 控制器

MVC的模式在此跳过不谈。

所有的控制器实际上都重载了Controller类,如AdminController, ModuleAdminController, FrontController, ModuleFrontController等。

### FrontController类

主要属性列表:

<pre>
Property
Description
$template Template name for page content.
$css_files Array list of CSS files.
$js_files Array list of JavaScript files.
$errors Array of errors that have occurred.
$guestAllowed Whether a customer who has signed out can access the page.
$initialized Whether the init() function has been called.
$iso The ISO code of the currently selected language.
$n The number of items per page.
$orderBy The field used to sort.
$orderWay Whether to sort is ascending or descending ("ASC" or "DESC").
$p The current page number.
$ajax If the ajax parameter is detected in request, set this flag to true.
</pre>

### 控制器内部函数执行顺序

1. __contruct(): Sets all the controller's member variables.
1. init(): Initializes the controller.
1. setMedia() or setMobileMedia(): Adds all JavaScript and CSS specifics to the page so that they can be combined, compressed and cached (see PrestaShop's CCC tool, in the back-office "Performance" page, under the "Advanced preferences" menu).
1. postProcess(): Handles ajaxProcess.
1. initHeader(): Called before initContent().
1. initContent(): Initializes the content.
1. initFooter(): Called after initContent().
1. display() or displayAjax(): Displays the content.

### 系统已有的控制器

控制器都在/controllers目录下,自己去看。

### 重载控制器

系统自带的控制器都带了一个Core的后缀,如

<pre>
文件 /controllers/CategoryController.php
类名: CategoryControllerCore
</pre>

要重载该控制器的话,

<pre>
文件: /override/controllers/front/CategoryController.php
类名: CategoryController
</pre>

## 视图

使用的Smarty引擎,文件扩展名.tpl。

## Cookies

统一使用/classes/Cookie.php中的类进行Cookie的读写。

<pre class="brush:php">
$this->context->cookie->variable;
</pre>

前端用户存储的cookie:

<pre>
Token
Description
viewed The IDs of recently viewed products as a comma-separated list.
passwd The MD5 hash of the _COOKIE_KEY_ in config/settings.inc.php and the password the customer used to log in.
logged Whether the customer is logged in.
last_visited_category The ID of the last visited category of product listings.
id_wishlist The ID of the current wishlist displayed in the wishlist block.
id_lang The ID of the selected language.
id_guest The guest ID of the visitor when not logged in.
id_customer The customer ID of the visitor when logged in.
id_currency The ID of the selected currency.
id_connections The connection ID of the visitor's current session.
id_cart The ID of the current cart displayed in the cart block.
email The email address that the customer used to log in.
date_add The date and time the cookie was created (in YYYY-MM-DD HH:MM:SS format).
customer_lastname The last name of the customer.
customer_firstname The first name of the customer.
checksum The Blowfish checksum used to determine whether the cookie has been modified by a third party.
The customer will be logged out and the cookie deleted if the checksum doesn't match.
checkedTOS Whether the "Terms of service" checkbox has been ticked (1 if it has and 0 if it hasn't)
ajax_blockcart_display Whether the cart block is "expanded" or "collapsed".
</pre>

后台用户存储的cookie:

Token
Description
date_add The date and time the cookie was created (in YYYY-MM-DD HH:MM:SS format).
id_lang The ID of the selected language.
id_employee The ID of the employee.
lastname The last name of the employee.
firstname The first name of the employee.
email The email address the employee used to log in.
profile The ID of the profile that determines which tabs the employee can access.
passwd The MD5 hash of the _COOKIE_KEY_ in config/settings.inc.php and the password the employee used to log in.
checksum The Blowfish checksum used to determine whether the cookie has been modified by a third party.
If the checksum doesn't match, the customer will be logged out and the cookie is deleted .

## 钩子

钩子是将你的代码与一些特定PrestaShop事件进行关联的机制。

主要的钩子有:

<pre>
Hook name
Description
displayFooter
Displays the content in the page's footer area.
displayHeader Displays the content in the page's header area.
displayHome Displays the content in the page's central area.
displayLeftColumn Displays the content in the page's left column.
displayRightColumn Displays the content in the page's right column.
displayTop Displays the content in the page's top area.

</pre>

### 使用钩子

在控制器中,

<pre class="brush:php">
$this->context->smarty->assign('HOOK_LEFT_COLUMN', Module::hookExec('displayLeftColumn'));
</pre>

在模块中,

<pre class="brush:php">
public function hookDisplayNameOfHook($params)
{
// Your code.
}
</pre>

为了让模块响应钩子的调用,要在模块安装代码中将钩子注册到PrestaShop中,

<pre class="brush:php">
public function install()
{
return parent::install() && $this->registerHook('NameOfHook');
}
</pre>

在视图中调用钩子,很容易,

<pre class="brush:html">
{hook h='displayLeftColumn' mod='blockcart'}
</pre>

### 创建自己的钩子

就是像上面模块安装代码中的一样,你想注册自己的钩子到系统中,只要简单的调用:

<pre class="brush:php">
$this->registerHook('NameOfHook');
</pre>

即可。他等同于:

<pre class="brush:sql">
INSERT INTO `ps_hook` (`name`, `title`, `description`) VALUES ('nameOfHook', 'The name of your hook', 'This is a custom hook!');
</pre>

译 PrestaShop开发者指南 第四篇 深入PrestaShop核心开发的更多相关文章

  1. 译 PrestaShop开发者指南 第三篇 设置本地安装环境

    ## 环境要求 - Unix, Linux 或 Windows - Web服务器:Apache 1.3 或更高的版本 - PHP:5.2或更高版本 - MySQL:5.0或更高版本 PrestaSho ...

  2. Eclipse插件开发 学习笔记 PDF 第一篇到第四篇 免分下载 开发基础 核心技术 高级进阶 综合实例

    <<Eclipse插件开发 学习笔记>>,本书由浅入深.有重点.有针对性地介绍了Eclipse插件开发技术,全书分为4篇共24章.第一篇介绍Eclipse平台界面开发的基础知识 ...

  3. [译]PrestaShop开发者指南 第一篇 基础

    # 第一篇 基础 PS(PrestaShop简称)一开始就设定了能够在它的基础上很简单的构建第三方模块的机制,让它成为一款具有极高定制性的电子商务软件. PS的可以在三个方面进行定制: * 主题 * ...

  4. 译 PrestaShop开发者指南 第二篇 代码规范

    原文:<http://doc.prestashop.com/display/PS15/Coding+Standards> 废话不多译了,讲重点. 代码风格验证工具:CodeSniffer( ...

  5. SQL学习指南第四篇

    SQL必知必会(第4版)学习笔记 插入数据 插入有几种方式: 插入完整的行 插入行的一部分 插入某些查询的结果(INSERT SELECT) 注意:省略列 如果表的定义允许,则可以在 INSERT 操 ...

  6. Angular开发者指南(四)控制器

    了解控制器controller 在AngularJS中,Controller由JavaScript构造函数定义,用于扩充AngularJS Scope. 当控制器通过ng-controller指令连接 ...

  7. 第四篇T语言实例开发,自动加血

    游戏自动加血 基础知识复习 通过前面的学习了解以下内容: TC软件的基本使用 TC的基础语法 变量与常量 功能的使用 流程语句的使用 线程的基本使用 TC控件的基本使用 热键和按钮的事件功能 控件的数 ...

  8. springboot第四篇:debug模式开发运用

    前提:项目是以maven project结构建立的,现状是无法进行断点调试的.怎么才能在eclipse里进行调试呢? 需要:①将项目打包部署到tomcat ②往项目加入dynamic web modu ...

  9. 解剖SQLSERVER 第十四篇 Vardecimals 存储格式揭秘(译)

    解剖SQLSERVER 第十四篇    Vardecimals 存储格式揭秘(译) http://improve.dk/how-are-vardecimals-stored/ 在这篇文章,我将深入研究 ...

随机推荐

  1. AchartEngine绘图引擎

    https://code.google.com/p/achartengine/  Code Test代码: /workspace/AChartEngineTest   /workspace/appco ...

  2. Spring MVC 事务配置

    Spring MVC事务配置 要了解事务配置的所有方法,请看一下<Spring事务配置的5种方法> 本文介绍两种配置方法: 一.      XML,使用tx标签配置拦截器实现事务 一.   ...

  3. 新一代服务器性能测试工具Gatling

    新一代服务器性能测试工具Gatlinghttp://automationqa.com/forum.php?mod=viewthread&tid=2898&fromuid=2

  4. Cubieboard2裸机开发之(五)看门狗操作

    前言 说到看门狗,应该不会陌生,看门狗说白了就是一个定时器,但是它有一个非常重要的功能就是复位系统.在A20里,看门狗的操作非常简单,只有两个寄存器,不需要操作时钟相关的东西,系统起来后可以直接使用, ...

  5. Android实战技巧:深入解析AsyncTask

    AsyncTask的介绍及基本使用方法 关于AsyncTask的介绍和基本使用方法可以参考官方文档和Android实战技巧:多线程AsyncTask这里就不重复. AsyncTask引发的一个问题 上 ...

  6. an introduction to conditional random fields

    1.Structured prediction methods are essentially a combination of classification and graphical modeli ...

  7. Ubuntu 配置AP总结

    1.这个是使用别人写的一个GUI来配置,:http://hi.baidu.com/lexiangtaotao/item/5d4e87f22db132c70cd1c86f 2.使用hostapd配置:h ...

  8. easyui textbox event 添加

    $('#tt').textbox({ inputEvents:$.extend({},$.fn.textbox.defaults.inputEvents,{ keyup:function(e){ co ...

  9. [转]C# 文本框只能输入数字

    调用TextBox的KeyPress事件 private void txtUserId_KeyPress(object sender, KeyPressEventArgs e){ //如果输入的不是数 ...

  10. log4net各种Filter使用

    log4net里面的filter类常用的为: 1.DenyAllFilter 拒绝所用的日志输出 <filter type="log4net.Filter.LevelMatchFilt ...