2012年10月26日金曜日

cakephp2 インターネット上の画像をサーバに保存する

実は、cakephpで、curlを使ってみたかっただけですが

cakephpネタでは、ないですが、インターネット上の画像をサーバに保存したい。
ということがあり、作って見ました。
本当は、wget関数とかがほしいですね
(ポイント)
・インターネット上の画像のURLは、$http_image
・サーバ上の画像のファイルを$local_imageで指定します。
・保存ディレクトリの名前に注意して、wb(ライト・バイナリ)モードで、オープンし、
・画像を読み込み、書き出す、だけです。

2012年10月25日木曜日

cakephp2 hybridauth(2)

hybridauth概要 その2/2です。

Hybrid_User_Profile Name type description
  identifier String  
Properties profileURL String IDPのWebサイト上でプロフィールページへのURLリンク
  webSiteURL String  
  photoURL String ユーザー写真やアバターへのURLリンク
  displayName String  
  description String 短いabout_me
  firstName String  
  lastName String  
  gender String  
  language String  
  age Integer  
  birthDay Integer  
  birthMonth Integer  
  birthYear Integer  
  email String  
  emailVerified String  
  phone String  
  address String  
  country String  
  region String  
  city String  
  zip Integer  
Update User Status      $hybridauth = new Hybrid_Auth( $config );
$adapter = $hybridauth->authenticate( "Facebook" );
$adapter->setUserStatus(
    array(
       "message" => "", // status or message content
       "link" => "", // webpage link
       "picture" => "", // a picture link
       )
    ); 
      $hybridauth = new Hybrid_Auth( $config );
$adapter = $hybridauth->authenticate( "Twitter" );
$adapter->setUserStatus( "Hi there!" ); 
Hybrid_User_Contact $hybridauth = new Hybrid_Auth( $config );
$adapter = $hybridauth->authenticate( "Twitter" );
$user_contacts = $adapter->getUserContacts();
foreach( $user_contacts as $contact ){
     echo $contact->displayName . " " . $contact->profileURL . "<hr />";
}
  Field Name Type Short description
  identifier  String The Unique contact's ID on the connected provider. Usually an interger.
  profileURL  String URL link to profile page on the IDp web site
  webSiteURL  String ユーザのウェブサイト、ブログ、ウェブページ
  photoURL  String ユーザー写真やアバターへのURLリンク
  displayName  String User dispalyName provided by the IDp or a concatenation of first and last name.
  description  String 短いabout_meまたは最後の接触状況
  email  String User email. Not all of IDp garant access to the user email
Hybrid_User_Activity $hybridauth = new Hybrid_Auth( $config );
$adapter = $hybridauth->authenticate( "Twitter" );
$user_timeline = $adapter->getUserActivity( "timeline" );
foreach( $user_timeline as $item ){
    echo $item->user->displayName . ": " . $item->text . "<hr />";
}

$user_timeline = $adapter->getUserActivity( "me" );
foreach( $user_timeline as $item ){
    echo $item->user->displayName . ": " . $item->text . "<hr />";
}
  Field Name Type Short description
  id  String Event id on the provider side
  date  String Event date of creation. provided as is for now.
  text  String activity/event/story content as string.
  user  stdClass Field Name    Type    Short description
------------------------------------------------------
identifier        string   The Unique user ID on the provider side. Usually an interger.
displayName string   User dispalyName provided by the provider
profileURL     string   URL link to profile page on the IDp web site
photoURL      string   URL link to user photo or avatar
Access social networks apis     try{
    $hybridauth = new Hybrid_Auth( $config );
    $facebook = $hybridauth->authenticate( "Facebook" );
    $twitter = $hybridauth->authenticate( "Twitter" );

    /* Facebook: https://developers.facebook.com/docs/reference/api/  */
    $response = $facebook->api()->api('/me/friends');
    $response = $facebook->api()->api("/me/feed", "post", array(
        message => "Hi there",
        picture => "http://www.mywebsite.com/path/to/an/image.jpg",
        link => "http://www.mywebsite.com/path/to/a/page/",
        name => "My page name",
       caption => "And caption"
       ));

     /* Twitter: https://dev.twitter.com/docs/api */
    $response = $twitter->api()->get( 'account/totals.json' );
   }
catch( Exception $e ){
    echo "Ooophs, we got an error: " . $e->getMessage();
}
HybridAuth Sessions         CREATE TABLE `users_connections` (
    `user_id` int(11) NOT NULL COMMENT 'refer to your user id on your application',
    `hybridauth_session` text NOT NULL COMMENT 'will contain the hybridauth session data',
    `updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
    ) ENGINE=InnoDB;
      try{
$hybridauth = new Hybrid_Auth( $config );
$twitter = $hybridauth->authenticate( "Twitter" );
$facebook = $hybridauth->authenticate( "Facebook" );
$google = $hybridauth->authenticate( "Google" );
/* ... */

$hybridauth_session_data = $hybridauth->getSessionData();
 
// then store it on your database or something
sotre_hybridauth_session( $current_user_id, $hybridauth_session_data );
}
catch( Exception $e ){
    echo "Ooophs, we got an error: " . $e->getMessage();
}
 
// define a function to sotre it on whatever storage you want to use
function sotre_hybridauth_session( $user_id, $data ){
    $sql = "INSERT INTO users_connections ( user_id, hybridauth_session ) VALUES (  $user_id , $data )";
// ..
}
      try{
    $hybridauth = new Hybrid_Auth( $config );

    $hybridauth_session_data = get_sotred_hybridauth_session( $current_user_id );
    $hybridauth->restoreSessionData( $hybridauth_session_data );

   $twitter = $hybridauth->getAdapter( "Twitter" );

  $user_profile = $twitter->getUserProfile();
 
// ..
}
catch( Exception $e ){
   echo "Ooophs, we got an error: " . $e->getMessage();
}
 
// define a function to get the stored hybridauth data back from your storage system
function get_sotred_hybridauth_session( $user_id ){
    $sql = "SELECT FROM users_connections WHERE user_id = $user_id ";
    return ...
}

cakephp2 hybridauth(1)

hybridauthの概要 その1/2です。

Methods   Usage
Hybrid_Auth authenticate() Hybrid_Auth::authenticate( provider, params  ) 
     
  getAdapter() Hybrid_Auth :: isConnectedWith( provider )
  isConnectedWith() Hybrid_Auth :: isConnectedWith( provider )
    現在のユーザーが指定に接続されている場合はtrueまたはfalseを返す
  getConnectedProviders() Hybrid_Auth :: getConnectedProviders()
    認証プロバイダのリストを返します。
  getSessionData() Hybrid_Auth :: getSessionData()
    データが格納されたセッションを取得します。シリアライズ返す
  restoreSessionData() Hybrid_Auth :: restoreSessionData( array )
    与えられた[シリアライズ]からHybridAuthセッションをリストアする
  logoutAllProviders() Hybrid_Auth :: logoutAllProviders()
    一度に接続されているすべてのプロバイダをログアウトする汎用関数。
  getCurrentUrl() Hybrid_Auth :: getCurrentUrl()
    効用関数は、要求Webページの現在のURLを返す。
Hybrid_Provider_Adapter  各認証プロバイダのためにそれのインスタンスを作成 $twitter_adapter = $hybridauth->authenticate( "Twitter" );
$twitter_user_profile = $twitter_adapter->getUserProfile();
$twitter_adapter->logout(); 
  isUserConnected() Hybrid_Provider_Adapter ::(isUserConnected)
  認証されている場合にtrueを返します  
  getUserProfile() Hybrid_Provider_Adapter :: getUserProfile()
  setUserStatus() Hybrid_Provider_Adapter :: setUserStatus($ status)
  ソーシャルネットワーク上の彼のwallへの
ユーザー·ステータスまたはポストを更新
ソーシャルサービスに送信するユーザのステータス
  getUserContacts() Hybrid_Provider_Adapter :: getUserContacts()
  接続ユーザーの連絡先リストを提供  
  getUserActivity() Hybrid_Provider_Adapter::getUserContacts( $stream )
  彼の友人のアクティビティストリームを提供 ユーザのアクティビティをロードするため
  logout() Hybrid_Provider_Adapter::logout()
  getAccessToken() Hybrid_Provider_Adapter::getAccessToken()
    access.tokenプロバイダがOAuthプロトコルを使用している場合
  API() Hybrid_Provider_Adapter::api()

cakephp2.2.3 hybridautu + tmhOAuth レイアウト twitter用

cakephpでtwitterをやるには、hybridauthだけで、OKそうなんですが、
画像付きの投稿が出来ないので、その部分は、tmhOAthでやります。
「手順」
1.ダウンロード、配置
2.Twitterのアプリを作成
3.アクションを作成し、実行(試す)

cakephp2.2.3 + Hybridauth + tmhOAth のレイアウトです。
それぞれをダウンロードして、「だた」下記のように配置(コピー)してください。
コピーするだけでOKなので、解りやすいですね。

「ダウンロード」
(1)cakephp2.2.3をダウンロード
(2)Hybridauthのcakephp用をダウンロード
(3)tmhOAthの最新版をダウンロード
「配置」
(1)cakephpのwebrootにhybridauthをホルダーごとコピー
(2)cakephpのwebrootにtmhOAthをホルダーごとコピー

「ツイッターのdeveloper」にいって、アプリケーション作成し、登録する。
・ここは、他の解説?を見て下さい

「アクション作成」
(ポイント)
・require_onceは、下記の例のままでOK
・base_urlは、例のままでOK
・Twitterのkeyとsecretに、作成したアプリケーションのkeyとsecretを書き込む
・tmhOAth用に、consumer_keyとconsumer_secretのテーブルに作成したアプリのkeyとsecretを書き込む
・表示するイメージを./img/images/とかに準備しておく



(Hybridauthのcallbackの解説)
・$twitter = $hybridauth->authenticate('Twitter'); とするだけで、
 webroot/hybridauth/index.phpを実行、認証して、次の行に戻ってきます。

認証済みの場合は、素通りします。
めちゃ便利ですよね。

2012年10月21日日曜日

cakephp2.3 find conditions and条件、or条件

忘れてしまうので、メモ。

  $conditions = array(
  'or' => array(
    'or' => array(
     array("Schedule.from BETWEEN ? AND ?" => array($from, $to)),
     array("Schedule.to BETWEEN ? AND ?" => array($from, $to))
     ),
    'and' => array(
     array("Schedule.from >=" => $from),
     array("Schedule.from <=" => $to),
     array("Schedule.to     >=" => $to)
     ),
    'and' => array(
     array("Schedule.from <=" => $from),
     array("Schedule.to     <=" => $to),
     array("Schedule.to  >=" => $from)
     ),
    'and' => array(
     array("Schedule.from <=" => $from),
     array("Schedule.to     >=" => $to)
     )
    ),
  'and' => array(
    'SchedulesUser.user_id' => $user_id
     )
   );

2012年10月6日土曜日

windowsにvirtualboxでMacOSを動かす

とりあえず、動いたので、画面を紹介します。
使い方はまた、後日、メモします。

2012年9月28日金曜日

cakephp2.2 create read save delete

(基本)レコード処理 create read save delete
cakephp1.3と特に変更はないですね
・(edit)アップデートの場合
(1)idにレコード番号をセットして
(2)create
(3)read レコード番号$idのフィールド'status'を読んで、・・・なにか処理があって
      レコードの全部のフィールドを読むときは、nullをセットする $this->Report->read(null, $id); 
(4)save セーブデータをarrayで渡してあげればOK return が falseの場合は、エラー処理してください
・(add)新規レコード作成の場合は、idをセットせずに、saveすればレコードが作成されます
・(delete) 対象のレコード番号をセットしてdeleteするだけです



2012年9月18日火曜日

cakephp2.2 + Twitter Bootstrap PopOver 小さなアイコン付きのPopOverのボタン

小さなアイコン付きのPopOverのボタン



$dataOriginalTitle = 'popoverのタイトル文字列です';
$dataDisplay = '<i class="icon-info-sign icon-white"></i> 情報';
$dataTrigger = 'hover';
$dataContent = '表示するコンテンツの内容です';

echo $this->Html->link($dataDisplay, array('action'=> 'edit', $id), 
              array('class' => 'btn btn-primary btn-mini', 
                      'rel' => 'popover', 
                      'data-trigger' =>$dataTrigger, 
                      'data-content' => $dataContent, 
                      'data-original-title' => $dataOriginalTitle, 
                      'escape' =>false
                       ));

$dataDisplayにアイコンの情報をセットしています。
'escape' => false とするのがみそです。

$data-triggerは、hover, toggleとかあります。

本当は、hoverで、popoverを表示して、
ボタンクリックで、~/edit/$idに分岐する機能が欲しかったのですが、

この機能は、改造のお楽しみになりそうです。

2012年9月9日日曜日

cakephp2.2 スマフォサイトを作ろう! cakephp2.2 + jQuery mobile 1.1.1

cakephp2.2 スマフォサイトを作ろう! cakephp2.2 + jQuery mobile 1.1.1

cakephp2.2.2とjQuery mobileをダウンロードして、配置するだけ
入り口は、とっても簡単なので、やってみよう

cakephp2.1のダウンロードと設定
http://cakephp.jp/ 下記の画面のDownloadから、ダウンロードする

(apache)
・/var/www/ 配下に展開して配置。

(windowsのxampp)
・htdocsに配置。


次は、cakephpに レイアウトファイル、コントローラ、ビューを作成する。は、こちら



cakephp2.2 jQuery mobile layout レイアウトファイル

cakephp2.2 + jQuery mobile layout
例えば、レイアウトファイル名を「mobile.ctp」として app/View/Layouts/mobile.ctp に配置する
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="">
<meta name="author" content="Toshio Nakashima">
<title><?php echo $title_for_layout; ?></title>
<?php echo $this->Html->meta('favicon.ico', $this->Html->url('/icons/favicon.ico'), array('type' => 'icon'));  ?>

<link rel="stylesheet" href="http://code.jquery.com/mobile/1.1.1/jquery.mobile-1.1.1.min.css" />
<script src="http://code.jquery.com/jquery-1.7.1.min.js"></script>
<script src="http://code.jquery.com/mobile/1.1.1/jquery.mobile-1.1.1.min.js"></script>
</head>

<body lang="ja">

<?php echo $this->Session->flash(); ?>
<?php echo $this->fetch('content');  ?>

</body>
</html>
コントローラ
デモソフトのdemo1とdemo2のコントローラでの記述です。
(何もありませんが)
controller
  public function demo1($id=null) {
   $this->layout = 'mobile';
   $this->set('title_for_layout', 'モバイルdemo1');
  }
  public function demo2($id=null) {
   $this->layout = 'mobile';
   $this->set('title_for_layout', 'モバイルdemo2');
  }

demo1 基本


demo1画面 その1
ソフトの配置等が合っているか、表示してみましょう
<div data-role="page" id="home">
 <div data-role="header" id="header">
  <h1>ソーシャルウェア</h1>
 </div>
 <div data-role="content">
<!-- ------------------------------------------------------    -->
モバイルのページです。<br/>
PCで作った表をそのまま表示しています<br/>
<br/>
<table class="gray">
<tbody>
<tr>
 <th>テーマを選ぶ</th>
 <th>ヘッダー</th>
 <th>フッター</th>
</tr>
<tr>
 <td>テーマ a,b,c,d,</td>
 <td>タイトル表示</td>
 <td>Facebook、Twitte</td>
</tr>
</tbody>
</table>

<!-- ------------------------------------------------------    -->
 </div><!-- id=content -->
 <div data-role="footer" id="footer">
  <h4>Copyright 2012 SoftwareFactoryTokyo inc.</h4>
 </div>
</div><!-- id=home -->

demo2 基本 その2


demo2画面
基本的な部品を配置してみましょう

demo2
<div data-role="page" id="home">
 <div data-role="header" id="header" data-theme="b">
  <h1>ソーシャルウェア</h1>
  <a href="#" data-icon="home" class="ui-btn-left">ホーム</a>
  <a href="#" data-icon="gear" class="ui-btn-right">オプション</a>
 </div>
 <div data-role="content"  data-theme="c">
<!-- ------------------------------------------------------    -->
<div data-role="navbar">
 <ul>
  <li><?php echo $this->Html->link(
      __('Nav-bar デモ1', true), 
      array('controller' =>'menus','action' => 'demo1', ''),
      array('data-transition'=>'')); ?>
  </li>
  <li><?php echo $this->Html->link(
      __('デモ2', true), 
      array('controller' => 'menus','action' => 'demo2', ''),
      array('data-transition' => '') ); ?>
  </li>
  <li><?php echo $this->Html->link(
      __('デモ3', true), 
      array('controller' => 'menus','action' => 'demo3', ''),
      array('data-transition' => '') ); ?></li>
 </ul>
</div>
<br/>
<table class="blue">
<tbody>
<tr><th>テーマの色を選ぶ</th><th>ヘッダー</th><th>フッター</th></tr>
<tr><td>色、表題、ナビゲーション</td><td>Facebook、Twitte</td><td>選択画面を作る</td></tr>
</tbody>
</table>
<br/><br/>
<ul data-role="listview">
 <li><?php echo $this->Html->link('リスト表示 デモ1', array('action' => 'demo1')); ?></li>
 <li><?php echo $this->Html->link('デモ2', array('action' => 'demo1')); ?></li>
 <li><a href="#">イベントリスト</a></li>
 <li><a href="#">チェックインリスト</a></li>
</ul>
<br/>

<!-- ------------------------------------------------------    -->
 </div><!-- id=content -->
 <div data-role="footer" id="footer" data-theme="b" class="ui-bar" data-position="fixed">
 <a href="#" data-role="button" data-icon="star" data-iconpos="left">Twitter</a>
 <a href="#" data-icon="star" data-iconpos="left">Facebook</a>
 <a href="#" data-icon="info" data-iconpos="left">SoftwareFactoryTokyo inc.</a>
 </div>
</div><!-- id=home -->

2012年9月8日土曜日

cakephp2.2 input datetime time => jQuery datetimePicker、timePickerを使う

input datetime と input time

・本当は、 HTML5基本として
$this->Html->input('fromTime', array('type' => 'datetime', 'value' => ・・・としたい (^_^;)
・$year、$month、$day、$second、$minute・・・の変数を準備して処理する→煩雑、バグの元?
・なんか、表示とか、いろいろ、イマイチ orz

そこで、
jQueryのdatetimepickerを使おう!
マニュアル、使い方は、こちら
(利点)
1)希望通りのフォーマットで入力される(はず)
2)Unixスタイルのフォーマットで統一したい が、実現できる
3)date、datetime、timeは、「Unixのdatetime型」で処理が便利(ワンパターンでコーディングできるので)

jQueryのcakephp2.2.2への配置は、こちらを参照してください

input datetime => jQueryのdatetimePickerを使う
datetimepicker (ビュー内にて)

<script type="text/javascript">
$(function() {
$('#ScheduleFrom').datetimepicker({
  showAnim: 'slideDown',
  timeFormat: 'hh:mm',
  stepHour: 1,
  stepMinute: 10,
  showSecond: false
  });
 });
</script>
Form->input('from', array('type' => 'text', 'label' => false, 'class' => 'span4')); ?>

input time => jQuery datetimepickerを使う
timepicker (ビュー内にて)

<script type="text/javascript">
$(function() {
$('#ReportBeginTime').timepicker({
  timeFormat: 'hh:mm',
  stepHour: 1,
  stepMinute: 10,
  showSecond: false
  });
 });
</script>
Form->input('begin_time', array('type' => 'text', 'label' =>false)); ?>

2012年9月7日金曜日

cakephp2.2.2 faviconが表示されない?

cakephp2.2.2 faviconが表示されない??

cakephp2.xのマニュアルは、下記だが、そうすると、URLを間違える?

echo $this->Html->meta('favicon.ico','/icons/favicon.ico',array('type' => 'icon'));

こうしました
echo $this->Html->meta('favicon.ico', $this->Html->url('/icons/favicon.ico'), array('type' => 'icon'));
表示されたよ(^^)♪

2012年9月5日水曜日

cakephp2.2 Auth認証 と usersテーブル、その1

Auth認証 と usersテーブル と モデル/コントローラ/ビュー

cakephpの認証機能は、とてもわかりやすいので、いいですね。
usersテーブルは、ログインしたユーザのデータを格納する大切なテーブルですね。

usersテーブルとM/C/Vを作成しながら、Auth(認証の設定)を進めます。

Sessionをdatabaseで管理する設定はこちら
(1)cake_sessionsテーブルが作成済みである
(2)core.phpで、Sessionをdatabaseで行う設定済みである。
(上記、2つなくても、Authは動きます)

作業手順
1)Sessionはデータベースで管理
  1.core.php に databaseで管理する設定をする 
  2.cake_sessionsテーブルを作成
2)usersテーブルを作成する
  1.userテーブルを作成
  2.roleを検討
3)bakeで UserモデルとUsersコントローラ、ビューを作成する
4)Usersコントローラの修正
5)indexファンクションとindex.ctp(ビュー)の修正
6)editファンクションとedit.ctp(ビュー)の修正
7)addファンクションとadd.ctp(ビュー)の修正
(1)usersテーブルの作成
CREATE TABLE IF NOT EXISTS `users` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `username` varchar(128) NOT NULL,
  `password` varchar(255) NOT NULL,
  `role` varchar(20) DEFAULT NULL,
  `status` int(11) DEFAULT '0',
  `name` varchar(24) DEFAULT NULL,
  `created` datetime DEFAULT NULL,
  `modified` datetime DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `username` (`username`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;

フィールド名説明
idint必須 Authに必須 auto-increment
usernamevarchar必須 Authに必須 e-mailアドレス
passwordvarchar必須 Authに必須
rolevarchar(オプション)admin, manager, userの役割で分ける
statusint(オプション)登録ステータス
namevarchar(オプション)氏名は漢字で欲しい
createddatetime(オプション)登録日時
modifieddatetime(オプション)変更日時

(1-1)スキーマファイルを作る。 bakeする(モデル、コントローラ、ビューを焼く)
(1)パスを通す
【windowsの場合】
webapp/app/Config/Console に 移動して

>set path=%path%;%cd%  (パスを Consoleに通し、bakeコマンドを使えるようにする)

webapp/app/に移動する

(2)スキーマファイルを作る
【windowsの場合】

>cake schema generate -f (次のメッセージでは、上書きの(o)を選択し、schemaファイルを作っておく

(3)bakeする

>cake bake で、 Model と Controller と View を 作ってください。

(1-2)認証とセッションは、どこでも使うので、AppControllerに登録しておきます。
class AppController extends Controller {
 var $components = array('Session','Auth');
 var $helpers=array('Session');
}

(2)Userモデル bakeしたままで、OKです

(3-1)Usersコントローラ (上の部分)
<?php
App::uses('AppController', 'Controller');

class UsersController extends AppController {
    var $layout = 'demo';
    public $uses = array('User', 'Auth', 'Session');
    public $components = Array(
            'Session',
            'Auth' => Array(
                'loginRedirect' => Array('controller'  => 'mypages', 'action' => 'index'),
                'logoutRedirect' => Array('controller' => 'users', 'action' => 'login'),
                'loginAction' => Array('controller' => 'users', 'action' => 'login')
 /*             'authenticate' => Array('Form' => Array('fields' => Array('username' => 'email')))  */
            )
        );


    public function beforeFilter() {

    parent::beforeFilter();
    $this->Auth->allow('login', 'logout', 'signup', 'add');

    $this->Auth->authError = 'ログインしてください';
    $this->Auth->loginError = 'メールアドレスかパスワードが違います';
  } 
(解説)
$layout    このコントローラ内のレイアウトを'demo'に設定。違うレイアウトを使う場合は、それそれの
       function内で再度、定義すればよい。
$uses     利用するモデルを列挙する。
$components     利用するコンポーネントを列挙する


(3-2)Usersコントローラ (login)
 function login() {
 $this->set('title_for_layout','ログイン');

        if($this->request->is('post')) {
            if($this->Auth->login()) {
             $loginuser = $this->Auth->user();
             $this->Session->write('LoginUser.Id', $loginuser['id']);
             $this->Session->write('LoginUser.UserName', $loginuser['username']);
             $this->Session->write('LoginUser.Name', $loginuser['name']);
             $this->Session->write('LoginUser.Role', $loginuser['role']);
             if ($loginuser['role'] == 'admin')  {
              $this->redirect(array('controller' => 'menus', 'action' => 'index'));
             } else {
              $this->redirect(array('controller' => 'favorites', 'action' => 'index'));
                }
            } else {
                $this->Session->setFlash(__('ユーザ名かパスワードが違います'));
            }
        }
    }
解説
・リクエストが、'post'じゃなかったら、そのまま、抜ける。
・リクエストが、'post'で、logoin認証がOKの時に
    Loginユーザのroleが 'admin'だったら、管理のページへリダイレクトして、
    Loginユーザのroleが 'その他’だったら、ユーザのページへリダイレクトする。
・リダイレクトの前に、セッションに、Loginユーザの情報を書き込んでおく。
(3-3)Usersコントローラ (logout)
 function logout() {
  $this->Session->write('LoginUser.Id', '');
  $this->Session->write('LoginUser.UserName', '');
  $this->Session->write('LoginUser.Name', '');
  $this->Session->write('LoginUser.Role', '');
  $this->redirect($this->Auth->logout());
 }

・セッション情報をクリアして、logoutする

(3-4)Usersコントローラ (index)
 function index() {
  $this->set('title_for_layout','ユーザ一覧');

  $this->User->recursive = 0;
  $this->set('users', $this->paginate());

  $allusers = new User;
  $allusers = $this->User->find('all',array(
   'conditions' => array('role <>' => 'admin'),
   'order' => array('User.id' => 'asc')
   ));
  $this->set('allusers', $allusers);
 }

・ロール(役割)がadminを表示したくない場合は、上記の$alluserのようなオブジェクトを作る

(3-5)Usersコントローラ (edit)
 public function edit($id = null) {
  $this->User->id = $id;
  if (!$this->User->exists()) {
   throw new NotFoundException(__('Invalid user'));
  }
  if ($this->request->is('post') || $this->request->is('put')) {
  $this->request->data['User']['password'] = AuthComponent::password($this->request->data['User']['password']);
   if ($this->User->save($this->request->data)) {
    $this->Session->setFlash(__('The user has been saved'));
    if($this->Session->read('LoginUser.Role' == 'admin')){
    $this->redirect(array('action' => 'edit'));
    } else if ($this->Session->read('LoginUser.Role' == 'user')){
     $this->redirect(array('action' =>'view'));
    }
   } else {
    $this->Session->setFlash(__('The user could not be saved. Please, try again.'));
   }
  } else {
   if($this->Session->read('LoginUser.Role') == 'user'){
    $id = $this->Session->read('LoginUser.Id');
    }
   $this->request->data = $this->User->read(null, $id);
  }
 }

・処理をロールがadmi userなどで分けたい場合は、上記のような処理をする
・自分の仕様に従って書き直してください

(3-6)Usersコントローラ (add)
 public function add() {
  $this->set('title_for_layout','ユーザ:新規登録');

  if ($this->request->is('post')) {
   $this->User->create();
   $this->request->data['User']['password'] = AuthComponent::password($this->request->data['User']['password']);
   if ($this->User->save($this->request->data)) {
    $this->Session->setFlash(__('次:ユーザ情報の登録・ログインしてください'));
    $this->redirect(array('controller' => 'users', 'action' => 'add'));
   } else {
    $this->Session->setFlash(__('The user could not be saved. Please, try again.'));
   }
  }

  $this->User->recursive = 0;
  $this->set('users', $this->paginate());

  $allusers = new User;
  $allusers = $this->User->find('all',array(
   'conditions' => array('role <>' => 'admin'),
   'order' => array('User.id' => 'asc')
   ));
  $this->set('allusers', $allusers);
 }

・パスワードの暗号化:$this->request->data['User']['password'] = AuthComponent::password($this->request->data['User']['password']); の部分が大事
・ユーザ新規登録は、「signUpファンクションを作る」など、自己のプログラムの仕様に従って、書き直してください。

(3-7)Usersコントローラ (view)
 public function view($id = null) {

  $this->User->id = $id;
  if (!$this->User->exists()) {
   throw new NotFoundException(__('Invalid user'));
  }
  $this->set('user', $this->User->read(null, $id));
 }

・ロールがuserの人は、自分のアカウントしか見られない、など、自己の仕様に従って、書き直してください。

(3-8)Usersコントローラ (delete)
 public function delete($id = null) {
  if (!$this->request->is('post')) {
   throw new MethodNotAllowedException();
  }
  $this->User->id = $id;
  if (!$this->User->exists()) {
   throw new NotFoundException(__('Invalid user'));
  }
  if ($this->User->delete()) {
   $this->Session->setFlash(__('User deleted'));
   $this->redirect(array('action' => 'index'));
  }
  $this->Session->setFlash(__('User was not deleted'));
  $this->redirect(array('action' => 'index'));
 }

・ロールがuserの人は、消去できるのは、自分のアカウントだけとか、消去できない、など、自己の仕様により、書き直してください。


cakephp2.2 $this->Form->create submit end

■フォームを始める(基本形)
$this->Form->create('モデル名');

■フォームを始める(詳細)
<?php
echo $this->Form->create('モデル名', array(
                   'type' => 'post', 
          'controller' => 'コントローラ名',
                    'action' => 'アクション名'
                     )
                   ); 
?>
■submitする
<?php echo $this->Form->submit('表示文字列', array()); ?>

■submitする(Twitter Bootstrap利用の場合)
<?php echo $this->Form->input('更新', array('type' => 'submit', 'class' => 'btn btn-primary')); ?>
のはずですが、2.2.2の場合は、submit文の場合はボタンが欠ける場合があるので、
 $this->Form->buttonを使って、typeにsubmitを指定すると良いようです。
(そのうち、修正されると思います。?)

<?php echo $this->Form->button('更新', array('type' => 'submit', 'class' => 'btn btn-primary')); ?>
<?php echo $this->Form->end(); ?>  // Formを閉じる

■フォームを閉じる
<?php echo $this->Form->end(); ?>

cakephp2.2 Sessionの設定 データベースで管理する

このページの内容

  • (1)app/Config/core.phpにて、Sessionをdatabaseで管理する設定
  • (2)databaseにcake_sessionsテーブルを作る
  • (3)Session read/writeの使い方

(1)app/Config/core.phpにて、Sessionをdatabaseで管理する設定
□app/Config/core.phpのSessionに関する説明を読む
 * The built in defaults are:
 *
 * - 'php' - Uses settings defined in your php.ini.
 * - 'cake' - Saves session files in CakePHP's /tmp directory.
 * - 'database' - Uses CakePHP's database sessions.
 * - 'cache' - Use the Cache class to save sessions.
160行目あたりに上記の記述があります。

↓defaults => 'php'の部分を'database'に変更すれば良いようです
 Configure::write('Session', array(
  'defaults' => 'php',
 ));

'cookie'と'timeout'の設定を追加しておきます。
↓下記は、24*60*60*7=1週間としました。
 Configure::write('Session', array(
  'defaults' => 'database',
  'cookie' => 'SID',
  'timeout' => 24*60*60*7,
 ));

(2)databaseにcake_sessionsテーブルを作る
 □app/Config/Schema/sessions.sql を読む
CREATE TABLE cake_sessions (
  id varchar(255) NOT NULL default '',
  data text,
  expires int(11) default NULL,
  PRIMARY KEY  (id)
);
上記のSQLを実行して、利用中のデータベースに cake_sessionsテーブル作成して完了です。

(3)Session read/writeの使い方

・セッション・オブジェクトへのの書き込み
$this->Session->write('LoginUser.Id', $uid);


・セッション・オブジェクトの読み出し
$this->Session->read('LoginUser.Id');

2012年9月4日火曜日

cakephp2.2 サーバに配置、gitで管理

○ソーシャルアプリ開発の準備段階

(*)バージョン管理は、git。
   ローカルでもサーバでも編集できる設定にするね。

■ローカルPCでソフトを集めて、サーバに配置して、gitするまでの流れ

1)ローカルPCに必要なソフトをダウンロードして、ローカルPCで動作を確認する
2)動作したcakephpをフォルダごと、ZIPして、目的のサーバにFTPする
3)サーバで、unzip(展開)して、必要な設定をする。サーバにアクセスして動作確認
4)ローカルPCにサーバのリポジトリのコピーを取る。ローカルPCでの設定をする。

□以下の(1)~(5)をダウンロードして、(2)~(5)は、cakephp2.2.2のwebrootに配置する。

(1)cakephp 2.2.2
(2)twitter bootstrap2.1.0
(3)jQuery
(4)jQuery UI
(5)jQuery mobile

配置は、レイアウトファイルの例を見て参考にしてください。

git-GUIの使い方は、

【git-GUI 基礎編 gitを使いまくる】


を参考にしてください。


cakephp2.2 find

○新しいアプリは新しい道具で作る

cakephpはfindを直感的に書けて、いいですね(*^_^*)

メニュー
・(基本形)findのパラメータの書き方
・(応用例)Menusコントローラの中で、Favoriteモデルのオブジェクトを読み込んでViewに渡す
・(応用例)conditions 'or' 条件

■ (基本形)findのパラメータの書き方

 $this->モデル名->find('all/list/count/', $parameter);

cakephp2.xマニュアルのfindはこちら
 array('Model.field' => $thisValue), //array of conditions
    'recursive' => 1, //int
    'fields' => array('Model.field1', 'DISTINCT Model.field2'), //array of field names
    'order' => array('Model.created', 'Model.field3 DESC'), //string or array defining order
    'group' => array('Model.field'), //fields to GROUP BY
    'limit' => n, //int
    'page' => n, //int
    'offset' => n, //int
    'callbacks' => true //other possible values are false, 'before', 'after'
)
recursive:アソシエーションの深さ。-1:自分だけ、0:自分と次まで、1:その次まで(ざっくり)
fields:取得するフィールドの指定。 おお! DISTINCTは、ここに書けばいいんだ!!!
order:arrayで並べて書けばいい。OR条件の場合は、下の記述を参照。
group:group byは、ここに書きます。
limit:paginateで表示するデータ数です。

(応用例)Menusコントローラの中で、Favoriteモデルのオブジェクトを読み込んでViewに渡す

(1)【準備】Menusコントローラの上部で、$usesに'Favarite’モデルを使う設定
class MenusController extends AppController {
 var $uses = array('Menu','Favorite', ・・・・); 

 ↑ $usesに'Favarite'モデルを追加

(2)【実行】コントローラのfunctionの中でfindする
1)App::importでFavoriteモデルをimportして
2)$favaritesオブジェクトをnewして準備しておきます
3)findで$favaritesに読み込み、このオブジェクトをsetしてViewに渡します
(実行したいfunctionの中で)

App::import('Model', 'Favorite');
$favorites = new Favorite;

$parameter = array(
          'conditions' => array('Favorite.valid <>' => 1, 'Favorite.show <>' =>0 ),
               'limit' => 10,
               'order' => array('modified' => 'desc'),
               );
$favorites = $this->Favorite->find('all', $parameter);
$this->set('favorites',$favorites);

conditionsで'or' 条件を使う
・'conditions'を 'or'のarrayで並べればOKです。

(例)ログインユーザで(and条件)、
   favarite(好きなもの)が 'りんご' か(or条件) 'みかん' のデータを抽出
(実行したいfunctionの中で)

App::import('Model', 'Favorite');
$favorites = new Favorite;

$parameter = array(
            'conditions' => array('Favorite.user_id' => $uid, 
                                      'OR' => array('Favorite.caption' => 'リンゴ'),
                                              array('Favarite.captiion' => 'みかん')
                                ),
               'limit' => 10,
               'order' => array('modified' => 'desc'),
               );
$favorites = $this->Favorite->find('all', $parameter);
$this->set('favorites',$favorites);

cakephp2.2 paginateの設定例

paginateの設定例

findと同様に、$paginateと$conditionsに設定します。
(コントローラのfunctionで)

var $paginate = array(
       'limit' => 10,
       'order' => array(
          'Menu.modified' => 'desc'
          ),
      );

$conditions = array('Menu.user_id' => $id);

$this->set('menus', $this->paginate('Menu', $conditions));


マニュアルより
public function paginate(
        $conditions, $fields, $order, $limit, $page = 1, $recursive = null, $extra = array()) {
    $recursive = -1;
    $group = $fields = array('weekly', 'category_id', 'start_time');
    return $this->find('all', 
        compact('conditions', 'fields', 'order', 'limit', 'page', 'recursive', 'group'));
}

2012年9月2日日曜日

CakePHP2.2 + Twitter Bootstrap2.1 ビューの書き方


ビューファイルの書き方

【基本パターン】


<div class="span12">
// span12の幅 で この中に ごにょ、ごにょ書いてゆけばよい


</div><!-- span12 -->

・どんな風に見えるか、デモページを用意します。  comming soon !! maybe?

レイアウトファイル cakephp2.2 + twitter bootstrap2.1 + jQuery1.7.2 + jQuery UI 1.8.21

■HTML5 + cakephp2.2.1 + twitter bootstrap2.1 と jQuery1.7.2 と jQueryUI 1.8.21

例えば、以下のレイアウトファイルを app/Vie/Layouts/ に配置すれば、
Twitter Bootstrap と jQuery を 自由に使えます。

レイアウトファイル  app/View/Layouts/home.ctp (ファイル名はお好きに)
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="">
<meta name="author" content="Toshio Nakashima">
<title><?php echo $title_for_layout; ?></title>
<?php  echo $this->Html->css('/css/bootstrap/bootstrap');  ?>
<?php  echo $this->Html->css('/css/bootstrap/bootstrap-responsive');  ?>
<?php  echo $this->Html->css('/css/bootstrap/docs');  ?>
<?php  echo $this->Html->css('/css/bootstrap/prettify');  ?>
<?php  echo $this->Html->css('/css/bootstrap/ticker');   ?>
<?php  echo $this->Html->css('/css/bootstrap/jquery.multiselect'); ?>
<?php  echo $this->Html->css('/css/bootstrap/jquery.multiselect.filter'); ?>

<?php  echo $this->Html->css('/css/themes/base/jquery.ui.base'); ?>
<?php  echo $this->Html->css('/css/themes/base/jquery.ui.theme'); ?>
<?php  echo $this->Html->css('/css/themes/base/jquery.ui.core'); ?>
<?php  echo $this->Html->css('/css/themes/base/jquery.ui.resizable'); ?>
<?php  echo $this->Html->css('/css/themes/base/jquery.ui.selectable'); ?>
<?php  echo $this->Html->css('/css/themes/base/jquery.ui.accordion'); ?>
<?php  echo $this->Html->css('/css/themes/base/jquery.ui.autocomplete'); ?>
<?php  echo $this->Html->css('/css/themes/base/jquery.ui.button'); ?>
<?php  echo $this->Html->css('/css/themes/base/jquery.ui.dialog'); ?>
<?php  echo $this->Html->css('/css/themes/base/jquery.ui.slider'); ?>
<?php  echo $this->Html->css('/css/themes/base/jquery.ui.tabs'); ?>
<?php  echo $this->Html->css('/css/themes/base/jquery.ui.datepicker'); ?>
<?php  echo $this->Html->css('/css/themes/base/jquery.ui.progressbar'); ?>
<?php  echo $this->Html->css('/css/themes/ui-lightness/jquery-ui-1.8.21.custom'); ?>

<?php  echo $this->Html->css('/css/jquery.ui.timepicker'); ?>

<?php echo $this->Html->script('/js/bootstrap/jquery-1.7.2');  ?>

<?php echo $this->Html->script('/js/bootstrap/bootstrap-transition');  ?>
<?php echo $this->Html->script('/js/bootstrap/bootstrap-alert');  ?>
<?php echo $this->Html->script('/js/bootstrap/bootstrap-modal');  ?>
<?php echo $this->Html->script('/js/bootstrap/bootstrap-dropdown');  ?>
<?php echo $this->Html->script('/js/bootstrap/bootstrap-scrollspy');  ?>
<?php echo $this->Html->script('/js/bootstrap/bootstrap-tab');  ?>
<?php echo $this->Html->script('/js/bootstrap/bootstrap-tooltip');  ?>
<?php echo $this->Html->script('/js/bootstrap/bootstrap-popover');  ?>
<?php echo $this->Html->script('/js/bootstrap/bootstrap-button');  ?>
<?php echo $this->Html->script('/js/bootstrap/bootstrap-collapse');  ?>
<?php echo $this->Html->script('/js/bootstrap/bootstrap-carousel');  ?>
<?php echo $this->Html->script('/js/bootstrap/application');  ?>

<?php echo $this->Html->script('/js/bootstrap/jquery.carouFredSel-5.1.0.js'); ?>
<?php echo $this->Html->script('/js/bootstrap/ticker'); ?>

<?php echo $this->Html->script('/js/jquery-ui-1.8.21.custom.min'); ?>
<?php echo $this->Html->script('/js/jquery.ui.datepicker-ja');  ?>

<?php echo $this->Html->script('/js/jquery.ui.timepicker'); ?>

<?php echo $this->Html->script('/js/bootstrap/jquery.multiselect'); ?>
<?php echo $this->Html->script('/js/bootstrap/jquery.multiselect.filter'); ?>

<?php echo $this->element('google_analtics'); ?>
</head>

<body lang="ja">
<div id="fb-root"></div>

<div class="container-fluid">

<?php echo $this->Session->flash();  ?>
<?php echo $this->fetch('content');  ?>
  <div class="span12">
    <div class="row-fluid">
       (C)copyright SoftwarefactoryTokyo inc. by ソフトウェア工場
    </div>

</div><!-- container-fluid -->

<script type="text/javascript" src="http://platform.twitter.com/widgets.js"></script>

</body>
</html>


■コントローラ

例えば、

public function test($id=null) {
   $this->layout = 'home';   // とレイアウトファイルを指定する


}

(PC画面向け組み合わせ)CakePHP + MySQL + jQuery + Twitter Bootstrap

さくさく開発環境を採用  (というか、利用させて、いただきます)


【基本】CakePHP+MySQL+jQuery+Twitter Bootstrap を基本とし、

PC画面は、Twitter Bootstrapを使い、画面の縦横の並びを合わせ、見やすい画面作りをしたい

jQueryは、jQUery + jQuery UI + jQuery Mobileを利用する

スマフォ画面は、jQuery Mobileで対応する

iPhoneアプリ/アンドロイドアプリは、 taitanium-mobileで対応させる

■Webアプリ
・PC用       基本
・スマフォ用         jQuery Mobile
・タブレット用       基本 + α 

■アプリ
・Facebookページアプリ 基本
・iPhoneアプリ       titanium-mobile
・アンドロイドアプリ    titanium-mobile

○開発環境
【データベース】 MySQL

【開発言語】 PHP、CakePHP2.2.1(最新)

(検討)
・データベースは、OracleかMySQLだけど、
  1.レンタルサーバでも対応できる
  2.予算的にMysql

・プログラミング言語
  1.PHP→CakePHPでしょう。超リアルタイムはいらないので、Javaの必要はない。
    CakePHPは、多国語対応が、2.2.1からとっても良くなったので。

cakephp2.2 select optgroup

■Cakephp セレクト <optgroup label='グループ名'>を表現する
        $options = array(
  '洋食' => array(
    '1' => 'ハンバーグ',
    '2' => 'ステーキ'
    ),
  '和食' => array(
    '3' => 'カレーライス',
    '4' => 'ラーメン'
    ),
  '中華' => array(
    '5' => '餃子',
    '6' => '天津飯'
    )
  );

 echo $this->Form->input('Mypage.menu' , array(
   'type' => 'select',
   'options'=> $options,
   'label' => 'メニュー(グループ)'
    )
   );


cakephp2.2 select radio checkbox

cake1.3 → cake2.2 変更は

cake1.3cake2.2
$form->input  $this->Form->input

デモ画面はこちらに設置しました

■Cakephp セレクト

$options = array(
  'shop1' => '和食',
  'shop2' => '洋食',
  'shop3' => '中華',
  'shop4' => 'アジアン',
  'shop5' => '居酒屋',
  'shop6' => 'バー',
  'shop7' => 'ラーメン',
  'shop8' => 'カフェ',
  'shop9' => 'その他'
  );

echo $this->Form->input( 'Mypage.menus' , array(
  'type' => 'select',
  'options'=> $options,
  'label' => 'メニュー(グループ無し)',
  'empty' => 'メニューを選んでください',
   )
  );


■CakePHP Radioボタン

 $options = array(
   'deal1' => '新規開業',
   'deal2' => '新規お取引開拓',
   'deal3' => '追加出店',
   'deal4' => '商品・サービスに関するお問い合わせ',
   'deal5' => 'その他'
   );

 echo $this->Form->input( 'Mypage.menu' , array(
   'type' => 'radio',
   'options'=> $options,
   'label' => '業態',
   'empty' => '業態を選んでください'
    )
   );
■Cakephp マルチチェックボックス

 $options = array(
   'check1' => 'カタログが欲しい',
   'check2' => '価格が知りたい',
   'check3' => 'サンプル等を試したい',
   'check4' => '詳細について商談がしたい',
   'check5' => 'その他のお問い合わせ',
   );

 echo $this->Form->input( 'Mypage.menu' , array(
   'type' => 'select',
   'multiple' => 'checkbox',
   'options'=> $options,
   'label' => 'お問合せの選択',
    )
   );


core.php timezone(時刻)の設定

■cakephp date.timezoneの設定

いつも、タイムゾーンの設定を忘れてしまうので、メモ。

Config/core.phpで

date_default_timezone_set('Asia/Tokyo');



2012年6月22日金曜日

git-GUI 基礎編 gitを使いまくる

この記事のメニュー

(1)ローカルマシンにサーバのリポジトリを複製するぞ
(2)サーバのコンテンツを配置する(リポジトリを作る)のが先じゃない?
(3)サーバでの作業
□git-GUIを使う

「環境」
    ・サーバ   ・gitコマンドが使えるレンタルホスト:OS: Linux
    ・開発マシン ・windows、(Linuxでもほぼ同じです) 
「要件」
    ・公開サーバに「コンテンツ」を置くが、実機での修正もしたい。
    ・開発マシンは、windows/Linux/Macが使えるように。


  (1)ローカルマシンに、サーバのリポジトリを複製するぞ

□作業の順序
(1)gitのクライアントをダウンロードする
(2)インストールする。画面に従ってすすめばOKです。
(3)サーバから、ローカルPCにリポジトリを複製する。(git-GUIの使い方ですね)

(1-1)サーバからリポジトリを複製する (サーバがオリジナルですね)
・ローカルPCで、配置したいディレクトリで右クリックすると、下の画面が出ます。

ソースの位置と
ローカルPCのディレクトリを入力します

次にSSHのパスワードを聞いてきます(3回)ので、入力すると
ローカルPCにコピーされます。 

(1-2)ローカルPCの設定
ローカルPCの名前を設定しておく (必ず、やってね)

(1-3)ローカルPCの変更を、サーバにアップする
ローカルPCで、追加、変更をサーバにアップします。
使う順番は、画面の順番の通りに、押してゆけばOKですね。
 1) 変更をコミット予定に入れる
 2)署名
 3)コミット
 4)プッシュ(サーバにプッシュします

(1-4)サーバから変更を取ってくる リモート→取得元→originを選択する

(1-5)取ってきたのをマージする マージしなきゃあ反映されないぞっ

 (2)サーバにコンテンツを配置する(リポジトリを作る)のが先じゃない?
サーバ:リポジトリ作成」
「事前準備」
FTPなどで、このディレクトリに必要な初期コンテンツを上げておく、
サーバにログインして、ディレクトリ内に移動

例えば、cakephp2.2.2を配置したディレクトリが /web/cakephp222/ とすると

$>cd /web/cakephp222/
$>git init --shared=true
$>git config --add receive.denyCurrentBranch ignore
$>git add .
$>git commit -a -m "start"

・リポジトリをinit初期化して、
・全部のファイルをリポジトリに加えて add.
・変更をcommit して完了です。
・$git init --bare とすると、working treeをつくらない設定なので、
今回は、共有夕オプションの --shared=true

・git管理除外設定ファイル(DB設定ファイルとかキャッシュファイルとか・・)の 
 .gitignoreに必要なファイル名を書いておく
・CakePHPだと、ダウンロードのファイルに用意されているので、便利、そのまま、使う
(FTPで送る)

(3)サーバでの作業

リポジトリを作り損なったので、gitディレクトリを丸々削除したい
$>chmod -R g-s .git
$>chmod -R 747 .git
$>rm -rf .git

ブランチ作成
$>git branch branch_name

ブランチに作業を移行
$>git checkout branch_name

コミットし、メッセージはmessage
$>git commit -a -m "message"

修正をにマージ
$>git checkout master
$>git merge branch_name

ブランチを削除
$>git branch -d branch_name

マージしてないブランチを削除
$>git branch -D branch_name


はまった。
 UTF-8環境前提 (~/.bashrcに記述して)
export LANG=ja_JP.UTF-8


$ git config --global user.name "Your Name"
$ git config --global user.email you@example.com