Nov 9, 2012

Building Attribute Group Tree


Each product has a defined attribute set in Magento and which is set on creation of the product. Attribute sets consists of a number of attribute groups which in turn has a number of attributes.

Normally that is used only in admin, but I got a request to classify the attributes like that in a grid on frontend, which was a bit tricky. Below is the solution that I came up to.


$retValue = array();

/* @var $product Mage_Catalog_Model_Product  */
$product = Mage::getModel('catalog/product')->load(3224);

// Get the attribute set of the product
$attributeSetId = $product->getAttributeSetId();

// Get the attribute groups associated to the attribute set
$attributeGroups = Mage::getResourceModel('eav/entity_attribute_group_collection')
    ->setAttributeSetFilter($attributeSetId)
    ->load();


// Get the attributes of each group
foreach ($attributeGroups as $value) {
    $group['title'] = $value->getAttributeGroupName();

    $attributes = $product->getAttributes($value->getId());

    $attributeVal = array();

    foreach ($attributes as $attribute) {
        $att['title'] = $attribute->getFrontEndLabel();
        $attributeCode = $attribute->getAttributeCode();

        
        $data = $product->getData($attributeCode);
        if (!empty($data['values'])) {
            $attributeVal = $product->getAttributeText($attributeCode);
        }

        if (!empty($attributeVal)) {
            $att['value'] = $attributeVal;
            $group['value'][] = $att;
        }
    }

        $retValue[] = $group;
}

echo '<pre>';
var_dump($retValue);
echo '</pre>';

Oct 5, 2012

How magento widget form container instantiates a form

In admin for Magento, widget forms are used in order to edit entities. You need a Mage_Adminhtml_Block_Widget_Form_Container that contains a Mage_Adminhtml_Block_Widget_Form (with tabs etc..). The full explanation of how the full edit works is beyond this blog post, and I am concentrating on an issue that I came on.

So, while creating a form, I got the following error:
Fatal error: Call to a member function setData() on a non-object in app/code/core/Mage/Adminhtml/Block/Widget/Form/Container.php on line 129 

It took me some time to figure out what going on, and after some digging in mage widget forms, I understood the error. In fact, Magento is not finding the form associated to the form container.

Basically for container to locate the form, it needs 3 attributes, an example below:

    protected $_blockGroup = 'training_commenteav';
    protected $_controller = 'adminhtml_eav_comment';
    protected $_mode = 'edit';

These specify the location of the form. In the parent class, here what's happening:
$this->getLayout()->createBlock($this->_blockGroup . '/' . $this->_controller . '_' . $this->_mode . '_form')

So for my example it would be "training_commenteav/adminhtml_eav_comment_edit_form" that it will use to create a block instance.

I don't know why you can't just specify the uri of the form as I would have expected. Instead it uses blockgroup, controller and mode. Maybe you could have an abstract class for several modes and reuse the blockgroup and controller which I don't think is that useful. Anyway that is how Magento works with widget forms.


Apr 24, 2012

Magento Country Codes per Continent for Table Rate


I was trying to setup flat shipping rate per continent on Magento and figured out that was not possible.  So I made a little sql script to categorize the countries according to their continent.


If you want more information about how to use it, read that blog post: http://php.quicoto.com/magento-country-codes-for-table-rate/

The information is stored in a database, so if you need if in a different format or with other data, let me know.


Find below the list.

id,code,name,continent

78,GA,Gabon,AFRICA
180,RW,Rwanda,AFRICA
58,CI,"Côte d’Ivoire",AFRICA
206,SD,Sudan,AFRICA
209,SZ,Swaziland,AFRICA
51,CD,"Congo - Kinshasa",AFRICA
50,CG,"Congo - Brazzaville",AFRICA
49,KM,Comoros,AFRICA
43,TD,Chad,AFRICA
42,CF,"Central African Republic",AFRICA
40,CV,"Cape Verde",AFRICA
38,CM,Cameroon,AFRICA
113,KE,Kenya,AFRICA
36,BI,Burundi,AFRICA
60,DJ,Djibouti,AFRICA
216,TZ,Tanzania,AFRICA
79,GM,Gambia,AFRICA
82,GH,Ghana,AFRICA
195,SL,"Sierra Leone",AFRICA
194,SC,Seychelles,AFRICA
192,SN,Senegal,AFRICA
200,SO,Somalia,AFRICA
69,ET,Ethiopia,AFRICA
67,ER,Eritrea,AFRICA
66,GQ,"Equatorial Guinea",AFRICA
201,ZA,"South Africa",AFRICA
64,EG,Egypt,AFRICA
91,GN,Guinea,AFRICA
92,GW,Guinea-Bissau,AFRICA
35,BF,"Burkina Faso",AFRICA
223,TN,Tunisia,AFRICA
157,NE,Niger,AFRICA
129,MW,Malawi,AFRICA
158,NG,Nigeria,AFRICA
136,MR,Mauritania,AFRICA
132,ML,Mali,AFRICA
137,MU,Mauritius,AFRICA
138,YT,Mayotte,AFRICA
146,MA,Morocco,AFRICA
147,MZ,Mozambique,AFRICA
149,NA,Namibia,AFRICA
219,TG,Togo,AFRICA
244,ZM,Zambia,AFRICA
6,AO,Angola,AFRICA
245,ZW,Zimbabwe,AFRICA
3,DZ,Algeria,AFRICA
23,BJ,Benin,AFRICA
230,UG,Uganda,AFRICA
121,LR,Liberia,AFRICA
28,BW,Botswana,AFRICA
128,MG,Madagascar,AFRICA
120,LS,Lesotho,AFRICA
122,LY,Libya,AFRICA


115,KW,Kuwait,ASIA
112,KZ,Kazakhstan,ASIA
151,NP,Nepal,ASIA
1,AF,Afghanistan,ASIA
116,KG,Kyrgyzstan,ASIA
165,PK,Pakistan,ASIA
196,SG,Singapore,ASIA
119,LB,Lebanon,ASIA
164,OM,Oman,ASIA
103,IQ,Iraq,ASIA
143,MN,Mongolia,ASIA
179,RU,Russia,ASIA
106,IL,Israel,ASIA
130,MY,Malaysia,ASIA
102,IR,Iran,ASIA
109,JP,Japan,ASIA
101,ID,Indonesia,ASIA
177,QA,Qatar,ASIA
100,IN,India,ASIA
97,HK,"Hong Kong SAR China",ASIA
172,PH,Philippines,ASIA
131,MV,Maldives,ASIA
117,LA,Laos,ASIA
111,JO,Jordan,ASIA
191,SA,"Saudi Arabia",ASIA
45,CN,China,ASIA
232,AE,"United Arab Emirates",ASIA
25,BT,Bhutan,ASIA
205,LK,"Sri Lanka",ASIA
225,TM,Turkmenistan,ASIA
33,BN,Brunei,ASIA
37,KH,Cambodia,ASIA
217,TH,Thailand,ASIA
215,TJ,Tajikistan,ASIA
212,SY,Syria,ASIA
214,TW,Taiwan,ASIA
18,BD,Bangladesh,ASIA
203,KR,"South Korea",ASIA
224,TR,Turkey,ASIA
17,BH,Bahrain,ASIA
243,YE,Yemen,ASIA
240,VN,Vietnam,ASIA
236,UZ,Uzbekistan,ASIA


134,MH,"Marshall Islands",AUSTRALIA
150,NR,Nauru,AUSTRALIA
237,VU,Vanuatu,AUSTRALIA
114,KI,Kiribati,AUSTRALIA
13,AU,Australia,AUSTRALIA
221,TO,Tonga,AUSTRALIA
166,PW,Palau,AUSTRALIA
140,FM,Micronesia,AUSTRALIA
227,TV,Tuvalu,AUSTRALIA
169,PG,"Papua New Guinea",AUSTRALIA
155,NZ,"New Zealand",AUSTRALIA
189,WS,Samoa,AUSTRALIA
199,SB,"Solomon Islands",AUSTRALIA
72,FJ,Fiji,AUSTRALIA


14,AT,Austria,EUROPE
73,FI,Finland,EUROPE
142,MC,Monaco,EUROPE
141,MD,Moldova,EUROPE
80,GE,Georgia,EUROPE
193,RS,Serbia,EUROPE
15,AZ,Azerbaijan,EUROPE
71,FO,"Faroe Islands",EUROPE
190,SM,"San Marino",EUROPE
144,ME,Montenegro,EUROPE
84,GR,Greece,EUROPE
2,AL,Albania,EUROPE
163,NO,Norway,EUROPE
197,SK,Slovakia,EUROPE
5,AD,Andorra,EUROPE
198,SI,Slovenia,EUROPE
152,NL,Netherlands,EUROPE
81,DE,Germany,EUROPE
74,FR,France,EUROPE
68,EE,Estonia,EUROPE
11,AM,Armenia,EUROPE
133,MT,Malta,EUROPE
204,ES,Spain,EUROPE
98,HU,Hungary,EUROPE
118,LV,Latvia,EUROPE
99,IS,Iceland,EUROPE
56,CY,Cyprus,EUROPE
34,BG,Bulgaria,EUROPE
54,HR,Croatia,EUROPE
210,SE,Sweden,EUROPE
20,BY,Belarus,EUROPE
211,CH,Switzerland,EUROPE
104,IE,Ireland,EUROPE
107,IT,Italy,EUROPE
57,CZ,"Czech Republic",EUROPE
178,RO,Romania,EUROPE
233,GB,"United Kingdom",EUROPE
21,BE,Belgium,EUROPE
231,UA,Ukraine,EUROPE
127,MK,Macedonia,EUROPE
174,PL,Poland,EUROPE
125,LU,Luxembourg,EUROPE
175,PT,Portugal,EUROPE
123,LI,Liechtenstein,EUROPE
124,LT,Lithuania,EUROPE
59,DK,Denmark,EUROPE


234,US,"United States",NAMERICA
168,PA,Panama,NAMERICA
62,DO,"Dominican Republic",NAMERICA
94,HT,Haiti,NAMERICA
108,JM,Jamaica,NAMERICA
96,HN,Honduras,NAMERICA
61,DM,Dominica,NAMERICA
39,CA,Canada,NAMERICA
89,GT,Guatemala,NAMERICA
86,GD,Grenada,NAMERICA
53,CR,"Costa Rica",NAMERICA
55,CU,Cuba,NAMERICA
22,BZ,Belize,NAMERICA
19,BB,Barbados,NAMERICA
65,SV,"El Salvador",NAMERICA
139,MX,Mexico,NAMERICA
16,BS,Bahamas,NAMERICA
156,NI,Nicaragua,NAMERICA

41,KY,"Cayman Islands",OTHERS
186,MF,"Saint Martin",OTHERS
213,ST,"São Tomé and Príncipe",OTHERS
47,CC,"Cocos [Keeling] Islands",OTHERS
52,CK,"Cook Islands",OTHERS
242,EH,"Western Sahara",OTHERS
8,AQ,Antarctica,OTHERS
241,WF,"Wallis and Futuna",OTHERS
7,AI,Anguilla,OTHERS
31,IO,"British Indian Ocean Territory",OTHERS
46,CX,"Christmas Island",OTHERS
218,TL,Timor-Leste,OTHERS
4,AS,"American Samoa",OTHERS
24,BM,Bermuda,OTHERS
229,VI,"U.S. Virgin Islands",OTHERS
228,UM,"U.S. Minor Outlying Islands",OTHERS
27,BA,"Bosnia and Herzegovina",OTHERS
226,TC,"Turks and Caicos Islands",OTHERS
12,AW,Aruba,OTHERS
29,BV,"Bouvet Island",OTHERS
238,VA,"Vatican City",OTHERS
246,AX,"Åland Islands",OTHERS
9,AG,"Antigua and Barbuda",OTHERS
222,TT,"Trinidad and Tobago",OTHERS
32,VG,"British Virgin Islands",OTHERS
220,TK,Tokelau,OTHERS
208,SJ,"Svalbard and Jan Mayen",OTHERS
202,GS,"South Georgia and the South Sandwich Islands",OTHERS
159,NU,Niue,OTHERS
182,BL,"Saint Barthélemy",OTHERS
105,IM,"Isle of Man",OTHERS
110,JE,Jersey,OTHERS
176,PR,"Puerto Rico",OTHERS
126,MO,"Macau SAR China",OTHERS
173,PN,"Pitcairn Islands",OTHERS
135,MQ,Martinique,OTHERS
181,RE,Réunion,OTHERS
145,MS,Montserrat,OTHERS
167,PS,"Palestinian Territories",OTHERS
148,MM,"Myanmar [Burma]",OTHERS
153,AN,"Netherlands Antilles",OTHERS
154,NC,"New Caledonia",OTHERS
162,MP,"Northern Mariana Islands",OTHERS
161,KP,"North Korea",OTHERS
160,NF,"Norfolk Island",OTHERS
183,SH,"Saint Helena",OTHERS
184,KN,"Saint Kitts and Nevis",OTHERS
185,LC,"Saint Lucia",OTHERS
85,GL,Greenland,OTHERS
88,GU,Guam,OTHERS
83,GI,Gibraltar,OTHERS
90,GG,Guernsey,OTHERS
77,TF,"French Southern Territories",OTHERS
76,PF,"French Polynesia",OTHERS
75,GF,"French Guiana",OTHERS
188,VC,"Saint Vincent and the Grenadines",OTHERS
187,PM,"Saint Pierre and Miquelon",OTHERS
70,FK,"Falkland Islands",OTHERS
95,HM,"Heard Island and McDonald Islands",OTHERS
87,GP,Guadeloupe,OTHERS

207,SR,Suriname,SAMERICA
239,VE,Venezuela,SAMERICA
10,AR,Argentina,SAMERICA
235,UY,Uruguay,SAMERICA
48,CO,Colombia,SAMERICA
171,PE,Peru,SAMERICA
26,BO,Bolivia,SAMERICA
63,EC,Ecuador,SAMERICA
44,CL,Chile,SAMERICA
93,GY,Guyana,SAMERICA
170,PY,Paraguay,SAMERICA
30,BR,Brazil,SAMERICA

Jan 12, 2012

SVN support for Sublime Text

Sublime Text is one of the best text editor available at the moment. It is not yet an IDE, I believe, but it is very close to that.

Unfortunately, I did not find any built-in svn support, so I created one using RabbitVCS with which you can update/commit/show log.



 Installation:
1. Open sublime. Then "preferences->browse packages"
2. Unzip these files in that folder
OR Run that command "git clone git://github.com/kervin/sublime-svn.git" in that folder.
3. Install RabbitVCS.

You are done, sublime-svn is installed. Just let me know if there are bugs that must be corrected or any improvements necessary or if you want to make it work on different platforms.



Jun 14, 2011

Zend server with ssh (libcrypto + libssl)

I got the following error after installing Zend Server on Ubuntu 11.04.


/usr/bin/python: /usr/local/zend/lib/libcrypto.so.0.9.8: no version information available (required by /usr/bin/python)

/usr/bin/python: /usr/local/zend/lib/libssl.so.0.9.8: no version information available (required by /usr/bin/python)


Whenever I wanted to use ssh or connect to rdp the same error message appeared. A workaround to that problem was:

sudo mv /usr/local/zend/lib/libssl.so.0.9.8 /usr/local/zend/lib/libssl.so.0.9.8.hold

sudo mv /usr/local/zend/lib/libcrypto.so.0.9.8 /usr/local/zend/lib/libcrypto.so.0.9.8.hold


[Update]
With the above I could at least use ssh and rdp, but I still got the warning messages. I remove the two files "libcrypto.so.0.9.8" and "libssl.so.0.9.8" from the lib directory and no more error message. Zend server seems to be working normally on which, a magento installation is also working smoothly.

I think there are files libcrypto.so and libssl.so still doing the job. I have not found any information on the web, so until my zend server crashes this is my solution. :)

Apr 22, 2011

Default xmodmap for Lenovo ThinkPad R500

If you messed up your xmodmap key mapping like I did. Find below (collapsed) the default key mapping for a Lenovo ThinkPad R500.

keycode 0x09 = Escape  NoSymbol Escape
keycode 0x43 = F1  XF86_Switch_VT_1 F1  XF86_Switch_VT_1
keycode 0x44 = F2  XF86_Switch_VT_2 F2  XF86_Switch_VT_2
keycode 0x45 = F3  XF86_Switch_VT_3 F3  XF86_Switch_VT_3
keycode 0x46 = F4  XF86_Switch_VT_4 F4  XF86_Switch_VT_4
keycode 0x47 = F5  XF86_Switch_VT_5 F5  XF86_Switch_VT_5
keycode 0x48 = F6  XF86_Switch_VT_6 F6  XF86_Switch_VT_6
keycode 0x49 = F7  XF86_Switch_VT_7 F7  XF86_Switch_VT_7
keycode 0x4A = F8  XF86_Switch_VT_8 F8  XF86_Switch_VT_8
keycode 0x4B = F9  XF86_Switch_VT_9 F9  XF86_Switch_VT_9
keycode 0x4C = F10  XF86_Switch_VT_10 F10  XF86_Switch_VT_10
keycode 0x5F = F11  XF86_Switch_VT_11 F11  XF86_Switch_VT_11
keycode 0x60 = F12  XF86_Switch_VT_12 F12  XF86_Switch_VT_12
keycode 0x6F = Up  NoSymbol Up
keycode 0x4E = Scroll_Lock NoSymbol Scroll_Lock
keycode 0x6E = Home  NoSymbol Home
keycode 0x31 = grave  asciitilde grave  asciitilde
keycode 0x0A = 1  exclam  1  exclam
keycode 0x0B = 2  at  2  at
keycode 0x0C = 3  numbersign 3  numbersign
keycode 0x0D = 4  dollar  4  dollar
keycode 0x0E = 5  percent  5  percent
keycode 0x0F = 6  asciicircum 6  asciicircum
keycode 0x10 = 7  ampersand 7  ampersand
keycode 0x11 = 8  asterisk 8  asterisk
keycode 0x12 = 9  parenleft 9  parenleft
keycode 0x13 = 0  parenright 0  parenright
keycode 0x14 = minus  underscore minus  underscore
keycode 0x15 = equal  plus  equal  plus
keycode 0x16 = BackSpace NoSymbol BackSpace
keycode 0x6A = KP_Divide XF86_Ungrab KP_Divide XF86_Ungrab
keycode 0x61 = NoSymbol
keycode 0x63 = Hiragana NoSymbol Hiragana
keycode 0x4D = Num_Lock Pointer_EnableKeys Num_Lock Pointer_EnableKeys
keycode 0x70 = Prior  NoSymbol Prior
keycode 0x3F = KP_Multiply XF86_ClearGrab KP_Multiply XF86_ClearGrab
keycode 0x52 = KP_Subtract XF86_Prev_VMode KP_Subtract XF86_Prev_VMode
keycode 0x17 = Tab  ISO_Left_Tab Tab  ISO_Left_Tab
keycode 0x18 = q  Q  q  Q
keycode 0x19 = w  W  w  W
keycode 0x1A = e  E  e  E
keycode 0x1B = r  R  r  R
keycode 0x1C = t  T  t  T
keycode 0x1D = y  Y  y  Y
keycode 0x1E = u  U  u  U
keycode 0x1F = i  I  i  I
keycode 0x20 = o  O  o  O
keycode 0x21 = p  P  p  P
keycode 0x22 = bracketleft braceleft bracketleft braceleft
keycode 0x23 = bracketright braceright bracketright braceright
keycode 0x24 = Return  NoSymbol Return
keycode 0x6B = Print  Sys_Req  Print  Sys_Req
keycode 0x67 = NoSymbol
keycode 0x69 = Control_R NoSymbol Control_R
keycode 0x4F = KP_Home  KP_7  KP_Home  KP_7
keycode 0x50 = KP_Up  KP_8  KP_Up  KP_8
keycode 0x51 = KP_Prior KP_9  KP_Prior KP_9
keycode 0x56 = KP_Add  XF86_Next_VMode KP_Add  XF86_Next_VMode
keycode 0x42 = Caps_Lock NoSymbol Caps_Lock
keycode 0x26 = a  A  a  A
keycode 0x27 = s  S  s  S
keycode 0x28 = d  D  d  D
keycode 0x29 = f  F  f  F
keycode 0x2A = g  G  g  G
keycode 0x2B = h  H  h  H
keycode 0x2C = j  J  j  J
keycode 0x2D = k  K  k  K
keycode 0x2E = l  L  l  L
keycode 0x2F = semicolon colon  semicolon colon
keycode 0x30 = apostrophe quotedbl apostrophe quotedbl
keycode 0x33 = backslash bar  backslash bar
keycode 0x53 = KP_Left  KP_4  KP_Left  KP_4
keycode 0x54 = KP_Begin KP_5  KP_Begin KP_5
keycode 0x55 = KP_Right KP_6  KP_Right KP_6
keycode 0x32 = Shift_L  NoSymbol Shift_L
keycode 0x5E = less  greater  less  greater  bar  brokenbar
keycode 0x34 = z  Z  z  Z
keycode 0x35 = x  X  x  X
keycode 0x36 = c  C  c  C
keycode 0x37 = v  V  v  V
keycode 0x38 = b  B  b  B
keycode 0x39 = n  N  n  N
keycode 0x3A = m  M  m  M
keycode 0x3B = comma  less  comma  less
keycode 0x3C = period  greater  period  greater
keycode 0x3D = slash  question slash  question
keycode 0x3E = Shift_R  NoSymbol Shift_R
keycode 0x62 = Katakana NoSymbol Katakana
keycode 0x57 = KP_End  KP_1  KP_End  KP_1
keycode 0x58 = KP_Down  KP_2  KP_Down  KP_2
keycode 0x59 = KP_Next  KP_3  KP_Next  KP_3
keycode 0x6C = Alt_R  Meta_R  Alt_R  Meta_R
keycode 0x25 = Control_L NoSymbol Control_L
keycode 0x73 = End  NoSymbol End
keycode 0x40 = Alt_L  Meta_L  Alt_L  Meta_L
keycode 0x41 = space  NoSymbol space
keycode 0x71 = Left  NoSymbol Left
keycode 0x74 = Down  NoSymbol Down
keycode 0x75 = Next  NoSymbol Next
keycode 0x6D = Linefeed NoSymbol Linefeed
keycode 0x64 = Henkan_Mode NoSymbol Henkan_Mode
keycode 0x68 = KP_Enter NoSymbol KP_Enter
keycode 0x66 = Muhenkan NoSymbol Muhenkan
keycode 0x5A = KP_Insert KP_0  KP_Insert KP_0
keycode 0x5B = KP_Delete KP_Decimal KP_Delete KP_Decimal

clear Shift
clear Lock
clear Control
clear Mod1
clear Mod2
clear Mod3
clear Mod4
clear Mod5

add    Shift   = Shift_L Shift_R
add    Control = Control_L Control_R
add    Mod1    = Alt_L Alt_R 0x00CD
add    Mod2    = Num_Lock
add    Mod4    = Super_L Super_R 0x00CE 0x00CF
add    Mod5    = ISO_Level3_Shift Mode_switch
add    lock    = Caps_Lock

Oct 15, 2010

WPF DataGrid Controlling the Scrollbar

I just started with WPF controls and one of the issues I came through is controlling the scrollbar in WPF objects. In WPF you have logical and visual trees. To get the scrollbar, Microsoft recommendation is to go trough the tree to get the scroll bar. So find my implementation below.

/// Method to get scrollbar in a visual object
private static ScrollViewer GetScrollbar(DependencyObject dep)
{
    for (int i = 0; i < VisualTreeHelper.GetChildrenCount(dep); i++)
    {
        var child = VisualTreeHelper.GetChild(dep, i);
        if (child != null && child is ScrollViewer)
            return child as ScrollViewer;
        else
        {
            ScrollViewer sub = GetScrollbar(child);
            if (sub != null)
                return sub;
        }
    }
    return null;
}

ScrollViewer scrollView = GetScrollbar(myDataGrid);

It should work with other objects too, but I only tried with a WPF Datagrid.  I lost some time to figure out how to do this, hope it helps.