is_in_stock在magento export products时会是其中一列,但我在attributes里怎么也找不到它,它到底是什么?
Category: 小小草
IT 技术领域学海无涯。其实任何领域都学海无涯,无非 IT 发展太快了,让我有更多嘘唏。希望我掌握的技术有如小小草,虽然渺小,却有旺盛的生命力。
-
Magento 1.2.0.1 is out
今天很欣喜地发现Magento 1.2.0出来了,赶紧用magento connect upgrade了一下,结果升级失败,前台出不来,后台也进不去。
我只好手动安装了一下,原先php环境设置前台safe_mode on,只对后台safe_mode off,安装了magento 1.2.0以后,前台出现了错误提示 Warning: set_time_limit() [function.set-time-limit]: Cannot set time limit in safe mode。magento对php环境要求越来越高了,我只好把safe_mode 前台、后台统统off。这下就没问题了。
在我成功把magento 1.2.0运行起来后,发现1.2.0.1发布了,才几个小时啊,magento更新真够快了。我猜想1.2.0.1是针对safe_mode苛刻要求发布的小补丁,因为我又把magento 1.2.0更新成1.2.0.1,试着把php safe_mode恢复原先的设置,一切正常!
-
Bank of China
中国银行的网站终于改进了一下。以前外汇牌价网页在非中文平台上总显示乱码,现在用上了utf-8,这才有点像个”中国银行-全球门户网站”
-
Magento user defined attributes in product list
Magento内置的产品属性与自定义的产品属性可访问范围不同。默认设置下,自定义的产品属性只能在product view取值,如在product view以外则取不到值;内置的产品属性则没有这种限制。
为了让自定义产品属性能在Magento前端(比如product list, product new, 或者自己写一个product featured)随意取值,至少有三种方法可以更改默认设置。
最简单的办法是创建一个config.xml(文件名任意),放在app/etc/modules/下:
<?xml version="1.0"?> <config> <frontend> <product> <collection> <attributes> <attributeyouwant/> </attributes> </collection> </product> </frontend> </config>
以后有空再讲其他两种办法。记得一定要刷新Magento cache才能让设置生效!
-
Clear Magento cache is essential after layout xml update
说来懊恼,为了让Magento product list能够显示自定义属性的值,我查看了magento wiki 和 forum 上几十个帖子,众说纷纭,我也不知道哪个是对的,或者哪个针对当前1.1.8可用。一个个实验下来,排列组合了不下100种可能,比如:
- 有人说layout add this line: my_attribute,另有人说是
my_attribute
- 有人说要用$_product->getMyAttribute(),也有人说用$_product->getAttribute(‘my_attribute’),也有人说用$_product->getData(‘my_attribute’),也有人说用$_product->getAdditionalData(‘my_attribute’),还有人说用$_product->getResource()->getAttribute(‘my_attribute’)->getFrontend()->getValue($_product))
- 还有人说Create separate module for your customization, Name it ‘Mycustomization’
(can be changed).
Then do this:
1. Create file app/etc/modules/Mycustomization.xml<?xml version="1.0"?> <config> <modules> <Mycustomization> <active> true </active> <codePool> local </codePool> </Mycustomization> </modules> </config>
2. Create folder app/code/local/Mycustomization and inside it app/code/local/Mycustomization/etc/
3. Create file
app/code/local/Mycustomization/etc/config.xml<?xml version="1.0"?> <config> <modules> <Mycustomization> <version> 0.0.1 </version> </Mycustomization> </modules> <frontend> <product> <collection> <attributes> <designer/> </attributes> </collection> </product> </frontend> </config>
Once done on the frontend in all product collections you will have designer attribute loaded automatically.
- 还有Create a file app/etc/modules/category_product_attributes.xml with the following:
<?xml version="1.0"?> <config> <frontend> <product> <collection> <attributes> <attributeyouwant/>//This is your attribute </attributes> </collection> </product> </frontend> </config>
- 等等
最后发现所有组合都不起作用,除非清除magento cache 让 layout xml 生效。
- 有人说layout add this line: my_attribute,另有人说是
-
Email encoder for not being spidered
我用Email encoder很久了。以前总是去别人网站上运算一下,拿来就用。如今觉得加密算法很多,我应该筛选一下,并作一个适合我自己的常用的工具。
因为跟javascript 字符串加解密有关,我首先找到一段程序,试运行了一下,相当不错,据说还支持中文字符串加密以及中文密码。
function Encrypt(str, pwd) { if(str=="")return ""; str = escape(str); if(!pwd || pwd==""){ var pwd="1234"; } pwd = escape(pwd); if(pwd == null || pwd.length <= 0) { alert("Please enter a password with which to encrypt the message."); return null; } var prand = ""; for(var i=0; i<pwd.length; i++) { prand += pwd.charCodeAt(i).toString(); } var sPos = Math.floor(prand.length / 5); var mult = parseInt(prand.charAt(sPos) + prand.charAt(sPos*2) + prand.charAt(sPos*3) + prand.charAt(sPos*4) + prand.charAt(sPos*5)); var incr = Math.ceil(pwd.length / 2); var modu = Math.pow(2, 31) - 1; if(mult < 2) { alert("Algorithm cannot find a suitable hash. Please choose a different password. \nPossible considerations are to choose a more complex or longer password."); return null; } var salt = Math.round(Math.random() * 1000000000) % 100000000; prand += salt; while(prand.length > 10) { prand = (parseInt(prand.substring(0, 10)) + parseInt(prand.substring(10, prand.length))).toString(); } prand = (mult * prand + incr) % modu; var enc_chr = ""; var enc_str = ""; for(var i=0; i<str.length; i++) { enc_chr = parseInt(str.charCodeAt(i) ^ Math.floor((prand / modu) * 255)); if(enc_chr < 16) { enc_str += "0" + enc_chr.toString(16); }else enc_str += enc_chr.toString(16); prand = (mult * prand + incr) % modu; } salt = salt.toString(16); while(salt.length < 8)salt = "0" + salt; enc_str += salt; return enc_str; }
function Decrypt(str, pwd) { if(str=="")return ""; if(!pwd || pwd==""){ var pwd="1234"; } pwd = escape(pwd); if(str == null || str.length < 8) { alert("A salt value could not be extracted from the encrypted message because it's length is too short. The message cannot be decrypted."); return; } if(pwd == null || pwd.length <= 0) { alert("Please enter a password with which to decrypt the message."); return; } var prand = ""; for(var i=0; i<pwd.length; i++) { prand += pwd.charCodeAt(i).toString(); } var sPos = Math.floor(prand.length / 5); var mult = parseInt(prand.charAt(sPos) + prand.charAt(sPos*2) + prand.charAt(sPos*3) + prand.charAt(sPos*4) + prand.charAt(sPos*5)); var incr = Math.round(pwd.length / 2); var modu = Math.pow(2, 31) - 1; var salt = parseInt(str.substring(str.length - 8, str.length), 16); str = str.substring(0, str.length - 8); prand += salt; while(prand.length > 10) { prand = (parseInt(prand.substring(0, 10)) + parseInt(prand.substring(10, prand.length))).toString(); } prand = (mult * prand + incr) % modu; var enc_chr = ""; var enc_str = ""; for(var i=0; i<str.length; i+=2) { enc_chr = parseInt(parseInt(str.substring(i, i+2), 16) ^ Math.floor((prand / modu) * 255)); enc_str += String.fromCharCode(enc_chr); prand = (mult * prand + incr) % modu; } return unescape(enc_str); }
转念一想,我把问题搞复杂了,对自己没什么好处。我的Email encoder用得着这么复杂吗?毕竟我想保护的又不是名人的Email address。所以我改用我自己的方式——采用双重url encode,在第二重url encoding时,encode全部字符(含字母和数字)。
-
让浏览主控服务器从幕后走到台前
可以用
nbtstat -a (computer name or ip address)
命令查看该计算机是否浏览主控服务器。如果是,则会出现“..__MSBROWSE_.
”字样。浏览主控服务器不一定非是选举产生,是可以指定的。
只要在希望成为浏览主控服务器的电脑上打开注册表,在
[HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Services/Browser/Parameters]
一项中把IsDomainMaster
的值改为“True”即可。这样,这台电脑就会成为一个浏览主控服务器。这台电脑启动时,如果网络中已经有了浏览主控服务器,那么它会发起一个新的选举,在这个选举中它常常会赢得选举。当然,如果其它电脑也做了同样的设置,那么它们之间的竞争就要按正常的选举规则了。另:如不想让某台电脑永远不成为浏览主控服务器,可以在注册表中的
[HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Services/Browser/Parameters]
一项中把MaintainServerList
的值改为“NO”,即可,这样这台电脑将不会成为浏览列表提供者,同时该电脑的Computer Browser服务也将无法启动,如强行启动会出现错误提示。 -
Update proof way to customise Magento code
如果直接修改Magento的文件,Magento每次升级后,又要重新修改,所以这肯定不是个办法。以我最近一次修改/app/code/core/Mage/Core/Model/Email/Template.php为例,修改后Magento使用gmail smtp server来发送邮件。以下我使用update proof way重作一遍。(当前Magento版本是1.1.8)
1. 不直接修改/app/code/core/Mage/Core/Model/Email/Template.php,而是新建一个/app/code/local/(MyNameSpace)/Core/Model/Email/Template.php,其中(MyNameSpace)可以随意命名。
/app/code/local/(MyNameSpace)/Core/Model/Email/Template.php 是 /app/code/core/Mage/Core/Model/Email/Template.php的子类,其中我只重载了send方法,所以,/app/code/local/(MyNameSpace)/Core/Model/Email/Template.php不需要拷贝其他部分,它完整的内容是:
class (MyNameSpace)_Core_Model_Email_Template extends Mage_Core_Model_Email_Template {
public function send($email, $name=null, array $variables = array())
{
if(!$this->isValidForSend()) {
return false;
}if (is_null($name)) {
$name = substr($email, 0, strpos($email, ‘@’));
}$variables[’email’] = $email;
$variables[‘name’] = $name;$mail = $this->getMail();
if (is_array($email)) {
foreach ($email as $emailOne) {
$mail->addTo($emailOne, $name);
}
} else {
$mail->addTo($email, ‘=?utf-8?B?’.base64_encode($name).’?=’);
}$this->setUseAbsoluteLinks(true);
$text = $this->getProcessedTemplate($variables, true);if($this->isPlain()) {
$mail->setBodyText($text);
} else {
$mail->setBodyHTML($text);
}$mail->setSubject(‘=?utf-8?B?’.base64_encode($this->getProcessedTemplateSubject($variables)).’?=’);
$mail->setFrom($this->getSenderEmail(), $this->getSenderName());$config = array(
‘ssl’ => ‘ssl’, //optional
‘port’ => 465, //optional – default 25
‘auth’ => ‘login’,
‘username’ => ‘your_email’,
‘password’ => ‘your_password’);$transport = new Zend_Mail_Transport_Smtp(‘smtp.gmail.com’, $config);
try {
$mail->send($transport); //add $transport object as parameter
$this->_mail = null;
}
catch (Exception $e) {
return false;
}return true;
}
}2. 新建一个/app/code/local/(MyNameSpace)/Core/etc/config.xml,内容是
<?xml version=”1.0″?>
<config>
<modules>
<(MyNameSpace)_Core>
<version>1.0.0</version>
</(MyNameSpace)_Core>
</modules>
<global>
<models>
<core>
<rewrite>
<email_template>(MyNameSpace)_Core_Model_Email_Template</email_template>
</rewrite>
</core>
</models>
</global>
</config>据说因为Zend Framework的一个bug,tag <email_template>必须在一行内封闭,其间不得有多余的white space。我试过,确实如此。
3. 最后,在Magento注册本次重载:新建一个/app/etc/modules/(MyNameSpace)_Core.xml,内容是:
<?xml version=”1.0″?>
<config>
<modules>
<(MyNameSpace)_Core>
<active>true</active>
<codePool>local</codePool>
</(MyNameSpace)_Core>
</modules>
</config>我只是以重载一个model class为例,重载block class也是同样步骤。按Magento的说法,重载controller class有点区别,我尚未亲试。
-
Send mail using Gmail SMTP in Magento
我能想到的也是大部分人能想到的——我想用gmail smtp server代替magento内置的sendmail,这么做的好处是用gmail sent mail log all emails sent out by magento。gmail smtp server是我所知的唯一一个能记录发送邮件的smtp服务器(感谢google)。
Magento默认使用MTA发送邮件,后台configuration可以设置使用smtp发送邮件,但仅限于未使用ssl的smtp服务器,看来只能修改程序才能让Magento用上gmail ssl smtp server了。
似乎有很多人有这个想法但无法成功完成程序的修改。我参照了Use any smtp to send email (even gmail)的代码,但发现它无法连接gmail smtp server (可能以前可以,但gmail smtp server改了设置?)。
经我修改,在magento 1.1.8版测试可行的代码方案是:
修改/app/code/core/Mage/Core/Model/Email/Template.php, 找到public function send($email, $name=null, array $variables = array()),删掉此函数中最后几句:
try {
$mail->send(); // Zend_Mail warning..
$this->_mail = null;
}
catch (Exception $e) {
return false;
}
return true;替换为:
$config = array(
'ssl' => 'ssl',
'port' => 465,
'auth' => 'login',
'username' => 'your_email',
'password' => 'your_password');$transport = new Zend_Mail_Transport_Smtp('smtp.gmail.com', $config);
try {
$mail->send($transport); //add $transport object as parameter
$this->_mail = null;
}
catch (Exception $e) {
return false;
}
return true;除此之外无需任何其他修改。赶紧试一下吧。
原贴主要的误导之处是一个错误的$config:
$config = array(
'ssl' => 'tls',
'port' => 465,
'auth' => 'login',
'username' => 'your_email',
'password' => 'your_password');
其实,如果非要使用tls的话,相应的port应该是587。tls+587的搭配虽然能发邮件,但编码不对,我想应该在程序其他地方相应调整。这个我就没去研究了,ssl+465已能正常发送邮件,我的想法已经实现了。
-
abuse and postmaster as email list
Google help有提到:
For your convenience, the Google Team monitors abuse@yourdomain.com and postmaster@yourdomain.com to ensure that we can properly address all reports of spam, abuse, and technical issues. If you’d like a copy of messages sent to abuse@yourdomain.com and postmaster@yourdomain.com, create email lists for both addresses, and add yourself as a recipient.
Since abuse and postmaster are reserved aliases, you won’t be able to use them as usernames or nicknames.
可我在读到这段说明之前,就建了两个email lists: abuse@mydomain.com 和 postmaster@mydomain.com,我并未想着要把这两个特殊地址创建为单独的邮箱用户,因为我觉得这样做有悖Google App Mail Best Practices。看来我和google想到一起去了。