Moral Hazard!!

ドラマーが音楽やホームページやガラクタを作るよ。

Microsoft AzureにWindows2008を入れてWordPressが動作する環境を構築する その1

No Comment wordpress,,

WordPressでサーバがWindows2008 RC2 SP1指定という案件があったので、折角なのでWindowsのクラウドサービスAzureを使って仮想テスト環境を構築。
非常に手間だったのでメモを残す。
※不具合・ご指摘大歓迎です。

で、結論から言うと、

・Windows環境でWordpressを動かすのはやめておいたほうがいい…
・Azure扱いやすい、UIが分かりやすい、けどとにかく高い

です。
特にhtaccessで簡単に設定できてたリダイレクト・Basic認証などがweb.configで書かないといけないところ、キャッシュ系プラグインがほぼ対応していない事、権限周りの煩わしさ、日本語URLのバグなどで泣きそうになる。

Azureのアカウントを作る。

クレジットカードがあれば20,000円分無料で1か月試用が可能なので、早速申し込む。

Azureダッシュボード。
綺麗で見やすく、カスタマイズしやすい。

Virtual Machineの作成

メニューのVirtual Machinesを選択し、「Virtual Machineの作成」をクリック。
お勧めに出る「Windows Server → Windows2008 R2 SP1」を選択。

「デプロイモデルの選択」はそのまま「作成」を押す。

基本設定を適当に埋め、仮想マシンのサイズ選択。

最初からお勧め環境が出てくるが、「すべてを表示」を選択すると月額57万円のサーバとか出てきて笑う。
もちろん価格は変動するが、僕が見た時点で一番安い環境が1vCPU,1GBメモリ,SSD2GB,iops800で1,500円。
※IOPS = (I/O per Second)。ディスクが1秒当たりに処理できるI/Oアクセスの数
※データディスク = 接続可能なデータディスクの最大数

まぁ試用なのでお勧めから適当なものを選択。
次のオプション機能の設定も触らずOKを押す。
検証が終了したらそのまま「作成」。デプロイにしばらく時間がかかる。

デプロイ終了後、デスクトップから仮想環境にアクセスできる。
「接続」を押してWindowsサーバへリモートアクセス。

資格情報には基本設定で入力したユーザー名とパスワードを入力。

Windowsにアクセス出来た。

IISのインストール

Microsoft Internet Information Services(WEBサーバ)をインストールする。

Startボタン右側のServer Managerを起動し、Rolesを右クリックして「Add Roles」を選択。
IISにチェックを入れてNext。

Select Role ServicesもそのままNext。

インストール完了後、IIS Managerに「Default Web Site」が作られている。

Default Web Siteを右クリック→Exploreでルートフォルダの位置(C:\inetpub\wwwroot)がわかる。

※ファイルの拡張子表示はエクスプローラーでaltキーでメニュー表示→Tools → Folder Options→ Viewタブの
「Hide extentions for known filetypes」のチェックを外す。
※右側Actionの「Browse *:80(http)」をクリックで、ローカルからブラウザ確認が可能。

Azure Network Security Groupでポートを開放

もちろんこのままではリモートからサイトが見れない、FTP接続もできないので、Webサーバの80番ポートと21番FTPのポートを開放。

AzureポータルからリソースのNetwork Security Group(盾のアイコン、名前は入力したID-nsg)をクリックし、ネットワークセキリュティグループを表示、「受信セキリュティ規則」に

ソース : IP Address
発信元IPアドレス範囲 : 自分のIP/32
発信元ポート範囲 : 任意。(webサーバは80,FTPは21。テスト環境なので今回は全ポート*を入力。)

を追加することで、自分だけがアクセス可能。
優先度、名前などは適宜変更。

設定が完了すると、リモートのブラウザから

初期ページが表示される。

静的IPの割り当て

Azureのリソースを停止したときにIPが変わってしまうのを防ぐため、IPを静的に変更する。
「パブリックIPアドレス→構成」
を選択し、「割り当て」を動的→静的に変更。

タイムゾーンの変更

タスクバー右側の時間を右クリック→Change date and time settingsをクリック。
Change time zone → (UTC+9:00) Osaka,Sapporo,Tokyoを選択。

FTPサーバのインストール、設定

・Web Manager(IIS)を右クリック「Add Role Services」でFTPをインストール。
・Defalut Web Siteの「FTP Authentication」で「Basic Authentication」を「Enable」に設定。
・Defalut Web SiteのFTP SSL Settingsで「SSL Policy」を「Allow SSL connections」に設定。
(※SSLを使用しない設定だと、デフォルトのファイアーウォールがブロックする仕様、との事)
・FTPソフトではActive接続を選択。

Windows Firewallの設定

AzureのNSGを使用するので、今回は特に設定しない。

HTMLの表示

Default Web Siteのルート(C:\inetpub\wwwroot)に適当にメモ帳でindex.htmlを作成&UTF8で保存すると、ブラウザで

表示される。

その2へ。

外部WordPressサイトから投稿記事をRSSで読み込み、表示

No Comment wordpress,,

■やりたい事…Wordpressサイト1の投稿記事を、他サーバにあるWordpress2サイトで取得、表示。

同一DBサーバのWPから記事を持ってくる方法は他にあるみたいけど、設定が煩雑なのとDBサーバに外部接続用のユーザを作ったりしないといけないのでレンタルサーバでは荷が重いか。

今回はWordpress自体が出力しているRSSを取得・表示する方法。
(出典・モンキーレンチ様。こことかこことか)

<?php
include_once(ABSPATH . WPINC . '/feed.php');
$rss = fetch_feed('http://hogehoge.com/feed'); // RSSの取得元URL
if (!is_wp_error( $rss ) ) : $maxitems = $rss->get_item_quantity(3); // 記事数
	$rss_items = $rss->get_items(0, $maxitems); 
endif;
?>

<ul>
<?php
if ($maxitems == 0): echo '<li>記事はありません</li>';
else :
date_default_timezone_set('Asia/Tokyo');
foreach ( $rss_items as $item ) : ?>

<li><a href="<?php echo $item->get_permalink(); ?>" target="_blank" rel="bookmark"><?php echo $item->get_title(); ?>
<span class="news-date"><?php echo $item->get_date('(Y/m/d)'); ?></span></a>
</li>

<?php endforeach; ?>
<?php endif; ?>
</ul>

で可能。
ただ、上記でRSSを取得した場合、取得した側のWordpressで最大12時間のキャッシュが効いてしまって最新記事が取得できないことがある。
なので、取得先Wordpressサイト1のfunction.phpに追記して、キャッシュ時間を変更する。

return 数値を秒で指定する。30分なら1800を入力することで、30分ごとにRSSキャッシュを更新してくれる。

add_filter( 'wp_feed_cache_transient_lifetime', function(){'return 1800;';});

上記はPHP5.3から使用可能な無名関数を使用。
ちなみにそれ以前のverの場合は

add_filter( 'wp_feed_cache_transient_lifetime', create_function( '$a', 'return 1800;' ) );

と匿名関数(create_functionで定義)を使うか、

function return_rss_num() {
	return 3600;
}
add_filter( 'wp_feed_cache_transient_lifetime' , 'return_rss_num' );

関数を作って入れることになる。

匿名関数と無名関数の違いはこちら

PHP5.3以降を使用している場合は、PHPマニュアルにもあるように無名関数を使用したほうがよさそう。

警告 / この関数は、内部的に eval() を実行しているので、 eval() と同様にセキュリティ上のリスクがあります。 さらに、パフォーマンスやメモリ使用効率の面でも問題があります。
PHP 5.3.0 以降を使っている場合は、この関数ではなく、ネイティブの 無名関数 を使うべきです。(出典・PHPマニュアル)

他にも無名関数は匿名関数の倍の処理速度だそうで。

WordPress カスタムフィールドの日付を使って今月の投稿を取得

1 Comment wordpress,

前提:
ミュージシャンのライブスケジュール用に、
カスタムフィールド(key:live_date)にDATE型の値(yyyy-mm-dd)を入れている。
その値を元に、指定した範囲の投稿を取得。(今月のライブなど)

※Wordpressには投稿日時を指定するdate_queryというパラメータがあるが、投稿日時自体は予約投稿などに使いたいので、今回はカスタムフィールドにライブ日時を設定している。

カスタム投稿用のパラメータcompareで、BETWEENなどの演算子が使え、しかもtype='DATE'と指定する事で、yyyy-mm-ddをそのまま比較する事が出来る。
具体的には、

$args = array(
	'order' => ASC,
	'orderby' => 'meta_value',
    'meta_query' => array(
       'relation' => 'AND',
       array(
         'key' => 'live_date',
         'value'=>array( '2016-05-01', '2016-05-31' ), //ここに配列で範囲をDATE型で設定。
         'compare'=>'BETWEEN',
	 'type'=>'DATE'
       )
    )
);
$wp_query = new WP_Query($args);

みたいな形。
ほんと凄い進化だねwordpress。

WordPressを4.5.2にアップデートしたら同梱のjQuery1.12で構文エラー祭り

No Comment wordpress,

WordPressがXSS,SOME(Same Origin Method Execution)脆弱性に対するアップデートを4.5.2で行った事を受けて、管理サイトを全てアップデートしていったのだが、この4.5.2に同梱されているjQueryが1.12になった事でエラーチェックが厳密になり、今まで動作してくれていたページ内遷移やYoutubeAPIなどが動作しなくなって困った。


(function($){

$(function() {
$('a[href^="#"]:not([href$="#"])').click(function() {
var href = $(this).attr('href');
var pos = $(href).offset().top;
var duration = 200;
$('body, html').animate({ scrollTop: pos }, duration, 'swing');
return false;
});
});

})(jQuery);

jQuery1.2以降で動作するスムーズスクロール。
出典はXakuro Systemさま
ありがとうございます。
エラーの詳細はリンク先を。

さて、ここからが本題。

上記スクリプトではページ内遷移出来ないケースがいくつかあった。
まぁ自分が悪いのだが、一応備忘録。

■ページ内遷移でドメインを入れている

例) http://mysite.com の中で、ページ内リンクを http://mysite.com#page-link などドメインを付けてリンクしていた場合、1.12では動かない。

■リンクhtmlに半角スペースを入れてしまっていた

例)

<a href=" page-link ">

phpの記述が不味く、リンクタグの属性内に半角スペースが入ってしまっていた場合、1.12では動かない。

javascriptと正規表現はホント苦手…。

pTypeConverterで残ってしまったカテゴリを除去する方法(荒業)

No Comment wordpress

タイトルの通り。
pTypeConverterで通常の投稿(カテゴリ名"hoge"とする)をカスタム投稿に変換しても、カテゴリ情報は削除されない。
そのため、その後条件分岐でin_category("hoge")などで振り分けようとしても通常の投稿と一緒に、変更したカスタム投稿が引っかかってしまう。
そりゃそうっちゃそうなんだけど、古いWPでカテゴリ分けで作っていたものを、カスタム投稿に振り分けたいなんて案件はざらにある。

で、カスタム投稿にした投稿からカテゴリ情報を除去する為には、そのカスタム投稿に"categeory"というカスタムタクソノミを作ってやればいい。

	register_post_type( 'hoge',
        array(
        'labels' => array(
        'name' => __( 'カスタム投稿名' ),
        'singular_name' => __( 'カスタム投稿名' )
        ),
        'public' => true,
        'has_archive' => true,
        'menu_position' => 5,
		'supports'=> array('title', 'thumbnail', 'excerpt', 'editor') ,
        )
    );
	register_taxonomy(
		'category',
		'column',
		array(
		'hierarchical' => true,
		'update_count_callback' => '_update_post_term_count',
		'label' => 'カテゴリー',
		'singular_label' => 'カテゴリー',
		'public' => true,
		'show_ui' => true,
		'query_var' => true
		)
	);  

こんな感じでカスタム投稿名に「カテゴリ」というカスタムタクソノミを追加してやると、通常の投稿(post)と同じカテゴリーが表示される。
ここでカテゴリ情報を除去すると、MySQL内のカテゴリとの関連性を示す「wp_term_relationships」が除去される。
カテゴリーもカスタムタクソノミの一種ってことですね。
流石Wordpress。