Laravelの配列(Array)のValidationの項目名に行を表示する。

Laravelの配列(Array)のValidationの項目名に行を表示する。

配列のバリデーションでメッセージを表示する場合に以下のように名前を割り当てていただけど。

    public function attributes()
    {
        return [
            'stock.*.jan' => 'JANコード',
            'stock.*.grade_id' => '商品グレード',
            'stock.*.location_id' => '場所',
            'stock.*.note' => 'メモ',
        ];
    }

複数行でえらーだと以下のようにバグっぽくなってしまう&どこかよくわかんなくなるので、行数をどうにかいれられないかあと

・このJANコードの値は既に存在しています
・このJANコードの値は既に存在しています
・このJANコードの値は既に存在しています
・このJANコードの値は既に存在しています

MessageBag($erros)を配列にtoArray()してKeyを見て強引に行数をいれる

もう少しスマートにできないかどうか。

<div class="alert alert-danger">
    <ul>
        @foreach( $errors->toArray() as $key => $errors)
            @foreach( $errors as $error)
                @if(preg_match('/(\.)([\d]+)(\.)/',$key,$matches))
                    <li>{{ sprintf('%s(%s行目)',$error,intval($matches[2])+1) }}</li>
                @else
                    <li>{{ $error }}</li>
                @endif
            @endforeach
        @endforeach
    </ul>
</div>

Laravel9 langフォルダのメッセージをPHP/JavaScriptで共有したい

Laravel9 langフォルダのメッセージをPHP/JavaScriptで共有したい。

/lang/ja/messages.phpを添付のように書いていたところ.
nodejsでコンパイル前のソースから同じ文言を共有したくなりました。

return [
    'login' => [
        'success' => 'ログインしました。',
        'fail' => 'ログインに失敗しました。'
    ],
];

そこで、/lang/ja/以下のPHPをJSONに変換してJavaScriptの定数のように使えるようにするコマンドを作成しました。

  • /lang/ja/以下のPHP
  • const ファイル名 という変数名になります。
  • とりあえず多言語化はしておらず、メッセージの定数管理のみ&JS側でIDEのコードヒントが出てほしいだけ
<?php
namespace App\Console\Commands;

use Illuminate\Console\Command;
use Illuminate\Support\Facades\File;

class YamaLabLangMesJsonCommand extends Command
{
    protected $signature = 'yamalab:lang_mes_json';
    protected $description = 'langファイル(PHP)をJSONに変換し保存';
    
    /**
     * Execute the console command.
     *
     * @return int
     */
    public function handle()
    {
        
        $langdir = base_path('lang/ja');
        if (is_dir($langdir)) {
            $files = scandir($langdir);
            if (!empty($files)) {
                $langjs = [];
                $files = array_filter($files, function ($f) {
                    return strpos($f, '.php') !== false;
                });
                foreach ($files as $f) {
                    $phpArr = include base_path("lang/ja/$f");
                    $json = json_encode($phpArr, JSON_UNESCAPED_UNICODE);
                    $name = str_replace('.php','.json',$f);
                    $varName = '__'.str($name)->replace('.json','')->upper().'__';
                    $row = sprintf('var %s = %s;',$varName,$json);
                    $langjs[] = $row; 
                }
                $langjs = implode("\n",$langjs);
                File::put(resource_path('js/lang.js'), $langjs);
            }
        }
        return Command::SUCCESS;
        
    }
    
}

2022年9月時点WebP画像対応のOSブラウザのメモ

2022年9月時点WebP画像対応のOSブラウザのメモ

基本殆どのブラウザが対応してきているので、どんどん進めたい所。

モバイルは

ほとんど大丈夫と思われます。

  • Androidは太古のバージョンのみなので無視できる。
  • iOSのSafariは14以上はOK 13以下もちょこちょこあるが 0.5%にも満たない感じなので無視できる範囲と思われる。

デスクトップは

  • IE11が2022年6月にサポート終了は朗報
  • 基本的に要件が最新ブラウザとなっていれば問題ないと思われる。
  • MacOS11(BigSur)以降でサポートされているが、その前のCatalinaユーザーがまだ多いので実際には対応しないと行けない感じ

ベターなバランス型の対応は以下のような感じになりそうです。

PCはSafariのためにJPGなども対応、SPはWebPのみで微細なアクセスは無視する。

    <picture>
        <source srcset="{PC用WebP}" type=”image/webp”>
        <source srcset="{PC用JPG}" type=”image/jpg”>
        <img src="{SP用WebP}" alt="">
    </picture>

ディレクトリ以下の画像を一括でwebpに変換したい人

ディレクトリ以下の画像を一括でwebpに変換したい人のためのワンライナー(jpgとpngのみ)

$ find -E . -iregex '^.+\.(jpe?g|png)$' | sed -r 'p;s/\.(jpg|jpeg|png)$/\.webp/gi' | xargs -n2 bash -c 'cwebp $0 -o $1'
  1. findで拡張子のファイルを探して(JPG,jpg,JPEG,jpeg,PNG,png)
  2. sedで元ファイル名/置換後ファイル名を出力
  3. xargsでbashを実行 -cオプションで文字列からcwebpを実行 ※1

※1.xargsで複数の引数の場合渡す位置が細かく設定できなかったんでbashに渡して実行

cwebpコマンドがない人はGoogleより先にDownLoadしていてください。

Downloading and Installing WebP

元ファイルを削除するバージョン

$ find -E . -iregex '^.+\.(jpe?g|png)$' | sed -r 'p;s/\.(jpg|jpeg|png)$/\.webp/gi' | xargs -n2 bash -c 'cwebp $0 -o $1; rm $0'

Vueのテンプレートでmomentが使えなかったdataにわたすと解決

Vue2のテンプレート内部で、momentが使えなかった、dataに渡してあげると解決。

import moment from 'moment';
moment.locale('ja');

new Vue({
    el: '#myApp',
    data: {
        moment: moment
    },
.
.
.

出ていたmomentが参照できないよとエラー

app.js:43920 [Vue warn]: Property or method "moment" is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based components, by initializing the property.

参考 :
https://stackoverflow.com/questions/58342090/typeerror-vm-moment-is-not-a-function-in-vuejs

Laravel9で定期バックアップなどを取る方法

旧バージョンでは’spatie/laravel-backup’を利用させてもらったんですが最新バージョンには対応されていないようなので、laravel-backupの内部でつかわれている、spatie/db-dumperのみをシンプルにCommandに組み込みました。

spatie/db-dumper

まずインストール

composer require spatie/db-dumper

で、コマンド作成 app/Console/Commands/BackupDb.php

<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use Illuminate\Support\Carbon;
use Spatie\DbDumper\Databases\MySql;

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

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Backup Database';

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

    /**
     * Execute the console command.
     *
     * @return mixed
     */
    public function handle()
    {
        $filename = "backup-" . Carbon::now()->format('Ymdhis') . ".sql";
        $file = storage_path() . "/app/backup/" . $filename;
        MySql::create()
            ->setDbName(env('DB_DATABASE'))
            ->setUserName($env('DB_USERNAME'))
            ->setPassword(env('DB_PASSWORD'))
            ->dumpToFile($file);        
    }
}

でcronn登録したり、Kernel.phpでスケジュールしたり。

$ php artisan myapp:backup_db

DeskTopのSafariやiPadのSafariでmp4のvideoファイルの読込が遅い問題

DeskTopのSafariやiPadのSafariでmp4のvideoファイルの読込が遅い問題

<video> タグでmp4動画を再生させる場合基本ストリーミング再生できるのですが、DeskTopのSafariやiPadのSafariでできなかったのでその解決方法は、DescTopのSafariは”HLSを使って再生対応する”

手順

  1. 事前準備:動画のメタデータを先頭にもってくる。
  2. 動画ファイルをセグメント化(細かく分割)
  3. JSでHSL対応/非対応ごとに再生方法を記述

0.事前準備:動画のメタデータを先頭にもってくる。

ffmpegでメタデータを先頭にもってきます。
メタデータ:動画の長さetcが後方にある場合は読込が重くなるため(Safariに限らず)

$ ffmpeg -i input.mp4 -codec copy -movflags faststart output.mp4

1.動画ファイルをセグメント化(細かく分割)

ffmpegで分割します。

ffmpeg -i input.mp4 -c:v copy -c:a copy -f hls -hls_time 9 -hls_playlist_type vod -hls_segment_filename "output%3d.ts" output.m3u8
  • m3u8ファイル(output.m3u8)は、分割されたファイルの再生順などが記載されたテキストファイル
  • 分割ファイル(output{xxx}.tsは分割された動画ファイル

2.JSでHSL対応/非対応ごとに再生方法を記述

2–1.HLS対応のライブラリを読込ます。

    <script src="https://cdn.jsdelivr.net/npm/hls.js@latest"></script> </head>

2–2.videoタグにHLS対応/非対応両方のsrcをdatasetとして記述

<video 
    id="video" 
    data-src="./assets/video/output.mp4" //HLS非対応用
    data-src-hls="./assets/video/output.m3u8" //HLS用
>
</video> 

2–3.JSで分岐処理

それぞれ再生方法を処理する。

if(Hls.isSupported()) { //HLS対応
    var hls = new Hls();
    hls.loadSource(video.dataset.srcHls);
    hls.attachMedia(video);
}else{                  //HLS非対応
    video.src = video.dataset.src;
}
video.play();

2–4.ソース全体像

<!DOCTYPE HTML>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>タイトル</title>
    <script src="https://cdn.jsdelivr.net/npm/hls.js@latest"></script> </head>
<body>
<video 
    id="video" 
    data-src="./assets/video/output.mp4"
    data-src-hls="./assets/video/output.m3u8">
</video> 
<script>
var video = document.querySelector('#video'); 
if(Hls.isSupported()) {
    var hls = new Hls();
    hls.loadSource(video.dataset.srcHls);
    hls.attachMedia(video);
}else{
    video.src = video.dataset.src;
}
video.play();
</script>
</body>
</html>

PHPStormでHTMLのClass属性からSASSのソースへジャンプできなくなった

PHPStormでHTMLのClass属性からSASSのソースへジャンプできなくなった。

なぜかコンパイル後のCSSへしかジャンプできなくなった。
コンパイル後のCSSファイルのファイルタイプを“PlainText”にすると、SASSのソースに飛ぶようになりました。

対象ファイルを右クリック
対象ファイルを右クリック
PlainTextに
PlainTextに

お知らせのタイトルです。

だみーてきすとです。これは仮入力のためのだみーてきすとです。全く意味はございません。だみーてきすとです。これは仮入力のためのだみーてきすとです。全く意味はございません。だみーてきすとです。

だみーてきすとです。これは仮入力のためのだみーてきすとです。全く意味はございません。だみーてきすとです。これは仮入力のためのだみーてきすとです。全く意味はございません。だみーてきすとです。

Vue3/Vue.js 親コンポネントから子コンポネントのメソッド呼び出し

Vue3/Vue.js 親コンポネントから子コンポネントのメソッド呼び出し

//親コンポネント
<script>
    .
    .
    methods: {
        onPlay(){
            this.$refs.player.play();
        }
    }

    .
    .
</script>
<template>
    <Player ref="player"></Player>
    <button type="button" @click="onPlay">PLAY</button>
</template>

-------------------------------------------------------

//子コンポネント
<script>
    .
    .
    methods: {
        play(){
            document.querySelector('#video').play();
        }
    }

    .
    .
</script>
<template>
    <div>
        <video id="video" src="video.mp4" />
    </div>
</template>

Page 1 of 45

Powered by WordPress & Theme by Anders Norén