WordPress4.0にアップデートしてログインできなくなった人へ

2014年09月11日

WordPress4.0がリリースされてから少し出遅れ気味ですが、
テスト環境を構築する意味も含めて、アップデートしてみました。
 
その後ログイン画面までは行くけど、ログインしようとすると何も表示されていない
画面に遷移するだけ・・・という、(おそらく)レアなケースが発生したので一応メモ。
 
1.事象
Wordpress3.9.2からアップデートしたら、強制的にログイン画面に飛ばされる
(セッション関連のモジュールもアップデートされるので当然です)
が、ログインしようとすると何も表示されない。
 
2.原因と対処
手っ取り早くapacheのログをチェックすると、phpで致命的なエラー吐いている場所を発見。
要約すると「hash()なんて関数ねーぞ」って言ってる。
調べてみるとphpの拡張モジュールにhash.soがあって、その中の関数であることが判明。
phpのインストールディレクトリにあるextensions.iniファイルを見てみると
見事にコメントアウトされていたので、コメントを外す。
;extension=hash.so → extensions=hash
 
3.結果
解決。
 
今回はサーバーのコンソールに入れる環境だったので対処できたけど、
レンタルサーバーの設定によってはWordpress4.0は動かない可能性があるので注意ですね。
(sshでアクセスできないとか、ftpで設定ファイル関係のある場所までいけないとか)
ただまぁ・・・レアなケースだろうなぁ。

facebookのrssのタイトルをUTF-8にデコードできた話

2014年07月24日

facebookのポストをrssで取得して出力しようとしたら、
タイトルの日本語が全部HTMLエンティティになってて、trimもなんにも上手くいかない。
なので、packしたり、html_entity_decode使ったりして変換しようとしたけれど、
どうにも言う事聞いてくれなくて、格闘した末うまくいったのでメモ。

// rss取得
// クラス
include_once(ABSPATH.WPINC.'class-simplepie.php');
$rss = new SimplePie();
// feed url
$rss->set_feed_url(array('あんなところ','こんなところ','のfeed url'));
$rss->init();
$maxitems = $rss->get_item_quantity(3);
// アイテム取得
$items = $rss->get_items(0,$maxitems);

// 出力ループ
foreach ($items as $item) :
    $title = $item->get_title();
    // 数値参照文字っぽいものを含む場合だけ処理
    // そうしないとまっとうなUTF-8タイトルまで破壊される
    if(preg_match('/&#x.{4};/',$title)){
        // get_title()メソッドで&が全て&に変換されてしまってたのでもとに戻す
        $title = preg_replace('/&/','&',$title);
        $title = mb_convert_encoding($title,'UTF-8','HTML-ENTITIES');
    }

    // こっから出力関係適当に
    ・・・・・
endforeach;

16進文字列取ってpackしてみたり、別のエンコード経由で変換してみたりと無駄なことをしていたことが判明。
ただし、エンティティと日本語の混合文字列だとどうなるか判らない模様。

wordpressでサイトurlを変更した結果生じるパスを正規化

2013年09月09日

wordpressを使ってて思うのが、サイトurlを変更したり、
cssやjs・画像ファイルをwordpressのインストールディレクトリとは
別にした時、ソース上のパスが相対パスの嵐になってしまうので、
それを正規化するフィルターを一本ゴリ押しで書いてみた。

<?php
	// 適当にパスを突っ込む
	$real = 'http://hoge.jp/install_dir/wp-admin/wp-content/../../../css/test/../test.css?aaa=bbb&amp;amp;ccc=ddd#flag';
	var_dump(opt_path($real));

	// パスを正規化(http(s)://から始まる絶対パスのみ)
	function opt_path($base=''){
		// urlパース
		$parse = parse_url($base);
		// schemeに合わなければ何もしない
		if (!preg_match('/^https?\:\/\//',$base) ){
			return $base;
		}
		// パスを/で区切る
		$tmp = split('\/',$parse['path']);
		// 配列を定義
		$dirs = array();

		foreach($tmp as $pt){
			// 親ディレクトリの場合は前に積んだディレクトリをはずす
			if($pt == '..'){
				array_pop($dirs);
			}else if($pt == '.'){
				// カレントの場合は何もしない
				continue;
			}else{
				// それ以外はディレクトリ名として突っ込む
				//(隠しディレクトリもいけると思うけど無対応)
				array_push($dirs,$pt);
			}
		}

		// url組み立て開始
		$urls = $parse['scheme'] . '://' . $parse['host'] . implode('/',$dirs);

		// クエリがあれば付加
		if($parse['query']){
			$urls = $urls . '?' . $parse['query'];
		}
		// フラグメントがあれば付加
		if($parse['fragment']){
			$urls = $urls . '#' . $parse['fragment'];
		}

		return $urls;
	}
?>