diff --git a/config/cache-path b/config/cache-path new file mode 100644 index 0000000..80a084a --- /dev/null +++ b/config/cache-path @@ -0,0 +1 @@ +var/cache diff --git a/config/config.ini b/config/config.ini index 7b9c98c..d0ae414 100644 --- a/config/config.ini +++ b/config/config.ini @@ -3,6 +3,8 @@ ; db section. ; ---------------------------------------------------------------- +; logLevel = DEBUG + [db] ; The Database Engine to use. Currently mysql is the only ; supported type. @@ -25,6 +27,7 @@ dbAdminPass = js9281djw ; need to, as you may introduce errors in your system. ; ---------------------------------------------------------------- + ; install path (file path) ; ; Leave as default to have it automatically detected. @@ -168,4 +171,4 @@ restrictAdminPasswords = default [cache] cacheDirectory = ${varDirectory}/cache -cacheEnabled = false +cacheEnabled = true diff --git a/config/dmsDefaults.php b/config/dmsDefaults.php index c090102..49e4f70 100644 --- a/config/dmsDefaults.php +++ b/config/dmsDefaults.php @@ -23,6 +23,9 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +// DEBUG DEBUG DEBUG APD +//if (extension_loaded('APD')) { apd_set_pprof_trace(); } + // Default settings differ, we need some of these, so force the matter. // Can be overridden here if actually necessary. error_reporting(E_ALL & ~E_NOTICE); @@ -54,6 +57,8 @@ if (!defined('PATH_SEPARATOR')) { } } +require_once(KT_LIB_DIR . '/Log.inc'); + // {{{ KTInit class KTInit { // {{{ prependPath() @@ -350,6 +355,84 @@ class KTInit { return ""; } // }}} + + // {{{ initConfig + function initConfig() { + global $default; + $use_cache = false; + $store_cache = false; + if (file_exists(KT_DIR . "/config/cache-path")) { + $store_cache = true; + $user = KTLegacyLog::running_user(); + $cache_file = trim(file_get_contents(KT_DIR . "/config/cache-path")) . '/configcache' . $user; + if (!KTUtil::isAbsolutePath($cache_file)) { $cache_file = sprintf("%s/%s", KT_DIR, $cache_file); } + $config_file = trim(file_get_contents(KT_DIR . "/config/config-path")); + if (!KTUtil::isAbsolutePath($config_file)) { $config_file = sprintf("%s/%s", KT_DIR, $config_file); } + + $exists = file_exists($cache_file); + if ($exists) { + $cachestat = stat($cache_file); + $configstat = stat($config_file); + $tval = 9; + // print sprintf("is %d > %d\n", $cachestat[$tval], $configstat[$tval]); + if ($cachestat[$tval] > $configstat[$tval]) { + $use_cache = true; + } + } + + + } + + if ($use_cache) { + $oKTConfig =& KTConfig::getSingleton(); + $oKTConfig->loadCache($cache_file); + + foreach ($oKTConfig->flat as $k => $v) { + $default->$k = $v; + } + } else { + $oKTConfig =& KTConfig::getSingleton(); + + $oKTConfig->setdefaultns("KnowledgeTree", "fileSystemRoot", KT_DIR); + $oKTConfig->setdefaultns("KnowledgeTree", "serverName", KTUtil::arrayGet($_SERVER, 'HTTP_HOST', 'localhost')); + $oKTConfig->setdefaultns("KnowledgeTree", "sslEnabled", false); + if (array_key_exists('HTTPS', $_SERVER)) { + if (strtolower($_SERVER['HTTPS']) === 'on') { + $oKTConfig->setdefaultns("KnowledgeTree", "sslEnabled", true); + } + } + $oKTConfig->setdefaultns("KnowledgeTree", "rootUrl", $this->guessRootUrl()); + $oKTConfig->setdefaultns("KnowledgeTree", "execSearchPath", $_SERVER['PATH']); + $oKTConfig->setdefaultns("KnowledgeTree", "pathInfoSupport", false); + $oKTConfig->setdefaultns("storage", "manager", 'KTOnDiskPathStorageManager'); + $oKTConfig->setdefaultns("config", "useDatabaseConfiguration", false); + $oKTConfig->setdefaultns("tweaks", "browseToUnitFolder", false); + $oKTConfig->setdefaultns("tweaks", "genericMetaDataRequired", true); + $oKTConfig->setdefaultns("tweaks", "phpErrorLogFile", false); + $oKTConfig->setdefaultns("tweaks", "developmentWindowLog", false); + + $oKTConfig->setdefaultns("user_prefs", "passwordLength", 6); + $oKTConfig->setdefaultns("user_prefs", "restrictAdminPasswords", false); + + $oKTConfig->setdefaultns("ui", "ieGIF", true); + $oKTConfig->setdefaultns("ui", "alwaysShowAll", false); + $oKTConfig->setdefaultns("ui", "condensedAdminUI", false); + + $oKTConfig->setdefaultns(null, "logLevel", 'INFO'); + $oKTConfig->setdefaultns("import", "unzip", 'unzip'); + $oKTConfig->setdefaultns("cache", "cacheDirectory", '${varDirectory}/cache'); + $oKTConfig->setdefaultns("cache", "cacheEnabled", 'false'); + + $this->readConfig(); + + $oKTConfig =& KTConfig::getSingleton(); + if ($store_cache) { $oKTConfig->createCache($cache_file);} + + + } + } + // }}} + // {{{ readConfig function readConfig () { global $default; @@ -367,6 +450,7 @@ class KTInit { } if ($v === "false") { $v = false; + } if ($v === "true") { $v = true; @@ -397,40 +481,8 @@ require_once(KT_LIB_DIR . '/util/ktutil.inc'); require_once(KT_LIB_DIR . "/config/config.inc.php"); +$KTInit->initConfig(); $oKTConfig =& KTConfig::getSingleton(); - -$oKTConfig->setdefaultns("KnowledgeTree", "fileSystemRoot", KT_DIR); -$oKTConfig->setdefaultns("KnowledgeTree", "serverName", KTUtil::arrayGet($_SERVER, 'HTTP_HOST', 'localhost')); -$oKTConfig->setdefaultns("KnowledgeTree", "sslEnabled", false); -if (array_key_exists('HTTPS', $_SERVER)) { - if (strtolower($_SERVER['HTTPS']) === 'on') { - $oKTConfig->setdefaultns("KnowledgeTree", "sslEnabled", true); - } -} -$oKTConfig->setdefaultns("KnowledgeTree", "rootUrl", $KTInit->guessRootUrl()); -$oKTConfig->setdefaultns("KnowledgeTree", "execSearchPath", $_SERVER['PATH']); -$oKTConfig->setdefaultns("KnowledgeTree", "pathInfoSupport", false); -$oKTConfig->setdefaultns("storage", "manager", 'KTOnDiskPathStorageManager'); -$oKTConfig->setdefaultns("config", "useDatabaseConfiguration", false); -$oKTConfig->setdefaultns("tweaks", "browseToUnitFolder", false); -$oKTConfig->setdefaultns("tweaks", "genericMetaDataRequired", true); -$oKTConfig->setdefaultns("tweaks", "phpErrorLogFile", false); -$oKTConfig->setdefaultns("tweaks", "developmentWindowLog", false); - -$oKTConfig->setdefaultns("user_prefs", "passwordLength", 6); -$oKTConfig->setdefaultns("user_prefs", "restrictAdminPasswords", false); - -$oKTConfig->setdefaultns("ui", "ieGIF", true); -$oKTConfig->setdefaultns("ui", "alwaysShowAll", false); -$oKTConfig->setdefaultns("ui", "condensedAdminUI", false); - -$oKTConfig->setdefaultns(null, "logLevel", 'INFO'); -$oKTConfig->setdefaultns("import", "unzip", 'unzip'); -$oKTConfig->setdefaultns("cache", "cacheDirectory", '${varDirectory}/cache'); -$oKTConfig->setdefaultns("cache", "cacheEnabled", 'false'); - -$KTInit->readConfig(); - $KTInit->setupServerVariables(); // instantiate log diff --git a/config/tableMappings.inc b/config/tableMappings.inc index 68e3960..cff29de 100644 --- a/config/tableMappings.inc +++ b/config/tableMappings.inc @@ -143,6 +143,7 @@ $default->notifications_table = "notifications"; $default->authentication_sources_table = "authentication_sources"; $default->dashlet_disable_table = "dashlet_disables"; $default->role_allocations_table = "role_allocations"; +$default->document_role_allocations_table = "document_role_allocations"; $default->plugins_table = "plugins"; $default->document_metadata_version_table = "document_metadata_version"; $default->document_content_version_table = "document_content_version"; diff --git a/lib/cache/cache.inc.php b/lib/cache/cache.inc.php index b24a4b6..8522a12 100644 --- a/lib/cache/cache.inc.php +++ b/lib/cache/cache.inc.php @@ -10,6 +10,15 @@ class KTCache { } // }}} + // takes an Entity type-name, and an array of the failed attrs. + function alertFailure($sEntityType, $aFail) { + //var_dump($aFail); + $sMessage = sprintf('Failure in cache-comparison on type "%s": %s', $sEntityType, implode(', ', $aFail)); + global $default; + $default->log->error($sMessage); + $_SESSION['KTErrorMessage'][] = $sMessage; + } + function KTCache() { require_once("Cache/Lite.php"); require_once(KT_LIB_DIR . '/config/config.inc.php'); diff --git a/lib/config/config.inc.php b/lib/config/config.inc.php index fa6e7ad..807c442 100644 --- a/lib/config/config.inc.php +++ b/lib/config/config.inc.php @@ -37,6 +37,38 @@ class KTConfig { var $flat = array(); var $flatns = array(); + // FIXME nbm: how do we cache errors here? + function loadCache($filename) { + $config_str = file_get_contents($filename); + $config_cache = unserialize($config_str); + $this->flat = $config_cache['flat']; + $this->flatns = $config_cache['flatns']; + $this->expanded = $config_cache['expanded']; + $this->expanding = $config_cache['expanding']; + /* + print "----- Me\n"; + unset($this->aFileRoot); + unset($this->aSectionFile); + var_dump($this); + print "----- Cache\n"; + var_dump($config_cache); + */ + + return true; + } + + function createCache($filename) { + $config_cache = array(); + $config_cache['flat'] = $this->flat; + $config_cache['flatns'] = $this->flatns; + $config_cache['expanded'] = $this->expanded; + $config_cache['expanding'] = $this->expanding; + + file_put_contents($filename, serialize($config_cache)); + + + } + function loadFile($filename, $bDefault = false) { $c = new Config; $root =& $c->parseConfig($filename, "IniCommented"); diff --git a/lib/documentmanagement/Document.inc b/lib/documentmanagement/Document.inc index 4d49851..4d9d2c8 100644 --- a/lib/documentmanagement/Document.inc +++ b/lib/documentmanagement/Document.inc @@ -69,6 +69,9 @@ class Document { function getCreatorID() { return $this->_oDocumentCore->getCreatorId(); } function setCreatorID($iNewValue) { $this->_oDocumentCore->setCreatorId($iNewValue); } + function getOwnerID() { return $this->_oDocumentCore->getOwnerId(); } + function setOwnerID($iNewValue) { $this->_oDocumentCore->setOwnerId($iNewValue); } + function getLastModifiedDate() { return $this->_oDocumentCore->getLastModifiedDate(); } function setLastModifiedDate($dNewValue) { $this->_oDocumentCore->setLastModifiedDate($dNewValue); } @@ -418,6 +421,7 @@ class Document { $oDocument = new Document(); $aOptions = array_change_key_case($aOptions); + $aCoreKeys = array( "CreatorId", "Created", diff --git a/lib/documentmanagement/documentcore.inc.php b/lib/documentmanagement/documentcore.inc.php index 0802b6b..7a9a188 100644 --- a/lib/documentmanagement/documentcore.inc.php +++ b/lib/documentmanagement/documentcore.inc.php @@ -73,6 +73,7 @@ class KTDocumentCore extends KTEntity { // transaction-related "iCreatorId" => 'creator_id', + "dCreated" => 'created', "iModifiedUserId" => 'modified_user_id', "dModified" => 'modified', @@ -92,6 +93,7 @@ class KTDocumentCore extends KTEntity { // permission-related "iPermissionObjectId" => 'permission_object_id', "iPermissionLookupId" => 'permission_lookup_id', + "iOwnerId" => 'owner_id', ); function KTDocument() { @@ -100,6 +102,8 @@ class KTDocumentCore extends KTEntity { // {{{ getters/setters function getCreatorId() { return $this->iCreatorId; } function setCreatorId($iNewValue) { $this->iCreatorId = $iNewValue; } + function getOwnerId() { return $this->iOwnerId; } + function setOwnerId($iNewValue) { $this->iOwnerId = $iNewValue; } function getCreatedDateTime() { return $this->dCreated; } function getModifiedUserId() { return $this->iModifiedUserId; } function setModifiedUserId($iNewValue) { $this->iModifiedUserId = $iNewValue; } @@ -142,28 +146,11 @@ class KTDocumentCore extends KTEntity { // {{{ ktentity requirements function _fieldValues () { - $this->sFullPath = KTDocumentCore::_generateFolderPath($this->iFolderId); - $this->sParentFolderIds = KTDocumentCore::_generateFolderIds($this->iFolderId); + $this->sFullPath = Folder::generateFolderPath($this->iFolderId); + $this->sParentFolderIds = Folder::generateFolderIds($this->iFolderId); return parent::_fieldValues(); } - /** - * Recursive function to generate a comma delimited string containing - * the parent folder ids - * - * @return String comma delimited string containing the parent folder ids - */ - function _generateParentFolderIds($iFolderId) { - $sTable = KTUtil::getTableName('folders'); - if (empty($iFolderId)) { - return; - } - - $sQuery = sprintf('SELECT parent_id FROM %s WHERE id = ?', $sTable); - $aParams = array($iFolderId); - $iParentId = DBUtil::getOneResultKey(array($sQuery, $aParams), 'parent_id'); - return KTDocumentCore::_generateParentFolderIds($iParentId) . ",$iFolderId"; - } /** * Returns a comma delimited string containing the parent folder ids, strips leading / @@ -195,9 +182,12 @@ class KTDocumentCore extends KTEntity { * Returns a forward slash deliminated string giving full path of document, strips leading / */ function _generateFolderPath($iFolderId) { + return Folder::generateFolderPath($iFolderId); +/* $sPath = KTDocumentCore::_generateFullFolderPath($iFolderId); $sPath = substr($sPath, 1, strlen($sPath)); return $sPath; +*/ } // }}} @@ -212,6 +202,9 @@ class KTDocumentCore extends KTEntity { if (empty($this->iModifiedUserId)) { $this->iModifiedUserId = $this->iCreatorId; } + if (empty($this->iOwnerId)) { + $this->iOwnerId = $this->iCreatorId; + } if (empty($this->iMetadataVersion)) { $this->iMetadataVersion = 0; } @@ -221,7 +214,7 @@ class KTDocumentCore extends KTEntity { $oFolder = Folder::get($this->getFolderId()); $this->iPermissionObjectId = $oFolder->getPermissionObjectId(); $res = parent::create(); - + if ($res === true) { KTPermissionUtil::updatePermissionLookup($this); } diff --git a/lib/documentmanagement/documentutil.inc.php b/lib/documentmanagement/documentutil.inc.php index 2f55829..232efe0 100644 --- a/lib/documentmanagement/documentutil.inc.php +++ b/lib/documentmanagement/documentutil.inc.php @@ -185,7 +185,7 @@ class KTDocumentUtil { return $res; } } else { - $oUploadChannel->sendMessage(new KTUploadGenericMessage(_("Storing contents"))); + // $oUploadChannel->sendMessage(new KTUploadGenericMessage(_("Storing contents"))); $res = KTDocumentUtil::storeContents($oDocument, $oContents, $aOptions); if (PEAR::isError($res)) { $oDocument->delete(); @@ -200,7 +200,7 @@ class KTDocumentUtil { return $res; } } else { - $oUploadChannel->sendMessage(new KTUploadGenericMessage(_("Saving metadata"))); + // $oUploadChannel->sendMessage(new KTUploadGenericMessage(_("Saving metadata"))); $res = KTDocumentUtil::saveMetadata($oDocument, $aMetadata); if (PEAR::isError($res)) { $oDocument->delete(); @@ -374,6 +374,16 @@ class KTDocumentUtil { // {{{ add function &add($oFolder, $sFilename, $oUser, $aOptions) { + $GLOBALS['_IN_ADD'] = true; + $ret = KTDocumentUtil::_in_add($oFolder, $sFilename, $oUser, $aOptions); + unset($GLOBALS['_IN_ADD']); + return $ret; + } + // }}} + + + // {{{ _in_add + function &_in_add($oFolder, $sFilename, $oUser, $aOptions) { if (KTDocumentUtil::fileExists($oFolder, $sFilename)) { $oDoc = Document::getByFilenameAndFolder($sFilename, $oFolder->getId()); if (PEAR::isError($oDoc)) { @@ -403,12 +413,12 @@ class KTDocumentUtil { $oUploadChannel =& KTUploadChannel::getSingleton(); $oUploadChannel->sendMessage(new KTUploadNewFile($sFilename)); $oDocument =& KTDocumentUtil::_add($oFolder, $sFilename, $oUser, $aOptions); - $oUploadChannel->sendMessage(new KTUploadGenericMessage(_("Document created"))); + // $oUploadChannel->sendMessage(new KTUploadGenericMessage(_("Document created"))); if (PEAR::isError($oDocument)) { return $oDocument; } - $oUploadChannel->sendMessage(new KTUploadGenericMessage(_("Scanning file"))); + // $oUploadChannel->sendMessage(new KTUploadGenericMessage(_("Scanning file"))); $oKTTriggerRegistry = KTTriggerRegistry::getSingleton(); $aTriggers = $oKTTriggerRegistry->getTriggers('content', 'scan'); $iTrigger = 0; @@ -416,7 +426,7 @@ class KTDocumentUtil { $sTrigger = $aTrigger[0]; $oTrigger = new $sTrigger; $oTrigger->setDocument($oDocument); - $oUploadChannel->sendMessage(new KTUploadGenericMessage(sprintf(_(" (trigger %s)"), $sTrigger))); + // $oUploadChannel->sendMessage(new KTUploadGenericMessage(sprintf(_(" (trigger %s)"), $sTrigger))); $ret = $oTrigger->scan(); if (PEAR::isError($ret)) { $oDocument->delete(); @@ -434,11 +444,11 @@ class KTDocumentUtil { } $oTrigger = new $sTrigger; $oTrigger->setDocument($oDocument); - $oUploadChannel->sendMessage(new KTUploadGenericMessage(sprintf(_(" (trigger %s)"), $sTrigger))); + // $oUploadChannel->sendMessage(new KTUploadGenericMessage(sprintf(_(" (trigger %s)"), $sTrigger))); $oTrigger->transform(); } - $oUploadChannel->sendMessage(new KTUploadGenericMessage(_("Creating transaction"))); + // $oUploadChannel->sendMessage(new KTUploadGenericMessage(_("Creating transaction"))); $aOptions = array('user' => $oUser); //create the document transaction record $oDocumentTransaction = & new DocumentTransaction($oDocument, "Document created", 'ktcore.transactions.create', $aOptions); @@ -448,7 +458,7 @@ class KTDocumentUtil { return $res; } - $oUploadChannel->sendMessage(new KTUploadGenericMessage(_("Sending subscriptions"))); + // $oUploadChannel->sendMessage(new KTUploadGenericMessage(_("Sending subscriptions"))); // fire subscription alerts for the checked in document $oSubscriptionEvent = new SubscriptionEvent(); $oFolder = Folder::get($oDocument->getFolderID()); @@ -467,6 +477,7 @@ class KTDocumentUtil { $ret = $oTrigger->postValidate(); } + KTDocumentUtil::updateSearchableText($oDocument, true); $oUploadChannel->sendMessage(new KTUploadGenericMessage(_("All done..."))); @@ -533,7 +544,10 @@ class KTDocumentUtil { // }}} // {{{ updateSearchableText - function updateSearchableText($oDocument) { + function updateSearchableText($oDocument, $bOverride = false) { + if (isset($GLOBALS['_IN_ADD']) && empty($bOverride)) { + return; + } $oDocument = KTUtil::getObject('Document', $oDocument); $iDocumentId = $oDocument->getId(); $sTable = KTUtil::getTableName('document_transaction_text'); diff --git a/lib/foldermanagement/Folder.inc b/lib/foldermanagement/Folder.inc index 9964f51..5972526 100644 --- a/lib/foldermanagement/Folder.inc +++ b/lib/foldermanagement/Folder.inc @@ -101,33 +101,31 @@ class Folder extends KTEntity { return $res; } // }}} - /** - * Recursive function to generate a comma delimited string containing - * the parent folder ids - * - * @return String comma delimited string containing the parent folder ids - */ - function generateParentFolderIDS($iFolderID) { - global $default; - //if the folder is not the root folder - if ($iFolderID != 0) { - $sql = $default->db; - $sql->query(array("SELECT parent_id FROM $default->folders_table WHERE ID = ?", $iFolderID));/*ok*/ - $sql->next_record(); - return Folder::generateParentFolderIDS($sql->f("parent_id")) . ",$iFolderID"; - } - return; - - } - + /** * Returns a comma delimited string containing the parent folder ids, strips leading / * * @return String comma delimited string containing the parent folder ids */ - function generateFolderIDs($iFolderID) { - $sFolderIDs = Folder::generateParentFolderIDS($iFolderID); - return substr($sFolderIDs, 1, strlen($sFolderIDs)); + function generateFolderIDs($iFolderId) { + if (empty($iFolderId)) { + return; + } + $oFolder =& Folder::get($iFolderId); + if (PEAR::isError($oFolder)) { + return $oFolder; + } + + $iParentId = $oFolder->getParentId(); + if (empty($iParentId)) { + return $oFolder->getId(); + } + $oParentFolder =& Folder::get($iParentId); + $sParentFolderParentFolderIds = $oParentFolder->getParentFolderIDs(); + if (empty($sParentFolderParentFolderIds)) { + return sprintf('%s,%s', $iParentId, $oFolder->getId());; + } + return sprintf('%s,%s,%s', $sParentFolderParentFolderIds, $iParentId, $oFolder->getId()); } /** @@ -212,12 +210,9 @@ class Folder extends KTEntity { global $default; //get the direct children $sql = $default->db; - $sql->query(array("SELECT id from $default->folders_table WHERE parent_id = ?", $iId));/*ok*/ - while ($sql->next_record()) { - //force an update, this will cause this child's children to be updated - $oFolder = Folder::get($sql->f("id")); + $aFolders =& Folder::getByParentId($iId); + foreach ($aFolders as $oFolder) { $oFolder->update(true); - } return; } @@ -260,6 +255,13 @@ class Folder extends KTEntity { Folder::getChildren($sql->f("id"), $aChildren); } return $aChildren; + /* + $oFolder = Folder::get($iFolderID); + $path = $oFolder->getParentFolderIds() . ',' . $oFolder->getId(); + return Folder::getList(array( + sprintf('(parent_folder_ids = "%s" OR parent_folder_ids LIKE "%s,%%")', $path, $path), + )); + */ } /** @@ -412,11 +414,8 @@ class Folder extends KTEntity { */ function getParentFolderID($iFolderID) { if ($iFolderID != 0) { - global $default; - $sql = $default->db; - $sql->query(array("SELECT parent_id FROM " . $default->folders_table . " WHERE id = ?", $iFolderID));/*ok*/ - $sql->next_record(); - return $sql->f("parent_id"); + $oFolder = Folder::get($iFolderID); + return $oFolder->getParentFolderID(); } return 0; } @@ -503,6 +502,12 @@ class Folder extends KTEntity { 'permission_lookup_id' => $iLookupID, ), array('multi' => true)); } + + function getByParentId($iParentID) { + return KTEntityUtil::getByDict('Folder', array( + 'parent_id' => $iParentID, + ), array('multi' => true)); + } // STATIC function &createFromArray($aOptions) { diff --git a/lib/ktentity.inc b/lib/ktentity.inc index 745a98e..fa4e777 100644 --- a/lib/ktentity.inc +++ b/lib/ktentity.inc @@ -26,8 +26,15 @@ * @package lib */ +$_LCASECACHE = array(); +$_OBJECTCACHE = array(); +$_RANDOMCALL = 0; +$_STOPCACHING = array(); + require_once(KT_LIB_DIR . '/cache/cache.inc.php'); +DEFINE("EVIL_CACHE_GRIND", false); + class KTEntity { var $_bUsePearError = false; /** object primary key */ @@ -41,18 +48,34 @@ class KTEntity { return array('getlist'); } - function clearCachedGroups() { - $groups = $this->_cachedGroups(); + function _innerClearCachedGroups($sClassName) { + if ($GLOBALS['_STOPCACHING'][$sClassName]) { + if ($GLOBALS['_STOPCACHING'][$sClassName] > 5) { + return; + } + } else { + $GLOBALS['_STOPCACHING'][$sClassName] = 0; + } + $group_func = array($sClassName, '_cachedGroups'); + $groups = call_user_func($group_func); + $groups[] = 'auto'; $oCache =& KTCache::getSingleton(); - $aSuffixes = array('', '_count', '_fullselect'); + $aSuffixes = array(''); // , '_count', '_fullselect'); foreach ($groups as $group_base) { global $default; foreach ($aSuffixes as $sSuffix) { - $group = sprintf("%s/%s%s", get_class($this), $group_base, $sSuffix); + $group = sprintf("%s/%s%s", $sClassName, $group_base, $sSuffix); $default->log->debug("Clearing cached group: $group"); $oCache->clear($group); } } + $GLOBALS['_STOPCACHING'][$sClassName]++; + + } + + function clearCachedGroups() { + $sClass = get_class($this); + $this->_innerClearCachedGroups($sClass); } /** @@ -143,27 +166,73 @@ class KTEntity { } function load($iId = null) { + global $default; if (is_null($iId)) { if (is_null($this->iId)) { return PEAR::raiseError("No ID given"); } $iId = $this->iId; } - $table = $this->_table(); - $select = $this->_getSqlSelection(); - $sQuery = "SELECT $select FROM $table WHERE id = ?"; - $aParams = array($iId); - - $res = DBUtil::getResultArray(array($sQuery, $aParams)); - - if (PEAR::isError($res)) { - return $res; - } - if (count($res) === 0) { - return PEAR::raiseError("No such ID: $iId"); - } - if (count($res) > 1) { - return PEAR::raiseError("Multiple matches for ID: $iId"); + $sClassName = get_class($this); + // cache at lowest possible level. + $oCache =& KTCache::getSingleton(); + $group = sprintf("%s/%s", $sClassName , 'id'); + list($bCached, $mCached) = $oCache->get($group, $iId); + if ($bCached && EVIL_CACHE_GRIND) { + $default->log->debug(sprintf("Found and testing object cache for class %s, id %d", $sClassName, $iId)); + + $table = $this->_table(); + $select = $this->_getSqlSelection(); + $sQuery = "SELECT $select FROM $table WHERE id = ?"; + $aParams = array($iId); + + $res = DBUtil::getResultArray(array($sQuery, $aParams)); + // we _have_ a cache: error is a disaster + if (PEAR::isError($res) || (count($res) === 0) || (count($res) > 1)) { + $oCache->alertFailure($sClassName, array('SERIOUS FAILURE: real object is an error, cache claims "valid".')); + return $res; + } + + // now compare the sub-values. + $aFailures = array(); + $sEntClass = get_class($this); + + foreach (array_keys($res) as $sKey => $sVal) { + if ($mCached[$sKey] != $res[$sKey]) { + $aFailures[] = $sKey; + } + } + + if (!empty($aFailures)) { + $oCache->alertFailure($sClassName, $aFailures); + } + + $res = $mCached; + } else if ($bCached) { + global $default; + $default->log->debug(sprintf("Using object cache for class %s, id %d", $sClassName, $iId)); + $res = $mCached; + /* */ + } else { + $default->log->debug(sprintf("No object cache for class %s, id %d", $sClassName, $iId)); + $table = $this->_table(); + $select = $this->_getSqlSelection(); + $sQuery = "SELECT $select FROM $table WHERE id = ?"; + $aParams = array($iId); + + $res = DBUtil::getResultArray(array($sQuery, $aParams)); + + if (PEAR::isError($res)) { + return $res; + } + if (count($res) === 0) { + return PEAR::raiseError("No such ID: $iId"); + } + + if (count($res) > 1) { + return PEAR::raiseError("Multiple matches for ID: $iId"); + } + $oCache->set($group, $iId, $res); // finally, cache if its "good". } $vk = array_flip($this->_aFieldToSelect); $aLoadInfo = array(); @@ -208,26 +277,43 @@ class KTEntity { // // If the element isn't in the case array, the method doesn't // exist. - + $sClassName = get_class($this); + + $aCache = KTUtil::arrayGet($GLOBALS['_LCASECACHE'], $sClassName); + + $sLowerElement = strtolower($sElement); + if ($aCache) { + $r = KTUtil::arrayGet($aCache['fieldnames'], $sLowerElement); + if ($r) { return $r; } + } + $array = array_keys($this->_aFieldToSelect); - foreach($array as $k) { - $case[strtolower($k)] = $k; + if (!$aCache) { + $case = array(); + foreach($array as $k) { + $case[strtolower($k)] = $k; + } + foreach($case as $k => $v) { + $case[substr($k, 1)] = $v; + } + } else { + $case = $aCache['fieldnames']; } - $sElement = strtolower($sElement); - - if (array_key_exists($sElement, $case)) { - return $case[strtolower($sElement)]; + //var_dump($case); + + if (!$aCache) { + $aCache = array(); + $aCache['fieldnames'] = $case; } - - foreach($array as $k) { - $case[substr(strtolower($k), 1)] = $k; + + $GLOBALS['_LCASECACHE'][$sClassName] =& $aCache; + + if (array_key_exists($sLowerElement, $case)) { + return $case[$sLowerElement]; } - if (array_key_exists($sElement, $case)) { - return $case[strtolower($sElement)]; - } return PEAR::raiseError("No such element"); } @@ -275,14 +361,29 @@ class KTEntityUtil { $bIDs = KTUtil::arrayGet($aOptions, "ids", false); $sIDField = 'id'; $cache = KTUtil::arrayGet($aOptions, 'cache', false); + + if (!$cache) { // && EVIL_CACHE_GRIND) { + $cache = 'auto'; + } + + if (isset($GLOBALS['_STOPCACHING'][$sClassName])) { + if ($GLOBALS['_STOPCACHING'][$sClassName] > 5) { + $cache = false; + } + } + + $fullselect = KTUtil::arrayGet($aOptions, 'fullselect', false); + if ($cache) { - if (is_array($sWhereClause)) { + if ($cache === 'auto') { + $vals = serialize($sWhereClause); + } else if (is_array($sWhereClause)) { $vals = serialize($sWhereClause[1]); } else { $vals = serialize($sWhereClause); } - $default->log->debug(sprintf("Trying object cache for class %s, %s: %s", $sClassName, $cache, $vals)); + $default->log->debug(sprintf("Trying list cache for class %s, %s: %s", $sClassName, $cache, $vals)); $oCache =& KTCache::getSingleton(); $suffix = ''; @@ -294,8 +395,63 @@ class KTEntityUtil { } else { $bCached = false; } + + if ($cache && !$bCached) { + global $default; + $default->log->debug(sprintf("No list cache for class %s, %s: %s", $sClassName, $cache, $vals)); + } + if ($bCached && EVIL_CACHE_GRIND) { + if (!empty($fullselect)) { + $oObject = new $sClassName; + $select = $oObject->_getSqlSelection(); + $sQuery = "SELECT $select FROM " . $sTable;/*ok*/ + } else { + $sIDField = KTUtil::arrayGet($aOptions, "idfield", 'id'); + $sQuery = "SELECT $sIDField FROM " . $sTable;/*ok*/ + } + $aParams = array(); + if (!is_null($sWhereClause)) { + if (is_string($sWhereClause)) { + if (substr($sWhereClause, 0, 5) != 'WHERE') { + if (substr($sWhereClause, 0, 5) != 'ORDER') { + $sQuery .= ' WHERE'; + } + } + $sQuery .= ' ' . $sWhereClause; + } else if (is_array($sWhereClause)) { + if (substr($sWhereClause[0], 0, 5) != 'WHERE') { + if (substr($sWhereClause[0], 0, 5) != 'ORDER') { + $sQuery .= ' WHERE'; + } + } + $sQuery .= ' ' . $sWhereClause[0]; + $aParams = $sWhereClause[1]; + } else { + return new PEAR_Error('Weird WhereClause passed'); + } + } + $sOrderBy = KTUtil::arrayGet($aOptions, 'orderby'); + if (!empty($sOrderBy)) { + $sQuery .= " ORDER BY " . $sOrderBy; + } - if ($bCached) { + if (!empty($fullselect)) { + $aIDs = DBUtil::getResultArray(array($sQuery, $aParams)); + } else { + $aIDs = DBUtil::getResultArrayKey(array($sQuery, $aParams), $sIDField); + } + // compare mcached == $aIds + + if ($aIDs != $mCached) { + /* + print "==================\n\n\n\n\n"; + var_dump($aIDs); + print "------\n"; + var_dump($mCached); + */ + $oCache->alertFailure($group, array('Stored IDS != Cache IDS')); + } + } else if ($bCached) { $default->log->debug(sprintf("Using object cache for class %s, %s: %s", $sClassName, $cache, $vals)); $aIDs = $mCached; /* */ @@ -401,15 +557,11 @@ class KTEntityUtil { if (PEAR::isError($ret)) { return $ret; } - $oCache =& KTCache::getSingleton(); - $group = sprintf("%s/%s", $sClassName, 'id'); - $oCache->set($group, $oObject->getId(), $oObject); return $oObject; } function &loadFromArrayMulti($sClassName, $aMultiArray, $aOptions = null) { $aRet = array(); - $oCache =& KTCache::getSingleton(); foreach ($aMultiArray as $aArray) { $oObject =& new $sClassName; $ret = $oObject->loadFromArray($aArray); @@ -417,28 +569,19 @@ class KTEntityUtil { return $ret; } $aRet[] = $oObject; - $group = sprintf("%s/%s", $sClassName, 'id'); - $oCache->set($group, $oObject->getId(), $oObject); } return $aRet; } function &get($sClassName, $iId) { - $oCache =& KTCache::getSingleton(); - $group = sprintf("%s/%s", $sClassName, 'id'); - list($bCached, $mCached) = $oCache->get($group, $iId); - if ($bCached) { - global $default; - $default->log->debug(sprintf("Using object cache for class %s, id %d", $sClassName, $iId)); - return $mCached; - /* */ - } + $oObject =& KTUtil::arrayGet($GLOBALS['_OBJECTCACHE'][$sClassName], $iId); + if ($oObject) { return $oObject; } $oObject =& new $sClassName; $res = $oObject->load($iId); if (PEAR::isError($res)) { return $res; } - $oCache->set($group, $iId, $oObject); + $GLOBALS['_OBJECTCACHE'][$sClassName][$iId] =& $oObject; return $oObject; } diff --git a/lib/permissions/permissiondescriptor.inc.php b/lib/permissions/permissiondescriptor.inc.php index d329ec6..59e17be 100644 --- a/lib/permissions/permissiondescriptor.inc.php +++ b/lib/permissions/permissiondescriptor.inc.php @@ -28,6 +28,10 @@ require_once(KT_LIB_DIR . "/ktentity.inc"); +$_PDGC = array(); +$_PDRC = array(); +$_PDUC = array(); + class KTPermissionDescriptor extends KTEntity { /** primary key */ var $iId = -1; @@ -142,6 +146,7 @@ class KTPermissionDescriptor extends KTEntity { // {{{ GROUPS // {{{ _clearGroups function _clearGroups() { + unset($GLOBALS['_PDGC'][$this->getId()]); $sTable = KTUtil::getTableName('permission_descriptor_groups'); $sQuery = "DELETE FROM $sTable WHERE descriptor_id = ?"; $aParams = array($this->getID()); @@ -188,10 +193,15 @@ class KTPermissionDescriptor extends KTEntity { // {{{ getGroups function getGroups() { + if (isset($GLOBALS['_PDGC'][$this->getId()])) { + return $GLOBALS['_PDGC'][$this->getId()]; + } $sTable = KTUtil::getTableName('permission_descriptor_groups'); $sQuery = "SELECT group_id FROM $sTable WHERE descriptor_id = ?"; $aParams = array($this->getID()); - return DBUtil::getResultArrayKey(array($sQuery, $aParams), 'group_id'); + $res = DBUtil::getResultArrayKey(array($sQuery, $aParams), 'group_id'); + $GLOBALS['_PDGC'][$this->getId()] = $res; + return $res; } // }}} @@ -245,6 +255,7 @@ class KTPermissionDescriptor extends KTEntity { // {{{ ROLES // {{{ _clearRoles function _clearRoles() { + unset($GLOBALS['_PDRC'][$this->getId()]); $sTable = KTUtil::getTableName('permission_descriptor_roles'); $sQuery = "DELETE FROM $sTable WHERE descriptor_id = ?"; $aParams = array($this->getID()); @@ -291,10 +302,15 @@ class KTPermissionDescriptor extends KTEntity { // {{{ getRoles function getRoles() { + if (isset($GLOBALS['_PDRC'][$this->getId()])) { + return $GLOBALS['_PDRC'][$this->getId()]; + } $sTable = KTUtil::getTableName('permission_descriptor_roles'); $sQuery = "SELECT role_id FROM $sTable WHERE descriptor_id = ?"; $aParams = array($this->getID()); - return DBUtil::getResultArrayKey(array($sQuery, $aParams), 'role_id'); + $res = DBUtil::getResultArrayKey(array($sQuery, $aParams), 'role_id'); + $GLOBALS['_PDRC'][$this->getId()] = $res; + return $res; } // }}} @@ -348,6 +364,7 @@ class KTPermissionDescriptor extends KTEntity { // {{{ USERS // {{{ _clearUsers function _clearUsers() { + unset($GLOBALS['_PDUC'][$this->getId()]); $sTable = KTUtil::getTableName('permission_descriptor_users'); $sQuery = "DELETE FROM $sTable WHERE descriptor_id = ?"; $aParams = array($this->getID()); @@ -394,10 +411,15 @@ class KTPermissionDescriptor extends KTEntity { // {{{ getUsers function getUsers() { + if (isset($GLOBALS['_PDUC'][$this->getId()])) { + return $GLOBALS['_PDUC'][$this->getId()]; + } $sTable = KTUtil::getTableName('permission_descriptor_users'); $sQuery = "SELECT user_id FROM $sTable WHERE descriptor_id = ?"; $aParams = array($this->getID()); - return DBUtil::getResultArrayKey(array($sQuery, $aParams), 'user_id'); + $res = DBUtil::getResultArrayKey(array($sQuery, $aParams), 'user_id'); + $GLOBALS['_PDUC'][$this->getId()] = $res; + return $res; } // }}} diff --git a/lib/permissions/permissionutil.inc.php b/lib/permissions/permissionutil.inc.php index 10b16e9..30a67c1 100644 --- a/lib/permissions/permissionutil.inc.php +++ b/lib/permissions/permissionutil.inc.php @@ -37,6 +37,7 @@ require_once(KT_LIB_DIR . "/permissions/permissionobject.inc.php"); require_once(KT_LIB_DIR . "/permissions/permissiondynamiccondition.inc.php"); require_once(KT_LIB_DIR . "/groups/GroupUtil.php"); require_once(KT_LIB_DIR . "/roles/roleallocation.inc.php"); +require_once(KT_LIB_DIR . "/roles/documentroleallocation.inc.php"); require_once(KT_LIB_DIR . "/workflow/workflowutil.inc.php"); require_once(KT_LIB_DIR . "/workflow/workflowstatepermissionsassignment.inc.php"); @@ -310,13 +311,22 @@ class KTPermissionUtil { foreach ($aAllowed['role'] as $iRoleId) { // store the PD <-> RoleId map if (!array_key_exists($iRoleId, $_roleCache)) { - $oRoleAllocation =& RoleAllocation::getAllocationsForFolderAndRole($iRoleSourceFolder, $iRoleId); + $oRoleAllocation = null; + if (is_a($oFolderOrDocument, 'KTDocumentCore') || is_a($oFolderOrDocument, 'Document')) { + $oRoleAllocation =& DocumentRoleAllocation::getAllocationsForDocumentAndRole($oFolderOrDocument->getId(), $iRoleId); + if (PEAR::isError($oRoleAllocation)) { $oRoleAllocation = null; } + } + // if that's null - not set _on_ the document, then + if (is_null($oRoleAllocation)) { + $oRoleAllocation =& RoleAllocation::getAllocationsForFolderAndRole($iRoleSourceFolder, $iRoleId); + } $_roleCache[$iRoleId] = $oRoleAllocation; } // roles are _not_ always assigned (can be null at root) - if ($_roleCache[$iRoleId] != null) { + if (!is_null($_roleCache[$iRoleId])) { $aMapPermAllowed[$iPermissionId]['user'] = array_merge($aAllowed['user'], $_roleCache[$iRoleId]->getUserIds()); $aMapPermAllowed[$iPermissionId]['group'] = array_merge($aAllowed['group'], $_roleCache[$iRoleId]->getGroupIds()); + // naturally, roles cannot be assigned roles, or madness follows. } } @@ -361,7 +371,8 @@ class KTPermissionUtil { } $oPD = KTPermissionDescriptor::get($oPLA->getPermissionDescriptorID()); $aGroups = GroupUtil::listGroupsForUserExpand($oUser); - return $oPD->hasGroups($aGroups); + if ($oPD->hasUsers(array($oUser))) { return true; } + else { return $oPD->hasGroups($aGroups); } } // }}} diff --git a/lib/plugins/pluginentity.inc.php b/lib/plugins/pluginentity.inc.php index 1e99f14..6e64e50 100644 --- a/lib/plugins/pluginentity.inc.php +++ b/lib/plugins/pluginentity.inc.php @@ -52,7 +52,7 @@ class KTPluginEntity extends KTEntity { } function _cachedGroups() { - return array('getList', 'getByNamespace'); + return array('getlist', 'getList', 'getByNamespace'); } // }}} @@ -80,13 +80,13 @@ class KTPluginEntity extends KTEntity { // STATIC function &getList($sWhereClause = null) { global $default; - $aOptions = array('fullselect' => true, 'cache' => 'getList'); + $aOptions = array('fullselect' => false, 'cache' => 'getList'); return KTEntityUtil::getList2('KTPluginEntity', $sWhereClause, $aOptions); } // STATIC function &getByNamespace($sName) { - $aOptions = array('fullselect' => true, 'cache' => 'getByNamespace'); + $aOptions = array('fullselect' => false, 'cache' => 'getByNamespace'); return KTEntityUtil::getBy('KTPluginEntity', 'namespace', $sName, $aOptions); } @@ -98,4 +98,14 @@ class KTPluginEntity extends KTEntity { return KTEntityUtil::getBy('KTPluginEntity', 'disabled', false, $aOptions); } + + function setEnabled($aIds) { + $sTable = KTPluginEntity::_table(); + $sIds = DBUtil::paramArray($aIds); + $sQuery = sprintf('UPDATE %s SET disabled = 1 WHERE id NOT IN (%s)', $sTable, $sIds); + DBUtil::runQuery(array($sQuery, $aIds)); + $sQuery = sprintf('UPDATE %s SET disabled = 0 WHERE id IN (%s)', $sTable, $sIds); + DBUtil::runQuery(array($sQuery, $aIds)); + KTPluginEntity::_innerClearCachedGroups('KTPluginEntity'); + } } diff --git a/lib/roles/roleallocation.inc.php b/lib/roles/roleallocation.inc.php index 5bf8950..f30e6de 100644 --- a/lib/roles/roleallocation.inc.php +++ b/lib/roles/roleallocation.inc.php @@ -66,6 +66,18 @@ class RoleAllocation extends KTEntity { $this->iPermissionDescriptorId = $oDescriptor->getId(); } + function getAllowed() { + if (!is_null($this->iPermissionDescriptorId)) { + $oDescriptor = KTPermissionDescriptor::get($this->iPermissionDescriptorId); // fully done, etc. + $aAllowed = $oDescriptor->getAllowed(); + } else { + $aAllowed = array(); + } + return $aAllowed; + } + + + function _fieldValues () { return array( 'role_id' => $this->iRoleId, 'folder_id' => $this->iFolderId, diff --git a/lib/storage/ondiskpathstoragemanager.inc.php b/lib/storage/ondiskpathstoragemanager.inc.php index 2efc1f3..266ab8a 100644 --- a/lib/storage/ondiskpathstoragemanager.inc.php +++ b/lib/storage/ondiskpathstoragemanager.inc.php @@ -73,7 +73,7 @@ class KTOnDiskPathStorageManager extends KTStorageManager { } function generateStoragePath(&$oDocument) { - $sStoragePath = sprintf("%s/%s-%s", KTDocumentCore::_generateFolderPath($oDocument->getFolderID()), $oDocument->getContentVersionId(), $oDocument->getFileName()); + $sStoragePath = sprintf("%s/%s-%s", Folder::generateFolderPath($oDocument->getFolderID()), $oDocument->getContentVersionId(), $oDocument->getFileName()); return $sStoragePath; } @@ -178,8 +178,8 @@ class KTOnDiskPathStorageManager extends KTStorageManager { $sDocumentRoot = $oConfig->get('urls/documentRoot'); foreach ($aContentVersions as $oVersion) { - $sOldPath = sprintf("%s/%s-%s", KTDocumentCore::_generateFolderPath($oSourceFolder->getID()), $oVersion->getId(), $oVersion->getFileName()); - $sNewPath = sprintf("%s/%s-%s", KTDocumentCore::_generateFolderPath($oDestinationFolder->getID()), $oVersion->getId(), $oVersion->getFileName()); + $sOldPath = sprintf("%s/%s-%s", Folder::generateFolderPath($oSourceFolder->getID()), $oVersion->getId(), $oVersion->getFileName()); + $sNewPath = sprintf("%s/%s-%s", Folder::generateFolderPath($oDestinationFolder->getID()), $oVersion->getId(), $oVersion->getFileName()); $sFullOldPath = sprintf("%s/%s", $sDocumentRoot, $sOldPath); $sFullNewPath = sprintf("%s/%s", $sDocumentRoot, $sNewPath); $res = KTUtil::moveFile($sFullOldPath, $sFullNewPath); @@ -322,8 +322,8 @@ class KTOnDiskPathStorageManager extends KTStorageManager { $oConfig =& KTConfig::getSingleton(); $sDocumentRoot = $oConfig->get('urls/documentRoot'); - $sOldPath = sprintf("%s/%s-%s", KTDocumentCore::_generateFolderPath($oDocument->getFolderID()), $oOldContentVersion->getId(), $oOldContentVersion->getFileName()); - $sNewPath = sprintf("%s/%s-%s", KTDocumentCore::_generateFolderPath($oDocument->getFolderID()), $oDocument->_oDocumentContentVersion->getId(), $sNewFilename); + $sOldPath = sprintf("%s/%s-%s", Folder::generateFolderPath($oDocument->getFolderID()), $oOldContentVersion->getId(), $oOldContentVersion->getFileName()); + $sNewPath = sprintf("%s/%s-%s", Folder::generateFolderPath($oDocument->getFolderID()), $oDocument->_oDocumentContentVersion->getId(), $sNewFilename); $sFullOldPath = sprintf("%s/%s", $sDocumentRoot, $sOldPath); $sFullNewPath = sprintf("%s/%s", $sDocumentRoot, $sNewPath); diff --git a/lib/templating/kt3template.inc.php b/lib/templating/kt3template.inc.php index 7351de1..59fea52 100644 --- a/lib/templating/kt3template.inc.php +++ b/lib/templating/kt3template.inc.php @@ -367,7 +367,7 @@ class KTPage { $microtime_simple = explode(' ', microtime()); $finaltime = (float) $microtime_simple[1] + (float) $microtime_simple[0]; - return ($finaltime - $GLOBALS['_KT_starttime']); + return sprintf("%.3f", ($finaltime - $GLOBALS['_KT_starttime'])); } } diff --git a/lib/widgets/portlet.inc.php b/lib/widgets/portlet.inc.php index e981aa9..f0a4a3c 100644 --- a/lib/widgets/portlet.inc.php +++ b/lib/widgets/portlet.inc.php @@ -46,6 +46,8 @@ class KTPortlet { } function setPlugin(&$oPlugin) { + global $default; + $default->log->debug('portlet regging plugin: ' . $oPlugin->sNamespace); $this->oPlugin =& $oPlugin; } diff --git a/plugins/ktcore/KTCorePlugin.php b/plugins/ktcore/KTCorePlugin.php index 17d8a07..f6c70a4 100644 --- a/plugins/ktcore/KTCorePlugin.php +++ b/plugins/ktcore/KTCorePlugin.php @@ -58,6 +58,7 @@ class KTCorePlugin extends KTPlugin { // Permissions $this->registerAction('documentaction', 'KTDocumentPermissionsAction', 'ktcore.actions.document.permissions', 'KTPermissions.php'); $this->registerAction('folderaction', 'KTRoleAllocationPlugin', 'ktcore.actions.folder.roles', 'KTPermissions.php'); + $this->registerAction('documentaction', 'KTDocumentRolesAction', 'ktcore.actions.document.roles', 'KTPermissions.php'); $this->registerDashlet('KTInfoDashlet', 'ktcore.dashlet.info', 'KTDashlets.php'); $this->registerDashlet('KTNotificationDashlet', 'ktcore.dashlet.notifications', 'KTDashlets.php'); diff --git a/plugins/ktcore/KTPermissions.php b/plugins/ktcore/KTPermissions.php index 67c8460..e51da90 100644 --- a/plugins/ktcore/KTPermissions.php +++ b/plugins/ktcore/KTPermissions.php @@ -35,10 +35,12 @@ require_once(KT_LIB_DIR . "/groups/Group.inc"); require_once(KT_LIB_DIR . "/users/User.inc"); require_once(KT_LIB_DIR . "/roles/Role.inc"); require_once(KT_LIB_DIR . "/roles/roleallocation.inc.php"); +require_once(KT_LIB_DIR . "/roles/documentroleallocation.inc.php"); require_once(KT_LIB_DIR . "/permissions/permission.inc.php"); require_once(KT_LIB_DIR . "/permissions/permissionobject.inc.php"); +require_once(KT_LIB_DIR . "/permissions/permissionlookup.inc.php"); require_once(KT_LIB_DIR . "/permissions/permissionassignment.inc.php"); require_once(KT_LIB_DIR . "/permissions/permissiondescriptor.inc.php"); require_once(KT_LIB_DIR . "/permissions/permissionutil.inc.php"); @@ -52,52 +54,87 @@ class KTDocumentPermissionsAction extends KTDocumentAction { } function do_main() { - $this->oPage->setBreadcrumbDetails("permissions"); - + $this->oPage->setBreadcrumbDetails("Document Permissions"); $oTemplate = $this->oValidator->validateTemplate("ktcore/document/document_permissions"); - $oPO = KTPermissionObject::get($this->oDocument->getPermissionObjectID()); + + $oPL = KTPermissionLookup::get($this->oDocument->getPermissionLookupID()); $aPermissions = KTPermission::getList(); $aMapPermissionGroup = array(); - $aMapPermissionRole = array(); + $aMapPermissionRole = array(); + $aMapPermissionUser = array(); + + $aAllGroups = Group::getList(); // probably small enough + $aAllRoles = Role::getList(); // probably small enough. + // users are _not_ fetched this way. + + $aActiveGroups = array(); + $aActiveUsers = array(); + $aActiveRoles = array(); + foreach ($aPermissions as $oPermission) { - $oPA = KTPermissionAssignment::getByPermissionAndObject($oPermission, $oPO); - if (PEAR::isError($oPA)) { + $oPLA = KTPermissionLookupAssignment::getByPermissionAndLookup($oPermission, $oPL); + if (PEAR::isError($oPLA)) { continue; } - $oDescriptor = KTPermissionDescriptor::get($oPA->getPermissionDescriptorID()); + $oDescriptor = KTPermissionDescriptor::get($oPLA->getPermissionDescriptorID()); $iPermissionID = $oPermission->getID(); $aIDs = $oDescriptor->getGroups(); $aMapPermissionGroup[$iPermissionID] = array(); foreach ($aIDs as $iID) { $aMapPermissionGroup[$iPermissionID][$iID] = true; + $aActiveGroups[$iID] = true; } $aIds = $oDescriptor->getRoles(); $aMapPermissionRole[$iPermissionID] = array(); foreach ($aIds as $iId) { $aMapPermissionRole[$iPermissionID][$iId] = true; + $aActiveRoles[$iId] = true; + } + $aIds = $oDescriptor->getUsers(); + $aMapPermissionUser[$iPermissionID] = array(); + foreach ($aIds as $iId) { + $aMapPermissionUser[$iPermissionID][$iId] = true; + $aActiveUsers[$iId] = true; } } + + // now we constitute the actual sets. + $users = array(); + $groups = array(); + $roles = array(); // should _always_ be empty, barring a bug in permissions::updatePermissionLookup - $oInherited = KTPermissionUtil::findRootObjectForPermissionObject($oPO); - if ($oInherited === $this->oDocument) { - $bEdit = true; - } else { - $iInheritedFolderID = $oInherited->getID(); - /* $sInherited = displayFolderPathLink(Folder::getFolderPathAsArray($iInheritedFolderID), - Folder::getFolderPathNamesAsArray($iInheritedFolderID), - "$default->rootUrl/control.php?action=editFolderPermissions");*/ - $sInherited = join(" » ", $oInherited->getPathArray()); - $bEdit = false; - } + // this should be quite limited - direct role -> user assignment is typically rare. + foreach ($aActiveUsers as $id => $marker) { + $oUser = User::get($id); + $users[$oUser->getName()] = $oUser; + } + asort($users); // ascending, per convention. + + foreach ($aActiveGroups as $id => $marker) { + $oGroup = Group::get($id); + $groups[$oGroup->getName()] = $oGroup; + } + asort($groups); + + foreach ($aActiveRoles as $id => $marker) { + $oRole = Role::get($id); + $roles[$oRole->getName()] = $oRole; + } + asort($roles); + + $bEdit = false; + $sInherited = ''; $aTemplateData = array( "context" => $this, "permissions" => $aPermissions, - "groups" => Group::getList(), - "roles" => Role::getList(), + "groups" => $groups, + "users" => $users, + "roles" => $roles, "iDocumentID" => $_REQUEST['fDocumentID'], "aMapPermissionGroup" => $aMapPermissionGroup, "aMapPermissionRole" => $aMapPermissionRole, + "aMapPermissionUser" => $aMapPermissionUser, "edit" => $bEdit, "inherited" => $sInherited, ); @@ -509,3 +546,93 @@ class KTRoleAllocationPlugin extends KTFolderAction { } } } + +class KTDocumentRolesAction extends KTDocumentAction { + var $sDisplayName = 'View Roles'; + var $sName = 'ktcore.actions.document.roles'; + + var $_sShowPermission = "ktcore.permissions.write"; + var $bAutomaticTransaction = true; + + function do_main() { + $this->oPage->setTitle(_("View Roles")); + $this->oPage->setBreadcrumbDetails(_("View Roles")); + $oTemplating = new KTTemplating; + $oTemplate = $oTemplating->loadTemplate("ktcore/action/view_roles"); + + // we need to have: + // - a list of roles + // - with their users / groups + // - and that allocation id + $aRoles = array(); // stores data for display. + + $aRoleList = Role::getList(); + foreach ($aRoleList as $oRole) { + $iRoleId = $oRole->getId(); + $aRoles[$iRoleId] = array("name" => $oRole->getName()); + $oRoleAllocation = DocumentRoleAllocation::getAllocationsForDocumentAndRole($this->oDocument->getId(), $iRoleId); + if (is_null($oRoleAllocation)) { + $oRoleAllocation = RoleAllocation::getAllocationsForFolderAndRole($this->oDocument->getFolderID(), $iRoleId); + } + + $u = array(); + $g = array(); + $aid = null; + $raid = null; + if (is_null($oRoleAllocation)) { + ; // nothing. + } else { + //var_dump($oRoleAllocation); + $raid = $oRoleAllocation->getId(); // real_alloc_id + $aAllowed = $oRoleAllocation->getAllowed(); + + if (!empty($aAllowed['user'])) { + $u = $aAllowed['user']; + } + if (!empty($aAllowed['group'])) { + $g = $aAllowed['group']; + } + } + $aRoles[$iRoleId]['users'] = $u; + $aRoles[$iRoleId]['groups'] = $g; + $aRoles[$iRoleId]['real_allocation_id'] = $raid; + } + + // final step. + + // map to users, groups. + foreach ($aRoles as $key => $role) { + $_users = array(); + foreach ($aRoles[$key]['users'] as $iUserId) { + $oUser = User::get($iUserId); + if (!(PEAR::isError($oUser) || ($oUser == false))) { + $_users[] = $oUser->getName(); + } + } + if (empty($_users)) { + $aRoles[$key]['users'] = ' ' . _('no users') . ''; + } else { + $aRoles[$key]['users'] = implode(', ',$_users); + } + + $_groups = array(); + foreach ($aRoles[$key]['groups'] as $iGroupId) { + $oGroup = Group::get($iGroupId); + if (!(PEAR::isError($oGroup) || ($oGroup == false))) { + $_groups[] = $oGroup->getName(); + } + } + if (empty($_groups)) { + $aRoles[$key]['groups'] = ' ' . _('no groups') . ''; + } else { + $aRoles[$key]['groups'] = implode(', ',$_groups); + } + } + + $aTemplateData = array( + 'context' => &$this, + 'roles' => $aRoles, + ); + return $oTemplate->render($aTemplateData); + } +} \ No newline at end of file diff --git a/plugins/ktcore/admin/plugins.php b/plugins/ktcore/admin/plugins.php index 1b4c4ec..3c64e74 100755 --- a/plugins/ktcore/admin/plugins.php +++ b/plugins/ktcore/admin/plugins.php @@ -63,12 +63,8 @@ class KTPluginDispatcher extends KTAdminDispatcher { function do_update() { $sTable = KTUtil::getTableName('plugins'); - $aIds = KTUtil::arrayGet($_REQUEST, 'pluginids'); - $sIds = DBUtil::paramArray($aIds); - $sQuery = sprintf('UPDATE %s SET disabled = 1 WHERE id NOT IN (%s)', $sTable, $sIds); - DBUtil::runQuery(array($sQuery, $aIds)); - $sQuery = sprintf('UPDATE %s SET disabled = 0 WHERE id IN (%s)', $sTable, $sIds); - DBUtil::runQuery(array($sQuery, $aIds)); + $aIds = (array) KTUtil::arrayGet($_REQUEST, 'pluginids'); + KTPluginEntity::setEnabled($aIds); $this->successRedirectToMain('Plugins updated'); } diff --git a/resources/js/toggleselect.js b/resources/js/toggleselect.js index 7235dba..0554448 100644 --- a/resources/js/toggleselect.js +++ b/resources/js/toggleselect.js @@ -20,6 +20,7 @@ function toggleSelectFor(source, nameprefix) { if (c.type == 'checkbox') { if ((n.length >= nameprefix.length) && (nameprefix == n.substring(0,nameprefix.length))) { c.checked = state; + activateRow(c); } } } diff --git a/templates/ktcore/document/document_permissions.smarty b/templates/ktcore/document/document_permissions.smarty index c5139da..9debfcc 100644 --- a/templates/ktcore/document/document_permissions.smarty +++ b/templates/ktcore/document/document_permissions.smarty @@ -1,31 +1,15 @@
{i18n}No roles or groups have been defined. Permissions can only -be allocated to roles and groups.{/i18n}
{i18n}This page shows the permissions that apply to +this specific document. Where the folder view shows you information by role and group, +this page shows the actual groups (and, if they are assigned directly to a role, the users) +who have the different permissions. As a result, groups, users and roles with no +permissions are not shown.{/i18n}
+ +{if ((empty($roles) && empty($groups) && empty($users)))} +{i18n}No roles or groups have been defined or have permissions.{/i18n}
{i18n arg_permission_source=$inherited}This folder inherits its permissions from #permission_source#.{/i18n} -{i18n}Override Permissions{/i18n}
-{ else } -{i18n}This folder defines its own permissions.{/i18n} -{i18n}Inherit permissions{/i18n} -{ /if } - -