リニューアルしました。
このページは、2011年1月から2013年1月初旬までのアーカイブです。
2011年1月から2013年1月初旬までのアーカイブトップへ

現在のトップページはこちら

MTでカスタムフィールドの値を月間で合算して、PHPで集計するカスタマイズ

| カテゴリ:

毎日何時間運動したかとか、今日の売り上げは~、今日の勉強時間は~、みたいなカタチの値を毎日メモしておいて、あとで集計するにはどうしたらいいかを考えました。

エントリー毎、カスタムフィールドに何時間運動したかを入力。

MT4.1UPのカスタムフィールドで演算をする を参考にさせていただきました。

まず、カスタムフィールドをエントリーで使う設定にしたので、運動時間用のカスタムフィールドの値<$mt:dietmemo$>は<mt:Entries>の中で使います。

<mt:Entries>
<mt:SetVar name="<mt:archiveDate format="%Y%m">_var_month" value="0">
<mt:SetVarBlock name="month_total" value="$<mt:archiveDate format=
"%Y%m">_var_month" op="+"><$mt:dietmemo$></mt:SetVarBlock>
</mt:Entries>

<mt:If name="month_total">
<div class="diet-month">
<mt:SetVarBlock name="this_diet_month"><mt:archiveDate format="%Y年%m"></mt:SetVarBlock><$mt:GetVar name="this_diet_month"$>月にエクササイズした合計時間:<$mt:GetVar name="month_total"$>時間
</div>
</mt:If>

クラス名diet-monthのうしろは、閉じタグのところまで改行しないで1行で続けます(後でPHPから呼び出す時に関係するので)。

<mt:If name="month_total">の部分のモディファイアをいろいろ考えていたけれど、リファレンスをよく見たら、何も指定しなければ、「MTSetVar ファンクションタグに value モディファイアが設定されていて、その値が 0 ではない場合にのみ実行します。」とあった。よかった、よかった。

さて、重要なのは、ただ単にカスタムフィールドの値の累計を取るなら、モジュールやウィジェットを使ってサイトの好きなところに結果表示できるんですが、月別の集計を取るのなら、月別アーカイブのテンプレートに直にコードを書く必要があります。
最初、インデックスにあるアーカイブ(archives.php)に結果を出力しようとしてあれこれ試して、どうにもうまくいかず・・・挫折しました(何かうまい方法があれば教えてください)。

ついでに、年間集計を取るなら、当然年間アーカイブのテンプレートを新規で作って・・・ということになります(年間アーカイブを作らないと<mt:archiveList archive_type="Yearly">自体が使えない)。

ただ、これだけだと月間の合計数字を同じページに一覧表示できない。
他の仕事で、プログラマーさんがMTの変数をPHPに反映させているのを見たことがあるので、同じ方法でできないか調べてみました。

月別アーカイブのページから、集計結果の部分だけを文字列として抜き出せばいいのだから・・・

PHPについての質問です。外部ファイルの一部を読み込んで表示するにはどうすればいいのでしょうか? に、同じような質問をしている人を発見。

提案されているコードをコピペして試してみるけれど、質問者と同じように真っ白のページにしかならない。あるいは、うまくいっても、中身を少し変えるとまた真っ白。
PHPはエラーメッセージが出ないので、何が悪いかわからない。

とりあえず、簡単なサンプルページを作り、file_get_contentsができてないのか、preg_matchがダメなのか1文字変えては確認、1行変えては確認・・・・と延々作業しながら、何とか完成したのがコチラ。

<mt:Ignore>カウンターを作る</mt:Ignore>
<$mt:SetVar name="counter" value="0"$>

<mt:Ignore>月別アーカイブが現在何個あるかカウンターで数える</mt:Ignore>
<mt:archiveList archive_type="Monthly">
<$mt:SetVar name="counter" op="++"$>
<mt:Ignore>月別アーカイブが増えたら「年月」名を配列に入れる</mt:Ignore>
<mt:SetVarBlock name="push(set_monthly)"><mt:archiveDate format="%Y/%m/"></mt:SetVarBlock>
</mt:archiveList>

<?php
//MTで宣言した変数をPHPの変数に入れる
$x = <$mt:GetVar name="counter"$>;

for($i = 0; $x > $i; $i++){
//「年月」名の配列を作る
$set_monthly = array();
//上で作った配列にMTでできる配列の中身を追加する
print "<mt:Loop name="set_monthly">";
array_push ($set_monthly, '<$mt:Var name="__value__"$>'). "\n";
print "</mt:Loop>";
}

//PHPの関数foreachは、要素の数だけループさせるもの
foreach( $set_monthly as $element ){
$url = ("https://kumachabin.net/kumachabin/archives/{$element}index.php");

//エクササイズした時間を上記URLから抜き出して表示
$str = file_get_contents($url);
if (preg_match('!<div class="diet-month">\n((.*)\n)!', $str, $res)){
print $res[1];
print "<br />";
}else{
print "failed";
}
}
?>

<mt:Ignore>で囲まれたところはMT内で使うコメント欄です。HTMLには出力されません。
PHPの場合は//ではじめるとコメントになります。

私と同じくらい初心者で、これを使ってうまくいかない場合は、行最後の「;」を忘れてるとか、「;」の後に半角スペースが入ってるとか、変数前後に余計な半角スペースがあるとか、まあつまりモロモロが原因です。1文字づつなめるように見直してみてください。
あと、エントリー欄にコードを貼ると他の文字に置き換わっちゃう場合もあるので、気をつけて見直してますが、直し忘れもあるかも・・・。

これをテンプレートモジュールに入れれば、好きな場所に呼び出せる・・・と思います、たぶん。

MTの配列の使い方はカテゴリ名の全取得、配列へセットするを参考にさせていただきました。
PHPの配列はあちこちで解説があるんですが、たとえばここみたいに

$a = array('abc', 'def', 'ghi');
こういう形で紹介されているものばかりで、配列の中身が最初は決まってなくて、後から追加するにはどうしたらいいんだろうと、かなり悩みました。

foreachは超便利だった!
配列([ ]のカタチの)に変数入れてループで回して~とかグルグル考えていたのが、これだけで済んじゃったよ。

ただ、最後の結果出力の部分にあるprint $res[1];は、なんでprint $res;じゃダメなのかがわからない。$urlの部分はprint $url;で確認できるんだけどなあ。
preg_match - 正規表現によるマッチングを行う の最初に解説があるので、$resが配列になってるのはわかるけど、それなら$urlも同じじゃないかなあと思ったり・・・。
ここは、もうちょっと勉強しないと。

結果的に上記の形にまとまりましたが、もっとスマートなやり方もありそうだ・・・。