Commit 80a81ee0dfb846001535b256011cba1c243aa750

Authored by bshuttle
1 parent 574efcf4

- added rudimentary subscription support into notifications.

- extended notifications to be activation-aware (notify.php).
- forced subscriptionengine::fireSubscription to generate notifications.
- handle very simple subscription events.
- made notifications more robust against data-values.
- corrected a new bug in subscriptions.

Note:

- subscriptions needs to be completely revised:  it touches the code in 15 places, and is currently very hard to understand, extend and debug.


git-svn-id: https://kt-dms.svn.sourceforge.net/svnroot/kt-dms/trunk@4227 c91229c3-7414-0410-bfa2-8a42b809f60b
lib/dashboard/Notification.inc.php
1 <?php 1 <?php
2 2
  3 +require_once(KT_LIB_DIR . "/session/control.inc");
3 require_once(KT_LIB_DIR . "/ktentity.inc"); 4 require_once(KT_LIB_DIR . "/ktentity.inc");
  5 +require_once(KT_LIB_DIR . "/database/datetime.inc");
4 require_once(KT_LIB_DIR . "/dashboard/NotificationRegistry.inc.php"); 6 require_once(KT_LIB_DIR . "/dashboard/NotificationRegistry.inc.php");
5 7
  8 +require_once(KT_LIB_DIR . '/users/User.inc');
  9 +require_once(KT_LIB_DIR . '/documentmanagement/Document.inc');
  10 +require_once(KT_LIB_DIR . '/foldermanagement/Folder.inc');
6 11
7 /** 12 /**
8 * class Notification 13 * class Notification
@@ -68,6 +73,12 @@ class KTNotification extends KTEntity { @@ -68,6 +73,12 @@ class KTNotification extends KTEntity {
68 $handler = $notificationRegistry->getHandler($this->sType); 73 $handler = $notificationRegistry->getHandler($this->sType);
69 return $handler->handleNotification($this); 74 return $handler->handleNotification($this);
70 } 75 }
  76 +
  77 + function resolve() {
  78 + $notificationRegistry =& KTNotificationRegistry::getSingleton();
  79 + $handler = $notificationRegistry->getHandler($this->sType);
  80 + return $handler->resolveNotification($this);
  81 + }
71 82
72 // Static function 83 // Static function
73 function &get($iId) { return KTEntityUtil::get('KTNotification', $iId); } 84 function &get($iId) { return KTEntityUtil::get('KTNotification', $iId); }
@@ -83,6 +94,9 @@ $notificationRegistry =&amp; KTNotificationRegistry::getSingleton(); @@ -83,6 +94,9 @@ $notificationRegistry =&amp; KTNotificationRegistry::getSingleton();
83 94
84 // abstract base-class for notification handler. 95 // abstract base-class for notification handler.
85 class KTNotificationHandler { 96 class KTNotificationHandler {
  97 +
  98 + // FIXME rename this to renderNotification
  99 + // called to _render_ the notification.
86 function handleNotification($oKTNotification) { 100 function handleNotification($oKTNotification) {
87 $oTemplating = new KTTemplating; 101 $oTemplating = new KTTemplating;
88 $oTemplate = $oTemplating->loadTemplate("kt3/notifications/generic"); 102 $oTemplate = $oTemplating->loadTemplate("kt3/notifications/generic");
@@ -91,17 +105,210 @@ class KTNotificationHandler { @@ -91,17 +105,210 @@ class KTNotificationHandler {
91 ); 105 );
92 return $oTemplate->render($aTemplateData); 106 return $oTemplate->render($aTemplateData);
93 } 107 }
  108 +
  109 + // called to resolve the notification (typically from /notify.php?id=xxxxx
  110 + function resolveNotification($oKTNotification) {
  111 + $_SESSION['KTErrorMessage'][] = 'This notification handler does not support publication.';
  112 + exit(redirect(generateControllerLink('dashboard')));
  113 + }
94 } 114 }
95 115
  116 +// FIXME consider refactoring this into plugins/ktcore/ktstandard/KTSubscriptions.php
  117 +
96 class KTSubscriptionNotification extends KTNotificationHandler { 118 class KTSubscriptionNotification extends KTNotificationHandler {
  119 + /* Subscription Notifications
  120 + *
  121 + * Subscriptions are a large part of the notification volume.
  122 + * That said, notifications cater to a larger group, so there is some
  123 + * degree of mismatch between the two.
  124 + *
  125 + * Mapping the needs of subscriptions onto the provisions of notifications
  126 + * works as:
  127 + *
  128 + * $oKTN->label: object name [e.g. Document Name]
  129 + * $oKTN->strData1: event type [AddFolder, AddDocument, etc.]
  130 + * $oKTN->strData2: _location_ name. (e.g. folder of the subscription.)
  131 + * $oKTN->intData1: object id (e.g. document_id, folder_id)
  132 + * $oKTN->intData2: actor id (e.g. user_id)
  133 + *
  134 + */
  135 +
  136 + var $notificationType = 'ktcore/subscriptions';
  137 +
  138 + var $_eventObjectMap = array(
  139 + "AddFolder" => 'folder',
  140 + "RemoveSubscribedFolder" => '', // nothing. your subscription is now gone.
  141 + "RemoveChildFolder" => 'folder',
  142 + "AddDocument" => 'document',
  143 + "RemoveSubscribedDocument" => '', // nothing. your subscription is now gone.
  144 + "RemoveChildDocument" => 'folder',
  145 + "ModifyDocument" => 'document',
  146 + "CheckInDocument" => 'document',
  147 + "CheckOutDocument" => 'document',
  148 + "MovedDocument" => 'document',
  149 + "ArchivedDocument" => 'document', // can go through and request un-archival (?)
  150 + "RestoredArchivedDocument" => 'document');
  151 +
  152 + var $_eventTypeNames = array(
  153 + "AddFolder" => 'Folder added',
  154 + "RemoveSubscribedFolder" => 'Folder removed', // nothing. your subscription is now gone.
  155 + "RemoveChildFolder" => 'Folder removed',
  156 + "AddDocument" => 'Document added',
  157 + "RemoveSubscribedDocument" => 'Document removed', // nothing. your subscription is now gone.
  158 + "RemoveChildDocument" => 'Document removed',
  159 + "ModifyDocument" => 'Document modified',
  160 + "CheckInDocument" => 'Document checked in',
  161 + "CheckOutDocument" => 'Document checked out',
  162 + "MovedDocument" => 'Document moved',
  163 + "ArchivedDocument" => 'Document archived', // can go through and request un-archival (?)
  164 + "RestoredArchivedDocument" => 'Document restored');
  165 +
  166 + // helper method to extract / set the various pieces of information
  167 + function _getSubscriptionData($oKTNotification) {
  168 + $info = array(
  169 + 'object_name' => $oKTNotification->getLabel(),
  170 + 'event_type' => $oKTNotification->getStrData1(),
  171 + 'location_name' => $oKTNotification->getStrData2(),
  172 + 'object_id' => $oKTNotification->getIntData1(),
  173 + 'actor_id' => $oKTNotification->getIntData2(),
  174 + 'has_actor' => false,
  175 + 'notify_id' => $oKTNotification->getId(),
  176 + );
  177 +
  178 + $info['title'] = KTUtil::arrayGet($this->_eventTypeNames, $info['event_type'], 'Subscription alert:') .': ' . $info['object_name'];
  179 +
  180 + if ($info['actor_id'] !== null) {
  181 + $oTempUser = User::get($info['actor_id']);
  182 + if (PEAR::isError($oTempUser) || ($oTempUser == false)) {
  183 + // no-act
  184 + $info['actor'] = null;
  185 + } else {
  186 + $info['actor'] = $oTempUser;
  187 + $info['has_actor'] = true;
  188 + }
  189 + }
  190 +
  191 + if ($info['object_id'] !== null) {
  192 + $info['object'] = $this->_getEventObject($info['event_type'], $info['object_id']);
  193 + }
  194 +
  195 + return $info;
  196 + }
  197 +
  198 + // resolve the object type based on the alert type.
  199 + function _getEventObject($sAlertType, $id) {
  200 + $t = KTUtil::arrayGet($this->_eventObjectMap, $sAlertType ,'');
  201 + if ($t == 'document') {
  202 + $o = Document::get($id);
  203 + if (PEAR::isError($o) || ($o == false)) { return null;
  204 + } else { return $o; }
  205 + } else if ($t == 'folder') {
  206 + $o = Folder::get($id);
  207 + if (PEAR::isError($o) || ($o == false)) { return null;
  208 + } else { return $o; }
  209 + } else {
  210 + return null;
  211 + }
  212 + }
  213 +
  214 + function _getEventObjectType($sAlertType) {
  215 + return KTUtil::arrayGet($this->_eventObjectMap, $sAlertType ,'');
  216 + }
  217 +
97 function handleNotification($oKTNotification) { 218 function handleNotification($oKTNotification) {
98 $oTemplating = new KTTemplating; 219 $oTemplating = new KTTemplating;
99 $oTemplate = $oTemplating->loadTemplate("kt3/notifications/subscriptions"); 220 $oTemplate = $oTemplating->loadTemplate("kt3/notifications/subscriptions");
100 $aTemplateData = array( 221 $aTemplateData = array(
101 "context" => $oKTNotification, 222 "context" => $oKTNotification,
  223 + "info" => $this->_getSubscriptionData($oKTNotification),
102 ); 224 );
103 return $oTemplate->render($aTemplateData); 225 return $oTemplate->render($aTemplateData);
104 } 226 }
  227 +
  228 + // helper to _create_ a notification, in a way that is slightly less opaque.
  229 + function &generateSubscriptionNotification($aOptions) {
  230 + $creationInfo = array();
  231 + /*
  232 + "iId" => "id",
  233 + "iUserId" => "user_id",
  234 + "sLabel" => "label",
  235 + "sType" => "type",
  236 + "dCreationDate" => "creation_date",
  237 + "iData1" => "data_int_1",
  238 + "iData2" => "data_int_2",
  239 + "sData1" => "data_str_1",
  240 + "sData2" => "data_str_2",
  241 +
  242 + 'object_name' => $oKTNotification->getLabel(),
  243 + 'event_type' => $oKTNotification->getStrData1(),
  244 + 'location_name' => $oKTNotification->getStrData2(),
  245 + 'object_id' => $oKTNotification->getIntData1(),
  246 + 'actor_id' => $oKTNotification->getIntData2(),
  247 + 'has_actor' => false,
  248 +
  249 + */
  250 + $creationInfo['sLabel'] = $aOptions['target_name'];
  251 + $creationInfo['sData1'] = $aOptions['event_type'];
  252 + $creationInfo['sData2'] = $aOptions['location_name'];
  253 + $creationInfo['iData1'] = $aOptions['object_id'];
  254 + $creationInfo['iData2'] = $aOptions['actor_id'];
  255 + $creationInfo['iUserId'] = $aOptions['target_user'];
  256 + $creationInfo['sType'] = 'ktcore/subscriptions';
  257 + $creationInfo['dCreationDate'] = getCurrentDateTime(); // erk.
  258 +
  259 + global $default;
  260 +
  261 + //$default->log->debug('subscription notification: from ' . print_r($aOptions, true));
  262 + $default->log->debug('subscription notification: using ' . print_r($creationInfo, true));
  263 +
  264 + $oNotification =& KTNotification::createFromArray($creationInfo);
  265 +
  266 +
  267 + $default->log->debug('subscription notification: created ' . print_r($oNotification, true));
  268 +
  269 + return $oNotification; // $res.
  270 + }
  271 +
  272 +
  273 +
  274 + function resolveNotification($oKTNotification) {
  275 + $notify_action = KTUtil::arrayGet($_REQUEST, 'notify_action', null);
  276 + if ($notify_action == 'clear') {
  277 + $_SESSION['KTInfoMessage'][] = 'Cleared notification.';
  278 + $oKTNotification->delete();
  279 + exit(redirect(generateControllerLink('dashboard')));
  280 + }
  281 +
  282 + // otherwise, we want to redirect the to object represented by the item.
  283 + // - viewDocument and viewFolder are the appropriate items.
  284 + // - object_id
  285 + $info = $this->_getSubscriptionData($oKTNotification);
  286 +
  287 + $object_type = $this->_getEventObjectType($info['event_type']);
  288 + if ($object_type == '') {
  289 + $_SESSION['KTErrorMessage'][] = 'This notification has no "target". Please report as a bug that this subscription should only have a clear action.' . $object_type;
  290 + exit(redirect(generateControllerLink('dashboard')));
  291 + }
  292 +
  293 + if ($object_type == 'document') {
  294 + if ($info['object_id'] !== null) { // fails and generates an error with no doc-id.
  295 + $params = 'fDocumentId=' . $info['object_id'];
  296 + $url = generateControllerLink('viewDocument', $params);
  297 + $oKTNotification->delete(); // clear the alert.
  298 + exit(redirect($url));
  299 + }
  300 + } else if ($object_type == 'folder') {
  301 + if ($info['object_id'] !== null) { // fails and generates an error with no doc-id.
  302 + $params = 'fFolderId=' . $info['object_id'];
  303 + $url = generateControllerLink('browse', $params);
  304 + $oKTNotification->delete(); // clear the alert.
  305 + exit(redirect($url));
  306 + }
  307 + }
  308 + $_SESSION['KTErrorMessage'][] = 'This notification has no "target". Please inform the KnowledgeTree developers that there is a target bug with type: ' . $info['event_type'];
  309 + exit(redirect(generateControllerLink('dashboard')));
  310 + }
  311 +
105 } 312 }
106 313
107 $notificationRegistry->registerNotificationHandler("ktcore/subscriptions","KTSubscriptionNotification"); 314 $notificationRegistry->registerNotificationHandler("ktcore/subscriptions","KTSubscriptionNotification");
lib/documentmanagement/documentutil.inc.php
@@ -393,7 +393,7 @@ class KTDocumentUtil { @@ -393,7 +393,7 @@ class KTDocumentUtil {
393 $count = SubscriptionEngine::fireSubscription($oDocument->getID(), SubscriptionConstants::subscriptionAlertType("AddDocument"), 393 $count = SubscriptionEngine::fireSubscription($oDocument->getID(), SubscriptionConstants::subscriptionAlertType("AddDocument"),
394 SubscriptionConstants::subscriptionType("DocumentSubscription"), 394 SubscriptionConstants::subscriptionType("DocumentSubscription"),
395 array( "folderID" => $oDocument->getFolderID(), 395 array( "folderID" => $oDocument->getFolderID(),
396 - "modifiedDocumentName" => $oDocument->getName() )); 396 + "newDocumentName" => $oDocument->getName() ));
397 global $default; 397 global $default;
398 $default->log->info("checkInDocumentBL.php fired $count subscription alerts for checked out document " . $oDocument->getName()); 398 $default->log->info("checkInDocumentBL.php fired $count subscription alerts for checked out document " . $oDocument->getName());
399 399
lib/subscriptions/SubscriptionConstants.inc
@@ -58,5 +58,22 @@ class SubscriptionConstants { @@ -58,5 +58,22 @@ class SubscriptionConstants {
58 "RestoredArchivedDocument" => 12); 58 "RestoredArchivedDocument" => 12);
59 return $aChangeType[$sType]; 59 return $aChangeType[$sType];
60 } 60 }
  61 +
  62 + function subscriptionAlertTypeString($iType) {
  63 + $aChangeType = array(1 => "AddFolder",
  64 + 2 => "RemoveSubscribedFolder",
  65 + 3 => "RemoveChildFolder",
  66 + 4 => "AddDocument",
  67 + 5 => "RemoveSubscribedDocument",
  68 + 6 => "RemoveChildDocument",
  69 + 7 => "ModifyDocument",
  70 + 8 => "CheckInDocument",
  71 + 9 => "CheckOutDocument",
  72 + 10 => "MovedDocument",
  73 + 11 => "ArchivedDocument",
  74 + 12 => "RestoredArchivedDocument",
  75 + );
  76 + return $aChangeType[$iType];
  77 + }
61 } 78 }
62 ?> 79 ?>
63 \ No newline at end of file 80 \ No newline at end of file
lib/subscriptions/SubscriptionEngine.inc
1 <?php 1 <?php
2 global $default; 2 global $default;
3 -require_once("$default->fileSystemRoot/lib/users/User.inc");  
4 -require_once("$default->fileSystemRoot/lib/documentmanagement/Document.inc");  
5 -require_once("$default->fileSystemRoot/lib/foldermanagement/Folder.inc");  
6 -require_once("$default->fileSystemRoot/lib/subscriptions/Subscription.inc");  
7 -require_once("$default->fileSystemRoot/lib/alert/AlertContent.inc");  
8 -require_once("$default->fileSystemRoot/lib/alert/delivery/EmailAlert.inc");  
9 -require_once("$default->fileSystemRoot/lib/alert/delivery/SMSAlert.inc"); 3 +require_once(KT_LIB_DIR . "/users/User.inc");
  4 +require_once(KT_LIB_DIR . "/documentmanagement/Document.inc");
  5 +require_once(KT_LIB_DIR . "/foldermanagement/Folder.inc");
  6 +require_once(KT_LIB_DIR . "/subscriptions/Subscription.inc");
  7 +require_once(KT_LIB_DIR . "/alert/AlertContent.inc");
  8 +require_once(KT_LIB_DIR . "/alert/delivery/EmailAlert.inc");
  9 +require_once(KT_LIB_DIR . "/alert/delivery/SMSAlert.inc");
  10 +
  11 +require_once(KT_LIB_DIR . "/dashboard/Notification.inc.php");
  12 +
10 /** 13 /**
11 * $Id$ 14 * $Id$
12 * 15 *
@@ -41,8 +44,9 @@ class SubscriptionEngine { @@ -41,8 +44,9 @@ class SubscriptionEngine {
41 * @param int the alert type (document change, new folder, etc.) 44 * @param int the alert type (document change, new folder, etc.)
42 * @param int the subscription content type (folder, document) 45 * @param int the subscription content type (folder, document)
43 * @param array any dynamic values that should be sent with the alert (eg. document name, path to modified document) 46 * @param array any dynamic values that should be sent with the alert (eg. document name, path to modified document)
  47 + * @param int the original object id (e.g. if fired on a document, and chained to a folder.
44 */ 48 */
45 - function fireSubscription($iExternalID, $iSubscriptionAlertType, $iSubscriptionType, $aValues) { 49 + function fireSubscription($iExternalID, $iSubscriptionAlertType, $iSubscriptionType, $aValues, $iOriginalId = null) {
46 global $default; 50 global $default;
47 $default->log->info("fireSubscription ($iExternalID, $iSubscriptionAlertType, $iSubscriptionType, values)"); 51 $default->log->info("fireSubscription ($iExternalID, $iSubscriptionAlertType, $iSubscriptionType, values)");
48 // get the list of subscriber addresses that we need to alert 52 // get the list of subscriber addresses that we need to alert
@@ -58,7 +62,8 @@ class SubscriptionEngine { @@ -58,7 +62,8 @@ class SubscriptionEngine {
58 SubscriptionConstants::subscriptionAlertType("RemoveChildDocument") : 62 SubscriptionConstants::subscriptionAlertType("RemoveChildDocument") :
59 $iSubscriptionAlertType), 63 $iSubscriptionAlertType),
60 SubscriptionConstants::subscriptionType("FolderSubscription"), 64 SubscriptionConstants::subscriptionType("FolderSubscription"),
61 - $aValues); 65 + $aValues,
  66 + $iExternalId);
62 $default->log->info("SubscriptionEngine::fireSubscription fired folder subscribers, count=$iSubscriptionsSent"); 67 $default->log->info("SubscriptionEngine::fireSubscription fired folder subscribers, count=$iSubscriptionsSent");
63 } 68 }
64 69
@@ -66,7 +71,7 @@ class SubscriptionEngine { @@ -66,7 +71,7 @@ class SubscriptionEngine {
66 for ($i=0; $i<count($aSubscribers); $i++) { 71 for ($i=0; $i<count($aSubscribers); $i++) {
67 // lookup the subscription 72 // lookup the subscription
68 if ($iSubscriptionType == SubscriptionConstants::subscriptionType("FolderSubscription")) { 73 if ($iSubscriptionType == SubscriptionConstants::subscriptionType("FolderSubscription")) {
69 - $oSubscription = & Subscription::getByIDs($aSubscribers[$i]->getID(), $oValues['folderID'], $iSubscriptionType); 74 + $oSubscription = & Subscription::getByIDs($aSubscribers[$i]->getID(), $aValues['folderID'], $iSubscriptionType);
70 if (empty($oSubscription) || PEAR::isError($oSubscription)) { 75 if (empty($oSubscription) || PEAR::isError($oSubscription)) {
71 $oSubscription =& new Subscription($aSubscribers[$i]->getID(), $aValues["folderID"], $iSubscriptionType); 76 $oSubscription =& new Subscription($aSubscribers[$i]->getID(), $aValues["folderID"], $iSubscriptionType);
72 $res = $oSubscription->create(); 77 $res = $oSubscription->create();
@@ -96,6 +101,109 @@ class SubscriptionEngine { @@ -96,6 +101,109 @@ class SubscriptionEngine {
96 $sAlertContent = AlertContent::getSubscriptionAlert($iSubscriptionAlertType, $aValues); 101 $sAlertContent = AlertContent::getSubscriptionAlert($iSubscriptionAlertType, $aValues);
97 102
98 // construct alerts 103 // construct alerts
  104 +
  105 + // dashboard notification.
  106 + $aNotificationOptions = array();
  107 +
  108 + $aNotificationOptions['target_user'] = $aSubscribers[$i]->getID();
  109 + $aNotificationOptions['actor_id'] = KTUtil::arrayGet($_SESSION,"userID", null); // _won't_ be null.
  110 +
  111 + // location name: ditto.
  112 + // target_name: ditto.
  113 +
  114 + //$default->log->debug('subscriptionengine: received ' . print_r($aValues, true));
  115 +
  116 + // sweet lord this is _hideous_. Please, oh please kill the subscriptionsconstants
  117 + if (SubscriptionConstants::subscriptionAlertTypeString($iSubscriptionAlertType) == "AddFolder") {
  118 + $aNotificationOptions['target_name'] = $aValues["newFolderName"];
  119 + $aNotificationOptions['location_name'] = $aValues["parentFolderName"];
  120 + $aNotificationOptions['object_id'] = $iExternalId; // parent folder_id, in this case.
  121 + $aNotificationOptions['event_type'] = "AddFolder";
  122 + } else if (SubscriptionConstants::subscriptionAlertTypeString($iSubscriptionAlertType) == "RemoveSubscribedFolder") {
  123 + $aNotificationOptions['target_name'] = $aValues["removedFolderName"];
  124 + $aNotificationOptions['location_name'] = $aValues["parentFolderName"];
  125 + $aNotificationOptions['object_id'] = $iExternalId; // parent folder_id, in this case.
  126 + $aNotificationOptions['event_type'] = "RemoveSubscribedFolder";
  127 + } else if (SubscriptionConstants::subscriptionAlertTypeString($iSubscriptionAlertType) == "RemoveChildFolder") {
  128 + $aNotificationOptions['target_name'] = $aValues["removedFolderName"];
  129 + $aNotificationOptions['location_name'] = $aValues["parentFolderName"];
  130 + $aNotificationOptions['object_id'] = $iExternalId; // parent folder_id, in this case, where user is subscribed.
  131 + $aNotificationOptions['event_type'] = "RemoveChildFolder";
  132 + } else if (SubscriptionConstants::subscriptionAlertTypeString($iSubscriptionAlertType) == "AddDocument") {
  133 + $aNotificationOptions['target_name'] = $aValues["newDocumentName"];
  134 + $aNotificationOptions['location_name'] = $aValues["parentFolderName"];
  135 + if ($iOriginalId !== null) {
  136 + $aNotificationOptions['object_id'] = $iOriginalId; // folder subscription, this _was_ the document.
  137 + } else {
  138 + $aNotificationOptions['object_id'] = $iExternalId; // this path _shouldn't_ be hit since its a new document - user _can't_ be subscribed to it already.
  139 + }
  140 + $aNotificationOptions['event_type'] = "AddDocument";
  141 + } else if (SubscriptionConstants::subscriptionAlertTypeString($iSubscriptionAlertType) == "RemoveChildDocument") {
  142 + $aNotificationOptions['target_name'] = $aValues["removedDocumentName"];
  143 + $aNotificationOptions['location_name'] = $aValues["folderName"];
  144 + $aNotificationOptions['object_id'] = $iExternalId; // parent folder_id, in this case, where user is subscribed... is it?
  145 + $aNotificationOptions['event_type'] = "RemoveChildDocument";
  146 + } else if (SubscriptionConstants::subscriptionAlertTypeString($iSubscriptionAlertType) == "RemoveSubscribedDocument") {
  147 + $aNotificationOptions['target_name'] = $aValues["removedDocumentName"];
  148 + $aNotificationOptions['location_name'] = $aValues["folderName"];
  149 + $aNotificationOptions['object_id'] = $iExternalId; // not used.
  150 + $aNotificationOptions['event_type'] = "RemoveSubscribedDocument";
  151 + } else if (SubscriptionConstants::subscriptionAlertTypeString($iSubscriptionAlertType) == "ModifyDocument") {
  152 + $aNotificationOptions['target_name'] = $aValues["modifiedDocumentName"];
  153 + $aNotificationOptions['location_name'] = null; // not used... why? don't we have the folder name? why not?
  154 + if ($iOriginalId !== null) {
  155 + $aNotificationOptions['object_id'] = $iOriginalId; // folder subscription, this _was_ the document.
  156 + } else {
  157 + $aNotificationOptions['object_id'] = $iExternalId; // this path _shouldn't_ be hit since its a new document - user _can't_ be subscribed to it already.
  158 + }
  159 + $aNotificationOptions['event_type'] = "ModifyDocument";
  160 + } else if (SubscriptionConstants::subscriptionAlertTypeString($iSubscriptionAlertType) == "CheckInDocument") {
  161 + $aNotificationOptions['target_name'] = $aValues["modifiedDocumentName"];
  162 + $aNotificationOptions['location_name'] = null; // not used... why? don't we have the folder name? why not?
  163 + if ($iOriginalId !== null) {
  164 + $aNotificationOptions['object_id'] = $iOriginalId; // folder subscription, this _was_ the document.
  165 + } else {
  166 + $aNotificationOptions['object_id'] = $iExternalId; // this path _shouldn't_ be hit since its a new document - user _can't_ be subscribed to it already.
  167 + }$aNotificationOptions['event_type'] = "CheckInDocument";
  168 + } else if (SubscriptionConstants::subscriptionAlertTypeString($iSubscriptionAlertType) == "CheckOutDocument") {
  169 + $aNotificationOptions['target_name'] = $aValues["modifiedDocumentName"];
  170 + $aNotificationOptions['location_name'] = null; // not used... why? don't we have the folder name? why not?
  171 + if ($iOriginalId !== null) {
  172 + $aNotificationOptions['object_id'] = $iOriginalId; // folder subscription, this _was_ the document.
  173 + } else {
  174 + $aNotificationOptions['object_id'] = $iExternalId; // this path _shouldn't_ be hit since its a new document - user _can't_ be subscribed to it already.
  175 + }$aNotificationOptions['event_type'] = "CheckOutDocument";
  176 + } else if (SubscriptionConstants::subscriptionAlertTypeString($iSubscriptionAlertType) == "MovedDocument") {
  177 + $aNotificationOptions['target_name'] = $aValues["modifiedDocumentName"];
  178 + $aNotificationOptions['location_name'] = $aValues["oldFolderName"];
  179 + if ($iOriginalId !== null) {
  180 + $aNotificationOptions['object_id'] = $iOriginalId; // folder subscription, this _was_ the document.
  181 + } else {
  182 + $aNotificationOptions['object_id'] = $iExternalId;
  183 + }$aNotificationOptions['event_type'] = "MovedDocument";
  184 + } else if (SubscriptionConstants::subscriptionAlertTypeString($iSubscriptionAlertType) == "ArchivedDocument") {
  185 + $aNotificationOptions['target_name'] = $aValues["modifiedDocumentName"];
  186 + $aNotificationOptions['location_name'] = $aValues["folderName"];
  187 + if ($iOriginalId !== null) {
  188 + $aNotificationOptions['object_id'] = $iOriginalId; // folder subscription, this _was_ the document.
  189 + } else {
  190 + $aNotificationOptions['object_id'] = $iExternalId;
  191 + }
  192 + $aNotificationOptions['event_type'] = "ArchivedDocument";
  193 + } else if (SubscriptionConstants::subscriptionAlertTypeString($iSubscriptionAlertType) == "RestoredArchivedDocument") {
  194 + $aNotificationOptions['target_name'] = $aValues["modifiedDocumentName"];
  195 + $aNotificationOptions['location_name'] = null; // $aValues["folderName"]; // not reachable.
  196 + if ($iOriginalId !== null) {
  197 + $aNotificationOptions['object_id'] = $iOriginalId; // folder subscription, this _was_ the document.
  198 + } else {
  199 + $aNotificationOptions['object_id'] = $iExternalId;
  200 + }
  201 + $aNotificationOptions['event_type'] = "RestoredArchivedDocument";
  202 + }
  203 +
  204 + $oNotification =& KTSubscriptionNotification::generateSubscriptionNotification($aNotificationOptions);
  205 +
  206 + // email alert.
99 if ($aSubscribers[$i]->getEmailNotification() && (strlen($aSubscribers[$i]->getEmail()) > 0)) { 207 if ($aSubscribers[$i]->getEmailNotification() && (strlen($aSubscribers[$i]->getEmail()) > 0)) {
100 208
101 $oEmail = new EmailAlert($aSubscribers[$i]->getEmail(), $sAlertContent["subject"], $sAlertContent["text"]); 209 $oEmail = new EmailAlert($aSubscribers[$i]->getEmail(), $sAlertContent["subject"], $sAlertContent["text"]);
@@ -135,7 +243,7 @@ class SubscriptionEngine { @@ -135,7 +243,7 @@ class SubscriptionEngine {
135 $iSubscriptionsSent += $iThisSubscriptionsSent; 243 $iSubscriptionsSent += $iThisSubscriptionsSent;
136 } 244 }
137 } 245 }
138 - 246 +
139 // return the number of processed subscriptions 247 // return the number of processed subscriptions
140 return $iSubscriptionsSent; 248 return $iSubscriptionsSent;
141 } 249 }
@@ -184,6 +292,7 @@ class SubscriptionEngine { @@ -184,6 +292,7 @@ class SubscriptionEngine {
184 $_SESSION["errorMessage"] = $lang_err_database; 292 $_SESSION["errorMessage"] = $lang_err_database;
185 return false; 293 return false;
186 } 294 }
  295 + $default->log->debug('retrieveSubscribers found count=' . count($aUsers));
187 return $aUsers; 296 return $aUsers;
188 } 297 }
189 } 298 }
notify.php 0 โ†’ 100644
  1 +<?php
  2 +
  3 +require_once('config/dmsDefaults.php');
  4 +require_once(KT_LIB_DIR . '/dashboard/NotificationRegistry.inc.php');
  5 +require_once(KT_LIB_DIR . '/dashboard/Notification.inc.php');
  6 +require_once(KT_LIB_DIR . '/dispatcher.inc.php');
  7 +require_once(KT_LIB_DIR . '/session/control.inc');
  8 +
  9 +/*
  10 + * Using KTStandardDispatcher for errorPage, overriding handleOutput as
  11 + * the document action dispatcher will handle that.
  12 + */
  13 +
  14 +/**
  15 + * Dispatcher for action.php/actionname
  16 + *
  17 + * This dispatcher looks up the action from the Action Registry, and
  18 + * then chains onto that action's dispatcher.
  19 + */
  20 +class KTNotificationDispatcher extends KTStandardDispatcher {
  21 + var $notification;
  22 +
  23 + function check() {
  24 + $notification_id = KTUtil::arrayGet($_REQUEST, 'id', null);
  25 + $oKTNotification =& KTNotification::get($notification_id);
  26 +
  27 + if (PEAR::isError($oKTNotification)) {
  28 + $_SESSION['KTErrorMessage'][] = 'Invalid notification.';
  29 + exit(redirect(generateControllerLink('dashboard')));
  30 + }
  31 +
  32 + $this->notification =& $oKTNotification;
  33 +
  34 + return true;
  35 + }
  36 + function do_main() {
  37 + // get the notification-handler, instantiate it, call resolveNotification.
  38 + return $this->notification->resolve();
  39 + }
  40 +}
  41 +
  42 +$dispatcher =& new KTNotificationDispatcher();
  43 +$dispatcher->dispatch();
0 \ No newline at end of file 44 \ No newline at end of file
plugins/ktstandard/KTSubscriptions.php
@@ -240,7 +240,8 @@ class KTArchiveSubscriptionTrigger { @@ -240,7 +240,8 @@ class KTArchiveSubscriptionTrigger {
240 SubscriptionConstants::subscriptionType("DocumentSubscription"), 240 SubscriptionConstants::subscriptionType("DocumentSubscription"),
241 array( 241 array(
242 "folderID" => $oDocument->getFolderID(), 242 "folderID" => $oDocument->getFolderID(),
243 - "modifiedDocumentName" => $oDocument->getName() 243 + "modifiedDocumentName" => $oDocument->getName(),
  244 + "folderName" => $oDocument->getFolderName(),
244 )); 245 ));
245 $default->log->info("archiveDocumentBL.php fired $count subscription alerts for archived document " . $oDocument->getName()); 246 $default->log->info("archiveDocumentBL.php fired $count subscription alerts for archived document " . $oDocument->getName());
246 } 247 }
sql/mysql/install/structure.sql
@@ -800,10 +800,10 @@ CREATE TABLE `notifications` ( @@ -800,10 +800,10 @@ CREATE TABLE `notifications` (
800 `label` varchar(255) NOT NULL default '', 800 `label` varchar(255) NOT NULL default '',
801 `type` varchar(255) NOT NULL default '', 801 `type` varchar(255) NOT NULL default '',
802 `creation_date` datetime NOT NULL default '0000-00-00 00:00:00', 802 `creation_date` datetime NOT NULL default '0000-00-00 00:00:00',
803 - `data_int_1` int(11) NOT NULL default '0',  
804 - `data_int_2` int(11) NOT NULL default '0',  
805 - `data_str_1` varchar(255) NOT NULL default '',  
806 - `data_str_2` varchar(255) NOT NULL default '', 803 + `data_int_1` int(11),
  804 + `data_int_2` int(11),
  805 + `data_str_1` varchar(255),
  806 + `data_str_2` varchar(255),
807 UNIQUE KEY `id` (`id`), 807 UNIQUE KEY `id` (`id`),
808 KEY `type` (`type`), 808 KEY `type` (`type`),
809 KEY `user_id` (`user_id`) 809 KEY `user_id` (`user_id`)
templates/kt3/notifications/subscriptions.smarty
1 -<dt class="actionitem subscription">Subscription Alert: {$context->getLabel()}</dt> 1 +<dt class="actionitem subscription">{$info.title}</dt>
2 <dd class="actionmessage"> 2 <dd class="actionmessage">
3 - This document was updated in the folder "{$context->getStrData1()}", to which you are subscribed.  
4 - <div class="actionoptions"><a href="#">Read Document</a> | <a href="#">Clear Alert</a></div> 3 +<!-- could break this up. -->
  4 +{if ($info.event_type == 'AddDocument')}
  5 + The document "{$info.object_name}" was added{if ($info.location_name !== null)} to "{$info.location_name}"{/if}.
  6 + <div class="actionoptions">
  7 + <a href="{$rootUrl}/notify.php?id={$info.notify_id}">Read Document</a> |
  8 + <a href="{$rootUrl}/notify.php?id={$info.notify_id}&notify_action=clear">Clear Alert</a>
  9 + </div>
  10 +{/if}
  11 +
5 </dd> 12 </dd>
6 \ No newline at end of file 13 \ No newline at end of file