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

初学者チームがWebサービス開発を始めて4週間で出来たことと出来なかったこと

2週間前にアップした「初学者チームがWebサービス開発を始めて最初の2週間でやったことを振り返り、そして次を考える」という記事から、また2週間経ったので、どこまで進捗したのかまとめたいと思います。

「初心者だけど何かモノを作ってみたい!」という方の参考になれば幸いです。

目標達成度

2週間前掲げていた目標と、実際できたことを整理します。
こちらが2週間前の記事では言っていたこと。

というわけで、次なる目標ですが、深い意味は特になく、なんとなくまた2週間先(9/21月曜)にチェックポイントを置きたいと思います。
目標は、9/21Monまでに人にURLをばら撒けるレベルのサイトにしたい!です。
具体的には、下記8点の要件を満たしたいです。

その8点と結果がこちら。

2週間前掲げた目標 達成度 10点満点 コメント
Heroku上でアプリが機能する 8 2週間前はHerokuにデプロイしたてでエラーもしばしば。今は表示は安定、基本動作も問題なし。
ページ内のリンクなど、ページがきちんと遷移する 5 まだ作れてないページがあったり、戻るボタン、キャンセルボタンなどが欠けています。
シンプルだが見るに耐えうるデザインであり全ページに統一感がある 3 フロントチームは頑張って作ってくれたのですが、サーバーサイドがそこまで手が回りませんでした。
投稿が新着順で表示でき、1ページの投稿は10件まで、それ以上は別ページとする 9 今ではペジネーションという専門用語も覚えました!でもデザイン配置のカスタマイズができてないので-1。
投稿がキーワード検索できる 0 全く手をつけてませんでした涙
アカウント登録した人がログイン、ログアウト、投稿、削除、編集できる 9 Laravelデフォルトのユーザ認証機能も利用しつつ、自分らのデザインを当て込むこともできてきました。
ゲストでも投稿できる 10 できました。
Contactページから問い合わせすると運営にメールが届く 5 今日滑り込みでメールを受信するまでの基礎機能の実装はできました。
総合得点 49/80 達成度61%

60点ならまずまずではないでしょうか!ただ、残念ながらまだ胸を張ってURLを配れるようなレベルはなりませんでした。
そして、ストレッチで掲げていた目標は綺麗に一切手を付けられませんでした(笑)↓

ストレッチ目標 達成度 10点満点 コメント
アカウントがアイコン画像を設定できる 0
投稿に画像を1枚添付できる 0
ミュージシャンごとの投稿を集約したページが生成できる 0
ライブハウスごとの投稿を集約したページが生成できる 0
いいね!ができる 0
利用規約のページがある 0
管理人が不適切な投稿を削除できる 0
総合得点 0/70 達成度0%

その他にこの2週間でできたこと箇条書き↓

感想3つ

(そういうのいいよって方は飛ばしてください)

初心者なのにモノを作ってみた感想

人それぞれ勉強方法はあるのかもしれませんが、基礎から教科書をやっていくという勉強方法よりも、実際にモノを作るというこの方法が僕には一番合っていると感じています。めっちゃくちゃ夢中になっています。ただし!1ページめくれば、次の手順を教えてくれるテキスト学習と違って、1歩進むごとに、何をしたらいいのかわからない、どう調べればいいかもわからない、手をつけたらエラーになるの繰り返しです。

上手くいかない時は、焦るし、焦って変なコマンド打ってしまったり、イライラしたり、精神的に安定しないこともありました。一般人は「プログラミングは超絶簡単」「1ヶ月でできるようになる」という有名人の言葉を鵜呑みにしない方がいいです。でも何かちょっと対策を講じてエラー文章が変わり、それで推理が進んで、原因を突き止めて、前に進んだ時の喜びと快感は尋常じゃなかったりします。

仲間という存在の貴重さ

まこなり社長さんが「プログラミング学習には仲間を作った方がいい」と仰っているのを聞いたことがありますが、僕も同意です。あれは単なるテックキャンプへ誘導する文言ではないと思います(笑)僕の理由は「行き詰まった時、話せる相手がいるのは超助かるから」です。相談する相手も初学者なので、答えがもらえるとは限らないのですが、一緒に調べてくれたり、解決のヒントを与えてくれたりします。自分の思考がクリアになって、話してるうちに閃くということも経験しました。そして何より精神的に落ち着けます。こういうことで悩んでるんだよねーというと、「わかるーー!」と言ってもらえるだけでなんか落ち着けるんですよね。女子の気持ちが少しわかりました(笑)

ただし、初心者のチーム開発はハッキリ言って楽ではありません。でもその大変さを差し引いてもプラスになっていると思います。

あと先輩やメンターの存在も結構大きいです。それらが揃ってるYouTube万屋エンジニアチャンネル超おすすめっす!

開発初期にはプログラミング以外の時間が結構かかる

最初の3週間はアプリの企画、設計を考えたり、開発環境を整えたりで手一杯で、コードを書く状態に至りませんでした。(フロントチームはその間HTML/CSSでサイトの見た目を作ってくれていました)ようやく4週間めくらいからプログラムを書けるようになってきて、やっぱりコーディングの方が楽しいなと思いました。

今後の開発

次の目標

期限:10/5月曜18:00
下記10点の実装を目指します。

  • 継承レイアウトで構築し、サイト全体にデザインの統一感がある
  • 投稿の文章が長い場合、全文表示/一部表示の切り替えができる
  • ドロップダウンメニュー
  • 投稿の際、チップスの効いたタグ付けができる
  • 投稿に付いたタグをクリックするとそのタグの投稿一覧を表示できる
  • 登録ユーザーの投稿一覧が表示できる
  • 検索機能
  • いいね機能の実装
  • Contactから運営側にメールが届き、問い合わせ内容がわかる
  • ユーザーがプロフ画像を設定できる

開発体制の変更

今まではフロントには一旦別環境でHTML/CSS作りに集中してもらっていたのですが、開発が進んできてそれでは大変になってきそうなので、フロントチームもLaravelを入れてもらってバックエンドと同じ環境下でフロントのブラッシュアップをしてもらうつもりです。

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

Laravel(mysql)

PHP拡張ツールをインストール

sudo apt-get install php-intl

PDO関連のドライバーやその他のパッケージをインストールする

sudo apt-get install apache2 php php-gd mysql-server php-mysql php-zip
sudo apt-get install php-mbstring php-xml php-json php-zip php7.4-cli

もしくは

sudo apt-get install php-mbstring php-xml php-json php-zip php7.2-cli

apache2関連の設定

sudo apt-get install libapache2-mod-php
sudo apt-get install apache2
sudo systemctl enable apache2
sudo systemctl restart apache2

Mysqlのパスワードの設定。
※不要であれば飛ばしてOK

sudo mysql_secure_installation

PDO関連のドライバー(sqlite)を入れておく

sudo apt-get install php7.2-sqlite3
sudo apt-get install php7.4-sqlite3

curlを入れておく

sudo apt-get  install curl

composerを入れておこう!!

curl -sS https://getcomposer.org/installer
sudo apt-get install composer
which composer

パス設定の場所を変えよう(mv)でね

sudo mv composer /usr/local/bin/composer
which composer

所有権の設定を変えよう

sudo chmod 755 /usr/local/bin/composer
export PATH=/usr/local/bin:$PATH
which composer

Laravel自体のインストールとかパスとか色々

composer global require "laravel/installer"
export PATH="$PATH:/.config/composer/vendor/bin"
source ~/.bashrc

インストールからコレクティブの設定まで

composer create-project --prefer-dist laravel/laravel Laravelapp
cd Laravelapp
composer update
composer install 
php artisan --version

composer require "laravelcollective/html":"^8.4.0"
composer require "laravelcollective/html":"^7.2.0"

composer require "laravelcollective/html":"^6.2.0"

sudo mysql -u root -p
create database databasename;


下記でブラウザツールも併せて作っておくと楽になります。

https://qiita.com/yuuki-furue/items/e2cb13b378f996fc69d9

下記は速攻で管理画面を作るコマンドです。因みに下記を入力することでVUE.JSをフロントエンドで使用できます。※好みですが・・・

composer require laravel/ui
php artisan ui vue --auth
sudo npm install 
sudo npm run dev

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

[Laravel]Laravel6.8 × Vue.jsでSPAを構築する流れ

今回の題

1ヶ月前に勉強がてらLaravelとVue.jsでSPAを構築してみたのですが、1ヶ月経った今、その手順をすっかり忘れてしまいました。
必要な時に振り返ればいい知識だとは思うのですが、忘れすぎて少し癪だったのでアウトプットしておきます。

この記事では、HomeとUserというページを作り、それぞれをページ遷移を行わずに切替えられる様にします。

ezgif.com-video-to-gif.gif

ページのコンテンツとURLがページ遷移なしに切り替わっているのがわかると思います。

バージョン

  • Laravel6.8
  • Laravel Mix 4.1.4
  • Vue.js 2.6.12
  • Vue Router 3.4.3

手順

Laravelのインストール

$ composer create-project "laravel/laravel=6.8" laravel-spa

各種パッケージのインストール

  • Vue.js
$ npm install vue --save-dev
  • Laravel Mix
$ npm install laravel-mix --save-dev
  • Vue Router
$ npm install vue-router --save-dev
  • cross-env
$ npm install cross-env --save-dev

Laravel Mixの設定

webpack.mix.jsにコンパイル先を定義します。

webpack.mix.js
const mix = require('laravel-mix');

mix.js('resources/js/app.js', 'public/js')
    .version();

これでresources/js/app.jsに書いたVueはpublic/jsにコンパイルされます。
version()はキャッシュ対策です。
ブラウザに以前のJavaScriptがキャッシュとして残っていると、キャッシュの方を使ってしまうので、ここでversion()を使い、さらにviewでmix関数を使ってjsを読み込むことで対策出来ます。
参考

コンパイル

以下のコマンドで変更を監視し、自動的にコンパイルが行われる様にします。

$ npm run watch

各種ファイル作成

view

resources/views/index.blade.php
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1">
</head>

<body>
  <div id="app">
    <router-view /> 
  </div>
  <script src="{{ mix('js/app.js') }}"></script> 
</body>

</html>

参考

router.js

resources/js/にrouter.jsを作成。
SPAのルーティングはここに定義します。

router.js
import Vue from 'vue'
import Router from 'vue-router'
import Home from './components/pages/Home'
import User from './components/pages/User'

Vue.use(Router)

export default new Router({
  mode: 'history', 
  routes: [
    {
      path: '/',
      name: 'home',
      component: Home 
    },
    {
      path: '/user',
      name: 'user',
      component: User 
    },
  ]
})

Vue.jsとvue-router、使用するコンポーネントをimportしたあと、ルーティングでパスにコンポーネントを割り振っています。
参考

app.js

resources/js/app.jsを以下の様に編集します。

import Vue from 'vue'
import router from './router.js'

new Vue({
 router
}).$mount('#app')

Vue.jsとvue-routerをimportして、routerを適用する要素を設定します。

参考

コンポーネント

ページの内容となるコンポーネントはcomponentsディレクトリで管理します。

$ mkdir resources/js/components

componentsディレクトリにpagesディレクトリを作成し、

$ mkdir resources/js/components/pages

そこに、Home.vue User.vueというファイルを作り、以下の様にそれぞれ編集します。

Home.vue
<template>
    <div>
        <h1>Home</h1>
        <router-link :to="{ name: 'user' }">User</router-link>
    </div>
</template>
User.vue
<template>
    <div>
        <h1>User</h1>
        <router-link :to="{ name: 'home' }">Home</router-link>
    </div>
</template>

確認

以下のコマンドでビルトインサーバーを立ち上げ、

$ php artisan serve

http://127.0.0.1:8000/
にアクセスして確認してください。

最初のgifの様な動きが確認できるはずです。
あとはこれを土台に好きな様に弄り回してSPAで色々作れると思います。

以上!!

一言

最初SPAの構築ができた時、めちゃくちゃ興奮して無駄にページ行き来しまくりました。
SPAすごい技術だなぁ……。

参考

readouble アセットのコンパイル
Vue Router
Laravel6.xとVue Routerでvue.jsのSPA構築

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

Heroku(Laravel)で自作アプリをHerokuにデプロイしようとしたらマイグレーションエラーが起きたので、ClearDB(MySQL5.5)からJawsDB(MySQL8.0)に変更した時の備忘録

開発環境

PHP7.3
Laravel5.8
MySQL8.0
Heroku使用時のDBアドオン:ClearDB MySQL5.5

やろうとしたこと

下記をheroku run php artisan migrate

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Query\Expression;
use Illuminate\Support\Facades\Schema;

class CreateChatRoomsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('chat_rooms', function (Blueprint $table) {
            $table->id();
            $table->text('user_info_json')->default(new Expression('(JSON_ARRAY())'));
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('chat_rooms');
    }
}

エラーが出現。

エラーの内容

  SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '(JSON_ARRAY()),   
  `created_at` timestamp null, `updated_at` timestamp null) defaul' at line 1 (SQL: create table `chat_rooms` (`id` bigint unsigned not null auto_increment primary key, `user_info_json` text not null default (  
  JSON_ARRAY()), `created_at` timestamp null, `updated_at` timestamp null) default character set utf8mb4 collate 'utf8mb4_unicode_ci')                                                                                                                                                                                                                                                                                             
  SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '(JSON_ARRAY()),   
  `created_at` timestamp null, `updated_at` timestamp null) defaul' at line 1

推測

$table->text('user_info_json')->default(new Expression('(JSON_ARRAY())'));

の部分がSQLのバージョンに対応していないらしい。

ローカル(MySQL8.0)ではエラーは起こらなかったため、本番環境のSQLをバージョンアップすれば通るかも?

ClearDBからJawsDBにアドオンを変更しよう

ClearDB・・・MySQL5.5、5.6、5.7対応
JawsDB・・・5.7及び8.0対応
とのことであったため、ローカル環境(MySQL8.0)と合わせるべくJawsDBにアドオンを変更することに。

JawsDBアドオン取得

heroku addons:create jawsdb:[プラン名] -a [アプリ名] --version=8.0

--version=8.0のようにすることで、バージョンを8.0指定でインストール。

ClearDBの環境変数を削除

JawsDBをインストールしただけの状態なので、まだClearDB使用時の環境変数が登録されている。

DB_DATABASE:           [ClearDBのDATABASE]
DB_HOST:               [ClearDBのHOST]
DB_PASSWORD:           [ClearDBのPASSWORD]
DB_USERNAME:           [ClearDBのUSERNAME]

これらを全て一旦削除

heroku config:unset DB_DATABASE
heroku config:unset DB_HOST
heroku config:unset DB_PASSWORD
heroku config:unset DB_USERNAME

その後

heroku config

すると、ClearDBの環境変数が消えている。

JawsDBの接続情報を確認

heroku config |grep JAWSDB_URL
JAWSDB_URL:       mysql://[DB_USERNAME]:[DB_PASSWORD]@[DB_HOST]/[DB_DATABASE]

もしくはHerokuのマイページからJawsDBアドオンに遷移して確認。

JawsDBの環境変数登録

heroku config:set DB_DATABASE=[DB_DATABASE]
heroku config:set DB_HOST=[DB_HOST]
heroku config:set DB_PASSWORD=[DB_PASSWORD]
heroku config:set DB_USERNAME=[DB_USERNAME]

再度マイグレーション

heroku run php artisan migrate

通った!

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

Laravel + Instagram Basic Display APIで投稿を取得する

はじめに

Laravelを触ってみながら、Instagram Basic Display API というAPIで自分のInstagramアカウントの投稿写真を 取得していこうと思います。

やること

  • Instagram Basic Display APIに必要なアクセストークンを取得する
  • Laravelで投稿を取得&表示する
  • Laravelでアクセストークンを定期更新する

動作環境

  • PHP 7.1.23
  • Laravel 5.8
  • MySQL 5.7

Instagram Basic Display APIとは

Instagram基本表示APIはHTTPベースのAPIです。アプリはこれを使用して、Instagramユーザーのプロフィール、画像、動画、アルバムを取得できます。

InstagramグラフAPIの簡易版で認証したユーザーに関する情報を取得できます。
InstagramグラフAPIと違って審査がいらないのでサクッと使いたい人向けです。

できること

  • ユーザのアクセス許可、アクセストークンの取得
  • 発行したアクセストークンを使用して
    • ユーザーのプロフィールを取得
    • ユーザーの画像、動画、アルバムを取得

基本的に自分のアカウントの投稿をサイトに表示するなどの目的で使うのであればInstagram Basic Display APIで大丈夫だと思います。

前提

スタートガイド

上記の公式のスタートガイドを参考にステップ3までを進めた状態で手順を進めていきます。

  • ステップ1: Facebookアプリを作成する
  • ステップ2: Instagram基本表示を構成する
  • ステップ3: Instagramテストユーザーを追加する

ステップ4のテストユーザーを認証する~長期アクセストークンを取得するまでを書いていきます。

アクセストークンとアクセス許可を取得する

参考 : アクセストークンとアクセス許可を取得する

Instagram Basic Display APIを使うにはアクセストークンが必要になるので取得しましょう。

リクエスト例: ユーザーのプロフィールを取得する

GET /me?fields={fields}&access_token={access-token}

認証を取得する

https://api.instagram.com/oauth/authorize
  ?client_id={instagram-app-id}
  &redirect_uri={redirect-uri}
  &scope=user_profile,user_media
  &response_type=code

instagram-app-id
[アプリダッシュボード] > [製品] > [Instagram] > [基本表示] で表示される InstagramアプリID
スクリーンショット 2020-09-22 1.54.44.png

redirect-uri
[アプリダッシュボード] > [製品] > [Instagram] > [基本表示] で設定した クライアントOAuth設定の 有効なOAuthリダイレクトURL

スクリーンショット 2020-09-22 1.58.03.png

上記の内容を自分の設定に変えてアクセスします。
アクセス例

https://api.instagram.com/oauth/authorize
  ?client_id=990602627938098
  &redirect_uri=https://socialsizzle.herokuapp.com/auth/
  &scope=user_profile,user_media
  &response_type=code

アクセスすると認証許可の画面が出てくるのでテスターとして登録したアカウントで許可しましょう

成功した場合のリダイレクト例

https://socialsizzle.herokuapp.com/auth/?code=AQBx-hBsH3...#_

成功するとredirect_uriに設定したURL + ?code=AQBx-hBsH3...#_

こんな感じの文字列がURLのバーに表示されています。code= と #_ の間の文字列をこのあと使うので控えておきましょう。
この文字列をcodeといいこのあと使います。

短命のアクセストークンを取得する

認証した際に取得した codeを用いて短命のアクセストークンを取得します。

POST https://api.instagram.com/oauth/access_token

リクエストの例

curl -X POST \ 
https://api.instagram.com/oauth/access_token \ 
-F client_id={instagram-app-id} \ 
-F client_secret={instagram-app-secret} \ 
-F grant_type=authorization_code \ 
-F redirect_uri={redirect_uri} \ 
-F code={さっき取得したcode}

instagram-app-secret
[アプリダッシュボード] > [製品] > [Instagram] > [基本表示] で表示される Instagram App Secret

スクリーンショット 2020-09-22 1.54.44.png

成功した時の応答例

{ "access_token": "IGQVJ...", "user_id": 17841405793187218 }

access_token ここの内容がAPIに必要なアクセストークンになります。

しかしこのままだとこのアクセストークンの使用できる期間は1時間と短命なので、長命のものと交換しましょう.

長期のアクセストークンを取得する

参考: 長期アクセストークン

curl -i -X GET "https://graph.instagram.com/access_token?grant_type=ig_exchange_token&client_secret={instagram-app-secret}&access_token={short-lived-access-token}"

short-lived-access-token 先ほど取得した access_token

成功した時の応答例

{ "access_token":"{long-lived-user-access-token}", "token_type": "bearer", "expires_in":5183944 // トークンが有効期限切れになるまでの秒数 }

long-lived-user-access-tokenが今回取得した長期トークンになります。

しかし長期とは言ってもこれも expires_inに記載されている通り期限が存在します。
このトークンに関しては60日間有効なのですがそれをすぎると無効になってしまうため定期的にトークンを更新しないといけません。

長期のアクセストークン更新する

参考: 長期アクセストークンの更新

最長でもアクセストークンは60日しか持たないので有効期限が切れる前に新しいアクセストークンと交換します。

リクエスト例

curl -i -X GET "https://graph.instagram.com/refresh_access_token?grant_type=ig_refresh_token&access_token={long-lived-access-token}"

long-lived-access-token 取得している長期アクセストークン

有効期間が過ぎていない長期アクセストークンを指定してください

応答の例

{ "access_token":"{long-lived-user-access-token}", "token_type": "bearer", "expires_in":5183944 // トークンが有効期限切れになるまでの秒数 }

long-lived-user-access-tokenが新たに取得した60日の有効期限の長期アクセストークンになります。

ユーザーの投稿を取得する

参考: メディアデータを取得する
参考: paging

GET /me/media?fields={fields}&access_token={access-token}

アクセス例

curl -X GET \ 
'https://graph.instagram.com/me/media?fields=id,caption,permalink,media_url,thumbnail_url&access_token={access-token}'

access_token は有効なアクセストークンを設定します。

fieldsで取得するデータを選択できます。

https://developers.facebook.com/docs/instagram-basic-display-api/reference/media#fields

応答例

{
   "data": [
      {
         "id": "メディアID",
         "caption": "キャプションテキスト",
         "permalink": "投稿先URL",
         "media_url": "画像URL"
      }
   ],
  "paging": {
    "cursors": {
      "after": "MTAxN...",
      "before": "NDMyN..."
      },
    "next": "https://graph.faceb..."
  }
}

Laravel を利用する

プロジェクト作成

$ composer create-project --prefer-dist laravel/laravel instagram "5.8.*"
$ cd instagram

コントローラー作成

$ php artisan make:controller InstagramController

ルーティング追加

/routes/web.php
Route::get('/instagram', 'InstagramController@index');

token保存用の簡易的なテーブルを追加します

$ php artisan make:migration create_instagramTokens_table
/database/migrations/...._create_instagram_tokens_table.php
<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateInstagramTokensTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('instagram_tokens', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->string('access_token');
            $table->string('token_type');
            $table->integer('expires_in');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('instagram_tokens');
    }
}

$ php artisan migrate
mysql> desc instagram_tokens
    -> ;
+--------------+---------------------+------+-----+---------+----------------+
| Field        | Type                | Null | Key | Default | Extra          |
+--------------+---------------------+------+-----+---------+----------------+
| id           | bigint(20) unsigned | NO   | PRI | NULL    | auto_increment |
| access_token | varchar(255)        | NO   |     | NULL    |                |
| token_type   | varchar(255)        | NO   |     | NULL    |                |
| expires_in   | int(11)             | NO   |     | NULL    |                |
| created_at   | timestamp           | YES  |     | NULL    |                |
| updated_at   | timestamp           | YES  |     | NULL    |                |
+--------------+---------------------+------+-----+---------+----------------+
6 rows in set (0.00 sec)

モデル作成

$ php artisan make:model InstagramToken

今回は最初の手順で有効な長期access_tokenを取得しているのでenvに追加しておきます。

/.env
INSTAGRAM_TOKEN=取得した有効な長期アクセストークン

Laravelでアクセストークンを更新

参考: Laravelのタスクスケジュール(cron)を使いこなす

Commandの作成

$ php artisan make:command Instagram
/app/Console/Commands/Instagram.php
<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use App\InstagramToken;

class Instagram extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'instagram:refresh';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Instagram access token update';

    /**
     * Create a new command instance.
     *
     * @return void
     */
    public function __construct()
    {
        parent::__construct();
    }

    /**
     * Execute the console command.
     *
     * @return mixed
     */
    public function handle()
    {
        // ここに処理を書いていく
    }
}


Commandの登録

/app/Console/Kernel.php
    protected $commands = [
      Commands\Instagram::Class,
    ];

トークンを更新する

/app/Console/Commands/Instagram.php
/**
     * Execute the console command.
     *
     * @return mixed
     */
    public function handle()
    {
      $baseUrl = "https://graph.instagram.com/refresh_access_token?";

      // アクセストークン取得
      $instagramToken = InstagramToken::select('access_token')->latest()->first();
      $accessToken = env('INSTAGRAM_TOKEN');

      if ($instagramToken->access_token) {
        $accessToken = $instagramToken->access_token;
      }

      // パラメーター設定
      $params = array(
        'grant_type' => 'ig_refresh_token',
        'access_token' => $accessToken
      );

      $ch = curl_init();
      curl_setopt($ch, CURLOPT_URL, $baseUrl . http_build_query($params));
      curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

      $responseText = curl_exec($ch);
      $result = json_decode($responseText, true);

      curl_close($ch);

      // DB保存
      if ($newAccessToken = $result['access_token']) {
        $instagramToken = new InstagramToken();
        $instagramToken->access_token = $newAccessToken;
        $instagramToken->token_type = $result['token_type'];
        $instagramToken->expires_in = $result['expires_in'];
        $instagramToken->save();
      }

    }

実行してみる

$ php artisan instagram:refresh
mysql> select * from instagram_tokens;
+----+-------------------------------------------------------------------------------------------------------------------------------------------------+------------+------------+---------------------+---------------------+
| id | access_token                                                                                                                                    | token_type | expires_in | created_at          | updated_at          |
+----+-------------------------------------------------------------------------------------------------------------------------------------------------+------------+------------+---------------------+---------------------+
|  1 | トークン | bearer     |    5177185 | 2020-09-21 21:53:07 | 2020-09-21 21:53:07 |
|  2 | トークン  | bearer     |    5177002 | 2020-09-21 21:56:10 | 2020-09-21 21:56:10 |
|  3 | トークン | bearer     |    5176998 | 2020-09-21 21:56:14 | 2020-09-21 21:56:14 |
+----+-------------------------------------------------------------------------------------------------------------------------------------------------+------------+------------+---------------------+---------------------+
3 rows in set (0.00 sec)

取得できていますね。
これを定期実行すれば有効期限問題は解消できそうです。

参考: Laravelのタスクスケジュール(cron)を使いこなす
などを参考に有効期限の60日が来る前に定期的にトークンを更新するように設定しましょう

scheduleの追加&cron設定

今回はscheduleに追加する形で実装していこうと思います。
scheduleではなくそのままphp artisan instagram:refreshこのコマンドをcron設定してもいいと思います。
scheduleにコマンドを追加することでcron設定を一個に済ませることができます
今回は実行するコマンドが一個なのであんまり恩恵はないかもしれませんが練習も兼ねてやろうと思います。

# エディタが開く
$ crontab -e

# * * * * *  左から「分」「時」「日」「月」「曜日」
# 分 0-59
# 時 0-23
# 日 1-31
# 月 1-12
# 曜日 0-7 (0または7は日曜日)
# * * * * * で毎分

# 下記の行を開いたエディタに追加
* * * * * cd [プロジェクトのパス] && php artisan schedule:run >> /dev/null 2>&1

スケジュールへの登録

参考: Laravel タスクスケジュールまとめ

/app/Console/Kernel.php
    /**
     * Define the application's command schedule.
     *
     * @param  \Illuminate\Console\Scheduling\Schedule  $schedule
     * @return void
     */
    protected function schedule(Schedule $schedule)
    {
      // 5分ごとに実行
      $schedule->command('instagram:refresh')
                ->everyFiveMinutes();
    }
mysql> select * from instagram_tokens;
+----+--------------------------------------------------------------------------------------------------------------------------------------------------+------------+------------+---------------------+---------------------+
| id | access_token                                                                                                                                     | token_type | expires_in | created_at          | updated_at          |
+----+--------------------------------------------------------------------------------------------------------------------------------------------------+------------+------------+---------------------+---------------------+
|  8 |トークン   | bearer     |    5156672 | 2020-09-22 03:35:01 | 2020-09-22 03:35:01 |
|  9 |トークン  | bearer     |    5156371 | 2020-09-22 03:40:01 | 2020-09-22 03:40:01 |
+----+--------------------------------------------------------------------------------------------------------------------------------------------------+------------+------------+---------------------+---------------------+

ちゃんと設定通りに定期実行されていますね

簡単な表示画面を作成します

/app/Http/Controllers/InstagramController.php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class InstagramController extends Controller
{
  public function index ()
  {
    return view('instagram');
  }
}
/resources/views/instagram.blade.php
<html>
  <head>
    <title>HelloWorld</title>
  </head>
  <body>
    <h1>HelloWorld!</h1>
  </body>
</html>

サーバー起動

$ php artisan serve

http://127.0.0.1:8000/instagram
アクセスできればOK

投稿した画像を取得

/app/Http/Controllers/InstagramController.php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\InstagramToken;

class InstagramController extends Controller
{
  public function index ()
  {
    $baseUrl = "https://graph.instagram.com/me/media?";

    // アクセストークン取得
    $instagramToken = InstagramToken::select('access_token')->latest()->first();
    $accessToken = env('INSTAGRAM_TOKEN');

    if ($instagramToken->access_token) {
      $accessToken = $instagramToken->access_token;
    }

    // パラメーター設定
    $params = array(
      'fields' => implode(',', array('id','caption','permalink','media_url','thumbnail_url')),
      'access_token' => $accessToken
    );

    //curlセッション初期化
    $ch = curl_init();

    curl_setopt($ch, CURLOPT_URL, $baseUrl . http_build_query($params));
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

    $responseText = curl_exec($ch);
    $result = json_decode($responseText, true);

    //セッション終了
    curl_close($ch);

    return view('instagram', [
      'mediaData' => $result['data'],
      'paging' => $result['paging']
    ]);
  }
}

投稿した画像を表示

/resources/views/instagram.blade.php
<html>
  <head>
    <title>HelloWorld</title>
  </head>
  <body>
    @foreach ($mediaData as $media)
      <a href="{{$media['permalink']}}" target="_brank" rel="noopener">
        <img src="{{$media['media_url']}}" width="100px" alt="{{$media['caption']}}">
      </a>
    @endforeach
  </body>
</html>

結果

スクリーンショット 2020-09-22 5.32.36.png

最後に

実装方法について
Laravelでcommandを作成し、定期実行すると言うのは初めてだったので結構楽しかったです。アクセストークンは定期実行、投稿の取得は毎回APIを実行という方法を今回取っていたのですが、
APIリクエストの節約の為に1日1回夜中に投稿を取得するようにし,その結果をjsonファイルとして出力,またはDBに保存するなどすればリクエスト数を節約出来ると思いました。
もっとこう言う良い方法ある等あれば教えてもらえると嬉しいです。

Instagram Basic Display APIについて
自分のブログなどにインスタで投稿したものを表示させたいなら、Instagram Basic Display APIで十分そうですね。今回は「InstagramのAPI使いたい!」と思ってやったのですが,よくよく考えたら僕自身が映える写真を投稿しているアカウントを持っていなかったので,今回のAPIだといい感じの写真が表示されませんでした。。。

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

Laravel CRUD処理を使った投稿アプリを作成する その9 バリデーションをRequestに記載する

目的

  • アプリを作成する上で基本となるCRUD処理を有したLaravelアプリをチュートリアル的に作成する方法をまとめる

実施環境

  • ハードウェア環境
項目 情報
OS macOS Catalina(10.15.5)
ハードウェア MacBook Pro (13-inch, 2020, Four Thunderbolt 3 ports)
プロセッサ 2 GHz クアッドコアIntel Core i5
メモリ 32 GB 3733 MHz LPDDR4
グラフィックス Intel Iris Plus Graphics 1536 MB
  • ソフトウェア環境
項目 情報 備考
PHP バージョン 7.4.3 Homwbrewを用いて導入
Laravel バージョン 7.0.8 commposerを用いてこちらの方法で導入→Mac Laravelの環境構築を行う
MySQLバージョン 8.0.19 for osx10.13 on x86_64 Homwbrewを用いてこちらの方法で導入→Mac HomebrewでMySQLをインストールする

前提条件

前提情報

  • ソースコードはこちら→https://github.com/miriwo0104/laravel_crud/tree/master
  • DockerやAWSなどは使用せずにMacのローカルに実施環境と同じLaravel開発環境を構築して実施する。
  • チュートリアルで実際に筆者が作成したソースコードをGitHubにて公開予定である。
  • CRUD処理の作成完了を最短目標にしてバリデーションなどは後々設定することとする。
  • 実施環境と同じ環境がDockerやAWSで用意できるなら都度読み替えていただければ実施が可能だと思う。
  • 公式ドキュメントと一冊の技術書を元に本記事を記載する。
  • DBへの意図しないデータの流入を防ぐためバリデーションを実装する。
  • 問い合わせの内容は「入力がされていること」のバリデーションルールを、新規投稿と投稿編集は「入力されており、かつ140文字以内であること」定義してバリデートする。
  • バリデーションで弾かれた時にエラーが出力される様にする。
  • 下記に目を通しておくと理解が早いかもしれない。
  • バリデーションルールは下記の公式ドキュメントに数多く記載されているので実装できたら遊んでみるのもいいかもしれない。

この記事の読後感

  • ユーザが入力する部分にバリデーションを実装することができ、バリデーションルールをRequestファイルに記載する。

概要

  1. Requestファイルの作成と記載
  2. コントローラファイルの記載修正
  3. 確認

詳細

  1. Requestファイルの作成と記載

    1. laravel_crudディレクトリで下記コマンドを実行し専用のリクエストファイルを作成する。

      $ php artisan make:request ContentRequest
      
    2. laravel_crudディレクトリで下記コマンドを実行し先に作成したリクエストファイルを開く。

      $ vi app/Http/Requests/ContentRequest.php
      
    3. 先に開いたリクエストファイルを下記の様に修正する。

      laravel_crud/app/Http/Requests/ContentRequest.php
      <?php
      
      namespace App\Http\Requests;
      
      use Illuminate\Foundation\Http\FormRequest;
      
      class ContentRequest extends FormRequest
      {
          /**
           * Determine if the user is authorized to make this request.
           *
           * @return bool
           */
          public function authorize()
          {
              // 下記を修正する
              return true;
          }
      
          /**
           * Get the validation rules that apply to the request.
           *
           * @return array
           */
          public function rules()
          {
              return [
                  // 下記を追記する
                  'content' => ['required', 'max: 140'],
              ];
          }
      }
      
    4. laravel_crudディレクトリで下記コマンドを実行し専用のリクエストファイルを作成する。

      $ php artisan make:request InquiryRequest
      
    5. laravel_crudディレクトリで下記コマンドを実行し先に作成したリクエストファイルを開く。

      $ vi app/Http/Requests/InquiryRequest.php
      
    6. 先に開いたリクエストファイルを下記の様に修正する。

      laravel_crud/app/Http/Requests/InquiryRequest.php
      <?php
      
      namespace App\Http\Requests;
      
      use Illuminate\Foundation\Http\FormRequest;
      
      class InquiryRequest extends FormRequest
      {
          /**
           * Determine if the user is authorized to make this request.
           *
           * @return bool
           */
          public function authorize()
          {
              // 下記を修正する
              return true;
          }
      
          /**
           * Get the validation rules that apply to the request.
           *
           * @return array
           */
          public function rules()
          {
              return [
                  // 下記を追記する
                  'content' => ['required'],
                  'name' => ['required'],
                  // 上記までを追記する
              ];
          }
      }
      
  2. コントローラファイルの記載修正

    1. laravel_crudディレクトリで下記コマンドを実行しコントローラファイルを開く。

      $ vi app/Http/Controllers/ContentController.php
      
    2. 先に開いたファイルを下記の様に修正する。

      laravel_crud/app/Http/Controllers/ContentController.php
      <?php
      
      namespace App\Http\Controllers;
      
      use Illuminate\Http\Request;
      use App\Models\Content;
      // 下記を追記する
      use App\Http\Requests\ContentRequest;
      
      class ContentController extends Controller
      {
          public function input()
          {
              return view('contents.input');
          }
      
          // 下記を修正する
          public function save(ContentRequest $contentRequest)
          {
              // バリデーションルールとバリデート命令を削除する
              $input_content = new Content();
              // 下記を修正する
              $input_content->content = $contentRequest['content'];
              $input_content->save();
      
              return redirect('/output');
          }
      
          public function output()
          {
              $contents_get_query = Content::select('*');
              $all_contents = $contents_get_query->get();
      
              return view('contents.output', [
                  'all_contents' => $all_contents,
              ]);
          }
      
          public function delete(Request $request)
          {
              $contents_delete_query = Content::select('*');
              $contents_delete_query->where('id', $request['content_id']);
              $contents_delete_query->delete();
      
              return redirect('/output');
          }
      
          public function edit($content_id)
          {
              $contents_edit_query = Content::select('*');
              $contents_edit_query->where('id', $content_id);
              $edit_contents = $contents_edit_query->get();
              $edit_content = $edit_contents[0];
      
              return view('contents.edit', [
                  'edit_content' => $edit_content,
              ]);
          }
      
          // 下記を修正する
          public function update(ContentRequest $contentRequest)
          {
              // バリデーションルールとバリデート命令を削除する
              $contents_update_query = Content::select('*');
              // 下記を修正する
              $contents_update_query->where('id', $contentRequest['content_id']);
              $update_contents = $contents_update_query->get();
      
              $update_content = $update_contents[0];
              // 下記を修正する
              $update_content->content = $contentRequest['content'];
              $update_content->save();
      
              return redirect('/output');
          }
      }
      
    3. laravel_crudディレクトリで下記コマンドを実行しコントローラファイルを開く。

      $ vi app/Http/Controllers/InquiryController.php
      
    4. 先に開いたファイルを下記の様に修正する。

      laravel_crud/app/Http/Controllers/InquiryController.php
      <?php
      
      namespace App\Http\Controllers;
      
      use Illuminate\Http\Request;
      use Illuminate\Support\Facades\Mail;
      use Illuminate\Support\Facades\Auth;
      use App\Mail\SendMail;
      // 下記を追記する
      use App\Http\Requests\InquiryRequest;
      
      class InquiryController extends Controller
      {
          public function input()
          {
              $user_infos = Auth::user();
              return view('inquiries.input', [
                  'user_infos' => $user_infos,
              ]);
          }
      
          // 下記を修正する
          public function send(InquiryRequest $inquiryRequest)
          {
              // バリデーションルールとバリデート命令を削除する
              // 下記を修正する
              $inquiry_content = $inquiryRequest->all();
              Mail::to('admin@example')->send(new SendMail($inquiry_content));
              return redirect(route('home'));
          }
      }
      
  3. 確認

    1. laravel_crudディレクトリで下記コマンドを実行しローカルサーバを起動する。

      $ php artisan serve
      
    2. 下記にユーザ認証後、下記にアクセスする。

    3. 何も入力せず「送信」をクリックし下記のようにエラーが出ることを確認する。

      127_0_0_1_8000_input.png

    4. 下記にユーザ認証後、下記にアクセスする。(コンテンツのidは1以外でも構わない)

    5. 何も入力せず「送信」をクリックし下記のようにエラーが出ることを確認する。

      127_0_0_1_8000_edit_5.png

    6. 下記にユーザ認証後、下記にアクセスする。(コンテンツのidは1以外でも構わない)

    7. 何も入力せず「送信」をクリックし下記のようにエラーが出ることを確認する。

      127_0_0_1_8000_inquiry_input.png

参考文献

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

Laravel CRUD処理を使った投稿アプリを作成する その8 バリデーションを実装する

目的

  • アプリを作成する上で基本となるCRUD処理を有したLaravelアプリをチュートリアル的に作成する方法をまとめる

実施環境

  • ハードウェア環境
項目 情報
OS macOS Catalina(10.15.5)
ハードウェア MacBook Pro (13-inch, 2020, Four Thunderbolt 3 ports)
プロセッサ 2 GHz クアッドコアIntel Core i5
メモリ 32 GB 3733 MHz LPDDR4
グラフィックス Intel Iris Plus Graphics 1536 MB
  • ソフトウェア環境
項目 情報 備考
PHP バージョン 7.4.3 Homwbrewを用いて導入
Laravel バージョン 7.0.8 commposerを用いてこちらの方法で導入→Mac Laravelの環境構築を行う
MySQLバージョン 8.0.19 for osx10.13 on x86_64 Homwbrewを用いてこちらの方法で導入→Mac HomebrewでMySQLをインストールする

前提条件

前提情報

  • ソースコードはこちら→https://github.com/miriwo0104/laravel_crud/tree/master
  • DockerやAWSなどは使用せずにMacのローカルに実施環境と同じLaravel開発環境を構築して実施する。
  • チュートリアルで実際に筆者が作成したソースコードをGitHubにて公開予定である。
  • CRUD処理の作成完了を最短目標にしてバリデーションなどは後々設定することとする。
  • 実施環境と同じ環境がDockerやAWSで用意できるなら都度読み替えていただければ実施が可能だと思う。
  • 公式ドキュメントと一冊の技術書を元に本記事を記載する。
  • DBへの意図しないデータの流入を防ぐためバリデーションを実装する。
  • 問い合わせの内容は「入力がされていること」のバリデーションルールを、新規投稿と投稿編集は「入力されており、かつ140文字以内であること」定義してバリデートする。
  • バリデーションで弾かれた時にエラーが出力される様にする。
  • 下記に目を通しておくと理解が早いかもしれない。
  • バリデーションルールは下記の公式ドキュメントに数多く記載されているので実装できたら遊んでみるのもいいかもしれない。

この記事の読後感

  • ユーザが入力する部分にバリデーションを実装することができる。

概要

  1. バリデーションの実装
  2. エラー出力部分とデフォルト値の設定
  3. 確認

詳細

  1. バリデーションの実装

    1. laravel_crudディレクトリで下記コマンドを実行してコントローラファイルを開く。

      $ vi app/Http/Controllers/ContentController.php
      
    2. 先に開いたコントローラファイルのsaveアクションを下記の様に修正する。

      laravel_crud/app/Http/Controllers/ContentController.php
      public function save(Request $request)
      {
          // 下記を追記する
          $rules = [
              'content' => ['required', 'max: 140'],
          ];
      
          $this->validate($request, $rules);
          // 上記までを追記する
          $input_content = new Content();
          $input_content->content = $request['content'];
          $input_content->save();
      
          return redirect('/output');
      }
      
    3. 先に開いたコントローラファイルのupdateアクションを下記の様に修正する。

      laravel_crud/app/Http/Controllers/ContentController.php
      public function update(Request $request)
      {
          // 下記を追記する
          $rules = [
              'content' => ['required', 'max: 140'],
          ];
      
          $this->validate($request, $rules);
          // 上記までを追記する
          $contents_update_query = Content::select('*');
          $contents_update_query->where('id', $request['content_id']);
          $update_contents = $contents_update_query->get();
      
          $update_content = $update_contents[0];
          $update_content->content = $request['content'];
          $update_content->save();
      
          return redirect('/output');
      }
      
    4. ContentController.phpの全体像を下記に記載する。

      laravel_crud/app/Http/Controllers/ContentController.php
      <?php
      
      namespace App\Http\Controllers;
      
      use Illuminate\Http\Request;
      use App\Models\Content;
      
      class ContentController extends Controller
      {
          public function input()
          {
              return view('contents.input');
          }
      
          public function save(Request $request)
          {
              // 下記を追記する
              $rules = [
                  'content' => ['required', 'max: 140'],
              ];
      
              $this->validate($request, $rules);
              // 上記までを追記する
              $input_content = new Content();
              $input_content->content = $request['content'];
              $input_content->save();
      
              return redirect('/output');
          }
      
          public function output()
          {
              $contents_get_query = Content::select('*');
              $all_contents = $contents_get_query->get();
      
              return view('contents.output', [
                  'all_contents' => $all_contents,
              ]);
          }
      
          public function delete(Request $request)
          {
              $contents_delete_query = Content::select('*');
              $contents_delete_query->where('id', $request['content_id']);
              $contents_delete_query->delete();
      
              return redirect('/output');
          }
      
          public function edit($content_id)
          {
              $contents_edit_query = Content::select('*');
              $contents_edit_query->where('id', $content_id);
              $edit_contents = $contents_edit_query->get();
              $edit_content = $edit_contents[0];
      
              return view('contents.edit', [
                  'edit_content' => $edit_content,
              ]);
          }
      
          public function update(Request $request)
          {
              // 下記を追記する
              $rules = [
                  'content' => ['required', 'max: 140'],
              ];
      
              $this->validate($request, $rules);
              // 上記までを追記する
              $contents_update_query = Content::select('*');
              $contents_update_query->where('id', $request['content_id']);
              $update_contents = $contents_update_query->get();
      
              $update_content = $update_contents[0];
              $update_content->content = $request['content'];
              $update_content->save();
      
              return redirect('/output');
          }
      }
      
      
    5. laravel_crudディレクトリで下記コマンドを実行してコントローラファイルを開く。

      $ vi app/Http/Controllers/InquiryController.php
      
    6. 先に開いたコントローラファイルのsendアクションを下記の様に修正する。

      laravel_crud/app/Http/Controllers/InquiryController.php
      public function send(Request $request)
      {
          // 下記を追記する
          $rules = [
              'content' => ['required'],
              'name' => ['required'],
          ];
      
          $this->validate($request, $rules);
          // 上記までを追記する
          $inquiry_content = $request->all();
          Mail::to('admin@example')->send(new SendMail($inquiry_content));
          return redirect(route('home'));
      }
      
    7. InquiryController.phpの全体像を下記に記載する。

      laravel_crud/app/Http/Controllers/InquiryController.php
      <?php
      
      namespace App\Http\Controllers;
      
      use Illuminate\Http\Request;
      use Illuminate\Support\Facades\Mail;
      use Illuminate\Support\Facades\Auth;
      use App\Mail\SendMail;
      
      class InquiryController extends Controller
      {
          public function input()
          {
              $user_infos = Auth::user();
              return view('inquiries.input', [
                  'user_infos' => $user_infos,
              ]);
          }
      
          public function send(Request $request)
          {
              // 下記を追記する
              $rules = [
                  'content' => ['required'],
                  'name' => ['required'],
              ];
      
              $this->validate($request, $rules);
              // 上記までを追記する
              $inquiry_content = $request->all();
              Mail::to('admin@example')->send(new SendMail($inquiry_content));
              return redirect(route('home'));
          }
      }
      
    8. laravel_crudディレクトリで下記コマンドを実行しローカルサーバを起動する。

      $ php artisan serve
      
    9. 下記にユーザ認証後、下記にそれぞれアクセスし内容を入力せずに送信ボタンをクリックし、ページ遷移せず同じページが再度読み込まれることを確認する。編集画面での確認はidが1以外のものでも良い。

  2. エラー出力部分とデフォルト値の設定

    1. laravel_crudディレクトリで下記コマンドを実行して新規投稿画面のビューファイルを開く。

      $ vi resources/views/contents/input.blade.php
      
    2. 開いたファイルを下記の様に修正する。

      laravel_crud/resources/views/contents/input.blade.php
      <h1>input</h1>
      {{-- 下記を追記する --}}
      @error('content')
          {{ $message }}
      @enderror
      {{-- 上記までを追記する --}}
      <form action="{{route('save')}}" method="post">
          @csrf
          {{-- 下記を修正する --}}
          <textarea name="content" cols="30" rows="10">{{ old('content') }}</textarea>
          <input type="submit" value="送信">
      </form>
      
    3. laravel_crudディレクトリで下記コマンドを実行して投稿編集画面のビューファイルを開く。

      $ vi resources/views/contents/edit.blade.php
      
    4. 開いたファイルを下記の様に修正する。

      laravel_crud/resources/views/contents/edit.blade.php
      <h1>edit</h1>
      {{-- 下記を追記する --}}
      @error('content')
          {{ $message }}
      @enderror
      {{-- 上記までを追記する --}}
      <form action="{{route('update')}}" method="post">
          @csrf
          <textarea name="content" cols="30" rows="10">{{$edit_content['content']}}</textarea>
          <input type="hidden" name="content_id" value="{{$edit_content['id']}}">
          <input type="submit" value="送信">
      </form>
      
    5. laravel_crudディレクトリで下記コマンドを実行して投稿編集画面のビューファイルを開く。

      $ vi resources/views/contents/edit.blade.php
      
    6. 開いたファイルを下記の様に修正する。

      laravel_crud/resources/views/contents/edit.blade.php
      <h1>edit</h1>
      {{-- 下記を追記する --}}
      @error('content')
          {{ $message }}
      @enderror
      {{-- 上記までを追記する --}}
      <form action="{{route('update')}}" method="post">
          @csrf
          <textarea name="content" cols="30" rows="10">{{$edit_content['content']}}</textarea>
          <input type="hidden" name="content_id" value="{{$edit_content['id']}}">
          <input type="submit" value="送信">
      </form>
      
    7. laravel_crudディレクトリで下記コマンドを実行して問い合わせ送信画面のビューファイルを開く。

      $ vi resources/views/inquiries/input.blade.php
      
    8. 開いたファイルを下記の様に修正する。

      laravel_crud/resources/views/inquiries/input.blade.php
      <form action="{{ route('inquiry.send') }}" method="POST">
          @csrf
          <p>お問い合わせ内容</p>
          <textarea name="content" cols="30" rows="10"></textarea>
          {{-- 下記を追記する --}}
          @error('content')
          {{ $message }}
          @enderror
          {{-- 上記までを追記する --}}
      
          <p>お客様のお名前</p>
          <input type="text" name="name" value="{{ $user_infos['name'] }}">
          {{-- 下記を追記する --}}
              @error('name')
              {{ $message }}
          @enderror
          {{-- 上記までを追記する --}}
      
          <p>お客様のメールアドレス</p>
          <p>{{ $user_infos['email'] }}</p>
          <input type="hidden" name="email" value="{{ $user_infos['email'] }}">
          <br>
          <input type="submit" value="送信">
      </form>
      
  3. 確認

    1. laravel_crudディレクトリで下記コマンドを実行しローカルサーバを起動する。

      $ php artisan serve
      
    2. 下記にユーザ認証後、下記にアクセスする。

    3. 何も入力せず「送信」をクリックし下記のようにエラーが出ることを確認する。

      127_0_0_1_8000_input.png

    4. 下記にユーザ認証後、下記にアクセスする。(コンテンツのidは1以外でも構わない)

    5. 何も入力せず「送信」をクリックし下記のようにエラーが出ることを確認する。

      127_0_0_1_8000_edit_5.png

    6. 下記にユーザ認証後、下記にアクセスする。(コンテンツのidは1以外でも構わない)

    7. 何も入力せず「送信」をクリックし下記のようにエラーが出ることを確認する。

      127_0_0_1_8000_inquiry_input.png

参考文献

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