Commit 80a81ee0dfb846001535b256011cba1c243aa750
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
Showing
8 changed files
with
404 additions
and
20 deletions
lib/dashboard/Notification.inc.php
| 1 | 1 | <?php |
| 2 | 2 | |
| 3 | +require_once(KT_LIB_DIR . "/session/control.inc"); | |
| 3 | 4 | require_once(KT_LIB_DIR . "/ktentity.inc"); |
| 5 | +require_once(KT_LIB_DIR . "/database/datetime.inc"); | |
| 4 | 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 | 13 | * class Notification |
| ... | ... | @@ -68,6 +73,12 @@ class KTNotification extends KTEntity { |
| 68 | 73 | $handler = $notificationRegistry->getHandler($this->sType); |
| 69 | 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 | 83 | // Static function |
| 73 | 84 | function &get($iId) { return KTEntityUtil::get('KTNotification', $iId); } |
| ... | ... | @@ -83,6 +94,9 @@ $notificationRegistry =& KTNotificationRegistry::getSingleton(); |
| 83 | 94 | |
| 84 | 95 | // abstract base-class for notification handler. |
| 85 | 96 | class KTNotificationHandler { |
| 97 | + | |
| 98 | + // FIXME rename this to renderNotification | |
| 99 | + // called to _render_ the notification. | |
| 86 | 100 | function handleNotification($oKTNotification) { |
| 87 | 101 | $oTemplating = new KTTemplating; |
| 88 | 102 | $oTemplate = $oTemplating->loadTemplate("kt3/notifications/generic"); |
| ... | ... | @@ -91,17 +105,210 @@ class KTNotificationHandler { |
| 91 | 105 | ); |
| 92 | 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 | 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 | 218 | function handleNotification($oKTNotification) { |
| 98 | 219 | $oTemplating = new KTTemplating; |
| 99 | 220 | $oTemplate = $oTemplating->loadTemplate("kt3/notifications/subscriptions"); |
| 100 | 221 | $aTemplateData = array( |
| 101 | 222 | "context" => $oKTNotification, |
| 223 | + "info" => $this->_getSubscriptionData($oKTNotification), | |
| 102 | 224 | ); |
| 103 | 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 | 314 | $notificationRegistry->registerNotificationHandler("ktcore/subscriptions","KTSubscriptionNotification"); | ... | ... |
lib/documentmanagement/documentutil.inc.php
| ... | ... | @@ -393,7 +393,7 @@ class KTDocumentUtil { |
| 393 | 393 | $count = SubscriptionEngine::fireSubscription($oDocument->getID(), SubscriptionConstants::subscriptionAlertType("AddDocument"), |
| 394 | 394 | SubscriptionConstants::subscriptionType("DocumentSubscription"), |
| 395 | 395 | array( "folderID" => $oDocument->getFolderID(), |
| 396 | - "modifiedDocumentName" => $oDocument->getName() )); | |
| 396 | + "newDocumentName" => $oDocument->getName() )); | |
| 397 | 397 | global $default; |
| 398 | 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 | 58 | "RestoredArchivedDocument" => 12); |
| 59 | 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 | 80 | \ No newline at end of file | ... | ... |
lib/subscriptions/SubscriptionEngine.inc
| 1 | 1 | <?php |
| 2 | 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 | 14 | * $Id$ |
| 12 | 15 | * |
| ... | ... | @@ -41,8 +44,9 @@ class SubscriptionEngine { |
| 41 | 44 | * @param int the alert type (document change, new folder, etc.) |
| 42 | 45 | * @param int the subscription content type (folder, document) |
| 43 | 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 | 50 | global $default; |
| 47 | 51 | $default->log->info("fireSubscription ($iExternalID, $iSubscriptionAlertType, $iSubscriptionType, values)"); |
| 48 | 52 | // get the list of subscriber addresses that we need to alert |
| ... | ... | @@ -58,7 +62,8 @@ class SubscriptionEngine { |
| 58 | 62 | SubscriptionConstants::subscriptionAlertType("RemoveChildDocument") : |
| 59 | 63 | $iSubscriptionAlertType), |
| 60 | 64 | SubscriptionConstants::subscriptionType("FolderSubscription"), |
| 61 | - $aValues); | |
| 65 | + $aValues, | |
| 66 | + $iExternalId); | |
| 62 | 67 | $default->log->info("SubscriptionEngine::fireSubscription fired folder subscribers, count=$iSubscriptionsSent"); |
| 63 | 68 | } |
| 64 | 69 | |
| ... | ... | @@ -66,7 +71,7 @@ class SubscriptionEngine { |
| 66 | 71 | for ($i=0; $i<count($aSubscribers); $i++) { |
| 67 | 72 | // lookup the subscription |
| 68 | 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 | 75 | if (empty($oSubscription) || PEAR::isError($oSubscription)) { |
| 71 | 76 | $oSubscription =& new Subscription($aSubscribers[$i]->getID(), $aValues["folderID"], $iSubscriptionType); |
| 72 | 77 | $res = $oSubscription->create(); |
| ... | ... | @@ -96,6 +101,109 @@ class SubscriptionEngine { |
| 96 | 101 | $sAlertContent = AlertContent::getSubscriptionAlert($iSubscriptionAlertType, $aValues); |
| 97 | 102 | |
| 98 | 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 | 207 | if ($aSubscribers[$i]->getEmailNotification() && (strlen($aSubscribers[$i]->getEmail()) > 0)) { |
| 100 | 208 | |
| 101 | 209 | $oEmail = new EmailAlert($aSubscribers[$i]->getEmail(), $sAlertContent["subject"], $sAlertContent["text"]); |
| ... | ... | @@ -135,7 +243,7 @@ class SubscriptionEngine { |
| 135 | 243 | $iSubscriptionsSent += $iThisSubscriptionsSent; |
| 136 | 244 | } |
| 137 | 245 | } |
| 138 | - | |
| 246 | + | |
| 139 | 247 | // return the number of processed subscriptions |
| 140 | 248 | return $iSubscriptionsSent; |
| 141 | 249 | } |
| ... | ... | @@ -184,6 +292,7 @@ class SubscriptionEngine { |
| 184 | 292 | $_SESSION["errorMessage"] = $lang_err_database; |
| 185 | 293 | return false; |
| 186 | 294 | } |
| 295 | + $default->log->debug('retrieveSubscribers found count=' . count($aUsers)); | |
| 187 | 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 | 44 | \ No newline at end of file | ... | ... |
plugins/ktstandard/KTSubscriptions.php
| ... | ... | @@ -240,7 +240,8 @@ class KTArchiveSubscriptionTrigger { |
| 240 | 240 | SubscriptionConstants::subscriptionType("DocumentSubscription"), |
| 241 | 241 | array( |
| 242 | 242 | "folderID" => $oDocument->getFolderID(), |
| 243 | - "modifiedDocumentName" => $oDocument->getName() | |
| 243 | + "modifiedDocumentName" => $oDocument->getName(), | |
| 244 | + "folderName" => $oDocument->getFolderName(), | |
| 244 | 245 | )); |
| 245 | 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 | 800 | `label` varchar(255) NOT NULL default '', |
| 801 | 801 | `type` varchar(255) NOT NULL default '', |
| 802 | 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 | 807 | UNIQUE KEY `id` (`id`), |
| 808 | 808 | KEY `type` (`type`), |
| 809 | 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 | 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}¬ify_action=clear">Clear Alert</a> | |
| 9 | + </div> | |
| 10 | +{/if} | |
| 11 | + | |
| 5 | 12 | </dd> |
| 6 | 13 | \ No newline at end of file | ... | ... |