Prestashop 的back office tab 筆記 - Part 4

由於prestashop 升級了1.5.x, 而且佢把入面基本的core 也作出了不少的改動,就連最基本的object class 也改了寫法呢, 當然舊有的寫法還是可以support的, 但新的寫法感覺上不錯而且也更易明,所以就記下新的寫法吧!可以在這裏回憶一下舊的寫法

如果嘗試睇一下ObjectModel這個class就會發現了很多東西也是 @deprecated 1.5.0呢, 其中包括了很多在筆記一所提到的變數呢
/**
 * @deprecated 1.5.0 This property shouldn't be overloaded anymore in class, use static $definition['table'] property instead
 */
protected $table;

/**
 * @deprecated 1.5.0 This property shouldn't be overloaded anymore in class, use static $definition['primary'] property instead
 */
protected $identifier;

/**
 * @deprecated 1.5.0 This property shouldn't be overloaded anymore in class, use static $definition['fields'] property instead
 */
protected $fieldsRequired = array();

/**
 * @deprecated 1.5.0 This property shouldn't be overloaded anymore in class, use static $definition['fields'] property instead
 */
protected $fieldsSize = array();

/**
 * @deprecated 1.5.0 This property shouldn't be overloaded anymore in class, use static $definition['fields'] property instead
 */
protected $fieldsValidate = array();

/**
 * @deprecated 1.5.0 This property shouldn't be overloaded anymore in class, use static $definition['fields'] property instead
 */
protected $fieldsRequiredLang = array();

/**
 * @deprecated 1.5.0 This property shouldn't be overloaded anymore in class, use static $definition['fields'] property instead
 */
protected $fieldsSizeLang = array();

/**
 * @deprecated 1.5.0 This property shouldn't be overloaded anymore in class, use static $definition['fields'] property instead
 */
protected $fieldsValidateLang = array();

從入面可以睇到好多的變數也改變成在definition中設,那就看看我重新寫的object class
public static $definition = array(
 'table' => 'product_fast_get_discount',
 'primary' => 'id_pfgd',
 'fields' => array(
  'id_product' =>  array('type' => self::TYPE_INT, 'validate' => 'isUnsignedInt', 'required' => true),  
  'position' =>  array('type' => self::TYPE_INT, 'validate' => 'isUnsignedInt', 'required' => true),     
  'reduction' =>   array('type' => self::TYPE_FLOAT, 'validate' => 'isPrice', 'required' => true),
  'reduction_type' => array('type' => self::TYPE_STRING, 'validate' => 'isReductionType', 'required' => true),
  'from' => array('type' => self::TYPE_DATE, 'validate' => 'isDateFormat', 'required' => false),
  'to' => array('type' => self::TYPE_DATE, 'validate' => 'isDateFormat', 'required' => false)  
 )
);
新的Object class, 只要設定好definition這個static 變數就可以了,因為入面的'table', 'primary', 'fields' 就已經包含了第筆記一中提到的那些設定..

除此之外,在筆記一中提到要建立的getFieldsgetTranslationsFieldsChild來到1.5+後也不用自己寫了

所以雖然1.5+的確作出了不少的改動,但感覺上在object class 的一part是改得不錯,因為整體來說佢係更加易明同整潔了呢


smarty3 autoload note

Php 有autoload 的功能簡單來說就是只要寫了個__autoload($class_name)之後,佢會當你嘗試create 一些class時佢會訧下行這個function 你設定了的include file

以下是我的__autoload class

 function __autoload($class_name) {
   global $classesDir;
  
   foreach($classesDir as $dir){
       if (file_exists($dir . $class_name . '.php')) {
          include $dir . $class_name . '.php';
       }
   }
}

不過如果你自己define 了這個__autoload之後再加上smarty3時行template 是有機會出現Fatal error: Class 'Smarty_Internal_TemplateCompilerBase' not found in smarty_internal_smartytemplatecompiler.php on line 23 的錯誤呢!

最簡單的簡決方法就係改用spl_autoload_register 把自己的autoload function 加上去, 也就是說把原本的code 加為如下,這樣就可以解決那個Smarty的fatal error了.

function __autoload($class_name) {
   global $classesDir;
  
   foreach($classesDir as $dir){
       if (file_exists($dir . $class_name . '.php')) {
          include $dir . $class_name . '.php';
       }
   }
}

spl_autoload_register('my_autoload');


Prestashop 的back office tab 筆記 - part 3

上一篇筆記成功地建立了一個最基本的檢視頁面,這一次就為admin tab 加入最基本的新增功能吧 (由於prestashop 最近升級了版本, 筆記part 1 至 3, 只適用於1.4.9)

sample code:
 function displayForm(){   
    global $currentIndex;
    $defaultLanguage = intval(Configuration::get('PS_LANG_DEFAULT'));
    $languages = Language::getLanguages();
   
    $obj = $this->loadObject(true);
   
    echo '
        <script type="text/javascript">
            id_language = Number('.$defaultLanguage.');
        </script>';

    echo '
        <form action="' . $currentIndex . '&submitAdd' .  $this->table . '=1&token=' . $this->token . '" method="post" class="width3">
            ' . ($obj->id ? '<input type="hidden" name="id_' . $this->table . '" value="' . $obj->id . '" />' : '').'
            <fieldset><legend><img src="../img/admin/profiles.png" />' . $this->l('Admin Test') . '</legend>
            <label>'.$this->l('Name:').' </label>
            <div class="margin-form">';       
   
    foreach ( $languages as $language )
        echo '
            <div id="test_' . $language['id_lang'|'id_lang'] . '" style="display: ' . ($language['id_lang'|'id_lang'] == $defaultLanguage ? 'block' : 'none') . '; float: left;">
                <input size="33" type="text" name="name_' . $language['id_lang'|'id_lang'] . '" value="' . htmlentities( $this->getFieldValue( $obj, 'name', intval( $language['id_lang'|'id_lang'] ) ), ENT_COMPAT, 'UTF-8' ) . '" /><sup>*</sup>
                <span class="hint" name="help_box">'.$this->l('Allowed characters: letters, spaces and').' ().-<span class="hint-pointer">&nbsp;</span></span>
            </div>';
   
    $this->displayFlags( $languages, $defaultLanguage, 'test', 'test' );
   
    echo '<div class="clear"></div></div>';                 
    echo '<label>'.$this->l('Description:').' </label>
            <div class="margin-form">
            <textarea name="description" rows="10" cols="100">'.htmlentities( $this->getFieldValue( $obj, 'description'), ENT_COMPAT, 'UTF-8' ).'</textarea>';
    echo '<div class="clear"></div></div>
            <div class="margin-form">
            <input type="submit" value="'.$this->l('Save').'" name="submitAdd'.$this->table.'" class="button" />
            </div>
            <div class="small"><sup>*</sup> '.$this->l('Required field').'</div>
        </fieldset>
        </form> ';       
}

要在按下新增或修改時出現form, 我地需要overwrite displayForm, 係入面設定我地需要的form elements, 而form 入面最重要的當然係張form 的action link同入面d parameters, 因為perstashop 原本的class 只會認指定了的名同parameter, 如果你的唔同了而你又沒有為自己新定的action加上code, 它可是不會作出對應的動作呢,所以基本上這一個form 的tag 是不用作出什麼改變的

echo '<form action="' . $currentIndex . '&submitAdd' .  $this->table . '=1&token=' . $this->token . '" method="post" class="width3">

而其他的則只需好似平時普通的html form 一樣,如果想為到張form 加回由db的值就要用上
// fields 為非多語言support時
$this->getFieldValue( $obj, 'description')

// fields 為多語言support時
$this->getFieldValue( $obj, 'name', intval( $language['id_lang'|'id_lang'] ) )

以上就可以為到prestashop 設定最basic的一個admin tab,不過由於prestashop出了新版而且也把admin的一部份也改成了controller,寫法上也有些改變,所以這筆記只可以應用在1.4.9版本中呢!


Prestashop 的back office tab 筆記 - part 2

上一份筆記寫下了db object 後, 這一篇的筆記就來掛上back-office 的頁面作出設定吧...

好首先就建立一個最基本的admin page, :
<?php
    class AdminTest extends AdminTab {
        public function __construct() {
            $this->table = 'test';
            $this->className = 'Test';
            $this->lang = true;
            $this->edit = true;  
            $this->delete = true;
            $this->fieldsDisplay = array(
              'id_test' => array(
                'title' => $this->l('ID'),
                'align' => 'center',
                'width' => 25),
              'name' => array(
                'title' => $this->l('Name'),
                'width' => 200),
              'description' => array(
                    'title' => $this->l('description'),
                    'width' => 510)          
            );

            $this->identifier = 'id_test';

            parent::__construct();
        }
  }
?> 

以上的code 掛上back-office後能出現以下的頁面
頁面
adminpage 也和db object class相類似, 也是需要去extends 一個基本的class - AdminTab, 之後就可以overwrite 它的 __construct來為版面作出設定..

$this->table = 'test';
$this->className = 'test';
$this->lang = true;

這裏的table是指你要為DB裏那一個table作出設定,所以就於入上次所建立的`test`, 同樣地是不用加上prefix的, 而className 則是這個table所對應的db object class, 所以填上上次所建立的Test, 由於我們當中有Field 是支援多語言的, 所以這個lang就要設定成true了..
注意: 如果沒有了_lang 的table, 但把lang設定為true 是會出現bad sql query 的錯誤!

我們可以設定不同的action, 只要把對應的變數設定係true 便可了

設定好需要顯示的fields
$this->fieldsDisplay = array(
  'id_test' => array(
    'title' => $this->l('ID'),
    'align' => 'center',
    'width' => 25),
  'name' => array(
    'title' => $this->l('Name'),
    'width' => 200),
  'description' => array(
    'title' => $this->l('description'),
    'width' => 510)           
); 

設定後的頁面
再set 番個table key 入去個identifier變數裏. $this->identifier = 'id_test';
最後因為你overwrite 了__construct , 所以當然不要忘記call 番parent 呢...
parent::__construct();

忘記了call 番parent 的__construct 可是會出現error 的呢..
這樣就可以有最基本的admin page了, 不過這時按下add new/edit 只會出現白頁,如何為頁面加入簡單的form 就留待下一篇筆記先再寫了


2012 香港電腦通訊節的收獲

在很多年沒有去過的電腦節, 因為今年拿到了兩張免費飛的關係, 再加上老婆話想買一部細的notebook, 所以最後就在26號入了場八卦一下....

手提電腦係入面真係幾多, 而且價錢也是很吸引的, 不過最後都唔係買左部平的, 而係買了一部sony 給老婆, 因為其實太太之前係外面都覺得隻色幾吸引,而且它是新出的model, 所以其實係入面買都冇話平到d乜, 只係話cash/eps價平左300蚊, 不過感覺上就係這300蚊, 使這部機同係BU用大學生價買個部sub-notebook(是目標之一), 的差價只餘下千元左右 (BU部機同這部是差唔多spec的,不過BU個部就好明顯將貨就價咁搞到部機好怪咁), 所以最後都係決定買這部 (其實係場內其他牌子差唔多spec太約都要29xx, 相對而言1000元的差別就當時買牌子同款吧,因為講真部機個款同隻色都真係幾靚)


除了買了部機真係買左個旅行插頭, 其實之前團購都想買, 但係最後因為冇時間去攞,所以都係冇買到, 現在見佢算叫平左d咁就買左佢la, 仲入手了PCM的特別版(再加送了拖鞋!?!?同相機帶), 而抽的憤怒鳥防塵塞就中左黑鳥(圓圓地咁睇落都幾順眼 :) )
小收獲
黑鳥