asklife

IT&Life

Category: PHP (page 2 of 16)

CakePHPのつまりどころ

権限関連の更新が出来ない問題

chmod -R 755 app/tmp/cache

.htaccessがない問題

.htaccessは3箇所にあります。
①/ (appと同一ディレクトリ)

<IfModule mod_rewrite.c>
   RewriteEngine on
   RewriteRule    ^$ app/webroot/    [L]
   RewriteRule    (.*) app/webroot/$1 [L]
</IfModule>

②/app/

<IfModule mod_rewrite.c>
    RewriteEngine on
    RewriteRule    ^$    webroot/    [L]
    RewriteRule    (.*) webroot/$1    [L]
</IfModule>

③/app/webroot

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^ index.php [L]
</IfModule>

ダウンロードしたばかりではここに置かれていません。

CakePHPの共通レイアウトを変更する手順

default.ctpを修正する

CakePHPのデフォルトレイアウト「default.ctp」を読み解く

default.ctpは各画面の基板となるものです。

cssは以下のようにして読み込みます。

echo $this->Html->css('cake.generic');

cssを修正する

①footerを下部に固定する

CSS

html,body{
     height:100%;
}
#wrap{
     width: 100%;
     position: relative;
     height:auto !important; /*IE6対策*/
     height: 100%; /*IE6対策*/
     min-height: 100%;
}
#contents{
     padding-bottom:140px; /*フッターの高さと同じ*/
}
#footer{
    height:140px;
     position:absolute;
     bottom:0;
}

CakePHPでFacebookのログイン認証を実装する手順

はじめに

#2013/12/30 初版
#2014/5/25  実装修正

CakePHPにはAuthコンポーネントというものがあります。
Authコンポーネントの認証クラスを作成し、Facebook認証をします。

Facebook SDK

以下からFacebook SDKをダウンロード
https://developers.facebook.co……ingstarted

git clone https://github.com/facebook/facebook-php-sdk

下記に配置

app/Controller/Component/Auth

Facebookアプリ登録

Developersサイトにてアプリ登録をします。
https://developers.facebook.com

※全部英語ですがなんとなくわかると思います。
Apps→Create a New App
アプリケーション名を決めてアプリケーション作成ボタンをクリック

DashboardにAppIDとAppSecretがあるのでそれをメモしておきます。

SettingにてContact Emailを登録します(これをしないと公開出来ません)

今回は、Webサイトでlocalhostなので
Setting→AddPlatform→WebSite→SiteURLに http://localhost:8888/とします。

FacebookAuthenticate.php

app/Controller/Component/Auth/FacebookAuthenticate.php

<?php
App::uses('BaseAuthenticate','Controller/Component/Auth');
App::import('Vendor','facebook',array('file'=>'facebook/src/facebook.php'));

class FacebookAuthenticate extends BaseAuthenticate {
	public $settings = array(
		'fields'=>array(
			'fbUserId'=>'fb_user_id',
			'fbToken'=>'fb_tokem',
		),
		'userModel'=>'User',
		'fbScope'=>'publish_stream,email',
	);
	
	public function authenticate(CakeRequest $request,CakeResponse $response){
		CakeLog::write('debug', '[FacebookAuthenticate/authenticate] REQUEST');
		try{
			$facebook = new Facebook(array(
				'appId'=>$this->settings['fbAppId'],
				'secret'=>$this->settings['fbAppSecret'],
				'cookie'=>true
			));
		
			switch ($request->params['action']){
				case 'fblogin':
					CakeLog::write('debug', '[FacebookAuthenticate/authenticate login] REQUEST');					
					$login_url = $facebook->getLoginUrl(array(
						'redirect_uri'=>$this->settings['fbRedirect'],
						'scope'=>$this->settings['fbScope'],
					));
					$response->header('Location',$login_url);
					$response->send();
					break;
				case 'callback':
					CakeLog::write('debug', '[FacebookAuthenticate/authenticate callback] REQUEST');			
					return $this->_fb_update_user(
						$user_id = $facebook->getUser(),
						$facebook->getAccessToken()
					);
					break;				
			}
		} catch(OAuthException $e){
			CakeLog::write('debug', '[FacebookAuthenticate/authenticate OAuthException] REQUEST');					
			debug($e);
		}
	}
	
	public function _fb_update_user($user_id,$token){
		CakeLog::write('debug', '[FacebookAuthenticate/_fb_update_user($user_id,$token)] REQUEST');					
		$fields = $this->settings['fields'];
		$model_name = $this->settings['userModel'];
		
		$model = ClassRegistry::init($model_name);
		$user = $model->find(
			'first',
			array(
				'conditions'=>array(
					$model_name.'.'.$fields['fbUserId']=>$user_id
				),
			'recursive'=>0
			)
		);
		
		if(empty($user)||empty($user[$model_name])){
			CakeLog::write('debug', '[FacebookAuthenticate/_fb_update_user($user_id,$token) empty($user)||empty($user[$model_name])] REQUEST');					
			$model->create();
			$user = array(
				$model_name => array(
					$fields['fbUserId']=>$user_id,
					$fields['fbToken']=>$token,
			));
		}else{
			CakeLog::write('debug', '[FacebookAuthenticate/_fb_update_user($user_id,$token) else REQUEST');					
			$user[$model_name][$fields['fbToken']]=$token;
		}
		return $model->save($user);
	}				
}

UsersController.php

app/Controller/UsersController.php

<?php
App::uses('AppController','Controller');

class UsersController extends AppController{
	public $name = 'Users';
	public $uses = array('User');
	public $components = array(
		'Auth' => array(
			'authenticate' => array(
				'Form'=>array(
					'fields'=>array(
						'username'=>'email',
						'password'=>'password',
					),
				),
				'Facebook'=>array(
					'fbAppId'=>'****',
					'fbAppSecret'=>'****',
					'fbScope'=>'publish_stream',
					'fbRedirect'=>'http://localhost:8888/Users/callback/facebook',
					'userModel'=>'User',
					'fields'=>array(
						'fbUserId'=>'fb_user_id',
						'fbToken'=>'fb_token',
						),					
				)
			),
			'loginAction' => '/Users/login',//ログインしていない時リダイレクトさせる
			'loginRedirect' => '/events/index',
			'logoutRedirect' => '/Users/login'
		)
	);
	
	public function selectbyuserid($user_id) {
		$this->log('[UsersController/selectbyuserid] REQUEST', 'debug');	
		return $this->User->find('all',array('fields'=>array('User.email'),'conditions'=>array('User.id'=>$user_id)));
	}
	
	function beforeFilter(){
		$this->log('[UsersController/beforeFilter] REQUEST', 'debug');	
		parent::beforeFilter();
		$this->Auth->allow('callback');
	}
		
	public function index(){
		$this->log('[UsersController/index()] REQUEST', 'debug');
		$this->set('user',$this->Auth->user());
	}
	
	public function login(){
		//メールによるログイン
		$this->log('[UsersController/maillogin()/] REQUEST', 'debug');
		$errors = array();
		if($this->request->data){
			$this->log('[UsersController/maillogin()/ $this->request->data true] REQUEST', 'debug');	
			if($this->Auth->login()){
				return $this->redirect($this->Auth->redirectUrl());
			}else{
				$this->log('[UsersController/maillogin()/ $this->request->data false] REQUEST', 'debug');	
				$errors[]='メールアドレスかパスワードが違います';
			}
			$this->set('errors',$errors);
		}
	}
	
	public function fblogin(){
		//Facebookによるログイン
		$this->log('[UsersController/fblogin()] REQUEST', 'debug');	
		$user = $this->Auth->user();
		if($user){
			$this->log('[UsersController/fblogin() ログイン済 ] REQUEST', 'debug');	
			$this->redirect($this->Auth->loginRedirect);
		}else{
			$this->log('[UsersController/fblogin() ログイン未 ] REQUEST', 'debug');
			$this->Auth->login();
		}			
	}
	
	public function callback($provider){
		$this->log('[UsersController/callback()] REQUEST', 'debug');
		if($this->Auth->login()){
			$this->log('[UsersController/callback()/login true] REQUEST', 'debug');
			$this->redirect($this->Auth->redirectUrl());
		}
	}
		
	public function logout(){
		$this->log('[UsersController/logout()] REQUEST', 'debug');
		$logout_url = $this->Auth->logout();
		$this->redirect($logout_url);		
	}

	public function islogin(){
		$this->log('[UsersController/islogin()] REQUEST', 'debug');		
		$logged_in = $this->Auth->User();
		$logged_in = AuthComponent::User();
		if(is_null($logged_in)){
		}else{
			return $logged_in['email'];
		}		
	}	
}

CakePHPでごりごり実装したので作業メモ

CakePHPでごりごり実装したので作業メモ

・RequestはPOST/GET/

$this->request->is('post')

・テーブルにカラムを追加する

ALTER TABLE events add etname varchar(10);

・hidden()をつかう

echo $this->Form->hidden('Event.etname',array('value' => $etname));

・viewからConrtorllerを呼ぶ

$etname = $this->requestAction('events/generateRandomString');

・CakePHPのセッション

$this->Session->write('etname',$etname);
if ($this->Session->check('etname')){
    	echo $this->Session->read('etname');
}

・Controllerの実行前に処理するメソッド

public function beforeFileter(){
	parent::beforeFileter();
	$this->Auth->allow();
}

・ログの出力

// app/Config/bootstrap.php
App::uses('CakeLog', 'Log');

//Controllerのメソッドの先頭等で
$this->log('[HogeController/hoge()] REQUEST', 'debug');

・SimplePasswordHasher()を使う

App::uses('SimplePasswordHasher', 'Controller/Component/Auth');

MacのMAMPでCakePHP入門

MacのMAMPでCakePHPのチュートリアルを実装

MAMPのDocument Rootは
/Applications/MAMP/htdocs
です。

CakePHPチュートリアルをやっていきます。
http://book.cakephp.org/2.0/ja……d.html#id2

以下は自分用のメモ

まずはCakePHPをgit cloneします。

cd /Applications/MAMP/htdocs
git clone git://github.com/cakephp/cakephp.git

次にDB・テーブル作成

/* まず、postsテーブルを作成します: */
CREATE TABLE posts (
    id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    title VARCHAR(50),
    body TEXT,
    created DATETIME DEFAULT NULL,
    modified DATETIME DEFAULT NULL
);

/* それから、テスト用に記事をいくつか入れておきます: */
INSERT INTO posts (title,body,created)
    VALUES ('タイトル', 'これは、記事の本文です。', NOW());
INSERT INTO posts (title,body,created)
    VALUES ('またタイトル', 'そこに本文が続きます。', NOW());
INSERT INTO posts (title,body,created)
    VALUES ('タイトルの逆襲', 'こりゃ本当にわくわくする!うそ。', NOW());

database.phpをリネームコピーし、中身を書き換える。

cp -p app/Config/database.php.default app/Config/database.php

DB設定をあわせます。

public $default = array(
         'datasource' => 'Database/Mysql',
         'persistent' => false,
         'host' => 'localhost',
         'login' => 'user',
         'password' => 'password',
         'database' => 'cakephp',
         'prefix' => '',
         //'encoding' => 'utf8',
);

セキュリティ用のSaltを書き換え、ハッシュ生成用にランダムな値をセット

vi app/Config/core.php
Configure::write('Security.salt', 'hogehogehogehoge');
Configure::write('Security.cipherSeed', 'hogehogehogehoge');

最後にapp/tmpの権限を変更

chmod -R 755 app/tmp

DebugKitをインストール
https://github.com/cakephp/debug_kit

上記からZipをダウンロードし、解凍しapp/Plugin/DebugKitとして展開します。

app/Config/bootstrap.php

CakePlugin::load('DebugKit');

app/Controller/AppController.php

class AppController extends Controller {
	public $components = array('DebugKit.Toolbar');
}

app/Config/core.php

Configure::write('debug',2);

さて、ここまででCakePHPの準備完了

ブログチュートリアル開始

Postモデル作成

touch app/Model/Post.php
vi app/Model/Post.php

<?php
class Post extends AppModel {
    public $validate = array(
        'title' => array(
            'rule' => 'notEmpty'
        ),
        'body' => array(
            'rule' => 'notEmpty'
        )
    );
}

ここでPostクラスとするのはPostテーブルを作ったからです。

Postコントローラ作成

touch app/Controller/PostsController.php
vi app/Controller/PostsController.php

<?php
class PostsController extends AppController {
    public $helpers = array('Html', 'Form', 'Session');
    public $components = array('Session');

    public function index() {
        $this->set('posts', $this->Post->find('all'));
    }

    public function view($id) {
        if (!$id) {
            throw new NotFoundException(__('Invalid post'));
        }

        $post = $this->Post->findById($id);
        if (!$post) {
            throw new NotFoundException(__('Invalid post'));
        }
        $this->set('post', $post);
    }

    public function add() {
        if ($this->request->is('post')) {
            $this->Post->create();
            if ($this->Post->save($this->request->data)) {
                $this->Session->setFlash(__('Your post has been saved.'));
                return $this->redirect(array('action' => 'index'));
            }
            $this->Session->setFlash(__('Unable to add your post.'));
        }
    }
    public function edit($id = null) {
    	if (!$id) {
        	throw new NotFoundException(__('Invalid post'));
    	}

    	$post = $this->Post->findById($id);
    	if (!$post) {
    	    throw new NotFoundException(__('Invalid post'));
    	}

    	if ($this->request->is(array('post', 'put'))) {
        	$this->Post->id = $id;
        	if ($this->Post->save($this->request->data)) {
        	    $this->Session->setFlash(__('Your post has been updated.'));
        	    return $this->redirect(array('action' => 'index'));
        	}
        	$this->Session->setFlash(__('Unable to update your post.'));
    	}

    	if (!$this->request->data) {
        	$this->request->data = $post;
    	}
    }

public function delete($id) {
    if ($this->request->is('get')) {
        throw new MethodNotAllowedException();
    }

    if ($this->Post->delete($id)) {
        $this->Session->setFlash(__('The post with id: %s has been deleted.', h($id)));
        return $this->redirect(array('action' => 'index'));
    }
}


}

ここでindex()メソッドは
example.com/posts/index
というHTTPリクエストで呼ぶことになる。

set()はControllerからViewへデータを渡す。

Postビュー作成

mkdir app/View/Posts
touch app/View/Posts/index.ctp
vi app/View/Posts/index.ctp

<!-- File: /app/View/Posts/index.ctp -->

<h1>Blog posts</h1>
<p><?php echo $this->Html->link('Add Post', array('action' => 'add')); ?></p>
<table>
    <tr>
        <th>Id</th>
        <th>Title</th>
        <th>Actions</th>
        <th>Created</th>
    </tr>

<!-- ここで$posts配列をループして、投稿情報を表示 -->

    <?php foreach ($posts as $post): ?>
    <tr>
        <td><?php echo $post['Post']['id']; ?></td>
        <td>
            <?php echo $this->Html->link($post['Post']['title'], array('action' => 'view', $post['Post']['id']));?>
        </td>
        <td>
            <?php echo $this->Form->postLink(
                'Delete',
                array('action' => 'delete', $post['Post']['id']),
                array('confirm' => 'Are you sure?'));
            ?>
            <?php echo $this->Html->link('Edit', array('action' => 'edit', $post['Post']['id'])); ?>
        </td>
        <td>
            <?php echo $post['Post']['created']; ?>
        </td>
    </tr>
    <?php endforeach; ?>

</table>

viewビューを作成
※わかりにくい。。。笑


touch app/View/Posts/view.ctp
vi app/View/Posts/view.ctp

<!-- File: /app/View/Posts/view.ctp -->

<h1><?php echo h($post['Post']['title']); ?></h1>

<p><small>Created: <?php echo $post['Post']['created']; ?></small></p>

<p><?php echo h($post['Post']['body']); ?></p>

addビューを作成

touch app/View/Posts/add.ctp
vi app/View/Posts/add.ctp

<!-- File: /app/View/Posts/add.ctp -->

<h1>Add Post</h1>
<?php
echo $this->Form->create('Post');
echo $this->Form->input('title');
echo $this->Form->input('body', array('rows' => '3'));
echo $this->Form->end('Save Post');
?>

editビューを作成

touch app/View/Posts/edit.ctp
vi app/View/Posts/edit.ctp

<!-- File: /app/View/Posts/edit.ctp -->

<h1>Edit Post</h1>
<?php
echo $this->Form->create('Post');
echo $this->Form->input('title');
echo $this->Form->input('body', array('rows' => '3'));
echo $this->Form->input('id', array('type' => 'hidden'));
echo $this->Form->end('Save Post');
?>

ルーティングを変える
※これはやらなくてもOK

vi /app/Config/routes.php

// Router::connect('/', array('controller' => 'pages', 'action' => 'display', 'home'));
Router::connect('/', array('controller' => 'posts', 'action' => 'index'));

http://localhost:8888/
http://localhost:8888/cakephp/posts/index

を確認してみる。

WEBサーバにあげて動かしてみると権限とかいろいろ詰まった。

Warning (512): CakePHPのフォルダ/app/tmp/cache/ is not writable [CORE/Cake/Cache/Engine/FileEngine.php, line 320]

chmod -R o+w app/tmp/cache/

つぎはCSSが反映されていない問題を解決

sudo vim /etc/apache2/apache2.conf

<Directory "CakePHPのパス(環境に合わせて変えましょう)">
    AllowOverride all
</Directory>

sudo service apache2 restart

次はこれを実装してみよう。
#CakePHP 爆速でAPIを実装するチュートリアル
http://slywalker.hateblo.jp/en……/15/115907

git clone https://github.com/slywalker/cakephp-app-api_sample
Older posts Newer posts

© 2017 asklife

Theme by Anders NorenUp ↑