我们把接下来的这个模块命名为“TutorialSecond”。所以还得创建一个新的模块目录和类文件,分别是“tutorialsecond” 和 “tutorialsecond.php”。类文件(tutorialsecond.php) 需要包含下面的代码:
view plaincopy to clipboardprint?
1. <?php
2. class Tutorialsecond extends Module
3. {
4. private $_html = '';
5.
6. function __construct()
7. {
8. $this->name = 'tutorialsecond';
9. parent::__construct();
10.
11. $this->tab = 'mypresta.cn Tutorials';
12. $this->version = '0.1.0';
13. $this->displayName = $this->l('Second Tutorial Module');
14. $this->description = $this->l('Our second module - A "Hello world" redux');
15. }
16.
17. public function getContent()
18. {
19.
20. }
21.
22. private function _displayForm()
23. {
24.
25. }
26.
27. }
28. // End of: tutorialsecond.php
29. ?>
<?php class Tutorialsecond extends Module { private $_html = ''; function __construct() { $this->name = 'tutorialsecond'; parent::__construct(); $this->tab = 'mypresta.cn Tutorials'; $this->version = '0.1.0'; $this->displayName = $this->l('Second Tutorial Module'); $this->description = $this->l('Our second module - A "Hello world" redux'); } public function getContent() { } private function _displayForm() { } } // End of: tutorialsecond.php ?>
你也许会注意到我们实现了两个新的成员函数::getContent() 和 ::_displayForm()。如果你把文件安装到服务器上,你会在模块列表里看到模块“Second Tutorial Module”有个新的选项。这个新选项是一个“>> Configure”链接,显示在模块项中,虽然你点它只是返回一个后台的几乎空白页面。成员函数::getContent()的作用就是为模块提供后台接口(页面)。
除了这两个方法,我们还增加了私有成员变量$_html private,待会我们用它来构建必要的后台输出页面。
保存和读取配置数据
Prestashop有一个“Configuration”类,它提供了几个操作配置数据的函数,但常用的是两个主要函数:
view plaincopy to clipboardprint?
1. Configuration::updateValue($key, $values, $html = false);
2. Configuration::get($key, $id_lang = NULL);
Configuration::updateValue($key, $values, $html = false); Configuration::get($key, $id_lang = NULL);
Configuration::updateValue() 函数用来存储配置项到数据库里(在多语言环境中,$values为数组), Configuration::get()函数用来读取配置,以某个选择的语言或店铺默认语言。目前,我们先忽略那些有默认值的参数,但会在下篇关于表单验证的文章中的Configuration::updateValue()函数再次用到 $html 参数。
实现配置页面
在我们的源文件里,我们创建了一个私有成员函数_displayForm()。尽管这个方法完全是可选的,我们可以把所有的页面代码放在 getContent()成员函数中,但我们还是推荐把它分离出来,便于代码维护。我们要在这个方法里创建一个表单,用类接受用户输入。
view plaincopy to clipboardprint?
1. private function _displayForm()
2. {
3. $this->_html .= '
4. <form action="'.$_SERVER['REQUEST_URI'].'" method="post">
5. <label>'.$this->l('Message to the world').'</label>
6. <div class="margin-form">
7. <input type="text" name="our_message" />
8. </div>
9. <input type="submit" name="submit" value="'.$this->l('Update').'" class="button" />
10. </form>';
11. }
private function _displayForm() { $this->_html .= ' <form action="'.$_SERVER['REQUEST_URI'].'" method="post"> <label>'.$this->l('Message to the world').'</label> <div class="margin-form"> <input type="text" name="our_message" /> </div> <input type="submit" name="submit" value="'.$this->l('Update').'" class="button" /> </form>'; }
你可以看到,::_displayForm()函数只是简单地把标准的html表单代码添加到 $_html 成员变量中,表单的target是$_SERVER['REQUEST_URI']。当Post提交表单时,Presstashop的后台框架会为我们将把这个请求自动定向到类成员函数::getContent。
下一步是在::getContent()函数添加代码,以显示表单和处理提交。
view plaincopy to clipboardprint?
1. public function getContent()
2. {
3. if (Tools::isSubmit('submit'))
4. {
5. Configuration::updateValue($this->name.'_message', Tools::getValue('our_message'));
6. }
7.
8. $this->_displayForm();
9.
10. return $this->_html;
11. }
public function getContent() { if (Tools::isSubmit('submit')) { Configuration::updateValue($this->name.'_message', Tools::getValue('our_message')); } $this->_displayForm(); return $this->_html; }
函数::getContent()首先使用Prestashop工具类“Tools”的方法检测是否在处理action为POST的提交,又或者是通过其他方式调用到的,比如在模块列表里点击“Configure”链接,这时的参数就是我们赋给表单的“update”按钮的名称。
如果这个函数被直接从后台调用(这种情况下Tools::isSubmit(’submit’)返回的是false),就会直接调用前面创建的表单绘制函数,并把结果赋给$this->_html变量以在后台显示。
如果这个函数是通过表单POST请求调用的,我们就可以把表单上输入的配置参数存到数据库。这里再一次用到了Tools类来获取表单变量,方法是 Tools::getValue("our_message"),其中"our_message"是表单上的input元素的名字。
你会看到我把模块名称加在了配置项的前头 — 这是使用它作为这些配置的命名空间来确保它们在整个店铺中是唯一的。
在存完数据之后,表单还是会显示的,如果需要的话,可以多输入几次。
在页面显示模块内容
现在我们有了一个可以获取用户输入并存储DB的方法,显然下面是要拿它来做点什么,比如在页面上显示出来。在第一步里,我们谈到了“hooks”与模块添加功能有关的。要用到这点,我们需要告诉Prestashop我们的模块需要挂载到前台页面,那就是使用下面的函数(基类Module里定义的):
view plaincopy to clipboardprint?
1. $this->registerHook($hook_name);
$this->registerHook($hook_name);
参数 $hook_name 是指Prestashop内核允许模块添加内容或者数据处理的各个点。目前,我们用一个比较常用的 — “leftColumn’,它让我们在所有页面左侧添加内容。要实现挂载,我们需要在自己的类里象下面这样覆盖一个方法:
view plaincopy to clipboardprint?
1. public function install()
2. {
3. parent::install();
4.
5. if (!$this->registerHook('leftColumn'))
6. return false;
7. }
public function install() { parent::install(); if (!$this->registerHook('leftColumn')) return false; }
它告诉Prestashop,在绘制所有页面的左侧时执行我们模块的挂载功能。下一步是添加一个方法处理挂载回调。函数名的约定是在挂载点名的前面加上“hook”:
view plaincopy to clipboardprint?
1. public function hookLeftColumn()
2. {
3. return '<div class="block"><h4>'. Configuration::get($this->name.'_message') . '</h4></div>';
4. }
public function hookLeftColumn() { return '<div class="block"><h4>'. Configuration::get($this->name.'_message') . '</h4></div>'; }
在我们的简单示例中,我们仅仅是用html标签把配置参数包了下,让它能正确显示在页面上。
如果之前装过了这个模块,需要把它卸载再安装,确保挂载正确地注册到Prestashop内核里去了。现在你可以在模块的配置页面输入值了,比如“Hello World”,它会作为店铺左侧页面的一个内容块的标题显示出来。第二个例子的完整代码在这里:
view plaincopy to clipboardprint?
1. <?php
2. class Tutorialsecond extends Module
3. {
4. private $_html = '';
5.
6. function __construct()
7. {
8. $this->name = 'tutorialsecond';
9. parent::__construct();
10.
11. $this->tab = 'mypresta.cn Tutorials';
12. $this->version = '0.1.0';
13. $this->displayName = $this->l('Second Tutorial Module');
14. $this->description = $this->l('Our second module - A "Hello world" redux');
15. }
16.
17. public function install()
18. {
19. parent::install();
20.
21. if (!$this->registerHook('leftColumn'))
22. return false;
23. }
24.
25. public function getContent()
26. {
27. if (Tools::isSubmit('submit'))
28. {
29. Configuration::updateValue($this->name.'_message', Tools::getValue('our_message'));
30. }
31.
32. $this->_displayForm();
33.
34. return $this->_html;
35. }
36.
37. private function _displayForm()
38. {
39. $this->_html .= '
40. <form action="'.$_SERVER['REQUEST_URI'].'" method="post">
41. <label>'.$this->l('Message to the world').'</label>
42. <div class="margin-form">
43. <input type="text" name="our_message" />
44. </div>
45. <input type="submit" name="submit" value="'.$this->l('Update').'" class="button" />
46. </form>';
47. }
48.
49. public function hookLeftColumn()
50. {
51. return '<div class="block"><h4>'. Configuration::get($this->name.'_message') . '</h4></div>';
52. }
53.
54. }
55. // End of: tutorialsecond.php
56. ?>
<?php class Tutorialsecond extends Module { private $_html = ''; function __construct() { $this->name = 'tutorialsecond'; parent::__construct(); $this->tab = 'mypresta.cn Tutorials'; $this->version = '0.1.0'; $this->displayName = $this->l('Second Tutorial Module'); $this->description = $this->l('Our second module - A "Hello world" redux'); } public function install() { parent::install(); if (!$this->registerHook('leftColumn')) return false; } public function getContent() { if (Tools::isSubmit('submit')) { Configuration::updateValue($this->name.'_message', Tools::getValue('our_message')); } $this->_displayForm(); return $this->_html; } private function _displayForm() { $this->_html .= ' <form action="'.$_SERVER['REQUEST_URI'].'" method="post"> <label>'.$this->l('Message to the world').'</label> <div class="margin-form"> <input type="text" name="our_message" /> </div> <input type="submit" name="submit" value="'.$this->l('Update').'" class="button" /> </form>'; } public function hookLeftColumn() { return '<div class="block"><h4>'. Configuration::get($this->name.'_message') . '</h4></div>'; } } // End of: tutorialsecond.php ?>
综述