Commit 840b2ee01352c539ff8aad551c20cb1e57de51e3

Authored by Brad Shuttleworth
1 parent 8ca4a168

- add and enable caching (properly)

- enable document roles (DOUBLE CHECK YOUR DB)
- fix minor toggleselect bug.


git-svn-id: https://kt-dms.svn.sourceforge.net/svnroot/kt-dms/trunk@5125 c91229c3-7414-0410-bfa2-8a42b809f60b
config/cache-path 0 → 100644
  1 +var/cache
config/config.ini
@@ -3,6 +3,8 @@ @@ -3,6 +3,8 @@
3 ; db section. 3 ; db section.
4 ; ---------------------------------------------------------------- 4 ; ----------------------------------------------------------------
5 5
  6 +; logLevel = DEBUG
  7 +
6 [db] 8 [db]
7 ; The Database Engine to use. Currently mysql is the only 9 ; The Database Engine to use. Currently mysql is the only
8 ; supported type. 10 ; supported type.
@@ -25,6 +27,7 @@ dbAdminPass = js9281djw @@ -25,6 +27,7 @@ dbAdminPass = js9281djw
25 ; need to, as you may introduce errors in your system. 27 ; need to, as you may introduce errors in your system.
26 ; ---------------------------------------------------------------- 28 ; ----------------------------------------------------------------
27 29
  30 +
28 ; install path (file path) 31 ; install path (file path)
29 ; 32 ;
30 ; Leave as default to have it automatically detected. 33 ; Leave as default to have it automatically detected.
@@ -168,4 +171,4 @@ restrictAdminPasswords = default @@ -168,4 +171,4 @@ restrictAdminPasswords = default
168 171
169 [cache] 172 [cache]
170 cacheDirectory = ${varDirectory}/cache 173 cacheDirectory = ${varDirectory}/cache
171 -cacheEnabled = false 174 +cacheEnabled = true
config/dmsDefaults.php
@@ -23,6 +23,9 @@ @@ -23,6 +23,9 @@
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 */ 24 */
25 25
  26 +// DEBUG DEBUG DEBUG APD
  27 +//if (extension_loaded('APD')) { apd_set_pprof_trace(); }
  28 +
26 // Default settings differ, we need some of these, so force the matter. 29 // Default settings differ, we need some of these, so force the matter.
27 // Can be overridden here if actually necessary. 30 // Can be overridden here if actually necessary.
28 error_reporting(E_ALL & ~E_NOTICE); 31 error_reporting(E_ALL & ~E_NOTICE);
@@ -54,6 +57,8 @@ if (!defined('PATH_SEPARATOR')) { @@ -54,6 +57,8 @@ if (!defined('PATH_SEPARATOR')) {
54 } 57 }
55 } 58 }
56 59
  60 +require_once(KT_LIB_DIR . '/Log.inc');
  61 +
57 // {{{ KTInit 62 // {{{ KTInit
58 class KTInit { 63 class KTInit {
59 // {{{ prependPath() 64 // {{{ prependPath()
@@ -350,6 +355,84 @@ class KTInit { @@ -350,6 +355,84 @@ class KTInit {
350 return ""; 355 return "";
351 } 356 }
352 // }}} 357 // }}}
  358 +
  359 + // {{{ initConfig
  360 + function initConfig() {
  361 + global $default;
  362 + $use_cache = false;
  363 + $store_cache = false;
  364 + if (file_exists(KT_DIR . "/config/cache-path")) {
  365 + $store_cache = true;
  366 + $user = KTLegacyLog::running_user();
  367 + $cache_file = trim(file_get_contents(KT_DIR . "/config/cache-path")) . '/configcache' . $user;
  368 + if (!KTUtil::isAbsolutePath($cache_file)) { $cache_file = sprintf("%s/%s", KT_DIR, $cache_file); }
  369 + $config_file = trim(file_get_contents(KT_DIR . "/config/config-path"));
  370 + if (!KTUtil::isAbsolutePath($config_file)) { $config_file = sprintf("%s/%s", KT_DIR, $config_file); }
  371 +
  372 + $exists = file_exists($cache_file);
  373 + if ($exists) {
  374 + $cachestat = stat($cache_file);
  375 + $configstat = stat($config_file);
  376 + $tval = 9;
  377 + // print sprintf("is %d > %d\n", $cachestat[$tval], $configstat[$tval]);
  378 + if ($cachestat[$tval] > $configstat[$tval]) {
  379 + $use_cache = true;
  380 + }
  381 + }
  382 +
  383 +
  384 + }
  385 +
  386 + if ($use_cache) {
  387 + $oKTConfig =& KTConfig::getSingleton();
  388 + $oKTConfig->loadCache($cache_file);
  389 +
  390 + foreach ($oKTConfig->flat as $k => $v) {
  391 + $default->$k = $v;
  392 + }
  393 + } else {
  394 + $oKTConfig =& KTConfig::getSingleton();
  395 +
  396 + $oKTConfig->setdefaultns("KnowledgeTree", "fileSystemRoot", KT_DIR);
  397 + $oKTConfig->setdefaultns("KnowledgeTree", "serverName", KTUtil::arrayGet($_SERVER, 'HTTP_HOST', 'localhost'));
  398 + $oKTConfig->setdefaultns("KnowledgeTree", "sslEnabled", false);
  399 + if (array_key_exists('HTTPS', $_SERVER)) {
  400 + if (strtolower($_SERVER['HTTPS']) === 'on') {
  401 + $oKTConfig->setdefaultns("KnowledgeTree", "sslEnabled", true);
  402 + }
  403 + }
  404 + $oKTConfig->setdefaultns("KnowledgeTree", "rootUrl", $this->guessRootUrl());
  405 + $oKTConfig->setdefaultns("KnowledgeTree", "execSearchPath", $_SERVER['PATH']);
  406 + $oKTConfig->setdefaultns("KnowledgeTree", "pathInfoSupport", false);
  407 + $oKTConfig->setdefaultns("storage", "manager", 'KTOnDiskPathStorageManager');
  408 + $oKTConfig->setdefaultns("config", "useDatabaseConfiguration", false);
  409 + $oKTConfig->setdefaultns("tweaks", "browseToUnitFolder", false);
  410 + $oKTConfig->setdefaultns("tweaks", "genericMetaDataRequired", true);
  411 + $oKTConfig->setdefaultns("tweaks", "phpErrorLogFile", false);
  412 + $oKTConfig->setdefaultns("tweaks", "developmentWindowLog", false);
  413 +
  414 + $oKTConfig->setdefaultns("user_prefs", "passwordLength", 6);
  415 + $oKTConfig->setdefaultns("user_prefs", "restrictAdminPasswords", false);
  416 +
  417 + $oKTConfig->setdefaultns("ui", "ieGIF", true);
  418 + $oKTConfig->setdefaultns("ui", "alwaysShowAll", false);
  419 + $oKTConfig->setdefaultns("ui", "condensedAdminUI", false);
  420 +
  421 + $oKTConfig->setdefaultns(null, "logLevel", 'INFO');
  422 + $oKTConfig->setdefaultns("import", "unzip", 'unzip');
  423 + $oKTConfig->setdefaultns("cache", "cacheDirectory", '${varDirectory}/cache');
  424 + $oKTConfig->setdefaultns("cache", "cacheEnabled", 'false');
  425 +
  426 + $this->readConfig();
  427 +
  428 + $oKTConfig =& KTConfig::getSingleton();
  429 + if ($store_cache) { $oKTConfig->createCache($cache_file);}
  430 +
  431 +
  432 + }
  433 + }
  434 + // }}}
  435 +
353 // {{{ readConfig 436 // {{{ readConfig
354 function readConfig () { 437 function readConfig () {
355 global $default; 438 global $default;
@@ -367,6 +450,7 @@ class KTInit { @@ -367,6 +450,7 @@ class KTInit {
367 } 450 }
368 if ($v === "false") { 451 if ($v === "false") {
369 $v = false; 452 $v = false;
  453 +
370 } 454 }
371 if ($v === "true") { 455 if ($v === "true") {
372 $v = true; 456 $v = true;
@@ -397,40 +481,8 @@ require_once(KT_LIB_DIR . '/util/ktutil.inc'); @@ -397,40 +481,8 @@ require_once(KT_LIB_DIR . '/util/ktutil.inc');
397 481
398 require_once(KT_LIB_DIR . "/config/config.inc.php"); 482 require_once(KT_LIB_DIR . "/config/config.inc.php");
399 483
  484 +$KTInit->initConfig();
400 $oKTConfig =& KTConfig::getSingleton(); 485 $oKTConfig =& KTConfig::getSingleton();
401 -  
402 -$oKTConfig->setdefaultns("KnowledgeTree", "fileSystemRoot", KT_DIR);  
403 -$oKTConfig->setdefaultns("KnowledgeTree", "serverName", KTUtil::arrayGet($_SERVER, 'HTTP_HOST', 'localhost'));  
404 -$oKTConfig->setdefaultns("KnowledgeTree", "sslEnabled", false);  
405 -if (array_key_exists('HTTPS', $_SERVER)) {  
406 - if (strtolower($_SERVER['HTTPS']) === 'on') {  
407 - $oKTConfig->setdefaultns("KnowledgeTree", "sslEnabled", true);  
408 - }  
409 -}  
410 -$oKTConfig->setdefaultns("KnowledgeTree", "rootUrl", $KTInit->guessRootUrl());  
411 -$oKTConfig->setdefaultns("KnowledgeTree", "execSearchPath", $_SERVER['PATH']);  
412 -$oKTConfig->setdefaultns("KnowledgeTree", "pathInfoSupport", false);  
413 -$oKTConfig->setdefaultns("storage", "manager", 'KTOnDiskPathStorageManager');  
414 -$oKTConfig->setdefaultns("config", "useDatabaseConfiguration", false);  
415 -$oKTConfig->setdefaultns("tweaks", "browseToUnitFolder", false);  
416 -$oKTConfig->setdefaultns("tweaks", "genericMetaDataRequired", true);  
417 -$oKTConfig->setdefaultns("tweaks", "phpErrorLogFile", false);  
418 -$oKTConfig->setdefaultns("tweaks", "developmentWindowLog", false);  
419 -  
420 -$oKTConfig->setdefaultns("user_prefs", "passwordLength", 6);  
421 -$oKTConfig->setdefaultns("user_prefs", "restrictAdminPasswords", false);  
422 -  
423 -$oKTConfig->setdefaultns("ui", "ieGIF", true);  
424 -$oKTConfig->setdefaultns("ui", "alwaysShowAll", false);  
425 -$oKTConfig->setdefaultns("ui", "condensedAdminUI", false);  
426 -  
427 -$oKTConfig->setdefaultns(null, "logLevel", 'INFO');  
428 -$oKTConfig->setdefaultns("import", "unzip", 'unzip');  
429 -$oKTConfig->setdefaultns("cache", "cacheDirectory", '${varDirectory}/cache');  
430 -$oKTConfig->setdefaultns("cache", "cacheEnabled", 'false');  
431 -  
432 -$KTInit->readConfig();  
433 -  
434 $KTInit->setupServerVariables(); 486 $KTInit->setupServerVariables();
435 487
436 // instantiate log 488 // instantiate log
config/tableMappings.inc
@@ -143,6 +143,7 @@ $default->notifications_table = "notifications"; @@ -143,6 +143,7 @@ $default->notifications_table = "notifications";
143 $default->authentication_sources_table = "authentication_sources"; 143 $default->authentication_sources_table = "authentication_sources";
144 $default->dashlet_disable_table = "dashlet_disables"; 144 $default->dashlet_disable_table = "dashlet_disables";
145 $default->role_allocations_table = "role_allocations"; 145 $default->role_allocations_table = "role_allocations";
  146 +$default->document_role_allocations_table = "document_role_allocations";
146 $default->plugins_table = "plugins"; 147 $default->plugins_table = "plugins";
147 $default->document_metadata_version_table = "document_metadata_version"; 148 $default->document_metadata_version_table = "document_metadata_version";
148 $default->document_content_version_table = "document_content_version"; 149 $default->document_content_version_table = "document_content_version";
lib/cache/cache.inc.php
@@ -10,6 +10,15 @@ class KTCache { @@ -10,6 +10,15 @@ class KTCache {
10 } 10 }
11 // }}} 11 // }}}
12 12
  13 + // takes an Entity type-name, and an array of the failed attrs.
  14 + function alertFailure($sEntityType, $aFail) {
  15 + //var_dump($aFail);
  16 + $sMessage = sprintf('Failure in cache-comparison on type "%s": %s', $sEntityType, implode(', ', $aFail));
  17 + global $default;
  18 + $default->log->error($sMessage);
  19 + $_SESSION['KTErrorMessage'][] = $sMessage;
  20 + }
  21 +
13 function KTCache() { 22 function KTCache() {
14 require_once("Cache/Lite.php"); 23 require_once("Cache/Lite.php");
15 require_once(KT_LIB_DIR . '/config/config.inc.php'); 24 require_once(KT_LIB_DIR . '/config/config.inc.php');
lib/config/config.inc.php
@@ -37,6 +37,38 @@ class KTConfig { @@ -37,6 +37,38 @@ class KTConfig {
37 var $flat = array(); 37 var $flat = array();
38 var $flatns = array(); 38 var $flatns = array();
39 39
  40 + // FIXME nbm: how do we cache errors here?
  41 + function loadCache($filename) {
  42 + $config_str = file_get_contents($filename);
  43 + $config_cache = unserialize($config_str);
  44 + $this->flat = $config_cache['flat'];
  45 + $this->flatns = $config_cache['flatns'];
  46 + $this->expanded = $config_cache['expanded'];
  47 + $this->expanding = $config_cache['expanding'];
  48 + /*
  49 + print "----- Me\n";
  50 + unset($this->aFileRoot);
  51 + unset($this->aSectionFile);
  52 + var_dump($this);
  53 + print "----- Cache\n";
  54 + var_dump($config_cache);
  55 + */
  56 +
  57 + return true;
  58 + }
  59 +
  60 + function createCache($filename) {
  61 + $config_cache = array();
  62 + $config_cache['flat'] = $this->flat;
  63 + $config_cache['flatns'] = $this->flatns;
  64 + $config_cache['expanded'] = $this->expanded;
  65 + $config_cache['expanding'] = $this->expanding;
  66 +
  67 + file_put_contents($filename, serialize($config_cache));
  68 +
  69 +
  70 + }
  71 +
40 function loadFile($filename, $bDefault = false) { 72 function loadFile($filename, $bDefault = false) {
41 $c = new Config; 73 $c = new Config;
42 $root =& $c->parseConfig($filename, "IniCommented"); 74 $root =& $c->parseConfig($filename, "IniCommented");
lib/documentmanagement/Document.inc
@@ -69,6 +69,9 @@ class Document { @@ -69,6 +69,9 @@ class Document {
69 function getCreatorID() { return $this->_oDocumentCore->getCreatorId(); } 69 function getCreatorID() { return $this->_oDocumentCore->getCreatorId(); }
70 function setCreatorID($iNewValue) { $this->_oDocumentCore->setCreatorId($iNewValue); } 70 function setCreatorID($iNewValue) { $this->_oDocumentCore->setCreatorId($iNewValue); }
71 71
  72 + function getOwnerID() { return $this->_oDocumentCore->getOwnerId(); }
  73 + function setOwnerID($iNewValue) { $this->_oDocumentCore->setOwnerId($iNewValue); }
  74 +
72 function getLastModifiedDate() { return $this->_oDocumentCore->getLastModifiedDate(); } 75 function getLastModifiedDate() { return $this->_oDocumentCore->getLastModifiedDate(); }
73 function setLastModifiedDate($dNewValue) { $this->_oDocumentCore->setLastModifiedDate($dNewValue); } 76 function setLastModifiedDate($dNewValue) { $this->_oDocumentCore->setLastModifiedDate($dNewValue); }
74 77
@@ -418,6 +421,7 @@ class Document { @@ -418,6 +421,7 @@ class Document {
418 $oDocument = new Document(); 421 $oDocument = new Document();
419 $aOptions = array_change_key_case($aOptions); 422 $aOptions = array_change_key_case($aOptions);
420 423
  424 +
421 $aCoreKeys = array( 425 $aCoreKeys = array(
422 "CreatorId", 426 "CreatorId",
423 "Created", 427 "Created",
lib/documentmanagement/documentcore.inc.php
@@ -73,6 +73,7 @@ class KTDocumentCore extends KTEntity { @@ -73,6 +73,7 @@ class KTDocumentCore extends KTEntity {
73 73
74 // transaction-related 74 // transaction-related
75 "iCreatorId" => 'creator_id', 75 "iCreatorId" => 'creator_id',
  76 +
76 "dCreated" => 'created', 77 "dCreated" => 'created',
77 "iModifiedUserId" => 'modified_user_id', 78 "iModifiedUserId" => 'modified_user_id',
78 "dModified" => 'modified', 79 "dModified" => 'modified',
@@ -92,6 +93,7 @@ class KTDocumentCore extends KTEntity { @@ -92,6 +93,7 @@ class KTDocumentCore extends KTEntity {
92 // permission-related 93 // permission-related
93 "iPermissionObjectId" => 'permission_object_id', 94 "iPermissionObjectId" => 'permission_object_id',
94 "iPermissionLookupId" => 'permission_lookup_id', 95 "iPermissionLookupId" => 'permission_lookup_id',
  96 + "iOwnerId" => 'owner_id',
95 ); 97 );
96 98
97 function KTDocument() { 99 function KTDocument() {
@@ -100,6 +102,8 @@ class KTDocumentCore extends KTEntity { @@ -100,6 +102,8 @@ class KTDocumentCore extends KTEntity {
100 // {{{ getters/setters 102 // {{{ getters/setters
101 function getCreatorId() { return $this->iCreatorId; } 103 function getCreatorId() { return $this->iCreatorId; }
102 function setCreatorId($iNewValue) { $this->iCreatorId = $iNewValue; } 104 function setCreatorId($iNewValue) { $this->iCreatorId = $iNewValue; }
  105 + function getOwnerId() { return $this->iOwnerId; }
  106 + function setOwnerId($iNewValue) { $this->iOwnerId = $iNewValue; }
103 function getCreatedDateTime() { return $this->dCreated; } 107 function getCreatedDateTime() { return $this->dCreated; }
104 function getModifiedUserId() { return $this->iModifiedUserId; } 108 function getModifiedUserId() { return $this->iModifiedUserId; }
105 function setModifiedUserId($iNewValue) { $this->iModifiedUserId = $iNewValue; } 109 function setModifiedUserId($iNewValue) { $this->iModifiedUserId = $iNewValue; }
@@ -142,28 +146,11 @@ class KTDocumentCore extends KTEntity { @@ -142,28 +146,11 @@ class KTDocumentCore extends KTEntity {
142 146
143 // {{{ ktentity requirements 147 // {{{ ktentity requirements
144 function _fieldValues () { 148 function _fieldValues () {
145 - $this->sFullPath = KTDocumentCore::_generateFolderPath($this->iFolderId);  
146 - $this->sParentFolderIds = KTDocumentCore::_generateFolderIds($this->iFolderId); 149 + $this->sFullPath = Folder::generateFolderPath($this->iFolderId);
  150 + $this->sParentFolderIds = Folder::generateFolderIds($this->iFolderId);
147 return parent::_fieldValues(); 151 return parent::_fieldValues();
148 } 152 }
149 153
150 - /**  
151 - * Recursive function to generate a comma delimited string containing  
152 - * the parent folder ids  
153 - *  
154 - * @return String comma delimited string containing the parent folder ids  
155 - */  
156 - function _generateParentFolderIds($iFolderId) {  
157 - $sTable = KTUtil::getTableName('folders');  
158 - if (empty($iFolderId)) {  
159 - return;  
160 - }  
161 -  
162 - $sQuery = sprintf('SELECT parent_id FROM %s WHERE id = ?', $sTable);  
163 - $aParams = array($iFolderId);  
164 - $iParentId = DBUtil::getOneResultKey(array($sQuery, $aParams), 'parent_id');  
165 - return KTDocumentCore::_generateParentFolderIds($iParentId) . ",$iFolderId";  
166 - }  
167 154
168 /** 155 /**
169 * Returns a comma delimited string containing the parent folder ids, strips leading / 156 * Returns a comma delimited string containing the parent folder ids, strips leading /
@@ -195,9 +182,12 @@ class KTDocumentCore extends KTEntity { @@ -195,9 +182,12 @@ class KTDocumentCore extends KTEntity {
195 * Returns a forward slash deliminated string giving full path of document, strips leading / 182 * Returns a forward slash deliminated string giving full path of document, strips leading /
196 */ 183 */
197 function _generateFolderPath($iFolderId) { 184 function _generateFolderPath($iFolderId) {
  185 + return Folder::generateFolderPath($iFolderId);
  186 +/*
198 $sPath = KTDocumentCore::_generateFullFolderPath($iFolderId); 187 $sPath = KTDocumentCore::_generateFullFolderPath($iFolderId);
199 $sPath = substr($sPath, 1, strlen($sPath)); 188 $sPath = substr($sPath, 1, strlen($sPath));
200 return $sPath; 189 return $sPath;
  190 +*/
201 } 191 }
202 // }}} 192 // }}}
203 193
@@ -212,6 +202,9 @@ class KTDocumentCore extends KTEntity { @@ -212,6 +202,9 @@ class KTDocumentCore extends KTEntity {
212 if (empty($this->iModifiedUserId)) { 202 if (empty($this->iModifiedUserId)) {
213 $this->iModifiedUserId = $this->iCreatorId; 203 $this->iModifiedUserId = $this->iCreatorId;
214 } 204 }
  205 + if (empty($this->iOwnerId)) {
  206 + $this->iOwnerId = $this->iCreatorId;
  207 + }
215 if (empty($this->iMetadataVersion)) { 208 if (empty($this->iMetadataVersion)) {
216 $this->iMetadataVersion = 0; 209 $this->iMetadataVersion = 0;
217 } 210 }
@@ -221,7 +214,7 @@ class KTDocumentCore extends KTEntity { @@ -221,7 +214,7 @@ class KTDocumentCore extends KTEntity {
221 $oFolder = Folder::get($this->getFolderId()); 214 $oFolder = Folder::get($this->getFolderId());
222 $this->iPermissionObjectId = $oFolder->getPermissionObjectId(); 215 $this->iPermissionObjectId = $oFolder->getPermissionObjectId();
223 $res = parent::create(); 216 $res = parent::create();
224 - 217 +
225 if ($res === true) { 218 if ($res === true) {
226 KTPermissionUtil::updatePermissionLookup($this); 219 KTPermissionUtil::updatePermissionLookup($this);
227 } 220 }
lib/documentmanagement/documentutil.inc.php
@@ -185,7 +185,7 @@ class KTDocumentUtil { @@ -185,7 +185,7 @@ class KTDocumentUtil {
185 return $res; 185 return $res;
186 } 186 }
187 } else { 187 } else {
188 - $oUploadChannel->sendMessage(new KTUploadGenericMessage(_("Storing contents"))); 188 + // $oUploadChannel->sendMessage(new KTUploadGenericMessage(_("Storing contents")));
189 $res = KTDocumentUtil::storeContents($oDocument, $oContents, $aOptions); 189 $res = KTDocumentUtil::storeContents($oDocument, $oContents, $aOptions);
190 if (PEAR::isError($res)) { 190 if (PEAR::isError($res)) {
191 $oDocument->delete(); 191 $oDocument->delete();
@@ -200,7 +200,7 @@ class KTDocumentUtil { @@ -200,7 +200,7 @@ class KTDocumentUtil {
200 return $res; 200 return $res;
201 } 201 }
202 } else { 202 } else {
203 - $oUploadChannel->sendMessage(new KTUploadGenericMessage(_("Saving metadata"))); 203 + // $oUploadChannel->sendMessage(new KTUploadGenericMessage(_("Saving metadata")));
204 $res = KTDocumentUtil::saveMetadata($oDocument, $aMetadata); 204 $res = KTDocumentUtil::saveMetadata($oDocument, $aMetadata);
205 if (PEAR::isError($res)) { 205 if (PEAR::isError($res)) {
206 $oDocument->delete(); 206 $oDocument->delete();
@@ -374,6 +374,16 @@ class KTDocumentUtil { @@ -374,6 +374,16 @@ class KTDocumentUtil {
374 374
375 // {{{ add 375 // {{{ add
376 function &add($oFolder, $sFilename, $oUser, $aOptions) { 376 function &add($oFolder, $sFilename, $oUser, $aOptions) {
  377 + $GLOBALS['_IN_ADD'] = true;
  378 + $ret = KTDocumentUtil::_in_add($oFolder, $sFilename, $oUser, $aOptions);
  379 + unset($GLOBALS['_IN_ADD']);
  380 + return $ret;
  381 + }
  382 + // }}}
  383 +
  384 +
  385 + // {{{ _in_add
  386 + function &_in_add($oFolder, $sFilename, $oUser, $aOptions) {
377 if (KTDocumentUtil::fileExists($oFolder, $sFilename)) { 387 if (KTDocumentUtil::fileExists($oFolder, $sFilename)) {
378 $oDoc = Document::getByFilenameAndFolder($sFilename, $oFolder->getId()); 388 $oDoc = Document::getByFilenameAndFolder($sFilename, $oFolder->getId());
379 if (PEAR::isError($oDoc)) { 389 if (PEAR::isError($oDoc)) {
@@ -403,12 +413,12 @@ class KTDocumentUtil { @@ -403,12 +413,12 @@ class KTDocumentUtil {
403 $oUploadChannel =& KTUploadChannel::getSingleton(); 413 $oUploadChannel =& KTUploadChannel::getSingleton();
404 $oUploadChannel->sendMessage(new KTUploadNewFile($sFilename)); 414 $oUploadChannel->sendMessage(new KTUploadNewFile($sFilename));
405 $oDocument =& KTDocumentUtil::_add($oFolder, $sFilename, $oUser, $aOptions); 415 $oDocument =& KTDocumentUtil::_add($oFolder, $sFilename, $oUser, $aOptions);
406 - $oUploadChannel->sendMessage(new KTUploadGenericMessage(_("Document created"))); 416 + // $oUploadChannel->sendMessage(new KTUploadGenericMessage(_("Document created")));
407 if (PEAR::isError($oDocument)) { 417 if (PEAR::isError($oDocument)) {
408 return $oDocument; 418 return $oDocument;
409 } 419 }
410 420
411 - $oUploadChannel->sendMessage(new KTUploadGenericMessage(_("Scanning file"))); 421 + // $oUploadChannel->sendMessage(new KTUploadGenericMessage(_("Scanning file")));
412 $oKTTriggerRegistry = KTTriggerRegistry::getSingleton(); 422 $oKTTriggerRegistry = KTTriggerRegistry::getSingleton();
413 $aTriggers = $oKTTriggerRegistry->getTriggers('content', 'scan'); 423 $aTriggers = $oKTTriggerRegistry->getTriggers('content', 'scan');
414 $iTrigger = 0; 424 $iTrigger = 0;
@@ -416,7 +426,7 @@ class KTDocumentUtil { @@ -416,7 +426,7 @@ class KTDocumentUtil {
416 $sTrigger = $aTrigger[0]; 426 $sTrigger = $aTrigger[0];
417 $oTrigger = new $sTrigger; 427 $oTrigger = new $sTrigger;
418 $oTrigger->setDocument($oDocument); 428 $oTrigger->setDocument($oDocument);
419 - $oUploadChannel->sendMessage(new KTUploadGenericMessage(sprintf(_(" (trigger %s)"), $sTrigger))); 429 + // $oUploadChannel->sendMessage(new KTUploadGenericMessage(sprintf(_(" (trigger %s)"), $sTrigger)));
420 $ret = $oTrigger->scan(); 430 $ret = $oTrigger->scan();
421 if (PEAR::isError($ret)) { 431 if (PEAR::isError($ret)) {
422 $oDocument->delete(); 432 $oDocument->delete();
@@ -434,11 +444,11 @@ class KTDocumentUtil { @@ -434,11 +444,11 @@ class KTDocumentUtil {
434 } 444 }
435 $oTrigger = new $sTrigger; 445 $oTrigger = new $sTrigger;
436 $oTrigger->setDocument($oDocument); 446 $oTrigger->setDocument($oDocument);
437 - $oUploadChannel->sendMessage(new KTUploadGenericMessage(sprintf(_(" (trigger %s)"), $sTrigger))); 447 + // $oUploadChannel->sendMessage(new KTUploadGenericMessage(sprintf(_(" (trigger %s)"), $sTrigger)));
438 $oTrigger->transform(); 448 $oTrigger->transform();
439 } 449 }
440 450
441 - $oUploadChannel->sendMessage(new KTUploadGenericMessage(_("Creating transaction"))); 451 + // $oUploadChannel->sendMessage(new KTUploadGenericMessage(_("Creating transaction")));
442 $aOptions = array('user' => $oUser); 452 $aOptions = array('user' => $oUser);
443 //create the document transaction record 453 //create the document transaction record
444 $oDocumentTransaction = & new DocumentTransaction($oDocument, "Document created", 'ktcore.transactions.create', $aOptions); 454 $oDocumentTransaction = & new DocumentTransaction($oDocument, "Document created", 'ktcore.transactions.create', $aOptions);
@@ -448,7 +458,7 @@ class KTDocumentUtil { @@ -448,7 +458,7 @@ class KTDocumentUtil {
448 return $res; 458 return $res;
449 } 459 }
450 460
451 - $oUploadChannel->sendMessage(new KTUploadGenericMessage(_("Sending subscriptions"))); 461 + // $oUploadChannel->sendMessage(new KTUploadGenericMessage(_("Sending subscriptions")));
452 // fire subscription alerts for the checked in document 462 // fire subscription alerts for the checked in document
453 $oSubscriptionEvent = new SubscriptionEvent(); 463 $oSubscriptionEvent = new SubscriptionEvent();
454 $oFolder = Folder::get($oDocument->getFolderID()); 464 $oFolder = Folder::get($oDocument->getFolderID());
@@ -467,6 +477,7 @@ class KTDocumentUtil { @@ -467,6 +477,7 @@ class KTDocumentUtil {
467 $ret = $oTrigger->postValidate(); 477 $ret = $oTrigger->postValidate();
468 478
469 } 479 }
  480 + KTDocumentUtil::updateSearchableText($oDocument, true);
470 481
471 $oUploadChannel->sendMessage(new KTUploadGenericMessage(_("All done..."))); 482 $oUploadChannel->sendMessage(new KTUploadGenericMessage(_("All done...")));
472 483
@@ -533,7 +544,10 @@ class KTDocumentUtil { @@ -533,7 +544,10 @@ class KTDocumentUtil {
533 // }}} 544 // }}}
534 545
535 // {{{ updateSearchableText 546 // {{{ updateSearchableText
536 - function updateSearchableText($oDocument) { 547 + function updateSearchableText($oDocument, $bOverride = false) {
  548 + if (isset($GLOBALS['_IN_ADD']) && empty($bOverride)) {
  549 + return;
  550 + }
537 $oDocument = KTUtil::getObject('Document', $oDocument); 551 $oDocument = KTUtil::getObject('Document', $oDocument);
538 $iDocumentId = $oDocument->getId(); 552 $iDocumentId = $oDocument->getId();
539 $sTable = KTUtil::getTableName('document_transaction_text'); 553 $sTable = KTUtil::getTableName('document_transaction_text');
lib/foldermanagement/Folder.inc
@@ -101,33 +101,31 @@ class Folder extends KTEntity { @@ -101,33 +101,31 @@ class Folder extends KTEntity {
101 return $res; 101 return $res;
102 } 102 }
103 // }}} 103 // }}}
104 - /**  
105 - * Recursive function to generate a comma delimited string containing  
106 - * the parent folder ids  
107 - *  
108 - * @return String comma delimited string containing the parent folder ids  
109 - */  
110 - function generateParentFolderIDS($iFolderID) {  
111 - global $default;  
112 - //if the folder is not the root folder  
113 - if ($iFolderID != 0) {  
114 - $sql = $default->db;  
115 - $sql->query(array("SELECT parent_id FROM $default->folders_table WHERE ID = ?", $iFolderID));/*ok*/  
116 - $sql->next_record();  
117 - return Folder::generateParentFolderIDS($sql->f("parent_id")) . ",$iFolderID";  
118 - }  
119 - return;  
120 -  
121 - }  
122 - 104 +
123 /** 105 /**
124 * Returns a comma delimited string containing the parent folder ids, strips leading / 106 * Returns a comma delimited string containing the parent folder ids, strips leading /
125 * 107 *
126 * @return String comma delimited string containing the parent folder ids 108 * @return String comma delimited string containing the parent folder ids
127 */ 109 */
128 - function generateFolderIDs($iFolderID) {  
129 - $sFolderIDs = Folder::generateParentFolderIDS($iFolderID);  
130 - return substr($sFolderIDs, 1, strlen($sFolderIDs)); 110 + function generateFolderIDs($iFolderId) {
  111 + if (empty($iFolderId)) {
  112 + return;
  113 + }
  114 + $oFolder =& Folder::get($iFolderId);
  115 + if (PEAR::isError($oFolder)) {
  116 + return $oFolder;
  117 + }
  118 +
  119 + $iParentId = $oFolder->getParentId();
  120 + if (empty($iParentId)) {
  121 + return $oFolder->getId();
  122 + }
  123 + $oParentFolder =& Folder::get($iParentId);
  124 + $sParentFolderParentFolderIds = $oParentFolder->getParentFolderIDs();
  125 + if (empty($sParentFolderParentFolderIds)) {
  126 + return sprintf('%s,%s', $iParentId, $oFolder->getId());;
  127 + }
  128 + return sprintf('%s,%s,%s', $sParentFolderParentFolderIds, $iParentId, $oFolder->getId());
131 } 129 }
132 130
133 /** 131 /**
@@ -212,12 +210,9 @@ class Folder extends KTEntity { @@ -212,12 +210,9 @@ class Folder extends KTEntity {
212 global $default; 210 global $default;
213 //get the direct children 211 //get the direct children
214 $sql = $default->db; 212 $sql = $default->db;
215 - $sql->query(array("SELECT id from $default->folders_table WHERE parent_id = ?", $iId));/*ok*/  
216 - while ($sql->next_record()) {  
217 - //force an update, this will cause this child's children to be updated  
218 - $oFolder = Folder::get($sql->f("id")); 213 + $aFolders =& Folder::getByParentId($iId);
  214 + foreach ($aFolders as $oFolder) {
219 $oFolder->update(true); 215 $oFolder->update(true);
220 -  
221 } 216 }
222 return; 217 return;
223 } 218 }
@@ -260,6 +255,13 @@ class Folder extends KTEntity { @@ -260,6 +255,13 @@ class Folder extends KTEntity {
260 Folder::getChildren($sql->f("id"), $aChildren); 255 Folder::getChildren($sql->f("id"), $aChildren);
261 } 256 }
262 return $aChildren; 257 return $aChildren;
  258 + /*
  259 + $oFolder = Folder::get($iFolderID);
  260 + $path = $oFolder->getParentFolderIds() . ',' . $oFolder->getId();
  261 + return Folder::getList(array(
  262 + sprintf('(parent_folder_ids = "%s" OR parent_folder_ids LIKE "%s,%%")', $path, $path),
  263 + ));
  264 + */
263 } 265 }
264 266
265 /** 267 /**
@@ -412,11 +414,8 @@ class Folder extends KTEntity { @@ -412,11 +414,8 @@ class Folder extends KTEntity {
412 */ 414 */
413 function getParentFolderID($iFolderID) { 415 function getParentFolderID($iFolderID) {
414 if ($iFolderID != 0) { 416 if ($iFolderID != 0) {
415 - global $default;  
416 - $sql = $default->db;  
417 - $sql->query(array("SELECT parent_id FROM " . $default->folders_table . " WHERE id = ?", $iFolderID));/*ok*/  
418 - $sql->next_record();  
419 - return $sql->f("parent_id"); 417 + $oFolder = Folder::get($iFolderID);
  418 + return $oFolder->getParentFolderID();
420 } 419 }
421 return 0; 420 return 0;
422 } 421 }
@@ -503,6 +502,12 @@ class Folder extends KTEntity { @@ -503,6 +502,12 @@ class Folder extends KTEntity {
503 'permission_lookup_id' => $iLookupID, 502 'permission_lookup_id' => $iLookupID,
504 ), array('multi' => true)); 503 ), array('multi' => true));
505 } 504 }
  505 +
  506 + function getByParentId($iParentID) {
  507 + return KTEntityUtil::getByDict('Folder', array(
  508 + 'parent_id' => $iParentID,
  509 + ), array('multi' => true));
  510 + }
506 511
507 // STATIC 512 // STATIC
508 function &createFromArray($aOptions) { 513 function &createFromArray($aOptions) {
lib/ktentity.inc
@@ -26,8 +26,15 @@ @@ -26,8 +26,15 @@
26 * @package lib 26 * @package lib
27 */ 27 */
28 28
  29 +$_LCASECACHE = array();
  30 +$_OBJECTCACHE = array();
  31 +$_RANDOMCALL = 0;
  32 +$_STOPCACHING = array();
  33 +
29 require_once(KT_LIB_DIR . '/cache/cache.inc.php'); 34 require_once(KT_LIB_DIR . '/cache/cache.inc.php');
30 35
  36 +DEFINE("EVIL_CACHE_GRIND", false);
  37 +
31 class KTEntity { 38 class KTEntity {
32 var $_bUsePearError = false; 39 var $_bUsePearError = false;
33 /** object primary key */ 40 /** object primary key */
@@ -41,18 +48,34 @@ class KTEntity { @@ -41,18 +48,34 @@ class KTEntity {
41 return array('getlist'); 48 return array('getlist');
42 } 49 }
43 50
44 - function clearCachedGroups() {  
45 - $groups = $this->_cachedGroups(); 51 + function _innerClearCachedGroups($sClassName) {
  52 + if ($GLOBALS['_STOPCACHING'][$sClassName]) {
  53 + if ($GLOBALS['_STOPCACHING'][$sClassName] > 5) {
  54 + return;
  55 + }
  56 + } else {
  57 + $GLOBALS['_STOPCACHING'][$sClassName] = 0;
  58 + }
  59 + $group_func = array($sClassName, '_cachedGroups');
  60 + $groups = call_user_func($group_func);
  61 + $groups[] = 'auto';
46 $oCache =& KTCache::getSingleton(); 62 $oCache =& KTCache::getSingleton();
47 - $aSuffixes = array('', '_count', '_fullselect'); 63 + $aSuffixes = array(''); // , '_count', '_fullselect');
48 foreach ($groups as $group_base) { 64 foreach ($groups as $group_base) {
49 global $default; 65 global $default;
50 foreach ($aSuffixes as $sSuffix) { 66 foreach ($aSuffixes as $sSuffix) {
51 - $group = sprintf("%s/%s%s", get_class($this), $group_base, $sSuffix); 67 + $group = sprintf("%s/%s%s", $sClassName, $group_base, $sSuffix);
52 $default->log->debug("Clearing cached group: $group"); 68 $default->log->debug("Clearing cached group: $group");
53 $oCache->clear($group); 69 $oCache->clear($group);
54 } 70 }
55 } 71 }
  72 + $GLOBALS['_STOPCACHING'][$sClassName]++;
  73 +
  74 + }
  75 +
  76 + function clearCachedGroups() {
  77 + $sClass = get_class($this);
  78 + $this->_innerClearCachedGroups($sClass);
56 } 79 }
57 80
58 /** 81 /**
@@ -143,27 +166,73 @@ class KTEntity { @@ -143,27 +166,73 @@ class KTEntity {
143 } 166 }
144 167
145 function load($iId = null) { 168 function load($iId = null) {
  169 + global $default;
146 if (is_null($iId)) { 170 if (is_null($iId)) {
147 if (is_null($this->iId)) { 171 if (is_null($this->iId)) {
148 return PEAR::raiseError("No ID given"); 172 return PEAR::raiseError("No ID given");
149 } 173 }
150 $iId = $this->iId; 174 $iId = $this->iId;
151 } 175 }
152 - $table = $this->_table();  
153 - $select = $this->_getSqlSelection();  
154 - $sQuery = "SELECT $select FROM $table WHERE id = ?";  
155 - $aParams = array($iId);  
156 -  
157 - $res = DBUtil::getResultArray(array($sQuery, $aParams));  
158 -  
159 - if (PEAR::isError($res)) {  
160 - return $res;  
161 - }  
162 - if (count($res) === 0) {  
163 - return PEAR::raiseError("No such ID: $iId");  
164 - }  
165 - if (count($res) > 1) {  
166 - return PEAR::raiseError("Multiple matches for ID: $iId"); 176 + $sClassName = get_class($this);
  177 + // cache at lowest possible level.
  178 + $oCache =& KTCache::getSingleton();
  179 + $group = sprintf("%s/%s", $sClassName , 'id');
  180 + list($bCached, $mCached) = $oCache->get($group, $iId);
  181 + if ($bCached && EVIL_CACHE_GRIND) {
  182 + $default->log->debug(sprintf("Found and testing object cache for class %s, id %d", $sClassName, $iId));
  183 +
  184 + $table = $this->_table();
  185 + $select = $this->_getSqlSelection();
  186 + $sQuery = "SELECT $select FROM $table WHERE id = ?";
  187 + $aParams = array($iId);
  188 +
  189 + $res = DBUtil::getResultArray(array($sQuery, $aParams));
  190 + // we _have_ a cache: error is a disaster
  191 + if (PEAR::isError($res) || (count($res) === 0) || (count($res) > 1)) {
  192 + $oCache->alertFailure($sClassName, array('<strong>SERIOUS FAILURE:</strong> real object is an error, cache claims "valid".'));
  193 + return $res;
  194 + }
  195 +
  196 + // now compare the sub-values.
  197 + $aFailures = array();
  198 + $sEntClass = get_class($this);
  199 +
  200 + foreach (array_keys($res) as $sKey => $sVal) {
  201 + if ($mCached[$sKey] != $res[$sKey]) {
  202 + $aFailures[] = $sKey;
  203 + }
  204 + }
  205 +
  206 + if (!empty($aFailures)) {
  207 + $oCache->alertFailure($sClassName, $aFailures);
  208 + }
  209 +
  210 + $res = $mCached;
  211 + } else if ($bCached) {
  212 + global $default;
  213 + $default->log->debug(sprintf("Using object cache for class %s, id %d", $sClassName, $iId));
  214 + $res = $mCached;
  215 + /* */
  216 + } else {
  217 + $default->log->debug(sprintf("No object cache for class %s, id %d", $sClassName, $iId));
  218 + $table = $this->_table();
  219 + $select = $this->_getSqlSelection();
  220 + $sQuery = "SELECT $select FROM $table WHERE id = ?";
  221 + $aParams = array($iId);
  222 +
  223 + $res = DBUtil::getResultArray(array($sQuery, $aParams));
  224 +
  225 + if (PEAR::isError($res)) {
  226 + return $res;
  227 + }
  228 + if (count($res) === 0) {
  229 + return PEAR::raiseError("No such ID: $iId");
  230 + }
  231 +
  232 + if (count($res) > 1) {
  233 + return PEAR::raiseError("Multiple matches for ID: $iId");
  234 + }
  235 + $oCache->set($group, $iId, $res); // finally, cache if its "good".
167 } 236 }
168 $vk = array_flip($this->_aFieldToSelect); 237 $vk = array_flip($this->_aFieldToSelect);
169 $aLoadInfo = array(); 238 $aLoadInfo = array();
@@ -208,26 +277,43 @@ class KTEntity { @@ -208,26 +277,43 @@ class KTEntity {
208 // 277 //
209 // If the element isn't in the case array, the method doesn't 278 // If the element isn't in the case array, the method doesn't
210 // exist. 279 // exist.
211 - 280 + $sClassName = get_class($this);
  281 +
  282 + $aCache = KTUtil::arrayGet($GLOBALS['_LCASECACHE'], $sClassName);
  283 +
  284 + $sLowerElement = strtolower($sElement);
  285 + if ($aCache) {
  286 + $r = KTUtil::arrayGet($aCache['fieldnames'], $sLowerElement);
  287 + if ($r) { return $r; }
  288 + }
  289 +
212 $array = array_keys($this->_aFieldToSelect); 290 $array = array_keys($this->_aFieldToSelect);
213 291
214 - foreach($array as $k) {  
215 - $case[strtolower($k)] = $k; 292 + if (!$aCache) {
  293 + $case = array();
  294 + foreach($array as $k) {
  295 + $case[strtolower($k)] = $k;
  296 + }
  297 + foreach($case as $k => $v) {
  298 + $case[substr($k, 1)] = $v;
  299 + }
  300 + } else {
  301 + $case = $aCache['fieldnames'];
216 } 302 }
217 303
218 - $sElement = strtolower($sElement);  
219 -  
220 - if (array_key_exists($sElement, $case)) {  
221 - return $case[strtolower($sElement)]; 304 + //var_dump($case);
  305 +
  306 + if (!$aCache) {
  307 + $aCache = array();
  308 + $aCache['fieldnames'] = $case;
222 } 309 }
223 -  
224 - foreach($array as $k) {  
225 - $case[substr(strtolower($k), 1)] = $k; 310 +
  311 + $GLOBALS['_LCASECACHE'][$sClassName] =& $aCache;
  312 +
  313 + if (array_key_exists($sLowerElement, $case)) {
  314 + return $case[$sLowerElement];
226 } 315 }
227 316
228 - if (array_key_exists($sElement, $case)) {  
229 - return $case[strtolower($sElement)];  
230 - }  
231 return PEAR::raiseError("No such element"); 317 return PEAR::raiseError("No such element");
232 } 318 }
233 319
@@ -275,14 +361,29 @@ class KTEntityUtil { @@ -275,14 +361,29 @@ class KTEntityUtil {
275 $bIDs = KTUtil::arrayGet($aOptions, "ids", false); 361 $bIDs = KTUtil::arrayGet($aOptions, "ids", false);
276 $sIDField = 'id'; 362 $sIDField = 'id';
277 $cache = KTUtil::arrayGet($aOptions, 'cache', false); 363 $cache = KTUtil::arrayGet($aOptions, 'cache', false);
  364 +
  365 + if (!$cache) { // && EVIL_CACHE_GRIND) {
  366 + $cache = 'auto';
  367 + }
  368 +
  369 + if (isset($GLOBALS['_STOPCACHING'][$sClassName])) {
  370 + if ($GLOBALS['_STOPCACHING'][$sClassName] > 5) {
  371 + $cache = false;
  372 + }
  373 + }
  374 +
  375 +
278 $fullselect = KTUtil::arrayGet($aOptions, 'fullselect', false); 376 $fullselect = KTUtil::arrayGet($aOptions, 'fullselect', false);
  377 +
279 if ($cache) { 378 if ($cache) {
280 - if (is_array($sWhereClause)) { 379 + if ($cache === 'auto') {
  380 + $vals = serialize($sWhereClause);
  381 + } else if (is_array($sWhereClause)) {
281 $vals = serialize($sWhereClause[1]); 382 $vals = serialize($sWhereClause[1]);
282 } else { 383 } else {
283 $vals = serialize($sWhereClause); 384 $vals = serialize($sWhereClause);
284 } 385 }
285 - $default->log->debug(sprintf("Trying object cache for class %s, %s: %s", $sClassName, $cache, $vals)); 386 + $default->log->debug(sprintf("Trying list cache for class %s, %s: %s", $sClassName, $cache, $vals));
286 387
287 $oCache =& KTCache::getSingleton(); 388 $oCache =& KTCache::getSingleton();
288 $suffix = ''; 389 $suffix = '';
@@ -294,8 +395,63 @@ class KTEntityUtil { @@ -294,8 +395,63 @@ class KTEntityUtil {
294 } else { 395 } else {
295 $bCached = false; 396 $bCached = false;
296 } 397 }
  398 +
  399 + if ($cache && !$bCached) {
  400 + global $default;
  401 + $default->log->debug(sprintf("No list cache for class %s, %s: %s", $sClassName, $cache, $vals));
  402 + }
  403 + if ($bCached && EVIL_CACHE_GRIND) {
  404 + if (!empty($fullselect)) {
  405 + $oObject = new $sClassName;
  406 + $select = $oObject->_getSqlSelection();
  407 + $sQuery = "SELECT $select FROM " . $sTable;/*ok*/
  408 + } else {
  409 + $sIDField = KTUtil::arrayGet($aOptions, "idfield", 'id');
  410 + $sQuery = "SELECT $sIDField FROM " . $sTable;/*ok*/
  411 + }
  412 + $aParams = array();
  413 + if (!is_null($sWhereClause)) {
  414 + if (is_string($sWhereClause)) {
  415 + if (substr($sWhereClause, 0, 5) != 'WHERE') {
  416 + if (substr($sWhereClause, 0, 5) != 'ORDER') {
  417 + $sQuery .= ' WHERE';
  418 + }
  419 + }
  420 + $sQuery .= ' ' . $sWhereClause;
  421 + } else if (is_array($sWhereClause)) {
  422 + if (substr($sWhereClause[0], 0, 5) != 'WHERE') {
  423 + if (substr($sWhereClause[0], 0, 5) != 'ORDER') {
  424 + $sQuery .= ' WHERE';
  425 + }
  426 + }
  427 + $sQuery .= ' ' . $sWhereClause[0];
  428 + $aParams = $sWhereClause[1];
  429 + } else {
  430 + return new PEAR_Error('Weird WhereClause passed');
  431 + }
  432 + }
  433 + $sOrderBy = KTUtil::arrayGet($aOptions, 'orderby');
  434 + if (!empty($sOrderBy)) {
  435 + $sQuery .= " ORDER BY " . $sOrderBy;
  436 + }
297 437
298 - if ($bCached) { 438 + if (!empty($fullselect)) {
  439 + $aIDs = DBUtil::getResultArray(array($sQuery, $aParams));
  440 + } else {
  441 + $aIDs = DBUtil::getResultArrayKey(array($sQuery, $aParams), $sIDField);
  442 + }
  443 + // compare mcached == $aIds
  444 +
  445 + if ($aIDs != $mCached) {
  446 + /*
  447 + print "==================\n\n\n\n\n";
  448 + var_dump($aIDs);
  449 + print "------\n";
  450 + var_dump($mCached);
  451 + */
  452 + $oCache->alertFailure($group, array('Stored IDS != Cache IDS'));
  453 + }
  454 + } else if ($bCached) {
299 $default->log->debug(sprintf("Using object cache for class %s, %s: %s", $sClassName, $cache, $vals)); 455 $default->log->debug(sprintf("Using object cache for class %s, %s: %s", $sClassName, $cache, $vals));
300 $aIDs = $mCached; 456 $aIDs = $mCached;
301 /* */ 457 /* */
@@ -401,15 +557,11 @@ class KTEntityUtil { @@ -401,15 +557,11 @@ class KTEntityUtil {
401 if (PEAR::isError($ret)) { 557 if (PEAR::isError($ret)) {
402 return $ret; 558 return $ret;
403 } 559 }
404 - $oCache =& KTCache::getSingleton();  
405 - $group = sprintf("%s/%s", $sClassName, 'id');  
406 - $oCache->set($group, $oObject->getId(), $oObject);  
407 return $oObject; 560 return $oObject;
408 } 561 }
409 562
410 function &loadFromArrayMulti($sClassName, $aMultiArray, $aOptions = null) { 563 function &loadFromArrayMulti($sClassName, $aMultiArray, $aOptions = null) {
411 $aRet = array(); 564 $aRet = array();
412 - $oCache =& KTCache::getSingleton();  
413 foreach ($aMultiArray as $aArray) { 565 foreach ($aMultiArray as $aArray) {
414 $oObject =& new $sClassName; 566 $oObject =& new $sClassName;
415 $ret = $oObject->loadFromArray($aArray); 567 $ret = $oObject->loadFromArray($aArray);
@@ -417,28 +569,19 @@ class KTEntityUtil { @@ -417,28 +569,19 @@ class KTEntityUtil {
417 return $ret; 569 return $ret;
418 } 570 }
419 $aRet[] = $oObject; 571 $aRet[] = $oObject;
420 - $group = sprintf("%s/%s", $sClassName, 'id');  
421 - $oCache->set($group, $oObject->getId(), $oObject);  
422 } 572 }
423 return $aRet; 573 return $aRet;
424 } 574 }
425 575
426 function &get($sClassName, $iId) { 576 function &get($sClassName, $iId) {
427 - $oCache =& KTCache::getSingleton();  
428 - $group = sprintf("%s/%s", $sClassName, 'id');  
429 - list($bCached, $mCached) = $oCache->get($group, $iId);  
430 - if ($bCached) {  
431 - global $default;  
432 - $default->log->debug(sprintf("Using object cache for class %s, id %d", $sClassName, $iId));  
433 - return $mCached;  
434 - /* */  
435 - } 577 + $oObject =& KTUtil::arrayGet($GLOBALS['_OBJECTCACHE'][$sClassName], $iId);
  578 + if ($oObject) { return $oObject; }
436 $oObject =& new $sClassName; 579 $oObject =& new $sClassName;
437 $res = $oObject->load($iId); 580 $res = $oObject->load($iId);
438 if (PEAR::isError($res)) { 581 if (PEAR::isError($res)) {
439 return $res; 582 return $res;
440 } 583 }
441 - $oCache->set($group, $iId, $oObject); 584 + $GLOBALS['_OBJECTCACHE'][$sClassName][$iId] =& $oObject;
442 return $oObject; 585 return $oObject;
443 } 586 }
444 587
lib/permissions/permissiondescriptor.inc.php
@@ -28,6 +28,10 @@ @@ -28,6 +28,10 @@
28 28
29 require_once(KT_LIB_DIR . "/ktentity.inc"); 29 require_once(KT_LIB_DIR . "/ktentity.inc");
30 30
  31 +$_PDGC = array();
  32 +$_PDRC = array();
  33 +$_PDUC = array();
  34 +
31 class KTPermissionDescriptor extends KTEntity { 35 class KTPermissionDescriptor extends KTEntity {
32 /** primary key */ 36 /** primary key */
33 var $iId = -1; 37 var $iId = -1;
@@ -142,6 +146,7 @@ class KTPermissionDescriptor extends KTEntity { @@ -142,6 +146,7 @@ class KTPermissionDescriptor extends KTEntity {
142 // {{{ GROUPS 146 // {{{ GROUPS
143 // {{{ _clearGroups 147 // {{{ _clearGroups
144 function _clearGroups() { 148 function _clearGroups() {
  149 + unset($GLOBALS['_PDGC'][$this->getId()]);
145 $sTable = KTUtil::getTableName('permission_descriptor_groups'); 150 $sTable = KTUtil::getTableName('permission_descriptor_groups');
146 $sQuery = "DELETE FROM $sTable WHERE descriptor_id = ?"; 151 $sQuery = "DELETE FROM $sTable WHERE descriptor_id = ?";
147 $aParams = array($this->getID()); 152 $aParams = array($this->getID());
@@ -188,10 +193,15 @@ class KTPermissionDescriptor extends KTEntity { @@ -188,10 +193,15 @@ class KTPermissionDescriptor extends KTEntity {
188 193
189 // {{{ getGroups 194 // {{{ getGroups
190 function getGroups() { 195 function getGroups() {
  196 + if (isset($GLOBALS['_PDGC'][$this->getId()])) {
  197 + return $GLOBALS['_PDGC'][$this->getId()];
  198 + }
191 $sTable = KTUtil::getTableName('permission_descriptor_groups'); 199 $sTable = KTUtil::getTableName('permission_descriptor_groups');
192 $sQuery = "SELECT group_id FROM $sTable WHERE descriptor_id = ?"; 200 $sQuery = "SELECT group_id FROM $sTable WHERE descriptor_id = ?";
193 $aParams = array($this->getID()); 201 $aParams = array($this->getID());
194 - return DBUtil::getResultArrayKey(array($sQuery, $aParams), 'group_id'); 202 + $res = DBUtil::getResultArrayKey(array($sQuery, $aParams), 'group_id');
  203 + $GLOBALS['_PDGC'][$this->getId()] = $res;
  204 + return $res;
195 } 205 }
196 // }}} 206 // }}}
197 207
@@ -245,6 +255,7 @@ class KTPermissionDescriptor extends KTEntity { @@ -245,6 +255,7 @@ class KTPermissionDescriptor extends KTEntity {
245 // {{{ ROLES 255 // {{{ ROLES
246 // {{{ _clearRoles 256 // {{{ _clearRoles
247 function _clearRoles() { 257 function _clearRoles() {
  258 + unset($GLOBALS['_PDRC'][$this->getId()]);
248 $sTable = KTUtil::getTableName('permission_descriptor_roles'); 259 $sTable = KTUtil::getTableName('permission_descriptor_roles');
249 $sQuery = "DELETE FROM $sTable WHERE descriptor_id = ?"; 260 $sQuery = "DELETE FROM $sTable WHERE descriptor_id = ?";
250 $aParams = array($this->getID()); 261 $aParams = array($this->getID());
@@ -291,10 +302,15 @@ class KTPermissionDescriptor extends KTEntity { @@ -291,10 +302,15 @@ class KTPermissionDescriptor extends KTEntity {
291 302
292 // {{{ getRoles 303 // {{{ getRoles
293 function getRoles() { 304 function getRoles() {
  305 + if (isset($GLOBALS['_PDRC'][$this->getId()])) {
  306 + return $GLOBALS['_PDRC'][$this->getId()];
  307 + }
294 $sTable = KTUtil::getTableName('permission_descriptor_roles'); 308 $sTable = KTUtil::getTableName('permission_descriptor_roles');
295 $sQuery = "SELECT role_id FROM $sTable WHERE descriptor_id = ?"; 309 $sQuery = "SELECT role_id FROM $sTable WHERE descriptor_id = ?";
296 $aParams = array($this->getID()); 310 $aParams = array($this->getID());
297 - return DBUtil::getResultArrayKey(array($sQuery, $aParams), 'role_id'); 311 + $res = DBUtil::getResultArrayKey(array($sQuery, $aParams), 'role_id');
  312 + $GLOBALS['_PDRC'][$this->getId()] = $res;
  313 + return $res;
298 } 314 }
299 // }}} 315 // }}}
300 316
@@ -348,6 +364,7 @@ class KTPermissionDescriptor extends KTEntity { @@ -348,6 +364,7 @@ class KTPermissionDescriptor extends KTEntity {
348 // {{{ USERS 364 // {{{ USERS
349 // {{{ _clearUsers 365 // {{{ _clearUsers
350 function _clearUsers() { 366 function _clearUsers() {
  367 + unset($GLOBALS['_PDUC'][$this->getId()]);
351 $sTable = KTUtil::getTableName('permission_descriptor_users'); 368 $sTable = KTUtil::getTableName('permission_descriptor_users');
352 $sQuery = "DELETE FROM $sTable WHERE descriptor_id = ?"; 369 $sQuery = "DELETE FROM $sTable WHERE descriptor_id = ?";
353 $aParams = array($this->getID()); 370 $aParams = array($this->getID());
@@ -394,10 +411,15 @@ class KTPermissionDescriptor extends KTEntity { @@ -394,10 +411,15 @@ class KTPermissionDescriptor extends KTEntity {
394 411
395 // {{{ getUsers 412 // {{{ getUsers
396 function getUsers() { 413 function getUsers() {
  414 + if (isset($GLOBALS['_PDUC'][$this->getId()])) {
  415 + return $GLOBALS['_PDUC'][$this->getId()];
  416 + }
397 $sTable = KTUtil::getTableName('permission_descriptor_users'); 417 $sTable = KTUtil::getTableName('permission_descriptor_users');
398 $sQuery = "SELECT user_id FROM $sTable WHERE descriptor_id = ?"; 418 $sQuery = "SELECT user_id FROM $sTable WHERE descriptor_id = ?";
399 $aParams = array($this->getID()); 419 $aParams = array($this->getID());
400 - return DBUtil::getResultArrayKey(array($sQuery, $aParams), 'user_id'); 420 + $res = DBUtil::getResultArrayKey(array($sQuery, $aParams), 'user_id');
  421 + $GLOBALS['_PDUC'][$this->getId()] = $res;
  422 + return $res;
401 } 423 }
402 // }}} 424 // }}}
403 425
lib/permissions/permissionutil.inc.php
@@ -37,6 +37,7 @@ require_once(KT_LIB_DIR . &quot;/permissions/permissionobject.inc.php&quot;); @@ -37,6 +37,7 @@ require_once(KT_LIB_DIR . &quot;/permissions/permissionobject.inc.php&quot;);
37 require_once(KT_LIB_DIR . "/permissions/permissiondynamiccondition.inc.php"); 37 require_once(KT_LIB_DIR . "/permissions/permissiondynamiccondition.inc.php");
38 require_once(KT_LIB_DIR . "/groups/GroupUtil.php"); 38 require_once(KT_LIB_DIR . "/groups/GroupUtil.php");
39 require_once(KT_LIB_DIR . "/roles/roleallocation.inc.php"); 39 require_once(KT_LIB_DIR . "/roles/roleallocation.inc.php");
  40 +require_once(KT_LIB_DIR . "/roles/documentroleallocation.inc.php");
40 41
41 require_once(KT_LIB_DIR . "/workflow/workflowutil.inc.php"); 42 require_once(KT_LIB_DIR . "/workflow/workflowutil.inc.php");
42 require_once(KT_LIB_DIR . "/workflow/workflowstatepermissionsassignment.inc.php"); 43 require_once(KT_LIB_DIR . "/workflow/workflowstatepermissionsassignment.inc.php");
@@ -310,13 +311,22 @@ class KTPermissionUtil { @@ -310,13 +311,22 @@ class KTPermissionUtil {
310 foreach ($aAllowed['role'] as $iRoleId) { 311 foreach ($aAllowed['role'] as $iRoleId) {
311 // store the PD <-> RoleId map 312 // store the PD <-> RoleId map
312 if (!array_key_exists($iRoleId, $_roleCache)) { 313 if (!array_key_exists($iRoleId, $_roleCache)) {
313 - $oRoleAllocation =& RoleAllocation::getAllocationsForFolderAndRole($iRoleSourceFolder, $iRoleId); 314 + $oRoleAllocation = null;
  315 + if (is_a($oFolderOrDocument, 'KTDocumentCore') || is_a($oFolderOrDocument, 'Document')) {
  316 + $oRoleAllocation =& DocumentRoleAllocation::getAllocationsForDocumentAndRole($oFolderOrDocument->getId(), $iRoleId);
  317 + if (PEAR::isError($oRoleAllocation)) { $oRoleAllocation = null; }
  318 + }
  319 + // if that's null - not set _on_ the document, then
  320 + if (is_null($oRoleAllocation)) {
  321 + $oRoleAllocation =& RoleAllocation::getAllocationsForFolderAndRole($iRoleSourceFolder, $iRoleId);
  322 + }
314 $_roleCache[$iRoleId] = $oRoleAllocation; 323 $_roleCache[$iRoleId] = $oRoleAllocation;
315 } 324 }
316 // roles are _not_ always assigned (can be null at root) 325 // roles are _not_ always assigned (can be null at root)
317 - if ($_roleCache[$iRoleId] != null) { 326 + if (!is_null($_roleCache[$iRoleId])) {
318 $aMapPermAllowed[$iPermissionId]['user'] = array_merge($aAllowed['user'], $_roleCache[$iRoleId]->getUserIds()); 327 $aMapPermAllowed[$iPermissionId]['user'] = array_merge($aAllowed['user'], $_roleCache[$iRoleId]->getUserIds());
319 $aMapPermAllowed[$iPermissionId]['group'] = array_merge($aAllowed['group'], $_roleCache[$iRoleId]->getGroupIds()); 328 $aMapPermAllowed[$iPermissionId]['group'] = array_merge($aAllowed['group'], $_roleCache[$iRoleId]->getGroupIds());
  329 + // naturally, roles cannot be assigned roles, or madness follows.
320 } 330 }
321 } 331 }
322 332
@@ -361,7 +371,8 @@ class KTPermissionUtil { @@ -361,7 +371,8 @@ class KTPermissionUtil {
361 } 371 }
362 $oPD = KTPermissionDescriptor::get($oPLA->getPermissionDescriptorID()); 372 $oPD = KTPermissionDescriptor::get($oPLA->getPermissionDescriptorID());
363 $aGroups = GroupUtil::listGroupsForUserExpand($oUser); 373 $aGroups = GroupUtil::listGroupsForUserExpand($oUser);
364 - return $oPD->hasGroups($aGroups); 374 + if ($oPD->hasUsers(array($oUser))) { return true; }
  375 + else { return $oPD->hasGroups($aGroups); }
365 } 376 }
366 // }}} 377 // }}}
367 378
lib/plugins/pluginentity.inc.php
@@ -52,7 +52,7 @@ class KTPluginEntity extends KTEntity { @@ -52,7 +52,7 @@ class KTPluginEntity extends KTEntity {
52 } 52 }
53 53
54 function _cachedGroups() { 54 function _cachedGroups() {
55 - return array('getList', 'getByNamespace'); 55 + return array('getlist', 'getList', 'getByNamespace');
56 } 56 }
57 // }}} 57 // }}}
58 58
@@ -80,13 +80,13 @@ class KTPluginEntity extends KTEntity { @@ -80,13 +80,13 @@ class KTPluginEntity extends KTEntity {
80 // STATIC 80 // STATIC
81 function &getList($sWhereClause = null) { 81 function &getList($sWhereClause = null) {
82 global $default; 82 global $default;
83 - $aOptions = array('fullselect' => true, 'cache' => 'getList'); 83 + $aOptions = array('fullselect' => false, 'cache' => 'getList');
84 return KTEntityUtil::getList2('KTPluginEntity', $sWhereClause, $aOptions); 84 return KTEntityUtil::getList2('KTPluginEntity', $sWhereClause, $aOptions);
85 } 85 }
86 86
87 // STATIC 87 // STATIC
88 function &getByNamespace($sName) { 88 function &getByNamespace($sName) {
89 - $aOptions = array('fullselect' => true, 'cache' => 'getByNamespace'); 89 + $aOptions = array('fullselect' => false, 'cache' => 'getByNamespace');
90 return KTEntityUtil::getBy('KTPluginEntity', 'namespace', $sName, $aOptions); 90 return KTEntityUtil::getBy('KTPluginEntity', 'namespace', $sName, $aOptions);
91 } 91 }
92 92
@@ -98,4 +98,14 @@ class KTPluginEntity extends KTEntity { @@ -98,4 +98,14 @@ class KTPluginEntity extends KTEntity {
98 return KTEntityUtil::getBy('KTPluginEntity', 'disabled', false, 98 return KTEntityUtil::getBy('KTPluginEntity', 'disabled', false,
99 $aOptions); 99 $aOptions);
100 } 100 }
  101 +
  102 + function setEnabled($aIds) {
  103 + $sTable = KTPluginEntity::_table();
  104 + $sIds = DBUtil::paramArray($aIds);
  105 + $sQuery = sprintf('UPDATE %s SET disabled = 1 WHERE id NOT IN (%s)', $sTable, $sIds);
  106 + DBUtil::runQuery(array($sQuery, $aIds));
  107 + $sQuery = sprintf('UPDATE %s SET disabled = 0 WHERE id IN (%s)', $sTable, $sIds);
  108 + DBUtil::runQuery(array($sQuery, $aIds));
  109 + KTPluginEntity::_innerClearCachedGroups('KTPluginEntity');
  110 + }
101 } 111 }
lib/roles/roleallocation.inc.php
@@ -66,6 +66,18 @@ class RoleAllocation extends KTEntity { @@ -66,6 +66,18 @@ class RoleAllocation extends KTEntity {
66 $this->iPermissionDescriptorId = $oDescriptor->getId(); 66 $this->iPermissionDescriptorId = $oDescriptor->getId();
67 } 67 }
68 68
  69 + function getAllowed() {
  70 + if (!is_null($this->iPermissionDescriptorId)) {
  71 + $oDescriptor = KTPermissionDescriptor::get($this->iPermissionDescriptorId); // fully done, etc.
  72 + $aAllowed = $oDescriptor->getAllowed();
  73 + } else {
  74 + $aAllowed = array();
  75 + }
  76 + return $aAllowed;
  77 + }
  78 +
  79 +
  80 +
69 function _fieldValues () { return array( 81 function _fieldValues () { return array(
70 'role_id' => $this->iRoleId, 82 'role_id' => $this->iRoleId,
71 'folder_id' => $this->iFolderId, 83 'folder_id' => $this->iFolderId,
lib/storage/ondiskpathstoragemanager.inc.php
@@ -73,7 +73,7 @@ class KTOnDiskPathStorageManager extends KTStorageManager { @@ -73,7 +73,7 @@ class KTOnDiskPathStorageManager extends KTStorageManager {
73 } 73 }
74 74
75 function generateStoragePath(&$oDocument) { 75 function generateStoragePath(&$oDocument) {
76 - $sStoragePath = sprintf("%s/%s-%s", KTDocumentCore::_generateFolderPath($oDocument->getFolderID()), $oDocument->getContentVersionId(), $oDocument->getFileName()); 76 + $sStoragePath = sprintf("%s/%s-%s", Folder::generateFolderPath($oDocument->getFolderID()), $oDocument->getContentVersionId(), $oDocument->getFileName());
77 return $sStoragePath; 77 return $sStoragePath;
78 } 78 }
79 79
@@ -178,8 +178,8 @@ class KTOnDiskPathStorageManager extends KTStorageManager { @@ -178,8 +178,8 @@ class KTOnDiskPathStorageManager extends KTStorageManager {
178 $sDocumentRoot = $oConfig->get('urls/documentRoot'); 178 $sDocumentRoot = $oConfig->get('urls/documentRoot');
179 179
180 foreach ($aContentVersions as $oVersion) { 180 foreach ($aContentVersions as $oVersion) {
181 - $sOldPath = sprintf("%s/%s-%s", KTDocumentCore::_generateFolderPath($oSourceFolder->getID()), $oVersion->getId(), $oVersion->getFileName());  
182 - $sNewPath = sprintf("%s/%s-%s", KTDocumentCore::_generateFolderPath($oDestinationFolder->getID()), $oVersion->getId(), $oVersion->getFileName()); 181 + $sOldPath = sprintf("%s/%s-%s", Folder::generateFolderPath($oSourceFolder->getID()), $oVersion->getId(), $oVersion->getFileName());
  182 + $sNewPath = sprintf("%s/%s-%s", Folder::generateFolderPath($oDestinationFolder->getID()), $oVersion->getId(), $oVersion->getFileName());
183 $sFullOldPath = sprintf("%s/%s", $sDocumentRoot, $sOldPath); 183 $sFullOldPath = sprintf("%s/%s", $sDocumentRoot, $sOldPath);
184 $sFullNewPath = sprintf("%s/%s", $sDocumentRoot, $sNewPath); 184 $sFullNewPath = sprintf("%s/%s", $sDocumentRoot, $sNewPath);
185 $res = KTUtil::moveFile($sFullOldPath, $sFullNewPath); 185 $res = KTUtil::moveFile($sFullOldPath, $sFullNewPath);
@@ -322,8 +322,8 @@ class KTOnDiskPathStorageManager extends KTStorageManager { @@ -322,8 +322,8 @@ class KTOnDiskPathStorageManager extends KTStorageManager {
322 $oConfig =& KTConfig::getSingleton(); 322 $oConfig =& KTConfig::getSingleton();
323 $sDocumentRoot = $oConfig->get('urls/documentRoot'); 323 $sDocumentRoot = $oConfig->get('urls/documentRoot');
324 324
325 - $sOldPath = sprintf("%s/%s-%s", KTDocumentCore::_generateFolderPath($oDocument->getFolderID()), $oOldContentVersion->getId(), $oOldContentVersion->getFileName());  
326 - $sNewPath = sprintf("%s/%s-%s", KTDocumentCore::_generateFolderPath($oDocument->getFolderID()), $oDocument->_oDocumentContentVersion->getId(), $sNewFilename); 325 + $sOldPath = sprintf("%s/%s-%s", Folder::generateFolderPath($oDocument->getFolderID()), $oOldContentVersion->getId(), $oOldContentVersion->getFileName());
  326 + $sNewPath = sprintf("%s/%s-%s", Folder::generateFolderPath($oDocument->getFolderID()), $oDocument->_oDocumentContentVersion->getId(), $sNewFilename);
327 $sFullOldPath = sprintf("%s/%s", $sDocumentRoot, $sOldPath); 327 $sFullOldPath = sprintf("%s/%s", $sDocumentRoot, $sOldPath);
328 $sFullNewPath = sprintf("%s/%s", $sDocumentRoot, $sNewPath); 328 $sFullNewPath = sprintf("%s/%s", $sDocumentRoot, $sNewPath);
329 329
lib/templating/kt3template.inc.php
@@ -367,7 +367,7 @@ class KTPage { @@ -367,7 +367,7 @@ class KTPage {
367 $microtime_simple = explode(' ', microtime()); 367 $microtime_simple = explode(' ', microtime());
368 $finaltime = (float) $microtime_simple[1] + (float) $microtime_simple[0]; 368 $finaltime = (float) $microtime_simple[1] + (float) $microtime_simple[0];
369 369
370 - return ($finaltime - $GLOBALS['_KT_starttime']); 370 + return sprintf("%.3f", ($finaltime - $GLOBALS['_KT_starttime']));
371 } 371 }
372 } 372 }
373 373
lib/widgets/portlet.inc.php
@@ -46,6 +46,8 @@ class KTPortlet { @@ -46,6 +46,8 @@ class KTPortlet {
46 } 46 }
47 47
48 function setPlugin(&$oPlugin) { 48 function setPlugin(&$oPlugin) {
  49 + global $default;
  50 + $default->log->debug('portlet regging plugin: ' . $oPlugin->sNamespace);
49 $this->oPlugin =& $oPlugin; 51 $this->oPlugin =& $oPlugin;
50 } 52 }
51 53
plugins/ktcore/KTCorePlugin.php
@@ -58,6 +58,7 @@ class KTCorePlugin extends KTPlugin { @@ -58,6 +58,7 @@ class KTCorePlugin extends KTPlugin {
58 // Permissions 58 // Permissions
59 $this->registerAction('documentaction', 'KTDocumentPermissionsAction', 'ktcore.actions.document.permissions', 'KTPermissions.php'); 59 $this->registerAction('documentaction', 'KTDocumentPermissionsAction', 'ktcore.actions.document.permissions', 'KTPermissions.php');
60 $this->registerAction('folderaction', 'KTRoleAllocationPlugin', 'ktcore.actions.folder.roles', 'KTPermissions.php'); 60 $this->registerAction('folderaction', 'KTRoleAllocationPlugin', 'ktcore.actions.folder.roles', 'KTPermissions.php');
  61 + $this->registerAction('documentaction', 'KTDocumentRolesAction', 'ktcore.actions.document.roles', 'KTPermissions.php');
61 62
62 $this->registerDashlet('KTInfoDashlet', 'ktcore.dashlet.info', 'KTDashlets.php'); 63 $this->registerDashlet('KTInfoDashlet', 'ktcore.dashlet.info', 'KTDashlets.php');
63 $this->registerDashlet('KTNotificationDashlet', 'ktcore.dashlet.notifications', 'KTDashlets.php'); 64 $this->registerDashlet('KTNotificationDashlet', 'ktcore.dashlet.notifications', 'KTDashlets.php');
plugins/ktcore/KTPermissions.php
@@ -35,10 +35,12 @@ require_once(KT_LIB_DIR . &quot;/groups/Group.inc&quot;); @@ -35,10 +35,12 @@ require_once(KT_LIB_DIR . &quot;/groups/Group.inc&quot;);
35 require_once(KT_LIB_DIR . "/users/User.inc"); 35 require_once(KT_LIB_DIR . "/users/User.inc");
36 require_once(KT_LIB_DIR . "/roles/Role.inc"); 36 require_once(KT_LIB_DIR . "/roles/Role.inc");
37 require_once(KT_LIB_DIR . "/roles/roleallocation.inc.php"); 37 require_once(KT_LIB_DIR . "/roles/roleallocation.inc.php");
  38 +require_once(KT_LIB_DIR . "/roles/documentroleallocation.inc.php");
38 39
39 40
40 require_once(KT_LIB_DIR . "/permissions/permission.inc.php"); 41 require_once(KT_LIB_DIR . "/permissions/permission.inc.php");
41 require_once(KT_LIB_DIR . "/permissions/permissionobject.inc.php"); 42 require_once(KT_LIB_DIR . "/permissions/permissionobject.inc.php");
  43 +require_once(KT_LIB_DIR . "/permissions/permissionlookup.inc.php");
42 require_once(KT_LIB_DIR . "/permissions/permissionassignment.inc.php"); 44 require_once(KT_LIB_DIR . "/permissions/permissionassignment.inc.php");
43 require_once(KT_LIB_DIR . "/permissions/permissiondescriptor.inc.php"); 45 require_once(KT_LIB_DIR . "/permissions/permissiondescriptor.inc.php");
44 require_once(KT_LIB_DIR . "/permissions/permissionutil.inc.php"); 46 require_once(KT_LIB_DIR . "/permissions/permissionutil.inc.php");
@@ -52,52 +54,87 @@ class KTDocumentPermissionsAction extends KTDocumentAction { @@ -52,52 +54,87 @@ class KTDocumentPermissionsAction extends KTDocumentAction {
52 } 54 }
53 55
54 function do_main() { 56 function do_main() {
55 - $this->oPage->setBreadcrumbDetails("permissions");  
56 - 57 + $this->oPage->setBreadcrumbDetails("Document Permissions");
57 $oTemplate = $this->oValidator->validateTemplate("ktcore/document/document_permissions"); 58 $oTemplate = $this->oValidator->validateTemplate("ktcore/document/document_permissions");
58 - $oPO = KTPermissionObject::get($this->oDocument->getPermissionObjectID()); 59 +
  60 + $oPL = KTPermissionLookup::get($this->oDocument->getPermissionLookupID());
59 $aPermissions = KTPermission::getList(); 61 $aPermissions = KTPermission::getList();
60 $aMapPermissionGroup = array(); 62 $aMapPermissionGroup = array();
61 - $aMapPermissionRole = array(); 63 + $aMapPermissionRole = array();
  64 + $aMapPermissionUser = array();
  65 +
  66 + $aAllGroups = Group::getList(); // probably small enough
  67 + $aAllRoles = Role::getList(); // probably small enough.
  68 + // users are _not_ fetched this way.
  69 +
  70 + $aActiveGroups = array();
  71 + $aActiveUsers = array();
  72 + $aActiveRoles = array();
  73 +
62 foreach ($aPermissions as $oPermission) { 74 foreach ($aPermissions as $oPermission) {
63 - $oPA = KTPermissionAssignment::getByPermissionAndObject($oPermission, $oPO);  
64 - if (PEAR::isError($oPA)) { 75 + $oPLA = KTPermissionLookupAssignment::getByPermissionAndLookup($oPermission, $oPL);
  76 + if (PEAR::isError($oPLA)) {
65 continue; 77 continue;
66 } 78 }
67 - $oDescriptor = KTPermissionDescriptor::get($oPA->getPermissionDescriptorID()); 79 + $oDescriptor = KTPermissionDescriptor::get($oPLA->getPermissionDescriptorID());
68 $iPermissionID = $oPermission->getID(); 80 $iPermissionID = $oPermission->getID();
69 $aIDs = $oDescriptor->getGroups(); 81 $aIDs = $oDescriptor->getGroups();
70 $aMapPermissionGroup[$iPermissionID] = array(); 82 $aMapPermissionGroup[$iPermissionID] = array();
71 foreach ($aIDs as $iID) { 83 foreach ($aIDs as $iID) {
72 $aMapPermissionGroup[$iPermissionID][$iID] = true; 84 $aMapPermissionGroup[$iPermissionID][$iID] = true;
  85 + $aActiveGroups[$iID] = true;
73 } 86 }
74 $aIds = $oDescriptor->getRoles(); 87 $aIds = $oDescriptor->getRoles();
75 $aMapPermissionRole[$iPermissionID] = array(); 88 $aMapPermissionRole[$iPermissionID] = array();
76 foreach ($aIds as $iId) { 89 foreach ($aIds as $iId) {
77 $aMapPermissionRole[$iPermissionID][$iId] = true; 90 $aMapPermissionRole[$iPermissionID][$iId] = true;
  91 + $aActiveRoles[$iId] = true;
  92 + }
  93 + $aIds = $oDescriptor->getUsers();
  94 + $aMapPermissionUser[$iPermissionID] = array();
  95 + foreach ($aIds as $iId) {
  96 + $aMapPermissionUser[$iPermissionID][$iId] = true;
  97 + $aActiveUsers[$iId] = true;
78 } 98 }
79 } 99 }
  100 +
  101 + // now we constitute the actual sets.
  102 + $users = array();
  103 + $groups = array();
  104 + $roles = array(); // should _always_ be empty, barring a bug in permissions::updatePermissionLookup
80 105
81 - $oInherited = KTPermissionUtil::findRootObjectForPermissionObject($oPO);  
82 - if ($oInherited === $this->oDocument) {  
83 - $bEdit = true;  
84 - } else {  
85 - $iInheritedFolderID = $oInherited->getID();  
86 - /* $sInherited = displayFolderPathLink(Folder::getFolderPathAsArray($iInheritedFolderID),  
87 - Folder::getFolderPathNamesAsArray($iInheritedFolderID),  
88 - "$default->rootUrl/control.php?action=editFolderPermissions");*/  
89 - $sInherited = join(" &raquo; ", $oInherited->getPathArray());  
90 - $bEdit = false;  
91 - } 106 + // this should be quite limited - direct role -> user assignment is typically rare.
  107 + foreach ($aActiveUsers as $id => $marker) {
  108 + $oUser = User::get($id);
  109 + $users[$oUser->getName()] = $oUser;
  110 + }
  111 + asort($users); // ascending, per convention.
  112 +
  113 + foreach ($aActiveGroups as $id => $marker) {
  114 + $oGroup = Group::get($id);
  115 + $groups[$oGroup->getName()] = $oGroup;
  116 + }
  117 + asort($groups);
  118 +
  119 + foreach ($aActiveRoles as $id => $marker) {
  120 + $oRole = Role::get($id);
  121 + $roles[$oRole->getName()] = $oRole;
  122 + }
  123 + asort($roles);
  124 +
  125 + $bEdit = false;
  126 + $sInherited = '';
92 127
93 $aTemplateData = array( 128 $aTemplateData = array(
94 "context" => $this, 129 "context" => $this,
95 "permissions" => $aPermissions, 130 "permissions" => $aPermissions,
96 - "groups" => Group::getList(),  
97 - "roles" => Role::getList(), 131 + "groups" => $groups,
  132 + "users" => $users,
  133 + "roles" => $roles,
98 "iDocumentID" => $_REQUEST['fDocumentID'], 134 "iDocumentID" => $_REQUEST['fDocumentID'],
99 "aMapPermissionGroup" => $aMapPermissionGroup, 135 "aMapPermissionGroup" => $aMapPermissionGroup,
100 "aMapPermissionRole" => $aMapPermissionRole, 136 "aMapPermissionRole" => $aMapPermissionRole,
  137 + "aMapPermissionUser" => $aMapPermissionUser,
101 "edit" => $bEdit, 138 "edit" => $bEdit,
102 "inherited" => $sInherited, 139 "inherited" => $sInherited,
103 ); 140 );
@@ -509,3 +546,93 @@ class KTRoleAllocationPlugin extends KTFolderAction { @@ -509,3 +546,93 @@ class KTRoleAllocationPlugin extends KTFolderAction {
509 } 546 }
510 } 547 }
511 } 548 }
  549 +
  550 +class KTDocumentRolesAction extends KTDocumentAction {
  551 + var $sDisplayName = 'View Roles';
  552 + var $sName = 'ktcore.actions.document.roles';
  553 +
  554 + var $_sShowPermission = "ktcore.permissions.write";
  555 + var $bAutomaticTransaction = true;
  556 +
  557 + function do_main() {
  558 + $this->oPage->setTitle(_("View Roles"));
  559 + $this->oPage->setBreadcrumbDetails(_("View Roles"));
  560 + $oTemplating = new KTTemplating;
  561 + $oTemplate = $oTemplating->loadTemplate("ktcore/action/view_roles");
  562 +
  563 + // we need to have:
  564 + // - a list of roles
  565 + // - with their users / groups
  566 + // - and that allocation id
  567 + $aRoles = array(); // stores data for display.
  568 +
  569 + $aRoleList = Role::getList();
  570 + foreach ($aRoleList as $oRole) {
  571 + $iRoleId = $oRole->getId();
  572 + $aRoles[$iRoleId] = array("name" => $oRole->getName());
  573 + $oRoleAllocation = DocumentRoleAllocation::getAllocationsForDocumentAndRole($this->oDocument->getId(), $iRoleId);
  574 + if (is_null($oRoleAllocation)) {
  575 + $oRoleAllocation = RoleAllocation::getAllocationsForFolderAndRole($this->oDocument->getFolderID(), $iRoleId);
  576 + }
  577 +
  578 + $u = array();
  579 + $g = array();
  580 + $aid = null;
  581 + $raid = null;
  582 + if (is_null($oRoleAllocation)) {
  583 + ; // nothing.
  584 + } else {
  585 + //var_dump($oRoleAllocation);
  586 + $raid = $oRoleAllocation->getId(); // real_alloc_id
  587 + $aAllowed = $oRoleAllocation->getAllowed();
  588 +
  589 + if (!empty($aAllowed['user'])) {
  590 + $u = $aAllowed['user'];
  591 + }
  592 + if (!empty($aAllowed['group'])) {
  593 + $g = $aAllowed['group'];
  594 + }
  595 + }
  596 + $aRoles[$iRoleId]['users'] = $u;
  597 + $aRoles[$iRoleId]['groups'] = $g;
  598 + $aRoles[$iRoleId]['real_allocation_id'] = $raid;
  599 + }
  600 +
  601 + // final step.
  602 +
  603 + // map to users, groups.
  604 + foreach ($aRoles as $key => $role) {
  605 + $_users = array();
  606 + foreach ($aRoles[$key]['users'] as $iUserId) {
  607 + $oUser = User::get($iUserId);
  608 + if (!(PEAR::isError($oUser) || ($oUser == false))) {
  609 + $_users[] = $oUser->getName();
  610 + }
  611 + }
  612 + if (empty($_users)) {
  613 + $aRoles[$key]['users'] = '<span class="descriptiveText"> ' . _('no users') . '</span>';
  614 + } else {
  615 + $aRoles[$key]['users'] = implode(', ',$_users);
  616 + }
  617 +
  618 + $_groups = array();
  619 + foreach ($aRoles[$key]['groups'] as $iGroupId) {
  620 + $oGroup = Group::get($iGroupId);
  621 + if (!(PEAR::isError($oGroup) || ($oGroup == false))) {
  622 + $_groups[] = $oGroup->getName();
  623 + }
  624 + }
  625 + if (empty($_groups)) {
  626 + $aRoles[$key]['groups'] = '<span class="descriptiveText"> ' . _('no groups') . '</span>';
  627 + } else {
  628 + $aRoles[$key]['groups'] = implode(', ',$_groups);
  629 + }
  630 + }
  631 +
  632 + $aTemplateData = array(
  633 + 'context' => &$this,
  634 + 'roles' => $aRoles,
  635 + );
  636 + return $oTemplate->render($aTemplateData);
  637 + }
  638 +}
512 \ No newline at end of file 639 \ No newline at end of file
plugins/ktcore/admin/plugins.php
@@ -63,12 +63,8 @@ class KTPluginDispatcher extends KTAdminDispatcher { @@ -63,12 +63,8 @@ class KTPluginDispatcher extends KTAdminDispatcher {
63 63
64 function do_update() { 64 function do_update() {
65 $sTable = KTUtil::getTableName('plugins'); 65 $sTable = KTUtil::getTableName('plugins');
66 - $aIds = KTUtil::arrayGet($_REQUEST, 'pluginids');  
67 - $sIds = DBUtil::paramArray($aIds);  
68 - $sQuery = sprintf('UPDATE %s SET disabled = 1 WHERE id NOT IN (%s)', $sTable, $sIds);  
69 - DBUtil::runQuery(array($sQuery, $aIds));  
70 - $sQuery = sprintf('UPDATE %s SET disabled = 0 WHERE id IN (%s)', $sTable, $sIds);  
71 - DBUtil::runQuery(array($sQuery, $aIds)); 66 + $aIds = (array) KTUtil::arrayGet($_REQUEST, 'pluginids');
  67 + KTPluginEntity::setEnabled($aIds);
72 $this->successRedirectToMain('Plugins updated'); 68 $this->successRedirectToMain('Plugins updated');
73 } 69 }
74 70
resources/js/toggleselect.js
@@ -20,6 +20,7 @@ function toggleSelectFor(source, nameprefix) { @@ -20,6 +20,7 @@ function toggleSelectFor(source, nameprefix) {
20 if (c.type == 'checkbox') { 20 if (c.type == 'checkbox') {
21 if ((n.length >= nameprefix.length) && (nameprefix == n.substring(0,nameprefix.length))) { 21 if ((n.length >= nameprefix.length) && (nameprefix == n.substring(0,nameprefix.length))) {
22 c.checked = state; 22 c.checked = state;
  23 + activateRow(c);
23 } 24 }
24 } 25 }
25 } 26 }
templates/ktcore/document/document_permissions.smarty
1 <h2>{i18n}Document permissions{/i18n}</h2> 1 <h2>{i18n}Document permissions{/i18n}</h2>
2 2
3 -  
4 -  
5 -{if ((empty($roles) && empty($groups)))}  
6 -<div class="ktInfo"><p>{i18n}No roles or groups have been defined. Permissions can only  
7 -be allocated to roles and groups.{/i18n}</p></div> 3 +<p class="descriptiveText">{i18n}This page shows the permissions that apply to
  4 +this specific document. Where the folder view shows you information by role and group,
  5 +this page shows the actual groups (and, if they are assigned directly to a role, the users)
  6 +who have the different permissions. As a result, groups, users and roles with <strong>no</strong>
  7 +permissions are not shown.{/i18n}</p>
  8 +
  9 +{if ((empty($roles) && empty($groups) && empty($users)))}
  10 +<div class="ktInfo"><p>{i18n}No roles or groups have been defined or have permissions.{/i18n}</p></div>
8 {else} 11 {else}
9 12
10 -{*  
11 -  
12 -{if $iFolderId != 1}  
13 -<div class="ktInfo">  
14 -{ if $inherited }  
15 -<p>{i18n arg_permission_source=$inherited}This folder <strong>inherits</strong> its permissions from #permission_source#.{/i18n}  
16 -<a class="ktActionLink ktEdit"  
17 - href="{addQS}action=copyPermissions&fFolderId={$iFolderId}{/addQS}">{i18n}Override Permissions{/i18n}</a> </p>  
18 -{ else }  
19 -<p>{i18n}This folder defines its own permissions.{/i18n}  
20 -<a class="ktActionLink ktDelete"  
21 - href="{addQS}action=inheritPermissions&fFolderId={$iFolderId}{/addQS}">{i18n}Inherit permissions{/i18n}</a>  
22 -{ /if }  
23 -</span>  
24 -</div>  
25 -{ /if }  
26 -  
27 -*}  
28 -  
29 <form action="{$smarty.server.PHP_SELF}" method="POST"> 13 <form action="{$smarty.server.PHP_SELF}" method="POST">
30 <input type="hidden" name="action" value="update"> 14 <input type="hidden" name="action" value="update">
31 <input type="hidden" name="fFolderId" value="{$iFolderId}"> 15 <input type="hidden" name="fFolderId" value="{$iFolderId}">
@@ -94,6 +78,36 @@ value=&quot;{$iGroupId}&quot;&gt;&lt;/td&gt; @@ -94,6 +78,36 @@ value=&quot;{$iGroupId}&quot;&gt;&lt;/td&gt;
94 { /foreach } 78 { /foreach }
95 </tr> 79 </tr>
96 { /foreach } 80 { /foreach }
  81 +
  82 +
  83 +{ foreach item=oUser from=$users }
  84 +<td><span class="descriptiveText">{i18n}User: {/i18n}</span> {$oUser->getName()}</td>
  85 + { assign var=iUserId value=$oUser->getId() }
  86 + { foreach item=oPerm from=$permissions }
  87 + { assign var=iPermId value=$oPerm->getId() }
  88 + { assign var=bHasPerm value=$aMapPermissionUser[$iPermId][$iUserId] }
  89 +
  90 +{ if $edit}
  91 +{ if $bHasPerm }
  92 +<td class="centered"><input type="checkbox" name="foo[{$iPermId}][group][]"
  93 +value="{$iGroupId}" checked="true"></td>
  94 +{ else }
  95 +<td class="centered"><input type="checkbox" name="foo[{$iPermId}][group][]"
  96 +value="{$iGroupId}"></td>
  97 +{ /if }
  98 +{else}
  99 +{ if $bHasPerm }
  100 +<td class="centered"><span class="ktAction ktInline ktAllowed">{i18n}Allowed{/i18n}</span></td>
  101 +{ else }
  102 +<td class="centered"><span class="ktAction ktInline ktDenied">{i18n}Denied{/i18n}</span></td>
  103 +{ /if }
  104 +{/if}
  105 +
  106 +
  107 + { /foreach }
  108 +</tr>
  109 +{ /foreach }
  110 +
97 </tbody> 111 </tbody>
98 </table> 112 </table>
99 {if $edit} 113 {if $edit}
var/cache/.empty 0 → 100644