有没有ZenCart的一些资料,原码分析

解决方案 »

  1.   

    zencart开发之观察者模式
    通过重写机制和自动加载机制, Zen-Cart使得二次开发人员能够很方便的向核心代码中增加自己的功能, 然而开发者并不能在不破坏原始代码的基础上随意向Zen-Cart核心代码中的不同地方增加自己的代码. 因此, Zen-Cart引入了通知者/观察者模式(observer/notifier system, ONS), 这给开发人员提供了访问Zen-Cart核心代码, 而不需要破坏其原始文件内容的方式.
        第1节  基类base
          为了实现通知者/观察者模式, 首先引入一个重要的类: base类(class.base.php).
          base类中包含了实现通知者/观察者模式的代码,  因此为了使通知者/观察者模式生效, Zen-Cart中的所有类都被定义为base类的子类, 任意打开一个类文件, 例如language.php,你讲可以看到如所示的代码.  如果你希望你自己的类也能够实现通知者/观察这模式, 请将你的类从base类派生.
    class language extends base {
    ….
     第2节   通知者
          ONS的意图是, 开发者可以写代码, 来等待特定的事件发生, 一旦事件发生, 就执行自己的代码. 那么这些事件如何定义, 什么时候触发呢?
          事件可以通过如下面所示的代码来进行触发.
    $this->notify('EVENT_NAME');
     
        第3节   观察者
          事件已经触发了, 可是这对开发者而言又有何用呢? 为了利用通知者的事件, 我们必须编写代码来监听这些事件. 一般而言, 我们需要将观察者编写成一个类, 并放到目录” includes/classes/observers”下面. 下面, 我们就来看一下如何写一个监听事件的观察者类.
     
    <?php
     class myObserver extends base {
       function myObserver() {
         $this->attach($this, array('NOTIFIER_CART_ADD_CART_END'));
       }
       function update(&$callingClass, $notifier, $paramsArray) {
         ... do some stuff
       }
      }
     
     
          从代码中, 可以看到, 我们定义了一个名为myObserver的类, 并且在构造函数中将myObserver类和事件NOTIFIER_CART_ADD_CARD_END(shopping_cart.php)进行了绑定.
    当某个事件被触发时, base类将检测是否有观察者类在监听这个事件, 如果有, base类将执行观察者类中的一个方法,  在这里当NOTIFIER_CART_ADD_CARD_END事件被触发后, update方法将会被执行.
         参数说明:
         attach方法.
             &$observer  - 观察者类的引用, 为新的观察者生成一个唯一的ID
             $eventIDArray  -  要监听的事件数组
         update 方法
             &$callingClass – 触发事件的类的引用, 你可以通过该参数访问类中的变量
             $notifier – 触发update通知者名称, 因为可能会监听到多个通知者触发事件
             $paramsArray – 传递的参数, 通知这可能利用该参数向观察者提供一些参数
     
        第4节   notifier类
          ONS是面向对象的思想而设计, 观察者期望将自己绑定到一个可以在自己方法中进行通知的类, 然而在Zen-Cart中的很多程序事实上并不包含在类中, 例如页面中的代码. 为了使在一般的程序中也能够进行事件的通知, Zen-Cart设计了一个notifier类, 作为全局的一个通知者. 如果你想创建一个类来监听在程序中(例如页面头部文件中的代码)触发的事件, 就应该将notifier加入myObserver类, 如下面代码所示.
     
    class myObserver extends base {
       function myObserver() {
         global $zco_notifier;
         $zco_notifier->attach($this, array('NOTIFY_HEADER_END_CHECKOUT_CONFIRMATION'));
       }
     
        第5节   包含观察者类文件
         值得注意的是”includes/classes/observersdirectory”目录中的文件并不会自动加载, 所以你需要让application_top.php文件能够自动加载myObserver类.在目录” includes/auto_loaders”中增加一个文件”config.freeProduct.php”,文件内容如表格 3 4 代码所示.
     
    $autoLoadConfig[10][] = array('autoType'=>'class',
                                  'loadFile'=>'observers/class.freeProduct.php');
    $autoLoadConfig[90][] = array('autoType'=>'classInstantiate',
                                  'className'=>'freeProduct',
                                  'objectName'=>'freeProduct');
     
        第6节   通知者/观察者模式编程实例
          有时会遇到的一种需求是, 当客户购买了一定数额的商品后, 如果购买的总金额超过指定的数量, 我们希望给客户一个免费的小赠品.
          通过分析后, 可以知道, 当客户增加了商品到购物车后, 会检测是否购买的数量超过了指定的最低消费数量, 则应该自动将该礼品加到客户的购物车, 而如果客户删掉了购物车中的商品, 同样也需要检测, 如果消费总数量已经小于了最低消费数量了, 则应该自动将该礼品从购物车中删除. 按照传统的编程方式, 要实现这个功能也不难, 但是这将在多处对Zen-Cart的核心代码产生破坏. 现在通过ONS, 我们可以通过一个很简单的自定义类来完成这个功能, 并且不会破坏Zen-Cart的核心代码.
     
     通知者/观察者编程实例
    <?php
    /**
     * Observer class used to add a free product to the cart if the user spends more than $x
     *
     */
    class freeProduct extends base {
      /**
       * The threshold amount the customer needs to spend.
       * 客户需要消费的总数
       * Note this is defined in the shops base currency, and so works with multi currency shops
       *
       * @var decimal
       */
      var $freeAmount = 50;
      /**
       * The id of the free product.
       * 赠品的ID
       * Note. This must be a true free product. e.g. price = 0 Also make sure that if you don't want the customer
       * to be charged shipping on this, that you have it set correctly.
       *
       * @var integer
       */
      var $freeProductID = 57;
      /**
       * constructor method
       * 构造方法
       * Attaches our class to the $_SESSION['cart'] class and watches for 2 notifier events.
       */
      function freeProduct() {
        $this->attach($this, array('NOTIFIER_CART_ADD_CART_END', 'NOTIFIER_CART_REMOVE_END'));
      }
      /**
       * Update Method
       * 
       * Called by observed class when any of our notifiable events occur
       *
       * @param object $class
       * @param string $eventID
       */
      function update(&$class, $eventID) {
        if ($_SESSION['cart']->show_total() >= $this->freeAmount && !$_SESSION['cart']->in_cart($this->freeProductID) ) {
          $_SESSION['cart']->add_cart($this->freeProductID);
        }
        if ($_SESSION['cart']->show_total() < $this->freeAmount && $_SESSION['cart']->in_cart($this->freeProductID) ) {
          $_SESSION['cart']->remove($this->freeProductID);
        }
        if ($_SESSION['cart']->in_cart($this->freeProductID)) {
          $_SESSION['cart']->contents[$this->freeProductID]['qty'] = 1;
        }
      }
    }
    ?>
     
         当然,也许由于开发者也不可能考虑的很周全,有时候在代码中不一定在我们想要的地方都进行了事件通知。遇到这种情况,还是有可能对核心代码做少量修改的。但是通过使用观察者模式,还是可以尽量的避免修改其核心代码。