📄 subscriptions.inc.php
字号:
$parentId = $oParentFolder->getId();
$this->sendNotification($aUsers, 'RestoreArchivedDocument', $oModifiedDocument->getName(), $oModifiedDocument->getId(), $parentId);
}
function DownloadDocument($oDocument, $oParentFolder) {
$content = new SubscriptionContent(); // needed for i18n
// OK: two actions: document registrants, folder registrants.
$aDocUsers = $this->_getSubscribers($oDocument->getId(), $this->subscriptionTypes["Document"]);
$aFolderUsers = $this->_getSubscribers($oParentFolder->getId(), $this->subscriptionTypes["Folder"]);
$aUsers = array_merge($aDocUsers, $aFolderUsers);
$parentId = $oParentFolder->getId();
$this->sendNotification($aUsers, 'DownloadDocument', $oDocument->getName(), $oDocument->getId(), $parentId);
}
function sendNotification($aUsers, $eventType, $targetName, $objectId, $parentId) {
$content = new SubscriptionContent(); // needed for i18n
//$aUsers = $this->_getSubscribers($oDocument->getId(), $this->subscriptionTypes["Document"]);
$locationName = Folder::generateFullFolderPath($parentId);
$userId = $_SESSION['userID'];
foreach ($aUsers as $oSubscriber) {
$emailAddress = $oSubscriber->getEmail();
if ($oSubscriber->getEmailNotification() && !empty($emailAddress)) {
// notification object first.
$aNotificationOptions = array();
$aNotificationOptions['target_user'] = $oSubscriber->getID();
$aNotificationOptions['actor_id'] = $userId;
$aNotificationOptions['target_name'] = $targetName;
$aNotificationOptions['location_name'] = $locationName;
$aNotificationOptions['object_id'] = $objectId;
$aNotificationOptions['event_type'] = $eventType;
$oNotification =& KTSubscriptionNotification::generateSubscriptionNotification($aNotificationOptions);
// now the email content.
$emailContent = $content->getEmailAlertContent($oNotification);
$emailSubject = $content->getEmailAlertSubject($oNotification);
$oEmail = new EmailAlert($emailAddress, $emailSubject, $emailContent);
$oEmail->send();
}
}
}
// small helper function to assist in identifying the numeric id.
function _getKeyForType($sEventType) {
foreach ($this->eventTypes as $key => $val) {
if ($val == $sSubType) { return $key; }
}
return -1;
}
// helper function to get & adjust the $alertedUsers
// note that this has side-effects: $this->alertedUsers is a merged version
// after this has been called.
function _pruneAlertedUsers($aUserIds) {
$returnArray = array_diff($aUserIds, $this->alertedUsers);
$this->alertedUsers = kt_array_merge($returnArray, $this->alertedUsers); // now contains all users who will have been alerted.
return $returnArray;
}
// gets subscribers to object, with appropriate type (e.g. folder or document).
// need the second part because docs and folders have separate ids.
// based on the old SubscriptionEngine::retrieveSubscribers.
function _getSubscribers($iObjectId, $iSubType) {
global $default; // for the logging.
if (KTLOG_CACHE) $default->log->debug("_getSubscribers(id=$iObjectId, type=$iSubType); table=" .Subscription::getTableName($iSubType). "; id=" .Subscription::getIdFieldName($iSubType));
$aUsers = array();
$aNewUsers = array();
$aSubUsers = array();
$table = Subscription::getTableName($iSubType);
$field = Subscription::getIdFieldName($iSubType);
// If we're dealing with a folder then get those user who are subscribed to one of the parent folders and want notifications on sub folders
if($iSubType == $this->subscriptionTypes["Folder"] && $iObjectId != 1){
// Get parent folder ids
$query= "SELECT parent_folder_ids FROM folders WHERE id = {$iObjectId}";
$aParentIds = DBUtil::getResultArrayKey($query, 'parent_folder_ids');
$parentIds = $aParentIds[0];
// Get those users who have checked the subfolders option on the above folders
$query = "SELECT user_id FROM {$table} WHERE {$field} IN ({$parentIds}) AND with_subfolders = 1";
$aSubUsers = DBUtil::getResultArrayKey($query, 'user_id');
}
$sQuery = "SELECT user_id FROM {$table} WHERE {$field} = ?";
$aParams = array($iObjectId);
$aNewUsers = DBUtil::getResultArrayKey(array($sQuery, $aParams), 'user_id');
// Add any users from parent folders
$aNewUsers = array_merge($aNewUsers, $aSubUsers);
$aNewUsers = array_unique($aNewUsers);
// Remove alerted users
$aNewUsers = $this->_pruneAlertedUsers($aNewUsers);
$iCurrentUserId = $_SESSION['userID'];
// notionally less efficient than the old code. if its a big issue, can easily
// be refactored.
foreach ($aNewUsers as $iUserId) {
// the user doesn't need to be notified for his/her own modifications
if($iUserId == $iCurrentUserId){
continue;
}
$oUser = & User::get($iUserId);
// do a quick prune here, for performance/maintenance reasons.
if (PEAR::isError($oUser) || ($oUser == false)) {
$sQuery = "DELETE FROM " . Subscription::getTableName($iSubType) . " WHERE user_id = ?";
$aParams = array($iUserId);
DBUtil::runQuery(array($sQuery, $sParams));
$default->log->error("SubscriptionEvent::fireSubscription error removing subscription for user id=$iUserId");
} else {
$aUsers[] = $oUser;
}
}
if (KTLOG_CACHE) $default->log->debug('retrieveSubscribers found count=' . count($aUsers));
return $aUsers;
}
}
// interesting: how do we want to generate email & notification content?
// first suggestion:
// - generate this content here.
// - alternatively, generate the content inside the notification environment (for part 2).
/* very simple class to handle and hold the various and sundry event types content for emails. */
class SubscriptionContent {
// have to be instantiated, or the i18n can't work.
function SubscriptionContent() {
$this->_eventTypeNames = array(
"AddFolder" => _kt('Folder added'),
"RemoveSubscribedFolder" => _kt('Folder removed'), // nothing. your subscription is now gone.
"RemoveChildFolder" => _kt('Folder removed'),
"AddDocument" => _kt('Document added'),
"RemoveSubscribedDocument" => _kt('Document removed'), // nothing. your subscription is now gone.
"RemoveChildDocument" => _kt('Document removed'),
"ModifyDocument" => _kt('Document modified'),
"CheckInDocument" => _kt('Document checked in'),
"CheckOutDocument" => _kt('Document checked out'),
"MovedDocument" => _kt('Document moved'),
"CopiedDocument" => _kt('Document copied'),
"ArchivedDocument" => _kt('Document archived'), // can go through and request un-archival (?)
"DownloadDocument" => _kt('Document downloaded'),
"RestoredArchivedDocument" => _kt('Document restored'),
"DiscussDocument" => _kt('Document Discussions updated'),
);
}
function getEmailAlertContent($oKTNotification) {
// we can re-use the normal template.
// however, we need to wrap it - no need for a second template here.
$str = '<html><body>' . $this->getNotificationAlertContent($oKTNotification) . '</body></html>';
return $str;
}
function getEmailAlertSubject($oKTNotification) {
$info = $this->_getSubscriptionData($oKTNotification);
return $info["title"];
}
function getNotificationAlertContent($oKTNotification) {
$info = $this->_getSubscriptionData($oKTNotification);
$oTemplating =& KTTemplating::getSingleton();
$oTemplate = $oTemplating->loadTemplate("kt3/notifications/subscriptions." . $info['event_type']);
// if, for some reason, this doesn't actually work, use the "generic" title.
if (PEAR::isError($oTemplate)) {
$oTemplate = $oTemplating->loadTemplate("kt3/notifications/subscriptions.generic");
}
// FIXME we need to specify the i18n by user.
$isBroken = false;
if (PEAR::isError($info['object']) || ($info['object'] === false) || is_null($info['object'])) {
$isBroken = true;
}
$aTemplateData = array("context" => $oKTNotification,
"info" => $info,
"is_broken" => $isBroken,
);
return $oTemplate->render($aTemplateData);
}
// no separate subject function, its rolled into get...Content()
var $_eventObjectMap = array(
"AddFolder" => 'folder',
"RemoveSubscribedFolder" => '', // nothing. your subscription is now gone.
"RemoveChildFolder" => 'folder',
"AddDocument" => 'document',
"RemoveSubscribedDocument" => '', // nothing. your subscription is now gone.
"RemoveChildDocument" => 'folder',
"ModifyDocument" => 'document',
"CheckInDocument" => 'document',
"CheckOutDocument" => 'document',
"MovedDocument" => 'document',
"CopiedDocument" => 'document',
"ArchivedDocument" => 'document', // can go through and request un-archival (?)
"DownloadDocument" => 'document',
"RestoredArchivedDocument" => 'document',
"DiscussDocument" => 'document');
function _getSubscriptionData($oKTNotification) {
$info = array(
'object_name' => $oKTNotification->getLabel(),
'event_type' => $oKTNotification->getStrData1(),
'location_name' => $oKTNotification->getStrData2(),
'object_id' => $oKTNotification->getIntData1(),
'actor_id' => $oKTNotification->getIntData2(),
'has_actor' => false,
'notify_id' => $oKTNotification->getId(),
);
$info['title'] = KTUtil::arrayGet($this->_eventTypeNames, $info['event_type'], 'Subscription alert:') .': ' . $info['object_name'];
if ($info['actor_id'] !== null) {
$oTempUser = User::get($info['actor_id']);
if (PEAR::isError($oTempUser) || ($oTempUser == false)) {
// no-act
$info['actor'] = null;
} else {
$info['actor'] = $oTempUser;
$info['has_actor'] = true;
$sName = $oTempUser->getName();
$iUnitId = $oTempUser->getUnitId();
if($iUnitId !== false) {
$oUnit = Unit::get($iUnitId);
if(!PEAR::isError($oUnit)) {
$sName .= sprintf(" (%s)", $oUnit->getName());
}
}
$info['actor_name'] = $sName;
}
}
if ($info['object_id'] !== null) {
$info['object'] = $this->_getEventObject($info['event_type'], $info['object_id']);
}
return $info;
}
// resolve the object type based on the alert type.
function _getEventObject($sAlertType, $id) {
$t = KTUtil::arrayGet($this->_eventObjectMap, $sAlertType ,'');
if ($t == 'document') {
$o = Document::get($id);
if (PEAR::isError($o) || ($o == false)) { return null;
} else { return $o; }
} else if ($t == 'folder') {
$o = Folder::get($id);
if (PEAR::isError($o) || ($o == false)) { return null;
} else { return $o; }
} else {
return null;
}
}
function _getEventObjectType($sAlertType) {
return KTUtil::arrayGet($this->_eventObjectMap, $sAlertType ,'');
}
}
?>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -