[+changenote:setDateSource+]
KP
I tend to go for the "suck it and see" approach, myself. Surprisingly often, things just work.Don’t get me wrong, I’m kind of a hobby scientist, and scientists like to make up hypotheses before testing something

. Inside phx:setDateSource $modx->documentObject[’id’] is not the id of the document currently processed by ditto, but the feed document itself. So I pass the currently processed id with the $options to the phx modifier ...[[Ditto? &parents=`0` &dateSource=`editedon` &sortBy=`editedon` &tpl=`rss_watched_item` &noResults=`<!-- keine Dokumente gefunden -->` &depth=`0` &display=`10` ]]
<item> <title><![CDATA[ [+title+] ]]></title> <link>[(site_url)][~[+id+]~]</link> <description><![CDATA[ [+changenote:setDateSource=`[+id+]`+] ]]></description> <pubDate>[+editedon:date=`%a, %d %b %Y %H:%M:%S +0100`+]</pubDate> </item>
<?php
$doc = isset($options) ? $modx->getDocument($options) : $modx->documentObject;
if (!$output) {
$doc['editedon'] = $doc['createdon'];
return $doc['introtext'];
}
else return $output;
?>changenote: [*changenote:ifempty=`(empty)`*]<br /> rss_description=[*changenote:setDateSource*]<br /> ditto_date=[*editedon*] <!-- from dateSource --> <br /> createdon=[*createdon*]
[[Ditto? &id=`xyz` &dateSource=`editedon` &filter=`changenote,,2` &appendOnly=`10` ]] <!-- get documents with set [*changenote*] --> [[Ditto? &id=`xyz` &dateSource=`createdon` &filter=`hidemenu,1,2` &appendOnly=`10` ]] <!-- other documents shown in menus --> [[Ditto? &id=`xyz` &display=`10` tpl=`rss_watched_item` ]] <!-- display items from both groups; will sort them anew no matter what date was -->
<item> <title><![CDATA[ [+title+] ]]></title> <link>[(site_url)][~[+id+]~]</link> <description><![CDATA[ [+changenote:setDateSource=`desc,[+id+],[+introtext+]`+] ]]></description> <pubDate>[+changenote:setDateSource=`date,[+id+]`+]</pubDate> </item>
<?php
$result="";
$switches = explode(',',$options);
$field = $switches[0]; // 'desc' = description, else date
$docId = $switches[1];
$intro = (isset($switches[2])) ? $switches[2] : "";
$docInfo = $modx->getPageInfo($docId,1,'createdon,editedon');
$created = $docInfo['createdon'];
$edited = $docInfo['editedon'];
if (!empty($output)) {
// item with changedate - return changedate text / editedon
if ($field == 'desc') {
$result = $output;
} else {
$result = strftime('%a, %d %b %Y %H:%M:%S +0100',$edited);
}
} else {
// no change - return introtext / createdon
if ($field == 'desc') {
$result = $intro;
} else {
$result = strftime('%a, %d %b %Y %H:%M:%S +0100',$created);
}
}
return $result;
?>
KP
SELECT sc.id, FROM_UNIXTIME( sc.editedon ) , tv.value FROM `site_content` AS sc LEFT JOIN site_tmplvar_contentvalues AS tv ON sc.id = tv.contentid WHERE tv.tmplvarid =13 -- tv changenote has id 13 AND tv.value IS NOT NULL ORDER BY editedon DESC LIMIT 10; 136 2009-05-21 17:37:46 139 2009-02-27 20:18:18 135 2009-02-02 21:51:11
SELECT id, FROM_UNIXTIME( createdon ) FROM `site_content` WHERE hidemenu =0 ORDER BY createdon DESC LIMIT 10; id FROM_UNIXTIME(createdon) 142 2009-04-10 16:30:05 141 2009-04-10 16:25:22 140 2009-03-15 00:07:13 139 2009-02-22 19:44:00 138 2009-02-22 19:41:04 137 2009-02-08 00:27:20 136 2009-02-04 20:48:53 135 2009-02-02 21:30:37 132 2009-01-06 16:24:28 131 2008-12-14 00:04:24
id <pubdate> <description> 136 2009-05-21 17:37:46 changenote 142 2009-04-10 16:30:05 introtext 141 2009-04-10 16:25:22 introtext 140 2009-03-15 00:07:13 introtext 139 2009-02-27 20:18:18 changenote 138 2009-02-22 19:41:04 introtext 137 2009-02-08 00:27:20 introtext 135 2009-02-02 21:51:11 changenote 132 2009-01-06 16:24:28 introtext 131 2008-12-14 00:04:24 introtext
,<?php
/* A snippet to be used in the MODx Content Management System
* title: "Change notification feed"
* author: agilero
* version: 0.9-beta, tested with MODx 0.9.6.3
*
* This snippet outputs (e.g.) rss-item chunks of docs which either
* - have been recently published (in this case, the item description is introtext)
* - or have been recently edited AND have got a change note set (description: value of the respective tv)
*
* NOTE: As soon as Ditto is capable of merging different results sets, this snippet may become obsolete.
* Check the changelog of the latest Ditto version and rather prefer that awesome piece.
*
* Requirements: A template variable of type text to keep what's to be displayed
* as intro for reannounced changed documents. If you don't want to have a
* changed document reappear in the feed, leave the value empty.
*
* Installation: Nothing special. Refer to the general snippet installation guidelines
*
* Example Call (snippet label assumed here: ChangeNotifiier):
* {... any prefix code ... }
* [!ChangeNotifier? &ids=`5*` &tpl=`rss_watched_item` &limit=`10` !]
* { ... any suffix code ... }
* &ids: either comma-separated list of ids (e.g. from Ditto) or one id with an asterisk denoting "this and all descendents"
* if unset: whole site
* &tpl: Omittable if you adjust the default value below. The chunk should contain the placeholders [+id+], [+title+], [+text+] and [+date+].
* For debugging purposes there is [+set+] which is 'N' for "newly published" documents and 'C' for changed documents
* &limit: default 10
* &datefmt: defaults to a rss-compliant notation. Refer to the strftime() documentation to adapt it
* TODO: Anybody knows how to enable phx support when parsing $tpl? So this parameter could be omitted in favour of phx:date ...
*
* Final Note: You should use change notifications only for significant, valuable changes on pages. Don't junk your user's feedreader
*/
/************** CONFIGURATION SECTION ********************/
$changenote_tv_id = 13; // as my tv "changenote" has the id 13 (shown on the resource manager / resources / template variables tab)
$title = 'longtitle'; // this is my choice. You'd rather use 'pagetitle', as this is mandatory at document creation, it cannot be empty -- 'longtitle' can.
// adapt the default values here (after the colon, always quoted), so you can ommit those parameters in the call.
$tpl = isset($tpl) ? $tpl : 'rss_watched_item';
$limit = isset($limit) ? $limit : 10;
$datefmt = isset($datefmt) ? $datefmt : '%a, %d %b %Y %H:%M:%S +0100';
/**************** PROGRAMMATIC SECTION (Changes on your risk of broken code ;-) ********************/
global $modx;
// 1. get the set of ids that can appear in the feed
if ( preg_match('/\d+\*$/', $ids) ) {
$ids = substr($ids, 0, -1);
$idset = $modx->getChildIds($ids);
array_unshift($idset,$ids);
}
elseif ( $ids != '*' ) { $idset = explode( ',', $ids); }
else { $idset = ''; }
if ($idset) {
array_walk( $idset, 'pack_sql_cond');
$idset = '( ' . implode( ' OR ', $idset) . ' ) AND';
}
function pack_sql_cond (&$id, $index) { $id = 'sc.id='.$id; }
$results = array();
// 2. Retrieve documents recently edited AND with a changenote set
$res = $modx->db->select(
"sc.id id, sc.editedon date, sc.$title title, tv.value text",
"site_content sc, site_tmplvar_contentvalues tv",
"$idset sc.id = tv.contentid AND tv.tmplvarid=$changenote_tv_id AND tv.value IS NOT NULL",
"sc.editedon DESC",
$limit);
while ( $row = $modx->db->getRow($res) ) {
$row['set'] = 'C';
array_push($results, $row);
}
// 3. Retrieve documents recently published and shown in the menus
$res = $modx->db->select(
"sc.id id, sc.publishedon date, sc.$title title, sc.introtext text",
"site_content sc",
"$idset sc.hidemenu=0",
"sc.publishedon DESC",
$limit);
while ( $row = $modx->db->getRow($res) ) {
$row['set'] = 'N';
array_push($results, $row);
}
// 3. Resort the array.
// (Let's hope that, if an id occurs in both sets, the C-set entry occurs always first)
usort($results, "order_desc");
function order_desc ($a, $b) {
$a = $a['date']; $b = $b['date'];
if ($a == $b) {
return 0;
}
return ($a > $b) ? -1 : 1;
}
// 4. Merge the results sets. Stop when limit is reached.
$keys = array();
foreach ( $results as $data ) {
$id = $data['id'];
if ($keys[$id]) continue;
if (!$limit--) break;
$keys[$id] = $data;
$keys[$id]['date'] = strftime($datefmt, $data['date']);
}
// 5. Pack the results each into the template
$results = '';
foreach ( $keys as $doc )
$results .= $modx->parseChunk($tpl, $doc, '[+', '+]');
return $results;
?>