1.数据库结构
表名都是以_ps前缀开头,这个可以再安装过程中进行指定
所有表名是小写的,单词用下划线_分割
当一个表建立了两个实体的连接,两个实体的名字会再表名中被提到,举个例子。
ps_category_product连接了商品和他们的分类
一些细节;
用id_lang 字段存储语言关联一条记录
用id_shop字段存储商店关联一条记录
表包含翻译必须用_lang结尾, 例如ps_product_lang包含所有关于ps_product表的翻译
表包含记录一个指定商店连接,必须以_shop结尾,例如,ps_category_shop包含每个类别取决于店面的位置。
0bjectModel类
这个主要对象,在Prestashp对象模型中,它可以被覆盖和预处理。
它是一个活动记录类型的类。
prestashop的数据库表属性或者视图属性是封装在类当中的,
因此,类是和数据库记录相关联的,在对象被初始化之后,一个记录被加到数据库中,
每一个对象检索它的数据。从数据库中,当一个对象被更新,被绑定的记录也会被更新,类实现存取每一个属性
定义一个model
你必须用$definition 静态变量来定义一个model
举例:
/** * 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), ), );
一个model,对于许多商店或者语言
为了让一个对象可以用多语言
'multilang' => true
为了让一个对象取决于当前商店
'multishop' => true
为了让对象取决于当前商店,而且有多种语言
'multilang_shop' => true
主要方法:
任何覆盖的方法会影响到所有其他类和方法,小心使用:
__construct($id = NULL, $id_lang = NULL) |
建立对象 |
add($autodate = true, $nullValues = false) |
保存当前对象到数据库(增加或更新) |
associateTo(integer|array $id_shops) | 关联一个项 |
delete() |
删除当前对象,从数据库 |
deleteImage(mixed $force_delete = false) | 删除对象关联的图片 |
deleteSelection($selection) |
删除几个对象,从数据库 |
getFields() |
为对象模型类准备字段 |
getValidationRules($className = _CLASS_) |
返回对象验证规则(字段验证) |
save($nullValues = false, $autodate = true) |
保存当前对象到数据库(增加或者更新) |
toggleStatus() |
切换对象状态,在数据库中 |
update($nullValues = false) |
更新当前对象到数据库 |
validateFields($die = true, $errorReturn = false) |
在与数据库互动之前检查字段 |
DBQuery 类
DBQuery类是一个查询创建器,帮助你创建SQL查询,举例:
$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);
一些类的常用方法:
where(string $restriction) | 增加一个WHERE子句(每个控制条件将以AND分割) |
string build() | 生成或者给到一个查询 |
select(string $fields) | 增加字段到查询的SELECT中 |
orderBy(string $fields) | 增加一个排序字句 |
naturalJoin(string $table, string $alias = null) | 增加一个自然连接 |
limit(string $limit, mixed $offset = 0) | 限定查询结果行数 |
leftOuterJoin(string $table, string $alias = null, string $on = null) | 增加一个左外连接 |
leftJoin(string $table, string $alias = null, string $on = null) | 增加左连接 |
join(string $join) | 增加join表连接 |
innerJoin(string $table, string $alias = null, string $on = null) | 增加inner join 表连接 |
having(string $restriction) | 增加HAVING子句(每一个约束讲以AND分割) |
groupBy(string $fields) | 增加GROUP子句 |
from(string $table, mixed $alias = null) | 设定FROM子句 |
__toString() | 生成SQL语句的字符串 |
路径
路径是1.5版本的特色功能之一,它控制URL的重定向,替代使用个目录下多个文件,例如product.php,order.php 或者category.php, 只有一个文件被使用:index.php, 从现在开始,内部URL会是这种样子:index.php?controller=category, index.php?controller=product, 等等
另外,路径支持URL重写,因此,当URL重写被关闭,prestaShop将使用以下格式的路径:
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=1
如果开启了URL重写,(或者友好连接),PrestaShop的路径会支持像这样的格式
http://myprestashop.com/en/3-music-ipods http://myprestashop.com/en/1-ipod-nano.html
有这些优点:
很简单来增加一个controller
你可以用自定义路由规则来改变你的油耗连接(对于SEO更好)
只有一个单独的入口进入到软件内部,提高了prestashop的可靠性,更容易开发。
调节器使用了3个新的1.5的抽象类:Controller, FrontController和AdminController(后两个继承字第一个)
新的路由规则可以用覆盖loadRoutes()方法来创建
商店管理员可以改变一个controller的路径,使用"SEO & URLs" 页面,在后台,“Preference”菜单下
Controllers
在MVC结构中,一个controller管理同步化事件,在View和Model之间,保持他们同步更新,它接受所有用户事件和触发操作到前台展示。
如果一个操作需要数据被更新,控制器将 “告知” Model来更改数据,然后是Model通知View数据已经被改变,让View可以自我更新
所有PrestaShop的controller 确实覆盖了Controller类,通过其他继承类,比如说AdminController, ModuleAdminController,FrontController, 或者ModuleFrontController.
FrontController类
$template |
页面内容的模板名. |
$p | 当前页数 |
$orderWay | 降序或者升序排列. |
$orderBy | 按照哪个字段排序. |
$n | 每页显示的数量. |
$js_files | JS文件的数组. |
$iso | ISO 编码,当前选择则的语言. |
$initialized | init()方法是否被调用过 . |
$guestAllowed | guest用户是否被允许访问本页. |
$errors | 错误信息的数组. |
$css_files | CSS文件的数组. |
$ajax |
Ajax参数被请求的,设置这个参数为true |
执行controller方法的顺序
1.__contruct():配置所有控制器的成员变量
2.init():初始化控制器
3.setMedia()
or setMobileMedia()
:增加所有JS和CSS脚本到页面,他们可以整合,压缩,缓存(请查看prestashop的CCC工具,在后台的“performance”页面,在Advanced preferences 菜单下面)
4.postProcess():控制ajax进程
5.initHeader(): 在initContent()之前
6.initContent(): 在initHeader()之后
7.initFooter():在initContent()之后
8.display() 或者 displayAjax():显示内容
本来存在的一些Controllers
AddressController.php | 编辑一个客户的一个地址 |
AddressesController.php | 编辑一个客户的多个地址 |
AuthController.php | 处理用户登陆 |
BestSalesController.php | 获取销售排行 |
CartController.php | 管理用户的购物车 |
CategoryController | 获取商品分类 |
CMSController.php | 获取一个CMS页面 |
CompareController.php | 比较商品. |
ContactController.php | 发送信息 |
DiscountController.php | 获取一个用户的抵用券 |
GuestTrackingController.php | 管理游客订单 |
HistoryController.php | 获取一个客户订单 |
IdentityController.php | 获取用户的信息 |
IndexController.php | 显示首页 |
ManufacturerController.php | 获取制造商 |
MyAccountController.php | 管理用户账号 |
NewProductsController.php | 获取新商品 |
OrderConfirmationController.php | 订单确认 |
OrderController.php | 管理五步结账流程 |
OrderDetailController.php | 获取一个订单详细信息 |
OrderFollowController.php | 获取一个用户的退货信息. |
OrderOpcController.php | 管理one-page结账流程. |
OrderReturnController.php | 获取一个制造商的退货信息. |
OrderSlipController.php | 获取一个客户的信用卡售货单 |
PageNotFoundController.php | 管理“页面没找到”页面. |
ParentOrderController.php | 管理分享订单代码 |
PasswordController.php | 重置丢失密码. |
PricesDropController.php | 获取打折的商品. |
ProductController.php | 获取一个商品. |
SearchController.php | 获取搜索结果. |
SitemapController.php | 获取 sitemap. |
StoresController.php | 获取商店信息 |
SupplierController.php | 获取供应商 |
覆盖一个controller
多亏了对象继承,你可以更改controller的行为,或者增加一个新的
PrestaShop的控制器都被存放在/controllers目录下面, 而且使用“Core”后缀
举例:
File: /controllers/CategoryController.php Class: CategoryControllerCore
为了覆盖一个controller,你必须先创建一个新的类,不包含Core后缀,然后放到/override/controllers目录下面
例如:
File: /override/controllers/front/CategoryController.php Class: CategoryController
Views
PrestaShop使用Smarty模板引擎:http://www.smarty.net/
视图文件以.tpl保存
一个视图名通常和代码脚本名字一样例如404.php 使用404.tpl
View覆盖
因为没有继承,所以不能覆盖一个视图
为了换一个视图,你必须重写模板文件,而且把它放到你的主题目录下面
Cookies
Prestashop使用加密cookies,来存储所有会话信息,
对于访问者/客户端,也可以对于职员/管理人模式
Cookie类(/classes/Cookie.php
)被用于读和写cookies
为了接近cookies,你可以用以下方式
$this->context->cookie;
所有存储于cookie当中的变量可以这么访问
$this->context->cookie->variable;
如果你需要使用PrestaShop cookie 从一个非Prestashop代码,你可以用以下代码:
include_once('path_to_prestashop/config/config.inc.php'); include_once('path_to_prestashop/config/settings.inc.php'); include_once('path_to_prestashop/classes/Cookie.php'); $cookie = new Cookie('ps'); // Use "psAdmin" to read an employee's cookie.
被存储在访客/客户端的cookie数据:
viewed | 以逗号形式分割最近访问过的商品ID |
passwd | 以MD5加密方式的_COOKIE_KEY_ 在 config/settings.inc.php中配置,用户登陆后的密码 |
logged | 用户是否已经登录 |
last_visited_category | 最后访问的分类ID |
id_wishlist | 当前收藏夹,显示在收藏夹区域 |
id_lang | 选中的语言ID |
id_guest | 未登录状态的游客ID |
id_customer | 登陆状态的顾客ID |
id_currency | 选择的货币ID |
id_connections | 当前访问者的会话连接ID |
id_cart | 当前购物车的ID |
用户过去经常登录的Email地址 | |
date_add | cookie创建的时间 |
customer_lastname | 客户的姓氏 |
customer_firstname | 客户的名字 |
checksum | 校验cookie是否被第三方修改,用户将注销,cookie会被清除,如果校验不匹配的话 |
checkedTOS | 服务条款复选框是否被勾选(1:勾选。0:未勾选) |
ajax_blockcart_display | 购物车区块是展开的还是闭合的 |
存储于 职员/管理员中的cookie
date_add | 创建的时间 |
id_lang | 选中的语言 |
id_employee | 职员的id |
lastname | 职员姓氏 |
firstname | 职员名字 |
职员邮箱地址 | |
profile | 资料的ID,决定哪个TAB是职员可以访问的 |
passwd | MD5加密的_COOKIE_KEY 在config/settings.inc.php中配置的,职员登陆用的密码 |
checksum | 验证cookie是否有被第三方修改,如果验证不通过,会被登出,然后清除cookie |
Hooks
Hooks 是用于关联你的代码到一些特殊的PrestaShop的事件
大多数时间,他们用于插入内容到一个页面
举个例子
PrestaShop默认主题的主页有以下Hooks
displayHeader | 显示页面头部区域的内容. |
displayTop | 显示页面顶部区域的内容 |
displayLeftColumn | 显示左侧边栏的内容 |
displayHome | 显示中间区块的内容 |
displayRightColumn | 显示右边栏的内容. |
displayFooter | 显示页脚的内容. |
Hooks可以被用于显示特殊操作,(比如说发送一个邮件给客户)
使用Hooks
在一个controller内
调用一个hook在一个controller内,你只需要使用他的名字,用hookExce()方法
例如
$this->context->smarty->assign('HOOK_LEFT_COLUMN', Module::hookExec('displayLeftColumn'));
在module中,
为了绑定你的代码到一个hook上,你必须创建一个非静态共用方法,以hook关键字开始后边跟Display或者action还有你想取的名字
这个方法接受一个(只有一个)参数:一个数组。一个上下文信息要传送给hook的数组
public function hookDisplayNameOfHook($params) { // Your code. }
为了让一个module相应到一个hook的调用,hook必须被注册到prestaShop, hook注册可以用registerHook()方法,注册是将在模块安装的时候被完成
public function install() { return parent::install() && $this->registerHook('NameOfHook'); }
在主题内:
在一个tpl文件中,你只需要使用hook方法,你可以添加一个想要挂钩的module的名字。
{hook h='displayLeftColumn' mod='blockcart'}
增加你自己的hook:
你可以增加一个新的PrestaShop钩子,用以下SQL语句
INSERT INTO `ps_hook` (`name`, `title`, `description`) VALUES ('nameOfHook', 'The name of your hook', 'This is a custom hook!');
但是你需要知道,在1.5版本中不需要这样做
现在当你的模块执行安装方法,你想要注册一个钩子。你可以这么做:
$this->registerHook('NameOfHook');
如果钩子”NameOfHook“ 不存在,PrestaShop将创建,没有必要执行SQL语句。