ラベル ショッピングカート の投稿を表示しています。 すべての投稿を表示
ラベル ショッピングカート の投稿を表示しています。 すべての投稿を表示

2011年9月1日

Codeigniterを使ってショッピングカートをゼロから作ってみよう。 # 7

ショッピングカートだけでなく、ほとんどのサイトで設定が必要になります。
今回はその設定をファイルに保存するロジックを作ります。

設定はDBに保存して必要な時にだけ呼び出してもいいんですが、アプリケーションを作っていく過程、もしくはリリースしたアプリケーションをアップデートする時に新しい機能を付けるなど、後で設定が増えていくことも考慮するとメンテナンスを楽にするならファイルだろうとの結論に達しました。DBアクセスは極力減らした方がいいですしね。
(もちろん作る前に使うであろう全ての設定項目を考えて一切追加しないなら別ですが・・・)

コントローラ:admin/application/controllers/setting.php
<?php
class Setting extends Controller
{
    function __construct()
    {
        parent::__construct();
        if( ! _s('admin')) redirect();
    }
    
    function index()
    {
        $this->form_validation->set_error_delimiters('<span class="error">', '</span>');
        $this->form_validation->set_rules('name',_l('SHOP_NAME'),'required|trim|xss_clean');
        $this->form_validation->set_rules('url',_l('SHOP_URL'),'required|trim|xss_clean');
        $this->form_validation->set_rules('title',_l('PAGE_TITLE'),'trim|xss_clean');
        $this->form_validation->set_rules('keywords',_l('PAGE_KEYWORDS'),'trim|xss_clean');
        $this->form_validation->set_rules('desc',_l('PAGE_DESCRIPTION'),'trim|xss_clean');
        if($this->form_validation->run())
        {
            $data['i'] = $this->input->post();
            
            $config_data = $this->load->view('setting/config_template', $data, TRUE);
            file_put_contents(EXTPATH.'config/'.((defined('ENVIRONMENT'))?ENVIRONMENT:'').'/setting.php', $config_data);
            setMessage('success', _l('SUCCESS_UPDATE_SETTING'));
            redirect('setting');
        }
        
        $data['setting'] = $this->config->item('setting');
        $data['breadcrumbs'] = array(_l('HOME')=>'', _l('SETTINGS')=>'settings');
        $data['h1'] = _l('SETTINGS_SHOP');
        $this->layout->view('setting/shop', $data);
    }
}


コントローラ22行目で読み込む設定ファイルテンプレート: admin/application/views/setting/config_template.php
<?php echo '<?php'.PHP_EOL; ?>
/*
 *  Setting Updated: <?php echo date('Y-m-d H:i:s').PHP_EOL; ?>
 */
    $config['site_name']        = '<?php echo $i['name']; ?>';
    $config['site_url']         = '<?php echo $i['url']; ?>';
    $config['page_title']       = '<?php echo $i['title']; ?>';
    $config['page_keywords']    = '<?php echo $i['keywords']; ?>';
    $config['page_desc']        = '<?php echo $i['desc']; ?>';

これで設定をアップデートするたびにsetting.phpを再作成することになります。
最後にconfig/autoload.phpにsettingを追加しておけば毎回設定を読み込んでくれます。

ビューファイルは設定項目が増えたらスクリーンショットを載せたいと思います。
今回はロジックのみでご勘弁をΣ(; ̄□ ̄A

2011年8月16日

Codeigniterを使ってショッピングカートをゼロから作ってみよう。 # 6

今回はユーザ管理です。
ユーザの一覧表示、新規作成(追加)、編集、最後に削除です。
苦手なjavascriptで手間取って時間かかりました( ̄Д ̄;;


■ File Tree


■ コントローラ:User
admin/application/controllers/user.php
<?php
class User extends Controller
{
    function __construct()
    {
        parent::__construct();
        if( ! _s('admin')) redirect();
        $this->load->model('users_model', 'usersdb');
    }
    
    function index()
    {
        $this->accounts();
    }
    
    function accounts($page=0)
    {
        $this->form_validation->set_rules('delete', '', 'isArray');
        if($this->form_validation->run())
        {
            $this->usersdb->delete_array($this->input->post('delete'));
        }
        
        $data['breadcrumbs'] = array(_l('HOME')=>'', _l('USERLIST')=>'user');
        $data['h1'] = _l('USERLIST');
        $data['all'] = $this->usersdb->all($page);
        $this->layout->view('user/accounts', $data);
    }
    
    function create()
    {
        $this->form_validation->set_error_delimiters('<span class="error">', '</span>');
        $this->form_validation->set_rules('email',_l('EMAIL'),'required|valid_email|email_exist');
        $this->form_validation->set_rules('firstname',_l('FIRSTNAME'),'required|min_length[2]');
        $this->form_validation->set_rules('lastname',_l('LASTNAME'),'required|min_length[2]');
        $this->form_validation->set_rules('passwd',_l('PASSWORD'),'required|min_length[6]|matches[passwdconf]');
        if($this->form_validation->run())
        {   // insert into db
            $data = array(
                'email'     => $this->input->post('email'),
                'password'  => $this->input->post('passwd'),
                'firstname' => $this->input->post('firstname'),
                'lastname'  => $this->input->post('lastname'),
                'status'    => $this->input->post('status')
            );
            
            $this->usersdb->newuser($data);
            
            redirect('user');
        }

        $data['breadcrumbs'] = array(_l('HOME')=>'', _l('USERLIST')=>'user', _l('CREATE_USER')=>'user/create');
        $data['h1'] = _l('CREATE_USER');
        $this->layout->view('user/create', $data);
    }
    
    function edit($id)
    {   // just in case
        if($user = $this->usersdb->byId($id))
        {
            $this->form_validation->set_error_delimiters('<span class="error">', '</span>');
            $this->form_validation->set_rules('email',_l('EMAIL'),'required|valid_email|email_exist['.$id.']');
            $this->form_validation->set_rules('firstname',_l('FIRSTNAME'),'required|min_length[2]');
            $this->form_validation->set_rules('lastname',_l('LASTNAME'),'required|min_length[2]');
            if($this->input->post('passwd')) $this->form_validation->set_rules('passwd',_l('PASSWORD'),'required|min_length[6]|matches[passwdconf]');

            if($this->form_validation->run())
            {   // update user info
                $data['email'] = $this->input->post('email');
                $data['firstname'] = $this->input->post('firstname');
                $data['lastname'] = $this->input->post('lastname');
                $data['status'] = $this->input->post('status');
                if($this->input->post('passwd')) $data['password'] = $this->input->post('password');
                
                $this->usersdb->update($user, $data);
                
                redirect('user');
            }

            $data['breadcrumbs'] = array(_l('HOME')=>'', _l('USERLIST')=>'user', _l('EDIT_USER')=>'user/edit');
            $data['h1'] = _l('EDIT_USER');
            $data['user'] = $user;
            $this->layout->view('user/edit', $data);
        }
        else redirect();
    }
}
□ メソッド
index ( accounts )で一覧表示と削除。
create で新規ユーザ作成
edit で編集しています。

■ モデル:Users_model.php
extension/models/users_model.php
function newuser($data)
    {
        $data['hash'] = $this->auth->_generate_hash();
        $data['password'] = $this->auth->_encode($data['password'], $data['hash']);
        $this->db->insert($this->table, $data);
        setMessage('success', _l('SUCCESS_CREATE_USER'));
    }
    
    function update($obj, $data)
    {
        if(array_key_exists('password', $data)) $data['password'] = $this->auth->_encode($data['password'], $obj->hash);
        $this->db->where('id', $obj->id);
        $this->db->update($this->table, $data);
        setMessage('success', _l('SUCCESS_UPDATE_USER'));
    }
ユーザ追加用とアップデート用のメソッドを追加。

■ Form_validationライブラリにルール追加
extension/libraries/MY_Form_validation.php
<?php
class MY_Form_validation extends Form_validation
{
    function __construct()
    {
        parent::__construct();
    }
    
    function email_exist($email, $id=FALSE)
    {
        $this->CI->form_validation->set_message('email_exist', $this->CI->lang->line('in_use'));
        $this->CI->load->model('users_model', 'usersdb');
        return ($this->CI->usersdb->exist($email, $id)) ? FALSE : TRUE;
    }
    
    function isArray($arr)
    {
        $this->CI->form_validation->set_message('isArray', $this->CI->lang->line('is_array'));
        return (is_array($arr) && count($arr) > 0) ? TRUE : FALSE;
    }
}

■ ビュー:一覧表示&削除
admin/application/views/user/accounts.php
<div class="buttons">
<button onclick="javascript:location.href = '<?php echo base_url('user/create'); ?>';"><?php echo _l('CREATE_USER'); ?></button>
<button onclick="confirmDelSelected();"><?php echo _l('DELETE_SELECTED'); ?></button>
</div>
<?php echo form_open(uri_string()); ?>
<?php if($all): ?>
<table class="list">
<tr>
    <th><input type="checkbox" onclick="applyToAll(this);" /></th>
    <th><?php echo _l('FULLNAME'); ?></th>
    <th><?php echo _l('EMAIL'); ?></th>
<?php /*    <th><?php echo _l('ROLE'); ?></th> */ ?>
    <th><?php echo _l('STATUS'); ?></th>
    <th><?php echo _l('ACTION'); ?></th>
</tr>
<?php foreach($all as $a): ?>
<tr>
    <td><input type="checkbox" name="delete[]" value="<?php echo $a->id; ?>"<?php if($a->id==1): ?> disabled="disabled"<?php endif; ?>></td>
    <td><?php echo $a->firstname.' '.$a->lastname; ?></td>
    <td><?php echo $a->email; ?></td>
<?php /*    <td><?php echo $a->role; ?></td> */ ?>
    <td><?php echo ($a->status) ? _l('ACTIVE') : _l('INACTIVE') ; ?></td>
    <td>
        <a href="<?php echo base_url('user/edit/'.$a->id); ?>"><?php echo _l('EDIT'); ?></a>
    </td>
</tr>
<?php endforeach; ?>
</table>
<?php endif; ?>
<?php echo form_close(); ?>

<script type="text/javascript">
function confirmDelSelected() {
    var c = 0;            
    $(":checkbox").each(function(){
        if($(this).attr('checked')) c++;
    })
    if(c > 0) { 
        if(confirm("<?php echo _l('CONFIRM_DELETE_SELECTED'); ?>")) $('form').submit();
    }
    else { alert("<?php echo _l('ALERT_PLZ_SELECT'); ?>"); }
}
</script>



全くスタイルしてない画面ですが(苦)
後でユーザレベル(タイプ)なんかを付け加えることになるでしょう。

削除する時には確認用のポップアップが表示されます。



■ ビュー:新規作成
admin/application/views/user/create.php
<?php echo form_open(uri_string()); ?>
<input type="button" value="<?php echo _l('CANCEL'); ?>" onclick="javascript:location.href = '<?php echo base_url('user'); ?>';" tabindex="9" />

<h2><?php echo _l('USER_DETAILS'); ?></h2>
<dl class="horizontal">
    <dt><?php echo _l('EMAIL'); ?></dt>
    <dd><input class="field" id="email" type="email" name="email" value="<?php echo set_value('email'); ?>" tabindex="1" /><?php echo form_error('email'); ?></dd>
    <dt><?php echo _l('LASTNAME'); ?></dt>
    <dd><input class="field" id="lastname" type="text" name="lastname" value="<?php echo set_value('lastname'); ?>" tabindex="2" /><?php echo form_error('lastname'); ?></dd>
    <dt><?php echo _l('FIRSTNAME'); ?></dt>
    <dd><input class="field" id="firstname" type="text" name="firstname" value="<?php echo set_value('firstname'); ?>" tabindex="3" /><?php echo form_error('firstname'); ?></dd>
    <dt><?php echo _l('PASSWORD'); ?></dt>
    <dd><input class="field" id="passwd" type="password" name="passwd" value="" tabindex="4" /><?php echo form_error('passwd'); ?></dd>
    <dt><?php echo _l('PASSWORDCONF'); ?></dt>
    <dd><input class="field" id="passwdconf" type="password" name="passwdconf" value="" tabindex="5" /></dd>
    <dt><?php echo _l('STATUS'); ?></dt>
    <dd>
        <select name="status" class="field" tabindex="6">
            <option value="1"><?php echo _l('ACTIVE'); ?></option>
            <option value="0"><?php echo _l('INACTIVE'); ?></option>
        </select>
    </dd>
    
    <dd><input type="submit" value="<?php echo _l('SAVE'); ?>" onclick="return check(['email','lastname','firstname','passwd','passwdconf']);" tabindex="7" /> <input type="reset" value="<?php echo _l('RESET'); ?>" tabindex="8" /></dd>
</dl>
<?php echo form_close(); ?>



javascriptは非常に簡単なチェックだけですが、javascriptとphpの両方で入力チェックしてます。
入力しないとこんな感じにハイライトされます。




■ ビュー:編集
admin/application/views/user/edit.php
<?php echo form_open(uri_string()); ?>
<input type="button" value="<?php echo _l('CANCEL'); ?>" onclick="javascript:location.href = '<?php echo base_url('user'); ?>';" tabindex="9" />

<h2><?php echo _l('USER_DETAILS'); ?></h2>
<dl class="horizontal">
    <dt><?php echo _l('EMAIL'); ?></dt>
    <dd><input class="field" id="email" type="email" name="email" value="<?php echo $user->email; ?>" tabindex="1" /><?php echo form_error('email'); ?></dd>
    <dt><?php echo _l('LASTNAME'); ?></dt>
    <dd><input class="field" id="lastname" type="text" name="lastname" value="<?php echo $user->lastname; ?>" tabindex="2" /><?php echo form_error('lastname'); ?></dd>
    <dt><?php echo _l('FIRSTNAME'); ?></dt>
    <dd><input class="field" id="firstname" type="text" name="firstname" value="<?php echo $user->firstname; ?>" tabindex="3" /><?php echo form_error('firstname'); ?></dd>
    <dt><?php echo _l('PASSWORD'); ?></dt>
    <dd><input class="field" id="passwd" type="password" name="passwd" value="" tabindex="4" /><?php echo form_error('passwd'); ?></dd>
    <dt><?php echo _l('PASSWORDCONF'); ?></dt>
    <dd><input class="field" id="passwdconf" type="password" name="passwdconf" value="" tabindex="5" /></dd>
    <dt><?php echo _l('STATUS'); ?></dt>
    <dd>
        <select name="status" class="field" tabindex="6">
            <option value="1"<?php if($user->status==1): ?> selected="selected"<?php endif; ?>><?php echo _l('ACTIVE'); ?></option>
            <option value="0"<?php if($user->status==0): ?> selected="selected"<?php endif; ?>><?php echo _l('INACTIVE'); ?></option>
        </select>
    </dd>
    
    <dd><input type="submit" value="<?php echo _l('SAVE'); ?>" onclick="return check(['email','lastname','firstname']);" tabindex="7" /> <input type="reset" value="<?php echo _l('RESET'); ?>" tabindex="8" /></dd>
</dl>
<?php echo form_close(); ?>



編集画面も似たようなものです。パスワードが入力されてない場合はスルーします。
パスワードのエラーはphpでのみ表示。javascriptは苦手・・・


だいぶ長くなってしまったので、今日はここまでにします。

2011年8月10日

Codeigniterを使ってショッピングカートをゼロから作ってみよう。 # 4

前回フロントエンドとバックエンドを分けたので、そこに認証機能をつけます。




■ ユーザに関する考察
ショッピングカートにはサイトの管理者と登録ユーザという2種類のユーザがいると思います。
サイトを運営するのは個人であったり会社であったりしますが、管理者が1人じゃないこともあるでしょう。そう考えると登録ユーザ(お客さん)と管理ユーザはわけたほうが良いかもしれません。

そこで登録ユーザをCustomer、管理ユーザをUserと位置づけ開発を続けていきたいと思います。


■ Usersテーブル作成
まず管理ユーザ用のDBテーブルを作成します。
(とりあえず現在のところは最低限必要な情報で構成しています。)

CREATE TABLE IF NOT EXISTS `users` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `email` varchar(50) COLLATE utf8_unicode_ci NOT NULL,
  `password` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  `firstname` varchar(50) COLLATE utf8_unicode_ci NOT NULL,
  `lastname` varchar(50) COLLATE utf8_unicode_ci NOT NULL,
  `status` tinyint(4) NOT NULL,
  `role` int(11) NOT NULL,
  `hash` varchar(32) COLLATE utf8_unicode_ci NOT NULL,
  `lastlogin` timestamp NULL DEFAULT NULL,
  `updated` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`),
  UNIQUE KEY `email` (`email`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci ;



■ Authライブラリ作成
Codeigniterでは有名(?)なDX Authなどのライブラリの使用も考慮しましたが、結局どれを使っても用途に合わせてカスタマイズしないといけないので自作します。
△要件△
- メールアドレスとパスワードで認証。ユーザ名は別途考慮。
- パスワード暗号化
- UserとCustomerの別認証

/extension/libraries/Auth.php
<?php
class Auth
{
    var $_error;

    public function __construct()
    {
        $this->ci =& get_instance();
    }
        
    function error()
    {
        return $this->_error;
    }
    
    function login($email, $passwd, $target='customer')
    {
        if($target === 'user')
        {   // load user model
            $this->ci->load->model('users_model','usersdb');
            // check if exists
            if($user = $this->ci->usersdb->exist($email))
            {   // retrieve user hash & matching up with entered password
                if($this->_encode($passwd, $user->hash) === $user->password)
                {   // update last login
                    $this->ci->usersdb->lastlogin($user->id);
                    // set admin session
                    $this->ci->session->set_userdata('admin',TRUE);
                    
                    return TRUE;
                }
                else $this->_error = _l('error_wrong_combination');
            }
            else $this->_error = _l('error_not_exist');
        }
        
        return FALSE;
    }
    
    private function _encode($passwd, $hash)
    {
        /* 暗号化スクリプト */
        
        return $passwd;
    }
}

/extension/models/users_model.php
<?php
class Users_model extends Model
{
    var $table = 'users';
    
    function __construct()
    {
        parent::__construct();
    }
    
    function exist($email)
    {
        $q = $this->db->get_where($this->table, array('email'=>$email));
        return ($q->num_rows() == 1) ? $q->row() : FALSE;
    }
    
    function lastlogin($id)
    {
        $this->db->where('id',$id);
        $this->db->update($this->table, array('lastlogin'=>date('Y-m-d H:i:s')));
    }
}



パスワードはユーザごとにハッシュを作成し、一定の法則で入力パスワードとマッチングさせてます。
法則は_encodeメソッド内に好きなように指定してください。
ユーザごとのハッシュは登録時に作成しないといけないので、それは次回に。

とりあえずのところ認証ライブラリ(Auth)はできたので、テストユーザを直接DBに作ってテストしてみます。

DBにテストユーザ追加
INSERT INTO `users` (`id`, `email`, `password`, `firstname`, `lastname`, `status`, `role`, `hash`, `lastlogin`, `updated`) VALUES
(1, 'test@test.com', '723e66f900dcb555d089050c80455331feb2b7ca', 'firstname', 'lastname', 0, 0, '5898e88516d636dbd3571c7d24550f67', '2011-08-04 10:49:04', '2011-08-04 10:49:04');


■ autoload変更
認証でデータベース、およびセッションを使うようになるのでconfig/autoload.phpを以下のように変更します。
$autoload['libraries'] = array('Auth','database','Form_validation','Session');


■ コントローラ
admin/application/controllers/login.php
<?php
class Login extends Controller
{
    function __construct()
    {
        parent::__construct();
        if(_s('admin')) redirect();
    }
    
    function index()
    {
        $this->form_validation->set_rules('email',_l('EMAIL'),'required|trim|valid_email');
        $this->form_validation->set_rules('password', _l('PASSWORD'), 'required|trim');
        if($this->form_validation->run())
        {
            $login = $this->auth->login($this->input->post('email'), $this->input->post('password'), 'user');
            if($login)  redirect();
            else $data['error'] = $this->auth->error();
        }
        else $data['error'] = validation_errors();
        
        $data['css'] = array('login');
        $data['page_title'] = _l('CONTROLPANEL');
        $this->layout->view('login', $data);
    }
}


■ ビュー
admin/application/view/login.php
<?php echo form_open(uri_string()); ?>
<div>
<h1><?php echo _l('CONTROLPANEL'); ?></h1>
<p><?php echo _l('MSG_LOGIN'); ?></p>
<dl>
    <dt><?php echo _l('EMAIL'); ?></dt>
    <dd><input type="email" name="email" value="<?php echo set_value('email'); ?>" /></dd>
    <dt><?php echo _l('PASSWORD'); ?></dt>
    <dd><input type="password" name="password" value="" /></dd>
    <dd><input type="submit" value="<?php echo _l('LOGIN'); ?>"></dd>
    <?php if(isset($error)): ?><dd><?php echo $error; ?></dd><?php endif; ?>
</dl>
</div>
<?php echo form_close(); ?>

これで準備は完了です。


■ログイン画面
どうせだったらと簡単にデザインしてみました。デザインは苦手なんですよねー(^_^;;



上で追加したユーザでログインしてみます。


うん、ちゃんと admin セッションが登録されていますね。
ログインした時に登録するべきセッションは admin だけではないですが、それは必要に応じて追加して行きたいと思います。


次回はユーザ登録をやります。

2011年7月28日

Codeigniterを使ってショッピングカートをゼロから作ってみよう。 # 3

テンプレート化の下地ができたので、調子に乗ってそのままバックエンドの分離に着手します。
テンプレート化はこちら


■フロントエンドとバックエンド(管理画面)の分離


一般的にフロントエンドとバックエンドはデザインが異なることが多いですし、機能的にも違ったものになります。そう考えると分離させるのはそれほど悪い考えでもないでしょう(であって欲しいw)

/admin/index.php は ./index.php をほぼコピーした感じです。

/admin/index.php
<?php
define('EXT', '.php');
define('FCPATH', __FILE__);
$pathinfo = pathinfo(FCPATH);
define('SELF', $pathinfo['basename']);
define('ROOT',realpath($pathinfo['dirname'].'/../').'/');
unset($pathinfo);

define('SYSPATH', ROOT.'system/');
define('EXTPATH', ROOT.'extension/');
define('APPPATH', ROOT.'admin/application/');

$f=pathinfo(__FILE__, PATHINFO_BASENAME);
if (!is_dir(SYSPATH))  exit("Your system folder path does not appear to be set correctly. Please open the following file and correct this: ".$f);
if (!is_dir(APPPATH))   exit("Your application folder path does not appear to be set correctly. Please open the following file and correct this: ".$f);
if (!is_dir(EXTPATH)) exit("Your extension folder path does not appear to be set correctly. Please open the following file and correct this: ".$f);

define('ENVIRONMENT', 'development');

if (defined('ENVIRONMENT'))
{
    switch (ENVIRONMENT)
    {
        case 'development':
            error_reporting(E_ALL);
        break;
    
        case 'testing':
        case 'production':
            error_reporting(0);
        break;

        default:
            exit('The application environment is not set correctly.');
    }
}

require(SYSPATH.'core/Bootstrap'.EXT);


ここで問題になってしまったのがLayoutライブラリです。
./index.phpでTEMPATHを設定していたため$this->layout->view()が全てTEMPATHに向いてしまっていました。

そこで両方のindex.phpにADMIN定数を設定し、ADMIN=TRUEの場合にはTEMPATHに向かないように/extension/core/Layout.phpを変更しました。
(毎回コントローラで$this->layout->set('admin');とやるのは無駄ですからね…)

./indexphp
define('ENVIRONMENT', 'development')直前

define('ADMIN', FALSE);

/admin/indexphp
define('ENVIRONMENT', 'development')直前

define('ADMIN', TRUE);

/extension/core/Layout.php
18行目

if(! ADMIN) $load->set_view_path(TEMPATH.$template.'/');


■ コントローラの設定
admin/application/controllers/home.php
<?php
class Home extends Controller
{
    function index()
    {
        $this->layout->view('home');
    }
}


■ ビューの設定
admin/application/views/home.php
this is admin directory - <?php echo __FILE__; ?>


■ レイアウトの設定
admin/application/views/_layout/main.php
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>Admin Template</title>
</head>
<body>

<?php echo $contents; ?>

<p><br />Page rendered in {elapsed_time} seconds</p>

</body>
</html>


■ てすと
http://localhost/lsc/admin/ にアクセスしてみます。


ちゃんとアクセスできてます。大丈夫そうです。
無事に分けられたところで、次はアクセス制御かな?

2011年7月25日

Codeigniterを使ってショッピングカートをゼロから作ってみよう。 # 2

さてインストールが終わったので目的に合わせて色々と変更していきます。
#1 インストールはこちらからどうぞ。



■ テンプレート化
デザインを拡張したり、変更したりできる機能は人に使ってもらうことを考えると外せないですよね。
もちろん、簡単に拡張できれば使ってくれる人も多くなるでしょうし。


そこで初期設定では application/views に設定されているview用のディレクトリを templates ディレクトリに移します。HTML/CSSなどのデザイン部分は1つにまとめられて楽になるんじゃないかな。(ダメそうなら後で変更しますw)



後で変更できるようにindex.phpにTEMPATHを追加。

define('TEMPATH', ROOT.'templates/');


■ Layoutライブラリ
当然templatesディレクトリに移しただけでは使えないので、ライブラリを1つ追加します。

extension/core/Layout.php
<?php
class Layout 
{
    var $layout;
    
    function __construct()
    {
        $this->layout = config_item('layout_default_file');
        log_message('debug', 'Layout Class Initialized');
    }
    
    function set($layout) { $this->layout = $layout; }
    
    function view($view = '' , $data = array(), $template = 'default', $return = FALSE)
    {
        $load =& load_class('Loader','core');
        // set template path as view path if not admin
        if($template !== 'admin') $load->set_view_path(TEMPATH.$template.'/');
        // load contetns in side of the layout
        $view_data['contents'] = $load->view($view, $data, TRUE);
        // load layout directory config
        $this->layout = config_item('layout_directory').$this->layout;

        // then finaly load layout
        return $load->view($this->layout, $view_data, $return);
    }
}


ライブラリ内で使われている設定をconfig/config.phpに2つ追加。
$config['layout_default_file']  = 'main';
$config['layout_directory']     = '_layouts/';
1つ目はLayoutライブラリがロードされた時にレイアウトファイルが指定されなかった場合に自動的に読み込まれるファイル名を指定します。
2つ目はディレクトリを分けたい際に指定できます。空欄も可。


■ Loaderクラス拡張
ビューファイルのパスを指定するのにLoaderクラスを拡張します。

extension/core/MY_Loader.php
<?php
class MY_Loader extends Loader
{
    /**
     * set view file path
     *
     * This function sets the location of view file.
     *
     * @access    public
     */
    public function set_view_path($path, $absolute=FALSE)
    {
        $this->_ci_view_path = ($absolute) ? ROOT.$path : $path;
    }
}
これで_ci_view_pathはtemplatesディレクトリに向きます。


■ Layoutライブラリ読み込み
最後にライブラリを読み込みます。
普通にconfig/autoload.phpに追加でもいいんですが、Layoutライブラリは常に使うことになるし、1行だけなのでsystem/core/Controller.phpに書き込んじゃいました。

$this->layout =& load_class('Layout', 'core');

Codeigniterのアップデートの時に面倒とか、わからない人はconfig/autoload.phpに追加してくださいね。

$autoload['libraries'] = array('Layout');



■ てすと

コントローラ:application/controllers/home.php
<?php
class Home extends Controller
{
    function __construct()
    {
        parent::__construct();
    }
    
    function index()
    {
        $this->layout->view('home/index');
    }
}

ビュー:templates/default/home/index.php
<?php echo __FILE__; ?>


結果:


大丈夫そうです(^_^v
これでテンプレート化の下地ができまた。

2011年7月24日

Codeigniterを使ってショッピングカートをゼロから作ってみよう。 # 1

■ 環境設定&インストール

本来なら開発は本番環境と同じ状態でやるのが一番良いのですが、ネットがない環境でも作業ができるようにローカルに開発環境をセットアップします。

まずWampをダウンロードしてDドライブにインストール。インストールする場所はご自由に。
www.wampserver.com

D:\wamp\www
がlocalhost(以下、ローカル)になります。


次にCodeigniterをダウンロード。
www.codeigniter.com/downloads

ダウンロードしたファイルを解凍してローカル配下に設置。
同梱されているuser_guideは開発自体には必要ないので別の場所に保管します。

開発ディレクトリ:
D:\wamp\www\lsc

マニュアルディレクトリ:
D:\wamp\www\manual\ci


とりあえずは、これで環境設定とインストールできました。


■ 微調整

初期設定でCodeigniterはsystemとapplicationの2つのディレクトリに別れてます。
これを少しだけ以下のように変更しました。


変更の理由は後日記載します。

それに伴い、index.phpも多少変更。

<?php
/*
 *  Constants: Core Application Constants
 *  EXT - The file extension.  Typically ".php"
 *  FCPATH - The full server path to THIS file
 *  SELF - The name of THIS file (typically "index.php")
 *  ROOT - ROOT direcotry
 *  SYSPATH - The full server path to the "system" folder
 *  APPPATH         - The full server path to the "application" folder
 *  EXTPATH- The full server path to the "extension" folder
 */

define('EXT', '.php');
define('FCPATH', __FILE__);
$pathinfo = pathinfo(FCPATH);
define('SELF', $pathinfo['basename']);
define('ROOT',realpath($pathinfo['dirname'].'/').'/');
unset($pathinfo);
define('SYSPATH', ROOT.'system/');
define('EXTPATH', ROOT.'extension/');
define('APPPATH', ROOT.'application/');

$f=pathinfo(__FILE__, PATHINFO_BASENAME);
if (!is_dir(SYSPATH)) exit("Your system folder path does not appear to be set correctly. Please open the following file and correct this: ".$f);
if (!is_dir(APPPATH)) exit("Your application folder path does not appear to be set correctly. Please open the following file and correct this: ".$f);
if (!is_dir(EXTPATH)) exit("Your extension folder path does not appear to be set correctly. Please open the following file and correct this: ".$f);

define('ENVIRONMENT', 'development');

if (defined('ENVIRONMENT'))
{
    switch (ENVIRONMENT)
    {
        case 'development':
            error_reporting(E_ALL);
        break;
   
        case 'testing':
        case 'production':
            error_reporting(0);
        break;

        default:
            exit('The application environment is not set correctly.');
    }
}

require(SYSPATH.'core/Bootstrap'.EXT);


よく見たらほとんど全部変えてた(笑)
わからない人は触らないほうがいいかもしれませんねー。


変更がちゃんと動いてるかhttp://localhost/lsc/にアクセスして確認。




大丈夫そう。
それじゃあ次回からガリガリ開発です!

2011年7月22日

Codeigniterを使ってショッピングカートをゼロから作ってみよう。 # 0

仕事柄毎日コード書いてるけど、色々と思うこともあるので日記風に書き残しておこうかと思います。

とは言えだ、ただの日記じゃ芸がないし自分が飽きそうなので企画っぽくしようかと。
Google先生に聞いてみたけど見当たらなかったのと慣れていることもあるので企画内容決定。


Codeigniterを使ってショッピングカートをゼロから作ってみよう。


それじゃ企画の概要。
- CodeigniterとjQueryをメインにiscなみのショッピングカートを作る。
- 原則としてコードは恥も外聞もなく公開。まぁでも徹底入門よりはマシだと思います、はいw
- 既に企画内容が途方もなく大きいので、いつ終わるかは不明。
- 途中で投げ出すこともあるでしょう。・・・っつーか、投げ出す気満々なんであまり期待しないでください(苦)
- 投げ出さずにできたら商用化。(あくまでも予定)

以下、仕様。
コア部分:
- カート機能
- ユーザ機能
- 管理ページ
- 製品管理系

準コア部分:
- 決済系(Paypalとか色々)
- 税金系
- 配送系
- 在庫管理系
- 返品受付機能

デザイン部分:
- テンプレート(スキン)機能

余力があれば:
- B2B機能
- SEO系
- プロモーション機能
- API


6ヶ月~1年くらいあればある程度まともなのできるかな?
機能はこのブログを読んでくれる人がいて、要望出してくれたりアドバイスくれたりしたら追加されるかもしれません。

投げ出す気は満々ですが、投げ出さないように励ましつつ見守ってくれれば幸いです。

んじゃ、始めますか。