diff --git a/lib/actions/bulkaction.php b/lib/actions/bulkaction.php index 7487d51..0edcdf5 100644 --- a/lib/actions/bulkaction.php +++ b/lib/actions/bulkaction.php @@ -1,677 +1,729 @@ -. - * - * You can contact KnowledgeTree Inc., PO Box 7775 #87847, San Francisco, - * California 94120-7775, or email info@knowledgetree.com. - * - * The interactive user interfaces in modified source and object code versions - * of this program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU General Public License version 3. - * - * In accordance with Section 7(b) of the GNU General Public License version 3, - * these Appropriate Legal Notices must retain the display of the "Powered by - * KnowledgeTree" logo and retain the original copyright notice. If the display of the - * logo is not reasonably feasible for technical reasons, the Appropriate Legal Notices - * must display the words "Powered by KnowledgeTree" and retain the original - * copyright notice. - * Contributor( s): ______________________________________ - * - */ - -require_once(KT_LIB_DIR . '/actions/actionregistry.inc.php'); -require_once(KT_LIB_DIR . '/workflow/workflowutil.inc.php'); -require_once(KT_LIB_DIR . '/dispatcher.inc.php'); -require_once(KT_LIB_DIR . '/browse/browseutil.inc.php'); -require_once(KT_LIB_DIR . '/actions/entitylist.php'); - -require_once(KT_LIB_DIR . '/foldermanagement/folderutil.inc.php'); -require_once(KT_LIB_DIR . '/documentmanagement/documentutil.inc.php'); - -require_once(KT_LIB_DIR . '/widgets/forms.inc.php'); - -require_once(KT_LIB_DIR . "/util/sanitize.inc"); - -class KTBulkAction extends KTStandardDispatcher { - var $sName; - var $sDescription; - - var $_sDisablePermission; - var $bAllowInAdminMode = false; - var $sHelpPage = 'ktcore/browse.html'; - - var $sSection = 'view_details'; - - var $_bMutator = false; - var $_bMutationAllowedByAdmin = true; - - var $sIconClass; - - // not 'sShowPermission' - mass actions are always shown - // this is used to check against individual entities - var $_sPermission = 'ktcore.permissions.read'; - - function KTBulkAction($oUser = null, $oPlugin = null) { - $this->oEntityList = null; - $this->oActiveEntityList = null; - $this->oUser =& $oUser; - $this->oPlugin =& $oPlugin; - - $this->aBreadcrumbs = array( - array('action' => 'browse', 'name' => _kt('Browse')), - ); - - $this->persistParams('fEntityListCode'); - parent::KTStandardDispatcher(); - } - - function setEntityList(&$oEntityList) { - $this->oEntityList =& $oEntityList; - } - - function setUser(&$oUser) { - $this->oUser =& $oUser; - } - - function _show() { - return true; - } - - function getURL() { - $oKTConfig =& KTConfig::getSingleton(); - $sExt = '.php'; - if (KTUtil::arrayGet($_SERVER, 'kt_no_extensions')) { - $sExt = ''; - } - if ($oKTConfig->get('KnowledgeTree/pathInfoSupport')) { - return sprintf('%s/action%s/%s', $GLOBALS['KTRootUrl'], $sExt, $this->sName); - } else { - return sprintf('%s/action%s?kt_path_info=%s', $GLOBALS['KTRootUrl'], $sExt, $this->sName); - } - } - - function getInfo() { - if ($this->_show() === false) { - return null; - } - - $url = $this->getURL(); - - $aInfo = array( - 'description' => $this->sDescription, - 'name' => $this->getDisplayName(), - 'ns' => $this->sName, - 'url' => $url, - 'icon_class' => $this->sIconClass, - ); - - $aInfo = $this->customiseInfo($aInfo); - return $aInfo; - } - - function getName() { - return sanitizeForSQLtoHTML($this->sName); - } - - function getDisplayName() { - return sanitizeForSQLtoHTML($this->sDisplayName); - } - - function getDescription() { - return sanitizeForSQLtoHTML($this->sDescription); - } - - function customiseInfo($aInfo) { - return $aInfo; - } - - // helper function - function _getNames($aIds, $sEntity) { - if(count($aIds)) { - $aNames = array(); - $aFunc = array($sEntity, 'get'); - - foreach($aIds as $id) { - $oE =& call_user_func($aFunc, $id); - $name = array(); - $name['name'] = $oE->getName(); - //add shortcut notice if the entity is a shortcut - if($oE->isSymbolicLink()){ - $name['notice'] = _kt("Shortcut"); - } - $aNames[] = $name; - } - return $aNames; - } else { - return array(); - } - } - - /** - * Checks if there are symlinks that are linking to items in the current list - * Useful if you want to prompt the user with a confirmation because they're - * automatically deleted when their targets are deleted or archived. - * - * @return boolean - */ - function symlinksLinkingToCurrentList(){ - $symlinksPresent = false; - foreach($this->oActiveEntityList->getDocumentIds() as $iDocument){ - $oDocument = Document::get($iDocument); - if(count($oDocument->getSymbolicLinks()) > 0){ - $symlinksPresent = true; - break; - } - } - if($symlinksPresent == false){ - foreach($this->oActiveEntityList->getFolderIds() as $iFolder){ - $oStartFolder = Folder::get($iFolder); - $aRemainingFolders = array($oStartFolder->getId()); - while (!empty($aRemainingFolders)) { - $iFolderId = array_pop($aRemainingFolders); - $oFolder = Folder::get($iFolderId); - - if(count($oFolder->getSymbolicLinks()) > 0){ - $symlinksPresent = true; - break; - } - - $aChildDocs = Document::getList(array('folder_id = ?',array($iFolderId))); - foreach ($aChildDocs as $oDoc) { - if(count($oDoc->getSymbolicLinks()) > 0){ - $symlinksPresent = true; - break; - } - } - - $aCFIds = Folder::getList(array('parent_id = ?', array($iFolderId)), array('ids' => true)); - $aRemainingFolders = kt_array_merge($aRemainingFolders, $aCFIds); - } - } - } - return $symlinksPresent; - } - -/** - * checks a folderList for shortcuts and queries the repositories for all folders - * that are somehow connected to these folders. - */ - function getLinkingEntities($aFolderList){ - $aSearchFolders = array(); - if(!empty($aFolderList)){ - foreach($aFolderList as $oFolderItem){ - if(Permission::userHasFolderReadPermission($oFolderItem)){ - // If it is a shortcut, we should do some more searching - if($oFolderItem->isSymbolicLink()){ - $oFolderItem = $oFolderItem->getLinkedFolder(); - $aSearchFolders[] = $oFolderItem->getID(); - } - } - } - } - $aLinkingFolders = array(); - $aSearchCompletedFolders = array(); - $count = 0; - while(count($aSearchFolders)>0){ - $count++; - $oFolder = Folder::get(array_pop($aSearchFolders)); - $sFolderId = $oFolder->getId(); - // Get all the folders within the current folder - $sWhereClause = "parent_folder_ids = '{$sFolderId}' OR - parent_folder_ids LIKE '{$sFolderId},%' OR - parent_folder_ids LIKE '%,{$sFolderId},%' OR - parent_folder_ids LIKE '%,{$sFolderId}'"; - $aFolderList = $this->oFolder->getList($sWhereClause); - foreach($aFolderList as $oFolderItem){ - if($oFolderItem->isSymbolicLink()){ - $oFolderItem = $oFolderItem->getLinkedFolder(); - } - if(Permission::userHasFolderReadPermission($oFolderItem)){ - if($aSearchCompletedFolders[$oFolderItem->getID()] != true){ - $aSearchFolders[] = $oFolderItem->getID(); - $aSearchCompletedFolders[$oFolderItem->getID()] = true; - } - } - } - if(!isset($aLinkingFolders[$oFolder->getId()])){ - $aLinkingFolders[$oFolder->getId()] = $oFolder; - } - } - return $aLinkingFolders; - } - - // doesn't actually do checks, as they have to be performed per-entity - function check() { - // not necessarily coming from a folder... - $iFolderId = KTUtil::arrayGet($_REQUEST, 'fFolderId', 1); - $this->oFolder = Folder::get($iFolderId); - //$this->oFolder =& $this->oValidator->validateFolder($_REQUEST['fFolderId']); - - $aOptions = array( - 'final' => false, - 'documentaction' => 'viewDocument', - 'folderaction' => 'browse', - ); - - $this->aBreadcrumbs = array(array('name'=>_kt('Bulk Actions')), - array('name'=>$this->getDisplayName())); - - return true; - } - - - // check the entire entity list. this needn't be overrided at any point - function check_entities() { - $aFailed = array('documents' => array(), 'folders' => array()); - $aSucceeded = array('documents' => array(), 'folders' => array()); - - if(!$this->oEntityList) { - return true; - } - - foreach($this->oEntityList->getDocumentIds() as $iId) { - $oDocument =& Document::get($iId); - - if(PEAR::isError($oDocument)) { - $aFailed['documents'][] = array($iId, _kt('No such document')); - } else { - $res = $this->check_entity($oDocument); - - // all these checks allow a return from check_entity of: - // 1. a PEAR error, indicating failure, with the message in the error - // 2. false, for unknown error - // 3. true, to pass - - if(PEAR::isError($res)) { - $aFailed['documents'][] = array($oDocument->getName(), $res->getMessage()); - } else if($res === false) { - $aFailed['documents'][] = array($oDocument->getName(), _kt('Failed (unknown reason)')); - } else { - $aSucceeded['documents'][] = $oDocument->getId(); - } - } - } - - foreach($this->oEntityList->getFolderIds() as $iId) { - $oFolder =& Folder::get($iId); - - if(PEAR::isError($oFolder)) { - $aFailed['folders'][] = array($iId, _kt('No such folder')); - } else { - $res = $this->check_entity($oFolder); - - if(PEAR::isError($res)) { - $aFailed['folders'][] = array($oFolder->getName(), $res->getMessage()); - } else if($res === false) { - $aFailed['folders'][] = array($oFolder->getName(), _kt('Failed (unknown reason)')); - } else { - $aSucceeded['folders'][] = $oFolder->getId(); - } - } - } - $this->oActiveEntityList = new KTEntityList($aSucceeded['documents'], $aSucceeded['folders']); - $this->aFailed = $aFailed; - - return count($aSucceeded['documents']) + count($aSucceeded['folders']); - } - - - // iterate over all entites to act on them - function perform_action_on_list() { - $this->aActionResults = array('folders'=>array(), 'documents'=>array()); - - foreach($this->oActiveEntityList->getDocumentIds() as $iId) { - $oDocument =& Document::get($iId); - if(!PEAR::isError($oDocument)) { - $sName = $oDocument->getName(); - } else { - $sName = _kt('Error fetching document name'); - } - - $res = $this->perform_action($oDocument); - - //check for shortcut notice - $notice = null; - if($oDocument->isSymbolicLink()){ - $notice = _kt("Shortcut"); - } - - if(PEAR::isError($res)) { - $this->aActionResults['documents'][] = array($sName, $res->getMessage(), $notice); - } else { - $this->aActionResults['documents'][] = array($sName, _kt('Success'), $notice); - } - } - - foreach($this->oActiveEntityList->getFolderIds() as $iId) { - $oFolder =& Folder::get($iId); - if(!PEAR::isError($oFolder)) { - $sName = $oFolder->getName(); - } else { - $sName = _kt('Error fetching folder name'); - } - - $res = $this->perform_action($oFolder); - - //check for shortcut notice - $notice = null; - if($oFolder->isSymbolicLink()){ - $notice = _kt("Shortcut"); - } - - if(PEAR::isError($res)) { - $this->aActionResults['folders'][] = array($sName, $res->getMessage(), $notice); - } else { - $this->aActionResults['folders'][] = array($sName, _kt('Success'), $notice); - } - } - } - - - - // list persistance - // fetch existing lists - function get_lists() { - $this->oEntityList = KTEntityList::retrieveList(KTUtil::arrayGet($_REQUEST, 'fListCode', null)); - $this->oActiveEntityList = KTEntityList::retrieveList(KTUtil::arrayGet($_REQUEST, 'fActiveListCode', null)); - if(PEAR::isError($this->oActiveEntityList)) { - $this->oActiveEntityList = null; - } - } - - // persist - function store_lists() { - $this->persistParams(array('fListCode', 'fActiveListCode', 'fFolderId', 'fReturnData', 'fReturnAction')); - } - - /** - * Get the return url based on the return action and data - */ - function getReturnUrl() - { - $sReturnAction = $_REQUEST['fReturnAction']; - $sReturnData = $_REQUEST['fReturnData']; - $sAction = 'main'; - $qs = ''; - - switch ($sReturnAction){ - case 'browse': - $sReturnData = (empty($sReturnData)) ? $_REQUEST['fFolderId'] : $sReturnData; - $sTargetUrl = KTBrowseUtil::getUrlForFolder(Folder::get($sReturnData)); - break; - case 'simpleSearch': - $sTargetUrl = KTBrowseUtil::getSimpleSearchBaseUrl(); - $extra = 'fSearchableText='.$sReturnData; - break; - case 'booleanSearch': - $sTargetUrl = KTBrowseUtil::getBooleanSearchBaseUrl(); - $sAction = 'performSearch'; - $extra = 'boolean_search_id='.$sReturnData; - break; - case 'search2': - $sTargetUrl = KTBrowseUtil::getSearchResultURL(); - $sAction = 'searchResults'; - break; - default: - $sTargetUrl = $sReturnAction; - $sAction = ''; - } - - $qs = (!empty($sAction))? 'action='.$sAction : ''; - $qs .= (!empty($extra))? '&'.$extra : ''; - $sTargetUrl = KTUtil::addQueryString($sTargetUrl, $qs); - - return $sTargetUrl; - } - - // forms - // form to list the entites after checking each one - function form_listing() { - $sListCode = $this->oEntityList->getCode(); - $sActiveListCode = $this->oActiveEntityList->getCode(); - - $sTargetUrl = $this->getReturnUrl(); - - $oForm = new KTForm; - $oForm->setOptions(array( - 'identifier' => 'ktcore.actions.bulk.listing.form', - 'submit_label' => _kt('Continue'), - 'targeturl' => $this->getURL(), - 'action' => 'collectinfo', - 'fail_action' => 'main', - 'cancel_url' => $sTargetUrl, - 'noframe' => true, - 'extraargs' => array('fListCode' => $sListCode, - 'fActiveListCode' => $sActiveListCode, - 'fFolderId' => $this->oFolder->getId(), - 'fReturnAction' => KTUtil::arrayGet($_REQUEST, 'fReturnAction'), - 'fReturnData' => KTUtil::arrayGet($_REQUEST, 'fReturnData'), - ), - 'context' => $this, - )); - return $oForm; - } - - // form to show on action completion, and list results - function form_complete() { - $sReturnAction = KTUtil::arrayGet($_REQUEST, 'fReturnAction'); - $sReturnData = KTUtil::arrayGet($_REQUEST, 'fReturnData'); - $sAction = 'main'; - - switch ($sReturnAction){ - case 'browse': - $sReturnData = (empty($sReturnData)) ? $_REQUEST['fFolderId'] : $sReturnData; - $sTargetUrl = KTBrowseUtil::getUrlForFolder(Folder::get($sReturnData)); - break; - case 'simpleSearch': // do we use this? - $sTargetUrl = KTBrowseUtil::getSimpleSearchBaseUrl(); - $extraargs = array('fSearchableText'=>$sReturnData); - break; - case 'booleanSearch': // do we use this? - $sTargetUrl = KTBrowseUtil::getBooleanSearchBaseUrl(); - $sAction = 'performSearch'; - $extraargs = array('boolean_search_id'=>$sReturnData); - break; - case 'search2': - $sTargetUrl = KTBrowseUtil::getSearchResultURL(); - $sAction = 'refresh'; - break; - default: - $sTargetUrl = $sReturnAction; - $sAction = ''; - } - - $oForm = new KTForm; - $oForm->setOptions(array( - 'identifier' => 'ktcore.actions.bulk.complete.form', - 'submit_label' => _kt('Return'), - 'targeturl' => $sTargetUrl, - 'context' => $this, - 'action' => $sAction, - 'extraargs' => $extraargs, - 'noframe' => true, - )); - return $oForm; - } - - - // main entry point - checks the entity list and displays lists - function do_main() { - // get entities (using the checkboxes atm) - $aFolders = KTUtil::arrayGet($_REQUEST, 'selection_f' , array()); - $aDocuments = KTUtil::arrayGet($_REQUEST, 'selection_d' , array()); - $this->oEntityList = new KTEntityList($aDocuments, $aFolders); - - // gives us $this->aFailed - $iActiveCount = $this->check_entities(); - - $oTemplating =& KTTemplating::getSingleton(); - $oTemplate = $oTemplating->loadTemplate('ktcore/bulk_action_listing'); - - $this->store_lists(); - - return $oTemplate->render(array('context' => $this, - 'form' => $this->form_listing(), - 'failed' => $this->aFailed, - 'active' => $this->oActiveEntityList, - 'activecount' => $iActiveCount, - 'failedform' => $this->form_complete(), - 'folders' => $this->_getNames($this->oActiveEntityList->getFolderIds(), 'Folder'), - 'documents' => $this->_getNames($this->oActiveEntityList->getDocumentIds(), 'Document'))); - - } - - // override to add a screen to get a reason, or whatever - // remember to pass to perform action next, and call the super's method - function do_collectinfo() { - $this->store_lists(); - return $this->do_performaction(); - } - - // perform the action itself, and list results (completion action) - function do_performaction() { - $this->get_lists(); - $this->aPersistParams = array(); - $this->perform_action_on_list(); - - $oTemplating =& KTTemplating::getSingleton(); - $oTemplate = $oTemplating->loadTemplate('ktcore/bulk_action_complete'); - return $oTemplate->render(array('context' => $this, - 'list' => $this->aActionResults, - 'form' => $this->form_complete())); - } - - - - - - - // main overrides - - // override to do the actual action, on an individual entity - function perform_action($oEntity) { - return PEAR::raiseError(_kt('Action component not implemented')); - } - - // check an individual entity - this should be overrided with additional - // checks required for the specific action, but should always call its - // parent implementation - function check_entity($oEntity) { - $oPermission =& KTPermission::getByName($this->_sPermission); - if(PEAR::isError($oPermission)) { - return true; - } - - // basic document checks - - // TODO: check if this is appropriate - // should probably store the 'equivalent' action (ie. document.delete) - // and check that, rather than add a new list of actions to the workflow - // section - if(is_a($oEntity, 'Document')) { - if(!KTWorkflowUtil::actionEnabledForDocument($oEntity, $this->sName)) { - return PEAR::raiseError(_kt('Action is disabled by workflow')); - } - $status = $oEntity->getStatusID(); - if($status==DELETED||$status==ARCHIVED) { - return PEAR::raiseError(_kt('Document is archived or deleted')); - } - } - - // admin check - if($this->bAllowInAdminMode) { - if(KTBrowseUtil::inAdminMode($this->oUser, null)) { - return true; - } - } - - if(!KTPermissionUtil::userHasPermissionOnItem($this->oUser, $oPermission, $oEntity)) { - return PEAR::raiseError(_kt('You do not have the required permissions')); - } - - return true; - } - - -} - -class KTBulkDocumentAction extends KTBulkAction { - function check_entity($oEntity) { - if(!is_a($oEntity, 'Document')) { - return false; - } - return parent::check_entity($oEntity); - } -} - -class KTBulkFolderAction extends KTBulkAction { - function check_entity($oEntity) { - if(!is_a($oEntity, 'Folder')) { - return false; - } - return parent::check_entity($oEntity); - } -} - - - -// util class for bulk actions - -class KTBulkActionUtil { - function getBulkActionInfo($slot = 'bulkaction') { - $oRegistry =& KTActionRegistry::getSingleton(); - return $oRegistry->getActions($slot); - } - - function getAllBulkActions($slot = 'bulkaction') { - $aObjects = array(); - - foreach (KTBulkActionUtil::getBulkActionInfo($slot) as $aAction) { - list($sClassName, $sPath, $sName, $sPlugin) = $aAction; - $oRegistry =& KTPluginRegistry::getSingleton(); - $oPlugin =& $oRegistry->getPlugin($sPlugin); - if (!empty($sPath)) { - require_once($sPath); - } - $aObjects[] = new $sClassName(null, null, $oPlugin); - } - return $aObjects; - } - - function getBulkActionsByNames($aNames, $slot = 'bulkaction', $oUser = null) { - $aObjects = array(); - foreach (KTBulkActionUtil::getBulkActionInfo($slot) as $aAction) { - list($sClassName, $sPath, $sName, $sPlugin) = $aAction; - $oRegistry =& KTPluginRegistry::getSingleton(); - $oPlugin =& $oRegistry->getPlugin($sPlugin); - if (!in_array($sName, $aNames)) { - continue; - } - if (!empty($sPath)) { - require_once($sPath); - } - $aObjects[] = new $sClassName(null, $oUser, $oPlugin); - } - return $aObjects; - } -} - -?> +. + * + * You can contact KnowledgeTree Inc., PO Box 7775 #87847, San Francisco, + * California 94120-7775, or email info@knowledgetree.com. + * + * The interactive user interfaces in modified source and object code versions + * of this program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU General Public License version 3. + * + * In accordance with Section 7(b) of the GNU General Public License version 3, + * these Appropriate Legal Notices must retain the display of the "Powered by + * KnowledgeTree" logo and retain the original copyright notice. If the display of the + * logo is not reasonably feasible for technical reasons, the Appropriate Legal Notices + * must display the words "Powered by KnowledgeTree" and retain the original + * copyright notice. + * Contributor( s): ______________________________________ + * + */ + +require_once(KT_LIB_DIR . '/actions/actionregistry.inc.php'); +require_once(KT_LIB_DIR . '/workflow/workflowutil.inc.php'); +require_once(KT_LIB_DIR . '/dispatcher.inc.php'); +require_once(KT_LIB_DIR . '/browse/browseutil.inc.php'); +require_once(KT_LIB_DIR . '/actions/entitylist.php'); + +require_once(KT_LIB_DIR . '/foldermanagement/folderutil.inc.php'); +require_once(KT_LIB_DIR . '/documentmanagement/documentutil.inc.php'); + +require_once(KT_LIB_DIR . '/widgets/forms.inc.php'); + +require_once(KT_LIB_DIR . "/util/sanitize.inc"); + +// // Jarrett Jordaan: Deal with bulk action +require_once(KT_LIB_DIR . '/subscriptions/subscriptions.inc.php'); + +class KTBulkAction extends KTStandardDispatcher { + var $sName; + var $sDescription; + + var $_sDisablePermission; + var $bAllowInAdminMode = false; + var $sHelpPage = 'ktcore/browse.html'; + + var $sSection = 'view_details'; + + var $_bMutator = false; + var $_bMutationAllowedByAdmin = true; + + var $sIconClass; + + // not 'sShowPermission' - mass actions are always shown + // this is used to check against individual entities + var $_sPermission = 'ktcore.permissions.read'; + + // Bulk Action Notification + var $uploadedDocs; + var $uploadedFolders; + var $eventAction; + + function KTBulkAction($oUser = null, $oPlugin = null) { + $this->oEntityList = null; + $this->oActiveEntityList = null; + $this->oUser =& $oUser; + $this->oPlugin =& $oPlugin; + // Bulk Action Notification + $this->uploadedDocs = array(); + $this->uploadedFolders = array(); + $this->eventAction = null; + $this->aBreadcrumbs = array( + array('action' => 'browse', 'name' => _kt('Browse')), + ); + + $this->persistParams('fEntityListCode'); + parent::KTStandardDispatcher(); + } + + function setEntityList(&$oEntityList) { + $this->oEntityList =& $oEntityList; + } + + function setUser(&$oUser) { + $this->oUser =& $oUser; + } + + function _show() { + return true; + } + + function getURL() { + $oKTConfig =& KTConfig::getSingleton(); + $sExt = '.php'; + if (KTUtil::arrayGet($_SERVER, 'kt_no_extensions')) { + $sExt = ''; + } + if ($oKTConfig->get('KnowledgeTree/pathInfoSupport')) { + return sprintf('%s/action%s/%s', $GLOBALS['KTRootUrl'], $sExt, $this->sName); + } else { + return sprintf('%s/action%s?kt_path_info=%s', $GLOBALS['KTRootUrl'], $sExt, $this->sName); + } + } + + function getInfo() { + if ($this->_show() === false) { + return null; + } + + $url = $this->getURL(); + + $aInfo = array( + 'description' => $this->sDescription, + 'name' => $this->getDisplayName(), + 'ns' => $this->sName, + 'url' => $url, + 'icon_class' => $this->sIconClass, + ); + + $aInfo = $this->customiseInfo($aInfo); + return $aInfo; + } + + function getName() { + return sanitizeForSQLtoHTML($this->sName); + } + + function getDisplayName() { + return sanitizeForSQLtoHTML($this->sDisplayName); + } + + function getDescription() { + return sanitizeForSQLtoHTML($this->sDescription); + } + + function customiseInfo($aInfo) { + return $aInfo; + } + + // helper function + function _getNames($aIds, $sEntity) { + if(count($aIds)) { + $aNames = array(); + $aFunc = array($sEntity, 'get'); + + foreach($aIds as $id) { + $oE =& call_user_func($aFunc, $id); + $name = array(); + $name['name'] = $oE->getName(); + //add shortcut notice if the entity is a shortcut + if($oE->isSymbolicLink()){ + $name['notice'] = _kt("Shortcut"); + } + $aNames[] = $name; + } + return $aNames; + } else { + return array(); + } + } + + /** + * Checks if there are symlinks that are linking to items in the current list + * Useful if you want to prompt the user with a confirmation because they're + * automatically deleted when their targets are deleted or archived. + * + * @return boolean + */ + function symlinksLinkingToCurrentList(){ + $symlinksPresent = false; + foreach($this->oActiveEntityList->getDocumentIds() as $iDocument){ + $oDocument = Document::get($iDocument); + if(count($oDocument->getSymbolicLinks()) > 0){ + $symlinksPresent = true; + break; + } + } + if($symlinksPresent == false){ + foreach($this->oActiveEntityList->getFolderIds() as $iFolder){ + $oStartFolder = Folder::get($iFolder); + $aRemainingFolders = array($oStartFolder->getId()); + while (!empty($aRemainingFolders)) { + $iFolderId = array_pop($aRemainingFolders); + $oFolder = Folder::get($iFolderId); + + if(count($oFolder->getSymbolicLinks()) > 0){ + $symlinksPresent = true; + break; + } + + $aChildDocs = Document::getList(array('folder_id = ?',array($iFolderId))); + foreach ($aChildDocs as $oDoc) { + if(count($oDoc->getSymbolicLinks()) > 0){ + $symlinksPresent = true; + break; + } + } + + $aCFIds = Folder::getList(array('parent_id = ?', array($iFolderId)), array('ids' => true)); + $aRemainingFolders = kt_array_merge($aRemainingFolders, $aCFIds); + } + } + } + return $symlinksPresent; + } + +/** + * checks a folderList for shortcuts and queries the repositories for all folders + * that are somehow connected to these folders. + */ + function getLinkingEntities($aFolderList){ + $aSearchFolders = array(); + if(!empty($aFolderList)){ + foreach($aFolderList as $oFolderItem){ + if(Permission::userHasFolderReadPermission($oFolderItem)){ + // If it is a shortcut, we should do some more searching + if($oFolderItem->isSymbolicLink()){ + $oFolderItem = $oFolderItem->getLinkedFolder(); + $aSearchFolders[] = $oFolderItem->getID(); + } + } + } + } + $aLinkingFolders = array(); + $aSearchCompletedFolders = array(); + $count = 0; + while(count($aSearchFolders)>0){ + $count++; + $oFolder = Folder::get(array_pop($aSearchFolders)); + $sFolderId = $oFolder->getId(); + // Get all the folders within the current folder + $sWhereClause = "parent_folder_ids = '{$sFolderId}' OR + parent_folder_ids LIKE '{$sFolderId},%' OR + parent_folder_ids LIKE '%,{$sFolderId},%' OR + parent_folder_ids LIKE '%,{$sFolderId}'"; + $aFolderList = $this->oFolder->getList($sWhereClause); + foreach($aFolderList as $oFolderItem){ + if($oFolderItem->isSymbolicLink()){ + $oFolderItem = $oFolderItem->getLinkedFolder(); + } + if(Permission::userHasFolderReadPermission($oFolderItem)){ + if($aSearchCompletedFolders[$oFolderItem->getID()] != true){ + $aSearchFolders[] = $oFolderItem->getID(); + $aSearchCompletedFolders[$oFolderItem->getID()] = true; + } + } + } + if(!isset($aLinkingFolders[$oFolder->getId()])){ + $aLinkingFolders[$oFolder->getId()] = $oFolder; + } + } + return $aLinkingFolders; + } + + // doesn't actually do checks, as they have to be performed per-entity + function check() { + // not necessarily coming from a folder... + $iFolderId = KTUtil::arrayGet($_REQUEST, 'fFolderId', 1); + $this->oFolder = Folder::get($iFolderId); + //$this->oFolder =& $this->oValidator->validateFolder($_REQUEST['fFolderId']); + + $aOptions = array( + 'final' => false, + 'documentaction' => 'viewDocument', + 'folderaction' => 'browse', + ); + + $this->aBreadcrumbs = array(array('name'=>_kt('Bulk Actions')), + array('name'=>$this->getDisplayName())); + + return true; + } + + + // check the entire entity list. this needn't be overrided at any point + function check_entities() { + $aFailed = array('documents' => array(), 'folders' => array()); + $aSucceeded = array('documents' => array(), 'folders' => array()); + + if(!$this->oEntityList) { + return true; + } + + foreach($this->oEntityList->getDocumentIds() as $iId) { + $oDocument =& Document::get($iId); + + if(PEAR::isError($oDocument)) { + $aFailed['documents'][] = array($iId, _kt('No such document')); + } else { + $res = $this->check_entity($oDocument); + + // all these checks allow a return from check_entity of: + // 1. a PEAR error, indicating failure, with the message in the error + // 2. false, for unknown error + // 3. true, to pass + + if(PEAR::isError($res)) { + $aFailed['documents'][] = array($oDocument->getName(), $res->getMessage()); + } else if($res === false) { + $aFailed['documents'][] = array($oDocument->getName(), _kt('Failed (unknown reason)')); + } else { + $aSucceeded['documents'][] = $oDocument->getId(); + } + } + } + + foreach($this->oEntityList->getFolderIds() as $iId) { + $oFolder =& Folder::get($iId); + + if(PEAR::isError($oFolder)) { + $aFailed['folders'][] = array($iId, _kt('No such folder')); + } else { + $res = $this->check_entity($oFolder); + + if(PEAR::isError($res)) { + $aFailed['folders'][] = array($oFolder->getName(), $res->getMessage()); + } else if($res === false) { + $aFailed['folders'][] = array($oFolder->getName(), _kt('Failed (unknown reason)')); + } else { + $aSucceeded['folders'][] = $oFolder->getId(); + } + } + } + $this->oActiveEntityList = new KTEntityList($aSucceeded['documents'], $aSucceeded['folders']); + $this->aFailed = $aFailed; + + return count($aSucceeded['documents']) + count($aSucceeded['folders']); + } + + + // iterate over all entites to act on them + function perform_action_on_list() { + $this->aActionResults = array('folders'=>array(), 'documents'=>array()); + foreach($this->oActiveEntityList->getDocumentIds() as $iId) { + $oDocument =& Document::get($iId); + // Store document + $this->uploadedDocs[] = $oDocument; + if(!PEAR::isError($oDocument)) { + $sName = $oDocument->getName(); + } else { + $sName = _kt('Error fetching document name'); + } + + $res = $this->perform_action($oDocument); + + //check for shortcut notice + $notice = null; + if($oDocument->isSymbolicLink()){ + $notice = _kt("Shortcut"); + } + + if(PEAR::isError($res)) { + $this->aActionResults['documents'][] = array($sName, $res->getMessage(), $notice); + } else { + // TODO better way of getting the bulk action type + if($this->eventAction == null) { + $this->eventAction = $res; + } + $this->aActionResults['documents'][] = array($sName, _kt('Success'), $notice); + } + } + + // List of ducument objects + $oFolderObjects = array(); + foreach($this->oActiveEntityList->getFolderIds() as $iId) { + $oFolder =& Folder::get($iId); + // Store folder + $this->uploadedFolders[] = $oFolder; + if(!PEAR::isError($oFolder)) { + $sName = $oFolder->getName(); + } else { + $sName = _kt('Error fetching folder name'); + } + + $res = $this->perform_action($oFolder); + + //check for shortcut notice + $notice = null; + if($oFolder->isSymbolicLink()){ + $notice = _kt("Shortcut"); + } + + if(PEAR::isError($res)) { + $this->aActionResults['folders'][] = array($sName, $res->getMessage(), $notice); + } else { + // // TODO better way of getting the bulk action type + if($this->eventAction == null) { + $this->eventAction = $res; + } + $this->aActionResults['folders'][] = array($sName, _kt('Success'), $notice); + } + } + + } + + + + // list persistance + // fetch existing lists + function get_lists() { + $this->oEntityList = KTEntityList::retrieveList(KTUtil::arrayGet($_REQUEST, 'fListCode', null)); + $this->oActiveEntityList = KTEntityList::retrieveList(KTUtil::arrayGet($_REQUEST, 'fActiveListCode', null)); + if(PEAR::isError($this->oActiveEntityList)) { + $this->oActiveEntityList = null; + } + } + + // persist + function store_lists() { + $this->persistParams(array('fListCode', 'fActiveListCode', 'fFolderId', 'fReturnData', 'fReturnAction')); + } + + /** + * Get the return url based on the return action and data + */ + function getReturnUrl() + { + $sReturnAction = $_REQUEST['fReturnAction']; + $sReturnData = $_REQUEST['fReturnData']; + $sAction = 'main'; + $qs = ''; + + switch ($sReturnAction){ + case 'browse': + $sReturnData = (empty($sReturnData)) ? $_REQUEST['fFolderId'] : $sReturnData; + $sTargetUrl = KTBrowseUtil::getUrlForFolder(Folder::get($sReturnData)); + break; + case 'simpleSearch': + $sTargetUrl = KTBrowseUtil::getSimpleSearchBaseUrl(); + $extra = 'fSearchableText='.$sReturnData; + break; + case 'booleanSearch': + $sTargetUrl = KTBrowseUtil::getBooleanSearchBaseUrl(); + $sAction = 'performSearch'; + $extra = 'boolean_search_id='.$sReturnData; + break; + case 'search2': + $sTargetUrl = KTBrowseUtil::getSearchResultURL(); + $sAction = 'searchResults'; + break; + default: + $sTargetUrl = $sReturnAction; + $sAction = ''; + } + + $qs = (!empty($sAction))? 'action='.$sAction : ''; + $qs .= (!empty($extra))? '&'.$extra : ''; + $sTargetUrl = KTUtil::addQueryString($sTargetUrl, $qs); + + return $sTargetUrl; + } + + // forms + // form to list the entites after checking each one + function form_listing() { + $sListCode = $this->oEntityList->getCode(); + $sActiveListCode = $this->oActiveEntityList->getCode(); + + $sTargetUrl = $this->getReturnUrl(); + + $oForm = new KTForm; + $oForm->setOptions(array( + 'identifier' => 'ktcore.actions.bulk.listing.form', + 'submit_label' => _kt('Continue'), + 'targeturl' => $this->getURL(), + 'action' => 'collectinfo', + 'fail_action' => 'main', + 'cancel_url' => $sTargetUrl, + 'noframe' => true, + 'extraargs' => array('fListCode' => $sListCode, + 'fActiveListCode' => $sActiveListCode, + 'fFolderId' => $this->oFolder->getId(), + 'fReturnAction' => KTUtil::arrayGet($_REQUEST, 'fReturnAction'), + 'fReturnData' => KTUtil::arrayGet($_REQUEST, 'fReturnData'), + ), + 'context' => $this, + )); + return $oForm; + } + + // form to show on action completion, and list results + function form_complete() { + $sReturnAction = KTUtil::arrayGet($_REQUEST, 'fReturnAction'); + $sReturnData = KTUtil::arrayGet($_REQUEST, 'fReturnData'); + $sAction = 'main'; + + switch ($sReturnAction){ + case 'browse': + $sReturnData = (empty($sReturnData)) ? $_REQUEST['fFolderId'] : $sReturnData; + $sTargetUrl = KTBrowseUtil::getUrlForFolder(Folder::get($sReturnData)); + break; + case 'simpleSearch': // do we use this? + $sTargetUrl = KTBrowseUtil::getSimpleSearchBaseUrl(); + $extraargs = array('fSearchableText'=>$sReturnData); + break; + case 'booleanSearch': // do we use this? + $sTargetUrl = KTBrowseUtil::getBooleanSearchBaseUrl(); + $sAction = 'performSearch'; + $extraargs = array('boolean_search_id'=>$sReturnData); + break; + case 'search2': + $sTargetUrl = KTBrowseUtil::getSearchResultURL(); + $sAction = 'refresh'; + break; + default: + $sTargetUrl = $sReturnAction; + $sAction = ''; + } + + $oForm = new KTForm; + $oForm->setOptions(array( + 'identifier' => 'ktcore.actions.bulk.complete.form', + 'submit_label' => _kt('Return'), + 'targeturl' => $sTargetUrl, + 'context' => $this, + 'action' => $sAction, + 'extraargs' => $extraargs, + 'noframe' => true, + )); + return $oForm; + } + + + // main entry point - checks the entity list and displays lists + function do_main() { + // get entities (using the checkboxes atm) + $aFolders = KTUtil::arrayGet($_REQUEST, 'selection_f' , array()); + $aDocuments = KTUtil::arrayGet($_REQUEST, 'selection_d' , array()); + $this->oEntityList = new KTEntityList($aDocuments, $aFolders); + + // gives us $this->aFailed + $iActiveCount = $this->check_entities(); + + $oTemplating =& KTTemplating::getSingleton(); + $oTemplate = $oTemplating->loadTemplate('ktcore/bulk_action_listing'); + + $this->store_lists(); + + return $oTemplate->render(array('context' => $this, + 'form' => $this->form_listing(), + 'failed' => $this->aFailed, + 'active' => $this->oActiveEntityList, + 'activecount' => $iActiveCount, + 'failedform' => $this->form_complete(), + 'folders' => $this->_getNames($this->oActiveEntityList->getFolderIds(), 'Folder'), + 'documents' => $this->_getNames($this->oActiveEntityList->getDocumentIds(), 'Document'))); + + } + + // override to add a screen to get a reason, or whatever + // remember to pass to perform action next, and call the super's method + function do_collectinfo() { + $this->store_lists(); + return $this->do_performaction(); + } + + // perform the action itself, and list results (completion action) + function do_performaction() { + $this->get_lists(); + $this->aPersistParams = array(); + $targetFolderId = $_REQUEST['fFolderId']; + $targetFolder =& Folder::get($targetFolderId); + $this->perform_action_on_list(); + // Parse affected documents and folders + if(count($this->uploadedDocs) > 0) + $this->do_notification($this->uploadedDocs, $this->eventAction, $targetFolder); + elseif(count($this->uploadedFolders) > 0) + $this->do_notification($this->uploadedFolders, $this->eventAction, $targetFolder); + // Action specific Emails + // Check if its a move action + if($this->eventAction == "MovedDocument") { + // Notify the folder from which the action happened + $originalFolderId = $_REQUEST['fOriginalFolderId']; + $originalFolder =& Folder::get($originalFolderId); + if(count($this->uploadedDocs) > 0) + $this->do_notification($this->uploadedDocs, $this->eventAction, $originalFolder); + elseif(count($this->uploadedFolders) > 0) + $this->do_notification($this->uploadedFolders, $this->eventAction, $originalFolder); + } + + $oTemplating =& KTTemplating::getSingleton(); + $oTemplate = $oTemplating->loadTemplate('ktcore/bulk_action_complete'); + + return $oTemplate->render(array('context' => $this, + 'list' => $this->aActionResults, + 'form' => $this->form_complete())); + } + + // Jarrett Jordaan: Deal with bulk actions + function do_notification($objects, $eventAction, $targetFolder) { + echo $eventAction." on folder ".$targetFolder->getId()."
"; + // Make sure there were documents/folders affected + if ($targetFolder && count($objects) > 0 && $eventAction != '') { + $oSubscriptionEvent = new SubscriptionEvent(); + $oSubscriptionEvent->notifyBulkDocumentAction($objects, $eventAction, $targetFolder); + } + } + + + + + // main overrides + + // override to do the actual action, on an individual entity + function perform_action($oEntity) { + return PEAR::raiseError(_kt('Action component not implemented')); + } + + // check an individual entity - this should be overrided with additional + // checks required for the specific action, but should always call its + // parent implementation + function check_entity($oEntity) { + $oPermission =& KTPermission::getByName($this->_sPermission); + if(PEAR::isError($oPermission)) { + return true; + } + + // basic document checks + + // TODO: check if this is appropriate + // should probably store the 'equivalent' action (ie. document.delete) + // and check that, rather than add a new list of actions to the workflow + // section + if(is_a($oEntity, 'Document')) { + if(!KTWorkflowUtil::actionEnabledForDocument($oEntity, $this->sName)) { + return PEAR::raiseError(_kt('Action is disabled by workflow')); + } + $status = $oEntity->getStatusID(); + if($status==DELETED||$status==ARCHIVED) { + return PEAR::raiseError(_kt('Document is archived or deleted')); + } + } + + // admin check + if($this->bAllowInAdminMode) { + if(KTBrowseUtil::inAdminMode($this->oUser, null)) { + return true; + } + } + + if(!KTPermissionUtil::userHasPermissionOnItem($this->oUser, $oPermission, $oEntity)) { + return PEAR::raiseError(_kt('You do not have the required permissions')); + } + + return true; + } + + +} + +class KTBulkDocumentAction extends KTBulkAction { + function check_entity($oEntity) { + if(!is_a($oEntity, 'Document')) { + return false; + } + return parent::check_entity($oEntity); + } +} + +class KTBulkFolderAction extends KTBulkAction { + function check_entity($oEntity) { + if(!is_a($oEntity, 'Folder')) { + return false; + } + return parent::check_entity($oEntity); + } +} + + + +// util class for bulk actions + +class KTBulkActionUtil { + function getBulkActionInfo($slot = 'bulkaction') { + $oRegistry =& KTActionRegistry::getSingleton(); + return $oRegistry->getActions($slot); + } + + function getAllBulkActions($slot = 'bulkaction') { + $aObjects = array(); + + foreach (KTBulkActionUtil::getBulkActionInfo($slot) as $aAction) { + list($sClassName, $sPath, $sName, $sPlugin) = $aAction; + $oRegistry =& KTPluginRegistry::getSingleton(); + $oPlugin =& $oRegistry->getPlugin($sPlugin); + if (!empty($sPath)) { + require_once($sPath); + } + $aObjects[] = new $sClassName(null, null, $oPlugin); + } + return $aObjects; + } + + function getBulkActionsByNames($aNames, $slot = 'bulkaction', $oUser = null) { + $aObjects = array(); + foreach (KTBulkActionUtil::getBulkActionInfo($slot) as $aAction) { + list($sClassName, $sPath, $sName, $sPlugin) = $aAction; + $oRegistry =& KTPluginRegistry::getSingleton(); + $oPlugin =& $oRegistry->getPlugin($sPlugin); + if (!in_array($sName, $aNames)) { + continue; + } + if (!empty($sPath)) { + require_once($sPath); + } + $aObjects[] = new $sClassName(null, $oUser, $oPlugin); + } + return $aObjects; + } +} + +?> diff --git a/lib/documentmanagement/documentutil.inc.php b/lib/documentmanagement/documentutil.inc.php index 8089fe6..b77d608 100644 --- a/lib/documentmanagement/documentutil.inc.php +++ b/lib/documentmanagement/documentutil.inc.php @@ -45,8 +45,6 @@ require_once(KT_LIB_DIR . '/documentmanagement/DocumentFieldLink.inc'); require_once(KT_LIB_DIR . '/documentmanagement/DocumentTransaction.inc'); require_once(KT_LIB_DIR . '/documentmanagement/Document.inc'); -require_once(KT_LIB_DIR . '/storage/storagemanager.inc.php'); - // NEW PATHS require_once(KT_LIB_DIR . '/storage/storagemanager.inc.php'); require_once(KT_LIB_DIR . '/filelike/filelikeutil.inc.php'); @@ -62,7 +60,7 @@ require_once(KT_LIB_DIR . '/browse/browseutil.inc.php'); require_once(KT_LIB_DIR . '/workflow/workflowutil.inc.php'); class KTDocumentUtil { - function checkin($oDocument, $sFilename, $sCheckInComment, $oUser, $aOptions = false) { + function checkin($oDocument, $sFilename, $sCheckInComment, $oUser, $aOptions = false, $bulk_action = false) { $oStorage =& KTStorageManagerUtil::getSingleton(); $iFileSize = filesize($sFilename); @@ -149,16 +147,17 @@ class KTDocumentUtil { } Indexer::index($oDocument); - - // fire subscription alerts for the checked in document - $oSubscriptionEvent = new SubscriptionEvent(); - $oFolder = Folder::get($oDocument->getFolderID()); - $oSubscriptionEvent->CheckinDocument($oDocument, $oFolder); + if(!$bulk_action) { + // fire subscription alerts for the checked in document + $oSubscriptionEvent = new SubscriptionEvent(); + $oFolder = Folder::get($oDocument->getFolderID()); + $oSubscriptionEvent->CheckinDocument($oDocument, $oFolder); + } return true; } - function checkout($oDocument, $sCheckoutComment, $oUser) { + function checkout($oDocument, $sCheckoutComment, $oUser, $bulk_action = false) { //automatically check out the linked document if this is a shortcut if($oDocument->isSymbolicLink()){ $oDocument->switchToLinkedCore(); @@ -191,7 +190,7 @@ class KTDocumentUtil { 'document' => $oDocument, ); $oTrigger->setInfo($aInfo); - $ret = $oTrigger->postValidate(); + $ret = $oTrigger->postValidate(true); if (PEAR::isError($ret)) { return $ret; } @@ -200,15 +199,17 @@ class KTDocumentUtil { $oDocumentTransaction = new DocumentTransaction($oDocument, $sCheckoutComment, 'ktcore.transactions.check_out'); $oDocumentTransaction->create(); - // fire subscription alerts for the downloaded document - $oSubscriptionEvent = new SubscriptionEvent(); - $oFolder = Folder::get($oDocument->getFolderID()); - $oSubscriptionEvent->CheckOutDocument($oDocument, $oFolder); + if(!$bulk_action) { + // fire subscription alerts for the downloaded document + $oSubscriptionEvent = new SubscriptionEvent(); + $oFolder = Folder::get($oDocument->getFolderID()); + $oSubscriptionEvent->CheckOutDocument($oDocument, $oFolder); + } return true; } - function archive($oDocument, $sReason) { + function archive($oDocument, $sReason, $bulk_action = false) { if($oDocument->isSymbolicLink()){ return PEAR::raiseError(_kt("It is not possible to archive a shortcut. Please archive the target document.")); @@ -256,17 +257,18 @@ class KTDocumentUtil { 'document' => $oDocument, ); $oTrigger->setInfo($aInfo); - $ret = $oTrigger->postValidate(); + $ret = $oTrigger->postValidate(true); if (PEAR::isError($ret)) { $oDocument->delete(); return $ret; } } - - // fire subscription alerts for the archived document - $oSubscriptionEvent = new SubscriptionEvent(); - $oFolder = Folder::get($oDocument->getFolderID()); - $oSubscriptionEvent->ArchivedDocument($oDocument, $oFolder); + if(!$bulk_action) { + // fire subscription alerts for the archived document + $oSubscriptionEvent = new SubscriptionEvent(); + $oFolder = Folder::get($oDocument->getFolderID()); + $oSubscriptionEvent->ArchivedDocument($oDocument, $oFolder); + } return true; } @@ -698,11 +700,21 @@ $sourceDocument->getName(), } } // }}} - + /* + * Document Add + * Author : Jarrett Jordaan + * Modified : 28/04/09 + * + * @params : KTFolderUtil $oFolder + * string $sFilename + * KTUser $oUser + * array $aOptions + * boolean $bulk_action + */ // {{{ add - function &add($oFolder, $sFilename, $oUser, $aOptions) { + function &add($oFolder, $sFilename, $oUser, $aOptions, $bulk_action = false) { $GLOBALS['_IN_ADD'] = true; - $ret = KTDocumentUtil::_in_add($oFolder, $sFilename, $oUser, $aOptions); + $ret = KTDocumentUtil::_in_add($oFolder, $sFilename, $oUser, $aOptions, $bulk_action); unset($GLOBALS['_IN_ADD']); return $ret; } @@ -731,8 +743,19 @@ $sourceDocument->getName(), return $sFilename; } + /* + * Document Add + * Author : Jarrett Jordaan + * Modified : 28/04/09 + * + * @params : KTFolderUtil $oFolder + * string $sFilename + * KTUser $oUser + * array $aOptions + * boolean $bulk_action + */ // {{{ _in_add - function &_in_add($oFolder, $sFilename, $oUser, $aOptions) { + function &_in_add($oFolder, $sFilename, $oUser, $aOptions, $bulk_action = false) { $aOrigOptions = $aOptions; $sFilename = KTDocumentUtil::getUniqueFilename($oFolder, $sFilename); @@ -785,9 +808,9 @@ $sourceDocument->getName(), } $oUploadChannel->sendMessage(new KTUploadGenericMessage(_kt('Sending subscriptions'))); - // fire subscription alerts for the checked in document // TODO : better way of checking if its a bulk upload - if($_SERVER['PATH_INFO'] != "ktcore.actions.folder.bulkUpload") { + if(!$bulk_action) { + // fire subscription alerts for the checked in document $oSubscriptionEvent = new SubscriptionEvent(); $oFolder = Folder::get($oDocument->getFolderID()); $oSubscriptionEvent->AddDocument($oDocument, $oFolder); @@ -939,8 +962,18 @@ $sourceDocument->getName(), } // }}} + /* + * Document Delete + * Author : Jarrett Jordaan + * Modified : 28/04/09 + * + * @params : KTDocumentUtil $oDocument + * string $sReason + * int $iDestFolderId + * boolean $bulk_action + */ // {{{ delete - function delete($oDocument, $sReason, $iDestFolderId = null) { + function delete($oDocument, $sReason, $iDestFolderId = null, $bulk_action = false) { // use the deleteSymbolicLink function is this is a symlink if ($oDocument->isSymbolicLink()) { @@ -1044,12 +1077,12 @@ $sourceDocument->getName(), $oDocument->setFolderID(1); DBUtil::commit(); - - - // we weren't doing notifications on this one - $oSubscriptionEvent = new SubscriptionEvent(); - $oSubscriptionEvent->RemoveDocument($oDocument, $oOrigFolder); - + // TODO : better way of checking if its a bulk delete + if(!$bulk_action) { + // we weren't doing notifications on this one + $oSubscriptionEvent = new SubscriptionEvent(); + $oSubscriptionEvent->RemoveDocument($oDocument, $oOrigFolder); + } // document is now deleted: triggers are best-effort. @@ -1062,7 +1095,7 @@ $sourceDocument->getName(), 'document' => $oDocument, ); $oTrigger->setInfo($aInfo); - $ret = $oTrigger->postValidate(); + $ret = $oTrigger->postValidate(true); if (PEAR::isError($ret)) { $oDocument->delete(); // FIXME nbm: review that on-fail => delete is correct ?! return $ret; @@ -1135,7 +1168,7 @@ $sourceDocument->getName(), return true; } - function copy($oDocument, $oDestinationFolder, $sReason = null, $sDestinationDocName = null) { + function copy($oDocument, $oDestinationFolder, $sReason = null, $sDestinationDocName = null, $bulk_action = false) { // 1. generate a new triad of content, metadata and core objects. // 2. update the storage path. //print '--------------------------------- BEFORE'; @@ -1284,11 +1317,12 @@ $sourceDocument->getName(), return $ret; } } - - // fire subscription alerts for the copied document - $oSubscriptionEvent = new SubscriptionEvent(); - $oFolder = Folder::get($oDocument->getFolderID()); - $oSubscriptionEvent->MoveDocument($oDocument, $oDestinationFolder, $oSrcFolder, 'CopiedDocument'); + if(!$bulk_action) { + // fire subscription alerts for the copied document + $oSubscriptionEvent = new SubscriptionEvent(); + $oFolder = Folder::get($oDocument->getFolderID()); + $oSubscriptionEvent->MoveDocument($oDocument, $oDestinationFolder, $oSrcFolder, 'CopiedDocument'); + } return $oNewDocument; } @@ -1369,7 +1403,18 @@ $sourceDocument->getName(), return true; } - function move($oDocument, $oToFolder, $oUser = null, $sReason = null) { + /* + * Document Move + * Author : Jarrett Jordaan + * Modified : 28/04/09 + * + * @params : KTDocumentUtil $oDocument + * KTFolderUtil $oToFolder + * KTUser $oUser + * string $sReason + * boolean $bulk_action + */ + function move($oDocument, $oToFolder, $oUser = null, $sReason = null, $bulk_action = false) { //make sure we move the symlink, and the document it's linking to if($oDocument->isSymbolicLink()){ $oDocument->switchToRealCore(); @@ -1425,9 +1470,9 @@ $sourceDocument->getName(), $oDocumentTransaction = new DocumentTransaction($oDocument, $sMoveMessage, 'ktcore.transactions.move'); $oDocumentTransaction->create(); - $oKTTriggerRegistry = KTTriggerRegistry::getSingleton(); $aTriggers = $oKTTriggerRegistry->getTriggers('moveDocument', 'postValidate'); + foreach ($aTriggers as $aTrigger) { $sTrigger = $aTrigger[0]; $oTrigger = new $sTrigger; @@ -1437,15 +1482,17 @@ $sourceDocument->getName(), 'new_folder' => $oFolder, ); $oTrigger->setInfo($aInfo); - $ret = $oTrigger->postValidate(); + $ret = $oTrigger->postValidate(true); if (PEAR::isError($ret)) { return $ret; } } - // fire subscription alerts for the moved document - $oSubscriptionEvent = new SubscriptionEvent(); - $oSubscriptionEvent->MoveDocument($oDocument, $oFolder, $oOriginalFolder); + if(!$bulk_action) { + // fire subscription alerts for the moved document + $oSubscriptionEvent = new SubscriptionEvent(); + $oSubscriptionEvent->MoveDocument($oDocument, $oFolder, $oOriginalFolder); + } return KTPermissionUtil::updatePermissionLookup($oDocument); } diff --git a/lib/foldermanagement/folderutil.inc.php b/lib/foldermanagement/folderutil.inc.php index 91c961f..6d10487 100644 --- a/lib/foldermanagement/folderutil.inc.php +++ b/lib/foldermanagement/folderutil.inc.php @@ -75,7 +75,17 @@ class KTFolderUtil { return $oFolder; } - function add($oParentFolder, $sFolderName, $oUser) { + /* + * Folder Add + * Author : Jarrett Jordaan + * Modified : 28/04/09 + * + * @params : KTDocumentUtil $oParentFolder + * string $sFolderName + * KTUser $oUser + * boolean $bulk_action + */ + function add($oParentFolder, $sFolderName, $oUser, $bulk_action = false) { $folderid=$oParentFolder->getId(); @@ -97,15 +107,16 @@ class KTFolderUtil { 'userid' => $oUser->getId(), 'ip' => Session::getClientIP(), )); - - // fire subscription alerts for the new folder - $oSubscriptionEvent = new SubscriptionEvent(); - $oSubscriptionEvent->AddFolder($oFolder, $oParentFolder); + if(!$bulk_action) { + // fire subscription alerts for the new folder + $oSubscriptionEvent = new SubscriptionEvent(); + $oSubscriptionEvent->AddFolder($oFolder, $oParentFolder); + } return $oFolder; } - function move($oFolder, $oNewParentFolder, $oUser, $sReason=null) { + function move($oFolder, $oNewParentFolder, $oUser, $sReason=null, $bulk_action = false) { if ($oFolder->getId() == 1) { return PEAR::raiseError(_kt('Cannot move root folder!')); @@ -312,7 +323,7 @@ class KTFolderUtil { * - step-by-step delete. */ - function delete($oStartFolder, $oUser, $sReason, $aOptions = null) { + function delete($oStartFolder, $oUser, $sReason, $aOptions = null, $bulk_action = false) { require_once(KT_LIB_DIR . '/unitmanagement/Unit.inc'); $oPerm = KTPermission::getByName('ktcore.permissions.delete'); diff --git a/lib/import/bulkimport.inc.php b/lib/import/bulkimport.inc.php index 76a2d10..0f2dcfa 100644 --- a/lib/import/bulkimport.inc.php +++ b/lib/import/bulkimport.inc.php @@ -40,17 +40,22 @@ require_once(KT_LIB_DIR . '/foldermanagement/folderutil.inc.php'); require_once(KT_LIB_DIR . '/documentmanagement/documentutil.inc.php'); require_once(KT_LIB_DIR . '/filelike/filelikeutil.inc.php'); -// // Jarrett Jordaan: Deal with bulk uploads +// // Jarrett Jordaan: Deal with bulk action require_once(KT_LIB_DIR . '/subscriptions/subscriptions.inc.php'); class KTBulkImportManager { var $oStorage; + // Bulk Action Notification + var $uploadedDocs; + var $uploadedFolders; function KTBulkImportManager($oFolder, $oStorage, $oUser, $aOptions = null) { $this->oFolder =& $oFolder; $this->oStorage =& $oStorage; $this->oUser =& $oUser; $this->aOptions =& $aOptions; + $this->uploadedDocs = array(); + $this->uploadedFolders = array(); if (is_null($aOptions)) { $aOptions = array(); } @@ -69,13 +74,21 @@ class KTBulkImportManager { $this->oStorage->cleanup(); return $res; } + if(count($this->uploadedDocs) > 0) { + // Bulk action subscription notification + $oSubscriptionEvent = new SubscriptionEvent(); + $oSubscriptionEvent->notifyBulkDocumentAction($this->uploadedDocs, 'AddDocument', $this->oFolder); + } elseif(count($this->uploadedFolders) > 0) { + $oSubscriptionEvent = new SubscriptionEvent(); + $oSubscriptionEvent->notifyBulkDocumentAction($this->uploadedFolders, 'AddFolder', $this->oFolder); + } $this->oStorage->cleanup(); + return; } function _importfolder($oFolder, $sPath) { $oPermission = KTPermission::getByName('ktcore.permissions.addFolder'); - $aDocPaths = $this->oStorage->listDocuments($sPath); if (PEAR::isError($aDocPaths)) { return $aDocPaths; @@ -86,16 +99,15 @@ class KTBulkImportManager { if (PEAR::isError($res)) { return $res; } - $oDocObjects[] = $res; + // Store document object + $this->uploadedDocs[] = $res; } - // Jarrett Jordaan: Deal with bulk uploads - $oSubscriptionEvent = new SubscriptionEvent(); - $oSubscriptionEvent->notifyBulkDocumentUpload($oDocObjects, $oFolder); $aFolderPaths = $this->oStorage->listFolders($sPath); if (PEAR::isError($aFolderPaths)) { return $aFolderPaths; } + $oFolderObjects = array(); foreach ($aFolderPaths as $sFolderPath) { $sFolderBasePath = basename($sFolderPath); $sFolderBasePath = ($this->is_utf8($sFolderBasePath)) ? $sFolderBasePath : utf8_encode($sFolderBasePath); @@ -115,7 +127,7 @@ class KTBulkImportManager { if(KTPermissionUtil::userHasPermissionOnItem($this->oUser, $oPermission, $oFolder)) { - $oThisFolder = KTFolderUtil::add($oFolder, $sFolderBasePath, $this->oUser); + $oThisFolder = KTFolderUtil::add($oFolder, $sFolderBasePath, $this->oUser, true); } else { @@ -135,7 +147,10 @@ class KTBulkImportManager { if (PEAR::isError($res)) { return $res; } + // Store folder object + $this->uploadedFolders[] = $res; } + } function _importdocument($oFolder, $sPath) { @@ -165,7 +180,7 @@ class KTBulkImportManager { $aOptions = array_merge($aOptions, $this->aOptions); $sPath = basename($sPath); $sPath = ($this->is_utf8($sPath)) ? $sPath : utf8_encode($sPath); - $oDocument =& KTDocumentUtil::add($oFolder, $sPath, $this->oUser, $aOptions); + $oDocument =& KTDocumentUtil::add($oFolder, $sPath, $this->oUser, $aOptions, true); return $oDocument; } diff --git a/lib/subscriptions/subscriptions.inc.php b/lib/subscriptions/subscriptions.inc.php index d9766b8..1f24add 100644 --- a/lib/subscriptions/subscriptions.inc.php +++ b/lib/subscriptions/subscriptions.inc.php @@ -103,11 +103,14 @@ class SubscriptionEvent { * @params : KTDocumentUtil $oDocObjects * KTFolderUtil $oParentFolder */ - function notifyBulkDocumentUpload($oDocObjects, $oParentFolder) { + function notifyBulkDocumentAction($oDocObjects, $eventType, $oParentFolder) { $content = new SubscriptionContent(); // needed for i18n - $parentId = $oParentFolder->getId(); - $aUsers = $this->_getSubscribers($parentId, $this->subscriptionTypes["Folder"]); - $this->bulkNotification($aUsers, 'AddDocument', $oDocObjects, $parentId); + // TODO Better way to check if this is a folder object + if (is_object($oParentFolder)) { + $parentId = $oParentFolder->getId(); + $aUsers = $this->_getSubscribers($parentId, $this->subscriptionTypes["Folder"]); + $this->bulkNotification($aUsers, $eventType, $oDocObjects, $parentId); + } } /* @@ -124,11 +127,25 @@ class SubscriptionEvent { $content = new SubscriptionContent(); // needed for i18n $locationName = Folder::generateFullFolderPath($parentId); $userId = $_SESSION['userID']; + $oUser = & User::get($userId); + $oUserName = $oUser->getName(); + foreach ($aUsers as $oSubscriber) { $userNotifications = array(); $aNotificationOptions = array(); $userSubscriberId = $oSubscriber->getID(); $emailAddress = $oSubscriber->getEmail(); + // Email type details + $actionTypeEmail = $this->actionTypeEmail($eventType); + // Better subject header with just the modified folder location + $eSubject = "Subscription Notification: Bulk {$actionTypeEmail['message']}"; + // now the email content. + $eContent .= "You are receiving this notification because you are subscribed to the \"$locationName\"
"; + $eContent .= "Your colleague, {$oUser->getName()}, has performed a Bulk {$actionTypeEmail['type']} in the \"$locationName\" folder.
"; + // REMOVE: debugger + global $default; + // Get first document/folders details into a notification + $oNotification = false; foreach($oDocObjects as $oDocObject) { $targetName = $oDocObject->getName(); $objectId = $oDocObject->getId(); @@ -139,25 +156,61 @@ class SubscriptionEvent { $aNotificationOptions['object_id'] = $objectId; $aNotificationOptions['event_type'] = $eventType; $oNotification =& KTSubscriptionNotification::generateSubscriptionNotification($aNotificationOptions); - $userNotifications[] = $oNotification; - } - $eContent = ''; - $eSubject = ''; - // now the email content. - // might not be a good idea to notify on each file - //foreach($userNotifications as $userNotification) { - // $eContent .= $content->getEmailAlertContent($userNotification)."

"; - // Might be an over kill subject - //$eSubject .= $content->getEmailAlertSubject($userNotification)." "; - //} - // Better subject header with just the modified folder location - $eSubject = "KnowledgeTree: Subscription notification for Bulk Upload In Folder \"$locationName\""; - $eContent = "KnowledgeTree: Subscription notification for Bulk Upload In Folder \"$locationName\""; - if($eContent != '' && $eSubject != '') { - //echo $eContent; - $oEmail = new EmailAlert($emailAddress, $eSubject, $eContent); - $oEmail->send(); + break; } + $eContent .= $content->getEmailAlertContent($oNotification, $parentId); + $oEmail = new EmailAlert($emailAddress, $eSubject, $eContent); + $oEmail->send(); + } + } + + function actionTypeEmail($eventType) { + switch($eventType){ + case 'AddFolder': + return array("message"=>"Folders/Documents Added", "type"=>"Add"); + break; + case 'RemoveSubscribedFolder': + return array("message"=>"Removed Subscribed Folders/Documents", "type"=>"Remove"); + break; + case 'RemoveChildFolder': + return array("message"=>"Removed Folders/Documents", "type"=>"Remove"); + break; + case 'AddDocument': + return array("message"=>"Added Folders/Documents", "type"=>"Add"); + break; + case 'RemoveSubscribedDocument': + return array("message"=>"Removed Subscribed Folders/Documents", "type"=>"Remove"); + break; + case 'RemoveChildDocument': + return array("message"=>"Removed Folders/Documents", "type"=>"Remove"); + break; + case 'ModifyDocument': + return array("message"=>"Modified Folders/Documents", "type"=>"Modify"); + break; + case 'CheckInDocument': + return array("message"=>"Checked In Documents", "type"=>"Check In"); + break; + case 'CheckOutDocument': + return array("message"=>"Checked Out Documents", "type"=>"Check Out"); + break; + case 'MovedDocument': + return array("message"=>"Moved Documents/Folders", "type"=>"Move"); + break; + case 'CopiedDocument': + return array("message"=>"Copied Folders/Documents", "type"=>"Copy"); + break; + case 'ArchivedDocument': + return array("message"=>"Archived Folders/Documents", "type"=>"Archive"); + break; + case 'RestoreArchivedDocument': + return array("message"=>"Restored Archived Documents", "type"=>"Archive Restore"); + break; + case 'DownloadDocument': + return array("message"=>"Downloaded Folders/Documents", "type"=>"Download"); + break; + default : + return array("message"=>"Unknown Operations", "type"=>"Unknown"); + break; } } @@ -505,7 +558,8 @@ class SubscriptionContent { * @param object $oKTNotification: The notification object * @return string $str: The html string that will be sent via email */ - function getEmailAlertContent($oKTNotification) { + function getEmailAlertContent($oKTNotification, $bulk_action = 0) { + if($bulk_action == 0) $bulk_action = false; // set up logo and title $rootUrl = KTUtil::kt_url(); @@ -528,7 +582,7 @@ class SubscriptionContent { $downloadDocumentText = _kt('The document "').$info['object_name']._kt('"'); $documentAlertText = _kt('An alert on the document "').$info['object_name']._kt('" has been added or modified'); - if($info['location_name'] !== NULL){ + if($info['location_name'] !== NULL && !$bulk_action){ $addFolderText .= _kt(' to "').$info['location_name']._kt('"'); $removeChildFolderText .= _kt(' from the folder "').$info['location_name']._kt('"'); $addDocumentText .= _kt(' to "').$info['location_name']._kt('"'); @@ -542,13 +596,16 @@ class SubscriptionContent { $downloadDocumentText .= _kt(' in the folder "').$info['location_name']._kt('" has been downloaded'); $documentAlertText .= _kt(' in the folder "').$info['location_name']._kt('"'); } - + if($bulk_action && $info['event_type']!="RemoveSubscribedFolder") { + $browse = "$rootUrl/browse.php?fFolderId=$bulk_action"; + $subFolder = ''._kt('View Subscription Folder ').''; + } // set up links switch($info['event_type']){ case 'AddFolder': $text = $addFolderText; $url = $rootUrl.'/notify.php?id='.$info['notify_id']; - $links = ''._kt('View New Folder').''; + if(!$bulk_action) $links = ''._kt('View New Folder').''; $url = $rootUrl.'/notify.php?id='.$info['notify_id'].'¬ify_action=clear'; $links .= ' | '._kt('Clear Alert').''; break; @@ -560,14 +617,14 @@ class SubscriptionContent { case 'RemoveChildFolder': $text = $removeChildFolderText; $url = $rootUrl.'/notify.php?id='.$info['notify_id']; - $links = ''._kt('View Folder').''; + if(!$bulk_action) $links = ''._kt('View Folder').''; $url = $rootUrl.'/notify.php?id='.$info['notify_id'].'¬ify_action=clear'; $links .= ' | '._kt('Clear Alert').''; break; case 'AddDocument': $text = $addDocumentText; $url = $rootUrl.'/notify.php?id='.$info['notify_id']; - $links = ''._kt('View Document').''; + if(!$bulk_action) $links = ''._kt('View Document').''; $url = $rootUrl.'/notify.php?id='.$info['notify_id'].'¬ify_action=clear'; $links .= ' | '._kt('Clear Alert').''; break; @@ -584,7 +641,7 @@ class SubscriptionContent { case 'ModifyDocument': $text = $modifyDocumentText; $url = $rootUrl.'/notify.php?id='.$info['notify_id']; - $links = ''._kt('View Document').''; + if(!$bulk_action) $links = ''._kt('View Document').''; $url = $rootUrl.'/notify.php?id='.$info['notify_id'].'¬ify_action=clear'; $links .= ' | '._kt('Clear Alert').''; break; @@ -598,21 +655,21 @@ class SubscriptionContent { case 'CheckOutDocument': $text = $checkOutDocumentText; $url = $rootUrl.'/notify.php?id='.$info['notify_id']; - $links = ''._kt('View Document').''; + if(!$bulk_action) $links = ''._kt('View Document').''; $url = $rootUrl.'/notify.php?id='.$info['notify_id'].'¬ify_action=clear'; $links .= ' | '._kt('Clear Alert').''; break; case 'MovedDocument': $text = $modifyDocumentText; $url = $rootUrl.'/notify.php?id='.$info['notify_id']; - $links = ''._kt('View New Location').''; + if(!$bulk_action) $links = ''._kt('View New Location').''; $url = $rootUrl.'/notify.php?id='.$info['notify_id'].'¬ify_action=clear'; $links .= ' | '._kt('Clear Alert').''; break; case 'CopiedDocument': $text = $copiedDocumentText; $url = $rootUrl.'/notify.php?id='.$info['notify_id']; - $links = ''._kt('View Document').''; + if(!$bulk_action) $links = ''._kt('View Document').''; $url = $rootUrl.'/notify.php?id='.$info['notify_id'].'¬ify_action=clear'; $links .= ' | '._kt('Clear Alert').''; break; @@ -624,14 +681,14 @@ class SubscriptionContent { case 'RestoreArchivedDocument': $text = $restoreArchivedDocumentText; $url = $rootUrl.'/notify.php?id='.$info['notify_id']; - $links = ''._kt('View Document').''; + if(!$bulk_action) $links = ''._kt('View Document').''; $url = $rootUrl.'/notify.php?id='.$info['notify_id'].'¬ify_action=clear'; $links .= ' | '._kt('Clear Alert').''; break; case 'DownloadDocument': $text = $downloadDocumentText; $url = $rootUrl.'/notify.php?id='.$info['notify_id']; - $links = ''._kt('View Document').''; + if(!$bulk_action) $links = ''._kt('View Document').''; $url = $rootUrl.'/notify.php?id='.$info['notify_id'].'¬ify_action=clear'; $links .= ' | '._kt('Clear Alert').''; break; @@ -652,16 +709,25 @@ class SubscriptionContent { // we can re-use the normal template. // however, we need to wrap it - no need for a second template here. //$str = '' . $this->getNotificationAlertContent($oKTNotification) . ''; - $str = '
-     '._kt('Subscription notification').': '.$this->_eventTypeNames[$info['event_type']].' -
-
-     '.$text.' -
-
-     '.$links.' -
-
'; + if(!$bulk_action) { + $str = '
+     '._kt('Subscription notification').': '.$this->_eventTypeNames[$info['event_type']].' +
+
+     '.$text.' +
+
+     '.$links.' +
+
'; + } else { + $str = '
+
+ '.$subFolder.' +  '.$links.' +
+
'; + } return $str; } diff --git a/plugins/ktcore/KTBulkActions.php b/plugins/ktcore/KTBulkActions.php index fd68f47..90f2c2c 100644 --- a/plugins/ktcore/KTBulkActions.php +++ b/plugins/ktcore/KTBulkActions.php @@ -259,16 +259,34 @@ class KTBulkDeleteAction extends KTBulkAction { return parent::do_performaction(); } + /* + * Bulk delete + * Author : Jarrett Jordaan + * Modified : 28/04/09 + * + * @params : KTDocumentUtil/KTFolderUtil $oEntity + * + * Description : Since its a bulk operation, the delete function needs to + * know that. Added extra boolean param to the delete + * function. + */ function perform_action($oEntity) { $sReason = $this->res['reason']; if(is_a($oEntity, 'Document')) { - $res = KTDocumentUtil::delete($oEntity, $sReason); + $res = KTDocumentUtil::delete($oEntity, $sReason, null, true); + if (PEAR::isError($res)) { + return $res; + } + return "RemoveChildDocument"; } else if(is_a($oEntity, 'Folder')) { - $res = KTFolderUtil::delete($oEntity, $this->oUser, $sReason); + $res = KTFolderUtil::delete($oEntity, $this->oUser, $sReason, null, true); + if (PEAR::isError($res)) { + return $res; + } + return "RemoveChildFolder"; } - return $res; } } @@ -484,7 +502,8 @@ class KTBulkMoveAction extends KTBulkAction { $this->oTargetFolder = Folder::get($this->iTargetFolderId); $_REQUEST['fReturnData'] = ''; $_REQUEST['fFolderId'] = $this->iTargetFolderId; - + // Jarrett Jordaan : Store initial folder + $_REQUEST['fOriginalFolderId'] = $this->oFolder->getId(); // does it exists if(PEAR::isError($this->oTargetFolder)) { $this->errorRedirectTo('collectinfo', _kt('Invalid target folder selected')); @@ -507,12 +526,27 @@ class KTBulkMoveAction extends KTBulkAction { return parent::do_performaction(); } + /* + * Bulk move + * Author : Jarrett Jordaan + * Modified : 28/04/09 + * + * @params : KTDocumentUtil/KTFolderUtil $oEntity + * + * Description : Since its a bulk operation, the move function needs to + * know that. Added extra boolean param to the move + * function. + */ function perform_action($oEntity) { if(is_a($oEntity, 'Document')) { - return KTDocumentUtil::move($oEntity, $this->oTargetFolder, $this->oUser, $this->sReason); + $res = KTDocumentUtil::move($oEntity, $this->oTargetFolder, $this->oUser, $this->sReason, true); } else if(is_a($oEntity, 'Folder')) { - return KTFolderUtil::move($oEntity, $this->oTargetFolder, $this->oUser, $this->sReason); + $res = KTFolderUtil::move($oEntity, $this->oTargetFolder, $this->oUser, $this->sReason, true); } + if (PEAR::isError($res)) + return $res; + + return 'MovedDocument'; } } @@ -737,12 +771,32 @@ class KTBulkCopyAction extends KTBulkAction { return parent::do_performaction(); } + /* + * Bulk copy + * Author : Jarrett Jordaan + * Modified : 28/04/09 + * + * @params : KTDocumentUtil/KTFolderUtil $oEntity + * + * Description : Since its a bulk operation, the copy function needs to + * know that. Added extra boolean param to the copy + * function. + */ function perform_action($oEntity) { if(is_a($oEntity, 'Document')) { - return KTDocumentUtil::copy($oEntity, $this->oTargetFolder, $this->sReason); + $res = KTDocumentUtil::copy($oEntity, $this->oTargetFolder, null, $this->sReason, true); + if (PEAR::isError($res)) { + return $res; + } + } else if(is_a($oEntity, 'Folder')) { - return KTFolderUtil::copy($oEntity, $this->oTargetFolder, $this->oUser, $this->sReason); + $res = KTFolderUtil::copy($oEntity, $this->oTargetFolder, $this->oUser, $this->sReason, true); + if (PEAR::isError($res)) { + return $res; + } } + + return 'CopiedDocument'; } } @@ -975,15 +1029,25 @@ class KTBulkArchiveAction extends KTBulkAction { return parent::do_performaction(); } + /* + * Bulk archive + * Author : Jarrett Jordaan + * Modified : 28/04/09 + * + * @params : KTDocumentUtil/KTFolderUtil $oEntity + * + * Description : Since its a bulk operation, the archive function needs + * to know that. Added extra boolean param to the archive + * function. + */ function perform_action($oEntity) { if(is_a($oEntity, 'Document')) { - $res = KTDocumentUtil::archive($oEntity, $this->sReason); + $res = KTDocumentUtil::archive($oEntity, $this->sReason, true); if(PEAR::isError($res)){ return $res; } - return true; }else if(is_a($oEntity, 'Folder')) { $aDocuments = array(); $aChildFolders = array(); @@ -1028,7 +1092,7 @@ class KTBulkArchiveAction extends KTBulkAction { return $oDocument; } - $res = KTDocumentUtil::archive($oDocument, $this->sReason); + $res = KTDocumentUtil::archive($oDocument, $this->sReason, true); if(PEAR::isError($res)){ return $res; @@ -1037,8 +1101,10 @@ class KTBulkArchiveAction extends KTBulkAction { }else { return PEAR::raiseError(_kt('The folder contains no documents to archive.')); } - return true; + + } + return "ArchivedDocument"; } } @@ -1150,8 +1216,19 @@ class KTBrowseBulkExportAction extends KTBulkAction { return $str; } + /* + * Bulk export + * Author : Jarrett Jordaan + * Modified : 28/04/09 + * + * @params : KTDocumentUtil/KTFolderUtil $oEntity + * + * Description : Since its a bulk operation, the export function needs + * to know that. Added extra boolean param to the export + * function. + */ function perform_action($oEntity) { - +// TODO find a way to do bulk email $exportCode = $_SESSION['exportcode']; $this->oZip = ZipFolder::get($exportCode); @@ -1189,7 +1266,8 @@ class KTBrowseBulkExportAction extends KTBulkAction { $oQueue->addFolder($this->oZip, $sFolderId); } } - return true; + + return "DownloadDocument"; } function do_downloadZipFile() { @@ -1411,6 +1489,17 @@ class KTBrowseBulkCheckoutAction extends KTBulkAction { return $result; } + /* + * Bulk checkout + * Author : Jarrett Jordaan + * Modified : 28/04/09 + * + * @params : KTDocumentUtil/KTFolderUtil $oEntity + * + * Description : Since its a bulk operation, the checkout function needs + * to know that. Added extra boolean param to the checkout + * function. + */ function perform_action($oEntity) { // checkout document $sReason = $this->sReason; @@ -1431,7 +1520,7 @@ class KTBrowseBulkCheckoutAction extends KTBulkAction { return PEAR::raiseError($oEntity->getName().': '._kt('Document has already been checked out by ').$oCheckedOutUser->getName()); } }else{ - $res = KTDocumentUtil::checkout($oEntity, $sReason, $this->oUser); + $res = KTDocumentUtil::checkout($oEntity, $sReason, $this->oUser, true); if(PEAR::isError($res)) { return PEAR::raiseError($oEntity->getName().': '.$res->getMessage()); @@ -1460,7 +1549,8 @@ class KTBrowseBulkCheckoutAction extends KTBulkAction { } $this->oZip->addDocumentToZip($oEntity); } - + if(!PEAR::isError($res)) { + } }else if(is_a($oEntity, 'Folder')) { // get documents and subfolders $aDocuments = array(); @@ -1553,7 +1643,7 @@ class KTBrowseBulkCheckoutAction extends KTBulkAction { } }else{ // Check out document - $res = KTDocumentUtil::checkout($oDocument, $sReason, $this->oUser); + $res = KTDocumentUtil::checkout($oDocument, $sReason, $this->oUser, true); if(PEAR::isError($res)) { $this->addErrorMessage($oDocument->getName().': '._kt('Document could not be checked out. ').$res->getMessage()); @@ -1590,7 +1680,8 @@ class KTBrowseBulkCheckoutAction extends KTBulkAction { } } } - return true; + + return "CheckOutDocument"; } function do_downloadZipFile() { diff --git a/plugins/ktstandard/KTBulkExportPlugin.php b/plugins/ktstandard/KTBulkExportPlugin.php index 82503da..73576bd 100644 --- a/plugins/ktstandard/KTBulkExportPlugin.php +++ b/plugins/ktstandard/KTBulkExportPlugin.php @@ -178,8 +178,8 @@ class KTBulkExportAction extends KTFolderAction { // fire subscription alerts for the downloaded document if($bNotifications){ - $oSubscriptionEvent = new SubscriptionEvent(); - $oSubscriptionEvent->DownloadDocument($oDocument, $oFolder); + //$oSubscriptionEvent = new SubscriptionEvent(); + //$oSubscriptionEvent->DownloadDocument($oDocument, $oFolder); } $this->oZip->addDocumentToZip($oDocument, $oFolder); diff --git a/plugins/ktstandard/KTSubscriptions.php b/plugins/ktstandard/KTSubscriptions.php index 618e040..d1b11b2 100644 --- a/plugins/ktstandard/KTSubscriptions.php +++ b/plugins/ktstandard/KTSubscriptions.php @@ -316,16 +316,16 @@ class KTCheckoutSubscriptionTrigger { $this->aInfo =& $aInfo; } - function postValidate() { + function postValidate($bulk_action = false) { global $default; $oDocument =& $this->aInfo["document"]; // fire subscription alerts for the checked out document - // fire subscription alerts for the checked in document - $oSubscriptionEvent = new SubscriptionEvent(); - $oFolder = Folder::get($oDocument->getFolderID()); - $oSubscriptionEvent->CheckoutDocument($oDocument, $oFolder); - + if(!$bulk_action) { + $oSubscriptionEvent = new SubscriptionEvent(); + $oFolder = Folder::get($oDocument->getFolderID()); + $oSubscriptionEvent->CheckoutDocument($oDocument, $oFolder); + } } } // }}} @@ -359,16 +359,17 @@ class KTDeleteSubscriptionTrigger { $this->aInfo =& $aInfo; } - function postValidate() { + function postValidate($bulk_action = false) { global $default; $oDocument =& $this->aInfo["document"]; // fire subscription alerts for the deleted document - - // fire subscription alerts for the checked in document - $oSubscriptionEvent = new SubscriptionEvent(); - $oFolder = Folder::get($oDocument->getFolderID()); - // $oSubscriptionEvent->RemoveDocument($oDocument, $oFolder); + if(!$bulk_action) { + // fire subscription alerts for the checked in document + $oSubscriptionEvent = new SubscriptionEvent(); + $oFolder = Folder::get($oDocument->getFolderID()); + //$oSubscriptionEvent->RemoveDocument($oDocument, $oFolder); + } } } // }}} @@ -380,16 +381,17 @@ class KTDocumentMoveSubscriptionTrigger { $this->aInfo =& $aInfo; } - function postValidate() { + function postValidate($bulk_action = false) { global $default; $oDocument =& $this->aInfo["document"]; $oOldFolder =& $this->aInfo["old_folder"]; $oNewFolder =& $this->aInfo["new_folder"]; - - // fire subscription alerts for the checked in document - $oSubscriptionEvent = new SubscriptionEvent(); - $oSubscriptionEvent->MoveDocument($oDocument, $oNewFolder, $oNewFolder); + if(!$bulk_action) { + // fire subscription alerts for the checked in document + $oSubscriptionEvent = new SubscriptionEvent(); + $oSubscriptionEvent->MoveDocument($oDocument, $oNewFolder, $oNewFolder); + } } } // }}} @@ -401,14 +403,15 @@ class KTArchiveSubscriptionTrigger { $this->aInfo =& $aInfo; } - function postValidate() { + function postValidate($bulk_action = false) { global $default; $oDocument =& $this->aInfo["document"]; - - // fire subscription alerts for the checked in document - $oSubscriptionEvent = new SubscriptionEvent(); - $oFolder = Folder::get($oDocument->getFolderID()); - $oSubscriptionEvent->ArchivedDocument($oDocument, $oFolder); + if(!$bulk_action) { + // fire subscription alerts for the checked in document + $oSubscriptionEvent = new SubscriptionEvent(); + $oFolder = Folder::get($oDocument->getFolderID()); + $oSubscriptionEvent->ArchivedDocument($oDocument, $oFolder); + } } } // }}}