/** * This function return an iterator on a list of documents (no folders). * * How it works: * 1. Get the list of all documents that match the criteria (if * any!). (permissions apply). * Note: the final list of documents is a subset of this result. * 2. Get the list of folders behind $parentId (permissions apply). * 3. Check that each document in list 1. is in a folder of list 2. * 5. Apply limits ($start, $offset) is only a subset of the list is required. * 6. If needed, add the metadata to the items. */ function &getItemSubTreeAsList($parentId, &$nbItemsFound, $params = null) { $_parentId = (int) $parentId; $user =& $params['user']; // Prepare filters if any $filter = null; if (isset($params['filter'])) { $filter =& $params['filter']; } // Obsolescence $searchItemsParams = array(); if (isset($params['ignore_obsolete'])) { $searchItemsParams['ignore_obsolete'] = $params['ignore_obsolete']; } // Range of documents to return $start = 0; if (isset($params['start'])) { $start = $params['start']; } $end = 25; if (isset($params['offset'])) { $end = $start + $params['offset']; } $dao =& $this->_getItemDao(); // // Build Folder List // $parentItem = $this->getItemFromDb($parentId); $dPm = Docman_PermissionsManager::instance($parentItem->getGroupId()); $folderList = array($parentId => &$parentItem); $pathIdArray = array($parentId => array()); $pathTitleArray = array($parentId => array()); $parentIds = array($parentId); $folderIds = array($parentId); $i = 0; do { $i++; $dar = $dao->searchSubFolders($parentIds); $parentIds = array(); $itemIds = array(); $itemRows = array(); if ($dar && !$dar->isError()) { $dar->rewind(); while ($dar->valid()) { $row = $dar->current(); $itemRows[$row['item_id']] = $row; $itemIds[] = $row['item_id']; $parentIds[$row['item_id']] = $row['item_id']; $dar->next(); } // Fetch all the permissions at the same time $dPm->retreiveReadPermissionsForItems($itemIds, $user); // Build hierarchy: only keep displayable items foreach ($itemIds as $id) { if ($dPm->userCanRead($user, $id)) { $folderList[$id] =& $this->getItemFromRow($itemRows[$id]); // Update path $pathIdArray[$id] = array_merge($pathIdArray[$folderList[$id]->getParentId()], array($id)); $pathTitleArray[$id] = array_merge($pathTitleArray[$folderList[$id]->getParentId()], array($folderList[$id]->getTitle())); } else { unset($parentIds[$id]); } } } } while (count($parentIds) > 0); // // Keep only documents in allowed subfolders // $mdFactory = new Docman_MetadataFactory($this->groupId); $ci = null; if ($filter !== null) { $ci = $filter->getColumnIterator(); } // // Build Document list // $itemArray = array(); if (isset($params['obsolete_only']) && $params['obsolete_only']) { $dar = $dao->searchObsoleteByGroupId($this->groupId); } else { $dar = $dao->searchByGroupId($this->groupId, $filter, $searchItemsParams); } $nbItemsFound = 0; if ($dar && !$dar->isError()) { $this->preloadItemPerms($dar, $user, $this->groupId); $dar->rewind(); while ($dar->valid()) { $row = $dar->current(); // The document is not is one of the allowed subfolder so we // can delete it. As a side effect decrease the number of // document found. if ($dPm->userCanRead($user, $row['item_id']) && isset($folderList[$row['parent_id']])) { if ($nbItemsFound >= $start && $nbItemsFound < $end || isset($params['getall']) && $params['getall']) { $itemArray[$row['item_id']] =& $this->getItemFromRow($row); // Append Path $itemArray[$row['item_id']]->setPathTitle($pathTitleArray[$row['parent_id']]); $itemArray[$row['item_id']]->setPathId($pathIdArray[$row['parent_id']]); // Append metadata if ($ci !== null) { $ci->rewind(); while ($ci->valid()) { $c = $ci->current(); if ($c->md !== null && $mdFactory->isRealMetadata($c->md->getLabel())) { $mdFactory->addMetadataValueToItem($itemArray[$row['item_id']], $c->md); } $ci->next(); } } } $nbItemsFound++; } $dar->next(); } } $docIter =& new ArrayIterator($itemArray); return $docIter; }