function renegeratePermissionsForRole($iRoleId, $iFolderId) { $iStartFolderId = $iFolderId; /* * 1. find all folders & documents "below" this one which use the role * definition _active_ (not necessarily present) at this point. * 2. tell permissionutil to regen their permissions. * * The find algorithm is: * * folder_queue <- (iStartFolderId) * while folder_queue is not empty: * active_folder = * for each folder in the active_folder: * find folders in _this_ folder without a role-allocation on the iRoleId * add them to the folder_queue * update the folder's permissions. * find documents in this folder: * update their permissions. */ $sRoleAllocTable = KTUtil::getTableName('role_allocations'); $sFolderTable = KTUtil::getTableName('folders'); $sQuery = sprintf('SELECT f.id as id FROM %s AS f LEFT JOIN %s AS ra ON (f.id = ra.folder_id) WHERE ra.id IS NULL AND f.parent_id = ?', $sFolderTable, $sRoleAllocTable); $folder_queue = array($iStartFolderId); while (!empty($folder_queue)) { $active_folder = array_pop($folder_queue); $aParams = array($active_folder); $aNewFolders = DBUtil::getResultArrayKey(array($sQuery, $aParams), 'id'); if (PEAR::isError($aNewFolders)) { //$this->errorRedirectToMain(_kt('Failure to generate folderlisting.')); echo _kt('Failure to generate folderlisting.'); } $folder_queue = kt_array_merge($folder_queue, (array) $aNewFolders); // push. // update the folder. $oFolder =& Folder::get($active_folder); if (PEAR::isError($oFolder) || $oFolder == false) { //$this->errorRedirectToMain(_kt('Unable to locate folder: ') . $active_folder); echo _kt('Unable to locate folder: ') . $active_folder; } KTPermissionUtil::updatePermissionLookup($oFolder); $aDocList =& Document::getList(array('folder_id = ?', $active_folder)); if (PEAR::isError($aDocList) || $aDocList === false) { //$this->errorRedirectToMain(sprintf(_kt('Unable to get documents in folder %s: %s'), $active_folder, $aDocList->getMessage())); echo _kt('Unable to get documents in folder ') . $active_folder; } foreach ($aDocList as $oDoc) { if (!PEAR::isError($oDoc)) { KTPermissionUtil::updatePermissionLookup($oDoc); } } } }
/** * Returns the relevant tags for the current user * * @return array */ function get_relevant_tags($oUser, $sTag) { $aTagList = isset($_SESSION['tagList']) ? $_SESSION['tagList'] : array(); $tagTree = array(); $documentList = ''; // Get the previous tag info: // the list of documents that contain the tag to search within // the tags that have already been filtered so they aren't displayed again if (!empty($aTagList)) { $aPrevTag = end($aTagList); $sPrevTag = $aPrevTag['tag']; $documentList = $aPrevTag['docs']; $tagTree = $aPrevTag['tagTree']; } if (empty($sTag)) { // If there is no tag specified then get all tags. $aUserPermissions = KTSearchUtil::permissionToSQL($oUser, 'ktcore.permissions.read'); if (PEAR::isError($aUserPermissions)) { return array(); } // ensure the user has read permission on the documents list($sWhere, $aParams, $sJoins) = $aUserPermissions; $sql = "SELECT TW.tag, count(*) as freq\n \t\tFROM document_tags DT\n \t\tINNER JOIN tag_words TW ON DT.tag_id=TW.id\n \t\tWHERE DT.document_id in (SELECT D.id FROM documents D {$sJoins} WHERE {$sWhere} AND D.status_id = '1')\n \t\tGROUP BY TW.tag"; $tags = DBUtil::getResultArray(array($sql, $aParams)); } else { // Create a new tag query to get the document id's associated with the tag $oQuery = new TagQuery($oUser, $sTag); $aOptions = array(); $aOptions['select'] = 'DISTINCT DTS.document_id'; $aQuery = $oQuery->getQuery($aOptions); $sInnerQuery = $aQuery[0]; $aParams = $aQuery[1]; $aDocIds = DBUtil::getResultArrayKey($aQuery, 'document_id'); $sDocs = implode(',', $aDocIds); // Make sure user not opening a new window on tag cloud filters if (!$sDocs) { return array(); } // Don't display tags that have already been selected. $tagTree[] = $sTag; $cnt = count($tagTree); $sIgnoreTags = '?'; for ($i = 1; $i < $cnt; $i++) { $sIgnoreTags .= ',?'; } // Get the tags within the documents that haven't been selected before $sQuery = "SELECT TW.tag, count(*) as freq\n FROM document_tags DT INNER JOIN tag_words TW ON DT.tag_id=TW.id\n WHERE DT.document_id in ({$sDocs}) AND TW.tag NOT IN ({$sIgnoreTags})\n GROUP BY TW.tag"; $tags = DBUtil::getResultArray(array($sQuery, $tagTree)); if (PEAR::isError($tags)) { echo $tags->getMessage(); } // Add new tag to the session if ($sPrevTag != $sTag) { $aTagList[] = array('tag' => $sTag, 'docs' => $sDocs, 'tagTree' => $tagTree); $_SESSION['tagList'] = $aTagList; } } $aTags = array(); if ($tags) { foreach ($tags as $tag) { $word = $tag['tag']; $freq = $tag['freq']; $aTags[$word] = $freq; } } return $aTags; }
function _getSubscribers($iObjectId, $iSubType) { global $default; // for the logging. if (KTLOG_CACHE) { $default->log->debug("_getSubscribers(id={$iObjectId}, type={$iSubType}); table=" . Subscription::getTableName($iSubType) . "; id=" . Subscription::getIdFieldName($iSubType)); } $aUsers = array(); $aNewUsers = array(); $aSubUsers = array(); $table = Subscription::getTableName($iSubType); $field = Subscription::getIdFieldName($iSubType); // If we're dealing with a folder then get those user who are subscribed to one of the parent folders and want notifications on sub folders if ($iSubType == $this->subscriptionTypes["Folder"] && $iObjectId != 1) { // Get parent folder ids $query = "SELECT parent_folder_ids FROM folders WHERE id = {$iObjectId}"; $aParentIds = DBUtil::getResultArrayKey($query, 'parent_folder_ids'); $parentIds = $aParentIds[0]; // Get those users who have checked the subfolders option on the above folders $query = "SELECT user_id FROM {$table} WHERE {$field} IN ({$parentIds}) AND with_subfolders = 1"; $aSubUsers = DBUtil::getResultArrayKey($query, 'user_id'); } $sQuery = "SELECT user_id FROM {$table} WHERE {$field} = ?"; $aParams = array($iObjectId); $aNewUsers = DBUtil::getResultArrayKey(array($sQuery, $aParams), 'user_id'); // Add any users from parent folders $aNewUsers = array_merge($aNewUsers, $aSubUsers); $aNewUsers = array_unique($aNewUsers); // Remove alerted users $aNewUsers = $this->_pruneAlertedUsers($aNewUsers); $iCurrentUserId = $_SESSION['userID']; // notionally less efficient than the old code. if its a big issue, can easily // be refactored. foreach ($aNewUsers as $iUserId) { // the user doesn't need to be notified for his/her own modifications if ($iUserId == $iCurrentUserId) { continue; } $oUser =& User::get($iUserId); // do a quick prune here, for performance/maintenance reasons. if (PEAR::isError($oUser) || $oUser == false) { $sQuery = "DELETE FROM " . Subscription::getTableName($iSubType) . " WHERE user_id = ?"; $aParams = array($iUserId); DBUtil::runQuery(array($sQuery, $sParams)); $default->log->error("SubscriptionEvent::fireSubscription error removing subscription for user id={$iUserId}"); } else { $aUsers[] = $oUser; } } if (KTLOG_CACHE) { $default->log->debug('retrieveSubscribers found count=' . count($aUsers)); } return $aUsers; }
function &getAllocationsForFolderAndRole($iFolderId, $iRoleId) { // FIXME the query we use here is ... not very pleasant. // NBM: is this the "right" way to do this? $raTable = KTUtil::getTableName('role_allocations'); $fTable = Folder::_table(); $oFolder =& Folder::get($iFolderId); // if its an invalid folder, we simply return null, since this is undefined anyway. if (PEAR::isError($oFolder)) { return null; } $parents = Folder::generateFolderIds($iFolderId); // FIXME what (if anything) do we need to do to check that this can't be used as an attack? $folders = '(' . $parents . ')'; $sQuery = "SELECT ra.id as `id` FROM " . $raTable . " AS ra " . ' LEFT JOIN ' . $fTable . ' AS f ON (f.id = ra.folder_id) ' . ' WHERE f.id IN ' . $folders . ' AND ra.role_id = ?' . ' ORDER BY CHAR_LENGTH(f.parent_folder_ids) desc, f.parent_folder_ids DESC'; $aParams = array($iRoleId); $aRoleAllocIds = DBUtil::getResultArrayKey(array($sQuery, $aParams), 'id'); if (false) { print '<pre>'; var_dump($aRoleAllocIds); print ''; print $sQuery; print '</pre>'; } if (empty($aRoleAllocIds)) { return null; } $iAllocId = $aRoleAllocIds[0]; // array pop? return RoleAllocation::get($iAllocId); }
function &getAssociatedTypes() { // NOTE: this returns null if we are generic (all is the wrong answer) if ($this->getIsGeneric()) { return array(); } $sTable = KTUtil::getTableName('document_type_fieldsets'); $aQuery = array("SELECT document_type_id FROM {$sTable} WHERE fieldset_id = ?", array($this->getId())); $aIds = DBUtil::getResultArrayKey($aQuery, 'document_type_id'); $aRet = array(); foreach ($aIds as $iID) { $oType = DocumentType::get($iID); if (!PEAR::isError($oType)) { $aRet[] = $oType; } } return $aRet; }
function rebuildPermissionLookups($bEmptyOnly = true) { if ($bEmptyOnly) { $sTable = KTUtil::getTableName('folders'); $sQuery = sprintf("SELECT id FROM %s WHERE permission_lookup_id IS NULL AND permission_object_id IS NOT NULL", $sTable); } else { $sTable = KTUtil::getTableName('folders'); $sQuery = sprintf("SELECT id FROM %s WHERE permission_object_id IS NOT NULL", $sTable); } $aIds = DBUtil::getResultArrayKey($sQuery, 'id'); foreach ($aIds as $iId) { $oFolder =& Folder::get($iId); KTPermissionUtil::updatePermissionLookup($oFolder); } if ($bEmptyOnly) { $sTable = KTUtil::getTableName('documents'); $sQuery = sprintf("SELECT id FROM %s WHERE permission_lookup_id IS NULL", $sTable); } else { $sTable = KTUtil::getTableName('documents'); $sQuery = sprintf("SELECT id FROM %s", $sTable); } $aIds = DBUtil::getResultArrayKey($sQuery, 'id'); foreach ($aIds as $iId) { $oDocument =& Document::get($iId); KTPermissionUtil::updatePermissionLookup($oDocument); } }
/** * Finds folders that aren't reachable by the user but to which the * user has read permissions. * * Returns an array of Folder objects. */ function getBrowseableFolders($oUser) { $aPermissionDescriptors = KTPermissionUtil::getPermissionDescriptorsForUser($oUser); if (empty($aPermissionDescriptors)) { return array(); } $sPermissionDescriptors = DBUtil::paramArray($aPermissionDescriptors); $oPermission = KTPermission::getByName('ktcore.permissions.read'); $oPermission2 = KTPermission::getByName('ktcore.permissions.folder_details'); $aPermissionIds = array($oPermission->getId(), $oPermission->getId(), $oPermission2->getId(), $oPermission2->getId()); $sFoldersTable = KTUtil::getTableName('folders'); $sPLTable = KTUtil::getTableName('permission_lookups'); $sPLATable = KTUtil::getTableName('permission_lookup_assignments'); $sQuery = "SELECT DISTINCT F.id AS id FROM\n {$sFoldersTable} AS F\n LEFT JOIN {$sPLTable} AS PL ON F.permission_lookup_id = PL.id\n LEFT JOIN {$sPLATable} AS PLA ON PLA.permission_lookup_id = PL.id AND (PLA.permission_id = ? || PLA.permission_id = ?)\n\n LEFT JOIN {$sFoldersTable} AS F2 ON F.parent_id = F2.id\n LEFT JOIN {$sPLTable} AS PL2 ON F2.permission_lookup_id = PL2.id\n LEFT JOIN {$sPLATable} AS PLA2 ON PLA2.permission_lookup_id = PL2.id AND (PLA2.permission_id = ? || PLA.permission_id = ?)\n WHERE\n PLA.permission_descriptor_id IN ({$sPermissionDescriptors})\n AND F2.id <> 1\n AND NOT (PLA2.permission_descriptor_id IN ({$sPermissionDescriptors}))"; $aParams = kt_array_merge($aPermissionIds, $aPermissionDescriptors, $aPermissionDescriptors); $res = DBUtil::getResultArrayKey(array($sQuery, $aParams), 'id'); if (PEAR::isError($res)) { return $res; } $aFolders = array(); foreach ($res as $iFolderId) { $aFolders[] = Folder::get($iFolderId); } return $aFolders; }
function checkRepoVersions($oDocument) { global $fsPath, $aRepoVersionProblems; $table = 'document_transactions'; $aVersions = DBUtil::getResultArrayKey(array("SELECT DISTINCT version FROM {$table} WHERE document_id = ?", array($oDocument->getID())), 'version'); foreach ($aVersions as $sVersion) { if ($sVersion == $oDocument->getVersion()) { continue; } $sDocumentPath = $oDocument->getStoragePath(); $sFullPath = sprintf('%s/%s-%s', $fsPath, $sDocumentPath, $sVersion); if (!is_file($sFullPath)) { $aRepoVersionProblems[] = array($sDocumentPath, $sVersion); continue; } } }
function &getByUsers($aUsers, $aOptions = null) { $sTable = KTUtil::getTableName('permission_descriptor_users'); if (is_null($aOptions)) { $aOptions = array(); } if (count($aUsers) === 0) { return array(); } $ids = KTUtil::arrayGet($aOptions, 'ids'); $aUserIDs = array(); foreach ($aUsers as $oUser) { if (is_numeric($oUser)) { $aUserIDs[] = $oUser; } else { $aUserIDs[] = $oUser->getID(); } } $sUserIDs = DBUtil::paramArray($aUserIDs); $sQuery = "SELECT DISTINCT descriptor_id FROM {$sTable} WHERE user_id IN ( {$sUserIDs} )"; $aParams = $aUserIDs; $aIDs = DBUtil::getResultArrayKey(array($sQuery, $aParams), 'descriptor_id'); $aRet = array(); foreach ($aIDs as $iID) { if ($ids === true) { $aRet[] = $iID; } else { $aRet[] =& KTPermissionDescriptor::get($iID); } } return $aRet; }
function getChildrenDocumentTransactions($iParentFolderId, $depth = '1') { $aParams = array($iParentFolderId); if ($depth == '1') { // Get direct child document id's $sQuery = "SELECT id FROM documents WHERE folder_id = ?"; } else { // Get all documents in child folders if ($iParentFolderId == 1) { $sQuery = "SELECT id FROM documents WHERE parent_folder_ids LIKE '?' OR parent_folder_ids LIKE '?,%'"; } $sQuery = "SELECT id FROM documents WHERE parent_folder_ids LIKE '%,?' OR parent_folder_ids LIKE '%,?,%'"; $aParams[] = $iParentFolderId; } $aDocumentList = DBUtil::getResultArrayKey(array($sQuery, $aParams), 'id'); if (PEAR::isError($aDocumentList)) { // XXX: log error return false; } if ($aDocumentList) { $aDocumentTransactions = KTrss::getDocumentTransactions($aDocumentList); } if ($aDocumentTransactions) { return $aDocumentTransactions; } }
function getSourceStates($oTransition, $aOptions = null) { $bIds = KTUtil::arrayGet($aOptions, 'ids'); $sTable = KTUtil::getTableName('workflow_state_transitions'); $aQuery = array("SELECT state_id FROM {$sTable} WHERE transition_id = ?", array($oTransition->getId())); $aStateIds = DBUtil::getResultArrayKey($aQuery, 'state_id'); if (PEAR::isError($aStateIds)) { return $aStateIds; } if ($bIds) { return $aStateIds; } $aRet = array(); foreach ($aStateIds as $iId) { $aRet[] =& KTWorkflowState::get($iId); } return $aRet; }
function buildQuery($aFolderIds) { $sFolderList = implode(', ', $aFolderIds); // First we get any document shortcuts $query = "SELECT linked_document_id FROM documents\n WHERE linked_document_id IS NOT NULL\n AND folder_id IN ({$sFolderList})"; $aLinkedDocIds = DBUtil::getResultArrayKey($query, 'linked_document_id'); if (PEAR::isError($aLinkedDocIds) || empty($aLinkedDocIds)) { $sDocList = ''; } else { $sDocList = implode(', ', $aLinkedDocIds); } // Get the permissions sql $oUser = User::get($_SESSION['userID']); $res = KTSearchUtil::permissionToSQL($oUser, $this->sPermissionName); if (PEAR::isError($res)) { return $res; } list($sPermissionString, $aPermissionParams, $sPermissionJoin) = $res; // Create the "where" criteria $sWhere = "WHERE {$sPermissionString} AND (D.folder_id IN ({$sFolderList})"; $sWhere .= !empty($sDocList) ? " OR D.id IN ({$sDocList}))" : ')'; $sWhere .= ' AND D.status_id = 1 AND linked_document_id IS NULL'; // Create the query $sQuery = "SELECT DISTINCT(D.id) FROM documents AS D\n LEFT JOIN document_metadata_version AS DM ON D.metadata_version_id = DM.id\n LEFT JOIN document_content_version AS DC ON DM.content_version_id = DC.id\n {$sPermissionJoin} {$sWhere}"; return array($sQuery, $aPermissionParams); }
function _listGroupIDsForUserExpand($oUser) { $iUserId = KTUtil::getId($oUser); global $default; $oCache = KTCache::getSingleton(); $group = "groupidsforuser"; if (PEAR::isError($oUser)) { var_dump($oUser); } list($bCached, $mCached) = $oCache->get($group, $oUser->getId()); if ($bCached) { if (KTLOG_CACHE) { $default->log->debug(sprintf("Using group cache for _listGroupIDsForUserExpand %d", $iUserId)); } return $mCached; } // Get all subgroups $aSubGroups = GroupUtil::_listSubGroups(); $aGroupArray = array(); if (!empty($aSubGroups)) { $aGroupArray = GroupUtil::_invertGroupArray($aSubGroups); } //$aGroupArray = GroupUtil::_invertGroupArray(GroupUtil::buildGroupArray()); //$aDirectGroups = GroupUtil::listGroupsForUser($oUser); $sQuery = "SELECT group_id FROM {$default->users_groups_table} WHERE user_id = ?"; $aParams = array($iUserId); $aGroupIDs = DBUtil::getResultArrayKey(array($sQuery, $aParams), "group_id"); if (!empty($aGroupArray)) { foreach ($aGroupIDs as $iGroupID) { $aExtraIDs = KTUtil::arrayGet($aGroupArray, $iGroupID); if (is_array($aExtraIDs)) { $aGroupIDs = kt_array_merge($aGroupIDs, $aExtraIDs); } } } $aGroupIDs = array_unique($aGroupIDs); sort($aGroupIDs); $oCache->set($group, $oUser->getId(), $aGroupIDs); return $aGroupIDs; }
function fieldsetsForDocument($oDocument, $iTypeOverride = null) { global $default; $oDocument = KTUtil::getObject('Document', $oDocument); $iMetadataVersionId = $oDocument->getMetadataVersionId(); $iDocumentTypeId = $oDocument->getDocumentTypeId(); if (!is_null($iTypeOverride)) { $iDocumentTypeId = $iTypeOverride; } $sQuery = "SELECT DISTINCT F.id AS fieldset_id " . "FROM {$default->document_metadata_version_table} AS DM INNER JOIN document_fields_link AS DFL ON DM.id = DFL.metadata_version_id " . "INNER JOIN {$default->document_fields_table} AS DF ON DF.ID = DFL.document_field_id " . "INNER JOIN {$default->fieldsets_table} AS F ON F.id = DF.parent_fieldset " . "WHERE DM.id = ?" . "AND F.disabled = false"; $aParam = array($iMetadataVersionId); $aDocumentFieldsetIds = DBUtil::getResultArrayKey(array($sQuery, $aParam), 'fieldset_id'); $aGenericFieldsetIds = KTFieldset::getGenericFieldsets(array('ids' => true)); $aSpecificFieldsetIds = KTFieldset::getForDocumentType($iDocumentTypeId, array('ids' => true)); $aFieldsetIds = kt_array_merge($aDocumentFieldsetIds, $aGenericFieldsetIds, $aSpecificFieldsetIds); $aFieldsetIds = array_unique($aFieldsetIds); sort($aFieldsetIds); $aRet = array(); foreach ($aFieldsetIds as $iID) { $aRet[] = call_user_func(array('KTFieldset', 'get'), $iID); } return $aRet; }
function getDisabledActionsForState($oState) { $iStateId = KTUtil::getId($oState); $sTable = KTUtil::getTableName('workflow_state_disabled_actions'); $aQuery = array("SELECT action_name FROM {$sTable} WHERE state_id = ?", array($iStateId)); return DBUtil::getResultArrayKey($aQuery, 'action_name'); }
function cleanupGroupMembership() { // 4 cases. $child_query = 'select L.id as link_id FROM groups_groups_link as L left outer join groups_lookup as G on (L.member_group_id = G.id) WHERE G.id IS NULL'; $parent_query = 'select L.id as link_id FROM groups_groups_link as L left outer join groups_lookup as G on (L.parent_group_id = G.id) WHERE G.id IS NULL'; $group_query = 'select L.id as link_id FROM users_groups_link as L left outer join groups_lookup as G on (L.group_id = G.id) WHERE G.id IS NULL'; $user_query = 'select L.id as link_id FROM users_groups_link as L left outer join users as U on (L.user_id = U.id) WHERE U.id IS NULL'; $bad_group_links = array(); $res = DBUtil::getResultArrayKey(array($child_query, null), 'link_id'); if (PEAR::isError($res)) { return $res; } else { $bad_group_links = $res; } $res = DBUtil::getResultArrayKey(array($parent_query, null), 'link_id'); if (PEAR::isError($res)) { return $res; } else { $bad_group_links = kt_array_merge($bad_group_links, $res); } foreach ($bad_group_links as $link_id) { $res = DBUtil::runQuery(array("DELETE FROM groups_groups_link WHERE id = ?", $link_id)); if (PEAR::isError($res)) { return $res; } } $res = DBUtil::getResultArrayKey(array($group_query, null), 'link_id'); if (PEAR::isError($res)) { return $res; } else { $bad_user_links = $res; } $res = DBUtil::getResultArrayKey(array($user_query, null), 'link_id'); if (PEAR::isError($res)) { return $res; } else { $bad_user_links = kt_array_merge($bad_user_links, $res); } foreach ($bad_user_links as $link_id) { $res = DBUtil::runQuery(array("DELETE FROM users_groups_link WHERE id = ?", $link_id)); if (PEAR::isError($res)) { return $res; } } return true; }
function deleteByCondition($oCondition) { $iConditionId = KTUtil::getId($oCondition); $sTable = KTUtil::getTableName('permission_dynamic_conditions'); $sAssignmentsTable = KTUtil::getTableName('permission_dynamic_assignments'); $aQuery = array(sprintf('SELECT id FROM %s WHERE condition_id = ?', $sTable), array($iConditionId)); $aIds = DBUtil::getResultArrayKey($aQuery, 'id'); $sParam = DBUtil::paramArray($aIds); $aAssignmentQuery = array(sprintf('DELETE FROM %s WHERE dynamic_condition_id IN (%s)', $sAssignmentsTable, $sParam), $aIds); DBUtil::runQuery($aAssignmentQuery); $aConditionQuery = array(sprintf('DELETE FROM %s WHERE id IN (%s)', $sTable, $sParam), $aIds); DBUtil::runQuery($aAssignmentQuery); return; }