zoukankan      html  css  js  c++  java
  • 【shopex】真正可用的app开发机制

    shopex的app开发机制详解

     

    网上流传的shopex4.8.5的app开发教程,不仅说得不明不白,而且由于版本问题,照着做根本是做不成的。

    知其然,亦要知其所以然。


    shopex提供了的一个干净的机制让开发者扩展或修改功能-app开发机制,让我们可以实现以下特性:

        1、建立自己的数据库表。
     2、创建自己的控制器。
     3、在前后台增加栏目。
     4、用自己的控制器替换系统默认的(自定义业务流程)。
     5、添加事件侦听器,使得系统事件时调用自己的代码。

    可以看到,这基本相当提供给大家一个简单的php框架了。下面说下技术细节。

    每个程序包占一个目录。 我们推荐将所有的包都放置在plugins/app文件夹下。下面用个例子, 阐述下功能包的各个控制点。假设这个文件夹的名字为:demo, 包里面必须有一个 app.demo.php。并且里面必须含有一个 app_demo的类。该类需要继承app这个基类。

    下面我们一个小例子来阐述下这种app功能包基本开发步骤:

        1、在网站根目录的/plugins/app目录下创建demo目录,那么同时这个文件下面就必须要有个app.demo.php文件,此文件可以如下定义:

     1 <?php
     2 class app_demo extends app{
     3 
     4     var $ver = 0.8;
     5     var $name='样例程序';
     6     var $website = 'http://www.shopex.cn';
     7     var $author = 'dev@shopex.cn';
     8 
     9     //可选函数
    10     //定义接管系统哪些流程,由自身的哪个类/方法去执行
    11     //本例表示,启用后前台将把所有访问购物车的控制器请求重定向
    12     //到本软件包内 democtl对象的cartidx方法里。
    13     function ctl_mapper(){
    14         return array(
    15             'shop:cart:index' => 'ctl:cartidx',//注意这里,文档是使用demo_ctl需要加app命名_前缀,实际不需要
    16         );
    17     }
    18 
    19     //可选函数
    20     //侦听系统哪些事件
    21     //此处可用关键字any表示所有事件
    22     //本例表示:
    23     //侦听订单新建事件 -> 调用event_handle类的order_new方法执行
    24     //侦听会员新建事件 -> 调用event_handle类的member_create方法执行
    25     function listener(){
    26         return array(
    27             'trading/order:create' =>
    28                 'demo_event_handler:order_new',
    29 
    30             'member/account:register' =>
    31                 'demo_event_handler:member_create',
    32 
    33             //'any'=>'demo_event_handler:any',
    34         );
    35     }
    36 
    37     //可选函数, 返回需要建表的信息
    38     //本例是建立两个表, 系统会自动加前缀 sdb_<ident>
    39     function dbtables(){
    40         $tables['table_2'] = array (
    41             'columns' =>
    42             array (
    43                 'controller' =>
    44                 array (
    45                     'type' => 'varchar(100)',
    46                     'required' => true,
    47                     'pkey' => true,
    48                     'editable' => false,
    49                 ),
    50                 'plugin' =>
    51                 array (
    52                     'type' =>'varchar(100)',
    53                     'required' => true,
    54                     'editable' => false,
    55                 ),
    56             ),
    57         );
    58         $tables['table_1'] = array (
    59             'columns' =>
    60             array (
    61                 'controller' =>
    62                 array (
    63                     'type' => 'varchar(100)',
    64                     'required' => true,
    65                     'pkey' => true,
    66                     'editable' => false,
    67                 ),
    68                 'plugin' =>
    69                 array (
    70                     'type' =>'varchar(100)',
    71                     'required' => true,
    72                     'editable' => false,
    73                 ),
    74             ),
    75         );
    76         return $tables;
    77     }
    78 
    79     
    80     //我承认这是个非常邪恶的设计...
    81     //但你要承认它可以让你无所不能
    82     function output_modifiers(){
    83         return array(
    84          'admin:goods/product:index'=>'modifiers:product_edit'
    85         );
    86     }
    87 
    88     //重载安装时的方法...
    89     //同样可重载的还有:
    90     //   uninstall -> 卸载
    91     //   enable -> 程序启动
    92     //   disable -> 程序关闭
    93     function install(){
    94         //别忘了调用父类的install
    95         return parent::install();
    96     }
    97 
    98 }

        2、为了防止命名冲突,请使用自己包的名字作为类的前缀,文件plugins/app/demo/demo_event_handler.php,这里的是对应上面的app.demo.php定义的与系统的本身的方法对接,该文件的代码如下:

     1 <?php
     2 class demo_event_handler{
     3 
     4     //订单新建时本方法将被自动执行
     5     //此处event被赋值为 order:new
     6     function order_new($event_type,$order_data){
     7         ...
     8     }
     9 
    10     //会员新建时本方法将被自动执行
    11     //此处event被赋值为 order:new
    12     function member_create($event_type,$member_data){
    13         ...
    14     }
    15 
    16     //任何事件都将调用此函数
    17     function any($event_type,$event_data){
    18         ...
    19     }
    20 }

        3、例如与前台购物车操作对接,我们可以定义一下文件来实现此功能,如文件plugins/app/demo/demo_ctl.php,代码如下:

        *注意,旧版是继承app_page类,实际上并没有这个类文件,真正要操作前台页面,需要继承shopPage类,且不需额外加载

     1 <?php
     2 class demo_ctl extends shopPage{
     3 
     4     function cartidx(){
     5         //输出模板:软件包文件夹里的cart.html
     6         //$this->system; //可以调用系统入口
     7         //$this->db; //可以直接使用数据库
     8 
     9         //载入包里的类...
    10         //require(dirname(__FILE__).'/demo_my_model_layer.php');
    11         //$obj = new demo_my_model_layer;
    12 
    13         $this->output('view/cart.html');
    14     }
    15 
    16 }

        4、建立一个类来重定义购物车页面用关键字<{$_BASE_PATH_}>可以定位到插件文件夹的url,如我们建立一个模板文件plugins/app/demo/view/cart.html在文件里面我们就可以使用此关键词

    <p>
    例如输出<br />
    plugins/app/demo/images/cart.png
    </p>
    
    <img src="<{$_BASE_PATH_}>/images/cart.png" />

    5,附:【过滤器】将后台商品列表页面的“新建商品”按钮上的文字换掉。 

    <?php
    class demo_modifiers{
        function product_edit( &$content ){
            return str_replace('添加商品','别看我是只羊!',$content);
        }
    }

    6,此时后台工具箱->插件与扩展->刷新插件数据库->应用中心 你就可以看到你新增的插件,点击启用,即进入安装流程:

    确认后打开你所接管的控制器方法,如例子中的购物车首页,你会发现并没有成功,而是提示

    对不起,无法找到您访问的页面,请返回重新访问。

     其实这就是shopex代码和手册的矛盾之处,系统核心是只能加载app对象的index方法action,手册上写明可以接管系统流程具体到某个action,否则app就失去了他的意义了。

    要修改有两种方法:

    1,在demo_ctl,即app前台控制器,以index方法为入口,去操作其他类方法(毕竟核心文件已加密,改不了);

    2,修改kernel.php,在callAction方法中将

    list( $objCtl, $act_method ) = $appmgrMdl->get_func( substr( $value, 0, strrpos( $value, ":" ) ).":".$act_method );
    修改为:
    list( $objCtl, $act_method ) = $appmgrMdl->get_func( $value );

    然后继续愉快地开发app扩展。

     

  • 相关阅读:
    496 服务器渲染 VS 客户端渲染
    495 队列,优先级队列
    493 JS中数据类型检测的四种方案
    492 js的继承:原型继承,CALL继承,寄生组合式继承,ES6中的类和继承
    491 CALL和APPLY以及BIND语法(含BIND的核心原理),CALL和APPLY的应用(类数组借用数组原型方法),CALL源码解析及阿里面试题
    490 JavaScript的this的五种指向
    488 DOM0和DOM2事件绑定的原理、使用、区别
    487 函数的三种角色:普通函数,构造函数(类),普通对象,原型链清明上河图
    486 原型及原型链模式:3个重要知识点,从面向对象角度来讲解内置类,hasOwnProperty,原型链方法中的THIS问题,基于内置类的原型扩展方法
    485 面向对象:单例设计模式,工厂模式,什么是面向对象,构造函数,instanceof,构造函数中的局部变量以及new构造函数时不加括号
  • 原文地址:https://www.cnblogs.com/GaZeon/p/7625723.html
Copyright © 2011-2022 走看看