matsudada技術ブログ

日々の雑念と備忘録

S3の静的ウェブサイトホスティングの罠

S3の静的ウェブサイトホスティングの罠

現象

Clipboard API を検証しようとして、S3で「静的ウェブサイトホスティング」を使用したところ、https接続できず検証できなかった。

画像をクリップボードにコピーするコード

async function writeClipImg(imgUrl) {
    try {
        const data = await fetch(imgUrl);
        const blob = await data.blob();

        await navigator.clipboard.write([
            new ClipboardItem({[blob.type]: blob})
        ]);
        console.log('Fetched image copied.');
    } catch (err) {
        console.error(err.name, err.message);
    }
}

const targets = document.getElementsByClassName("copyable");
for(let i = 0; i < targets.length; i++){
    targets[i].addEventListener('click', () => {
        writeClipImg(targets[i].getAttribute("src"));
    }, false);
}

対応

https://s3-ap-northeast-1.amazonaws.com/<バケット名>/index.htmlの形式でアクセスするように変更した。

参考

1) https://s3-ap-northeast-1.amazonaws.com/<バケット名>/sample1.jpg (デフォルト(「REST APIエンドポイント」)で使える、パス形式のバケットへのアクセス方法) 2) https://<バケット名>.s3-ap-northeast-1.amazonaws.com/sample1.jpg (デフォルト(「REST APIエンドポイント」)で使える、仮想ホスト型式のバケットへのアクセス方法) 3) http://<バケット名>.s3-website-ap-northeast-1.amazonaws.com/sample.html(ウェブサイトエンドポイントを構成をした時のみ使える)

この内3)のドメインフォーマットでは、https 通信が使えません。

https://qiita.com/Yuhkih/items/1754ac9caf3f12d75946

感想

「静的ウェブサイトホスティング」でしかhtmlの公開ができないのかと思い込んでいた。

Clipboard APIの方はChromeではimage/jpegに対応していないようだったので、使用しないことにした。(サポートしているMIME TYPEのリストは探したが見つからなかった。)

TCPDFで日本語カスタムフォントをPDFに埋めこむ方法

TCPDFで日本語カスタムフォントをPDFに埋めこむ方法

TCPDFでカスタムフォント(IPAexゴシック)を使用してPDFを作成したが、
PDFにフォントが埋め込まれておらず表示する環境によりフォントが変わっていた。
その原因と対応について記載する。

環境

  • PHP 7.2.10
  • setasign\Fpdi ver.2
  • tecnickcom/tcpdf ver.6.2.25
  • IPAexゴシック ver.003.01

現象

コマンドで事前に登録したフォントをPHPで設定しPDFの作成をしていたが、
PDFにフォントが埋め込まれていない。

フォントを登録するコマンド(PDFに埋め込まれない)

php ./vendor/tecnickcom/tcpdf/tools/tcpdf_addfont.php -b -t CID0JP -f 32 -i ./resources/fonts/ipaexg00301/ipaexg.ttf

PHPでフォントを設定した部分のコード

$pdf = new Fpdi\TcpdfFpdi();
$pdf->SetFont('ipaexg');
// 以降でファイル内容の作成処理

対応

フォントを登録するコマンドが誤っていた。
IPAexフォントのReadmeにもあるとおり、IPAexフォントはTrueTypeアウトラインベースのOpenTypeフォントTrueTypeフォントの拡張版)なので、TrueTypeで登録する必要がある。

# CID0JPのフォント種類で追加⇒ipaexg.phpファイルしか作成されない
php ./vendor/tecnickcom/tcpdf/tools/tcpdf_addfont.php -b -t CID0JP -f 32 -i ./resources/fonts/ipaexg00301/ipaexg.ttf

# TrueTypeUnicodeのフォント種類で追加(-tオプションで指定しない場合も同様)
# ⇒ipaexg.ctg.z, ipaexg.php, ipaexg.z の3ファイルが作成される
php ./vendor/tecnickcom/tcpdf/tools/tcpdf_addfont.php -b -t TrueTypeUnicode -f 32 -i ./resources/fonts/ipaexg00301/ipaexg.ttf

また、TCPDFの仕様でそもそもコアフォントとCID-0フォントはPDFに埋め込みされないようである。

The fonts that could be not embedded are only the standard core fonts and CID-0 fonts.

https://tcpdf.org/docs/fonts/

参考

TCPDF をダウンロードして、フリーフォントを埋め込み型で使用する方法
http://logicalerror.seesaa.net/article/374474910.html

感想

浅い理解ではあるが、とりあえず問題は解消。
フォントの知識がまるで無かったので、フォント種類の名前くらいは分かるようにはなった。

ただ疑問なのが、CID0JPって結局なんなのだろうか。 CIDフォントなのは分かるが詳しイことが分からない。Adobe-Japan1-0のこと?

PHP7.2:Excelで編集できるCSVを作る

PHP7.2:Excelで編集できるCSVを作る

Excel 2016以降はUTF-8で扱えるようですので、2013以前の場合のお話です。

このやり方でダウンロードしたCSVファイルをExcelで編集してそのままアップロードできます。
ただ、Excelによる値の変換(ex.全角数字のみの項目は半角数字に変換される、数字の頭に有る0が消える)は起きるので注意してください。

環境

現象

CSVファイルをExcelで開くときに、文字コードSJIS以外の場合はBOMをつけないとSJISで読み込もうとして文字化けしてしまう。

また、開いたCSVファイルを保存したときにExcelが自動変換してしまう。

Excelで開いたとき、保存したときの動作は下表の通り。

区切り文字 文字コード BOM Excelで開いたときの動作 Excelで保存したときの動作
カンマ UTF-8 無し 項目がセルごとに別れる。文字化け カンマ区切り・SJISで保存
カンマ UTF-8 有り 項目がセルごとに別れる。文字化けしない タブ区切り・SJISで保存
カンマ UTF-16 LE 有り セルごとに別れない。文字化けしない 1行が1項目扱い・UTF-16 LEで保存
タブ UTF-8 無し セルごとに別れない。文字化け 1行が1項目扱い・SJISで保存
タブ UTF-8 有り セルごとに別れない。文字化けしない 1行が1項目扱い・SJISで保存
タブ UTF-16 LE 有り 項目がセルごとに別れる。文字化けしない タブ区切り・UTF-16 LEで保存

対応

対応策としては2通り。今回は下のパターンで対応します。

  • カンマ区切りのSJISで出力する
  • タブ区切りのUTF-16 LEで出力する

参考リンクを参考にstream_filterでUTF-16 LEに変換し、タブ区切りで出力する。

// ストリームを開く
$fp = fopen('php://output','w');

// 文字コードを変換するフィルター
stream_filter_prepend($fp, "convert.iconv.utf-8/utf-16le//TRANSLIT");

// BOMをつける
fwrite($fp, "\xEF\xBB\xBF"); //UTF-8

// CSVのヘッダ行出力
$csvHeader = ["1列目", "2列目", "3列目"];
fputcsv($fp, $csvHeader, "\t");

// レコード出力
foreach ($rows as $row) {
    fputcsv($fp, $row, "\t");
}

// ストリームを閉じる
fclose($fp);

参考

[PHP] MacExcelと互換性のあるCSVファイルを出来るだけ効率よく作成する
https://qiita.com/mpyw/items/2795bef3ed561f4cf4e9

PHPのストリームフィルタでCSV読み込み
https://qiita.com/rana_kualu/items/dc99be34b9e2f721b70f

感想

お願いですからUTF-8で処理できるようにしといてください。

というか2016以降を使えという話かもしれないが。

一点分からないのが、なぜ付与するBOMが「\xFF\xFE」(UTF-16 LE)でなく「\xEF\xBB\xBF」(UTF-8)なのか。

BOMもstream_filterで変換されるのだろうか?

もう少し調べる必要がある。

Laravel 5.7:生のSQLを利用してページネーション

Laravel 5.7:生のSQLを利用してページネーション

クエリビルダーでページネーションをするサンプルは多いが、

生のSQLからページネーションをする例は少なかったため記載

環境

現象

クエリビルダーからはpaginateを呼ぶことができるが、

DB::selectは、結果がarrayなのでpaginateが呼べない。

$perPage = 50;

$rawQuery = "
    select
        hoge
    from
        table_a";

$result = \DB::select(\DB::raw("{$rawQuery}")); // ⇒結果がarrayなので、paginateは呼べない

対応

副問い合わせの形でクエリビルダに入れ込んだ。

$perPage = 50;

$rawQuery = "
    select
        hoge
    from
        table_a";

$result = \DB::table(\DB::raw("({$rawQuery}) as alias"))
->select("hoge")
->paginate($perPage);

結果の表示

<div>
    <form>
        {{-- 検索条件 --}}
    </form>
</div>

<div>
    @if(!empty($results))
    <div>
        @foreach($results as $row)
        <div>{{ $row->hoge }}</div>
        @endforeach
    </div>
    
    <div>
        {{ $results->appends($_GET)->links() }}
    </div>
    @endif
</div>

WCS2019エリア代表決定戦

WCS2019エリア代表決定戦

目標

3000位以内

結果

2227位

f:id:matsudada:20190614185506p:plain
2227位

総括

とりあえず目標は達成

迷ったときに流行りのサブテラーや墓所青眼を使ったが、
メタったデッキが多い点と練習不足により勝率が出なかった。
結局、前環境の時に慣れている六武で勝率を伸ばした。
更に上に行くには、初日や二日目の時点で勝率を出せるデッキを模索する必要がある。

各デッキの勝率

使用キャラ 使用デッキ 勝利数 敗北数 勝率
キース すりかえ コアキネオス 7 6 53.84615385
仮面 同胞サブテラー 7 12 36.84210526
迷宮兄弟 魔神招来 スナストネオス 11 8 57.89473684
クロノス レッドアイズバスブレ 22 24 47.82608696
イシズ 墓所青眼 8 14 36.36363636
クロノス 粉砕六武 52 28 65

使用デッキ

すりかえコアキネオス (1戦目~13戦目)

スナスト3
マキシマム
アイス2
バレット3
チェンジャー
ネオス2
ネオフュ3
金剛3
こうかく1
はねくり1

f:id:matsudada:20190614124802p:plain
すりかえコアキネオス

同胞仮面サブテラー(14戦目~32戦目)

アサイ
ならず者
リグリ3
翻弄
アクエリ
ブリンカー
戦士3
同胞3
決戦3
フレファイ2
ゴーストリックパニック

f:id:matsudada:20190614125421p:plain
同胞サブテラー

招来スナストネオス(33戦目~51戦目)

スナスト3
クリボール3
翻弄3
タスケル
バレット3
ネオス2
ラクフュージョン
ネオフュ3
星遺物2
狡猾1

f:id:matsudada:20190614125617p:plain
招来スナストネオス

レッドアイズバスブレ(52戦目~66戦目, 77戦目~107戦目)

ワイバーン2
ブラックメタル3
クリボール2
バスブレ2
レッドアイズ2
フュージョン2
破壊剣士融合
インサイト3
ネクロフュージョン2
狡猾2

f:id:matsudada:20190614125928p:plain
レッドアイズバスブレ

墓所青眼(67戦目~76戦目, 154戦目~165戦目)

霊廟
スナスト3
太古3
クリボール3
霊龍2
曙光2
コスモ3
青眼2
狡猾2

f:id:matsudada:20190614184737p:plain
墓所青眼

粉砕六武(108戦目~153戦目, 166戦目~199戦目)

師範2
キザン2
エニシ2
キザル
フウマ3
しんえい
星遺物2
幽閉
結束2
道場2
2刀流2

f:id:matsudada:20190614185319p:plain
粉砕六武

Bladeテンプレート上で条件によりURLを切り替える

Bladeテンプレート上で条件によりURLを切り替える

Bladeテンプレート上でControllerから渡した変数によってURLを切り替える時のやり方で少し詰まったので、備忘録として記載

環境

  • Laravel 5.7

現象

ルート名から分岐などなくURLを生成するケースでは、以下の様なコードで生成できる。

<a href="{{ route('your.route.hoge') }}">リンクテキスト</a>

⇒生成されるコード
<a href="http://domain/hoge">リンクテキスト</a>

しかし、変数によって分岐させたいときに以下のコードではうまくいかない。

<a href="
  @if ($state === 1)
      route('your.route.hoge1')
  @elseif ($state === 2)
      route('your.route.hoge2')
  @elseif ($state === 3)
      route('your.route.hoge3')
  @endif
">リンクテキスト</a>

⇒生成されるコード
<a href="route('your.route.hoge1')">リンクテキスト</a>

対応

以下のようなやりかたで生成できた。

<a 
    @if ($state === 1)
        href={{ route('your.route.hoge1') }}
    @elseif ($state === 2)
        href={{ route('your.route.hoge2') }}
    @elseif ($state === 3)
        href={{ route('your.route.hoge3') }}
    @endif
>リンクテキスト</a>

⇒生成されるコード
<a href="http://domain/hoge1">リンクテキスト</a>

しかし、そもそもViewで分岐などをやろうとするのが良くないので、 Controllerでurlを変数に設定してViewからは呼び出すだけにした方が良いと思う。

<a href="{{ $url }}">リンクテキスト</a>

Source TreeのGit Flow操作にオプションをつける

Source TreeのGit Flow操作にオプションをつける

Source TreeでReleaseブランチを完了するときにエラーが発生した。

gitコマンドにオプションをつければ良いことは分かったが、SourceTreeでの実現方法が分からなかった。
結論としては、 下記フォルダ内のgit flowのコマンドに対応するファイルを修正する。
C:\Users{ログインユーザー}\AppData\Local\Atlassian\SourceTree\gitflow_local\gitflow\

環境

現象

git flowのブランチワークに沿って管理しているプロジェクトでReleaseブランチを完了するときにエラーが発生した。

エラー内容

Switched to branch 'master'
Your branch is up-to-date with 'origin/master'.
fatal: refusing to merge unrelated histories
There were merge conflicts.

原因

git 2.9以降のバージョンのデフォルト設定では、共通のノードを持たないブランチはマージできないようになっているらしい。

"git merge" used to allow merging two branches that have no common base by default, which led to a brand new history of an existing project created and then get pulled by an unsuspecting maintainer, which allowed an unnecessary parallel history merged into the existing project. The command has been taught not to allow this by default, with an escape hatch --allow-unrelated-histories option to be used in a rare event that merges histories of two projects that started their lives independently. https://stackoverflow.com/questions/37937984/git-refusing-to-merge-unrelated-histories-on-rebase

対応

上記引用にもあるが、コマンドの場合は"--allow-unrelated-histories"オプションをつければよい。
Source Treeで実現するには、Release完了時に実行される下記ファイルを修正する。
C:\Users\{ログインユーザー}\AppData\Local\Atlassian\SourceTree\gitflow_local\gitflow\git-flow-release

# master(228行目)とdevelop(258行目)へのマージがあるので2ヶ所修正する。
# git merge --no-ff "$BRANCH" || \
# ↓の様に変更する。
git merge --no-ff "$BRANCH" --allow-unrelated-histories || \