workflowutil.inc.php
来自「PHP 知识管理系统(基于树结构的知识管理系统), 英文原版的PHP源码。」· PHP 代码 · 共 886 行 · 第 1/3 页
PHP
886 行
// create the document transaction record
$sTransactionComments = sprintf(_kt("Workflow state changed from %s to %s"), $sSourceState, $sTargetState);
if ($sComments) {
$sTransactionComments .= _kt("; Reason given was: ") . $sComments;
}
$oDocumentTransaction = new DocumentTransaction($oDocument, $sTransactionComments, 'ktcore.transactions.workflow_state_transition');
$oDocumentTransaction->create();
// walk the action triggers.
foreach ($aActionTriggers as $oTrigger) {
$res = $oTrigger->performTransition($oDocument, $oUser);
if (PEAR::isError($res)) {
return $res;
}
}
KTPermissionUtil::updatePermissionLookup($oDocument);
KTWorkflowUtil::informUsersForState($oTargetState, KTWorkflowUtil::getInformedForState($oTargetState), $oDocument, $oUser, $sComments);
return true;
}
// }}}
// {{{ informUsersForState
function informUsersForState($oState, $aInformed, $oDocument, $oUser, $sComments) {
// say no to duplicates.
KTWorkflowNotification::clearNotificationsForDocument($oDocument);
$aUsers = array();
$aGroups = array();
$aRoles = array();
foreach (KTUtil::arrayGet($aInformed,'user',array()) as $iUserId) {
$oU = User::get($iUserId);
if (PEAR::isError($oU) || ($oU == false)) {
continue;
} else {
$aUsers[$oU->getId()] = $oU;
}
}
foreach (KTUtil::arrayGet($aInformed,'group',array()) as $iGroupId) {
$oG = Group::get($iGroupId);
if (PEAR::isError($oG) || ($oG == false)) {
continue;
} else {
$aGroups[$oG->getId()] = $oG;
}
}
foreach (KTUtil::arrayGet($aInformed,'role',array()) as $iRoleId) {
$oR = Role::get($iRoleId);
if (PEAR::isError($oR) || ($oR == false)) {
continue;
} else {
$aRoles[] = $oR;
}
}
// FIXME extract this into a util - I see us using this again and again.
// start with roles ... roles _only_ ever contain groups.
foreach ($aRoles as $oRole) {
// do NOT alert anonymous or Everyone roles - that would be very scary.
$iRoleId = KTUtil::getId($oRole);
if (($iRoleId == -3) || ($iRoleId == -4)) {
continue;
}
// first try on the document, then the folder above it.
$oRoleAllocation = DocumentRoleAllocation::getAllocationsForDocumentAndRole($oDocument->getId(), $iRoleId);
if (is_null($oRoleAllocation)) {
// if we don't get a document role, try folder role.
$oRoleAllocation = RoleAllocation::getAllocationsForFolderAndRole($oDocument->getFolderID(), $oRole->getId());
}
if (is_null($oRoleAllocation) || PEAR::isError($oRoleAllocation)) {
continue;
}
$aRoleUsers = $oRoleAllocation->getUsers();
$aRoleGroups = $oRoleAllocation->getGroups();
foreach ($aRoleUsers as $id => $oU) {
$aUsers[$id] = $oU;
}
foreach ($aRoleGroups as $id => $oGroup) {
$aGroups[$id] = $oGroup;
}
}
// we now have a (potentially overlapping) set of groups, which may
// have subgroups.
//
// what we need to do _now_ is build a canonical set of groups, and then
// generate the singular user-base.
$aGroupMembershipSet = GroupUtil::buildGroupArray();
$aAllIds = array_keys($aGroups);
foreach ($aGroups as $id => $oGroup) {
$aAllIds = kt_array_merge($aGroupMembershipSet[$id], $aAllIds);
}
foreach ($aAllIds as $id) {
if (!array_key_exists($id, $aGroups)) {
$aGroups[$id] = Group::get($id);
}
}
// now, merge this (again) into the user-set.
foreach ($aGroups as $oGroup) {
$aNewUsers = $oGroup->getMembers();
foreach ($aNewUsers as $oU) {
$id = $oU->getId();
if (!array_key_exists($id, $aUsers)) {
$aUsers[$id] = $oU;
}
}
}
// and done.
foreach ($aUsers as $oU) {
if (!PEAR::isError($oU)) {
KTWorkflowNotification::newNotificationForDocument($oDocument, $oU, $oState, $oUser, $sComments);
}
}
}
// }}}
// {{{ setInformedForState
/**
* Sets which users/groups/roles are to be informed when a state is
* arrived at.
*/
function setInformedForState(&$oState, $aInformed) {
$oDescriptor =& KTPermissionUtil::getOrCreateDescriptor($aInformed);
if (PEAR::isError($oDescriptor)) {
return $oDescriptor;
}
$iOldDescriptorId = $oState->getInformDescriptorId();
$oState->setInformDescriptorId($oDescriptor->getId());
$res = $oState->update();
if (PEAR::isError($res)) {
$oState->setInformDescriptorId($iOldDescriptorId);
return $res;
}
return $res;
}
// }}}
// {{{ getInformedForState
/**
* Gets which users/groups/roles are to be informed when a state is
* arrived at.
*/
function getInformedForState($oState) {
$iDescriptorId = $oState->getInformDescriptorId();
if (empty($iDescriptorId)) {
return array();
}
return KTPermissionUtil::getAllowedForDescriptor($iDescriptorId);
}
// }}}
// retrieves the triggers for a given transition in their WorkflowTrigger form.
function getTriggersForTransition($oTransition) {
$oKTWorkflowTriggerRegistry =& KTWorkflowTriggerRegistry::getSingleton();
$aTriggers = array();
$aTriggerInstances = KTWorkflowTriggerInstance::getByTransition($oTransition);
foreach ($aTriggerInstances as $oTriggerInstance) {
$oTrigger = $oKTWorkflowTriggerRegistry->getWorkflowTrigger($oTriggerInstance->getNamespace());
if (PEAR::isError($oTrigger)) {
return $oTrigger;
}
$oTrigger->loadConfig($oTriggerInstance);
$aTriggers[] = $oTrigger;
}
return $aTriggers;
}
function getGuardTriggersForTransition($oTransition) {
$aTriggers = KTWorkflowUtil::getTriggersForTransition($oTransition);
if (PEAR::isError($aTriggers)) {
return $aTriggers;
}
$aGuards = array();
foreach ($aTriggers as $oTrigger) {
$aInfo = $oTrigger->getInfo();
if ($aInfo['guard']) {
$aGuards[] = $oTrigger;
}
}
return $aGuards;
}
function getActionTriggersForTransition($oTransition) {
$aTriggers = KTWorkflowUtil::getTriggersForTransition($oTransition);
if (PEAR::isError($aTriggers)) {
return $aTriggers;
}
$aGuards = array();
foreach ($aTriggers as $oTrigger) {
$aInfo = $oTrigger->getInfo();
if ($aInfo['action']) {
$aGuards[] = $oTrigger;
}
}
return $aGuards;
}
function replaceState($oState, $oReplacement) {
$state_id = KTUtil::getId($oState);
$replacement_id = KTUtil::getId($oReplacement);
// we need to convert:
// - documents
// - transitions
// before we do a delete.
$doc = KTUtil::getTableName('document_metadata_version');
$aDocQuery = array(
"UPDATE $doc SET workflow_state_id = ? WHERE workflow_state_id = ?",
array($replacement_id, $state_id),
);
$res = DBUtil::runQuery($aDocQuery);
if (PEAR::isError($res)) { return $res; }
$wf = KTUtil::getTableName('workflow_transitions');
$aTransitionQuery = array(
"UPDATE $wf SET target_state_id = ? WHERE target_state_id = ?",
array($replacement_id, $state_id),
);
$res = DBUtil::runQuery($aTransitionQuery);
if (PEAR::isError($res)) { return $res; }
$wf = KTUtil::getTableName('workflow_state_transitions');
$aTransitionQuery = array(
"DELETE FROM $wf WHERE state_id = ?",
array($state_id),
);
$res = DBUtil::runQuery($aTransitionQuery);
if (PEAR::isError($res)) { return $res; }
Document::clearAllCaches();
}
}
class KTWorkflowTriggerRegistry {
var $triggers;
function KTWorkflowTriggerRegistry() {
$this->triggers = array();
}
static function &getSingleton () {
if (!KTUtil::arrayGet($GLOBALS['_KT_PLUGIN'], 'oKTWorkflowTriggerRegistry')) {
$GLOBALS['_KT_PLUGIN']['oKTWorkflowTriggerRegistry'] = new KTWorkflowTriggerRegistry;
}
return $GLOBALS['_KT_PLUGIN']['oKTWorkflowTriggerRegistry'];
}
function registerWorkflowTrigger($sNamespace, $sClassname, $sPath) {
$this->triggers[$sNamespace] = array('class' => $sClassname, 'path' => $sPath);
}
function getWorkflowTrigger($sNamespace) {
$aInfo = KTUtil::arrayGet($this->triggers, $sNamespace, null);
if (is_null($aInfo)) {
return PEAR::raiseError(sprintf(_kt("Unable to find workflow trigger: %s"), $sNamespace));
}
require_once($aInfo['path']);
return new $aInfo['class'];
}
// get a keyed list of workflow triggers
function listWorkflowTriggers() {
$triggerlist = array();
foreach ($this->triggers as $sNamespace => $aTrigInfo) {
$oTriggerObj = $this->getWorkflowTrigger($sNamespace);
$triggerlist[$sNamespace] = $oTriggerObj->getInfo();
}
// FIXME do we want to order this alphabetically?
return $triggerlist;
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?