多嚿魚教室

Opencart優化技巧

Showing posts with label opencart admin. Show all posts
Showing posts with label opencart admin. Show all posts

In Opencart Admin panel, this is an Autocomplete function for entry of product attributes. When user types in something into the text field of product attribute, a word box of defined product attributes will appear below the field to let user click that wanted to save the typing time.

However, if the user does not click the word box and type a complete word by oneself, the Opencart system will not save the product attribute data the user types. In fact, the Autocomplete function wanted to prevent user inputting undefined product attributes. In other words, the system does not record what the user types but just detects which item the user clicks in the word box. The Autocomplete function is user-unfriendly, especially there are many product attributes defined.

To simplify the entry of product attributes, I have programmed a vQmod plug-in to change the text field into drop-down list so that the user does not need to type anything.

If vQmod have been installed in your Opencart system,
click the below fish and save the XML script into the directory [vqmod/xml].


<p>
&#60;!--<br />
Make sure that you have properly installed Opencart vQmod.<br />
Copy this page of script.<br />
Save as a .xml file of utf-8 encoding without BOM into the directory [vqmod/xml].<br />
Name the file as you like.<br />
--&gt;</p>
<pre contenteditable="true">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;modification&gt;
 &lt;id&gt;Display attribute choices of products in drop-down list&lt;/id&gt;
 &lt;version&gt;1.1.0&lt;/version&gt;
 &lt;author&gt;Flexidigi Solution Ltd.&lt;/author&gt;
 &lt;file name=&quot;admin/model/catalog/product.php&quot;&gt;
  &lt;operation&gt;
   &lt;search position=&quot;after&quot;&gt;&lt;![CDATA[class ModelCatalogProduct extends Model {]]&gt;&lt;/search&gt;
   &lt;add&gt;&lt;![CDATA[
 public function get_all_attribute_names() {
  $query = $this-&gt;db-&gt;query(&quot;SELECT attribute_group_id, attribute_id , name FROM &quot; . DB_PREFIX . &quot;attribute_description NATURAL JOIN &quot; . DB_PREFIX . &quot;attribute WHERE language_id = '&quot; . (int)$this-&gt;config-&gt;get('config_language_id') . &quot;' order by attribute_group_id DESC&quot;);
  
  return $query-&gt;rows;
 }
 public function get_all_attribute_group_names() {
  $query = $this-&gt;db-&gt;query(&quot;SELECT attribute_group_id , name FROM &quot; . DB_PREFIX . &quot;attribute_group_description WHERE language_id = '&quot; . (int)$this-&gt;config-&gt;get('config_language_id') . &quot;' order by attribute_group_id DESC&quot;);
  
  return $query-&gt;rows;
 }  
   ]]&gt;&lt;/add&gt;
  &lt;/operation&gt;
 &lt;/file&gt;
 &lt;file name=&quot;admin/controller/catalog/product.php&quot;&gt;
  &lt;operation&gt;
   &lt;search position=&quot;after&quot;&gt;&lt;![CDATA[private function getForm() {]]&gt;&lt;/search&gt;
   &lt;add&gt;&lt;![CDATA[
     $this-&gt;data['attribute_names'] = array();
  $results = $this-&gt;model_catalog_product-&gt;get_all_attribute_names();
  foreach ($results as $result) {
   $this-&gt;data['attribute_names'][] = array(
    'name' =&gt; $result['name'],
    'attribute_id' =&gt; $result['attribute_id'],
    'attribute_group_id' =&gt; $result['attribute_group_id']);
  }
  $this-&gt;data['attribute_group_names'] = array();
  $results = $this-&gt;model_catalog_product-&gt;get_all_attribute_group_names();
  foreach ($results as $result) {
   $this-&gt;data['attribute_group_names'][] = array(
    'name' =&gt; $result['name'],
    'attribute_group_id' =&gt; $result['attribute_group_id']);
  }
   ]]&gt;&lt;/add&gt;
  &lt;/operation&gt;
 &lt;/file&gt;
 &lt;file name=&quot;admin/view/template/catalog/product_form.tpl&quot;&gt;
 &lt;!-- Show all existing Product attributes --&gt;
  &lt;operation&gt;
   &lt;search position=&quot;before&quot; offset=&quot;1&quot;&gt;&lt;![CDATA[&lt;div id=&quot;tab-option&quot;&gt;]]&gt;&lt;/search&gt;
   &lt;add&gt;&lt;![CDATA[
   &lt;aside&gt;
   &lt;header style=&quot;margin-right: 3em;float:left;font-size:1.5em&quot;&gt;&lt;?php echo $entry_attribute; ?&gt;&lt;/header&gt;
            &lt;?php foreach ($attribute_group_names as $all_attribute_group){ ?&gt;
            &lt;details style=&quot;border:#6FF solid thin; margin-right: 3em; padding:1em;float:left;&quot;&gt;
            &lt;summary style=&quot;text-decoration:underline;&quot;&gt;&lt;?php print($all_attribute_group['name']); ?&gt;&lt;/summary&gt;
        &lt;ul style=&quot;list-style-type:none;&quot; title=&quot;&lt;?php echo $all_attribute_group['name']; ?&gt;&quot;&gt;
        &lt;?php foreach ($attribute_names as $all_attribute){ 
   if($all_attribute['attribute_group_id']==$all_attribute_group['attribute_group_id']) { ?&gt;
         &lt;li&gt;&lt;?php print($all_attribute['name']); ?&gt;&lt;/li&gt;
        &lt;?php } } ?&gt;
        &lt;/ul&gt;
        &lt;/details&gt;
        &lt;?php } ?&gt;
        &lt;/aside&gt;
   ]]&gt;&lt;/add&gt;
  &lt;/operation&gt;
  &lt;operation&gt;
   &lt;search position=&quot;replace&quot;&gt;&lt;![CDATA[&lt;input type=&quot;text&quot; name=&quot;product_attribute[' + attribute_row + '][name]&quot;]]&gt;&lt;/search&gt;
   &lt;add&gt;&lt;![CDATA[';
   html += '&lt;select title=&quot;Product attributes&quot; name=&quot;product_attribute[' + attribute_row + '][name]&quot; onchange=&quot;document.getElementsByName(\'product_attribute[' + attribute_row + '][attribute_id]\')[0].value=this.options[this.selectedIndex].value;&quot;&gt;';
   html += '&lt;option value=&quot;&quot; selected=&quot;selected&quot;&gt;&lt;?php echo $text_select; ?&gt;&lt;/option&gt;';
  &lt;?php foreach ($attribute_group_names as $all_attribute_group){ ?&gt;
  html += '&lt;optgroup label=&quot;&lt;?php echo $all_attribute_group['name']; ?&gt;&quot;&gt;';
  &lt;?php foreach ($attribute_names as $all_attribute){ 
   if($all_attribute['attribute_group_id']==$all_attribute_group['attribute_group_id']) { ?&gt;
   html += '&lt;option value=&quot;&lt;?php echo $all_attribute['attribute_id']; ?&gt;&quot;&gt;&lt;?php print($all_attribute['name']); ?&gt;&lt;/option&gt;';
  &lt;?php } } ?&gt;
  html += '&lt;/optgroup&gt;';
  &lt;?php } ?&gt;
 html += '    &lt;/select&gt;';
   html += '&lt;input style=&quot;visibility:hidden&quot; list=&quot;attribute_list&quot; type=&quot;text&quot; name=&quot;product_attribute[' + attribute_row + '][name]&quot;]]&gt;&lt;/add&gt;
  &lt;/operation&gt;
 &lt;/file&gt;
&lt;/modification&gt;
</pre>
唔識英文?
自己查字典啦!

我在Opencart後台用CKEditor編輯文章,想插入圖片,於是用CKEditor上傳圖片,但失敗了。到底是甚麼一回事?

以下是錯誤的圖片上傳示範:

  1. 在CKEditor按「影像」,「影像屬性」視窗會彈出。
  2. 按「上傳」標籤,再按「瀏覽...」。
  3. 挑選一個檔案,按「開啟舊檔」。
  4. 按「上傳至伺服器」。
  5. 出錯了!沒有圖片上傳到Opencart伺服器。
上載唔到圖片
有乜叉用!

CKEditor本身不是用來上傳檔案,要插入圖片就要配合檔案上傳工具(file manager)。CKFinder是CKEditor的官方搭檔,專門配合CKEditor上傳圖片。
CKFinder file manager

不過,Opencart並沒有安裝CKFinder,因為Opencart本身已經有檔案上傳工具“Image Manager”。


Finding Solution

正確的圖片上傳方法:

  1. 在CKEditor按「影像」,「影像屬性」視窗會彈出。
  2. 按「影像資訊」標籤,再「瀏覽伺服器端」,“Image Manager”視窗會彈出。
  3. 按“Upload”,檔案瀏覽器會彈出。
  4. 挑選需要的圖片檔案,按「開啟舊檔」。
  5. 上傳完成後,所需圖片會出現在“Image Manager”,雙擊圖片。
  6. 在「影像資訊」輸入有關設定,按「確定」完成圖片插入。

原來Opencart已經有圖片上載工具。但是既然CKEditor的「上傳」是無效,怎樣防止其他人再用?

CKEditor的「上傳」標籤十分誤導用家,既然是失效的,就應該隱藏掉。

隱藏「上傳」標籤的步驟:

  1. 到安裝了Opencart的伺服器,開啟路徑[admin/view/javascript/ckeditor/plugins/image/dialogs]。
  2. 編輯[image.js],搜尋並刪除以下程式碼,然後儲存檔案:
    {id:'Upload',hidden:true,filebrowser:'uploadButton',label:b.lang.image.upload,elements:[{type:'file',id:'upload',label:b.lang.image.btnUpload,style:'height:40px',size:38},{type:'fileButton',id:'uploadButton',filebrowser:'info:txtUrl',label:b.lang.image.btnUpload,'for':['Upload','upload']}]},
    
  3. 在CKEditor按「影像」,「影像屬性」視窗會彈出。「上傳」標籤不見了。

Opencart後台內置了CKEditor,讓用家以所見即所得方式編輯文本,例如 product 和 category 的 description。

不過,Opencart和CKEditor的版本更新並不同步,所以用家要自行安裝新版本的CKEditor到Opencart。


為什麼要使用新版本的CKEditor?
怎樣安裝新版本的CKEditor到Opencart?

HTML的最新版本——HTML5在網絡越來越普及,而新版本的CKEditor已支援HTML5的新標籤,包括<article><section><header>等等。另外,新版本有糾正錯誤和新增功能。

做乜叉嘢?


以下方法適用於Opencart v1.5.1.3

更新步驟:

  1. CKEditor官網下載最新版本的CKEditor,並解壓縮出來。
  2. 打開ckeditor文件夾,將多餘的“_samples”和“_source”文件夾刪除。
  3. 到安裝了Opencart的伺服器,開啟[admin/view/javascript/ckeditor]路徑,下載“config.js”和“contents.css”,儲存到剛才解壓縮出來的ckeditor文件夾,覆蓋掉原有的檔案。
  4. 將新版本的ckeditor文件夾上傳到伺服器,覆蓋掉舊版本的ckeditor文件夾即可。

Opencart儘管有英文以外的語言包下載,但國家和地區名字仍以英文顯示。
怎樣把Opencart的英文國家和地區名字轉為中文?

雖然英文是國際語言,一般人都可以基本理解,但未必人人都記得自己的英文地址。
服務稱心的網店應該照顧到使用不同語言的客戶,雖然不必要譒譯所有國家的名字,但最基本要譒譯網店生意涵蓋地區的名字。

笨實的方法是登入Opencart後台,到“System”→“Localisation”→“Zones”&“Country”逐一編輯各國、各地區的名字。
但你既然來到「多嚿魚教室」,就不用做這些Macau Friend的事,教你一次過修改國家和地區名字!

Finding Solution

批量修改國家和地區名字的方法就是用phpMyAdmin修改儲存在MySQL Database的國家和地區名字。

修改MySQL Database之前,請備份Opencart的數據庫,以便你日後還原。
備份方法:

  1. 登入phpMyAdmin,進入Opencart所在的database。
  2. 按右頁的“匯出”標籤。
  3. 揀選“SQL”為格式,然後按「自訂 - 顯示所有可用的選項」。
  4. 在「資料表」一欄揀選“Zones”和“Country”。
  5. 揀選「儲存爲檔案」,揀選「CREATE TABLE 選項」的「IF NOT EXISTS」。
  6. ,並儲存.sql檔案。

備份完成後,就正式開始修改MySQL Database的資料。
修改MySQL Database步驟:

  1. 登入phpMyAdmin,進入Opencart所在的database。
  2. 複製以下的SQL script。
    REPLACE INTO `country` VALUES ('242', 'Republic of South Sudan', 'SS', 'SSD', '', '0', '1');
    REPLACE INTO `country` VALUES ('241', 'Republic of Serbia', 'RS', 'SRB', '', '0', '1');
    REPLACE INTO `country` VALUES ('240', 'Montenegro', 'ME', 'MNE', '', '0', '1');
    REPLACE INTO `country` VALUES ('206', '台灣', 'TW', 'TWN', '', '0', '1');
    REPLACE INTO `country` VALUES ('125', '中國澳門(Macau, China)', 'MO', 'MAC', '', '0', '1');
    REPLACE INTO `country` VALUES ('107', '日本国', 'JP', 'JPN', '', '0', '1');
    REPLACE INTO `country` VALUES ('96', '中國香港(Hong Kong, China)', 'HK', 'HKG', '', '0', '1');
    REPLACE INTO `country` VALUES ('44', '中华人民共和国', 'CN', 'CHN', '', '0', '1');
    REPLACE INTO `zone` VALUES ('684', '44', 'AN', '安徽省', '1');
    REPLACE INTO `zone` VALUES ('685', '44', 'BE', '北京市', '1');
    REPLACE INTO `zone` VALUES ('686', '44', 'CH', '重庆市', '1');
    REPLACE INTO `zone` VALUES ('687', '44', 'FU', '福建省', '1');
    REPLACE INTO `zone` VALUES ('688', '44', 'GA', '甘肃省', '1');
    REPLACE INTO `zone` VALUES ('689', '44', 'GU', '广东省', '1');
    REPLACE INTO `zone` VALUES ('690', '44', 'GX', '广西壮族自治区', '1');
    REPLACE INTO `zone` VALUES ('691', '44', 'GZ', '贵州省', '1');
    REPLACE INTO `zone` VALUES ('692', '44', 'HA', '海南省', '1');
    REPLACE INTO `zone` VALUES ('693', '44', 'HB', '河北省', '1');
    REPLACE INTO `zone` VALUES ('694', '44', 'HL', '黑龙江省', '1');
    REPLACE INTO `zone` VALUES ('695', '44', 'HE', '河南省', '1');
    REPLACE INTO `zone` VALUES ('696', '44', 'HK', '香港', '0');
    REPLACE INTO `zone` VALUES ('697', '44', 'HU', '湖北省', '1');
    REPLACE INTO `zone` VALUES ('698', '44', 'HN', '湖南省', '1');
    REPLACE INTO `zone` VALUES ('699', '44', 'IM', '内蒙古自治区', '1');
    REPLACE INTO `zone` VALUES ('700', '44', 'JI', '江苏省', '1');
    REPLACE INTO `zone` VALUES ('701', '44', 'JX', '江西省', '1');
    REPLACE INTO `zone` VALUES ('702', '44', 'JL', '吉林省', '1');
    REPLACE INTO `zone` VALUES ('703', '44', 'LI', '辽宁省', '1');
    REPLACE INTO `zone` VALUES ('704', '44', 'MA', '澳门', '0');
    REPLACE INTO `zone` VALUES ('705', '44', 'NI', '宁夏回族自治区', '1');
    REPLACE INTO `zone` VALUES ('706', '44', 'SH', '陕西省', '1');
    REPLACE INTO `zone` VALUES ('707', '44', 'SA', '山东省', '1');
    REPLACE INTO `zone` VALUES ('708', '44', 'SG', '上海市', '1');
    REPLACE INTO `zone` VALUES ('709', '44', 'SX', '山西省', '1');
    REPLACE INTO `zone` VALUES ('710', '44', 'SI', '四川省', '1');
    REPLACE INTO `zone` VALUES ('711', '44', 'TI', '天津市', '1');
    REPLACE INTO `zone` VALUES ('712', '44', 'XI', '新疆维吾尔自治区', '1');
    REPLACE INTO `zone` VALUES ('713', '44', 'YU', '云南省', '1');
    REPLACE INTO `zone` VALUES ('714', '44', 'ZH', '浙江省', '1');
    REPLACE INTO `zone` VALUES ('1410', '96', 'HCW', '港島中西區(Central and Western, Hong Kong Island)', '1');
    REPLACE INTO `zone` VALUES ('1411', '96', 'HEA', '港島東區(Eastern, Hong Kong Island)', '1');
    REPLACE INTO `zone` VALUES ('1412', '96', 'HSO', '港島南區(Southern, Hong Kong Island)', '1');
    REPLACE INTO `zone` VALUES ('1413', '96', 'HWC', '港島灣仔區(Wan Chai, Hong Kong Island)', '1');
    REPLACE INTO `zone` VALUES ('1414', '96', 'KKC', '九龍九龍城區(Kowloon City, Kowloon)', '1');
    REPLACE INTO `zone` VALUES ('1415', '96', 'KKT', '九龍觀塘區(Kwun Tong, Kowloon)', '1');
    REPLACE INTO `zone` VALUES ('1416', '96', 'KSS', '九龍深水埗區(Sham Shui Po, Kowloon)', '1');
    REPLACE INTO `zone` VALUES ('1417', '96', 'KWT', '九龍黃大仙區(Wong Tai Sin, Kowloon)', '1');
    REPLACE INTO `zone` VALUES ('1418', '96', 'KYT', '九龍油尖旺區(Yau Tsim Mong, Kowloon)', '1');
    REPLACE INTO `zone` VALUES ('1419', '96', 'NIS', '新界離島區(Islands, New Territories)', '1');
    REPLACE INTO `zone` VALUES ('1420', '96', 'NKT', '新界葵青區(Kwai Tsing, New Territories)', '1');
    REPLACE INTO `zone` VALUES ('1421', '96', 'NNO', '新界北區(North, New Territories)', '1');
    REPLACE INTO `zone` VALUES ('1422', '96', 'NSK', '新界西貢區(Sai Kung, New Territories)', '1');
    REPLACE INTO `zone` VALUES ('1423', '96', 'NST', '新界沙田區(Sha Tin, New Territories)', '1');
    REPLACE INTO `zone` VALUES ('1424', '96', 'NTP', '新界大埔區(Tai Po, New Territories)', '1');
    REPLACE INTO `zone` VALUES ('1425', '96', 'NTW', '新界荃灣區(Tsuen Wan, New Territories)', '1');
    REPLACE INTO `zone` VALUES ('1426', '96', 'NTM', '新界屯門區(Tuen Mun, New Territories)', '1');
    REPLACE INTO `zone` VALUES ('1427', '96', 'NYL', '新界元朗區(Yuen Long, New Territories)', '1');
    REPLACE INTO `zone` VALUES ('1657', '107', 'AI', '愛知県', '1');
    REPLACE INTO `zone` VALUES ('1658', '107', 'AK', '秋田県', '1');
    REPLACE INTO `zone` VALUES ('1659', '107', 'AO', '青森県', '1');
    REPLACE INTO `zone` VALUES ('1660', '107', 'CH', '千葉県', '1');
    REPLACE INTO `zone` VALUES ('1661', '107', 'EH', '愛媛県', '1');
    REPLACE INTO `zone` VALUES ('1662', '107', 'FK', '福井県', '1');
    REPLACE INTO `zone` VALUES ('1663', '107', 'FU', '福岡県', '1');
    REPLACE INTO `zone` VALUES ('1664', '107', 'FS', '福島県', '1');
    REPLACE INTO `zone` VALUES ('1665', '107', 'GI', '岐阜県', '1');
    REPLACE INTO `zone` VALUES ('1666', '107', 'GU', '群馬県', '1');
    REPLACE INTO `zone` VALUES ('1667', '107', 'HI', '広島県', '1');
    REPLACE INTO `zone` VALUES ('1668', '107', 'HO', '北海道', '1');
    REPLACE INTO `zone` VALUES ('1669', '107', 'HY', '兵庫県', '1');
    REPLACE INTO `zone` VALUES ('1670', '107', 'IB', '茨城県', '1');
    REPLACE INTO `zone` VALUES ('1671', '107', 'IS', '石川県', '1');
    REPLACE INTO `zone` VALUES ('1672', '107', 'IW', '岩手県', '1');
    REPLACE INTO `zone` VALUES ('1673', '107', 'KA', '香川県', '1');
    REPLACE INTO `zone` VALUES ('1674', '107', 'KG', '鹿児島県', '1');
    REPLACE INTO `zone` VALUES ('1675', '107', 'KN', '神奈川県', '1');
    REPLACE INTO `zone` VALUES ('1676', '107', 'KO', '高知県', '1');
    REPLACE INTO `zone` VALUES ('1677', '107', 'KU', '熊本県', '1');
    REPLACE INTO `zone` VALUES ('1678', '107', 'KY', '京都府', '1');
    REPLACE INTO `zone` VALUES ('1679', '107', 'MI', '三重県', '1');
    REPLACE INTO `zone` VALUES ('1680', '107', 'MY', '宮城県', '1');
    REPLACE INTO `zone` VALUES ('1681', '107', 'MZ', '宮崎県', '1');
    REPLACE INTO `zone` VALUES ('1682', '107', 'NA', '長野県', '1');
    REPLACE INTO `zone` VALUES ('1683', '107', 'NG', '長崎県', '1');
    REPLACE INTO `zone` VALUES ('1684', '107', 'NR', '奈良県', '1');
    REPLACE INTO `zone` VALUES ('1685', '107', 'NI', '新潟県', '1');
    REPLACE INTO `zone` VALUES ('1686', '107', 'OI', '大分県', '1');
    REPLACE INTO `zone` VALUES ('1687', '107', 'OK', '岡山県', '1');
    REPLACE INTO `zone` VALUES ('1688', '107', 'ON', '沖縄県', '1');
    REPLACE INTO `zone` VALUES ('1689', '107', 'OS', '大阪府', '1');
    REPLACE INTO `zone` VALUES ('1690', '107', 'SA', '佐賀県', '1');
    REPLACE INTO `zone` VALUES ('1691', '107', 'SI', '埼玉県', '1');
    REPLACE INTO `zone` VALUES ('1692', '107', 'SH', '滋賀県', '1');
    REPLACE INTO `zone` VALUES ('1693', '107', 'SM', '島根県', '1');
    REPLACE INTO `zone` VALUES ('1694', '107', 'SZ', '静岡県', '1');
    REPLACE INTO `zone` VALUES ('1695', '107', 'TO', '栃木県', '1');
    REPLACE INTO `zone` VALUES ('1696', '107', 'TS', '徳島県', '1');
    REPLACE INTO `zone` VALUES ('1697', '107', 'TK', '東京都', '1');
    REPLACE INTO `zone` VALUES ('1698', '107', 'TT', '鳥取県', '1');
    REPLACE INTO `zone` VALUES ('1699', '107', 'TY', '富山県', '1');
    REPLACE INTO `zone` VALUES ('1700', '107', 'WA', '和歌山県', '1');
    REPLACE INTO `zone` VALUES ('1701', '107', 'YA', '山形県', '1');
    REPLACE INTO `zone` VALUES ('1702', '107', 'YM', '山口県', '1');
    REPLACE INTO `zone` VALUES ('1703', '107', 'YN', '山梨県', '1');
    REPLACE INTO `zone` VALUES ('1933', '125', 'OLF', '澳門半島花地瑪堂區(Our Lady of Fatima Parish)', '1');
    REPLACE INTO `zone` VALUES ('1934', '125', 'ANT', '澳門半島聖安多尼堂區(St. Anthony Parish)', '1');
    REPLACE INTO `zone` VALUES ('1935', '125', 'LAZ', '澳門半島望德堂區(St. Lazarus Parish)', '1');
    REPLACE INTO `zone` VALUES ('1936', '125', 'CAT', '澳門半島大堂區(Cathedral Parish)', '1');
    REPLACE INTO `zone` VALUES ('1937', '125', 'LAW', '澳門半島風順堂區(St. Lawrence Parish)', '1');
    REPLACE INTO `zone` VALUES ('3135', '206', 'TW-CHA', '彰化縣', '1');
    REPLACE INTO `zone` VALUES ('3136', '206', 'TW-CYQ', '嘉義縣', '1');
    REPLACE INTO `zone` VALUES ('3137', '206', 'TW-HSZ', '新竹市', '1');
    REPLACE INTO `zone` VALUES ('3138', '206', 'TW-HUA', '花蓮縣', '1');
    REPLACE INTO `zone` VALUES ('3139', '206', 'TW-ILA', '宜蘭縣', '1');
    REPLACE INTO `zone` VALUES ('3140', '206', 'KH', 'Kao-hsiung county', '0');
    REPLACE INTO `zone` VALUES ('3141', '206', 'KM', '金門縣', '1');
    REPLACE INTO `zone` VALUES ('3142', '206', 'LC', '連江縣', '1');
    REPLACE INTO `zone` VALUES ('3143', '206', 'TW-MIA', '苗栗縣', '1');
    REPLACE INTO `zone` VALUES ('3144', '206', 'TW-NAN', '南投縣', '1');
    REPLACE INTO `zone` VALUES ('3145', '206', 'TW-PEN', '澎湖縣', '1');
    REPLACE INTO `zone` VALUES ('3146', '206', 'TW-PIF', '屏東縣', '1');
    REPLACE INTO `zone` VALUES ('3147', '206', 'TG', 'T\'ai-chung', '0');
    REPLACE INTO `zone` VALUES ('3148', '206', 'TW-TNN', '台南市', '1');
    REPLACE INTO `zone` VALUES ('3149', '206', 'TW-TPQ', '新北市', '1');
    REPLACE INTO `zone` VALUES ('3150', '206', 'TW-TTT', '台東縣', '1');
    REPLACE INTO `zone` VALUES ('3151', '206', 'TW-TAO', '桃園縣', '1');
    REPLACE INTO `zone` VALUES ('3152', '206', 'TW-YUN', '雲林縣', '1');
    REPLACE INTO `zone` VALUES ('3153', '206', 'TW-CYI', '嘉義市', '1');
    REPLACE INTO `zone` VALUES ('3154', '206', 'TW-KEE', '基隆市', '1');
    REPLACE INTO `zone` VALUES ('3155', '206', 'TW-HSQ', '新竹縣', '1');
    REPLACE INTO `zone` VALUES ('3156', '206', 'TW-TXG', '台中市', '1');
    REPLACE INTO `zone` VALUES ('3157', '206', 'TN', 'T\'ai-nan', '0');
    REPLACE INTO `zone` VALUES ('3158', '206', 'TW-KHH', '高雄市', '1');
    REPLACE INTO `zone` VALUES ('3159', '206', 'TW-TPE', '台北市', '1');
    REPLACE INTO `zone` VALUES ('3970', '44', 'QH', '青海省', '1');
    REPLACE INTO `zone` VALUES ('3971', '44', 'TB', '西藏自治區', '1');
    REPLACE INTO `zone` VALUES ('3972', '125', 'TP', '氹仔(Taipa)', '1');
    REPLACE INTO `zone` VALUES ('3973', '125', 'CO', '路環(Coloane)', '1');
    REPLACE INTO `zone` VALUES ('3974', '125', 'CT', '路氹城(Cotai)', '1');
    REPLACE INTO `zone` VALUES ('3975', '240', 'ME-01', 'Andrijevica', '1');
    REPLACE INTO `zone` VALUES ('3976', '240', 'ME-02', 'Bar', '1');
    REPLACE INTO `zone` VALUES ('3977', '240', 'ME-03', 'Berane', '1');
    REPLACE INTO `zone` VALUES ('3978', '240', 'ME-04', 'Bijelo Polje', '1');
    REPLACE INTO `zone` VALUES ('3979', '240', 'ME-05', 'Budva', '1');
    REPLACE INTO `zone` VALUES ('3980', '240', 'ME-06', 'Cetinje', '1');
    REPLACE INTO `zone` VALUES ('3981', '240', 'ME-07', 'Danilovgrad', '1');
    REPLACE INTO `zone` VALUES ('3982', '240', 'ME-08', 'Herceg-Novi', '1');
    REPLACE INTO `zone` VALUES ('3983', '240', 'ME-09', 'Kolašin', '1');
    REPLACE INTO `zone` VALUES ('3984', '240', 'ME-10', 'Kotor', '1');
    REPLACE INTO `zone` VALUES ('3985', '240', 'ME-11', 'Mojkovac', '1');
    REPLACE INTO `zone` VALUES ('3986', '240', 'ME-12', 'Nikšić', '1');
    REPLACE INTO `zone` VALUES ('3987', '240', 'ME-13', 'Plav', '1');
    REPLACE INTO `zone` VALUES ('3988', '240', 'ME-14', 'Pljevlja', '1');
    REPLACE INTO `zone` VALUES ('3989', '240', 'ME-15', 'Plužine', '1');
    REPLACE INTO `zone` VALUES ('3990', '240', 'ME-16', 'Podgorica', '1');
    REPLACE INTO `zone` VALUES ('3991', '240', 'ME-17', 'Rožaje', '1');
    REPLACE INTO `zone` VALUES ('3992', '240', 'ME-18', 'Šavnik', '1');
    REPLACE INTO `zone` VALUES ('3993', '240', 'ME-19', 'Tivat', '1');
    REPLACE INTO `zone` VALUES ('3994', '240', 'ME-20', 'Ulcinj', '1');
    REPLACE INTO `zone` VALUES ('3995', '240', 'ME-21', 'Žabljak', '1');
    REPLACE INTO `zone` VALUES ('3998', '241', 'RS-00', 'Beograd', '1');
    REPLACE INTO `zone` VALUES ('3999', '241', 'RS-14', 'Borski okrug', '1');
    REPLACE INTO `zone` VALUES ('4000', '241', 'RS-11', 'Braničevski okrug', '1');
    REPLACE INTO `zone` VALUES ('4001', '241', 'RS-23', 'Jablanički okrug', '1');
    REPLACE INTO `zone` VALUES ('4002', '241', 'RS-06', 'Južnobački okrug', '1');
    REPLACE INTO `zone` VALUES ('4003', '241', 'RS-04', 'Južnobanatski okrug', '1');
    REPLACE INTO `zone` VALUES ('4004', '241', 'RS-09', 'Kolubarski okrug', '1');
    REPLACE INTO `zone` VALUES ('4005', '241', 'RS-25', 'Kosovski okrug', '1');
    REPLACE INTO `zone` VALUES ('4006', '241', 'RS-28', 'Kosovsko-Mitrovački okrug', '1');
    REPLACE INTO `zone` VALUES ('4007', '241', 'RS-29', 'Kosovsko-Pomoravski okrug', '1');
    REPLACE INTO `zone` VALUES ('4008', '241', 'RS-08', 'Mačvanski okrug', '1');
    REPLACE INTO `zone` VALUES ('4009', '241', 'RS-17', 'Moravički okrug', '1');
    REPLACE INTO `zone` VALUES ('4010', '241', 'RS-20', 'Nišavski okrug', '1');
    REPLACE INTO `zone` VALUES ('4011', '241', 'RS-24', 'Pčinjski okrug', '1');
    REPLACE INTO `zone` VALUES ('4012', '241', 'RS-26', 'Pećki okrug', '1');
    REPLACE INTO `zone` VALUES ('4013', '241', 'RS-22', 'Pirotski okrug', '1');
    REPLACE INTO `zone` VALUES ('4014', '241', 'RS-10', 'Podunavski okrug', '1');
    REPLACE INTO `zone` VALUES ('4015', '241', 'RS-13', 'Pomoravski okrug', '1');
    REPLACE INTO `zone` VALUES ('4016', '241', 'RS-27', 'Prizrenski okrug', '1');
    REPLACE INTO `zone` VALUES ('4017', '241', 'RS-19', 'Rasinski okrug', '1');
    REPLACE INTO `zone` VALUES ('4018', '241', 'RS-18', 'Raški okrug', '1');
    REPLACE INTO `zone` VALUES ('4019', '241', 'RS-01', 'Severnobački okrug', '1');
    REPLACE INTO `zone` VALUES ('4020', '241', 'RS-03', 'Severnobanatski okrug', '1');
    REPLACE INTO `zone` VALUES ('4021', '241', 'RS-02', 'Srednjebanatski okrug', '1');
    REPLACE INTO `zone` VALUES ('4022', '241', 'RS-07', 'Sremski okrug', '1');
    REPLACE INTO `zone` VALUES ('4023', '241', 'RS-12', 'Šumadijski okrug', '1');
    REPLACE INTO `zone` VALUES ('4024', '241', 'RS-21', 'Toplički okrug', '1');
    REPLACE INTO `zone` VALUES ('4025', '241', 'RS-15', 'Zaječarski okrug', '1');
    REPLACE INTO `zone` VALUES ('4026', '241', 'RS-05', 'Zapadnobački okrug', '1');
    REPLACE INTO `zone` VALUES ('4027', '241', 'RS-16', 'Zlatiborski okrug', '1');
    REPLACE INTO `zone` VALUES ('4028', '242', 'SS-EC', 'Central Equatoria', '1');
    REPLACE INTO `zone` VALUES ('4029', '242', 'SS-EE', 'Eastern Equatoria', '1');
    REPLACE INTO `zone` VALUES ('4030', '242', 'SS-JG', 'Jonglei', '1');
    REPLACE INTO `zone` VALUES ('4031', '242', 'SS-LK', 'Lakes', '1');
    REPLACE INTO `zone` VALUES ('4032', '242', 'SS-BN', 'Northern Bahr el-Ghazal', '1');
    REPLACE INTO `zone` VALUES ('4033', '242', 'SS-UY', 'Unity', '1');
    REPLACE INTO `zone` VALUES ('4034', '242', 'SS-NU', 'Upper Nile', '1');
    REPLACE INTO `zone` VALUES ('4035', '242', 'SS-WR', 'Warrap', '1');
    REPLACE INTO `zone` VALUES ('4036', '242', 'SS-BW', 'Western Bahr el-Ghazal', '1');
    REPLACE INTO `zone` VALUES ('4037', '242', 'SS-EW', 'Western Equatoria', '1');
    
  3. 按右頁的“SQL”標籤。
  4. 在SQL查詢欄貼上SQL script,然後按
  5. 登入Opencart後台,到“System”→“Localisation”→“Zones”,隨便“Edit”一個地區,不用改任何字,按
    (這一步的目的是讓Opencart對在phpMyAdmin的資料修改起反應)。
  6. 在“Zones”和“Country”版面,到最後一頁(因為漢字國家名字排最後),檢查一下地區名稱,如無意外應該是漢字。
  7. 瀏覽網店前台的會員註冊表格,國家和地區選擇欄已經更新。
以上方法適用於Opencart v1.5.1.3
你有叉用?
剛才的SQL script發揮甚麼功效呢?
一下子就改妥國家和地區名。

Opencart的database有兩個表用來儲存地方資料——“Country”儲存了國家和特殊政區的資料,“Zones”儲存了各國行政區域的資料。

SQL script針對這兩個表作以下修改:
“Country”

  • 新增3個國家——“Republic of South Sudan”“Republic of Serbia”“Montenegro”
  • 翻譯使用漢字的國家/特殊政區名稱——將“China”、“Hong Kong”、“Macau”、“Taiwan”、“Japan”分別改為「中华人民共和国」、「中國香港(Hong Kong, China)」、「中國澳門(Macau, China)」、「台灣」、「日本国」。

“Zones”
  • 台灣行政區域的英文名稱譒譯成正體中文;
    “T'ai-pei county”更新為「新北市」;
    停用台中縣高雄縣台南縣的選項(這些行政區在2010年已經廢止);
    將各區的地區代碼(Zone Code)轉為ISO 3166-2
  • 中国行政区域的英文名称翻译成简体中文;
    新增原Opencart遗漏了的「青海省」和「西藏自治区」;
    停用“Hong Kong”和“Macau”的选项,因为它们是特殊政区,已经在“Country”出现。
  • 香港行政區域的英文名字改成中英並列。
  • 澳門行政區域的英文名字改成中英並列;
    新增「氹仔(Taipa)」、「路環(Coloane)」、「路氹城(Cotai)」原Opencart遺漏的區域。


  • 日本行政區域的英文名稱譒譯成日文(漢字)


  • 新增黑山的21個地區。


  • 新增塞爾維亞的30個地區。


  • 新增南蘇丹的10個地區。


國家和地區的資料源自《維基百科》。

世界政局波譎雲詭,隨時有新政區新國家成立。所以最好在國家選擇欄新增一個「其他地方」供客戶揀選。

我想輸入兩個中文字的Product Attribute Name,但Opencart系統就警告我,難道它不了解漢語使用者的習慣?
沒錯!因為Opencart設計者是英國人,他不明白漢語的美妙之處在於「精簡」——跟其他語言相比,漢語用很少字符就表達相同的意思出來。所以Opencart所設的Product Attribute Name的三個字符下限是多卵魚的。
Opencart所設的Product Attribute Name的三個字符下限
低智簡單的解決方法是打空格湊夠三個字符。
但是,我才不會像個傻子每次都要留空格,所以要修正它的程式碼。

係咪無叉用呢?我有!
以下方法適用於Opencart v1.5.1.3
程式修正1:
  1. 編輯[admin/controller/catalog/attribute.php]。
  2. 搜尋下列程式碼:
    foreach ($this->request->post['attribute_description'] as $language_id => $value) {
       if ((utf8_strlen($value['name']) < 3) || (utf8_strlen($value['name']) > 64)) {
          $this->error['name'][$language_id] = $this->language->get('error_name');
       }
    }
  3. 只要將utf8_strlen($value['name']) < 3改成utf8_strlen($value['name']) < 2,就可以儲存兩個字符的Attribute Name。utf8_strlen()是用來計算UTF-8字符串的字數。)

Opencart系統容許儲存兩個中文字符,而且容許儲存兩個英文字符,好像有點奇怪。
Opencart系統容許儲存兩個中文字符,而且容許儲存兩個英文字符。
大多數有實際意義的英文字都超過兩個字母,所以設計者才要求使用者輸入不少於兩個英文字符,用有意義的詞語作為Attribute Name。下一步要修改程式令系統容許使用者儲存兩個中文字符,同強制輸入不少於兩個英文字符。
程式修正2:
  1. 復原剛才的attribute.php檔案,搜尋同一段程式碼。
  2. utf8_strlen($value['name']) < 3改成strlen($value['name']) < 3
Opencart系統容許儲存兩個中文字符,但不容許儲存兩個英文字符。
strlen()是用來計算字符串的字數,而實際上它是計算字符串的位元組。
由於UTF-8拉丁字母只佔一個位元組,而UTF-8漢字佔三個位元組,所以strlen()會將2個UTF-8漢字視為6個字符,而2個拉丁字母仍然是2個字符。
以上修正方法同樣適用於 Attribute Group Name 和 Manufacturer Name ,只要照辦煮碗編輯程式碼便可。
Attribute Group Name: [admin/controller/catalog/attribute_group.php]
Manufacturer Name: [admin/controller/catalog/manufacturer.php]

<p>
&#60;!--<br />
Make sure that you have properly installed Opencart vQmod.<br />
Copy this page of script.<br />
Save as a .xml file of utf-8 encoding without BOM into the directory [vqmod/xml].<br />
Name the file as you like.<br />
--&gt;</p>
<pre contenteditable="true">
&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;modification&gt;
&nbsp;&lt;id&gt;Allow attribute name of 2 charcters&lt;/id&gt;
&nbsp;&lt;version&gt;1.0.0&lt;/version&gt;
&nbsp;&lt;author&gt;Flexidigi Solution Ltd&lt;/author&gt;
&nbsp;&lt;file name="admin/controller/catalog/attribute.php"&gt;
&nbsp;&nbsp;&lt;operation error="skip"&gt;
&nbsp;&nbsp;&nbsp;&lt;search position="replace"&gt;&lt;![CDATA[utf8_strlen($value['name']) &lt; 3]]&gt;&lt;/search&gt;
&nbsp;&nbsp;&nbsp;&lt;add&gt;&lt;![CDATA[strlen($value['name']) &lt; 3]]&gt;&lt;/add&gt;
&nbsp;&nbsp;&lt;/operation&gt;
&nbsp;&lt;/file&gt;
&nbsp;&lt;file name="admin/controller/catalog/attribute_group.php"&gt;
&nbsp;&nbsp;&lt;operation error="skip"&gt;
&nbsp;&nbsp;&nbsp;&lt;search position="replace"&gt;&lt;![CDATA[utf8_strlen($value['name']) &lt; 3]]&gt;&lt;/search&gt;
&nbsp;&nbsp;&nbsp;&lt;add&gt;&lt;![CDATA[strlen($value['name']) &lt; 3]]&gt;&lt;/add&gt;
&nbsp;&nbsp;&lt;/operation&gt;
&nbsp;&lt;/file&gt;
&nbsp;&lt;file name="admin/controller/catalog/manufacturer.php"&gt;
&nbsp;&nbsp;&lt;operation error="skip"&gt;
&nbsp;&nbsp;&nbsp;&lt;search position="replace"&gt;&lt;![CDATA[utf8_strlen($value['name']) &lt; 3]]&gt;&lt;/search&gt;
&nbsp;&nbsp;&nbsp;&lt;add&gt;&lt;![CDATA[strlen($value['name']) &lt; 3]]&gt;&lt;/add&gt;
&nbsp;&nbsp;&lt;/operation&gt;
&nbsp;&lt;/file&gt;
&lt;/modification&gt;</pre>

當頁面有多筆資料,實在看得人眼花撩亂。


如果資料展示不同背景顏色,就不會混淆了。

無叉用?等我幫下你
以下方法適用於Opencart v1.5.1.3

修改方法:
  1. 編輯[admin/view/stylesheet/stylesheet.css]
  2. 搜尋到.list tbody td {
  3. 刪除background: #FFFFFF;
  4. 在最後一行插入以下源碼:
    .list tbody tr {
     background-color: Lime;
    }
    .list tbody tr:nth-child(odd) {
     background-color: Lime;
    }
    .list tbody tr:nth-child(even) {
     background-color: GreenYellow;
    }
    .list tbody tr:hover {
     background-color: white;
    }
    (由於nth-child是CSS3新增的Selector,所以舊瀏覽器並不支援,建議用最新版本的瀏覽器。)
你可以設定background-color為你喜歡的顏色。