DocListerでテンプレート変数(日付)を使ったフィルター

いやはや、リソース変数の日付関連のフィールドはUnixtimeで保存されているのに、テンプレート変数ではフォーマットされた(%Y/%m/%d %H:%i:%s)になっているので、filtersパラメータがうまくいかなかった。
ロシア語のフォーラムを探していると、addWhereListのパラメータを使って抽出していたのでやってみました。
参考:http://modx.im/blog/5290.html
今回はイベントを表示するスニペットです。条件としては次のようなものです。
- テンプレート変数は、EvtStartが開催日、EvtEndが終了日
- イベントの開催日が早い順、同じ日の場合は終了日が早い順
- 現在の日時以前の過去の終了日が設定されているリソースは表示しない
if(!isset($debug))$debug = '0'; //どうにかならないときには1か2にして原因を探ってみる
$p = array(); //パラメータは配列
$p['parents'] = '2'; //親リソースID
$p['tvPrefix'] = ''; //デフォルトではtv.をつけることになっているので、消す。([+tv.テンプレート変数名+]がデフォルト)
$p['tvList'] = 'EvtStart,EvtEnd'; //読み込むテンプレート変数
$p['addWhereList'] = "UNIX_TIMESTAMP('dltv_EvtEnd_2.value') > UNIX_TIMESTAMP()"; //Unixtimeで比較
$p['orderBy'] = 'EvtStart ASC, EvtEnd ASC'; //テンプレート変数でソート
$p['debug'] = $debug;
return $modx->runSnippet('DocLister', $p); //スニペットを実行
今回、まず行き詰まったのはfiltersパラメータでテンプレート変数を扱おうとしたことです。
どうにかしてフォーマットされた日付をUnixtimeに変換しなければなりませんでした。
解決策はaddWhereListで直接絞り込む条件を書くことです。書き方はMySQLのWhere句と同じです。
初めはEvtStart変数だけでソートをしていたため、EvtEnd変数で抽出しようとするとうまくいきませんでした。
orderByパラメータでEvtEnd変数も読み込む必要があったのです。
このパラメータにテンプレート変数名を記述していないと、そもそも値として認識されませんでした。
「dltv_テンプレート変数名_1.value」にあるように、テンプレート変数のあとに来る「_1」はorderByパラメータで読み込んだ順番になっているようです。
paginateパラメータと相性が悪く、エラーが出るようなので気をつけてください。
回避策
リソースIDを前もって抽出してからDocListerに渡します。
これで無事回避できました。ページネーションもちゃんと動作します。
テンプレートIDはイベント終了日時のIDです。
if($view == 'past'){// getパラメータの値 $where = " AND UNIX_TIMESTAMP(value) <= UNIX_TIMESTAMP()"; }else{ $where = " AND UNIX_TIMESTAMP(value) > UNIX_TIMESTAMP()"; } $table = '[+prefix+]site_tmplvar_contentvalues'; $rs = $modx->db->select('contentid', $table, "tmplvarid = 7".$where); $ids = array(); while($row = $modx->db->getRow($rs, $mode = 'assoc')){ $ids[] = $row['contentid']; } if(empty($ids))return '
過去のイベントはありません。'; $ids = implode(',', $ids); $p = array(); $p['idType'] = 'documents'; $p['documents'] = $ids;
$p['paginate'] = 'pages';
return $modx->runSnippet('DocLister', $p);
2018年12月21日 / CMS