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 + -
显示快捷键?