譯PrestaShop開發者指南第四篇深入PrestaShop核心開發
## 訪問資料庫
### 資料庫結構
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獨立站REST
- PrestaShop網站漏洞修復如何修復REST網站
- 使用命令列指令碼安裝PrestaShop1.6命令列指令碼REST
- PrestaShop 1.7 使用者付款的時候無法支付錯誤REST
- Coingate與Prestashop合作,為歐洲八萬商家提供加密貨幣接收服務REST加密
- PrestaShop1.7訂單生成後下載伺服器出現505的錯誤REST伺服器
- Bran的核心開發指南(5)
- 【譯】JavaScript 原型的深入指南JavaScript原型
- [譯] 使用 Architecture Components 開發 MVVM 應用:MVP 開發者的實踐指南MVVMMVP
- [譯] 寫給前端開發者的 GraphQL 指南前端
- [自譯]給Web開發者的VR指南WebVR
- 《深入核心的敏捷開發》讀書筆記(2)敏捷筆記
- 記憶體安全週報第102期 | 威脅行為者利用PrestaShop中的0day漏洞記憶體REST
- Sentry 開發者貢獻指南 - SDK 開發(事件負載)事件負載
- Sentry 開發者貢獻指南 - SDK 開發(效能監控)
- [譯] 寫給 React 開發者的自定義元素指南React
- 給Android開發者的Flutter指南 (下) [翻譯]AndroidFlutter
- 給Android開發者的Flutter指南 (上) [翻譯]AndroidFlutter
- python開發第四篇–函式Python函式
- [譯] 寫給“老派” Web 開發者的“現代” JavaScript 指南WebJavaScript
- 公開“Google開發者文件風格指南”Go
- 用友開發者中心全新升級,YonBuilder移動開發入門指南UI移動開發
- 開發指南
- 針對web開發者的瀏覽器快取指南(譯)Web瀏覽器快取
- PHP核心介紹及擴充套件開發指南—類和物件PHP套件物件
- [譯] 2018 年 iOS 開發找工作完全指南iOS
- WWDC 2018:寫給 OpenGL 開發者們的 Metal 開發指南
- GCC開發指南GC
- Harmony OS 開發避坑指南——原始碼下載和編譯原始碼編譯
- 開源Android容器化框架Atlas開發者指南Android框架
- 開發者演講指南
- 深入探索Chrome開發者工具:開發者的利器Chrome
- SuperTextView 最全開發指南TextView
- ADO 開發指南
- [譯] App架構指南之開山篇APP架構
- [譯]深入FlutterFlutter
- Android開源專案第四篇:開發及測試工具篇Android
- [翻譯]現代java開發指南 第一部分Java