ラベル Laravel の投稿を表示しています。 すべての投稿を表示
ラベル Laravel の投稿を表示しています。 すべての投稿を表示

2016-12-08

Laravel で全 view からログイン中のユーザー情報を取得する

Laravel を利用して開発をしていると、まだまだ全ての機能を使いきれていないことに気付かされることがあります。
ということで今回は ViewComposer を使って、どのビューからでもログイン中のユーザーにアクセスできるようにしてみたいと思います。

【実行環境】Laravel 5.3


手順は以下の3つです。
  1. ViewComposer を作る
  2. ServiceProvider を作る
  3. ServiceProvider を登録する

ではひとつひとつ見ていきましょう。

1. ViewComposer を作る

まず ViewComposer の作成です。
デフォルトでは専用のフォルダは用意されていませんので app/Http/ViewComposers というフォルダを新たに作成しましょう。
そして、その中に AuthViewComposer.php というファイルを作成&以下のコードを保存します。
 <?php namespace App\Http\ViewComposers;  
 use Illuminate\View\View;  
 class AuthViewComposer  
 {  
   protected $user;  
   public function __construct()  
   {  
     $this->user = \Auth::user();  
   }  
   public function compose(View $view)  
   {  
     $view->with([  
       'user' => $this->user  
     ]);  
   }  
 }  


2.ServiceProvider を作る

次に専用の ServiceProvider を作ります。
app/Providers/ViewComposerServiceProvider.php を作成&以下のコードを保存してください。
 <?php namespace App\Providers;  
 use Illuminate\Support\ServiceProvider;  
 class ViewComposerServiceProvider extends ServiceProvider  
 {  
   public function boot()  
   {  
     \View::composers([  
       \App\Http\ViewComposers\AuthViewComposer::class => 'layouts.*'  
     ]);  
   }  
 }  
※ ちなみに layouts.* の部分ではどの view に適用するかを設定することができます。


3.ServiceProvider を登録する

最後は先ほど作った ViewComposerServiceProvider を config/app.php へ登録します。
 'providers' => [  
   App\Providers\ViewComposerServiceProvider::class,  
 ],  

さあ、以上で設定は完了です。好きな view の中で {{ $user->email }} という風にユーザー情報にアクセスしてみましょう。
なお、念のために、以下のコマンドを実行しておくといいかもしれません。
 composer dumpautoload -o  

今回は以上です。
お疲れ様でした。



2016-06-22

FlysystemをLaravelで使う

開発サイトの規模が大きくなってきたり、よりセキュアなサーバー環境を整えるためにサーバーを「ウェブサーバー」と「データサーバー」で物理的に分割する場合があると思います。

そして、PHPでファイルをリモートで読み込み/書き込みをするためには「Flysystem」という有名なパッケージを利用すればとても簡単にできるのですが、今回はこの「Flysystem」をLaravel(5.2)で使う方法をお届けしたいと思います。

※ちなみに今回はSFTPを使ってリモートサーバーとの連携をしますが、Flysystemは他にもaws」や「Azure」、その他には「DropBox」との連携までサポートしています。


【環境】

Laravel 5.2
SFTPで自分のVPSへSFTPを使って接続

【インストール】

まずは composer でパッケージのインストールです。
ここではLaravelと統合されているものをインストールします。
(ちなみにGitHubはこちら)
composer require graham-campbell/flysystem
次に私の場合はSFTPでの接続ですので、Flysystemのサブパッケージをインストールします。
league/flysystem-sftp:^1.0
はい。これでインストールは完了です。


【準備】

いつものように ServiceProvider と aliases を config/app.php に設置しましょう。

(ServiceProvider)
 GrahamCampbell\Flysystem\FlysystemServiceProvider::class  


(Aliases)
 'Flysystem' => GrahamCampbell\Flysystem\Facades\Flysystem::class  


そして、以下のコマンドで専用の設定ファイルを publish します。
php artisan vendor:publish
実行すると、configフォルダの中に「flysystem.php」というファイルが作成されていると思いますのでこの中で接続情報を保存します。

※もしコマンドを実行しても flysystem.php が作成されない場合は、以下のコマンドを実行してからもう一度トライしてみてください。
  • composer dumpautoload -o
  • php artisan config:cache

では、実際の中身です。

今回はSFTPでの接続なので「SFTP」のエリアを探して、必要な情報を入力すればOKです。
変更する場所としては、

  • host(IPアドレスなど)
  • port(変えている場合)
  • username
  • password
  • privateKey(プライベート・キーファイルのパス)
  • root(リモートサーバーの保存したいフォルダパス)

あたりになるかと思います。

はい、これで設定は完了です。


【使い方】

(基本的な使い方)

使い方はとても直感的でシンプルです。
次の例は、「test.txt」というファイルを作り、さらにそこに「bar」という文字列を書き込む手準になります。

 \Flysystem::connection('sftp')->put('test.txt', 'bar');  

たったこれだけです。
では逆にその保存した内容を読み込んでみましょう。

 echo \Flysystem::connection('sftp')->read('test.txt');  

これで「bar」が表示されます。


(フォルダを指定して保存)

もし、フォルダを指定して保存したい場合はこのようになります。

 \Flysystem::connection('sftp')->put('test_dir/test.txt', 'bar');  

この場合は、test_dir/test.txt にファイルが保存されます。


(画像を保存)

これもテキストファイルなどとやり方はほぼ同じで、

 $content = file_get_contents(public_path('images/my_photo.jpg'));  
 \Flysystem::connection('sftp')->put('me.jpg', $content); 

とやればOK。
とてもシンプルです。

ちなみに、Laravelを使って保存した画像をサーバーから呼び出して表示するには以下のようにすればいいでしょう。

(コントローラ)
 public function flysystem_image() {  
      $image_contents = \Flysystem::connection('sftp')->read('me.jpg');  
      return response($image_contents, 200)->header('Content-Type', 'image/jpeg');  
 }  

以上、Laravel と Flysystem を使ったサーバーの連携方法でした。
ではでは!



2016-06-09

受信したメールをLaravelで受け取る

受信メールをPHPプログラムへ送り、メールを解析して送信元のメールアドレスや本文を取得してDBに保存ということをLaravel(5.2)をからめてやるにはどうすればいいかをメールサーバーをたてるところからやってみたので備忘録としてお届けします。
(はっきり言って作業内容は多かったです、、^^;)




【作業環境】

CentOS 6.7


【作業の手順】
  1. Postfix をインストール/設定
  2. ドメインのDNS設定
  3. Pecl(Pear)本体をインストール
  4. Pecl の mailparse をインストール、extensionの読み込み
  5. Laravelパッケージ「php-mime-mail-parser」をインストール
  6. LaravelにCommandを追加

【実際の作業】

では、ここからは実際の作業になりますが、全部書くと確実に長くなってしまいますので途中は参考にしたサイトを紹介しながらすすめていきます。

1. Postfix をインストール/設定

私の場合はCentOSなので
sudo yum install postfix
でインストールしましたが、環境によって変更してください。
また、設定の方法は以下のページがとてもわかりやすいと思いますのでぜひ参考にしてみてください。


また、この記事の中にも紹介されていますが、設定が完了したら以下のサイトでセキュアチェックができます。


そして「/etc/aliases」をエディタで開き、以下のような振り分け設定を追加しましょう。

mail: "| /usr/bin/php /path/to/your/public/folder/example.com/artisan mail:parse"

意味としては

  • mail・・・はユーザー名。つまり、mail@example.comでメール受信した場合の設定ですよという意味です。
  • /usr/bin/php(以下略)・・・PHPを使ってLaravelのartisanを実行
  • mail:parse・・・実行するコマンド(「6.LaravelにCommandを追加」で作る独自コマンドです)

完了したら、 sudo postalias /etc/aliases でエイリアスをアップデートします。
そして、最後に sudo service postfix reload でpostfixをリロードで完了です。


2.ドメインのDNS設定

これも人によって記述が違うと思いますが私の設定は以下のようにしています。
mx mail.example.com. 10
a * 01.234.567.890
txt @ v=spf1 a:example.com ~all
2行目はIPアドレスです。
※ちなみにこれはサーバー設定ではなく、取得したドメインの管理サイトで設定をします。


3.Pecl(Pear)本体をインストール
sudo yum install php-pear
ここは戸惑いました。
Peclをインストールするにはpearをインストールするんですね。
(その昔、mecabをインストールしたことあるのに...)

なお、リポジトリを設定しないとパッケージが見つからないかもしれません。


4. Pecl の mailparse をインストール、extensionの読み込み
pecl install mailparse
でメール解析に必要な mailparse をインストールします。
ただ、もしかすると
The php-devel package is required for use of this command.
というエラーがでてインストールできないかもしれません。
そのときはエラーの表示にある php-devel をインストールしてからやってみてください。

では、インストールした mailparse を PHPが利用できるように設定をしましょう。
ファイルを作成する場所は php.ini の「Additional .ini files parsed」でリストに出てくるフォルダです。



たとえば、もし「/etc/php5/apache2/conf.d/05-opcache.ini」が表示されているとするなら「/etc/php5/apache2/conf.d」がそのフォルダになります。

ではここに mailparse.ini というファイルを作成し、以下の内容を保存します。
php extension=mailparse.so
はい。
これでmailparseの設定は完了です。
ウェブサーバーを再起動してもう一度 phpinfo を確認すると以下のようにmailparse が表示されているはずです。



5.Laravelパッケージ「php-mime-mail-parser」をインストール

これはとても簡単です。
composer で一気にインストールできます。
composer require php-mime-mail-parser/php-mime-mail-parser
ちなみに、パッケージがあるなら mailparse は要らないんじゃ?と思った方。
私もそうでした。
でも、実際は mailparse を前提にしたパッケージなのでやはり Pecl他は必要なんです。^^;

※GitHubのページはこちらです。


6.LaravelにCommandを追加

やっとここまで来ました。
コマンドの作成/設定方法は本家Laravelページで確認してください。

コマンドの中身は以下のようになります。
$parser = new Parser();
$parser->setStream(fopen('php://stdin', 'r'));
あとは、以下のような便利なメソッドが備わっているのでこれを使ってメールを思うように加工してください。
$to = $parser->getHeader('to'); // 送信先
$addressesTo = $parser->getAddresses('to'); // 送信先(配列)
$from = $parser->getHeader('from'); // 送信元
$addressesFrom = $parser->getAddresses('from'); // 送信元(配列)
$subject = $parser->getHeader('subject');  // 件名

$text = $parser->getMessageBody('text');   // 本文(テキスト)
$html = $parser->getMessageBody('html');   // 本文(HTML
$htmlEmbedded = $parser->getMessageBody('htmlEmbedded');   // データを含む本文(HTML
添付ファイル

添付ファイルの扱い方は以下になります。

(保存)
$parser->saveAttachments('/path/to/save/attachments/');

(ループ)
$attachments = $parser->getAttachments();
if (count($attachments) > 0) {
   foreach ($attachments as $attachment) {
      $filename = $attachment->getFilename();
      $path = '/path/to/save/attachments/'. $attachment->getFilename();
      $type = $attachment->getContentType();
   }
}

ということで、環境の違いもあるので全てを一気にやろうと思うとなかなか難しいかもしれませんがこんな感じで受信メールをLaravelで受け取ることができます。

お疲れ様でした。

【その他参考にしたページ】

https://sboersma.nl/blog/setting-up-postfix-and-pipe-incoming-emails-to-laravel




2016-04-23

Laravel で独自コマンドを作成する方法

Laravelは本当に利用がしやすく誰にでもおすすめができるのですが、その理由のひとつ
として「自分の好きなコマンドを独自に作成することができる」というものが挙げられるかと思います。

コマンド。
そう、あまり windows ユーザーの方は馴染みがないかもしれませんが、cron が利用して定期的にプログラムを起動するといった用途に使えるととても便利な機能です。

※たしか windows 10 で Ubuntu が使えるようになる(った?)のでこれからはコマンドも windows ユーザーには馴染みのあるものに成るかもしれませんね。


ということで、今回はLaravel 5 を例に独自コマンドを作成する方法をご紹介したいと思います。




【準備】

では、まずターミナルを開いてLaravelがインストールしてあるフォルダまで移動してください。
そして、独自コマンドから起動するPHPファイルを作成します。
以下のコマンドを打ち込んで実行してください。
(TestCommandの部分はお好きな名前が使えます。)

php artisan make:console TestCommand

実行すると「Console command created successfully.」というメッセージが出て以下にひな形のファイルが自動で作成されています。
 app/Console/TestCommand.php

【コマンドファイルの作成】

ファイルを開くと「TestCommand」というクラスが書かれていて、中にいくつかのメンバ変数やメソッドなどが書かれていると思います。

ここで変更する点は以下の3点です。

  1. $signature
  2. $description
  3. handle()

ではひとつずつ見て行きましょう。

1.$signature

$signature は実際にどんなコマンドを使いたいかを設定します。
例えば、E-Mail を定期的に送信するプログラムを起動したい場合は以下のようにすればいいでしょう。

protected $signature = 'cron:email';

コロン「:」をつけておくとコマンドの一覧を確認する際に大ジャンル、少ジャンルのようにリスト表示してくれて見やすいので付けられる場合はぜひつけておきましょう。

cron
  cron:email
  cron:test
db
  db:seed

はい。
これでコマンド「php artisan cron:email」というコマンドが利用できるようになります。(実際には登録がまだなので実行はできません。もし先に登録したい場合は一番最後の項目「コマンドの登録」へ移動してください。)


2.$description

$description はそのままでコマンドの説明分です。
後で「あれ?どんなコマンドだったっけ?」なんてこともたまにはあるので、ぜひ登録しておきましょう。説明文はコマンド一覧から読むことができます。

protected $description = 'Send email to users';


3.handle()

public function handle(){  } の中にはコマンド実行した時に呼ばれるプログラムになります。
つまり心臓部分ですね。
メールを送信する、データをスクレイピングしてとってくるなどお好きな使い方をしてください。


なお、もしかするとコマンドに値を渡したい場合があるかもしれません。
例えば、

  • メールを最大10件だけ送信したい
  • 日本人ユーザーだけにメールを送信したい

そんな場合は 「argument」と「option」が利用できます。
まずは argument から。

例えばこんなカンジでコマンドを利用したい場合です。

(10件だけ送信) 
php artisan cron:email 10

$signature に

protected $signature = 'cron:test {count}';

と、{オプション名}をつけるだけでhandle()内で以下のように値を受け取れます。

$count = $this->argument('count');

ただし、この場合は必ず引数を指定しないとエラーが発生します。
もし値を任意にしたい場合は、以下のように?をつけるといいでしょう。

protected $signature = 'cron:test {count?}';

また、デフォルト値を指定したい場合はこうなります。

protected $signature = 'cron:test {count=50}';


では、次に「option」です。
option も先ほどと似ていて、基本の形はこうなります。

protected $signature = 'cron:test {--country}'


ただし、この場合は「値をとらない場合」になります。
つまり、

php artisan cron:test --country=japan

という形では利用できず、

php artisan cron:test --country

という形で、値としては true/false を受け取ることになります。
ですので、使い方としては以下のような形がいいでしょう。

if($this->option('country')) {
   echo 'Yes!';
}


では、値を渡したい場合はというと、「=」をつけて上げることで実現できます。

protected $signature = 'cron:test {--country=}';

値は、

echo $this->option('country');

として受けることができます。

同じくデフォルト値が必要な場合は

protected $signature = 'cron:test {--country=canada}';

とします。


コマンドの登録

では、最後に作成したコマンドを実際に使えるよう登録しましょう。
変更するファイルは以下になります。
app/Console/Kernel.php
このファイルの中の $commands という変数へ先ほどのコマンドを追加します。

実際にはこんなカンジです。

protected $commands = [
    \App\Console\Commands\Inspire::class,
    \App\Console\Commands\TestCommand::class,
];

※一つめの値は始めから記述されているものになります。

はい。
これでコマンドラインから実行ができるようになりました。
まず、一覧に表示されているかを確認してみましょう。

php artisan

おそらく

 cron
  cron:test             Send email

という形で表示がされていると思います。

では!
実際にあなたの独自コマンドを実行してみましょう。

php artisan cron:test

handle() に書かれたプログラムが実行できるのを確認できるはずです。


なお、コマンドに文字を表示するには echo() でも問題ありませんが、以下を利用すると見やすいので一度試してみてもいいかもしれません。

  • $this->line('テキスト');
  • $this->info('テキスト');
  • $this->error('テキスト');
上から、通常のテキスト、色付きテキスト、背景が赤のテキストとなります。


と今回はLaravelの独自コマンド作成をお届けしました。
皆さんのお役にたてれば幸いです(^^)







2016-03-29

【Blade】Laravelテンプレートの便利な書き方

昨日RedditのPHP板でテンプレートエンジンの話が出ていて興味をもったので、この際、Laravelのテンプレートエンジン「Blade」でできる便利な書き方を(@extends@sectionなどのメインは省いて)3つまとめてみました。




 1.「or」でチェックを省略ができる

もし変数に何も入っていない可能性がある場合、Blade内でPHP記法を使うと以下のようになります。
@if(isset($test))
    {{ $test }}
@else
    変数の中身がありません。
@endif
どの言語でもおなじみの if文ですね。
でもBladeを使うと上の5行がたった1行でできるようになります。
それが「or」です。
{{ $test or '変数の中身がありません。' }}
どうでしょう。
三項演算子を使うと1行でも書けなくはないですが、おそらくこちらの方がデザイン担当の人が見てもわかりやすいんじゃないでしょうか。
もちろん以下のようにいろんな変数名を指定できます。
{{ $blog->title or 'Default' }}


2.「forelse」でもチェックを省略できる

PHPで配列をひとつずつ取り出して計算をする際には for や foreach を使うと思います。
Blade でもこのループの書き方は同じで以下のようになります。
@if($posts->count() > 0)
    @foreach($posts as $post)
        {{ $post->title }}
    @endforeach
@else
    データが見つかりませんでした。
@endif
このケースではDBからデータを取得しているので count() を使ってデータが入っているのかをチェックしています。
なんだか少しゴチャゴチャしていますね。

これがBladeでは以下のように書くこともできます。
@forelse($posts as $post)
    {{ $post->title }}
@empty
    データが見つかりませんでした。
@endforelse
表示がスッキリしました。
「できるだけエラーを出さないためにはできるだけコードを書かないこと」という原則を考えるならこちらの方が断然方がいいですね。
もちろん、 foreach と 同じく、以下のようにインデックスも取得できます。
@forelse($posts as $index => $post)


3.各言語を呼び出す

これは日本語圏の環境では利用する機会は少ないかもしれませんが、翻訳された単語を取得する際、より省略した記述をすることができます。
Laravelでは trans() もしくは Lang::get() という2つの取得法があるため通常は以下のようになります。
{{ trans('validation.accepted') }}
{{ Lang::get('validation.accepted') }}

これがBladeではこう書くことができます。
@lang('validation.accepted')
文字数的にはそこまで差はありませんが、横のヒゲがなくなっているので可読性は上がっていると思います。

以上、短いですがBladeの便利な書き方でした。
ちなみに最近は Twig (←小枝という意味みたいです)という高機能なテンプレートエンジンも人気があるようですが、どうやらPHPのコードを直接追加できならしく、またBladeの方が軽いらしいので、私の場合はもし採用するとしてももう少し先になるかなーと思いました。

(それにしても、PhpStormから直接貼り付けるとコード部分が楽に作成できていいですね。^^)



2016-03-06

Laravel の独自パッケージを作成する「PackageCreator」を公開しました。

Laravelでの開発を行っていると「この機能はきっとまた必要になるときが来るはず!」という場面に多々出会います。
そんなときは独自パッケージを作りましょう。
Laravelの強みのひとつは「世界中のプログラマが作成した独自パッケージ」が利用できるという点にあると思います。

ただ、パッケージを作成するには「Laravel の独自パッケージを作成する手順 」 「Laravel 5 の独自パッケージを作成する手順 」でも紹介しましたが多少の労力が必要になります。
毎回やっているとこれはなかなかめんどくさかったりします。

そこで!
今回はこの独自パッケージに必要なファイルを自動で作成してくれる「PackageCreator」というLaravel用パッケージをGitHubで公開しました。
少しでもパッケージ開発が楽にできれば嬉しいです。
(今のところはLaravel 5+です。)

※追記・・・「package_creator」コマンドは「make:package」に入れ替わりました。(記事中の古いコマンドは全て修正されています)


■PackageCreator
https://github.com/SUKOHI/PackageCreator


ではインストール方法から。
PackageCreator 自体も Laravel の独自パッケージですので Composer でのインストールが可能です。
 composer require sukohi/package-creator:2.*  

次にサービス・プロバイダーを登録しましょう。
 Sukohi\PackageCreator\PackageCreatorServiceProvider::class,  

はい。
これで独自パッケージ生成のコマンド「php artisan make:package」が使えるようになっていると思います。


コマンドの使い方
 php artisan make:package (ベンダー名) (パッケージ名) (保存するフォルダ名)  

引数の説明

・ベンダー名: そのままベンダー名(あなたの名前)。必須。
・パッケージ名: 作成したいパッケージの名前。もし名前が複数の単語からできている場合はハイフンつなぎにしてください。必須
・保存するフォルダ名: パッケージを作成/保存する場所です。任意。デフォルトは packages

実際の例)
 php artisan make:package sukohi my-package test_packages  


オプション

--views

もし独自パッケージで view を使いたい場合はこのオプションを使ってください。


--publish

もし独自パッケージで publish 機能を付けたい場合はこのオプションを使ってください。


パッケージを生成するとその後どうすればいいかが表示されますのでその指示に従ってください。
後はController などからこんな感じアクセスすることができます。
↓↓↓

MyPackage::test();


ちなみにパッケージの開発手法は「Developing your packages in Laravel 5」を参考にしたものです。感謝!

以上です。
できればそのうち独自パッケージを公開する方法もブログ記事にしたいと思っています。
Let's develop! ^^


2016-01-31

PHPでユーザー管理するならSentinelが便利すぎる!

カナダからの帰国後気持ち的にも少し落ち着いてきたので、ここいらでよく利用しているパッケージの使い方を再度おさらいしようというモチベーションが(なぜか)高まってきました。
そこで、今回は機能が豊富でとても使いやすいユーザー管理パッケージ「Sentinel」をご紹介したいと思います。



【Sentinelの感想】まさにかゆいところに手が届く感謝感激のパッケージです!


1.まずは主な特徴
  • ログイン/ログアウト(当たり前ですけど^-^;)
  • ユーザーに役割をもたせられる
  • パスワードリマインダー機能
  • パスワードを自動で暗号化して保存
  • ユーザー登録時のアクティベーション機能(選択可)
  •  ユーザー名(姓と名)をデフォルトで保存可能
などなど。
あとは私の大好物、Laravelにも対応しています。(バージョン>=5.0)


2.次にインストール

PHPの自動パッケージ管理システム composer でインストールします。
composerは便利すぎて一度使うとやめられませんね(笑)
こんなカンジです。
composer require cartalyst/sentinel "2.0.*"

3-1.初期設定(Laravel)

Laravelで利用するには、app.php の中にある providers へ ServiceProviderを追加。
 'providers' => [  
   Cartalyst\Sentinel\Laravel\SentinelServiceProvider::class,  
 ]  
aliases へ以下3つを追加
  'aliases' => [  
     'Activation' => Cartalyst\Sentinel\Laravel\Facades\Activation::class,  
     'Reminder'  => Cartalyst\Sentinel\Laravel\Facades\Reminder::class,  
     'Sentinel'  => Cartalyst\Sentinel\Laravel\Facades\Sentinel::class,  
 ]  
あとは、データベースにテーブルを作成して完了です。
便利なので migration で一気に作成しましょう。

※注意

DBテーブル名の衝突をさけるためにデフォルトで存在する「users」作成マイグレーションは事前に削除するかプログラム部分をコメントアウトしておきましょう。
私の環境では「2014_10_12_000000_create_users_table.php」でした。

(1)Publish でmigrationファイルをパッケージからコピー
php artisan vendor:publish --provider="Cartalyst\Sentinel\Laravel\SentinelServiceProvider"
(2)Migration 実行
php artisan migrate

3-2.初期設定(Laravel以外)

illuminate/database パッケージがあれば通常のPHPからでも利用できるようです。
(ただし、この部分は検証していません。なにぶんLove Laravelなもので、、、^^;)
composer require illuminate/database
でインストールして以下のように設定をします。

(以下本家ページからの引用)
 // 必要なクラスをインポート
 use Cartalyst\Sentinel\Native\Facades\Sentinel;  
 use Illuminate\Database\Capsule\Manager as Capsule;

 // autoloadを読み込む
 require 'vendor/autoload.php';

 // Eloquent Capsule インスタンスを生成
 $capsule = new Capsule;  
 $capsule->addConnection([  
   'driver'  => 'mysql',  
   'host'   => 'localhost',  
   'database' => 'sentinel',  
   'username' => 'user',  
   'password' => 'secret',  
   'charset'  => 'utf8',  
   'collation' => 'utf8_unicode_ci',  
 ]);  
 $capsule->bootEloquent();  
そして、DBの構造はこんな感じです。
 CREATE TABLE IF NOT EXISTS `activations` (  
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,  
  `user_id` int(10) unsigned NOT NULL,  
  `code` varchar(255) COLLATE utf8_unicode_ci NOT NULL,  
  `completed` tinyint(1) NOT NULL DEFAULT '0',  
  `completed_at` timestamp NULL DEFAULT NULL,  
  `created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',  
  `updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',  
  PRIMARY KEY (`id`)  
 );  
 CREATE TABLE IF NOT EXISTS `persistences` (  
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,  
  `user_id` int(10) unsigned NOT NULL,  
  `code` varchar(255) COLLATE utf8_unicode_ci NOT NULL,  
  `created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',  
  `updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',  
  PRIMARY KEY (`id`),  
  UNIQUE KEY `persistences_code_unique` (`code`)  
 );  
 CREATE TABLE IF NOT EXISTS `reminders` (  
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,  
  `user_id` int(10) unsigned NOT NULL,  
  `code` varchar(255) COLLATE utf8_unicode_ci NOT NULL,  
  `completed` tinyint(1) NOT NULL DEFAULT '0',  
  `completed_at` timestamp NULL DEFAULT NULL,  
  `created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',  
  `updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',  
  PRIMARY KEY (`id`)  
 );  
 CREATE TABLE IF NOT EXISTS `roles` (  
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,  
  `slug` varchar(255) COLLATE utf8_unicode_ci NOT NULL,  
  `name` varchar(255) COLLATE utf8_unicode_ci NOT NULL,  
  `permissions` text COLLATE utf8_unicode_ci,  
  `created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',  
  `updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',  
  PRIMARY KEY (`id`),  
  UNIQUE KEY `roles_slug_unique` (`slug`)  
 );  
 CREATE TABLE IF NOT EXISTS `role_users` (  
  `user_id` int(10) unsigned NOT NULL,  
  `role_id` int(10) unsigned NOT NULL,  
  `created_at` timestamp NULL DEFAULT NULL,  
  `updated_at` timestamp NULL DEFAULT NULL,  
  PRIMARY KEY (`user_id`,`role_id`)  
 );  
 CREATE TABLE IF NOT EXISTS `throttle` (  
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,  
  `user_id` int(10) unsigned DEFAULT NULL,  
  `type` varchar(255) COLLATE utf8_unicode_ci NOT NULL,  
  `ip` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,  
  `created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',  
  `updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',  
  PRIMARY KEY (`id`),  
  KEY `throttle_user_id_index` (`user_id`)  
 );  
 CREATE TABLE IF NOT EXISTS `users` (  
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,  
  `email` varchar(255) COLLATE utf8_unicode_ci NOT NULL,  
  `password` varchar(255) COLLATE utf8_unicode_ci NOT NULL,  
  `permissions` text COLLATE utf8_unicode_ci,  
  `last_login` timestamp NULL DEFAULT NULL,  
  `first_name` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,  
  `last_name` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,  
  `created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',  
  `updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',  
  PRIMARY KEY (`id`),  
  UNIQUE KEY `users_email_unique` (`email`)  
 );  


4.基本的な使い方

さあ、ではやっと実際の使い方です。
おそらくSentinelは直感的に使えると思います。

1.新規ユーザーの追加
 $credentials = [  
   'email'  => 'taro.yamada@example.com',  
   'password' => 'password',  
   'first_name' => '太郎',  // 省略可
   'last_name' => '山田'  // 省略可
 ];  
 $user = Sentinel::registerAndActivate($credentials);  
これだけでOK!
パスワードは自動的に暗号化されているのでセキュリティにも強くなっています。

  • 必要がない場合は「first_name」「last_name」は省略できます。
  •  「メール送信→URLをクリックで本登録」という流れにしたい場合は「6.アクティベーション」を参照してください。

2.ログイン
 $credentials = [  
   'email'  => 'taro.yamada@example.com',  
   'password' => 'password',  
 ];  
 $user = Sentinel::authenticate($credentials);  
もし次からのログインを省略する場合は以下のように第二引数に true をセットします。
 Sentinel::authenticate($credentials, true);   

3.ユーザーの取得

(1)IDから取得
 $user = Sentinel::findById(1);  
(2)メールアドレスから取得
 $credentials = [  
   'login' => 'taro.yamada@example.com',  
 ];  
 $user = Sentinel::findByCredentials($credentials);  
あとは、Persistence code  などからでもユーザーを取得できるようです。


4.ユーザー情報の変更/削除

変更は update() を使います。
 $user = Sentinel::findById(1);  
 $credentials = [  
   'email' => 'new.taro.yamada@example.com',  
   'password' => 'new_password',  
   'first_name' => '二郎',  
   'last_name' => '鈴木'  
 ];  
 $user = \Sentinel::update($user, $credentials);  
削除は delete() です。
 $user = Sentinel::findById(1);  
 $user->delete();  


5.役割の設定

Sentinel では、例えば
  • Aさん → 管理者
  •  Bさん → 一般ユーザー
というようにログインする人たちに役割を設定することができます。

(1)新しい役割を追加する
 $role = Sentinel::getRoleRepository()  
   ->createModel()  
   ->create([  
     'name' => '管理者',  
     'slug' => 'admin'  
  ]);  
(2)役割をユーザーに割り当てる/解除する
 $user = Sentinel::findById(1);  
 $role = Sentinel::findRoleByName('管理者');  
 $role->users()->attach($user);  // 割り当てる  
 $role->users()->detach($user);  // 割り当てを解除する  
(3)役割を取得
 $role = Sentinel::findRoleById(1);  // ID
 $role = Sentinel::findRoleBySlug('admin');  // Slug(ユニークIDみたいなもの)  
 $role = Sentinel::findRoleByName('管理者');  // 役割の名前

6.アクティベーション

サイトによっては、ユーザー登録をするときまず「本登録URL」をメール送信し、そのURLがクリックされた時点で本登録するという流れが必要な場合があると思います。
アクティベーションはこの機能を実現するため利用できます。

(1)本登録コードの取得
 $user = \Sentinel::register([  
   'email'  => $email,  
   'password' => 'password'  
 ]);  
 $activation = \Activation::create($user);  
 $activation_code = $activation->code;  
$activation_code に本登録に必要なコードが入っていますので、このコードを使って
http://example.com/activation/****************************************
のような本登録のURLを作成することができます。

(2)本登録を実行
 $user = Sentinel::findById(1);  
 if (Activation::complete($user, '本登録コード'))  
 {  
   // 本登録完了!
 }  
 else  
 {  
   // 失敗,,,
 }  
※ちなみに本登録していない状態でログインを試みると「NotActivatedException」エラーが帰ってきます。


7.パスワード・リマインダー

ユーザーがパスワードを忘れたときに利用する再発行の機能です。

(1)リマインダー・コードを取得する
 $user = \Sentinel::findById(1);  
 $reminder = \Reminder::create($user);  
 $reminder_code = $reminder->code;  
(2)新パスワードの設定
 $user = Sentinel::findById(1);  
 if ($reminder = Reminder::complete($user, 'リマインダー・コード', '新パスワード'))  
 {  
   // 成功!
 }  
 else  
 {  
   // 失敗,,,
 }  

ということで少し長くなってしまいましたが、Sentinelの主な機能は以上です。他にもまだいくつか機能がありますが、それはまたの機会ということで ^-^
ではでは〜。



Thank you, Cartalyst.
Sentinel is a great package!

2015-08-26

Laravel 5 の独自パッケージを作成する手順

少し前に第二の故郷、カナダのバンクーバーでの生活が始まり、最近は少し落ち着いてきたので、そろそろLaravel5(現在5.1)を見据えた活動をしていきたいと考えています。
ということで、今回はLaravel 5 の独自パッケージを作る手順を今回も備忘録的にお届けしたいと思います。

※ここでの開発手順を自動でやってくれるパッケージ「PackageCreator」を公開しました。詳しくは以下のページをご覧ください。
Laravel の独自パッケージを作成する「PackageCreator」を公開しました。





[結論] おそらく自由度が上がった分、より根本を理解する必要がでてきたなー、という印象です。


まず、前提として

1.Laravel 5以上(私の場合は5.1)がインストールされていること。
2.composer がインストールされていること。

として話を進めます。


では!
実際にパッケージの作成に移りましょう。
手順は以下の6点です。

1.パッケージ開発をするためのフォルダ構造を作成
2.composer.json を作成
3.Rootフォルダ直下にある composer.json にパッケージを追加
4.ServiceProvider を作成
5.パッケージのクラス本体を作成
6.ServiceProvider を登録






1.パッケージ開発をするためのフォルダ構造を作成


まずパッケージを開発するためのフォルダを作成します。

(Laravel5のフォルダ)/packages/Vendor/Package/src


※便宜上、ベンダー名には「Vendor」、パッケージ名は「Package」として説明します。
そのため、もしあなたの開発者名が「Sukohi」で、これから開発する独自パッケージが「Own」の場合は「(Laravel5のフォルダ)/packages/Sukohi/Own/src」となります。


2.composer.json を作成


1番で作成した (Laravel5のフォルダ)/package/Vendor/Package へコマンドで移動し、

composer init

を実行してください。色々と質問を聞かれるので自分にあった情報を打ち込み composer.json を作成します。

※composer.json は後でエディタで変更可能ですので、あまり深く考える必要はありません。


3.Rootフォルダ直下にある composer.json にパッケージを追加

以下のように「autoload/psr-4」内に独自パッケージのネームスペースとパスを追加します。

"autoload": {
    "psr-4": {
        "App\\": "app/",
        "Vendor\\Package\\": "packages/Vendor/Package/src"
    }
}
※もちろんカンマで区切ることで複数のパッケージを指定できます。



4.ServiceProvider を作成

(Laravel5のフォルダ)/packages/Vendor/Package/src」 内に PackageServiceProvider.php を作成し、以下をコピペする。

<?php namespace Vendor\Package;

use Illuminate\Support\ServiceProvider;

class PackageServiceProvider extends ServiceProvider {

    /**
     * Indicates if loading of the provider is deferred.
     *
     * @var bool
     */
    protected $defer = true;

    /**
     * Bootstrap the application events.
     *
     * @return void
     */
    public function boot()
    {
        //
    }

    /**
     * Register the service provider.
     *
     * @return void
     */
    public function register()
    {
        $this->app['package'] = $this->app->share(function($app)
        {
            return new Package;
        });
    }

    /**
     * Get the services provided by the provider.
     *
     * @return array
     */
    public function provides()
    {
        return ['package'];
    }

}

※実際には  を以下のようにあなたのベンダー名とパッケージ名に置き換える必要があります。

PackageServiceProvider ・・・ (独自パッケージ名)ServiceProvider
package ・・・ (独自パッケージ名)
Vendor ・・・ (あなたの開発者名)


※独自に view を利用する場合は boot() 内に「loadViewsFrom()」で読み込みができます。
※独自にpublishする必要がある場合は同じく boot() 内で publishes() を使う。

詳しくはこちら
↓↓↓

Resources
Publishing File Groups


5.パッケージのクラス本体を作成

以下のようにネームスペース付きでクラスを作成

<?php namespace Vendor\Package;

class Package {

    // ここにプログラムを作成

}

6.ServiceProvider を登録


(Laravel5のフォルダ)/config/app.php に、


(i)ServiceProvider を登録

    'providers' => [

        // その他のServiceProvider

        /*
         * Package Service Providers
         */

        Vendor\Package\PackageServiceProvider::class,

    ],
(ii)エイリアスを登録

    'aliases' => [

        'Package'       => Illuminate\Support\Facades\Package::class,

    ]


(iii)コマンドラインでルートフォルダへ移動し、以下のコマンドを実行

composer dumpautoload -o


はい!
これで Controller 内などから

 Package::something();

という形で独自パッケージを呼び出すことができます。


[参考ページ](参考というかほぼ全体的に訳しただけです^-^;)

https://laracasts.com/discuss/channels/tips/developing-your-packages-in-laravel-5

Thank you, davidxd33!
Your tip helped me out. :)))



■おまけ(Laravel5.1に関して)

※これからは実際に Laravel 5.1を使って開発をしていきたいと考えています。だけど、5.1は要件がPHP5.5.9以上ということもあり、いわゆるレンタルサーバーと呼ばれる環境では使えるようになるにはまだまだ時間がかかりそうってとこがネックになりそうですねー。


以上です。
おつかれさまでした!



2014-10-09

Laravelでローカリゼーションするなら「Translation Manager」がすごく便利!(多言語翻訳ファイルも紹介してます)

さて今回はLaravelのローカリゼーションに関する便利なパッケージを発見したので備忘録として使い方+αをお届けしたいと思います。

実際少し前にLaravelを英語と日本語でローカリゼーションする機会があったのですが、この作業が地味に大変なんです。

つまり、英語のファイルと日本語のファイルが(もちろん)別れているため、一回一回キーを追加したり探したりする必要があります。

いつか自分で管理パッケージをつくろうかと思っていたらやはり先に同じことを考えている人がいたようですね。
さすがはLaravelです。^-^


出典:M. Adiputra


最終結論: ローカリゼーションが必要でなくてもバリデーション用にも使えるパッケージでした!


まず今回使わせていただくパッケージの紹介から。

barryvdh/laravel-translation-manager

※この作者は他にも「laravel-debugbar」や「laravel-ide-helper」などの有名なパッケージを作成しているようですね。心から感謝です。m_ _m



では、早速インストールしましょう。

Laravelをインストールしたフォルダ直下にある「composer.json」を開いて以下のように require にパッケージを追加します。

composer.json

"require": {
(その他のパッケージ),
"barryvdh/laravel-translation-manager": "0.1.x"
},


そして、コマンドから `compser update` を実行しましょう。
自動でパッケージがインストールされます。


そして、パッケージを使えるように設定をします。

app/config/app.php

'providers' => array( (その他のパッケージ),  'Barryvdh\TranslationManager\ManagerServiceProvider',
),
※追記

すみません。migrationする作業が抜けていました。T_T
以下を実行してDBに専用テーブルを作成してください。

php artisan migrate --package="barryvdh/laravel-translation-manager"


つぎに通常のパッケージインストールではあまり使わない以下のコマンドを実行してパッケージ内にある config ファイルをLaravel本体へコピーします。

php artisan config:publish barryvdh/laravel-translation-manager

※注: なぜかわかりませんが、私の場合存在するはずの 


vendor/barryvdh/laravel-translation-manger/src/config/
vendor/barryvdh/laravel-translation-manger/src/config/config.php

が見つかりませんでした。
もし同じことが発生していたら configフォルダを作成し、その中にconfig.php をコピペしてください。


そして、 app/routes.php に

Route::group(array('before' => 'auth_admin'), function() {
    Route::controller('translations', 'Barryvdh\TranslationManager\Controller');
});

を追加すると、http://***.com/translations にアクセスできるようになります。


※もし本番環境で表示したくない場合は、App::isLocal() などを使って場合分けをしたほうがいいですね。



使い方

※まだ app/lang/ja を作っていない場合はフォルダを作成しましょう。


まず、画像にある「import groups」をクリックしましょう。すでに「lang」登録されている単語を抽出します。



それが完了したら、ページを再読み込みすれば以下のようにどのファイルを編集するかを選択できるようになりますのでクリックしましょう。


あとは単語一覧が表示されるので個別に編集していくだけです。
(※まだファイル自体には反映されてません次の「ファイルへの反映」をみてください)




ファイルへの反映

ページには「publish translations」ボタンを押すとファイルに反映されると書いてますが実際はできなかった(おそらく権限を変更すればいけるのかな?)のでもうひとつの方法である「コマンドでの反映」をご紹介します。

コマンドでLaravelをインストールしているフォルダへ移動し、

php artisan translation:export ***

を実行しましょう。
言語ファイルに変更が反映されます。


※ ***は .phpをぬいたファイル名。例えば「messages」「validation」です。


はい!
ということで Translation Manager の紹介は終了です。


おまけ

世界各国の翻訳データを集めたファイルが以下のページからダウンロードできます。
もし、サイト内容が日本だけでなく世界に向けたものなら言語ファイルだけでも追加しておいて損はしないかもしれませんね。

https://github.com/caouecs/Laravel4-lang



Thank you barryvdh and caouecs!
You guy's works must save my time when developing websites.:)))

2014-10-01

Laravel の独自パッケージを作成する手順

ここのところ多忙のためブログ投稿をサボってしまっていますが、Laravel(CakePHP)は常に触っていて、知れば知るほどその便利さがよくわかっきている今日このごろです。

さて、そんな多忙な中なのになぜブログ投稿をするのか?というと今はクライアント様の判断待ちで、さらにタイトルにある独自パッケージの作成方法を備忘録として残しておきたかったからです。

以前作成したこがあるのにやることが多くて忘れてしまっていました(汗)
ということで今回はLaravelの独自パッケージの作成法をまとめてみたいと思います。


[最終結論] Laravel 5.0ではもっと楽にできればいいなー^^


では、早速作業を開始しましょう。
前提としまして、パッケージの名前は、

sukohi/hoge

として話をすすめていきます。
これは、「ベンダー名(あなたの名前)/パッケージ名」になります。

では、ターミナルを開いて Laravelがインストールされている場所(artisanのあるフォルダ)まで移動して以下を実行してください。

php artisan workbench sukohi/hoge --resources


実行が完了すると、

laravel
├ app
├ bootstrap
├ public
├ vendor
└ workbench

という形で workbench フォルダが作成されています。
では、この中にある以下のフォルダを開きましょう。

laravel/workbench/sukohi/hoge/src/Sukohi/Hoge/

このフォルダで独自クラスの作成&「HogeServiceProvider.php」の設定をします。

では、独自クラスを作成しましょう。このサンプルでは「Hoge.php」です。
フォルダ構成は以下のようになります。


Sukohi
 └ Hoge
   ├ Hoge.php
   └ HogeServiceProvider.php


そして、このHoge.php 内にご自身でやりたいことができるようプログラムを作成しましょう。
書き方は通常のPHPクラスとまったく同じですが、クラス名とファイル名は同じにする必要があります。また、ネームスペースをいれることにも注意してください。


(Hoge.php)

<?php namespace Sukohi\Hoge;

class Hoge {

    // Something...

}


では、次に「HogeServiceProvider.php」の設定を見ていきましょう。
やることは2つ。
register() と provides() メソッドにそれぞれ決まり文句を追加するだけです。

1.register()

 public function register()
  {
  $this->app['hoge'] = $this->app->share(function($app)
  {
   return new Hoge;
  });
  }

※「hoge」「Hoge」はあなたのパッケージ名に置き換えてください。


2.provides() 

 public function provides()
 {
  return array('hoge');
 }


はい。
これでここの作業は終了です。


では、次に以下のような形でクラスを呼び出せるように Facades を作成しましょう。

Hoge::method();

HogeServiceProvider.phpがあるフォルダに「Facades」というフォルダを作成し、さらにその中に「Hoge.php」を作成してください。
フォルダ構成は以下のようになります。

Sukohi
 └ Hoge
   ├ Facades 
   ├ Hoge.php
   └ HogeServiceProvider.php

そして Hoge.phpの中に以下のプログラムを書き込みましょう。


<?php namespace Sukohi\Hoge\Facades;

use Illuminate\Support\Facades\Facade;

class Hoge extends Facade {

  /**
   * コンポーネントの登録名を取得
   *
   * @return string
   */
  protected static function getFacadeAccessor() { return 'hoge'; }

}

※太字の部分がベンダー名とパッケージ名になります。大文字/小文字に気をつけてください。



では、次に Laravel からこのパッケージを呼び出せるように設定しましょう。
(いつものパッケージを composer からインストールしたときの手順と同じです。^-^)

Laravel/app/config/app.php 

を開いて、配列の providers の最後に「HogeServiceProvider」を登録し、

'providers' => array(

 (他のパッケージ), 
 'Sukohi\Hoge\HogeServiceProvider', 

),


さらに同じファイルにある「エイリアス」も設定します。


'aliases' => array(

 (他のパッケージ), 
  'Hoge' => 'Sukohi\Hoge\Facades\Hoge',

),


はい!
これでパッケージが完成しました。
もしエラーがでるようなら、フォルダの階層がまちがっていないか(←これは私のことです^^)、もしくは composer dump-autoload 、 composer update などをするとうまくいくことがあるようです。

ということで少し複雑でしたが、独自パッケージを作成手順でした。
ちなみに、フリーランスとしてプログラムの著作権をすべて渡してしまう約束の場合、こういったパッケージの開発は私はしません。全部持って行かれるのが悔しいパッケージは後のことを考えると便利ですが作成するのに少し時間がかかるので。(笑)
なので、プロジェクトとは別でゼロからパッケージを作成するようにしています。
でも、これってプロジェクトにとってもマイナスなんだけどなー。。。
この辺みんなはどうしてるんでしょう?

とにかくお疲れ様でした。



[参考ブログ(というかほぼ訳しただけ)]

http://culttt.com/2013/06/24/creating-a-laravel-4-package/

Thank you the author(s) of Culttt.com.
Your tip is really useful!
So I've just followed your twitter. :)))