2016-04-01

PHPの自動テストcodeception【実行サンプルDL可】

開発を多数こなしていると、やはり感じるのは実行テストというのはなかなか難しいなということです。
というのも、やはりプログラムを組んだ本人はもちろんそれでうまくいくと信じてコードを書いているわけで、残念ながら基本的なバグに気がつかなかったりします。

この辺は前から懸案だったたのですが、「じゃあ自動テストは?」というと人の目でチェックしていないため完璧ではなく、しかも時間がかかり、さらにテストコードすらテストが必要になるんだろ?というのが頭にずっとあったため正直言うと敬遠してきたという経緯があります。

しかし、今回は「デバッグの効率化」という観点から現在人気があり、なおかつとてもシンプルに自動テストができる「Codeception」を体験してみました。
雑感としてはとても好感触です。
今後は納品する際にテストの結果をつけてもいいのかなと考えています。

・・・と、いうことで今回は「Codeception」のインストール〜Acceptance testの基本的な使い方をご紹介します。


【Codeceptionの実行結果サンプル】




【実行環境】
OS: Ubuntu 14.04
言語: PHP 5.6.19


【インストール】
ここではグローバルで利用ができるようにインストールする方法です。
以下のコマンドをターミナルから実行します。

sudo curl -LsS http://codeception.com/codecept.phar -o /usr/local/bin/codecept
sudo chmod a+x /usr/local/bin/codecept

はい。これで codecept コマンドが利用できるはずです。
codecept -v
を実行すると 2.1.7 がインストールされていました。
(ちなみに2016/03/31の時点で2.2 は今ベータ版だそうですので、すぐに正式版が出そうですね。)


【自動テストの開始】
ターミナルでテスト実行したいサイトのルートフォルダへ移動して以下のコマンドを実行します。
codecept bootstrap
これを実行すると、以下が作成されます。

1. codeception.yml
2. testsフォルダ


【Acceptance Test の設定】 

tests/acceptance.suite.yml ファイルを開いてトップページのURLをセットして保存します。
class_name: 
AcceptanceTester
modules:
    enabled:
        - PhpBrowser:
            url: {あなたのチェックしたいサイトのトップURL}
        - \Helper\Acceptance


【自動テストファイルの作成】

codecept generate コマンドを使って個別の自動テストシナリオを作成します。

codecept generate:cept acceptance Welcome

これは、「Welcome」という名前のAcceptance Test(受け入れテスト)をするファイルを作成するという意味になります。
そして、実行後は以下にファイルが作成されますのでここに実際に命令を追加していくことになります。

・tests/acceptance/WelcomeCept.php


では実際の例を見てみましょう。

(実際の例)
$I = new AcceptanceTester($scenario);
$I->wantTo('フォームエラーをチェック');
$I->amOnPage('/form_error');
$I->see('フォームエラーのテスト');
$I->click('送信する');
$I->see('メールアドレスは必須です。');
 見ての通り、シンプルな英語の文法とほぼ同じなのでとても簡単に追加ができます。

1行目はお約束の文章。($Iは「私」のアイです。)
2行目「wanTo」はこのファイルで実行するテストの要約です。実行テスト自体には関係ありません。

3行目からが自動テストの本体になります。具体的には、

amOnPage(): 「/form_error」にアクセス
see(): 「フォームエラーのテスト」という文字があるか確認
click(): 「送信する」ボタンをクリック
see: 「メールアドレスは必須です。」という文字があるか確認

となります。
つまり、チェックの流れとしては、

1. わざとメールアドレスを入力せずに
2. 送信ボタンをクリック
3. エラーが表示

となります。

以上、本当に基本的ですが以下にシンプルかを知ってもらいたかったのでこの辺で終了します。
他にも「DBにデータが存在してるのか?」 といったチェックもできるので興味のある人は以下からチェックしてみてください。

Codeception(英語)
Codeceptionの公式ドキュメントの日本語化(ガイドのみ)


(ちなみに)
この動画はCodeception入門者にはとてもわかり易いと思います。
ホントに便利な時代になりましたよね。



(終わりに)
ふと、クライアントにテスト結果を提出するとき英語じゃやっぱり嫌がられるのかな...?と感じました。
時間ができたら自動翻訳ページ作ってみても面白いかもしれません。
あと、JavaScriptは実行できないのでその辺は Selenium  などとも連携できるようなのでまたトライしてみたいと思います。







2016-03-29

【Blade】Laravelテンプレートの便利な書き方

昨日RedditのPHP板でテンプレートエンジンの話が出ていて興味をもったので、この際、Laravelのテンプレートエンジン「Blade」でできる便利な書き方を(@extends@sectionなどのメインは省いて)3つまとめてみました。




 1.「or」でチェックを省略ができる

もし変数に何も入っていない可能性がある場合、Blade内でPHP記法を使うと以下のようになります。
@if(isset($test))
    {{ $test }}
@else
    変数の中身がありません。
@endif
どの言語でもおなじみの if文ですね。
でもBladeを使うと上の5行がたった1行でできるようになります。
それが「or」です。
{{ $test or '変数の中身がありません。' }}
どうでしょう。
三項演算子を使うと1行でも書けなくはないですが、おそらくこちらの方がデザイン担当の人が見てもわかりやすいんじゃないでしょうか。
もちろん以下のようにいろんな変数名を指定できます。
{{ $blog->title or 'Default' }}


2.「forelse」でもチェックを省略できる

PHPで配列をひとつずつ取り出して計算をする際には for や foreach を使うと思います。
Blade でもこのループの書き方は同じで以下のようになります。
@if($posts->count() > 0)
    @foreach($posts as $post)
        {{ $post->title }}
    @endforeach
@else
    データが見つかりませんでした。
@endif
このケースではDBからデータを取得しているので count() を使ってデータが入っているのかをチェックしています。
なんだか少しゴチャゴチャしていますね。

これがBladeでは以下のように書くこともできます。
@forelse($posts as $post)
    {{ $post->title }}
@empty
    データが見つかりませんでした。
@endforelse
表示がスッキリしました。
「できるだけエラーを出さないためにはできるだけコードを書かないこと」という原則を考えるならこちらの方が断然方がいいですね。
もちろん、 foreach と 同じく、以下のようにインデックスも取得できます。
@forelse($posts as $index => $post)


3.各言語を呼び出す

これは日本語圏の環境では利用する機会は少ないかもしれませんが、翻訳された単語を取得する際、より省略した記述をすることができます。
Laravelでは trans() もしくは Lang::get() という2つの取得法があるため通常は以下のようになります。
{{ trans('validation.accepted') }}
{{ Lang::get('validation.accepted') }}

これがBladeではこう書くことができます。
@lang('validation.accepted')
文字数的にはそこまで差はありませんが、横のヒゲがなくなっているので可読性は上がっていると思います。

以上、短いですがBladeの便利な書き方でした。
ちなみに最近は Twig (←小枝という意味みたいです)という高機能なテンプレートエンジンも人気があるようですが、どうやらPHPのコードを直接追加できならしく、またBladeの方が軽いらしいので、私の場合はもし採用するとしてももう少し先になるかなーと思いました。

(それにしても、PhpStormから直接貼り付けるとコード部分が楽に作成できていいですね。^^)



2016-03-25

【PHP】独自パッケージを composer で使えるようにする方法

以前「Laravel の独自パッケージを作成する「PackageCreator」を公開しました」で書いたように、今回は作成した独自パッケージを公開し、さらに composer でインストールするまでを紹介したいと思います。



手順としては、以下の2点です。

1.Githubへパッケージをアップする 
2.Packagistへパッケージ登録

(※事前準備として、GithubPackagistにアカウント登録し、composer 、git が使えるようにしておいてください。)



それでは、ひとつずつ見ていきましょう。


1. Githubへパッケージをアップする

まずGithub にログインし、独自パッケージ用のレポジトリを作成します。
右上にあるボタンをクリックした時に出てくる「New repository」をクリック。



パッケージ名と説明文を入力、さらに「Initialize this repository with a README」にチェック✔を入れてボタンをクリックすれば完了です。



次にローカル環境でターミナルを開き、cd コマンドをつかって独自パッケージのディレクトリまで移動しましょう。


ここで git の初期化コマンドを実行します。

git init


そして、git pull を使って先ほど Github レポジトリからファイルを取り込みます。

git pull https://github.com/xxxxxxxx/xxxxxxxx.git

※ちなみに、レポジトリの git URLは以下の場所に書かれています。




はい!
これでローカル環境からファイルをアップロードできるようになりました。



続いて composer init を使って composer に必要なファイル「composer.json」を作成しましょう。
以下のコマンドを実行すると、パッケージ名や説明文を聞かれるので入力していきます。
重要なのは以下の3つ。

Package name (<vendor>/<name>)  ・・・ パッケージ名
Description ・・・ パッケージの説明文
License・・・ パッケージのライセンス。後でPackagistで注意されるので^^;

これで composer.json が出来上がります。


ちなみに、もしコマンドラインが好きじゃない人は普通に composer.json を作ってもOKですし、後から変更するのも普通にエディタから変更することができます。


そして、README.md も適宜変更しましょう。
このファイルは markdown という形式で作成する必要があります。(こちらのページがとても便利だと思います。)


さぁ、それではやっと Github へのアップロードです。
実際には以下のようにして行います。

git add .
git commit -m="First commit"
git push https://github.com/xxxxxxxx/xxxxxxxx.git master

この時ログインID, パスワードを聞かれたら入力してください。
アップロードがうまくいっていれば Github ページが変更になっているはずです。


はい!
ここまでがGithubへのアップロード手順です。



(今回は記事が長いね...分けたほうが、良かったね....)



2.Packagistへパッケージ登録

では次に packagist です。
ログインして右上の「submit」から登録ページへ移動し、githubで先ほどつくったページのURLを入力してパッケージを登録します。


これでパッケージが composer からインストールできるようになっているはずです。
実際にはこのような形になります。

composer require sukohi/xxxxxx:dev-master

※sukohi/xxxxx の部分は composer.json の name にかかれている値です。



ちなみに、Github のウェブフックを使えば git push されるたびに自動で packagist も最新版にアップされるのでぜひ設定しておきましょう。
やり方はこんな感じです。

1.まず packagist からトークンを取得します。


2.先ほどつくった Github のパッケージページから setting > Webhooks & services へ移動し、「Add Service」ボタンの中から Packagist を選択します。
すると、以下のようなページが表示されるので先ほど Packagist のユーザー名と取得したAPIトークンを入力しましょう。

これでウェブフックの設定は終了です。


(あと1トピックだけ、、、)


また将来のことを考えると git で 1.0 や 1.0.0などブランチとタグをつかってバージョンを作成しておくといいと思います。
やり方は以下。

(ブランチ)

git branch 1.0
git checkout 1.0
git push https://github.com/xxxxxxxx/xxxxxxxx.git 1.0

(タグ)
git tag 1.0.0
git push https://github.com/xxxxxxxx/xxxxxxxx.git 1.0.0

※もしバクを修正したり新しい機能を追加したらブランチを同じようにpush し、タグを「1.0.1」というのようにバージョンを上げて push しましょう。
ウェブフックを設定しているなら自動で packagist も最新版になっているはずです。


composer でバージョンを指定してインストールするには以下のようにします。

composer require sukohi/xxxxx:1.*

はい!
これで終了です。

独自パッケージを作って公開しておけば、後から同じ作業を省略できますし、もしバグがあれば他のユーザーから教えてもらえるかもしれないのでメリットは多いですよ!

なにより自分のパッケージにスターがついたりするととてもテンションが上がります。
ぜひみなさんもトライしてみてくださいね。
ではでは〜!(^o^)


 (スマホで記事の原案を書くとなぜか記事が長くなるなー)


2016-03-19

【LINE】突然アカウントを失いかけた話

最近になって何の前触れもなくスマホの動きが極端に遅くなってきてました。
たまに電車に乗った時なんかは Bluetooth のイヤホンを使って窓の外の景色を眺めるのが好きなんですけど、このスマホのせいで曲がよく途切れてしまっていつもイライラさせられていました。

もういい加減限界に近づいてきていたのでいっそのこと工場出荷時まで戻してやろうと思い、かるーい気持ちで即実行にうつしました。
(ちなみにLINEのメールアドレスとパスワードは登録していてきちんと別で保存していました)

…が、しかーし!
この初期化のせいで後で冷や汗をかくことになりました。^^;


手順としては

1.工場出荷時に戻す
2.使ってたアプリをインストール
3.ニコニコしながら電車で音楽を楽しむ

 とてもシンプルなもんですね。


でも、僕に待ち受けていたのは、、、

「2段階認証」 


ええっ!


前はそんなのなかったぞ!?



そうなんです。
LINEはセキュリティの関係でインストールしてメールアドレスとパスワードだけあればアカウントを復活できるわけではないんですねー。。

僕の場合は最初にショートメッセージ認証をしてOKかなと思っていたら2段階認証を要求されました。そして、海外へ言った関係上携帯電話を登録していなかったんですね。

だから認証のためのパスワードももちろん受け取れない。


「終わった」


今まで買い集めたスタンプたち、さようなら、、、、、、、、、、、、、

そして、LINEでしか連絡がとれないフレンドたち、さようなら、、、、、、、、、、、、、、、、、、、、(これが一番辛かった T^T)



もう策なしだと思ったので、仕方なしに新アカウントを作成しようとしたその瞬間思い出しました。


「そうだ!パソコン版のLINEがあるじゃないか!」


そうです。
じつは2段階認証のパスワードはLINEの公式アカウントの方にも送信されてくるらしいんです。

そこで早速パソコンでLINEに「こんにちは」してみると…


「 あったぁあーーーーーー!」


きちんと送られてきていました。
ほんとにこの瞬間にはITの神様にありがとうと言いたい気持ちでした。
たぶんその昔、東京の神田明神(←ITの神様だそうです)にわざわざ遠いながらも寄ったことで守られたのだろうとも思いましたよ。


…ということで、なんとかその2段階認証パスワードを使ってアカウントの引き継ぎに成功したのでした。
ホントにパソコン版があって良かったです。




しかしまぁ、なんてLINEは不便になったものだと思いました。
パソコン版を除いて基本一つのデバイスに一個だけしかアカウントを作れないし、登録する際にSMS認証は必要だし(←この辺は携帯会社の圧力か!?とすら思ってしまいますね。(笑)陰謀論はあまり信じませんけど)

状況が少し特殊かもしれませんが、とにかく皆さんも気をつけてください。
LINEを失うってことは友達を失うことにもつながるってホントこわいですねーーー。orz...




2016-03-10

【PHP】顔認証の精度をあげるためやったこと

とある開発で画像から顔だけを切り出す必要あったので、いろいろとGoogleさんで探っていたらすでに「php-facedetection」というパッケージを公開している人がいました。

やっぱり世界中には天才的なプログラマがゴロゴロしてるんだなーと関心しつつ、なによりPHPでも画像から顔だけを切り出すことができるという事実にとても感動しました。
デジタルとリアルが融合してる気がしたんですね(笑)

ってことで早速誰かの顔を抽出しよう!
・・・とはならず、まずどうやって(効率的に)顔を検出しているのかが気になってしょうがなかったのでこれもGoogleさんで探ってみました。

するととてもわかりやすく説明してくれている記事を発見!
このページはまるでテレビ番組のように「Viola & Johns」と呼ばれる顔認証テクニックをわかりやすく紹介してくれています。
↓↓↓

サルでもわかる顔検出の原理


この記事を読むと顔が入っている画像には共通のパターンがあって、それを利用することで顔認証をショートカットしているようです。
やっぱり賢い人はすごいねー。

ひと番組楽しんだ感覚を覚えた後、「php-facedetection」を使って実際に顔検出をやってみました。


すごい!

こんなに簡単に画像から顔を抽出するなんて。。
その昔ニュートンが「俺が遠くまで見渡せるのは巨人の肩の上にのっかってるからだぜ」って名言を思い出しましたよ。


しかし!

顔を自動で抽出してくれるのはいいんだけど、画像によってはやっぱり精度がよくなったりする。
というのも、実際には顔じゃないものまで顔として検出してしまうことが少なくなかったから。

…ってことで僕も今いる巨人の肩の上でさらにつま先立ちができるよういろいろと考えてみました。
まず考えたのは、色を使ってフィルターをかける方法です。

この方法は「顔は基本的に肌色なんだから肌色が適度に含まれているものだけ抽出する」というものです。
実際には以下のページを参考にどんな色がどれだけ含まれているかを抽出してみました。

http://stackoverflow.com/questions/3468500/detect-overall-average-color-of-the-picture/3468588#3468588

そして、「肌色が他の色の何%になっているか」を計算して、それがある範囲以内なら「顔」として判断するようにすると期待通り、少しだけ精度が上がりました。
(今回ターゲットにした色は['FFCC99', 'CC9966', 'CC9999', 'FFCCCC']の4つです)


でも、でも、、、それでもまだ顔じゃないものまで検出されてしまう。。。

んー、もうこのまま妥協しようかとも思った瞬間にひとつアイデアが浮かびました。
php-facedetection抽出してくれる顔は、もちろん顔だけじゃなく髪の毛や背景なども含まれています。

じゃあ、「画像の真ん中だけをくり抜いて、そこに肌色ばっかり残ってたらほぼ顔ってことになるんじゃ?」

ってことで早速やってみたらさらに精度があがってほぼたまにしか顔じゃないものを検出しなくなりました。

とまぁ、色を使ってフィルターをかけることで(今のところは)満足がいく精度で顔画像だけを抽出することができました。
めでたしめでたし。^-^

(それでもたまーに顔以外もはいってくるし、そもそもphp-facedetectionは画像につきひとつしか顔を検出できないけどね。。^^;)


どうやら以下のページのように画像から肌色だけを抽出するというアプローチもあるみたいです。
時間ができたらいつか機械学習も含めて勉強してみようかな、、、英語の勉強が終わったら(笑)

https://www.blogger.com/blogger.g?blogID=6545450414259005128#editor/target=post;postID=6012962723697327725


※ちなみに僕の好きなX Japanで顔認証をためしたらギタリストの Pataさんが検出されました。ファンとして早いご回復を切に願っています。m_ _m


2016-03-06

Laravel の独自パッケージを作成する「PackageCreator」を公開しました。

Laravelでの開発を行っていると「この機能はきっとまた必要になるときが来るはず!」という場面に多々出会います。
そんなときは独自パッケージを作りましょう。
Laravelの強みのひとつは「世界中のプログラマが作成した独自パッケージ」が利用できるという点にあると思います。

ただ、パッケージを作成するには「Laravel の独自パッケージを作成する手順 」 「Laravel 5 の独自パッケージを作成する手順 」でも紹介しましたが多少の労力が必要になります。
毎回やっているとこれはなかなかめんどくさかったりします。

そこで!
今回はこの独自パッケージに必要なファイルを自動で作成してくれる「PackageCreator」というLaravel用パッケージをGitHubで公開しました。
少しでもパッケージ開発が楽にできれば嬉しいです。
(今のところはLaravel 5+です。)

※追記・・・「package_creator」コマンドは「make:package」に入れ替わりました。(記事中の古いコマンドは全て修正されています)


■PackageCreator
https://github.com/SUKOHI/PackageCreator


ではインストール方法から。
PackageCreator 自体も Laravel の独自パッケージですので Composer でのインストールが可能です。
 composer require sukohi/package-creator:2.*  

次にサービス・プロバイダーを登録しましょう。
 Sukohi\PackageCreator\PackageCreatorServiceProvider::class,  

はい。
これで独自パッケージ生成のコマンド「php artisan make:package」が使えるようになっていると思います。


コマンドの使い方
 php artisan make:package (ベンダー名) (パッケージ名) (保存するフォルダ名)  

引数の説明

・ベンダー名: そのままベンダー名(あなたの名前)。必須。
・パッケージ名: 作成したいパッケージの名前。もし名前が複数の単語からできている場合はハイフンつなぎにしてください。必須
・保存するフォルダ名: パッケージを作成/保存する場所です。任意。デフォルトは packages

実際の例)
 php artisan make:package sukohi my-package test_packages  


オプション

--views

もし独自パッケージで view を使いたい場合はこのオプションを使ってください。


--publish

もし独自パッケージで publish 機能を付けたい場合はこのオプションを使ってください。


パッケージを生成するとその後どうすればいいかが表示されますのでその指示に従ってください。
後はController などからこんな感じアクセスすることができます。
↓↓↓

MyPackage::test();


ちなみにパッケージの開発手法は「Developing your packages in Laravel 5」を参考にしたものです。感謝!

以上です。
できればそのうち独自パッケージを公開する方法もブログ記事にしたいと思っています。
Let's develop! ^^


2016-02-02

【無料HTTS】 Let's Encrypt を試してみた!

先日Googleが 「HTTPS ページが優先的にインデックスに登録されるようになります」というアナウンスをしたんで、さすがに私が運営している個人サイトでも https通信に対応させないとまずいだろうと思い、最近話題になっている「Let's Encrypt」を試してみました。

※なお、2016/02/01現在でまだパブリックベータですので企業向けサイトにはまだ利用するべきではないと個人的には思っています。




今回の結論:
無料でHTTPSを利用できるようにしてくれてホントにありがとう!(^-^)b でも、できればもう少し有効期間を伸ばしてくれたらなー。


インストール

Gitでパッケージをコピーしてコマンドを実行するだけです。

こちらのページがとても親切に説明してくれていますのでインストール方法については省略します。
↓↓↓
無料SSL証明書の Let's Encrypt が公開されたので実際に試してみた


私の場合は --webroot をつけてウェブルート・モードを利用しました。
その際に少しハマってしまったのが以下2点です。

  • sudo をつけないと認証に必要なファイルを作成できなかった。
  • 作成するファイルのパスが正しくなかったので認証できなかった。

つまり流れとしては、

1. 指定したウェブルート/.well-known/acme-challenge 内に認証ファイルを作成

2. 指定したドメイン/.well-known/acme-challenge/*********** にアクセスがあることで認証を完了

というものでしたので、私の好きな Laravel では「ウェブルート/public」にしなければいけないのでした。^-^;
(Google Analyticsとかの認証と同じやり方ですねー。)


しかし、結果として以下のように証明書をゲット。


あとは httpdのコンフィグファイル(httpd.conf等)に以下のように追加すればOK!

1.NameVirtualHost を追加
 NameVirtualHost *:443  
2.SSL接続の設定を追加
 <VirtualHost *:443>  
   SSLEngine on  
   SSLCertificateFile /etc/letsencrypt/live/www.example.com/fullchain.pem  # ゲットした証明
   SSLCertificateKeyFile /etc/letsencrypt/live/www.example.com/privkey.pem  # ゲットした証明キー
   DocumentRoot /var/www/html/www.example.com/public  
   ServerName www.example.com  
   ServerAlias example.com  
 </VirtualHost>  
3.最後に忘れちゃいけない restart
 service httpd restart  

はい!
これで https://example.com に接続が可能になるはずです!

※ ちなみに、iptablesの443ポートを開けるのをお忘れなく(←私です^-^;)


自動で証明を更新

あとは、90日で証明の期限がきれるので crontab を使って自動で再取得をしましょう。

↓こんな感じです

 0 5 1 * * /YOUR_PATH/letsencrypt-auto certonly --webroot -w /var/www/html/example.com/public -d example.com --renew-by-default --debug && service httpd restart  


(追記: 20160724)

どうやらLetsencrypt の仕様が変わって上記の「letsencrypt-auto」コマンドは使えなくなってしまったようで実行しても以下のようなエラーが発生してしまいます。

【エラー】
You are running with an old copy of letsencrypt-auto that does not receive updates, and is less reliable than more recent versions. We recommend upgrading to the latest certbot-auto script, or using native OS packages.

【エラー訳】

古い letsencrypt-auto を実行しようとしていますがアップデートできないですし、現バージョンよりも信頼性が低いです。
最新の certbot-auto scriptへのアップグレードかOSパッケージの利用をおすすめします。

・・・ということで新しい更新プログラムのインストールは以下をご覧ください。


1.どこか適当なフォルダにcertbotをインストール

といっても git clone で自動でダウンロードができます。以下を実行しましょう。
(現在いるフォルダ直下にフォルダを作成する例になります。)

 git clone https://github.com/certbot/certbot ./certbot

2.自動で更新ができるように cron に以下を追加しましょう。

 0 5 1 * * /YOUR_PATH/certbot-auto certonly --webroot -w /var/www/html/example.com/public -d example.com --renew-by-default --debug && service httpd restart  



以上です。
次は mod_spdy か mod_http2 とかを試してみようかな〜。^-^


(追記 1)いつも忘れちゃうので apacheのコンフィグファイルの内容を保存。
どうやら apache のバージョンによってアクセスするべきファイルが少し違うらしい。
 <VirtualHost *:443>  
   SSLEngine on  
   SSLCertificateFile /etc/letsencrypt/live/example.com/cert.pem  
   SSLCertificateChainFile /etc/letsencrypt/live/example.com/chain.pem  
   SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem  
   DocumentRoot /var/www/html/example.com/public  
   ServerName example.com  
   <Directory "/PATH/TO/example.com/public"> 
     AllowOverride All
   </Directory> 
 </VirtualHost>  


(追記 2)ちなみにHTTPSへ移行した後、ブラウザでアクセスすると「混在コンテンツ」として警告をうけることがあります。
これは、HTTPSでアクセスしたページに「http://」で始まっているCSSやJavaScriptなどが存在しているという意味です。

解決するためには、以下のように「http:」の部分を削除してしまえばOK。
あとはブラウザが自動でプロトコルを選択してくれます。

 <link href='//fonts.googleapis.com/css?family=Open+Sans:300italic,400italic,600italic,700italic,800italic,400,300,600,700,800' rel='stylesheet' type='text/css'>