2015年3月26日木曜日

Mobile-Friendly Websites

検索結果をもっとモバイル フレンドリーに[googlewebmastercentral-ja.blogspot.jp]ですでに発表されている通り、Googleが、2015年4月21日より、ウェブサイトがモバイル フレンドリーかどうかをランキング要素として使用し始めます。

Googleのモバイルガイド[developers.google.com]に従って対策を進めましょう。

2015年3月24日火曜日

Webmaster Guidelinesを理解する

[Web] = [Google Search] の現状では、Webサイトを作成するには、Googleが公表しているWebmaster Guidelinesの理解が欠かせない。

さくらインターネットのSNI SSLでWordPressを運用できない

さくらインターネットで、SNI SSLが使用できるようになったというので、早速WordPressで構築したサイトに導入してみた。 

トップページはSSLで表示できるが、下層ページを表示させようとすると、スタイルシートやjavascript、画像等がSSLで読み込まれない。

原因を探っていると、下層ページで $_SERVER['HTTPS'] がセットされていないことが判明。

 いろいろなケースを確認したところ、WordPressのパーマリンク設定をディレクトリ形式にせず、デフォルトにすると表示できることも分かった。 

ディレクトリ形式のパーマリンクをリダイレクトする所に何かがあると考え、リダイレクト部分を突き詰めていくと、結局、以下のような .htaccess ということになる。

# BEGIN WordPress
<IfModule mod_rewrite.c>
 RewriteEngine On
 RewriteBase /
 RewriteRule ^index\.php$ - [L]
 RewriteCond %{REQUEST_FILENAME} !-f
 RewriteCond %{REQUEST_FILENAME} !-d
 RewriteRule . /index.php [L]
</IfModule>
# END WordPress

原因を切り分けるために、WordPressを使用せず、index.php で $_SERVER['HTTPS'] を表示させてみると、

実在するディレクトリ内に設置した index.php では、$_SERVER['HTTPS'] がセットされているが、
実在しないディレクトリにアクセスしてみると、$_SERVER['HTTPS'] がセットされていないことが判明した。

この現象にWordPressは関与していないわけだ。

さくらインターネットのサポートに電話したが、コンテンツに関することはサポートできないとのこと。いや、これはコンテンツに関する問題ではないでしょう。

WordPressがSSLを判定している関数は、wp-includes/functions.php 内の is_ssl() だが、以下の通り、$_SERVER['HTTPS'] をもとに判断している。さくらインターネットの SNI SSL のポートは80のままなので、ポート番号も使用できない。

/**
 * Determine if SSL is used.
 *
 * @since 2.6.0
 *
 * @return bool True if SSL, false if not used.
 */
function is_ssl() {
if ( isset($_SERVER['HTTPS']) ) {
if ( 'on' == strtolower($_SERVER['HTTPS']) )
return true;
if ( '1' == $_SERVER['HTTPS'] )
return true;
} elseif ( isset($_SERVER['SERVER_PORT']) && ( '443' == $_SERVER['SERVER_PORT'] ) ) {
return true;
}
return false;
}

もう、やけくそで、上の関数を常に true を返すように書き換えてやったら、SSLで表示できた。

このままでは、さくらインターネットのSNI SSLでWordPressを運用するのは無理だね。

さくらレンタルサーバーの共有SSLを使うによると、共有SSLと同じような仕様のようだ。

2015.5.7更新
とりあえず、現状は上記サイトで述べられている共有SSLへの対応と同じ方法で運用してます。

2018年3月、さくらインターネットのレンタルサーバー仕様変更で$_SERVER['HTTPS'] がリダイレクトで消去されなくなったとのこと。

Facebookのアプリを公開し忘れる

Opauthでソーシャルログインを実装する」の「Facebookでログイン」を実装する際に、https://developers.facebook.com/apps/でアプリを登録して、自分では動作確認ができたので、すっかり終わったつもりでいたのだが、他の人がログインできないとのこと。

Facebookアプリは、登録すると development mode になって、開発者自身のアカウントでは動作するが、公開しないと全ての人には利用できないようだ。

Status & Review の一番上で Do you want to make this app and all its live features available to the general public? と聞かれているので、トグルスイッチをONにしようとすると、You must have a valid Contact Email specified to make this app available to all users.とTool tip が出て、ONにできない。Settings のContact Email に自分のEmailを入力して、Status & Reviewに戻ると、今度はトグルスイッチをONにできた。

2015年3月23日月曜日

[Types - Custom Posts and Taxonomies]を更新して、はまる

Types - Complete Solution for Custom Fields and Types をバージョン 1.6.5.1 に更新したら、Taxonomyが設定された投稿一覧を表示する際に、archiveのテンプレートで表示されず、index.php が適用されてしまう。

例)
http://example.com/(post_type)/?(Taxonomy_slug)=(Taxonomy名

朝から絶望的な気持ちで、オプション等を確認していたら、query_varのチェックを外したところ、元に戻った。

「query_var」の下にある説明が、またよくわからない。

クエリーを妨げるために偽とする或いはクエリーをカスタマイズするためのストリング。初期設定に$taxonomyがクエリーとしてが使用されます。
初期設定: $taxonomy

まあいいかと思って、よく見たら、単に[query_var]が無効になってTaxonomyが反映されなくなっただけだった。やはり[query_var]のチェックを外すことはできない。

バックアップしてあった前のバージョンに戻したらなおったので、前のバージョンで運用する。やはりプラグインは怖い。

(追記 2015.4.16)
今日、バージョン 1.6.6.2に更新したら治ってました。更新履歴によると、1.6.6.1で対応したっぽい。

2015年3月17日火曜日

PHPのIF文で、はまる

PHPのIF文の2つの異なる構文、即ち、

if ( 「論理式」 ) {
  「真の処理」
}else {
  「偽の処理」
}

および

if ( 「論理式」 ) :
  「真の処理」
else :
  「偽の処理」
endif;

において、下の構文の処理内に、上の構文をいれた以下のようなコードを書いたところ、文法エラーが発生した。

if ( 「論理式1」 ) :
  if ( 「論理式2」 ) {
    「処理1」
  }
else :
  「処理2」
endif;

Parse error: syntax error, unexpected ':' in XXX(else : の行)
あれ、どこかで括弧閉じ忘れたかな、としばらく右往左往・・・

以下の様に変更すると、エラーは発生しない。

if ( 「論理式1」 ) :
  if ( 「論理式2」 ) :
    「処理1」
  endif;
else :
  「処理2」
endif;

以下のリンク先ページにある、「注意同じブロック内で別の構文を混ぜて使うことはできません。」というのは、このことなのか。

http://php.net/manual/ja/control-structures.alternative-syntax.php

ただし、これを以下の様にしてもエラーは発生しなかった。

if ( 「論理式1」 ) :
  if ( 「論理式2」 ) {
    「処理」
  }else {
    「空文」
  }
endif;

組み合わせによって、エラーが発生したりしなかったりするようだ。まあ、そもそも別の構文を混ぜちゃだめだと言われれば仕方ないけど、通っちゃう場合もあるというのは混乱を招くよね。

2015年3月16日月曜日

WordPressでポストバックしたら404 Not Foundになった。

WordPressの固定ページにフォームを設置してポストバックしたら、404 Not Foundになった。

さんざん試行錯誤した揚句、フォームの項目に名前(name="name")が含まれると発生することが判明。

post変数を「name="name1"」等に変更したら回避できた。名前空間の衝突には注意すべし。

2015年3月13日金曜日

Opauthでソーシャルログインを実装する

サイトで会員登録するのは自分でも抵抗があるので、ソーシャルログインを実装してみた。

Opauthは、PHPにおける認証処理を標準化してくれるフレームワークだ。

https://github.com/opauth/opauth

上記サイトから、ZIPをダウンロードして展開したら、

1) libをサイトのドキュメントルートにコピーする。
2) 認証用として例えばauthというディレクトリをドキュメントルートに作成する。
3) authの中には、展開したexampleフォルダの中の、index.php、callback.php、.htaccessおよびopauth.conf.php.defaultをコピーする。
4) opauth.conf.php.defaultをopauth.conf.phpにリネームする。
5) opauth.conf.phpの'path' => '/'を'path' => '/auth/'に書き換える。
6) opauth.conf.phpの'security_salt'にランダムな文字列を設定する。
7) opauth.conf.phpのStrategyを、例に従って記述する。

Strategyに記載するパラメーターは、各プロバイダのサイトでアプリケーション登録をすると得られる。

プロバイダのアプリケーション登録ページの例
Facebook
Twitter
Google+

プロバイダ毎のStrategyは以下からダウンロードして、lib/Opauth/Strategyの下にプロバイダ名のディレクトリを作成してコピーする。

https://github.com/opauth/opauth/wiki/List-of-strategies

例えば、Facebookであれば、

lib/Opauth/Strategy/Facebookの下に、FacebookStrategy.phpをコピーする。

Twitterの場合は、Vendor/tmhOAuthディレクトリもコピーする。

認証手続きを開始するには、opauth.conf.phpで設定した'path/(プロバイダ名)'にアクセスする。

私の場合は、Strategyが見つからないというエラーが出たので、opauth.conf.phpのStrategyに以下のパラメータを追加した。

例えば、Facebookであれば、
'Facebook' => array(
            'app_id' => '(app_id)',
            'app_secret' => '(app_secret)',
            'strategy_url_name' => 'Facebook'
)

Googleの場合は、Googleサイト側でError: redirect_uri_mismatchという画面が出てしまい、認証画面が表示されなかったので、以下のパラメータも追加してみた。

'Google' => array(
            'client_id' => '(client_id)',
            'client_secret' => '(client_secret)',
            'redirect_uri' => 'http://(ドメイン)/auth/Google/oauth2callback',
            'strategy_url_name' => 'Google'
)

なお、Googleは、https://console.developers.google.com/project でリダイレクトURLを設定する必要がある。

しかし、結局Googleで認証ができない。

試行錯誤しているうちに、なぜか認証できるようになった。

Googleは、GoogleApps for Workでも感じたが、設定しても反映するまでの遅延が大きいようなので、設定したらある程度時間を置く必要があるのかもしれない。24時間以上かかる場合もある?

サーバー間の同期に時間がかかっているのだろうか。設定方法に自信がない場合は、設定が終了するまでになんともいえない無為な時間が流れるのは、かなり困る。

アプリの設定に表示されないのも、そのせいかと思っていたら、アカウント権限という別ページで管理するようだorz

2015年3月4日水曜日

[PHPによるHTTP 認証]$_SERVER["PHP_AUTH_USER"]が取得できない

PHPによるHTTP 認証[php.net]ができることを知って、早速試してみたのだが、認証画面が繰り返し表示されてしまう。

$_SERVER["PHP_AUTH_USER"]が取得できていないようだ。

Webを検索してみると、さくらのレンタルサーバーだとPHPがCGIとして動作するため、うまく動作しないとの情報が。

よく見ると、php.netにも以下の情報がありました。

There are .htaccess which actually works for us (cPanel + phpsuexec) unless others failed. Perhaps it may help someone.

# PHP (CGI mode) HTTP Authorization with ModRewrite:
RewriteEngine on
RewriteCond %{HTTP:Authorization} ^(.*)
RewriteRule ^(.*) - [E=HTTP_AUTHORIZATION:%1]

Then you need small piece of php code to parse this line and then everything will work like with mod_php:

if (isset($_SERVER['HTTP_AUTHORIZATION']))
{
$ha = base64_decode( substr($_SERVER['HTTP_AUTHORIZATION'],6) );
list($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']) = explode(':', $ha);
unset $ha;
}
でも、ロリポップではやはり動作しない。まあ、PHPで認証すればいいと言われればその通りだ。