Bug #5208 - SCORM courses: Fixing deletion of a SCORM course, based on the proposal by Christophe, see http://www.dokeos.com/forum/viewtopic.php?t=29673. The pesent solution works on Windows OS too. A new library file rmdirr.lib.php has been created (and revised), also, a formal test for this library file has been added.

skala
Ivan Tcholakov 17 years ago
parent aa2c972607
commit d007d59a99
  1. 53
      main/inc/lib/rmdirr.lib.php
  2. 12
      main/newscorm/learnpath.class.php
  3. 3
      main/newscorm/lp_controller.php
  4. 72
      tests/main/inc/lib/rmdirr.lib.test.php
  5. 49
      tests/rmdirr.lib.test_standalone.php

@ -0,0 +1,53 @@
<?php
/**
* Delete a file, or a folder and its contents
*
* @author Aidan Lister <aidan@php.net>
* @version 1.0.3
* @param string $dirname Directory to delete
* @return bool Returns TRUE on success, FALSE on failure
* @link http://aidanlister.com/2004/04/recursively-deleting-a-folder-in-php/
* @author Yannick Warnier, adaptation for the Dokeos LMS, April, 2008
* @author Ivan Tcholakov, a sanity check about Directory class creation has been added, September, 2009
*/
function rmdirr($dirname) {
// A sanity check
if (!file_exists($dirname)) {
return false;
}
// Simple delete for a file
if (is_file($dirname) || is_link($dirname)) {
$res = unlink($dirname);
if ($res === false) {
error_log(__FILE__.' line '.__LINE__.': '.(ini_get('track_errors') != false ? $php_errormsg : 'error not recorded because track_errors is off in your php.ini'), 0);
}
return $res;
}
// Loop through the folder
$dir = dir($dirname);
// A sanity check
$is_object_dir = is_object($dir);
if ($is_object_dir) {
while (false !== $entry = $dir->read()) {
// Skip pointers
if ($entry == '.' || $entry == '..') {
continue;
}
// Recurse
rmdirr("$dirname/$entry");
}
}
// Clean up
if ($is_object_dir) {
$dir->close();
}
$res = rmdir($dirname);
if ($res === false) {
error_log(__FILE__.' line '.__LINE__.': '.(ini_get('track_errors') != false ? $php_errormsg : 'error not recorded because track_errors is off in your php.ini'), 0);
}
return $res;
}

@ -833,6 +833,7 @@ class learnpath {
}
$lp = Database :: get_course_table(TABLE_LP_MAIN);
$lp_item = Database :: get_course_table(TABLE_LP_ITEM); // Proposed by Christophe (clefevre), see below.
$lp_view = Database :: get_course_table(TABLE_LP_VIEW);
$lp_item_view = Database :: get_course_table(TABLE_LP_ITEM_VIEW);
@ -844,6 +845,10 @@ class learnpath {
$res_del_item_view = api_sql_query($sql_del_view, __FILE__, __LINE__);
}
// Proposed by Christophe (nickname: clefevre), see http://www.dokeos.com/forum/viewtopic.php?t=29673
$sql_del_item = "DELETE FROM $lp_item WHERE lp_id = " . $this->lp_id;
$res_del_item = api_sql_query($sql_del_item, __FILE__, __LINE__);
$sql_del_view = "DELETE FROM $lp_view WHERE lp_id = " . $this->lp_id;
//if($this->debug>2){error_log('New LP - Deleting views bound to lp '.$this->lp_id.': '.$sql_del_view,0);}
$res_del_view = api_sql_query($sql_del_view, __FILE__, __LINE__);
@ -870,7 +875,12 @@ class learnpath {
if ($this->debug > 2) {
error_log('New LP - In learnpath::delete(), found SCORM, deleting directory: ' . $course_scorm_dir . $path, 0);
}
exec('rm -rf ' . $course_scorm_dir . $path);
// Proposed by Christophe (clefevre).
if (strcmp(substr($path, -2), "/.") == 0) {
$path = substr($path, 0, -1); // Remove "." at the end
}
//exec('rm -rf ' . $course_scorm_dir . $path); // See Bug #5208, this is not OS-portable way.
rmdirr($course_scorm_dir . $path);
}
}
}

@ -51,7 +51,8 @@ if ($is_allowed_in_course == false){
api_not_allowed(true);
}
require_once(api_get_path(LIBRARY_PATH) . "/fckeditor/fckeditor.php");
require_once api_get_path(LIBRARY_PATH).'rmdirr.lib.php';
require_once api_get_path(LIBRARY_PATH).'fckeditor/fckeditor.php';
$lpfound = false;
$myrefresh = 0;

@ -0,0 +1,72 @@
<?php
/**
* Testing the function rmdirr() for recursive directory deletion.
* This test is an adaptation of a published sample test.
* @link http://aidanlister.com/2004/04/recursively-deleting-a-folder-in-php/
* @author Aidan Lister, April, 2004
* @author Ivan Tcholakov, September, 2009 - adaptation for the Dokeos LMS.
*/
class Test_RmDirRFunction extends UnitTestCase {
function Test_RmDirRFunction() {
$this->UnitTestCase('Testing the function rmdirr() for recursive directory deletion');
}
public function test_rmdirr() {
$current_dir = dirname(__FILE__).'/';
$test_dir = $current_dir.'../../../../archive/'; // Write-access is needed for this directory.
$test_dir = realpath($test_dir).'/';
// Let us not clean backwars slashes on Windows, intentionally.
//$test_dir = str_replace('\\', '/', $test_dir);
// Create a directory and file tree
mkdir($test_dir.'testdelete');
mkdir($test_dir.'testdelete/one-a');
touch($test_dir.'testdelete/one-a/testfile');
mkdir($test_dir.'testdelete/one-b');
// Add some hidden files for good measure
touch($test_dir.'testdelete/one-b/.hiddenfile');
mkdir($test_dir.'testdelete/one-c');
touch($test_dir.'testdelete/one-c/.hiddenfile');
// Add some more depth
mkdir($test_dir.'testdelete/one-c/two-a');
touch($test_dir.'testdelete/one-c/two-a/testfile');
mkdir($test_dir.'testdelete/one-d/');
// Test that symlinks are not followed
// The function symlink() does not work on some Windows OS versions. For these cases this part of the test is skipped.
$function_symlink_exists = function_exists('symlink');
if ($function_symlink_exists) {
mkdir($test_dir.'testlink');
touch($test_dir.'testlink/testfile');
symlink($test_dir.'testlink/testfile', 'testdelete/one-d/my-symlink');
symlink($test_dir.'testlink', 'testdelete/one-d/my-symlink-dir');
}
// Run the actual delete
$status = rmdirr($test_dir.'testdelete');
// Check if we passed the test
if ($status === true && !file_exists($test_dir.'testdelete') && ($function_symlink_exists ? file_exists($test_dir.'testlink/testfile') : true)) {
//echo 'TEST PASSED';
$res = true;
} else {
//echo 'TEST FAILED';
$res = false;
}
if ($function_symlink_exists) {
@rmdirr($test_dir.'testlink');
}
// Pass the result of this test
$this->assertTrue($res === true);
//var_dump($test_dir);
}
}

@ -0,0 +1,49 @@
<?php
/**
* A standalone test for testing the function rmdirr()
* @author Ivan Tcholakov, September 2009.
* For licensing terms, see /dokeos_license.txt
*/
//ini_set('memory_limit','128M');
$_current_dir = dirname(__FILE__).'/';
$_sys_code_path = $_current_dir.'../main/';
$_sys_include_path = $_sys_code_path.'inc/';
$_sys_library_path = $_sys_code_path.'inc/lib/';
$_test_sys_code_path = $_current_dir.'main/';
$_test_sys_include_path = $_test_sys_code_path.'inc/';
$_test_sys_library_path = $_test_sys_code_path.'inc/lib/';
require_once($_current_dir.'simpletest/unit_tester.php');
require_once($_sys_include_path.'global.inc.php');
require_once($_sys_library_path.'rmdirr.lib.php');
//header('Content-Type: text/html; charset=' . $charset);
header('Content-Type: text/html; charset=' . 'UTF-8');
require_once($_current_dir.'simpletest/web_tester.php');
require_once($_current_dir.'simpletest/mock_objects.php');
require_once($_current_dir.'simpletest/autorun.php');
$_SESSION['_user']['user_id'] = 1;
class RmDirRTests extends TestSuite {
function RmDirRTests() {
$this->TestSuite('Testing the function rmdirr()');
global $_test_sys_library_path;
$this->addTestFile($_test_sys_library_path.'rmdirr.lib.test.php');
}
}
$test = & new RmDirRTests();
//$test-> run( new HtmlReporter());
?>
Loading…
Cancel
Save