だ。ログ。

開発とかスノボとかやきうとか。

PHPからSESを利用してメールを飛ばしてみる

いつかはやろうやろうと思っていたのだが、結局機会がなかったSESでのメール送信。
AWS-SDKまでインストールした状態である事が前提だが、忘備録。

1. サーバーにSES用のアクセスキーを設定する

$ aws configure
AWS Access Key ID [None]: accesskey
AWS Secret Access Key [None]: secretkey
# ここは契約したリージョンに合わせる
Default region name [None]: us-west-2
Default output format [None]: json

この設定を入れていないと、メール送信する際にIAMの権限が無いから拒否する。みたいなメッセージが出てくる。

2. AWSのリファレンスのソースをコピる。
https://docs.aws.amazon.com/ja_jp/ses/latest/DeveloperGuide/send-using-sdk-php.html

ここに有るソースコードをコピる。

<?php

// Replace path_to_sdk_inclusion with the path to the SDK as described in 
// http://docs.aws.amazon.com/aws-sdk-php/v3/guide/getting-started/basic-usage.html
define('REQUIRED_FILE','path_to_sdk_inclusion'); 
                                                  
// Replace sender@example.com with your "From" address. 
// This address must be verified with Amazon SES.
define('SENDER', 'sender@example.com');           

// Replace recipient@example.com with a "To" address. If your account 
// is still in the sandbox, this address must be verified.
define('RECIPIENT', 'recipient@example.com');    

// Specify a configuration set. If you do not want to use a configuration
// set, comment the following variable, and the 
// 'ConfigurationSetName' => CONFIGSET argument below.
define('CONFIGSET','ConfigSet');

// Replace us-west-2 with the AWS Region you're using for Amazon SES.
define('REGION','us-west-2'); 

define('SUBJECT','Amazon SES test (AWS SDK for PHP)');

define('HTMLBODY','<h1>AWS Amazon Simple Email Service Test Email</h1>'.
                  '<p>This email was sent with <a href="https://aws.amazon.com/ses/">'.
                  'Amazon SES</a> using the <a href="https://aws.amazon.com/sdk-for-php/">'.
                  'AWS SDK for PHP</a>.</p>');
define('TEXTBODY','This email was send with Amazon SES using the AWS SDK for PHP.');

define('CHARSET','UTF-8');

require REQUIRED_FILE;

use Aws\Ses\SesClient;
use Aws\Ses\Exception\SesException;

$client = SesClient::factory(array(
    'version'=> 'latest',     
    'region' => REGION
));

try {
     $result = $client->sendEmail([
    'Destination' => [
        'ToAddresses' => [
            RECIPIENT,
        ],
    ],
    'Message' => [
        'Body' => [
            'Html' => [
                'Charset' => CHARSET,
                'Data' => HTMLBODY,
            ],
			'Text' => [
                'Charset' => CHARSET,
                'Data' => TEXTBODY,
            ],
        ],
        'Subject' => [
            'Charset' => CHARSET,
            'Data' => SUBJECT,
        ],
    ],
    'Source' => SENDER,
    // If you are not using a configuration set, comment or delete the
    // following line
    //'ConfigurationSetName' => CONFIGSET,
]);
     $messageId = $result->get('MessageId');
     echo("Email sent! Message ID: $messageId"."\n");

} catch (SesException $error) {
     echo("The email was not sent. Error message: ".$error->getAwsErrorMessage()."\n");
}

?>

まんまAWSソースコードをパクった。
ただ1行だけ違うのは 'ConfigurationSetName' => CONFIGSET, この文字列をコメントアウトした。
このコードの上の行に、使わないならコメントか消してね。と書いてある。
利用していないままコードを貼り付けると

The email was not sent. Error message: Configuration set does not exist.

と言うエラーでメッセージが送信出来ない。これをコメントアウトしたらメールの送信が出来た。

追記

ユーザー毎にキーを生成する必要がある。
1. サーバーにSES用のアクセスキーを設定する
は、実行するユーザーで作っておかないと、他のユーザーで実行した際に設定が無いのでエラーとしてメールが送信できない。

PHPを利用した入力チェックのアンチョコ カタカナ

この頃はjQueryでの入力チェックばかり書いていて、POSTした後にエラーが表示されるタイプのPHP側でのチェックがめっきり減った。
たまに書くとんーどうだっけ。。となるのでコピペ出来るようにメモ。

if(preg_match("/^[ァ-ヶヲ-゚ー  \t\r\n]+$/u",$postdata)){

}

この場合、カタカナとハイフン、それにタブと改行と半角全角スペースの場合は許可。
それ以外の文字列の場合はデータelse挙動として振り分ける。

開幕カードのスワローズ戦を終えて感じた事として、去年のスワローズとは比べ物にならない戦術と攻撃意識

去年開幕前後に名を連ねた大引選手、谷地選手、西浦選手、今浪選手は居ない。
辛うじて西浦選手は代打陣には居るけど、チームのコンセプトとしてとにかく打つ。とにかく打って走る。
山田選手はフォアで出塁すれば走る。 間違いなく去年の打線とは攻撃力が格段に違う。ランナー溜まってグッチこと坂口選手が出てくるとお腹痛いレベルで打つ。

現状では春の風物詩、山田選手は冷えっ冷え。
それも3試合で5見逃し三振、振ってアウトならまだしもアウトを相手に渡してる状況。かなりこれは長く掛かると予測。
青木選手は前評判通り1試合2出塁する、場合によってはバントしてくる。

そのバントを支えるのは去年怪我で1年居なかった川端選手。
川端選手のバットが通常運転で冴え続けている。アウトのなり方がライトに超良い当たりのライトライナーや強襲する鋭い当たり乱発。
三振しない、そしてミスショットがない。この5番が有ってバレ選手と青木選手が引き立つ。

そして今一番恐ろしいのは絶好調の坂口選手。
ランナー溜まるとしっかりボールを打ち返してくる。そしてランナー居ないと振り切って来る。
この切替が出来ている以上、ピッチャーは6番までは気を抜けない。
ランナー溜まって坂口選手だとお腹痛くなるレベルの現状。

廣岡選手は2試合大暴れだったけど3試合目はパッタリ。可能性は無限大、逸材である事は間違いないけどまだ何処かに穴が有る。
いわば山田選手のような何処投げても当ててくるって言う怖さはまだない。
寧ろ振り切る力に注力している感じ、ここの確実性や弱点が解った時にどうなるか。

そして雄平が戻ってきた際に機動力である山崎選手をベンチに下げるか。って言う事も今後の注目点である。

さくらインターネットのphp.cgiの取扱

さくらのレンタルサーバーを使うとphpを利用する際に、php.cgi.htaccess

Action myphp-script /php.cgi
AddHandler myphp-script .php .html

と言うスクリプトがどこにあるかと言う事を明記しなければならない。
このphp.cgiにちょっと癖があって、これをコピーして持っていけばどのディレクトリでも利用する事は可能である。

特に癖のある使い方として、ディレクトリトップではphpを使わず他の階層で使いたい。と言って使い回す事がたまにある。
ただ、ここで毎回ローカルにコピーしたphp.cgiディレクトリ毎にアップした際に動かない事が有る。

アップロードの際にパーミッションがそのままだと0600でアップロードされてしまっていて実行されない事が有る。
その場合はパーミッションを0704に設定すると動作する。
CGIの場合特にパーミッション関連が肝になってくるので、さくらのレンタルサーバーは癖が強い。

今シーズン行ったゲレンデ 石打丸山スキー場

12月23日 晴

越後湯沢近辺のスキー場だとかぐらがひと足早くオープンをし、その後を追うように近辺のスキー場がオープンするのが例年である。
かぐらはどうしてもスロープが多く、ボードにはキツめのレイアウトと言う事もあり、斜面の造りがシッカリした所。と言う事で毎年1回は行く石打丸山スキー場に決定。
同行した友人は石打は初めてらしく、どんなスキー場?ってな事でざっくりと以下にまとめてみる。

ゲレンデの特色

1. ハツカ石口、中央口、銀座口とゲレンデのベースが別れている。
2. 斜度は中級コースでもかなりキツいコースが多い
3. ベースとなるゲレンデの近くにも結構キツめのコースが有る
4. かなり歴史があるので、よく言えばバブリー、悪く言えば古め。
5. 山頂コースの難度は高め、山頂からガーラ湯沢へ降りる事が出来る。(三山共通券が必要)
6. 越後湯沢駅からバスで10分
7. コース幅はそこまで広くない。特に山頂側に上がるにつれコースが絞られる

なんと言っても近い。斜度にメリハリが付いていてスロープが少ないので滑る事を楽しめるゲレンデと言う印象。
12月でまだ雪が降り始めと言う事もあり、パークのアイテムは少なめ。そして土日だがまだ人がまばらで快適に滑れる状況だった。

アットホーム?

今回は銀座口のレンタルショップのコインロッカーを利用する事にした。
その際に受付の方が「お兄さん達日帰り?帰る時間分かる?」と聞かれたので、てっきり閉鎖時間かな?と思い17時だと思います。と返すと
「あーじゃあ帰りの車17時で取っとくからね」との返事が。
石打丸山には雪だるま号と言う、石打丸山 ←→ 越後湯沢を回るバスが有るがレンタルショップの方のご厚意で送迎をやってくれている所もある。
嬉しい誤算と言うか、時間の融通を利かせてくれ必ず座れると言う事は日帰り人間には非常に助かる提案だった。
古くからやっているゲレンデ、周りのゲレンデとの差を付ける為の事かもしれないが、個人的には凄くありがたいサービスであった。

石打特有の。

基本的にゲレンデと言うと山の上なので町や人が生活していると言うよりは、森や林と言った景色がメインであるのに対して石打は魚沼平野や関越道を見下ろし開けた視界を思い切り楽しむ事が出来る。
日常生活のある町並みを眼下に雪山と言う非日常を体験出来る。写真だと画角が狭い為、あまり開けたように見えないが眼下に広がる銀世界の魚沼の平野部を見渡す事が出来る。
この風景を楽しみながらガンガンと本数を滑る。
と言うのが石打の楽しみ方なのだが、この日は生憎朝から気温が上がり続ける。こうなると東向き斜面の石打は午前中にさんさんと降り注ぐ太陽で融雪がすすみ人が滑る事で凹凸がはっきりと付く。
そして太陽が正午を過ぎると西側のガーラに早々に日が落ちていく。12月だと14時を回ると山頂ゲレンデは完全に日陰に入ってしまう。こうなると一気に気温が落ちる。
気温が落ちると一気に雪が冷え固まり、今度はアイスバーンが形成される。これはこの日に限った事ではなく毎年石打に行くと天気が良い度にこの状況が生まれる。
先程迄とは違って雪をボードが食わなくなり、掘られた溝がかなり深く目で追わないとボードの場合は乗り上げてしまったりエッジが言う事を利かずにスピードが出たまま転倒してしまう事もある。
ポジティブに考えると午前中とはコンディションが大きく変わり難易度が格段に上がるので二度楽しめる。と言うところだろうか。
特に山頂コースは斜度が有るので、雪質が良い時とは違いかなり難しいコースに変わる。

盛り上げる

石打は山、そして麓の町を挙げてゲレンデを盛り上げているように感じられる。
まずはフード、クレープ等のスイーツから七輪での焼き肉まで、こだわりのフードが楽しめる。
そして設備面ではパズドラとコラボを行っており、パズドラレーダーを利用すると限定のダンジョンが出る等のスキー・スノボだけでなく、様々なアプローチから集客しようとする気概がそこかしこで観る事が出来る。

アクセス: ★★★★★
越後湯沢駅からバスで10分、タクシーだと2300円、しかもレンタルショップの送迎まで有りいたれりつくせり。
帰りの新幹線の時間に融通が効くのであれば、ナイターを楽しんでもゆっくり帰れる。湯沢界隈は基本的にアクセス良いがその中でも抜群のアクセスであることは間違いない。

ゲレンデ: ★★★☆☆
ボーダーとしての視点で観た時には大きなスロープが少なくコースからリフトの距離が短いので滑りやすい。
ただ山頂に行けば行く程コース幅が狭まってしまう事と、迂回コースはかなり細く狭い。またメインゲレンデをトラバースするルートなので意外とコースを見失う事がある。
新雪が多い時は新雪ジャンキーの上手い人の飛び出しに注意すべき。

施設: ★★★☆☆
どこをベースキャンプにするか。と言う事を先に決めた上で行動しておくべき。
日帰りセンターはハツカ石にはあるものの、他の口は宿泊街に囲まれていきなりゲレンデにたどり着いてしまう。
また、コインロッカー等もかなり数が限られているので、早めに自分が使う場所を確保しておかないとコインロッカーで右往左往してしまう。

食事: ★★★★☆
どこに行ってもハズレがない、ただベースキャンプではなくリフトで上部に行った所に密集している。
個人的には定食モノが一番美味しいと感じる。

総合: ★★★★☆

ファミリーでも楽しめるが若者が連れ立って本数を滑る。と言う感じの石打。
一つ一つのゲレンデのコースレイアウトに各々特色があり、そのコースを把握して次はこう滑ろう。こうしよう。と言う意図を持って滑る事が出来る。
山頂コース側は難しく、ベースキャンプ側ほど広く楽しめるとレイアウトなので人の分散がしっかり出来ている。
日帰りのゲレンデの中では値段もリーズナブル、そして12月のシーズンはじめはかぐら等に比べると人がまばらなので練習しやすい。
2月くらいからはじまる三山共通券を利用すると、石打丸山ガーラ湯沢、そして湯沢高原スキー場へと渡る事が出来る。
石打よりももう少しゆったり滑りたいのであればガーラと言った滑り分ける事も出来る。
また越後湯沢を使わず敢えてガーラ湯沢で着替えまで済ませガーラから石打に渡り、帰り際にまたガーラ湯沢に戻ると言った利用のしかたも出来る。

個人的にはリフト終了前に山頂まで上り、上から一気に自分のベースとしたゲレンデまで一気に滑り降りるのが一番の楽しみ。
ただ、気をつけないと出口のゲレンデを間違えて歩かねばならない。下のコースをあまり滑らないと把握できなくなるので注意。
f:id:rider_dice:20180315180138j:plain

Doctrineで発行したSQLを表示させる

どうしてもEC-CUBEを使っていると避けられないDoctrine、使えれば便利。と言う事だが旧型人間なのでクエリが確認出来ない事にもどかしさを感じる。
結局の所、SQL式が正しいかの評価がし辛い所は難点。憎きqbからSQLを取り出す為のコード

	print_r($qb->getQuery()->getSQL());

以外と簡単に取り出せる。
何を現在取得しているか。と言う事を確認する場合は上記のやり方でいける。

EC-CUBE3のテンプレートで税抜き価格を表示する

商品詳細ページに登録されている価格が、運用によっては税込税抜ってまちまちなってしまっている。
先にその辺を取り決めておけば良いのだが、後々カスタマイズを入れると変更したいってなる事が多い。

と言う訳で、基本は税込になっているテンプレートを税抜にしてみる。

/src/Eccube/Resource/template/default/Product/detail.twig

                    <!--★販売価格★-->
                    {% if Product.hasProductClass -%}
                        {% if Product.getPrice02IncTaxMin == Product.getPrice02IncTaxMax %}
                        <p id="detail_description_box__class_sale_price" class="sale_price text-primary"> <span class="price02_default">{{ Product.getPrice02IncTaxMin|price }}</span> <span class="small">税込</span></p>
                        {% else %}
                        <p id="detail_description_box__class_range_sale_price" class="sale_price text-primary"> <span class="price02_default">{{ Product.getPrice02IncTaxMin|price }} ~ {{  Product.getPrice02IncTaxMax|price }}</span> <span class="small">税込</span></p>
                        {% endif %}
                    {% else -%}
                        <p id="detail_description_box__sale_price" class="sale_price text-primary"> <span class="price02_default">{{ Product.getPrice02IncTaxMin|price }}</span> <span class="small">税込</span></p>
                    {% endif -%}

この IncTaxを削る。

                    <!--★販売価格★-->
                    {% if Product.hasProductClass -%}
                        {% if Product.getPrice02Min == Product.getPrice02Max %}
                        <p id="detail_description_box__class_sale_price" class="sale_price text-primary"> <span class="price02_default">{{ Product.getPrice02Min|price }}</span> <span class="small">税込</span></p>
                        {% else %}
                        <p id="detail_description_box__class_range_sale_price" class="sale_price text-primary"> <span class="price02_default">{{ Product.getPrice02Min|price }} ~ {{  Product.getPrice02Max|price }}</span> <span class="small">税込</span></p>
                        {% endif %}
                    {% else -%}
                        <p id="detail_description_box__sale_price" class="sale_price text-primary"> <span class="price02_default">{{ Product.getPrice02Min|price }}</span> <span class="small">税込</span></p>
                    {% endif -%}

元々税込がデフォになっているので明示的に税込と言う命令を削る。