diff --git a/action.php b/action.php index 83dd5e4..cec8254 100644 --- a/action.php +++ b/action.php @@ -6,31 +6,31 @@ * Document Management Made Simple * Copyright (C) 2008 KnowledgeTree Inc. * Portions copyright The Jam Warehouse Software (Pty) Limited - * + * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License version 3 as published by the * Free Software Foundation. - * + * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. - * + * * You should have received a copy of the GNU General Public License * along with this program. If not, see . - * - * You can contact KnowledgeTree Inc., PO Box 7775 #87847, San Francisco, + * + * 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 + * 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 + * must display the words "Powered by KnowledgeTree" and retain the original * copyright notice. * Contributor( s): ______________________________________ * @@ -85,6 +85,42 @@ class KTActionDispatcher extends KTStandardDispatcher { return $this->do_main(); } + function getBulkReturnUrl(){ + $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; + } + function do_bulkaction() { $act = (array) KTUtil::arrayGet($_REQUEST, 'submit',null); @@ -101,11 +137,23 @@ class KTActionDispatcher extends KTStandardDispatcher { $oFolder = Folder::get(KTUtil::arrayGet($_REQUEST, 'fFolderId', 1)); if (PEAR::isError($oFolder)) { + $redirectUrl = $this->getBulkReturnUrl(); + if(!empty($redirectUrl)){ + $this->addErrorMessage(_kt('Invalid folder selected.')); + redirect($redirectUrl); + exit(0); + } $this->errorRedirectToBrowse(_kt('Invalid folder selected.')); exit(0); } if (empty($aFolderSelection) && empty($aDocumentSelection)) { + $redirectUrl = $this->getBulkReturnUrl(); + if(!empty($redirectUrl)){ + $this->addErrorMessage(_kt('Please select documents or folders first.')); + redirect($redirectUrl); + exit(0); + } $this->errorRedirectToBrowse(_kt('Please select documents or folders first.'), sprintf('fFolderId=%d', $oFolder->getId())); exit(0); } diff --git a/lib/actions/bulkaction.php b/lib/actions/bulkaction.php index 102949b..c3575cc 100644 --- a/lib/actions/bulkaction.php +++ b/lib/actions/bulkaction.php @@ -430,9 +430,12 @@ class KTBulkAction extends KTStandardDispatcher { $sTargetUrl = KTBrowseUtil::getSearchResultURL(); $sAction = 'searchResults'; break; + default: + $sTargetUrl = $sReturnAction; + $sAction = ''; } - $qs = 'action='.$sAction; + $qs = (!empty($sAction))? 'action='.$sAction : ''; $qs .= (!empty($extra))? '&'.$extra : ''; $sTargetUrl = KTUtil::addQueryString($sTargetUrl, $qs); @@ -489,7 +492,7 @@ class KTBulkAction extends KTStandardDispatcher { break; case 'search2': $sTargetUrl = KTBrowseUtil::getSearchResultURL(); - $sAction = 'searchResults'; + $sAction = 'refresh'; break; } diff --git a/lib/documentmanagement/documentutil.inc.php b/lib/documentmanagement/documentutil.inc.php index 876c184..92690b3 100644 --- a/lib/documentmanagement/documentutil.inc.php +++ b/lib/documentmanagement/documentutil.inc.php @@ -194,6 +194,11 @@ class KTDocumentUtil { return PEAR::raiseError(_kt('There was a database error while trying to archive this file')); } + // Ensure the action is not blocked + if(!KTWorkflowUtil::actionEnabledForDocument($oDocument, 'ktcore.actions.document.archive')){ + return PEAR::raiseError(_kt('Document cannot be archived as it is restricted by the workflow.')); + } + //delete all shortcuts linking to this document $aSymlinks = $oDocument->getSymbolicLinks(); foreach($aSymlinks as $aSymlink){ diff --git a/lib/foldermanagement/folderutil.inc.php b/lib/foldermanagement/folderutil.inc.php index b75a6ea..f31fb9a 100644 --- a/lib/foldermanagement/folderutil.inc.php +++ b/lib/foldermanagement/folderutil.inc.php @@ -8,31 +8,31 @@ * Document Management Made Simple * Copyright (C) 2008 KnowledgeTree Inc. * Portions copyright The Jam Warehouse Software (Pty) Limited - * + * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License version 3 as published by the * Free Software Foundation. - * + * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. - * + * * You should have received a copy of the GNU General Public License * along with this program. If not, see . - * - * You can contact KnowledgeTree Inc., PO Box 7775 #87847, San Francisco, + * + * 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 + * 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 + * must display the words "Powered by KnowledgeTree" and retain the original * copyright notice. * Contributor( s): ______________________________________ */ @@ -392,6 +392,14 @@ class KTFolderUtil { $oStorage =& KTStorageManagerUtil::getSingleton(); $oStorage->removeFolderTree($oStartFolder); + // Check for symbolic links to the folder and its sub folders + $aSymlinks = array(); + foreach($aFolderIds as $iFolder){ + $oFolder = Folder::get($iFolder); + $aLinks = $oFolder->getSymbolicLinks(); + array_merge($aSymlinks, $aLinks); + } + // documents all cleared. $sQuery = 'DELETE FROM ' . KTUtil::getTableName('folders') . ' WHERE id IN (' . DBUtil::paramArray($aFolderIds) . ')'; $aParams = $aFolderIds; @@ -402,17 +410,22 @@ class KTFolderUtil { DBUtil::rollback(); return PEAR::raiseError(_kt('Failure deleting folders.')); } - - //delete all folder shortcuts - foreach($aFolderIds as $iFolder){ - $oFolder = Folder::get($iFolder); - $aSymlinks = $oFolder->getSymbolicLinks(); - - foreach($aSymlinks as $aSymlink){ - KTFolderUtil::deleteSymbolicLink($aSymlink['id']); - } + + // now that the folder has been deleted we delete all the shortcuts + if(!empty($aSymlinks)){ + $links = array(); + foreach($aSymlinks as $link){ + $links[] = $link['id']; + } + $linkIds = implode(',', $links); + + $query = "DELETE FROM folders WHERE id IN ($linkIds)"; + } + + foreach($aSymlinks as $aSymlink){ + KTFolderUtil::deleteSymbolicLink($aSymlink['id']); } - + // purge caches KTEntityUtil::clearAllCaches('Folder'); @@ -584,7 +597,7 @@ class KTFolderUtil { return true; } - + /** * Create a symbolic link in the target folder * @@ -634,7 +647,7 @@ class KTFolderUtil { return PEAR::raiseError(_kt('You\'re not authorized to create a shortcut to this folder')); } } - + //check if the shortcut doesn't already exists in the target folder $aSymlinks = $sourceFolder->getSymbolicLinks(); foreach($aSymlinks as $iSymlink){ @@ -643,7 +656,7 @@ class KTFolderUtil { return PEAR::raiseError(_kt('There already is a shortcut to this folder in the target folder.')); } } - + //Create the link $oSymlink = Folder::createFromArray(array( 'iParentID' => $targetFolder->getId(), @@ -677,7 +690,7 @@ class KTFolderUtil { } if (!$folder->isSymbolicLink()) { - return PEAR::raiseError(_kt('Focument must be a symbolic link entity')); + return PEAR::raiseError(_kt('Folder must be a symbolic link entity')); } if (is_null($user)) { @@ -692,17 +705,17 @@ class KTFolderUtil { $oPerm = KTPermission::getByName('ktcore.permissions.delete'); if (!KTBrowseUtil::inAdminMode($user, $folder)) { if(!KTPermissionUtil::userHasPermissionOnItem($user, $oPerm, $folder)){ - return PEAR::raiseError(_kt('You\'re not authorized to create shortcuts')); + return PEAR::raiseError(_kt('You\'re not authorized to delete shortcuts')); } } - + // we only need to delete the folder entry for the link $sql = "DELETE FROM folders WHERE id=?"; DBUtil::runQuery(array($sql, array($folder->getId()))); } - - + + } ?> diff --git a/lib/plugins/pluginutil.inc.php b/lib/plugins/pluginutil.inc.php index 477e7a4..40b95a6 100644 --- a/lib/plugins/pluginutil.inc.php +++ b/lib/plugins/pluginutil.inc.php @@ -475,6 +475,64 @@ class KTPluginUtil { * This is called by the 'Re-read plugins' action in the web interface. */ function registerPlugins () { + global $default; + + // Path to lock file + $cacheDir = $default->cacheDirectory . DIRECTORY_SEPARATOR; + $lockFile = $cacheDir.'plugin_register.lock'; + + // Check if the lock file exists + if(KTPluginUtil::doCheck($lockFile)){ + return true; + } + + // Create the lock file, run through the plugin registration and then delete the lock file + touch($lockFile); + KTPluginUtil::doPluginRegistration(); + @unlink($lockFile); + } + + /** + * Check the lockfile + */ + function doCheck($lockFile) + { + if(file_exists($lockFile)){ + // If it does exist, do a stat on it to check when it was created. + // if it was accessed more than 5 minutes ago then delete it and proceed with the plugin registration + // otherwise wait till lock file is deleted signalling that the registration is complete and return. + + $stat = stat($lockFile); + + $time = time() - (60 * 5); + if($stat['mtime'] > $time){ + + $cnt = 0; + + while(file_exists($lockFile)){ + $cnt++; + sleep(2); + + // if we've been waiting too long - typically it should only take a few seconds so 2 mins is too much time. + if($cnt > 60){ + @unlink($lockFile); + return false; + } + } + return true; + } + @unlink($lockFile); + } + return false; + } + + /** + * Read the plugins directory and register all plugins in the database. + */ + function doPluginRegistration() + { + global $default; + KTPluginUtil::_deleteSmartyFiles(); require_once(KT_LIB_DIR . '/cache/cache.inc.php'); $oCache =& KTCache::getSingleton(); @@ -493,7 +551,6 @@ class KTPluginUtil { } } - global $default; $oRegistry =& KTPluginRegistry::getSingleton(); $aRegistryList = $oRegistry->getPlugins(); foreach ($aRegistryList as $oPlugin) { diff --git a/plugins/ktcore/KTBulkActions.php b/plugins/ktcore/KTBulkActions.php index 8283fe5..169e403 100644 --- a/plugins/ktcore/KTBulkActions.php +++ b/plugins/ktcore/KTBulkActions.php @@ -103,13 +103,15 @@ class KTBulkDeleteAction extends KTBulkAction { * @return KTForm the form */ function form_confirm() { + $cancelUrl = $this->getReturnUrl(); + $oForm = new KTForm; $oForm->setOptions(array( 'label' => _kt('Are you sure?'), 'description' => _kt('There are shortcuts linking to some of the documents or folders in your selection; continuing will automatically delete the shortcuts. Would you like to continue?'), 'action' => 'collectinfo', 'fail_action' => 'main', - 'cancel_url' => KTBrowseUtil::getUrlForFolder($this->oFolder), + 'cancel_url' => $cancelUrl, 'submit_label' => _kt('Continue'), 'context' => $this, )); @@ -539,6 +541,11 @@ class KTBulkArchiveAction extends KTBulkAction { if($oEntity->isSymbolicLink()){ return PEAR::raiseError(_kt("It is not possible to archive a shortcut. Please archive the target document or folder instead.")); } + if(is_a($oEntity, 'Document')){ + if(!KTWorkflowUtil::actionEnabledForDocument($oEntity, 'ktcore.actions.document.archive')){ + return PEAR::raiseError(_kt('Document cannot be archived as it is restricted by the workflow.')); + } + } return parent::check_entity($oEntity); } @@ -548,13 +555,15 @@ class KTBulkArchiveAction extends KTBulkAction { * @return KTForm the form */ function form_confirm() { + $cancelUrl = $this->getReturnUrl(); + $oForm = new KTForm; $oForm->setOptions(array( 'label' => _kt('Are you sure?'), 'description' => _kt('There are shortcuts linking to some of the documents or folders in your selection; continuing will automatically delete the shortcuts. Would you like to continue?'), 'action' => 'collectinfo', 'fail_action' => 'main', - 'cancel_url' => KTBrowseUtil::getUrlForFolder($this->oFolder), + 'cancel_url' => $cancelUrl, 'submit_label' => _kt('Continue'), 'context' => $this, )); @@ -640,7 +649,7 @@ class KTBulkArchiveAction extends KTBulkAction { // Get documents in folder $sDocuments = $oFolder->getDocumentIDs($sFolderId); - $aDocuments = explode(',', $sDocuments); + $aDocuments = (!empty($sDocuments)) ? explode(',', $sDocuments) : array(); // Get all the folders within the folder $sWhereClause = "parent_folder_ids = '{$sFolderId}' OR @@ -680,6 +689,8 @@ class KTBulkArchiveAction extends KTBulkAction { return $res; } } + }else { + return PEAR::raiseError(_kt('The folder contains no documents to archive.')); } return true; } diff --git a/plugins/tagcloud/TagCloudRedirectPage.php b/plugins/tagcloud/TagCloudRedirectPage.php index 415c004..f9fbc88 100644 --- a/plugins/tagcloud/TagCloudRedirectPage.php +++ b/plugins/tagcloud/TagCloudRedirectPage.php @@ -142,7 +142,8 @@ class TagCloudRedirectPage extends KTStandardDispatcher { $aOptions = $collection->getEnvironOptions(); // extract data from the environment - $aOptions['return_url'] = KTUtil::addQueryString('TagCloudRedirection&action=search&tag='. urlencode($tag), false ); + $returnUrl = KTUtil::addQueryString('TagCloudRedirection&action=search&tag='. urlencode($tag), false); + $aOptions['return_url'] = $returnUrl; $aOptions['empty_message'] = _kt('No documents or folders match this query.'); $aOptions['is_browse'] = true; @@ -159,8 +160,7 @@ class TagCloudRedirectPage extends KTStandardDispatcher { 'boolean_search' => $sSearch, 'bulkactions' => KTBulkActionUtil::getAllBulkActions(), 'browseutil' => new KTBrowseUtil(), - 'returnaction' => 'booleanSearch', - 'returndata' => $sSearch, + 'returnaction' => $returnUrl, ); return $oTemplate->render($aTemplateData); } diff --git a/search2.php b/search2.php index 63b5378..6ec3162 100644 --- a/search2.php +++ b/search2.php @@ -274,6 +274,14 @@ class SearchDispatcher extends KTStandardDispatcher { redirect(KTUtil::kt_url().'/dashboard.php'); } + function do_refresh(){ + // Get query from session + $query = $_SESSION['search2_query']; + + $this->processQuery($query); + $this->redirectTo('searchResults'); + } + /** * Processes a query sent by HTTP POST in searchQuery. *