Magento 数据导入sku自动增长

近来由于业务需要研究了下Magento的数据导入模块,只能说很好很强大。起初的目的是为了业务组的一些BT要求(此处对业务组500字的谴责…):要求导入产品的时候根据产品的id自动生成sku,忽略sku的意义。在粗略的研究了导入模块的源码之后,用了一个不是很优雅的方法实现。唉,每个优雅的接口都有个龌龊的实现。

Magento的导入模块从csv中读取数据后,会把数据序列化后存在表importexport_importdata中。之后导入的时候会从表里读取数据,这样办法就有了。我们在序列化之前,修改导入产品的sku,然后存到数据库中就ok了。
具体实现如下

//app/code/local/Mage/ImportExport/Model/Import/Entity/Abstract.php
 /**
     * Import product sku
     *
     * @var int
     */
    protected $_sku = 0;
 
/**
     * Change row data before saving in DB table.
     *
     * @param array $rowData
     * @return array
     */
    protected function _prepareRowForDb(array $rowData)
    {
        /**
         * Convert all empty strings to null values, as
         * a) we don't use empty string in DB
         * b) empty strings instead of numeric values will product errors in Sql Server
         */
        foreach ($rowData as $key => $val) {
            if ($val === '') {
                $rowData[$key] = null;
            }
        }
        //add product sku auto increment
        $key = Mage_ImportExport_Model_Import_Entity_Product::COL_SKU;
        $type = Mage_ImportExport_Model_Import_Entity_Product::COL_TYPE;
        $set = Mage_ImportExport_Model_Import_Entity_Product::COL_ATTR_SET;
        if( $rowData[$key] &&  ( $rowData[$type] == 'simple' && $rowData[$set] == 'Default' || $rowData[$type] == 'configurable' ) ) {
            if(!$this->_sku){
                //get last product entity id
                $res = Mage::getSingleton('core/resource');
                $readConnection = $res->getConnection('core_read');
                $table = $res->getTableName('catalog_product_entity');
                $this->_sku = Mage::getResourceHelper('importexport')->getNextAutoincrement("{$table}");
            }
            $rowData[$key] = strval($this->_sku);
        }
        return $rowData;
    }

就这样子吧。

Yii实现Password Repeat Validate Rule

在使用Yii时遇到这样的需求:在一个注册的页面输入两次密码,并验证两次输入是否一致。可是password的repeat的字段在数据库并不存在。问题来了,如何创建一个password_repeat的属性,进行密码验证。最偷懒的方法就是利用yii自带的验证器。在这里记录下实现的方法。

假设项目结构如下

protected/models/User.php

proteced/controllers/SiteController.php

protected/views/site/forgot.php

首先在User.php添加一个public的password_repeat属性,该属性会自动映射到rules中。注意on属性,是决定rule应用的场景,默认的场景是insert。在这里,我应用在forgot场景。

class User extends CActiveRecord
{
    public $password_repeat;
    public function rules()
    {
        // NOTE: you should only define rules for those attributes that
        // will receive user inputs.
        return array(
            ...
            array('password_repeat', 'required' , 'on' => 'forgot'),
            array('password', 'compare', 'compareAttribute'=>'password_repeat' ,'on'=>'forgot'),
 
        );
    }
}

在SiteController.php中的actionForgot方法中,添加一个User的model。

public function actionForgotPassword(){
   $model = new User();
   //set current scenario
   $model->scenario = 'forgot';
   $User = Yii::app()->getRequest()->getParam('User');
   if($User){
      $model->attributes = $User;
      Helper::performAjaxValidation($model);
   ....
   }
   $this->render('forgot',array( 'model' => $model));
}
//Helper的ajax 验证方法,这个在默认生成的controller可以找到
static function performAjaxValidation($model)
    {
        if(isset($_POST['ajax']) && $_POST['ajax']==='user-form')
        {
            echo CActiveForm::validate($model);
            Yii::app()->end();
        }
    }

在视图文件中forgot.php,添加password_repeat字段。

<?php $form=$this->beginWidget('CActiveForm', array(
    'id'=>'user-form',
    'enableAjaxValidation'=>true,
)); ?>
<ul>
<li>
        <?php echo $form->label($model,'password' , array( 'label' => 'Your New Password')); ?>
        <?php echo $form->passwordField($model,'password',array('size'=>32,'maxlength'=>32)); ?>
        <?php echo $form->error($model,'password'); ?>
    </li>
<li>
        <?php echo $form->labelEx($model,'password_repeat' , array( 'label' => 'Repeat Password')); ?>
        <?php echo $form->passwordField($model,'password_repeat',array('size'=>32,'maxlength'=>32)); ?>
        <?php echo $form->error($model,'password_repeat'); ?>
    </li>
</ul>

这样就实现了password的验证了。

参考资料

Understanding Scenarios

安装Redmine 2.0

Redmine 这厮就这样大张旗鼓的升级到了2.0。正好公司的mantisbt实在是不给力,就准备安装Redmine。很之前安装的方法并没有什么区别,可以参考之前安装CentOS 6 安装Redmine。特此记录下。

下载Ruby 1.8.7稳定版即可。

cd ~
 
wget ftp://ftp.ruby-lang.org/pub/ruby/1.8/ruby-1.8.7.tar.gz
 
tar  xzvf ruby-1.8.7.tar.gz
 
cd ruby-1.8.7
 
./configure
 
make && make install

查看Ruby的版本,会报错。

ruby -v
 
-bash: /usr/bin/ruby: No such file or directory

查看ruby的安装路径

which ruby
 
/usr/local/bin/ruby
 
where ruby
 
ruby: /usr/lib/ruby /usr/local/bin/ruby /usr/local/lib/ruby

修复ruby的路径问题

ln -s /usr/local/bin/ruby /usr/bin/ruby

现在可以查看ruby的版本了

ruby -v
 
ruby 1.8.7 (2008-05-31 patchlevel 0) [i686-linux]

安装rubygems

wget http://production.cf.rubygems.org/rubygems/rubygems-1.4.2.tgz
 
tar xzvf rubygems-1.4.2.tgz
 
cd rubygems-1.4.2
 
ruby setup.rb
 
RubyGems 1.4.2 installed

修复gem的路径问题

ln -s /usr/local/bin/gem /usr/bin/gem
 
gem -v
 
1.4.2

安装 passenger模块

gem install passenger
 
//安装passenger的apache模块,同样也有nginx下的模块
//passenger-install-nginx-module
 
passenger-install-apache2-module

会提示你有哪些依赖没有被安装。

To install GNU C++ compiler:
Please run yum install gcc-c++ as root.
 
To install Curl development headers with SSL support:
Please run yum install curl-devel as root.
 
To install Zlib development headers:
Please run yum install zlib-devel as root.
 
yum install gcc-c++
 
yum install curl-devel
 
yum install zlib-devel
 
passenger-install-apache2-module

安装完成后 添加 配置到apache的配置文件

vim /etc/httpd/conf/httpd.conf
 
LoadModule passenger<em>module /usr/local/lib/ruby/gems/1.8/gems/passenger-3.0.12/ext/apache2/mod</em>passenger.so
PassengerRoot /usr/local/lib/ruby/gems/1.8/gems/passenger-3.0.12
PassengerRuby /usr/local/bin/ruby
 
service httpd restart

从rubyforge下载redmine

wget http://rubyforge.org/frs/download.php/76134/redmine-2.0.0.tar.gz
 
tar xzvf redmine-2.0.0.tar.gz
 
cp -rf redmine-2.0.0 /var/www/redmine
 
//设置相关属性
cd /var/www
 
chmod 755 -R redmine
 
chown apache.apache -R redmine

添加网站配置文件

DocumentRoot /var/www/redmine/public
ServerName pms.xbc.me

添加数据库配置文件

cd redmine/config
 
cp database.yml.example database.yml
 
vim database.yml
 
production:
adapter: mysql
database: redmine
host: localhost
username: redmine
password: my_password
encoding: utf8
 
chmod 755 -R database.yml
 
chown apache.apache -R database.yml

不要忘记了 redmine 1.4以后添加bundler依赖。

gem install bundler
 
bundle install --without development test

如果在bundle安装时,出现下面的这些错误的话,去掉一些不需要的扩展。

An error occured while installing pg (0.13.2), and Bundler cannot continue.
An error occured while installing rmagick (2.13.1), and Bundler cannot continue.
An error occured while installing sqlite3 (1.3.6), and Bundler cannot continue.
 
bundle install --without development test postgresql rmagick sqlite

生成session 密钥

cd /var/www/redmine
 
//Generate a session store secret.
rake generate_secret_token

创建数据库结构。

//Create the database structure, by running the following command under the application root directory:
 
RAILS_ENV=production rake db:migrate

导入默认的配置文件

RAILS_ENV=production rake redmine:load_default_data

安装环境为Centos 5.6+Apache2.2。
参考

http://www.redmine.org/boards/2/topics/30244

http://www.redmine.org/projects/redmine/wiki/RedmineInstall

添加Apache模块

和php添加模块类似,Apache也有动态添加模块的工具apxs。

找到下载的模块目录

cd /usr/local/apache/modules/filters
// 编译并安装
apxs -ica mod_deflate.c
 
//会出现编译问题,换成绝对路径编译
apxs -ica /usr/local/apache/modules/filters/mod_deflate.c

apxs在编译完成时,会自动将编译好的模块安装到apache的所在的模块目录,例如/usr/local/apache/modules。并在/etc/httpd/conf/httpd.conf添加

LoadModule deflate_module     modules/mod_deflate.so

参考

http://httpd.apache.org/docs/2.2/programs/apxs.html

apxs添加apache模块

动态添加php extension

通常情况下,在手动编译下都会添加一些常用的php模块,例如mbstring、curl等。那如果手动编译后,发现有些应用又需要添加新的php模块呢?

php官方列出了几种动态添加模块的方式:

1. 使用pear来安装pecl的模块。

2. 使用phpize来安装pecl模块。

3. 使用pecl来安装模块。

4. 重新静态编译php,添加相关的模块。

其中1和3都要求已经安装pecl或者pear模块。pecl和pear的命令参数都差不多了。使用pecl安装模块的命令如下:

/usr/local/php5.3.10/bin/pecl install apc
//卸载apc
/usr/local/php5.3.10/bin/pecl uninstall apc

不过我在使用pecl的安装模块出现了编译错误,只好使用phpize来安装。先在pecl.php.net上下载所需要的php模块,例如我需要安装apc。最新的stable版的是3.1.9。

cd /root/tmp
wget http://pecl.php.net/get/APC-3.1.9.tgz
tar xzvf APC-3.1.9.tgz
cd APC-3.1.9
/usr/local/php5.3.10/bin/phpize
./configure
make
make install

这样就安装了一个apc模块。默认情况下会安装include/php/ext/下,以我的为例就是/usr/local/php5.3.10/include/php/ext/。

参考资料

用 PEAR 编译共享 PECL 扩展库