visibility != 2 $sql = "SELECT docs.path, docs.session_id, docs.id, docs.c_id FROM resource_node AS n INNER JOIN $tblDocument AS docs ON (docs.resource_node_id = n.id) INNER JOIN resource_link l ON (l.resource_node_id = n.id) WHERE docs.c_id = $courseId AND docs.path LIKE '".$querypath."/%' AND docs.filetype = 'file' AND docs.path NOT LIKE '%_DELETED_%' AND l.visibility NOT IN ('".ResourceLink::VISIBILITY_DELETED."') "; $sql .= DocumentManager::getSessionFolderFilters($querypath, $sessionId); $result = Database::query($sql); $files = []; while ($row = Database::fetch_array($result, 'ASSOC')) { $files[$row['path']] = $row; } foreach ($files as $not_deleted_file) { // Filtering folders and if (strpos($not_deleted_file['path'], 'chat_files') > 0 || strpos($not_deleted_file['path'], 'shared_folder') > 0 ) { if (!empty($sessionId)) { if ($not_deleted_file['session_id'] != $sessionId) { continue; } } } $file = $courseInfo['path'].'/document'.$not_deleted_file['path']; //$document = $repo->find($not_deleted_file['id']); $data = $repo->getDocumentContent($not_deleted_file['id']); $zip->addFile($not_deleted_file['path'], $data); /*@$zip->add( $sysCoursePath.$courseInfo['path'].'/document'.$not_deleted_file['path'], PCLZIP_OPT_REMOVE_PATH, $sysCoursePath.$courseInfo['path'].'/document'.$remove_dir, PCLZIP_CB_PRE_ADD, 'fixDocumentNameCallback' );*/ } $zip->finish(); } else { // For other users, we need to create a zip file with only visible files and folders if ($path == '/') { $querypath = ''; // To prevent ...path LIKE '//%'... in query } else { $querypath = $path; } /* A big problem: Visible files that are in a hidden folder are included when we do a query for visibility='v' So... I do it in a couple of steps: 1st: Get all files that are visible in the given path */ $querypath = Database::escape_string($querypath); $sql = "SELECT path, docs.session_id, docs.id, props.to_group_id, docs.c_id FROM $doc_table AS docs INNER JOIN $prop_table AS props ON docs.id = props.ref AND docs.c_id = props.c_id $groupJoin WHERE docs.c_id = $courseId AND props.tool = '".TOOL_DOCUMENT."' AND docs.path LIKE '".$querypath."/%' AND props.visibility = '1' AND docs.filetype = 'file' AND (props.session_id IN ('0', '$sessionId') OR props.session_id IS NULL) AND $groupCondition "; $sql .= DocumentManager::getSessionFolderFilters($querypath, $sessionId); $result = Database::query($sql); $files = []; $all_visible_files_path = []; // Add them to an array while ($all_visible_files = Database::fetch_assoc($result)) { if (strpos($all_visible_files['path'], 'chat_files') > 0 || strpos($all_visible_files['path'], 'shared_folder') > 0 ) { if (!empty($sessionId)) { if ($all_visible_files['session_id'] != $sessionId) { continue; } } } $all_visible_files_path[] = $all_visible_files['path']; $files[$all_visible_files['path']] = $all_visible_files; } // 2nd: Get all folders that are invisible in the given path $sql = "SELECT path, docs.session_id, docs.id, props.to_group_id, docs.c_id FROM $doc_table AS docs INNER JOIN $prop_table AS props ON docs.id = props.ref AND docs.c_id = props.c_id WHERE docs.c_id = $courseId AND props.tool = '".TOOL_DOCUMENT."' AND docs.path LIKE '".$querypath."/%' AND props.visibility <> '1' AND (props.session_id IN ('0', '$sessionId') OR props.session_id IS NULL) AND docs.filetype = 'folder'"; $query2 = Database::query($sql); // If we get invisible folders, we have to filter out these results from all visible files we found if (Database::num_rows($query2) > 0) { $files = []; // Add item to an array while ($invisible_folders = Database::fetch_assoc($query2)) { //3rd: Get all files that are in the found invisible folder (these are "invisible" too) $sql = "SELECT path, docs.id, props.to_group_id, docs.c_id FROM $doc_table AS docs INNER JOIN $prop_table AS props ON docs.id = props.ref AND docs.c_id = props.c_id WHERE docs.c_id = $courseId AND props.tool ='".TOOL_DOCUMENT."' AND docs.path LIKE '".$invisible_folders['path']."/%' AND docs.filetype = 'file' AND (props.session_id IN ('0', '$sessionId') OR props.session_id IS NULL) AND props.visibility ='1'"; $query3 = Database::query($sql); // Add tem to an array while ($files_in_invisible_folder = Database::fetch_assoc($query3)) { $files_in_invisible_folder_path[] = $files_in_invisible_folder['path']; $files[$files_in_invisible_folder['path']] = $files_in_invisible_folder; } } // Compare the array with visible files and the array with files in invisible folders // and keep the difference (= all visible files that are not in an invisible folder) $files_for_zipfile = diff( (array) $all_visible_files_path, (array) $files_in_invisible_folder_path ); } else { // No invisible folders found, so all visible files can be added to the zipfile $files_for_zipfile = $all_visible_files_path; } Session::write('doc_files_to_download', $files); // Add all files in our final array to the zipfile for ($i = 0; $i < count($files_for_zipfile); $i++) { $zip->add( $sysCoursePath.$courseInfo['path'].'/document'.$files_for_zipfile[$i], PCLZIP_OPT_REMOVE_PATH, $sysCoursePath.$courseInfo['path'].'/document'.$remove_dir, PCLZIP_CB_PRE_ADD, 'fixDocumentNameCallback' ); } Session::erase('doc_files_to_download'); } exit; /** * Returns the difference between two arrays, as an array of those key/values * Use this as array_diff doesn't give the. * * @param array $arr1 first array * @param array $arr2 second array * * @return array difference between the two arrays */ function diff($arr1, $arr2) { $res = []; $r = 0; foreach ($arr1 as &$av) { if (!in_array($av, $arr2)) { $res[$r] = $av; $r++; } } return $res; }