埋め込みgoogleカレンダーは簡単に設置できますが、デザインの自由度はとても低いです。そんな埋め込みgoogleカレンダーのデザインをもっと自由に変更できるスクリプト「gcalendar-wrapper.php」の使い方をご紹介します。

gcalendar-wrapper.phpのダウンロード

以下のサイトよりダウンロードできます。ページ中程にある「Download the wrapper script」をクリックしてファイルを保存してください。


ダウンロードしたファイルを解凍し、サーバーにアップロード

ダウンロードしたファイルを解凍すると「gcalendar-wrapper.php」が出てきますので、それをサーバーの任意の場所にアップロードします。WordPressの場合などはテーマディレクトリに一緒にアップしておくと良いと思います。

googleカレンダーの準備

公開用googleカレンダーを用意します。ここではサンプルとして「予約管理」というカレンダーを用意しました。


公開設定をしておく

一般公開するので、設定から共有設定を行っておきます。「アクセス権限」から「一般公開して誰でも利用できるようにする」にチェックを入れます。


googleカレンダーの埋め込みコードを取得

「Google カレンダー埋め込み支援ツール」などを利用して埋め込みコードを取得します。
この時点で「印刷アイコン」など不要な項目があればチェックを外しておくと、後々のカスタマイズもやりやすくなります。


埋め込みコードの編集

取得したコードを編集します。デフォルトではhttps://www.google.com/calendar/embedから始まっていますが、これをgcalendar-wrapper.phpへのパスに変更します。

<iframe src="ttps://calendar.google.com/calendar/embed?showTitle=0&showNav=0&showPrint=0&showTabs=0&showCalendars=0&showTz=0&height=600&wkst=1&bgcolor=%23FFFFFF&src=xxxxxxxxxx&color=%23182C57" style="border-width:0" width="800" height="600" frameborder="0" scrolling="no"></iframe>

<iframe src="ドメイン/gcalendar-wrapper.php?showTitle=0&showNav=0&showPrint=0&showTabs=0&showCalendars=0&showTz=0&height=600&wkst=1&bgcolor=%23FFFFFF&src=xxxxxxxxxx&color=%23182C57" style="border-width:0" width="800" height="600" frameborder="0" scrolling="no"></iframe>

WordPressの場合

テーマディレクトリにgcalendar-wrapper.phpを置き、

<iframe src="<?php echo get_template_directory_uri(); ?>/gcalendar-wrapper.php?showTitle=0&showNav=0&showPrint=0&showTabs=0&showCalendars=0&showTz=0&height=600&wkst=1&bgcolor=%23FFFFFF&src=xxxxxxxxxx&color=%23182C57" style="border-width:0" width="800" height="600" frameborder="0" scrolling="no"></iframe>

とすれば出来ると思います。

デザインの変更

デザインを変更するには、gcalendar-wrapper.phpを編集します。gcalendar-wrapper.phpの26〜30行あたりに以下の記述がありますので、カラーコードを変更すればカレンダーに反映されます。

/**
 * Set your color scheme below
 */
$calColorBgDark      = '#c3d9ff';	// dark background color
$calColorTextOnDark  = '#000000';	// text appearing on top of dark bg color
$calColorBgLight     = '#e8eef7';	// light background color
$calColorTextOnLight = '#000000';	// text appearing on top of light bg color
$calColorBgToday     = '#ffffcc';	// background color for "today" box

また、プリセットとして幾つかカラースキームが用意されているのでそちらを使うことも出来ます。
試しに36〜40行にある「Orange color scheme」のコメントを外し、適用させてみたものが以下の通りです。


もっと凝ったデザインの変更

上記で紹介した方法を使ってデザインを変更しても枠の色が変えられるだけで、正直あまり良いデザインにはなりません・・・。ではどうすればもっと凝ったデザイン出来るかと言うと、実は上記で設定したカラーコード達は、gcalendar-wrapper.phpの87〜182行目にあるcss設定の変数として定義されています。なので上記を使わず、もう直接cssを書き込んでいけばもっと柔軟なデザイン変更が可能になります。

実際にもっとスッキリしたものにしてみた

cssを色々と追記して作ってみたのが以下のカレンダーです。まだまだ余白など気になる点はありますが、ここまで出来ればサイトの雰囲気にもあったものになるのではないかと思います。


追記したcssです。

table.mv-daynames-table {
	background: #FFF !important;
}

td.st-dtitle {
	background: #FFF !important;
	border: 1px solid #000 !important;
	border-bottom: none !important;
}

td.st-dtitle.st-dtitle-today {
	background: #F0F0F0 !important;
}

.st-bg-table {
	border-collapse: collapse;
}

.st-grid {
    border-collapse: collapse !important;
}

.view-cap {
	display: none !important;
}

.mv-event-container {
	border: none;
}

.rb-n {
	background: #000 !important;
}

.view-container-border {
	padding: 0 !important;
}

td.st-bg {
	border: 1px solid #000 !important;
}

td.st-bg-today {
	background: #F0F0F0 !important;
}

.footer {
	display: none;
}

一手間をかけるだけでデザインがグッと良くなるので、ぜひお試しください。

Slim3単体ではBasic認証は出来ませんが、「slim-basic-auth」を使えば簡単に実装できます。

PHPフレームワーク「Slim3」でBasic認証

Slim3でBasic認証ページを用意したい場合、slim-basic-authを使えば簡単に実装することが出来ますので、その方法をご紹介します。

slim-basic-authのインストール方法

composer経由でインストールします。

composer require tuupola/slim-basic-auth

その後、以下のコードを記述すればOKです。Slim-Skeletonの場合は、/src/middleware.php に書くのが良いと思います。

$app = new \Slim\App;

$app->add(new \Slim\Middleware\HttpBasicAuthentication([
    "path" => "/admin",
    "secure" => false,
    "users" => [
        "user" => "pass"
    ]
]));

上記の場合、/admin 以下がBasic認証になります。user と pass に任意の文字列を設定して完了です。

なお、secureをfalseにするとSSLじゃなくても動きます。

また、認証に失敗した場合に何か処理をさせたい場合は、errorに書けばOKです。

$app->add(new \Slim\Middleware\HttpBasicAuthentication([
    "path" => "/admin",
    "secure" => false,
    "users" => [
        "user" => "pass"
    ],
    "error" => function ($request, $response, $arguments) {
        // 処理を書く
        return $response->write("認証失敗");
    }
]));

簡単に認証ページを作りたい場合に使えますね。

PHPでは様々なフレームワークが存在しますが、その中でも特に軽量なマイクロフレームワーク「Slim3」を使ってみましたので、使った様子などをまとめました。

PHPで軽量フレームワークを探していました

PHPでwebサービスを作りたい場合、フレームワークを使って作る事があると思いますが、PHPのフレームワークって色んな種類があって、どれを使うべきなのか迷います。

有名なのは、CakePHP、Laravel、FuelPHP、Symfony、CodeIgniter、Zend Framework辺りでしょうか。日本においてはCakePHPが一番使われていて、今後Laravelが伸びてくるというのが共通認識のようです。

以前より小規模なサイトをPHPでいくつか作りましたが、その際も上記の様なフレームワークを使おうと思って色々と調べていました。ただ、そこまでの機能を必要としていなく、とりあえずルーティングとテンプレートだけあればよかったので、いわゆるマイクロフレームワークと呼ばれる「Slim」を使ってみました。

Slimのインストール方法

composerを使ってインストールします。Slimには、slim-skeletonというものが用意されており、それを使うとpublicやsrc、logsなどのディレクトリが自動で作られるので、1から作るときに便利です。

php composer.phar create-project slim/slim-skeleton [my-app-name]

[my-app-name]の所に、任意の名前をつけると、その名前でディレクトリが作られます。

何も考えずにドキュメントルートである、publicにアクセスすると

エラー画面

とエラーが出ちゃうので、logsディレクトリにサーバーの書き込み権限をつければOKです。

インストールが成功した画面

再度アクセスすると、無事表示されましたね。

ルーティング

ではルーティングについて見ていきます。slimのルーティングの基本は下記のような形です。

$app->get('/hello/{id}', function ($request, $response, $args) {
    // 処理を書く
    echo $args['id'];
});

上記の場合、/hello/hoge でアクセスした場合だと、hoge が出力されます。

その他にも、正規表現でマッチさせることも可能で、

$app->get('/hello/{id:[0-9]+}', function ($request, $response, $args) {
    // 処理を書く
    echo $args['id'];
});

上記の場合、/hello/1 や /hello/123 は問題なくアクセスできますが、/hello/hoge の場合は404になります。

ルーティングに関しては、GETメソッド以外にも、POST、PUT、DELETEなどもあり、複数のメソッドにマッチさせる事もできます。公式サイトにその辺りが詳しく書いてあります。

テンプレートエンジンとしてTwigを使う

ルーティングの設定がわかった所で、次はテンプレートエンジンとしてTwigを使ってみます。Slim3に対応した「Twig-View」というものがあるので、こちらを使います。

Twig-Viewのインストール

こちらもcomposerを使ってインストールします。

composer require slim/twig-view

インストールが完了したら、各種設定をしていきます。
なお、以下は全てslim-skeletonを使った場合のファイル名です。

/src/dependencies.phpに以下を追記

$container['view'] = function ($c) {
    $settings = $c->get('settings');
    $view = new Slim\Views\Twig($settings['view']['template_path'], $settings['view']['twig']);

    // Add extensions
    $view->addExtension(new Slim\Views\TwigExtension($c->get('router'), $c->get('request')->getUri()));
    $view->addExtension(new Twig_Extension_Debug());
    return $view;
};

/src/settings.phpに以下を追記

return [
    'settings' => [

        ・・・

        // View settings
        'view' => [
            'template_path' => '{テンプレートのパス}',
            'twig' => [
                'cache' => '{キャッシュのパス}',
                'debug' => true,
                'auto_reload' => true,
            ],
        ],

        ・・・
    ],
];

Twigを使う場合の書き方

$app->get('/hello/{id:[0-9]+}', function ($request, $response, $args) {
    $id = $args['id'];
    return $this->view->render($response, 'hello.html', ['id' => $id]);
});

上記例の場合、urlからidを取得し、変数idに格納して、それを「hello.html」という名のテンプレートファイルに、変数idを渡しています。

hello.htmlの方で

{{ id }}

と書くと、変数idが表示されます。

{{ }}というのはTwigの記述法です。公式サイトに詳しく書いてあります。

ドキュメントが少なくて苦労

Slimは2015年末に、バージョン3がリリースされました。以前までのバージョン2と比べると全体的に書き方が変わっている所がいくつかあります。途中動かなくてネットで調べまくりましたが、バージョン2の書き方しかされてない事も多く苦労しましたが、なんとか動いてやりたいことは出来ているので、今後も使っていこうと思っています。

参考にしたサイト

以下のサイトを参考にしました。ありがたや。

MySQLのInnoDBエンジンを使った場合、AUTO INCLIMENTで欠番が出てしまいます。これは仕様なので基本的にはどうすることも出来ませんが、なんとなく気持ち悪いので解決方法などを調べてみました。

AUTO INCLIMENTで欠番が出るのが気持ち悪い

以前調べた方法で、重複自体は簡単に防げたのですが、AUTO INCREMENTの番号が飛んでしまう現象がありました。

MySQLで採用されているInnoDBエンジンの仕様なので、基本的にはどうしようもありません。特に実害も無いのですが、ただ単純に番号が飛ぶのが気持ち悪い。。
何か他の方法で解決できないかを調べるとネットで見つけました。

重複を防ぎ、AUTO_INCLIMENTで欠番を出さずINSERTする方法

まずはtestテーブルを作ってテストしてみます。

テストするtestテーブルのデータ

mysql> select * from test;
+----+--------+
| id | name   |
+----+--------+
|  1 | yamada |
+----+--------+
1 row in set (0.00 sec)

testテーブルには、yamadaというデータが1件入っている状態です。

次の構文を入力し、重複回避ができるかテストします

mysql> INSERT INTO test (name) SELECT 'yamada' FROM dual WHERE NOT EXISTS(SELECT * FROM test WHERE name = 'yamada');
Query OK, 0 rows affected (0.00 sec)
Records: 0  Duplicates: 0  Warnings: 0

INSERT SELECTはSELECTした結果をINSERTする構文です。上記の例だと、yamadaをINSERTしようとしていますね。
次に続くdualというのはテーブルのデータを参照する必要が無い場合に指定するダミーのテーブル。
そしてNOT EXISTSは、その後に続くサブクエリが1行でも返したらFALSEになるというものです。

つまり、NOT EXISTSの後のサブクエリでヒットしたら、INSERT処理をしないというものになり、上記の例だと既に「name」に「yamada」が入っている(重複している)ので、サブクエリにヒットしINSERTされなかった。という結果になります。

続いて重複しないデータでテストしてみます

次は重複しないtanakaというデータを入力してテストします。

mysql> INSERT INTO test (name) SELECT 'tanaka' FROM dual WHERE NOT EXISTS(SELECT * FROM test WHERE name = 'tanaka');
Query OK, 1 row affected (0.01 sec)
Records: 1  Duplicates: 0  Warnings: 0

mysql> select * from test;
+----+--------+
| id | name   |
+----+--------+
|  1 | yamada |
|  2 | tanaka |
+----+--------+
2 rows in set (0.00 sec)

無事、tanakaが挿入されているのがわかります。この方法だと、重複したデータを挿入しようとしても、INSERTがされないため、AUTO_INCLIMENTの番号が飛びません。

AUTO_INCLIMENTの番号が飛ばない!

mysql> select * from test;
+----+--------+
| id | name   |
+----+--------+
|  1 | yamada |
|  2 | tanaka |
+----+--------+
2 rows in set (0.00 sec)

mysql> INSERT INTO test (name) SELECT 'tanaka' FROM dual WHERE NOT EXISTS(SELECT * FROM test WHERE name = 'tanaka');
Query OK, 0 rows affected (0.00 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> INSERT INTO test (name) SELECT 'tanaka' FROM dual WHERE NOT EXISTS(SELECT * FROM test WHERE name = 'tanaka');
Query OK, 0 rows affected (0.00 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> INSERT INTO test (name) SELECT 'tanaka' FROM dual WHERE NOT EXISTS(SELECT * FROM test WHERE name = 'tanaka');
Query OK, 0 rows affected (0.01 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> INSERT INTO test (name) SELECT 'suzuki' FROM dual WHERE NOT EXISTS(SELECT * FROM test WHERE name = 'suzuki');
Query OK, 1 row affected (0.01 sec)
Records: 1  Duplicates: 0  Warnings: 0

mysql> select * from test;
+----+--------+
| id | name   |
+----+--------+
|  1 | yamada |
|  2 | tanaka |
|  3 | suzuki |
+----+--------+
3 rows in set (0.00 sec)

わざと重複するtanakaを挿入し、その後suzukiを挿入してみますが、AUTO_INCLIMENTの番号が飛ばず、無事データの挿入が出来ているのがわかります。

SQLって難しい・・・

ネットで調べまくって、ようやく綺麗な形でINSERTできる方法を見つけました。SELECTでINSERTする方法やサブクエリなど全然知りませんでした。SQLって本当に奥が深く難しいですね。。
一度ちゃんと本を読んで勉強してみようかと思います。

参考にしたサイト

以下の記事に助けられました。ありがたや。

知ってる方からしたら今更何言ってんだって話だと思うんですが、データベースにあまり詳しくない自分からすると、かなり謎現象で悩まされました。色々とネットで調べたので調べたことを備忘録的に書いていきます。

やりたかった事と発生した現象

PHPからMySQLへデータを入れていきたい。でもデータ重複を回避したいので、特定のカラムにユニークを設定。データを追加し重複のテストをしていた所、auto increment設定したIDが飛び飛びになってしまったという現象です。

テストテーブルを作って再現してみます

CREATE TABLE test (
  id int auto_increment primary key,
  name varchar(255) unique
) ENGINE = InnoDB;

idをauto increment、nameをuniqueにしたテーブルを作りテストしてみます。

mysql> insert into test (name) values ('yamada');
Query OK, 1 row affected (0.01 sec)

mysql> select * from test;
+----+--------+
| id | name   |
+----+--------+
|  1 | yamada |
+----+--------+
1 row in set (0.01 sec)

まずは普通にレコードを1行挿入してみます。
selectするとnameに「yamada」が入っているのが分かります。

mysql> insert into test (name) values ('yamada');
ERROR 1062 (23000): Duplicate entry 'yamada' for key 'name'
mysql> insert into test (name) values ('yamada');
ERROR 1062 (23000): Duplicate entry 'yamada' for key 'name'
mysql> insert into test (name) values ('yamada');
ERROR 1062 (23000): Duplicate entry 'yamada' for key 'name'
mysql> insert into test (name) values ('yamada');
ERROR 1062 (23000): Duplicate entry 'yamada' for key 'name'
mysql> insert into test (name) values ('yamada');
ERROR 1062 (23000): Duplicate entry 'yamada' for key 'name'

そして、わざと同じ「yamada」という値を入れ、insertすると、重複しているよ!というエラーが出ています。uniqueに設定しているので、特に問題ありませんね。

mysql> insert into test (name) values ('tanaka');
Query OK, 1 row affected (0.01 sec)

mysql> select * from test;
+----+--------+
| id | name   |
+----+--------+
|  7 | tanaka |
|  1 | yamada |
+----+--------+
2 rows in set (0.00 sec)

今度は重複しない「'tanaka'」を入れてみます。
その後selectしてみると、idが2じゃなくて7になっている・・・

番号が飛ぶ原因

調べてみると、MySQLのストレージエンジンとして採用されたInnoDBの仕様だと言うことがわかりました。高速化の為にそうしているらしいです。

欠番を作らない方法

「--innodb_autoinc_lock_mode=0」オプションを付けて起動
もしくは
my.cnfのmysqldに「innodb_autoinc_lock_mode=0」と記述
のどちらかで「従来」ロックモードというものになり、欠番が発生しなくなるそうです。

とはいえ、高速化の為にやっている事をわざわざやめるのもなぁ、、という感じもして悩ましい。。

参考にしたサイト

以下の記事が参考になりました。ありがたや。

去年末にPHP7が正式リリースされました。ネットの情報を見る限りでは後方互換性がしっかりしており、WordPressやその他フレームワークもPHP7対応が完了しているみたいですので、アップデートしてみることにしました。

まずは既に入っているPHP5.6をアンインストール

アップデートでも良かったのですが、一回消したほうがスッキリするのかと思い、yum remove を使ってPHPをアンインストールしました。

yum remove php *
php -v

でバージョン情報が出てこなければアンインストール完了です。

remiリポジトリを追加

wget //rpms.famillecollet.com/enterprise/remi-release-7.rpm
rpm -Uvh remi-release-7.rpm

最新のremiリポジトリを追加し、インストールします。

yumコマンドでPHP7をインストール

yum -y install --enablerepo=remi-php70 php php-mbstring php-pear php-fpm php-mcrypt php-devel php-xml

remi-php70を有効にして、yumコマンドでインストールしました。

php -v
PHP 7.0.2 (cli) (built: Jan  6 2016 15:25:31) ( NTS )
Copyright (c) 1997-2015 The PHP Group
Zend Engine v3.0.0, Copyright (c) 1998-2015 Zend Technologies

バージョンを確認すると、PHP7.0.2が入ってるのがわかります。

新しくインストールしたので、php.iniの文字コード関連の設定

vim /etc/php.ini
default_charset = "UTF-8"
mbstring.language = Japanese
mbstring.internal_encoding = UTF-8
mbstring.encoding_translation = Off
mbstring.http_input = pass
mbstring.http_output = pass
mbstring.detect_order = auto

改めてphp.iniを設定し直します。

Apacheの再起動をして設定を反映

systemctl restart httpd

最後にApacheの再起動をして設定を反映させます。

動作確認

無事にインストールが出来たみたいなので、WordPressで作ったサイトが正常に表示されているかを確認します。特にエラーが出ることもなく記事が表示できたので、問題ありませんでした。また他にもslimというPHPのマイクロフレームワークと、Twigというテンプレートエンジンを使っているサイトもあるのですが、そちらの方も特に問題なく動作していました。

PHP7の最大のウリである速度ですが、特に計測はしていないので何とも言えませんw
が、体感的にはWordPressの記事や、管理画面の表示が速くなったような気がします。
レンタルサーバーでもPHP7が使えるところも増えてきており、今後PHP7に移行する人が増えていきそうですね。

参考にした記事・サイト

今回のアップデートは以下の記事を参考にしました。ありがたや。