20190301のlaravelに関する記事は7件です。

LaravelでSlackのSlash Commandを複数使う

はじめに

前回の記事で、Laravel Slack Slash Commandの大まかな説明をした。
インストールや簡単な使い方などを説明しているので、読んでいない人はそちらを先に読んでほしい。
今回は、複数のコマンドを扱う方法について説明する。

今回の目標

スクリーンショット 2019-03-01 20.05.49.png
と送信すると、
スクリーンショット 2019-03-01 20.08.55.png
と応答してくれる。


スクリーンショット 2019-03-01 20.06.31.png
と送信すると、
スクリーンショット 2019-03-01 20.06.43.png
と応答してくれる。

Slack側の設定

スクリーンショット 2019-03-01 20.11.52.png
こんな感じで、2つのコマンド/hello/how-are-you?を用意する。

/hello

スクリーンショット 2019-03-01 20.20.32.png

/how-are-you?

スクリーンショット 2019-03-01 20.20.50.png

2つのコマンドで、1つのURLを共有している。

Laravel側の設定

今回の一番悩ましいところは、2つのトークンをどう記述するかだ。
トークンは前回同様、config/laravel-slash-command.phpに記述する。
結論から言うと、トークンは配列で記述すると良い。

config/laravel-slash-command.php
<?php

return [

  /*
   * At the integration settings over at Slack you can configure the url to which the
   * slack commands are posted. Specify the path component of that url here.
   *
   * For example `http://example.com/slack` you would put `slack` here.
   */
  'url' => 'slack',

  /*
   * The token generated by Slack with which to verify if a incoming slash command request is valid (deprecated).
   */
  'token' => ['/helloのトークン', '/how-are-you?のトークン'],      //コマンドのトークンを配列で記述する

  /*
   * The signing_secret generated by Slack with which to verify if a incoming slash command request is valid.
   */
  'signing_secret' => env('SLACK_SIGNING_SECRET'),

  /*
   * Verify requests from slack with signing_secret signature
   */
  'verify_with_signing' => false,

  /*
   * The handlers that will process the slash command. We'll call handlers from top to bottom
   * until the first one whose `canHandle` method returns true.
   */
  'handlers' => [
      //add your own handlers here
      App\SlashCommandHandlers\Hello::class,             //コマンド/helloの処理を書くクラス
      App\SlashCommandHandlers\HowAreYou::class,       //コマンド/how-are-you?の処理を書くクラス

      //this handler will display instructions on how to use the various commands.
      Spatie\SlashCommand\Handlers\Help::class,

      //this handler will respond with a `Could not handle command` message.
      Spatie\SlashCommand\Handlers\CatchAll::class,
  ],
];

つまり、今後コマンドを増やしたかったら、そのトークンを配列に入れていけば良いわけだ。
とっても楽で便利である。
前回はenv関数を使っていたが、それだと複数のトークンを扱えないのだ。

なぜ配列で記述できるのか?

$ php artisan route:list
を実行すると、その中に
スクリーンショット 2019-03-01 21.03.49.png
があるように、
/slackにslackからリクエストがPOSTされると、画像にあるコントローラーのメソッドが呼ばれる事がわかる。
Spatieのgithubか、下記のファイルを確認する。

vender/spatie/laravel-slack-slash-command/src/Controller.php
//該当する部分のみを抜き出している
class Controller extends IlluminateController
{
    /** @var \Spatie\SlashCommand\Request */
    protected $request;

    /** @var \Illuminate\Support\Collection */
    protected $config;

    public function __construct(IlluminateRequest $request, Repository $config)
    {
        $this->request = Request::createFromIlluminateRequest($request);
        $this->config = collect($config->get('laravel-slack-slash-command'));
    }

    public function getResponse(IlluminateRequest $request): IlluminateResponse
    {
        $this->guardAgainstInvalidRequest($request);

        $handler = $this->determineHandler();

        try {
            if ($handler instanceof SignatureHandler) {
                $handler->validate();
            }
            $response = $handler->handle($this->request);
        } catch (SlackSlashCommandException $exception) {
            $response = $exception->getResponse($this->request);
        } catch (Exception $exception) {
            $response = $this->convertToResponse($exception);
        }

        return $response->getIlluminateResponse();
    }

    protected function guardAgainstInvalidRequest(IlluminateRequest $request)
    {
        if ($this->config->get('verify_with_signing')) {
            $this->verifyWithSigning($request);
        } else {
            $this->verifyWithToken($request);
        }
    }

    protected function verifyWithSigning(IlluminateRequest $request)
    {
        $signature = app(RequestSignature::class)->create($request);

        if ($request->header('X-Slack-Signature') !== $signature) {
            throw InvalidRequest::invalidSignature($signature);
        }
    }

    protected function verifyWithToken(IlluminateRequest $request)
    {
        if (! $request->has('token')) {
            throw InvalidRequest::tokenNotFound();
        }

        $validTokens = $this->config->get('token');

        if (! is_array($validTokens)) {
            $validTokens = [$validTokens];
        }

        if (! in_array($this->request->get('token'), $validTokens)) {
            throw InvalidRequest::invalidToken($this->request->get('token'));
        }
    }

いま、
$this->config->get('token')config/laravel-slack-slash-commandに書いたトークン
$this->request->get('token') → slack command の設定時に、slack側から発行されたトークン
となっている。

関数verifyWithTokenでは、$this->config->get('token')$validTokensとした上で、

if (! is_array($validTokens)) {
   $validTokens = [$validTokens];
}

$validTokensが配列じゃないなら配列にするという処理を行っている。
その後、

if (! in_array($this->request->get('token'), $validTokens)) {
   throw InvalidRequest::invalidToken($this->request->get('token'));
}

$this->request->get('token')が配列$validTokensの中に存在するかを調べている。

つまり、config/laravel-slack-slash-commandに記述するトークンは、最初から配列でも構わない。
というか、こんな処理を行うなら、配列で書くように示してくれれば良いのに…。

ちなみにだが、関数getResponse内の
$this->guardAgainstInvalidRequest($request);を消してしまえば、トークンの照合を行わないのだ。
そんなことしちゃだめだぞ。絶対だからな。絶対だぞ。

classの書き方

app/SlashCommandHandlers/Hello.php
<?php
namespace App\SlashCommandHandlers;

use Spatie\SlashCommand\Request;
use Spatie\SlashCommand\Response;
use Spatie\SlashCommand\Handlers\BaseHandler;

class Hello extends BaseHandler
{
    /**
     * If this function returns true, the handle method will get called.
     *
     * @param \Spatie\SlashCommand\Request $request
     *
     * @return bool
     */
    public function canHandle(Request $request): bool
    {
        return $request->command == 'hello';
    }

    /**
     * Handle the given request. Remember that Slack expects a response
     * within three seconds after the slash command was issued. If
     * there is more time needed, dispatch a job.
     *
     * @param \Spatie\SlashCommand\Request $request
     *
     * @return \Spatie\SlashCommand\Response
     */
    public function handle(Request $request): Response
    {
        return $this->respondToSlack("Hello! I'm Laravel Slack Slash Command.");
    }
}
app/SlashCommandHandlers/HowAreYou.php
<?php
namespace App\SlashCommandHandlers;

use Spatie\SlashCommand\Request;
use Spatie\SlashCommand\Response;
use Spatie\SlashCommand\Handlers\BaseHandler;

class HowAreYou extends BaseHandler
{
    /**
     * If this function returns true, the handle method will get called.
     *
     * @param \Spatie\SlashCommand\Request $request
     *
     * @return bool
     */
    public function canHandle(Request $request): bool
    {
        return $request->command == 'how-are-you?';
    }

    /**
     * Handle the given request. Remember that Slack expects a response
     * within three seconds after the slash command was issued. If
     * there is more time needed, dispatch a job.
     *
     * @param \Spatie\SlashCommand\Request $request
     *
     * @return \Spatie\SlashCommand\Response
     */
    public function handle(Request $request): Response
    {
        return $this->respondToSlack("I'm good!");
    }
}

クラスの細かい解説は前回の記事に詳しく書いたので省略する。
関数canHandleで条件分岐を行っている感じだ。

おわりに

仕組みを理解できれば、今後簡単にコマンドを増やすことができるだろう。
ご質問があればいつでもどうぞ。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Laravel5基本機能Tips&ブロックチェーン

概要

目的:MVCのWebアプリケーション開発用のオープンソースであるLaravelについて基本機能を調査して記録した。今後、マイニング機器を使用して得られた採掘結果の欲しい情報をAPIなどからバックエンドで取得し見やすいUIにまとめグラフ化する予定である。

開発環境

-PHP5
-MySQL
-laravel5
- ローカル
- mac osx
- (XAMPP)
- Vscode
- 未定:リモートレンタルサーバー(AWS)、Docker
ーNanoppol API

主な参照記事:Laravel5 入門 インストールからMVCの基本機能をさっと眺める
[リンク](https://blog.hrendoh.com/getting-start-and-overview-of-laravel5/)

1 インストール&ローカル環境構築手順(Windows、Mac)
2 ルーティング
3コントローラー
4 ビュー
 4.1 基本的なビューの呼び出し方
 4.2 Bladeテンプレート
 4.3 Asset
5データベース操作
 5.1 接続設定
 5.2 モデル (ORM)
 5.3 マイグレーション
 5.4 モデルの利用
6 テスト
 6.1 データベースを利用するテスト
 6.2 テストデータベースのマイグレーション
7 標準機能について
 7.1Authについて
 7.2 使用可能なライブラリについて
 7.3 JavaScriptフレームワークについて(Vue.jsなど)

8  その他
 8.1 よく使うコマンドや実装について
         

1 インストール&ローカル環境構築手順(Windows、Mac)

   Laravel プロジェクトの作成

  Laravelインストール手順は、上記の手順を参照

$ composer create-project laravel/laravel --prefer-dist
<project name>

  
$ php artisan serve
Laravel development server started on http://localhost:8000/

artisanコマンドは、 Artisan CLI Usage を参照。artisan listで使用可能なコマンドは右のコマンドで確認できる。

$ php artisan list

2ルーティング

  ルーティングは app/Http/routes.php に記述する

// app/Http/routes.php

<?php
Route::get('/', 'WelcomeController@index');

   上記は、プロジェクトの作成後のデフォルト、’/’を
   WelcomeControllerの indexメソッドにマッピングしている

3コントローラー

コントローラーは、app/Http/Controllersに
App\Http\Controllers\Controllerを継承するクラスを置く
artisanコマンドでもコントローラーを生成可能
$ php artisan make:controller ArticleController
生成されるコントローラーはRestfullなリソースアクセスを提供する
RESTful Resource Controllers

4 ビュー

基本的なビューの呼び出し方
概要は、The BasicsのViews を参照
ビューのファイルは、resources/viewsに置く
ビューへ渡すデータは、view関数の第二引数に渡す
return view('greeting', ['name' => 'James']);
ビュー側は以下のように、渡されたマップのキーで値を参照できる

// resources/views/greeting.php
<html>
<body>
<h1>Hello, <?php echo $name; ?></h1>
</body>
</html>

resources/viewsのサブディレクトリに配置したビューの呼び出しは、以下のようにドットで連結して呼び出す(‘/’でも呼び出せる)

return view('article.create');

Asset

Laravel5 では、CSS、JavascriptをビルドするGulp タスク Laravel Elixir が標準で提供されている
プロジェクト直下のgulpfile.jsを見てみると、resources/assets/less/app.lessをビルドするタスクがはじめから設定されている

    // gulpfile.js
var elixir = require('laravel-elixir');

elixir(function(mix) {
mix.less('app.less');
});

npm実行環境とgulpをインストールして、プロジェクト直下にて以下のコマンドを実行する

$ npm install

開発中はgulp watchしておけば、lessの修正が自動で反映される

$ gulp watch

5 データベース操作

Basic Database Usage の Configuration によると対応データベースは、
MySQL, Postgres, SQLite, SQL Server と豊富
参照URL:laravel データベースの接続、マイグレーションによる

テーブル作成
https://qiita.com/ryo2132/items/a1c8119b00799d3aed00
LaravelでMAMPのMySQLに接続する
https://qiita.com/kei4eva4/items/480448b83df25774fc74

接続設定

データベースへの接続設定は、config/database.phpに記述する
Laravelのルートディレクトリ.envがあり、環境ごとの設定はこちらに記述
Environmentの設定については、LaravelはDotEnv PHPを利用する
MySQLを使用し Read/Write接続を分けない場合は、config/database.phpではなく.envに接続情報を記述する
デフォルトは以下の.env.exampleがインストール時に.envにコピーされる
(homesteadは、MySQLが.env.exampleの内容に合わせてセットアップ済み)

// .env

APP_ENV=local
APP_DEBUG=true
APP_KEY=SomeRandomString

DB_HOST=localhost
DB_DATABASE=homestead
DB_USERNAME=homestead
DB_PASSWORD=secret

CACHE_DRIVER=file
SESSION_DRIVER=file
QUEUE_DRIVER=sync

MAIL_DRIVER=smtp
MAIL_HOST=mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null

参考: Laravel 5.0 – Environment Detection & Environment Variables
モデル (ORM)

Laravelには、Eloquent ORMというActiveRecord実装がある
モデル生成の artisan コマンドが用意されている

$ php artisan make:model Article

app直下に以下のBlog.phpが生成される

// app/Blog.php

 `<?php

  namespace App;

 use Illuminate\Database\Eloquent\Model;

  class Article extends Model
 {
  //
  }

$tableプロパティに明示的にテーブル名を指定していないので、
このArticleクラスの場合は、articlesテーブルにアクセスする

マイグレーション

上記のArticleモデルを保存するarticlesテーブルを追加する
マイグレーションを作成する場合、以下のように

 artisan mke:migration コマンドを実行する
 $ php artisan make:migration create_articles_table
 Created Migration: 2015_06_09_164737_create_articles_table

マイグレーションファイルはdatabase/migrationsに作成される
(モデル作成時、artisan make:modelコマンドにオプション-mを付けると、モデルと同時にマイグレーションも生成される)
マイグレーションの書き方はWriting Migrationを参照
オートインクリメントのレコードIDと、文字列のtitleとtextをフィールドに持つarticlesテーブルを作成するマイグレーションは以下のようになる

  database/migrations/2015_06_09_164737_create_articles_table

 <?php
 use Illuminate\Database\Schema\Blueprint;
 use Illuminate\Database\Migrations\Migration;

 class CreateArticlesTable extends Migration
  {
   /**
    * Run the migrations.
    *
    * @return void
    */
       public function up()
     { 
         Schema::create('articles',                  
         function($table)
         {
         $table->increments('id');
         $table->string('title');
         $table->text('text');
         $table->timestamps();});
                                }
     /**
     * Reverse the migrations.
     *
     * @return void
     */
        public function down()
     {
        Schema::drop('articles');
                               }
                                }

timestampsは、インスタンスのdateTime型のupdated_atおよびcreated_at列マイグレーションはmigrateコマンドで適用
$ php artisan migrate 
Illuminate/Database/Eloquent/Model – Laravel API
モデルの利用
コントローラーでモデルを利用するには、インポートする
モデル操作は、Modelクラスのファサードおよびインスタンスメソッドで行う
Illuminate/Database/Eloquent/Model – Laravel API

RESTFullコントローラーの実装例

// app/Http/Controllers/ArticleController" highlight="7, 15, 21
<?php
  namespace App\Http\Controllers;
  use Illuminate\Http\Request;
  use App\Article;
  use App\Http\Requests;
  use App\Http\Controllers\Controller;
  class ArticleController extends Controller
   {
   public function index()
   {
     $articles = Article::all();
     return view('article.index', ['articles' => $articles];  }
      public function destroy($id)
     {
    $article = Article::find($id);
    $article->delete(); }}

6 テスト

データベースを利用するテスト
Laravel5では、テスト時にデータベースを切り替える仕組みを標準で用意していない
必要な環境変数はphpunit.xmlに記述する
データベースだけ切り替られれば良いのでDB_DATABASEのみ追加する

// phpunit.xml

テストデータベースのマイグレーション
マイグレーションは、DatabaseMigrationsトレイトを利用して、テストごとにMigrationを実行する

  //tests/ArticleTest
  <?php
  use Illuminate\Foundation\Testing\WithoutMiddleware;
  use Illuminate\Foundation\Testing\DatabaseMigrations;
  use Illuminate\Foundation\Testing\DatabaseTransactions;

    class ArticleTest extends TestCase
       {
           use DatabaseMigrations;
                                    }

7 標準機能について

7.1Authについて
Laravel5.2からmake:authでViewが生成できるようになった
参照:Laravelの標準Authentication(Auth)の動きを調べてみる
   
7.2 使用可能なライブラリについて

Laravelと合わせて使いたいライブラリ
・Pusher
     PusherはPHPでwebsocket(双方向データ通信)を行うためのライブラリ 
    参照URL:PusherはPHPでwebsocket(双方向データ通信)を行う
・Carbon
  PHPで時間を扱うDateTimeのラッパーライブラリ。

   参照URL:PHPで日付時刻処理を書くならCarbonを使うべき
参照URL:Laravelと合わせて使いたいライブラリ5選

7.3 JavaScriptフレームワークについて(Vue.jsなど)
Laravelとフロントエンド

Laravelでは、5.3から、Vue.jsが標準のJavaScriptフレームワークになっているさらに、5.4では、フロントエンドのビルドツールが、gulpベースのElixirから、WebpackベースのMixに変わった。Laravelをインストールすれば、Web APIはLaravelで作って、SPA(Single Page Application)をVue.jsで組む、といったことが簡単にできるようになっている

8.1 よく使うコマンドや実装について

参照URL:
https://walking-succession-falls.com/laravel%E3%81%AE%E5%9F%BA%E6%9C%AC%E6%A9%9F%E8%83%BD%E3%80%81%E3%81%A1%E3%82%87%E3%81%A3%E3%81%A8%E3%81%97%E3%81%9F%E5%B0%8F%E6%8A%80%E3%81%BE%E3%81%A8%E3%82%81/

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

TwilioとLaravel(PHP)を使って大量のSMSを送信する方法

原本

あなたが多数のユーザを持っていて、あなたがSMSを通してそれらを同時に更新するか、または通知する必要がある時があります。 たぶんあなたは会員制サイトや個人的なブログを運営しています。 どのような場合でも、このチュートリアルはあなたのWebアプリを使って大量のSMSを送信するための効率的で簡単な方法を提供します。

環境/対象

  • ターミナル(コマンドライン)
  • Composerインストール済み
  • PHPに精通している
  • Laravel(5+)に精通している
  • 既存のLaravelプロジェクトがある
  • Twilioアカウントを保持している

インストールとTwilio Laravel SDKの設定

最初にやるべきことはTwilio Laravel SDKをインストールすることです。TwilioLaravel SDKは、私たちの一括SMSアプリを起動するために必要な機能を提供します。 そのためにコマンドラインを使用します。 コマンドラインで次のように入力します:

$ composer require twilio/sdk

SDKがインストールされたので、Twilioアカウントを認識するように設定する必要があります。
.envファイルを開き、次のコードを貼り付けます。 必ず変数をTwilioの認証情報に置き換えてください。 TWILIO_FROMはあなたのTwilio番号です。

TWILIO_SID=ACXXXXXXXXXXXXXXXXXXX
TWILIO_TOKEN=XXXXXXXXXXXXXXXXXXXXX
TWILIO_FROM=+81XXXXXXXXXX

BulkSMS ControllerのViewとCodeを設定する

BulkSMSアプリには専用のControllerが必要です。Laravelのartisanコマンドを使用してControllerを作成します。
以下コマンドを貼り付けてControllerを作成します。

$ php artisan make:controller BulkSmsController

Controllerを開き、上部にTwilioクラスをincludeします。

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Twilio\Rest\Client;
use Validator;

次に、bulksms.blade.phpという名前のビューファイルを作成して、BulkSMSアプリケーションに必要なフィールドを作成するためのHTMLフォームを作成します。

$ touch resources/views/bulksms.blade.php

新しく作成されたresources/views/bulksms.blade.phpファイルを開き、以下のコードを貼り付けます:

<html>
      <body>
         <form action='' method='post'>
              @csrf
                      @if($errors->any())
              <ul>
             @foreach($errors->all() as $error)
            <li> {{ $error }} </li>
             @endforeach
        @endif

        @if( session( 'success' ) )
             {{ session( 'success' ) }}
        @endif

             <label>Phone numbers (seperate with a comma [,])</label>
             <input type='text' name='numbers' />

            <label>Message</label>
            <textarea name='message'></textarea>

            <button type='submit'>Send!</button>
      </form>
    </body>
</html>

routesフォルダにあるweb.phpを開き、一番下に次のコードを貼り付けます。

<?php

Route::view('/bulksms', 'bulksms');
Route::post('/bulksms', 'BulkSmsController@sendSms');

それでは、HTMLフォームを検証してテキストメッセージを送信するための関数を作成します。app/Http/ControllersフォルダーにあるBulkSmsController.phpファイルを開き、最後の中括弧の前に次のコードを入力します。

<?php

        public function sendSms( Request $request )
    {
       // Your Account SID and Auth Token from twilio.com/console
       $sid    = env( 'TWILIO_SID' );
       $token  = env( 'TWILIO_TOKEN' );
       $client = new Client( $sid, $token );

       $validator = Validator::make($request->all(), [
           'numbers' => 'required',
           'message' => 'required'
       ]);

       if ( $validator->passes() ) {

           $numbers_in_arrays = explode( ',' , $request->input( 'numbers' ) );

           $message = $request->input( 'message' );
           $count = 0;

           foreach( $numbers_in_arrays as $number )
           {
               $count++;

               $client->messages->create(
                   $number,
                   [
                       'from' => env( 'TWILIO_FROM' ),
                       'body' => $message,
                   ]
               );
           }

           return back()->with( 'success', $count . " messages sent!" );

       } else {
           return back()->withErrors( $validator );
       }
   }

テスト

アプリをテストするには、プロジェクトディレクトリでコンソールを開き、次のコマンドを入力します。

$ php artisan serve

お好みのブラウザを使用してhttp://localhost:8000/bulksmsにアクセスし、フォームに記入して送信します。

Conclusion

これで、一括SMS送信アプリを設定したので、SMS機能の拡張がどれほど簡単かを確認できます。
これはあなたの電話番号をあなた自身のデータベースに保存させるという利点をあなたに与えます。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

[MailhogとLaravel]Expected response code 220 but got code "500"のエラー解決方法

Expected response code 220 but got code "500"

上記のようなエラーが発生する場合の解決方法

環境

  • docker
  • laravel
  • mailhog
  • 開発環境(ENV=development)

問題点:確実に環境変数

  • 500エラーが帰ってきているのでメールサーバにはアクセスできている
  • 環境変数自体がおかしいか、読み込めていない

実際に通る.env

MAIL_USERNAMEMAIL_PASSWORDMAIL_ENCRYPTIONはNULLを設定しておきましょう。

MAIL_DRIVER=smtp
MAIL_HOST=mailhog
MAIL_PORT=1025
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null

解決方法

上記の環境変数さえ読み込めれば、実行はできる。
もしこれを設定してできない場合は環境変数がうまく読み込めていない。
以下の手順で確認してください。

0.環境変数が読み込めているか確認するコマンド

\Config::get('mail')

上記コマンドを実行して、意図した環境変数になっているか確認。
image.png

なっていない場合は以下の手順を試すべし

1.キャッシュクリア

bash
php artisan cache:clear
php artisan config:clear
php artisan route:clear
php artisan view:clear

2.環境変数ロード

bash
. .env
# もしくは環境変数を環境ごとに分けてる場合は読み込みたいファイルを指定
. .env.development

3.環境変数直接設定する

bash
MAIL_DRIVER=smtp
MAIL_HOST=mailhog
MAIL_PORT=1025
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null

4.最終手段、mail.phpを書き換える

環境変数を実際に読み込んでいるのはconfig/mail.phpというファイルだ。
ここの環境変数を読み込む部分を削除し、直接値を書き込んでしまえば良い。

bash
'encryption' => env('MAIL_ENCRYPTION', 'ssl'),

# こうなっているのをこうじゃ!

'encryption' => env(''),
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【laravel5.7】メール�送信周りを日本語化

laravelでのメール周り?の英文を日本語に直すメモ

やりたいこと

Email VerificationやPassword Resetの時のメール文や送信しました!などの英語部分を日本語にする。

環境

MacOS 10.14.3
VisualStudio
laravel 5.7

メール内容

viewsで日本語かしても下のようにまだ英語が残っているので、その部分を日本語化します。
スクリーンショット 2019-02-28 14.34.44.png

Notificationのレイアウトを編集する

terminal
php artisan vendor:publish

と打つと、下記のようなリストが表示されます。
スクリーンショット 2019-02-28 14.23.05.png
laravel-notificationsが書いてある番号を入力してEnter。
(上のリストだと"11")

環境によって番号は変わります。

resources/views/vendor/notifications/email.blade.phpが生成されるので編集します。

resources/views/vendor/notifications/email.blade.php
@component('mail::message')
{{-- Greeting --}}
@if (! empty($greeting))
# {{ $greeting }}
@else
@if ($level === 'error')
# @lang('Whoops!')
@else
+# こんにちは
@endif
@endif

{{-- Intro Lines --}}
@foreach ($introLines as $line)
{{ $line }}

@endforeach

{{-- Action Button --}}
@isset($actionText)
<?php
    switch ($level) {
        case 'success':
        case 'error':
            $color = $level;
            break;
        default:
            $color = 'primary';
    }
?>
@component('mail::button', ['url' => $actionUrl, 'color' => $color])
{{ $actionText }}
@endcomponent
@endisset

{{-- Outro Lines --}}
@foreach ($outroLines as $line)
{{ $line }}

@endforeach

{{-- Salutation --}}
@if (! empty($salutation))
{{ $salutation }}
@else
+{{ config('app.name') }}より
@endif

{{-- Subcopy --}}
@isset($actionText)
@slot('subcopy')
+もし、「{{ $actionText }}ボタン」がうまく機能しない場合、以下のURLをコピー&ペーストして直接ブラウザからアクセスしてください。
+ [{{ $actionUrl }}]({{ $actionUrl }})
@endslot
@endisset
@endcomponent

動作確認

再度、メールを送ってみて下のように日本語になっていたらOK。
スクリーンショット 2019-02-28 14.28.47.png

Password Resetの文

下の画像の緑の部分を日本語にします。
スクリーンショット 2019-02-28 12.56.33.png

config/app.php

変更箇所

  • timezone:タイムゾーン
  • locale:言語
  • fallback_local:該当言語が見つからない場合の言語
config/app.php
'timezone' => 'Asia/Tokyo',
'locale' => 'ja',
'fallback_locale' => 'ja',

app.phpのデフォルト言語で指定してある"en"は、
resources/lang/enから表示をしています。

その中に、下記4つのファイルがあるかと思います。

  • auth.php
  • pagination.php
  • password.php
  • validation.php

これを日本語に編集します。
1. enファイルをコピペして"ja"にリネーム。
2. ここから日本語訳をコピーして日本語に編集

今回はパスワードリセット部分を日本語化にしたいので、password.phpだけ編集します。

resources/lang/ja/password.php
<?php

return [

    /*
    |--------------------------------------------------------------------------
    | Password Reset Language Lines
    |--------------------------------------------------------------------------
    |
    | The following language lines are the default lines which match reasons
    | that are given by the password broker for a password update attempt
    | has failed, such as for an invalid token or invalid new password.
    |
    */

    'password' => 'パスワードは6文字以上にして、確認用入力欄と一致させてください。',
    'reset' => 'パスワードは再設定されました!',
    'sent' => 'パスワード再設定用のURLをメールで送りました。',
    'token' => 'パスワード再設定用のトークンが不正です。',
    'user' => "メールアドレスに一致するユーザーが存在しません。",

];

動作確認

http://127.0.0.1:8000
ログイン画面のPassword Resetリンクにとんで、メールアドレスをいれて送信してみてください。
スクリーンショット 2019-03-01 10.48.09.png

日本語になっていればOK。

おまけ

その他3つのファイルは日本語にするとこんな感じになります。

resources/lang/ja/auth.php
<?php

return [

    /*
    |--------------------------------------------------------------------------
    | Authentication Language Lines
    |--------------------------------------------------------------------------
    |
    | The following language lines are used during authentication for various
    | messages that we need to display to the user. You are free to modify
    | these language lines according to your application's requirements.
    |
    */

    'failed' => '認証情報が記録と一致しません。',
    'throttle' => 'ログイン試行が規定回数を超えました。:seconds秒後に再開できます。',

];

resources/lang/ja/pagination.php
<?php

return [

    /*
    |--------------------------------------------------------------------------
    | Pagination Language Lines
    |--------------------------------------------------------------------------
    |
    | The following language lines are used by the paginator library to build
    | the simple pagination links. You are free to change them to anything
    | you want to customize your views to better match your application.
    |
    */

    'previous' => '&laquo; 前へ',
    'next' => '次へ &raquo;',

];

resources/lang/ja/validation.php
<?php

return [

    /*
    |--------------------------------------------------------------------------
    | Validation Language Lines
    |--------------------------------------------------------------------------
    |
    | The following language lines contain the default error messages used by
    | the validator class. Some of these rules have multiple versions such
    | as the size rules. Feel free to tweak each of these messages here.
    |
    */

    'accepted'             => ':attributeを承認してください。',
    'active_url'           => ':attributeには有効なURLを指定してください。',
    'after'                => ':attributeには:date以降の日付を指定してください。',
    'after_or_equal'       => ':attributeには:dateかそれ以降の日付を指定してください。',
    'alpha'                => ':attributeには英字のみからなる文字列を指定してください。',
    'alpha_dash'           => ':attributeには英数字・ハイフン・アンダースコアのみからなる文字列を指定してください。',
    'alpha_num'            => ':attributeには英数字のみからなる文字列を指定してください。',
    'array'                => ':attributeには配列を指定してください。',
    'before'               => ':attributeには:date以前の日付を指定してください。',
    'before_or_equal'      => ':attributeには:dateかそれ以前の日付を指定してください。',
    'between'              => [
        'numeric' => ':attributeには:min〜:maxまでの数値を指定してください。',
        'file'    => ':attributeには:min〜:max KBのファイルを指定してください。',
        'string'  => ':attributeには:min〜:max文字の文字列を指定してください。',
        'array'   => ':attributeには:min〜:max個の要素を持つ配列を指定してください。',
    ],
    'boolean'              => ':attributeには真偽値を指定してください。',
    'confirmed'            => ':attributeが確認用の値と一致しません。',
    'date'                 => ':attributeには正しい形式の日付を指定してください。',
    'date_format'          => '":format"という形式の日付を指定してください。',
    'different'            => ':attributeには:otherとは異なる値を指定してください。',
    'digits'               => ':attributeには:digits桁の数値を指定してください。',
    'digits_between'       => ':attributeには:min〜:max桁の数値を指定してください。',
    'dimensions'           => ':attributeの画像サイズが不正です。',
    'distinct'             => '指定された:attributeは既に存在しています。',
    'email'                => ':attributeには正しい形式のメールアドレスを指定してください。',
    'exists'               => '指定された:attributeは存在しません。',
    'file'                 => ':attributeにはファイルを指定してください。',
    'filled'               => ':attributeには空でない値を指定してください。',
    'gt' => [
        'numeric' => ':attributeには、:valueより大きな値を指定してください。',
        'file'    => ':attributeには、:value kBより大きなファイルを指定してください。',
        'string'  => ':attributeは、:value文字より長く指定してください。',
        'array'   => ':attributeには、:value個より多くのアイテムを指定してください。',
    ],
    'gte' => [
        'numeric' => ':attributeには、:value以上の値を指定してください。',
        'file'    => ':attributeには、:value kB以上のファイルを指定してください。',
        'string'  => ':attributeは、:value文字以上で指定してください。',
        'array'   => ':attributeには、:value個以上のアイテムを指定してください。',
    ],
    'image'                => ':attributeには画像ファイルを指定してください。',
    'in'                   => '選択された:attributeは正しくありません。',
    'in_array'             => ':attributeには:otherの値を指定してください。',
    'integer'              => ':attributeは整数で指定してください。',
    'ip'                   => ':attributeには、有効なIPアドレスを指定してください。',
    'ipv4'                 => ':attributeには、有効なIPv4アドレスを指定してください。',
    'ipv6'                 => ':attributeには、有効なIPv6アドレスを指定してください。',
    'json'                 => ':attributeには、有効なJSON文字列を指定してください。',
    'lt' => [
        'numeric' => ':attributeには、:valueより小さな値を指定してください。',
        'file'    => ':attributeには、:value kBより小さなファイルを指定してください。',
        'string'  => ':attributeは、:value文字より短く指定してください。',
        'array'   => ':attributeには、:value個より少ないアイテムを指定してください。',
    ],
    'lte' => [
        'numeric' => ':attributeには、:value以下の値を指定してください。',
        'file'    => ':attributeには、:value kB以下のファイルを指定してください。',
        'string'  => ':attributeは、:value文字以下で指定してください。',
        'array'   => ':attributeには、:value個以下のアイテムを指定してください。',
    ],
    'max' => [
        'numeric' => ':attributeには、:max以下の数字を指定してください。',
        'file'    => ':attributeには、:max kB以下のファイルを指定してください。',
        'string'  => ':attributeは、:max文字以下で指定してください。',
        'array'   => ':attributeは:max個以下指定してください。',
    ],
    'mimes'                => ':attributeには:valuesタイプのファイルを指定してください。',
    'mimetypes'            => ':attributeには:valuesタイプのファイルを指定してください。',
    'min' => [
        'numeric' => ':attributeには、:min以上の数字を指定してください。',
        'file'    => ':attributeには、:min kB以上のファイルを指定してください。',
        'string'  => ':attributeは、:min文字以上で指定してください。',
        'array'   => ':attributeは:min個以上指定してください。',
    ],
    'not_in'               => '選択された:attributeは正しくありません。',
    'not_regex'            => ':attributeの形式が正しくありません。',
    'numeric'              => ':attributeには、数字を指定してください。',
    'present'              => ':attributeが存在していません。',
    'regex'                => ':attributeに正しい形式を指定してください。',
    'required'             => ':attributeは必ず指定してください。',
    'required_if'          => ':otherが:valueの場合、:attributeも指定してください。',
    'required_unless'      => ':otherが:valuesでない場合、:attributeを指定してください。',
    'required_with'        => ':valuesを指定する場合は、:attributeも指定してください。',
    'required_with_all'    => ':valuesを指定する場合は、:attributeも指定してください。',
    'required_without'     => ':valuesを指定しない場合は、:attributeを指定してください。',
    'required_without_all' => ':valuesのどれも指定しない場合は、:attributeを指定してください。',
    'same'                 => ':attributeと:otherには同じ値を指定してください。',
    'size' => [
        'numeric' => ':attributeは:sizeを指定してください。',
        'file'    => ':attributeのファイルは、:sizeキロバイトでなくてはなりません。',
        'string'  => ':attributeは:size文字で指定してください。',
        'array'   => ':attributeは:size個指定してください。',
    ],
    'starts_with' => ':attributeは:valuesのいずれかで始めてください。',
    'string'               => ':attributeは文字列を指定してください。',
    'timezone'             => ':attributeには、有効なゾーンを指定してください。',
    'unique'               => ':attributeの値は既に存在しています。',
    'uploaded'             => ':attributeのアップロードに失敗しました。',
    'url'                  => ':attributeに正しい形式を指定してください。',
    'uuid'                 => ':attributeに有効なUUIDを指定してください。',

    /*
    |--------------------------------------------------------------------------
    | Custom Validation Language Lines
    |--------------------------------------------------------------------------
    |
    | Here you may specify custom validation messages for attributes using the
    | convention "attribute.rule" to name the lines. This makes it quick to
    | specify a specific custom language line for a given attribute rule.
    |
    */

    'custom' => [
        'attribute-name' => [
            'rule-name' => 'custom-message',
        ],
    ],

    /*
    |--------------------------------------------------------------------------
    | Custom Validation Attributes
    |--------------------------------------------------------------------------
    |
    | The following language lines are used to swap our attribute placeholder
    | with something more reader friendly such as "E-Mail Address" instead
    | of "email". This simply helps us make our message more expressive.
    |
    */

    'attributes' => [],

];

ただ、これだけだと下記のようにバリデーションがinputタグのname値が表示されます。

emailは必ず指定してください。
passwordは必ず指定してください。

ここも日本語化したい場合は、
validation.phpの"attributes"で指定します。

resources/lang/ja/validation.php
'attributes' => [
    'email' => 'メールアドレス',
    'password' => 'パスワード',
    'password_confirmation' => 'パスワード(確認)',
    'name' => 'ユーザー名'
],

とりあえず以上です。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Laravel-Mixコンパイル時のcode ELIFECYCLEエラーに対応する

概要

Laravel-Mixコンパイル時のエラーに対応したのでメモ。

事象

Laravel-Mixのコンパイルを実行すると、code ELIFECYCLE〜のエラーが発生。

npm run dev
npm run watch
npm run production

-------

npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! @ development: `cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the @ development script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     /Users/xxxx/.npm/_logs/xxxx.log

対策

node_modulesを入れ直す

#既存jsモジュール群を全削除
rm -rf node_modules

#lockファイルを削除
rm package-lock.json yarn.lock

#npmのキャッシュをクリア
npm cache clear --force

#jsモジュール群をインストール
npm install

#動作確認
npm run dev

参考

Sudden npm error

LaravelMIX セットアップ

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

ECSのバックエンドをEC2からFargateに変更

概要

ECS+EC2で動作しているアプリケーションをFargateに変更にします。
ECS+EC2での環境構築は、LaravelアプリケーションをAWS上のDockerで動かすを参考にしてください。

全てマネジメントコンソール上で行います。

前提条件

Farageteについて

メリット

  • コンテナのためのEC2の管理が不要
    • コンテナのスケールに合わせてインスタンスタイプの変更、あるいはスケールアウトさせる必要がない
    • インスタンスタイプの選択が不要
  • AutoScaleのタイミング設定が不要

デメリット

  • コンテナホストにssh接続できない
    • Dockerコマンドが実行できないため、コンテナの状況を確認するといったことができない
  • ログドライバがawslogsのみ

料金

EC2単位ではなく、コンテナ単位で料金が発生します。
下記の記事に最新の料金が記載されていましたので、参考にしてみてください。
2019年1月にAWS Fargateが大幅値下げしたのでEC2との価格比を確認してみた | DevelopersIO

nginxの設定ファイルを修正

Fargateでは、コンテナ間通信の宛先は127.0.0.1になります。
nginxの設定ファイルの一部を下記の通り変更します。

default.conf
# 変更前
fastcgi_pass php-fpm:9000;
# 変更後
fastcgi_pass 127.0.0.1:9000;

IAMロールを作成

ECSタスク実行ロールを作成します。
手順は、下記のecsTaskExecutionRole IAM ロールを作成するにはに従って作成してください。
Amazon ECS タスク実行 IAM ロール - Amazon Elastic Container Service

なお、タスク定義のリビジョンの作成前にECSタスク実行ロールが作成されている必要があります。新しいリビジョンの作成の途中でロールを作成した場合、ECSタスク実行ロールを選択することができず、エラーとなります。

ALBのターゲットグループを作成

ALBのターゲットグループのターゲットの種類はipである必要があります。
既存のEC2のALBのターゲットグループがターゲットの種類がinstanceとなっている場合、新規で作成する必要があります。

タスクの定義のリビジョンを作成する

Amazon ECS > タスク定義 から作成済みのタスクを選択し、新しいリビジョンの作成を選択します。

以下の項目を変更します。

項目
ネットワークモード awsvpc
互換性が必要 FARGATE

Fargateの場合、ネットワークモードはawsvpcを設定する必要があります。
nginxの設定ファイルを修正で、コンテナ間通信の宛先を127.0.0.1に変更した理由もここにあります。

タスクサイズ

項目
タスクメモリ (GB) 0.5GB
タスクメモリ (GB) 0.25vCPU

EC2の場合、設定はオプション項目となっていますが、FARGATEを選択した場合は必須となります。

コンテナの定義
コンテナのネットワーク設定でリンクを設定している場合、awsvpcではサポートされていないため変更する必要があります。今回は、EC2で動作している際に、nginxコンテナのネットワーク設定のリンクの設定を削除します。

また、ここではログの設定も行います。
コンテナでの運用の場合、コンテナを落とした際にログが消えてしまうため、ログを外部に出力する必要があります。
今回は、awslogsログドライバーを利用して、標準出力に出力されたログをCloudWatchに送信します。

ストレージとログのログ設定でログの出力先を設定します。
Auto-configure CloudWatch Logsにチェックを入れると、自動でロググループが作成されます。以上でログの設定は完了です。CloudWatchからログを確認することが可能となりました。

スクリーンショット 2019-03-02 15.15.24.png

そのほかの設定の変更がなければ作成を押下して、新しいリビジョンの作成は完了です。

サービスを作成する

Amazon ECS > クラスター から作成済みのクラスタを選択し、サービスタブの作成を押下します。

項目
起動タイプ FARGATE
タスク定義 上記で作成した新しいリビジョンを選択
プラットフォームのバージョン LATEST
クラスタ sample-api-cluster
サービス名 sample-fargate-api
サービスタイプ REPLICA
タスクの数 1

Elastic Load Balancing(オプション)

項目
ELB タイプ Application Load Balancer
サービス用の IAM ロールの選択 自動で生成されるAWSServiceRoleForECSサービスリンクロールが使用される
ELB 名 作成したALBを選択

負荷分散用のコンテナ

nginx:80:80を指定し、ELBへの追加を選択。
ターゲットグループ名に、作成したALBに紐づくターゲットグループを選択を選択。

以上で、ECSの環境構築は完了です。

動作確認

作成したALBのDNS名にアクセスし、動作確認を行います。

余談

Laravelのログを標準出力する際に、以下の余分なメッセージが出力される問題にぶつかりました。

WARNING: [pool www] child 10 said into stdout

原因と対応方法は、https://github.com/docker-library/php/issues/207 に記載されています。
また、PHP7.3ではこの問題が解消しており、 DockerイメージFROM php:7.3.2-fpm-alpineでは余分なメッセージが出力されていないことを確認できています。

参考記事

参考にさせていただきました。ありがとうございます。
AWS FargateでElixirのコンテンツ配信システムを動かしてみた (実装編) - エムスリーテックブログ
AWSにおける本番環境を想定したCI/CD実践 - y-ohgi's blog
AWS Fargate のすヽめ | 開発ブログ | Elastic Infra

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む