2012/08/21

PHP parse_url 不用再自己拆解URL了

曾經用過EXPLODE 和PREG_MATCH慢慢拆開URL...但原來有快方法parse_url


$url = "http://www.electrictoolbox.com/php-extract-domain-from-full-url/";
$parts = parse_url($url);

輸出:

Array
(
[scheme] => http
[host] => www.electrictoolbox.com
[path] => /php-extract-domain-from-full-url/
)


================================================================

<?php
$url = 'http://username:password@hostname/path?arg=value#anchor';
print_r(parse_url($url));
echo parse_url($url, PHP_URL_PATH);
?>
Array
(
[scheme] => http
[host] => hostname
[user] => username
[pass] => password
[path] => /path
[query] => arg=value
[fragment] => anchor
)

2012/08/10

改變地址次序等格式 Customer Address Format

因香港地區問題, 客人需要印出的PDF SLIP 中的姓名欄位根據特定格式展現:

E.G.   prefix LAST NAME , firstname

即是本來內置看成Mr Chris Wong 的, 要改成 Mr WONG , Chris

其實要分成兩部份去做

(1) 修改Address template
原來magento 已在backend提供了template 的XML

System->Configuration->Customer->Customers->Customer Configuration->Address Templates

改改排序就可以了 

{{depend prefix}}{{var prefix}} {{/depend}}{{var lastname}} {{depend middlename}}{{var middlename}}{{/depend}}, {{var firstname}}

這樣姓氏和名字的次序便倒轉了, 還可在中間加上逗號

(2)override observer "customer_address_format" 把姓氏轉為大寫

簡單先講做法:
config.xml 


<adminhtml>
<events>
            <customer_address_format>
                <observers>
                    <cleargo_custom>
                        <class>Cleargo_Custom_Model_Countryformat</class>
                        <method>countryFormat</method>
                    </cleargo_custom>
                </observers>
            </customer_address_format>
        </events>
    </adminhtml>

Cleargo/Custom/Model/Countryformat.php


class Cleargo_Custom_Model_Countryformat {
    public function countryFormat($observer) {
        $event = $observer->getEvent();
        $address = $event->getAddress();
        $type = $event->getType();
        //if($address->getData('country_id') == 'FR'){
            $lastname = strtoupper($address->getData('lastname'));
            $address->setData('lastname', $lastname);
        //}
    }
}
 



順便講講發現既過程

事源我要在PDF 裏更改格式, 於是在order/pdf/shipment.php 發現
$shippingAddress = $this->_formatAddress($order->getShippingAddress()->format('pdf'));

再追尋format這function 是源自Mage_Customer_Model_Address_Abstract

在入面可發現在render address前, dispatch了一個event
Mage::dispatchEvent('customer_address_format', array('type' => $formatType, 'address' => $this));

於是根據magento的dispatchEvent 機制, 我們可輕鬆override observer 以改變程式run到呢行時既data





2012/07/30

magento print invoice PDF 繁體中文字型


因為PRINT 中文INVOICE PDF 會出現亂碼...

所以到了WINDOWS內的字型檔案, COPY出標楷體TTF 檔案

其他內置繁體字型可能容量太大而超出MEMORY LIMIT........

app/code/core/Mage/Sales/Model/Order/Pdf/Abstract.php

protected function _setFontRegular($object, $size = 7)
    {
     
         $font = Zend_Pdf_Font::fontWithPath(Mage::getBaseDir() . '/lib/LinLibertineFont/KAIU.TTF',(Zend_Pdf_Font::EMBED_SUPPRESS_EMBED_EXCEPTION |
                                                             Zend_Pdf_Font::EMBED_DONT_COMPRESS));
        $object->setFont($font, $size);
        return $font;
    }


2012/07/10

Mage_Checkout.cvs Click here to print a copy of your order confirmation


Meet the double quotes

Notice that in the example above, both strings are surrounded by double quotes. Both what happens when the string itself has quotes in it. This is for instance the case when the Magento shopping cart is visited, while it contains no items.
The solution is simple: Just use 2 double quotes instead of 1. The translation-line would look like the following:
"Click <a href="/"%s"">here</a> to continue shopping.", "Click <a href="/"%s"">here</a> to go back."

2012/06/14

PHP利用EOT代替ECHO輸出


有時要在PHP加入JS/HTML, 會因為括號問題而需要很多改動....

間中會在OPEN SOURCE CODE 中見到以下方法

---------------------------------------------------------------------

使用eot的時候,好處就是可以直接把網頁的html當成一般的php程式一樣放在程式中,不用特別的去寫
<?php
     echo <<< EOT
     <div>新增 Div 標籤的內容放在這裡</div>
EOT;
?>
用法大概就是上面那樣,但要注意的地方是
1:<<<EOT  使用的時候,後面要是空的,不能夠有任何的資料在,空格也不行
2:EOT;這個一定要放在最前面,前面不能夠有任何的資料,空格也不行

2012/06/08

Sitemap.xml cannot change name - Path “/ sitemap_es.xml” is not available and can not be used


I also ran into that, and there’s a simple reason, and a simple and clean solution, which doesn’t tap any code.
They simply limit the file naming to this pattern: “/*/sitemap.xml”. So you can choose any directory, but you’ve to name the file “sitemap.xml”.
That implies, that you create an own directory for every sitemap you generate!
But regardless how simple the solution might be, the question arrises, WHY it is like that at all?! I can’t think of any reason, and it’s not even mentioned anywhere in the admin interface, so of course, you’re confused and start checking path permissions, etc.,
This is even the case with the latest 1.6!
Sourcinggate’s modification is not a very good idea, as it makes a maybe also otherwise used verification function to always return true, so you might mess up paths somewhere else, and Magento can’t tell you anymore.
So, here’s the fix:
In

/app/code/core/Mage/Adminhtml/etc/config.xml

Replace (at around line 190)

<any_path>/*/sitemap.xml</any_path>

with

<!-- zLabs Black BEGIN -->
<!-- 
No wonderthat we couldn't save any other filename than sitemap.xml ;)
        Is this a bug, or a "protection" feature? It doesn'
t tell this anywhere
        in the admin 
interface ... -->
<!-- <
any_path>/*/sitemap.xml</any_path> -->
<!-- zLabs | Black | END -->

2012/05/22

Nominal recurring products show zero in shipping fee

For recurring products, even you have set table rates/ shipping fee,

in the checkout section or cart section you will only just see Zero value, with another nominal item total / nominal shipping fee

It is confusing so that i want to set the normal shipping the same to the nominal shipping fee

The problem is here:
core/Mage/Shipping/Model/Carrier/Tablerate.php

public function collectRates


 if ($request->getFreeShipping() === true || ($request->getPackageQty() == $freeQty)) {
                //var_dump($rate['price']);
                $shippingPrice = 0;
            } else {
                $shippingPrice = $this->getFinalPriceWithHandlingFee($rate['price']);
            }

the shipping price is set to 0 .... but i don;t know why nominal product will enter this check case, maybe due to the ($request->getPackageQty() == $freeQty


Anyway , the shipping fee is now return to normal , lets see the  subtotal....



2012/05/21

Check the current page is a cms page or not


<?php
//for checking it is a CMS page, if true => show the order now button
$urlkey =  Mage::getSingleton('cms/page')->getIdentifier();

//remove any symbol
$cleanUrlKey = trim(preg_replace("/[^a-zA-Z0-9]+/", " ", $urlkey));

    if (!empty($urlkey)){

    // write down your code!!!!!!

}

?>
 

2012/05/04

console.trace()

在webkit 的debug tool or firebug 用console.trace() 超方便 自動log 哂由咩js function call 入黎!!

2012/05/01

Can't create table: eav_prefix_text , Integrity constraint violation: 1452 Cannot add or update a child row

http://www.magentocommerce.com/bug-tracking/issue/?issue=12126
http://www.magentocommerce.com/bug-tracking/issue/?issue=12336


Error :
(For magento 1.6 bug)
I encountered the same problem. In my situation I realized that the error occurring when trying to create the database table was: BLOB/TEXT column 'value' used in key specification without a key length
To force Magento to render SQL statements that my database could accept, I had to modify the app/code/core/Mage/Eav/Model/Entity/Setup.php file at approximately line 1337 (inside the createEntityTables method). Replacing the following lines:

        ->addIndex($this->getIdxName($eavTableName, array('attribute_id', 'value')),
            array('attribute_id', 'value'))
        ->addIndex($this->getIdxName($eavTableName, array('entity_type_id', 'value')),
            array('entity_type_id', 'value'))
 
With this:
 

 ->addIndex($this->getIdxName($eavTableName, array('entity_id')),  
                array('entity_id'));  

                if ($eavTableName[1] != 'text')  
                {  

                $eavTable->addIndex($this->getIdxName($eavTableName, array('attribute_id', 'value')),  
                array('attribute_id', 'value'))  
                ->addIndex($this->getIdxName($eavTableName, array('entity_type_id', 'value')),  
                array('entity_type_id', 'value'));  
                }  
 
 
 On the other hand, there is also an error for magento1.6:
Was also getting an error
-- Integrity constraint violation: 1452 Cannot add or update a child row magento
 

 
Had to remove the entity_id FK constraint (removing the ->addForeignKey... entity_id)

The createEntityTables() method Mage_Eav_Model_Entity_Setup creates FK's
 in the type sub-tables pointing at $this->getTable('eav/entity') 
instead of $baseTableName.


replace 
//                ->addForeignKey($this->getFkName($eavTableName, 'entity_id', 'eav/entity', 'entity_id'),
//                    'entity_id', $this->getTable('eav/entity'), 'entity_id',
//                    Varien_Db_Ddl_Table::ACTION_CASCADE, Varien_Db_Ddl_Table::ACTION_CASCADE)
//                

with this:

 $eavTable->addForeignKey($this->getFkName($eavTableName, 'entity_id', 'eav/entity', 'entity_id'),  
'entity_id', $baseTableName, 'entity_id',  
Varien_Db_Ddl_Table::ACTION_CASCADE, Varien_Db_Ddl_Table::ACTION_CASCADE)


 



  

2012/04/24

frontend cannot see pending payment orders


要加番 <visible_on_front/> 先會俾CUSTOMER見到...

app/code/core/Mage/Sales/etc/config.xml 

<new translate="label">
  <
label>New</label>
    <
statuses>
      <
pending/>
      <
processing/>
      <
holded/>
      <
complete/>
      <
closed/>
      <
canceled/>
    </
statuses>
    <
visible_on_front/>
  </new>
  <
pending translate="label">
    <
label>Pending</label>
    <
statuses>
      <
pending/>
      <
processing/>
      <
holded/>
      <
complete/>
      <
closed/>
      <
canceled/>
    </
statuses>
    <
visible_on_front/>
  </
pending>

漏左就會FRONTEND睇唔到某D STATUS既ORDER...

2012/04/17

Linux 下的各種解壓, 壓縮方法

 大致總結了一下Linux下各種格式的壓縮包的壓縮、解壓方法。.tar
打包:tar cvf FileName.tar DirName
解包: tar xvf FileName.tar

.gz
壓縮:gzip FileName
解壓1:gunzip FileName.gz
解壓2:gzip -d FileName.gz

.tar.gz
壓縮:tar zcvf FileName.tar.gz DirName
解壓:tar zxvf FileName.tar.gz

.bz2
壓縮: bzip2 -z FileName
解壓1:bzip2 -d FileName.bz2
解壓2:bunzip2 FileName.bz2

.tar.bz2
壓縮:tar jcvf FileName.tar.bz2 DirName
解壓:tar jxvf FileName.tar.bz2

.bz
壓縮:unkown
解壓1:bzip2 -d FileName.bz
解壓2:bunzip2 FileName.bz

.tar.bz
壓縮:unkown
解壓:tar jxvf FileName.tar.bz

.Z
壓縮:compress FileName
解壓:uncompress FileName.Z

.tar.Z
壓縮:tar Zcvf FileName.tar.Z DirName
解壓:tar Zxvf FileName.tar.Z

.tgz
壓縮:unkown
解壓:tar zxvf FileName.tgz


.tar.tgz
壓縮:tar zcvf FileName.tar.tgz FileName
解壓:tar zxvf FileName.tar.tgz

.zip
壓縮:zip FileName.zip DirName
解壓:unzip FileName.zip

.rar
壓縮:rar e FileName.rar
解壓:rar a FileName.rar

.lha
壓縮:lha -a FileName.lha FileName
解壓:lha -e FileName.lha

2012/04/16

javascript get/set cookie

/*set Cookie*/
function setCookie(c_name, c_data, expireDays){
var date=new Date();
if (!expireDays) expireDays = 1000;

date.setTime(date.getTime()+expireDays*24*3600*1000);
document.cookie = c_name+'='+escape(c_data)+'; expires='+date.toUTCString()+'; path=/';
}

/*get Cookie*/
function getCookie(c_name) {
if (document.cookie.length>0) {
c_start=document.cookie.indexOf(c_name + "=");
if (c_start!=-1) {
c_start=c_start + c_name.length+1;
c_end=document.cookie.indexOf(";",c_start);
if (c_end==-1) c_end=document.cookie.length;
return unescape(document.cookie.substring(c_start,c_end));
}
}
return "";
}

2012/04/12

PHP 中 extract() 的功用

近日在看一個牛人的代碼時,看到一個非常好用的函數:extract(),它的主要作用是將數組展開,鍵名作為變量名,元素值為變量值,可以說為數組的操作提供了另外一個方便的工具,比方說,可以很方便的提取$_POST或者$_GET的元素,對錶單提交上來的內容不能不用一一賦值,直接使用下面代碼:
form.html


 
<form action="action.php" method="post"><input type="text" name="username"><input type="password" name="password"><input type="submit">
在action.php中只要使用extract()函數將$_POST全局數據解開:action.php


 
<?phpextract($_POST);//相當於$username = $_POST['username'];//$password = $_POST['password'];?>
是不是很方便呢?呵呵,下面是PHP手冊裡的詳細解釋:
extract(PHP 4, PHP 5)
extract — 從數組中將變量導入到當前的符號表

說明int extract ( array $var_array [, int $extract_type [, string $prefix ]] )
本函數用來將變量從數組中導入到當前的符號表中。接受結合數組var_array 作為參數並將鍵名當作變量名,值作為變量的值。對每個鍵/值對都會在當前的符號表中建立變量,並受到extract_type 和prefix 參數的影響。

2012/04/03

[MAGENTO] DASHBOARD 中的圖表消失了


DASHBOARD 中LAST 24 HOURS的圖表不見了

由官方論壇看到

                            
This is related to the minimal allowed GET variable length settings. Check your settings for suhosin:

suhosin.get.max_value_length 1024


SOLUTION: 
Putting “suhosin.get.max_value_length = 1024” into /etc/php5/conf.d/suhosinn.ini” reload apache

2012/03/27

[wordpress] Deprecated: Assigning the return value of new by reference is deprecated

在搬移空間後,如果有這個問題,是因為新的伺服器PHP版本是5.3.0以上版本的緣故。
如果你的程式版本沒有更新,使用的語法太舊。就會出現類似這樣的警告提示,wordpress的訊息:
Deprecated: Assigning the return value of new by reference is deprecated in /home/xxx/public_html/wp-settings.php on line 264

Deprecated: Assigning the return value of new by reference is deprecated in /home/xxx/public_html/wp-settings.php on line 266

Deprecated: Assigning the return value of new by reference is deprecated in /home/xxx/public_html/wp-settings.php on line 267

Deprecated: Assigning the return value of new by reference is deprecated in /home/xxx/public_html/wp-settings.php on line 284

Deprecated: Assigning the return value of new by reference is deprecated in /home/xxx/public_html/wp-includes/cache.php on line 36

Deprecated: Assigning the return value of new by reference is deprecated in /home/xxx/public_html/wp-includes/query.php on line 21

Deprecated: Assigning the return value of new by reference is deprecated in /home/exxx/public_html/wp-includes/theme.php on line 540
解決方法:
找到警告訊息的程式,將程式修改,例如上面的提示是wp-settings.php檔案的第264列
原本是以下,將&刪除
$wp_locale = & new WP_Locale();
修改成為
$wp_locale = new WP_Locale();

這樣應該就不會出現這個訊息了。

http://www.php.net/manual/en/oop4.newref.php

2012/03/23

將Facebook iFrame Tab 設定高度大於 800 Pixels


One of the best things to happen in Facebook development lately was to enable iframe application tabs. This was widely welcomed by developers. However many blog posts wrongly assumed there was a 800 pixel limit on the tab height. Behold, here is the 5000 pixel tab.

New Tab is iFrame Canvas Application

New tab works the same way as iframe canvas application. First load the JavaScript SDK. Easiest is to load it synchronously using a script tag (for production you want to load SDK asynchronously since it gives impression of faster loading page).
<script type="text/javascript" src="http://connect.facebook.net/en_US/all.js"></script>
<script type="text/javascript" charset="utf-8">
    /* Resizing code will be here. */
</script>  
When JavaScript SDK is loaded you have access to FB.Canvas.setSize and FB.Canvas.setAutoResize methods. If you know the content size wont change later resize the frame only once when page loads.
FB.Canvas.setSize();
You can also pass the desired size as parameter.
FB.Canvas.setSize({ width: 520, height: 600 });
If content is dynamic and size might change tell Facebook to resize the iframe periodically.
FB.Canvas.setAutoResize();
Default is to try resizing every 100ms. If you want to force resizing more often you can pass desired interval as parameter.
FB.Canvas.setAutoResize(50);

Is There a Maximum Limit?

Quick search on Google did not reveal any browser limitation. Theoretically on 32 bit machines maximum page length would be 4 294 967 295 pixels. On 64 bit machines theoretical limit would be 8 446 744 073 709 551 615 pixels. Now I’m sure real limit is smaller but the bottom line is: there is enough pixels for marketers to create their next Facebook campaign…

2012/03/21

Adding/Removing Items from header top links



To edit top links content, we need to access the xml files

1. app/design/frontend/default/default/layout/checkout.xml
2. app/design/frontend/default/default/layout/customer.xml

[code]

<!--
Default layout, loads most of the pages
-->

    <default>

        <!-- Mage_Customer -->
        <reference name="top.links">
            <action method="addLink" translate="label title" module="customer"><label>My Account</label><url helper="customer/getAccountUrl"/><title>My Account</title><prepare/><urlParams/><position>10</position></action>
<action method="addLink" translate="label title" module="customer"><label>Contact
Us</label><url>contacts</url><title>Contact
Us</title><prepare/><urlParams/><position>999</position></action>
</reference>
    </default>
[/code]

2012/03/12

use SSH connection for MYSQL


 Do I need to open the port 3306 for MySQL server to accept outside connections if I use SSH connection?
Answer: No, you don’t need. The reason is you are making an SSH connection to the SSH server at your Amazon EC2 from your local computer (where the HeidiSQL is), not directly making a connection to MySQL server anymore. More precisely, you have to make sure your SSH is running (this is as I know the default config of Amazon), opening the default port for SSH to accept outside connections: port 22 and that’s it.
HeidiSQL specific question: How do I enter the params in the Heidi?

Answer:
In the ‘Settings’ tab
1. In the dropdown list of ‘Network type’, please select SSH tunnel
2. Hostname/IP: localhost (even you are connecting remotely)
3. Username & Password: your mysql user and password
Next, in the tab SSH Tunnel:
1. specify plink.exe or you need to download it and specify where it’s located
2. Host + port: the remote IP of your SSH server(should be MySQL server as well), port 22 if you don’t change anything
3. Username & password: SSH username (not MySQL users)
4. You might ignore the password in the above step if you have the .ppk file.
After that, you can test the connection. Hope it works!

2012/01/11

Cannot create `tag` table in Magento installation with sample data

彈出的ERROR
Documentation
#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ‘USING BTREE,
KEY `FK_TAG_FIRST_CUSTOMER_ID_CUSTOMER_ENTITY_ENTITY_ID` (`first’ at line 7

原來是MYSQL 5.0 和5.1 的SYNTAX問題, 升級到5.1可以解決問題, 或是用以下方法

solved this problem by changing:

PRIMARY KEY (`tag_id`) USING BTREE,
changed into
PRIMARY KEY USING BTREE (`tag_id`),

PRIMARY KEY (`tag_relation_id`) USING BTREE ,
changed into
PRIMARY KEY USING BTREE (`tag_relation_id`),

2012/01/10

改變sandbox testuser feedback score

原來可以出cheat 自行調教feedback score... 當然是在sandbox
api 名為 ValidateTestUserRegistration

<?xml version="1.0" encoding="utf-8"?>
<ValidateTestUserRegistrationRequest xmlns="urn:ebay:apis:eBLBaseComponents">
  <!-- Standard Input Fields -->
  <FeedbackScore>500</FeedbackScore>
  <RequesterCredentials>
    <eBayAuthToken>token</eBayAuthToken>
  </RequesterCredentials>
</ValidateTestUserRegistrationRequest>