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);
             }
         }
     }
 }
Exemplo n.º 2
0
/**
* 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;
}
Exemplo n.º 3
0
 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;
 }
Exemplo n.º 4
0
 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);
 }
Exemplo n.º 5
0
 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;
 }
Exemplo n.º 6
0
 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);
     }
 }
Exemplo n.º 7
0
 /**
  * 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;
 }
Exemplo n.º 8
0
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;
 }
Exemplo n.º 10
0
 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;
 }
Exemplo n.º 12
0
 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);
 }
Exemplo n.º 13
0
 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;
 }
Exemplo n.º 14
0
 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;
 }
Exemplo n.º 15
0
 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');
 }
Exemplo n.º 16
0
 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;
 }