[ Index ]

PHP Cross Reference of Unnamed Project

title

Body

[close]

/lib/filestorage/tests/ -> file_storage_test.php (source)

   1  <?php
   2  // This file is part of Moodle - http://moodle.org/
   3  //
   4  // Moodle is free software: you can redistribute it and/or modify
   5  // it under the terms of the GNU General Public License as published by
   6  // the Free Software Foundation, either version 3 of the License, or
   7  // (at your option) any later version.
   8  //
   9  // Moodle is distributed in the hope that it will be useful,
  10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12  // GNU General Public License for more details.
  13  //
  14  // You should have received a copy of the GNU General Public License
  15  // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
  16  
  17  /**
  18   * Unit tests for /lib/filestorage/file_storage.php
  19   *
  20   * @package   core_files
  21   * @category  phpunit
  22   * @copyright 2012 David Mudrak <david@moodle.com>
  23   * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  24   */
  25  
  26  defined('MOODLE_INTERNAL') || die();
  27  
  28  global $CFG;
  29  require_once($CFG->libdir . '/filelib.php');
  30  require_once($CFG->dirroot . '/repository/lib.php');
  31  require_once($CFG->libdir . '/filestorage/stored_file.php');
  32  
  33  class core_files_file_storage_testcase extends advanced_testcase {
  34  
  35      /**
  36       * Files can be created from strings.
  37       */
  38      public function test_create_file_from_string() {
  39          global $DB;
  40  
  41          $this->resetAfterTest(true);
  42  
  43          // Number of files installed in the database on a fresh Moodle site.
  44          $installedfiles = $DB->count_records('files', array());
  45  
  46          $content = 'abcd';
  47          $syscontext = context_system::instance();
  48          $filerecord = array(
  49              'contextid' => $syscontext->id,
  50              'component' => 'core',
  51              'filearea'  => 'unittest',
  52              'itemid'    => 0,
  53              'filepath'  => '/images/',
  54              'filename'  => 'testfile.txt',
  55          );
  56          $pathhash = sha1('/'.$filerecord['contextid'].'/'.$filerecord['component'].'/'.$filerecord['filearea'].'/'.$filerecord['itemid'].$filerecord['filepath'].$filerecord['filename']);
  57  
  58          $fs = get_file_storage();
  59          $file = $fs->create_file_from_string($filerecord, $content);
  60  
  61          $this->assertInstanceOf('stored_file', $file);
  62          $this->assertSame(sha1($content), $file->get_contenthash());
  63          $this->assertSame($pathhash, $file->get_pathnamehash());
  64  
  65          $this->assertTrue($DB->record_exists('files', array('pathnamehash'=>$pathhash)));
  66  
  67          $location = test_stored_file_inspection::get_pretected_pathname($file);
  68  
  69          $this->assertFileExists($location);
  70  
  71          // Verify the dir placeholder files are created.
  72          $this->assertEquals($installedfiles + 3, $DB->count_records('files', array()));
  73          $this->assertTrue($DB->record_exists('files', array('pathnamehash'=>sha1('/'.$filerecord['contextid'].'/'.$filerecord['component'].'/'.$filerecord['filearea'].'/'.$filerecord['itemid'].'/.'))));
  74          $this->assertTrue($DB->record_exists('files', array('pathnamehash'=>sha1('/'.$filerecord['contextid'].'/'.$filerecord['component'].'/'.$filerecord['filearea'].'/'.$filerecord['itemid'].$filerecord['filepath'].'.'))));
  75  
  76          // Tests that missing content file is recreated.
  77  
  78          unlink($location);
  79          $this->assertFileNotExists($location);
  80  
  81          $filerecord['filename'] = 'testfile2.txt';
  82          $file2 = $fs->create_file_from_string($filerecord, $content);
  83          $this->assertInstanceOf('stored_file', $file2);
  84          $this->assertSame($file->get_contenthash(), $file2->get_contenthash());
  85          $this->assertFileExists($location);
  86  
  87          $this->assertEquals($installedfiles + 4, $DB->count_records('files', array()));
  88  
  89          // Test that borked content file is recreated.
  90  
  91          $this->assertSame(2, file_put_contents($location, 'xx'));
  92  
  93          $filerecord['filename'] = 'testfile3.txt';
  94          $file3 = $fs->create_file_from_string($filerecord, $content);
  95          $this->assertInstanceOf('stored_file', $file3);
  96          $this->assertSame($file->get_contenthash(), $file3->get_contenthash());
  97          $this->assertFileExists($location);
  98  
  99          $this->assertSame($content, file_get_contents($location));
 100          $this->assertDebuggingCalled();
 101  
 102          $this->assertEquals($installedfiles + 5, $DB->count_records('files', array()));
 103      }
 104  
 105      /**
 106       * Local files can be added to the filepool
 107       */
 108      public function test_create_file_from_pathname() {
 109          global $CFG, $DB;
 110  
 111          $this->resetAfterTest(true);
 112  
 113          // Number of files installed in the database on a fresh Moodle site.
 114          $installedfiles = $DB->count_records('files', array());
 115  
 116          $filepath = $CFG->dirroot.'/lib/filestorage/tests/fixtures/testimage.jpg';
 117          $syscontext = context_system::instance();
 118          $filerecord = array(
 119              'contextid' => $syscontext->id,
 120              'component' => 'core',
 121              'filearea'  => 'unittest',
 122              'itemid'    => 0,
 123              'filepath'  => '/images/',
 124              'filename'  => 'testimage.jpg',
 125          );
 126          $pathhash = sha1('/'.$filerecord['contextid'].'/'.$filerecord['component'].'/'.$filerecord['filearea'].'/'.$filerecord['itemid'].$filerecord['filepath'].$filerecord['filename']);
 127  
 128          $fs = get_file_storage();
 129          $file = $fs->create_file_from_pathname($filerecord, $filepath);
 130  
 131          $this->assertInstanceOf('stored_file', $file);
 132          $this->assertSame(sha1_file($filepath), $file->get_contenthash());
 133  
 134          $this->assertTrue($DB->record_exists('files', array('pathnamehash'=>$pathhash)));
 135  
 136          $location = test_stored_file_inspection::get_pretected_pathname($file);
 137  
 138          $this->assertFileExists($location);
 139  
 140          // Verify the dir placeholder files are created.
 141          $this->assertEquals($installedfiles + 3, $DB->count_records('files', array()));
 142          $this->assertTrue($DB->record_exists('files', array('pathnamehash'=>sha1('/'.$filerecord['contextid'].'/'.$filerecord['component'].'/'.$filerecord['filearea'].'/'.$filerecord['itemid'].'/.'))));
 143          $this->assertTrue($DB->record_exists('files', array('pathnamehash'=>sha1('/'.$filerecord['contextid'].'/'.$filerecord['component'].'/'.$filerecord['filearea'].'/'.$filerecord['itemid'].$filerecord['filepath'].'.'))));
 144  
 145          // Tests that missing content file is recreated.
 146  
 147          unlink($location);
 148          $this->assertFileNotExists($location);
 149  
 150          $filerecord['filename'] = 'testfile2.jpg';
 151          $file2 = $fs->create_file_from_pathname($filerecord, $filepath);
 152          $this->assertInstanceOf('stored_file', $file2);
 153          $this->assertSame($file->get_contenthash(), $file2->get_contenthash());
 154          $this->assertFileExists($location);
 155  
 156          $this->assertEquals($installedfiles + 4, $DB->count_records('files', array()));
 157  
 158          // Test that borked content file is recreated.
 159  
 160          $this->assertSame(2, file_put_contents($location, 'xx'));
 161  
 162          $filerecord['filename'] = 'testfile3.jpg';
 163          $file3 = $fs->create_file_from_pathname($filerecord, $filepath);
 164          $this->assertInstanceOf('stored_file', $file3);
 165          $this->assertSame($file->get_contenthash(), $file3->get_contenthash());
 166          $this->assertFileExists($location);
 167  
 168          $this->assertSame(file_get_contents($filepath), file_get_contents($location));
 169          $this->assertDebuggingCalled();
 170  
 171          $this->assertEquals($installedfiles + 5, $DB->count_records('files', array()));
 172  
 173          // Test invalid file creation.
 174  
 175          $filerecord['filename'] = 'testfile4.jpg';
 176          try {
 177              $fs->create_file_from_pathname($filerecord, $filepath.'nonexistent');
 178              $this->fail('Exception expected when trying to add non-existent stored file.');
 179          } catch (Exception $e) {
 180              $this->assertInstanceOf('file_exception', $e);
 181          }
 182      }
 183  
 184      /**
 185       * Tests get get file.
 186       */
 187      public function test_get_file() {
 188          global $CFG;
 189  
 190          $this->resetAfterTest(false);
 191  
 192          $filepath = $CFG->dirroot.'/lib/filestorage/tests/fixtures/testimage.jpg';
 193          $syscontext = context_system::instance();
 194          $filerecord = array(
 195              'contextid' => $syscontext->id,
 196              'component' => 'core',
 197              'filearea'  => 'unittest',
 198              'itemid'    => 0,
 199              'filepath'  => '/images/',
 200              'filename'  => 'testimage.jpg',
 201          );
 202          $pathhash = sha1('/'.$filerecord['contextid'].'/'.$filerecord['component'].'/'.$filerecord['filearea'].'/'.$filerecord['itemid'].$filerecord['filepath'].$filerecord['filename']);
 203  
 204          $fs = get_file_storage();
 205          $file = $fs->create_file_from_pathname($filerecord, $filepath);
 206  
 207          $this->assertInstanceOf('stored_file', $file);
 208          $this->assertEquals($syscontext->id, $file->get_contextid());
 209          $this->assertEquals('core', $file->get_component());
 210          $this->assertEquals('unittest', $file->get_filearea());
 211          $this->assertEquals(0, $file->get_itemid());
 212          $this->assertEquals('/images/', $file->get_filepath());
 213          $this->assertEquals('testimage.jpg', $file->get_filename());
 214          $this->assertEquals(filesize($filepath), $file->get_filesize());
 215          $this->assertEquals($pathhash, $file->get_pathnamehash());
 216  
 217          return $file;
 218      }
 219  
 220      /**
 221       * Local images can be added to the filepool and their preview can be obtained
 222       *
 223       * @depends test_get_file
 224       */
 225      public function test_get_file_preview(stored_file $file) {
 226          global $CFG;
 227  
 228          $this->resetAfterTest();
 229          $fs = get_file_storage();
 230  
 231          $previewtinyicon = $fs->get_file_preview($file, 'tinyicon');
 232          $this->assertInstanceOf('stored_file', $previewtinyicon);
 233          $this->assertEquals('6b9864ae1536a8eeef54e097319175a8be12f07c', $previewtinyicon->get_filename());
 234  
 235          $previewtinyicon = $fs->get_file_preview($file, 'thumb');
 236          $this->assertInstanceOf('stored_file', $previewtinyicon);
 237          $this->assertEquals('6b9864ae1536a8eeef54e097319175a8be12f07c', $previewtinyicon->get_filename());
 238  
 239          $this->expectException('file_exception');
 240          $fs->get_file_preview($file, 'amodewhichdoesntexist');
 241      }
 242  
 243      public function test_get_file_preview_nonimage() {
 244          $this->resetAfterTest(true);
 245          $syscontext = context_system::instance();
 246          $filerecord = array(
 247              'contextid' => $syscontext->id,
 248              'component' => 'core',
 249              'filearea'  => 'unittest',
 250              'itemid'    => 0,
 251              'filepath'  => '/textfiles/',
 252              'filename'  => 'testtext.txt',
 253          );
 254  
 255          $fs = get_file_storage();
 256          $fs->create_file_from_string($filerecord, 'text contents');
 257          $textfile = $fs->get_file($syscontext->id, $filerecord['component'], $filerecord['filearea'],
 258              $filerecord['itemid'], $filerecord['filepath'], $filerecord['filename']);
 259  
 260          $preview = $fs->get_file_preview($textfile, 'thumb');
 261          $this->assertFalse($preview);
 262      }
 263  
 264      /**
 265       * Make sure renaming is working
 266       *
 267       * @copyright 2012 Dongsheng Cai {@link http://dongsheng.org}
 268       */
 269      public function test_file_renaming() {
 270          global $CFG;
 271  
 272          $this->resetAfterTest();
 273          $fs = get_file_storage();
 274          $syscontext = context_system::instance();
 275          $component = 'core';
 276          $filearea  = 'unittest';
 277          $itemid    = 0;
 278          $filepath  = '/';
 279          $filename  = 'test.txt';
 280  
 281          $filerecord = array(
 282              'contextid' => $syscontext->id,
 283              'component' => $component,
 284              'filearea'  => $filearea,
 285              'itemid'    => $itemid,
 286              'filepath'  => $filepath,
 287              'filename'  => $filename,
 288          );
 289  
 290          $originalfile = $fs->create_file_from_string($filerecord, 'Test content');
 291          $this->assertInstanceOf('stored_file', $originalfile);
 292          $contenthash = $originalfile->get_contenthash();
 293          $newpath = '/test/';
 294          $newname = 'newtest.txt';
 295  
 296          // This should work.
 297          $originalfile->rename($newpath, $newname);
 298          $file = $fs->get_file($syscontext->id, $component, $filearea, $itemid, $newpath, $newname);
 299          $this->assertInstanceOf('stored_file', $file);
 300          $this->assertEquals($contenthash, $file->get_contenthash());
 301  
 302          // Try break it.
 303          $this->expectException('file_exception');
 304          $this->expectExceptionMessage('Can not create file "1/core/unittest/0/test/newtest.txt" (file exists, cannot rename)');
 305          // This shall throw exception.
 306          $originalfile->rename($newpath, $newname);
 307      }
 308  
 309      /**
 310       * Create file from reference tests
 311       *
 312       * @copyright 2012 Dongsheng Cai {@link http://dongsheng.org}
 313       */
 314      public function test_create_file_from_reference() {
 315          global $CFG, $DB;
 316  
 317          $this->resetAfterTest();
 318          // Create user.
 319          $generator = $this->getDataGenerator();
 320          $user = $generator->create_user();
 321          $this->setUser($user);
 322          $usercontext = context_user::instance($user->id);
 323          $syscontext = context_system::instance();
 324  
 325          $fs = get_file_storage();
 326  
 327          $repositorypluginname = 'user';
 328          // Override repository permission.
 329          $capability = 'repository/' . $repositorypluginname . ':view';
 330          $guestroleid = $DB->get_field('role', 'id', array('shortname' => 'guest'));
 331          assign_capability($capability, CAP_ALLOW, $guestroleid, $syscontext->id, true);
 332  
 333          $args = array();
 334          $args['type'] = $repositorypluginname;
 335          $repos = repository::get_instances($args);
 336          $userrepository = reset($repos);
 337          $this->assertInstanceOf('repository', $userrepository);
 338  
 339          $component = 'user';
 340          $filearea  = 'private';
 341          $itemid    = 0;
 342          $filepath  = '/';
 343          $filename  = 'userfile.txt';
 344  
 345          $filerecord = array(
 346              'contextid' => $usercontext->id,
 347              'component' => $component,
 348              'filearea'  => $filearea,
 349              'itemid'    => $itemid,
 350              'filepath'  => $filepath,
 351              'filename'  => $filename,
 352          );
 353  
 354          $content = 'Test content';
 355          $originalfile = $fs->create_file_from_string($filerecord, $content);
 356          $this->assertInstanceOf('stored_file', $originalfile);
 357  
 358          $newfilerecord = array(
 359              'contextid' => $syscontext->id,
 360              'component' => 'core',
 361              'filearea'  => 'phpunit',
 362              'itemid'    => 0,
 363              'filepath'  => $filepath,
 364              'filename'  => $filename,
 365          );
 366          $ref = $fs->pack_reference($filerecord);
 367          $newstoredfile = $fs->create_file_from_reference($newfilerecord, $userrepository->id, $ref);
 368          $this->assertInstanceOf('stored_file', $newstoredfile);
 369          $this->assertEquals($userrepository->id, $newstoredfile->get_repository_id());
 370          $this->assertEquals($originalfile->get_contenthash(), $newstoredfile->get_contenthash());
 371          $this->assertEquals($originalfile->get_filesize(), $newstoredfile->get_filesize());
 372          $this->assertRegExp('#' . $filename. '$#', $newstoredfile->get_reference_details());
 373  
 374          // Test looking for references.
 375          $count = $fs->get_references_count_by_storedfile($originalfile);
 376          $this->assertEquals(1, $count);
 377          $files = $fs->get_references_by_storedfile($originalfile);
 378          $file = reset($files);
 379          $this->assertEquals($file, $newstoredfile);
 380  
 381          // Look for references by repository ID.
 382          $files = $fs->get_external_files($userrepository->id);
 383          $file = reset($files);
 384          $this->assertEquals($file, $newstoredfile);
 385  
 386          // Try convert reference to local file.
 387          $importedfile = $fs->import_external_file($newstoredfile);
 388          $this->assertFalse($importedfile->is_external_file());
 389          $this->assertInstanceOf('stored_file', $importedfile);
 390          // Still readable?
 391          $this->assertEquals($content, $importedfile->get_content());
 392      }
 393  
 394      private function setup_three_private_files() {
 395  
 396          $this->resetAfterTest();
 397  
 398          $generator = $this->getDataGenerator();
 399          $user = $generator->create_user();
 400          $this->setUser($user->id);
 401          $usercontext = context_user::instance($user->id);
 402          // Create a user private file.
 403          $file1 = new stdClass;
 404          $file1->contextid = $usercontext->id;
 405          $file1->component = 'user';
 406          $file1->filearea  = 'private';
 407          $file1->itemid    = 0;
 408          $file1->filepath  = '/';
 409          $file1->filename  = '1.txt';
 410          $file1->source    = 'test';
 411  
 412          $fs = get_file_storage();
 413          $userfile1 = $fs->create_file_from_string($file1, 'file1 content');
 414          $this->assertInstanceOf('stored_file', $userfile1);
 415  
 416          $file2 = clone($file1);
 417          $file2->filename = '2.txt';
 418          $userfile2 = $fs->create_file_from_string($file2, 'file2 content longer');
 419          $this->assertInstanceOf('stored_file', $userfile2);
 420  
 421          $file3 = clone($file1);
 422          $file3->filename = '3.txt';
 423          $userfile3 = $fs->create_file_from_storedfile($file3, $userfile2);
 424          $this->assertInstanceOf('stored_file', $userfile3);
 425  
 426          $user->ctxid = $usercontext->id;
 427  
 428          return $user;
 429      }
 430  
 431      public function test_get_area_files() {
 432          $user = $this->setup_three_private_files();
 433          $fs = get_file_storage();
 434  
 435          // Get area files with default options.
 436          $areafiles = $fs->get_area_files($user->ctxid, 'user', 'private');
 437  
 438          // Should be the two files we added plus the folder.
 439          $this->assertEquals(4, count($areafiles));
 440  
 441          // Verify structure.
 442          foreach ($areafiles as $key => $file) {
 443              $this->assertInstanceOf('stored_file', $file);
 444              $this->assertEquals($key, $file->get_pathnamehash());
 445          }
 446  
 447          // Get area files without a folder.
 448          $folderlessfiles = $fs->get_area_files($user->ctxid, 'user', 'private', false, 'sortorder', false);
 449          // Should be the two files without folder.
 450          $this->assertEquals(3, count($folderlessfiles));
 451  
 452          // Verify structure.
 453          foreach ($folderlessfiles as $key => $file) {
 454              $this->assertInstanceOf('stored_file', $file);
 455              $this->assertEquals($key, $file->get_pathnamehash());
 456          }
 457  
 458          // Get area files ordered by id.
 459          $filesbyid  = $fs->get_area_files($user->ctxid, 'user', 'private', false, 'id', false);
 460          // Should be the two files without folder.
 461          $this->assertEquals(3, count($filesbyid));
 462  
 463          // Verify structure.
 464          foreach ($filesbyid as $key => $file) {
 465              $this->assertInstanceOf('stored_file', $file);
 466              $this->assertEquals($key, $file->get_pathnamehash());
 467          }
 468  
 469          // Test with an itemid with no files.
 470          $areafiles = $fs->get_area_files($user->ctxid, 'user', 'private', 666, 'sortorder', false);
 471          // Should be none.
 472          $this->assertEmpty($areafiles);
 473      }
 474  
 475      public function test_get_area_tree() {
 476          $user = $this->setup_three_private_files();
 477          $fs = get_file_storage();
 478  
 479          // Get area files with default options.
 480          $areatree = $fs->get_area_tree($user->ctxid, 'user', 'private', 0);
 481          $this->assertEmpty($areatree['subdirs']);
 482          $this->assertNotEmpty($areatree['files']);
 483          $this->assertCount(3, $areatree['files']);
 484  
 485          // Ensure an empty try with a fake itemid.
 486          $emptytree = $fs->get_area_tree($user->ctxid, 'user', 'private', 666);
 487          $this->assertEmpty($emptytree['subdirs']);
 488          $this->assertEmpty($emptytree['files']);
 489  
 490          // Create a subdir.
 491          $dir = $fs->create_directory($user->ctxid, 'user', 'private', 0, '/testsubdir/');
 492          $this->assertInstanceOf('stored_file', $dir);
 493  
 494          // Add a file to the subdir.
 495          $filerecord = array(
 496              'contextid' => $user->ctxid,
 497              'component' => 'user',
 498              'filearea'  => 'private',
 499              'itemid'    => 0,
 500              'filepath'  => '/testsubdir/',
 501              'filename'  => 'test-get-area-tree.txt',
 502          );
 503  
 504          $directoryfile = $fs->create_file_from_string($filerecord, 'Test content');
 505          $this->assertInstanceOf('stored_file', $directoryfile);
 506  
 507          $areatree = $fs->get_area_tree($user->ctxid, 'user', 'private', 0);
 508  
 509          // At the top level there should still be 3 files.
 510          $this->assertCount(3, $areatree['files']);
 511  
 512          // There should now be a subdirectory.
 513          $this->assertCount(1, $areatree['subdirs']);
 514  
 515          // The test subdir is named testsubdir.
 516          $subdir = $areatree['subdirs']['testsubdir'];
 517          $this->assertNotEmpty($subdir);
 518          // It should have one file we added.
 519          $this->assertCount(1, $subdir['files']);
 520          // And no subdirs itself.
 521          $this->assertCount(0, $subdir['subdirs']);
 522  
 523          // Verify the file is the one we added.
 524          $subdirfile = reset($subdir['files']);
 525          $this->assertInstanceOf('stored_file', $subdirfile);
 526          $this->assertEquals($filerecord['filename'], $subdirfile->get_filename());
 527      }
 528  
 529      public function test_get_file_by_id() {
 530          $user = $this->setup_three_private_files();
 531          $fs = get_file_storage();
 532  
 533          $areafiles = $fs->get_area_files($user->ctxid, 'user', 'private');
 534  
 535          // Test get_file_by_id.
 536          $filebyid = reset($areafiles);
 537          $shouldbesame = $fs->get_file_by_id($filebyid->get_id());
 538          $this->assertEquals($filebyid->get_contenthash(), $shouldbesame->get_contenthash());
 539  
 540          // Test an id which doens't exist.
 541          $doesntexist = $fs->get_file_by_id(99999);
 542          $this->assertFalse($doesntexist);
 543      }
 544  
 545      public function test_get_file_by_hash() {
 546          $user = $this->setup_three_private_files();
 547          $fs = get_file_storage();
 548  
 549          $areafiles = $fs->get_area_files($user->ctxid, 'user', 'private');
 550          // Test get_file_by_hash.
 551          $filebyhash = reset($areafiles);
 552          $shouldbesame = $fs->get_file_by_hash($filebyhash->get_pathnamehash());
 553          $this->assertEquals($filebyhash->get_id(), $shouldbesame->get_id());
 554  
 555          // Test an hash which doens't exist.
 556          $doesntexist = $fs->get_file_by_hash('DOESNTEXIST');
 557          $this->assertFalse($doesntexist);
 558      }
 559  
 560      public function test_get_external_files() {
 561          $user = $this->setup_three_private_files();
 562          $fs = get_file_storage();
 563  
 564          $repos = repository::get_instances(array('type'=>'user'));
 565          $userrepository = reset($repos);
 566          $this->assertInstanceOf('repository', $userrepository);
 567  
 568          // No aliases yet.
 569          $exfiles = $fs->get_external_files($userrepository->id, 'id');
 570          $this->assertEquals(array(), $exfiles);
 571  
 572          // Create three aliases linking the same original: $aliasfile1 and $aliasfile2 are
 573          // created via create_file_from_reference(), $aliasfile3 created from $aliasfile2.
 574          $originalfile = null;
 575          foreach ($fs->get_area_files($user->ctxid, 'user', 'private') as $areafile) {
 576              if (!$areafile->is_directory()) {
 577                  $originalfile = $areafile;
 578                  break;
 579              }
 580          }
 581          $this->assertInstanceOf('stored_file', $originalfile);
 582          $originalrecord = array(
 583              'contextid' => $originalfile->get_contextid(),
 584              'component' => $originalfile->get_component(),
 585              'filearea'  => $originalfile->get_filearea(),
 586              'itemid'    => $originalfile->get_itemid(),
 587              'filepath'  => $originalfile->get_filepath(),
 588              'filename'  => $originalfile->get_filename(),
 589          );
 590  
 591          $aliasrecord = $this->generate_file_record();
 592          $aliasrecord->filepath = '/foo/';
 593          $aliasrecord->filename = 'one.txt';
 594  
 595          $ref = $fs->pack_reference($originalrecord);
 596          $aliasfile1 = $fs->create_file_from_reference($aliasrecord, $userrepository->id, $ref);
 597  
 598          $aliasrecord->filepath = '/bar/';
 599          $aliasrecord->filename = 'uno.txt';
 600          // Change the order of the items in the array to make sure that it does not matter.
 601          ksort($originalrecord);
 602          $ref = $fs->pack_reference($originalrecord);
 603          $aliasfile2 = $fs->create_file_from_reference($aliasrecord, $userrepository->id, $ref);
 604  
 605          $aliasrecord->filepath = '/bar/';
 606          $aliasrecord->filename = 'jedna.txt';
 607          $aliasfile3 = $fs->create_file_from_storedfile($aliasrecord, $aliasfile2);
 608  
 609          // Make sure we get three aliases now.
 610          $exfiles = $fs->get_external_files($userrepository->id, 'id');
 611          $this->assertEquals(3, count($exfiles));
 612          foreach ($exfiles as $exfile) {
 613              $this->assertTrue($exfile->is_external_file());
 614          }
 615          // Make sure they all link the same original (thence that all are linked with the same
 616          // record in {files_reference}).
 617          $this->assertEquals($aliasfile1->get_referencefileid(), $aliasfile2->get_referencefileid());
 618          $this->assertEquals($aliasfile3->get_referencefileid(), $aliasfile2->get_referencefileid());
 619      }
 620  
 621      public function test_create_directory_contextid_negative() {
 622          $fs = get_file_storage();
 623  
 624          $this->expectException('file_exception');
 625          $fs->create_directory(-1, 'core', 'unittest', 0, '/');
 626      }
 627  
 628      public function test_create_directory_contextid_invalid() {
 629          $fs = get_file_storage();
 630  
 631          $this->expectException('file_exception');
 632          $fs->create_directory('not an int', 'core', 'unittest', 0, '/');
 633      }
 634  
 635      public function test_create_directory_component_invalid() {
 636          $fs = get_file_storage();
 637          $syscontext = context_system::instance();
 638  
 639          $this->expectException('file_exception');
 640          $fs->create_directory($syscontext->id, 'bad/component', 'unittest', 0, '/');
 641      }
 642  
 643      public function test_create_directory_filearea_invalid() {
 644          $fs = get_file_storage();
 645          $syscontext = context_system::instance();
 646  
 647          $this->expectException('file_exception');
 648          $fs->create_directory($syscontext->id, 'core', 'bad-filearea', 0, '/');
 649      }
 650  
 651      public function test_create_directory_itemid_negative() {
 652          $fs = get_file_storage();
 653          $syscontext = context_system::instance();
 654  
 655          $this->expectException('file_exception');
 656          $fs->create_directory($syscontext->id, 'core', 'unittest', -1, '/');
 657      }
 658  
 659      public function test_create_directory_itemid_invalid() {
 660          $fs = get_file_storage();
 661          $syscontext = context_system::instance();
 662  
 663          $this->expectException('file_exception');
 664          $fs->create_directory($syscontext->id, 'core', 'unittest', 'notanint', '/');
 665      }
 666  
 667      public function test_create_directory_filepath_invalid() {
 668          $fs = get_file_storage();
 669          $syscontext = context_system::instance();
 670  
 671          $this->expectException('file_exception');
 672          $fs->create_directory($syscontext->id, 'core', 'unittest', 0, '/not-with-trailing/or-leading-slash');
 673      }
 674  
 675      public function test_get_directory_files() {
 676          $user = $this->setup_three_private_files();
 677          $fs = get_file_storage();
 678  
 679          $dir = $fs->create_directory($user->ctxid, 'user', 'private', 0, '/testsubdir/');
 680          $this->assertInstanceOf('stored_file', $dir);
 681  
 682          // Add a file to the subdir.
 683          $filerecord = array(
 684              'contextid' => $user->ctxid,
 685              'component' => 'user',
 686              'filearea'  => 'private',
 687              'itemid'    => 0,
 688              'filepath'  => '/testsubdir/',
 689              'filename'  => 'test-get-area-tree.txt',
 690          );
 691  
 692          $directoryfile = $fs->create_file_from_string($filerecord, 'Test content');
 693          $this->assertInstanceOf('stored_file', $directoryfile);
 694  
 695          // Don't recurse without dirs.
 696          $files = $fs->get_directory_files($user->ctxid, 'user', 'private', 0, '/', false, false, 'id');
 697          // 3 files only.
 698          $this->assertCount(3, $files);
 699          foreach ($files as $key => $file) {
 700              $this->assertInstanceOf('stored_file', $file);
 701              $this->assertEquals($key, $file->get_pathnamehash());
 702          }
 703  
 704          // Don't recurse with dirs.
 705          $files = $fs->get_directory_files($user->ctxid, 'user', 'private', 0, '/', false, true, 'id');
 706          // 3 files + 1 directory.
 707          $this->assertCount(4, $files);
 708          foreach ($files as $key => $file) {
 709              $this->assertInstanceOf('stored_file', $file);
 710              $this->assertEquals($key, $file->get_pathnamehash());
 711          }
 712  
 713          // Recurse with dirs.
 714          $files = $fs->get_directory_files($user->ctxid, 'user', 'private', 0, '/', true, true, 'id');
 715          // 3 files + 1 directory +  1 subdir file.
 716          $this->assertCount(5, $files);
 717          foreach ($files as $key => $file) {
 718              $this->assertInstanceOf('stored_file', $file);
 719              $this->assertEquals($key, $file->get_pathnamehash());
 720          }
 721  
 722          // Recurse without dirs.
 723          $files = $fs->get_directory_files($user->ctxid, 'user', 'private', 0, '/', true, false, 'id');
 724          // 3 files +  1 subdir file.
 725          $this->assertCount(4, $files);
 726          foreach ($files as $key => $file) {
 727              $this->assertInstanceOf('stored_file', $file);
 728              $this->assertEquals($key, $file->get_pathnamehash());
 729          }
 730      }
 731  
 732      public function test_search_references() {
 733          $user = $this->setup_three_private_files();
 734          $fs = get_file_storage();
 735          $repos = repository::get_instances(array('type'=>'user'));
 736          $repo = reset($repos);
 737  
 738          $alias1 = array(
 739              'contextid' => $user->ctxid,
 740              'component' => 'user',
 741              'filearea'  => 'private',
 742              'itemid'    => 0,
 743              'filepath'  => '/aliases/',
 744              'filename'  => 'alias-to-1.txt'
 745          );
 746  
 747          $alias2 = array(
 748              'contextid' => $user->ctxid,
 749              'component' => 'user',
 750              'filearea'  => 'private',
 751              'itemid'    => 0,
 752              'filepath'  => '/aliases/',
 753              'filename'  => 'another-alias-to-1.txt'
 754          );
 755  
 756          $reference = file_storage::pack_reference(array(
 757              'contextid' => $user->ctxid,
 758              'component' => 'user',
 759              'filearea'  => 'private',
 760              'itemid'    => 0,
 761              'filepath'  => '/',
 762              'filename'  => '1.txt'
 763          ));
 764  
 765          // There are no aliases now.
 766          $result = $fs->search_references($reference);
 767          $this->assertEquals(array(), $result);
 768  
 769          $result = $fs->search_references_count($reference);
 770          $this->assertSame($result, 0);
 771  
 772          // Create two aliases and make sure they are returned.
 773          $fs->create_file_from_reference($alias1, $repo->id, $reference);
 774          $fs->create_file_from_reference($alias2, $repo->id, $reference);
 775  
 776          $result = $fs->search_references($reference);
 777          $this->assertTrue(is_array($result));
 778          $this->assertEquals(count($result), 2);
 779          foreach ($result as $alias) {
 780              $this->assertTrue($alias instanceof stored_file);
 781          }
 782  
 783          $result = $fs->search_references_count($reference);
 784          $this->assertSame($result, 2);
 785  
 786          // The method can't be used for references to files outside the filepool.
 787          $exceptionthrown = false;
 788          try {
 789              $fs->search_references('http://dl.dropbox.com/download/1234567/naked-dougiamas.jpg');
 790          } catch (file_reference_exception $e) {
 791              $exceptionthrown = true;
 792          }
 793          $this->assertTrue($exceptionthrown);
 794  
 795          $exceptionthrown = false;
 796          try {
 797              $fs->search_references_count('http://dl.dropbox.com/download/1234567/naked-dougiamas.jpg');
 798          } catch (file_reference_exception $e) {
 799              $exceptionthrown = true;
 800          }
 801          $this->assertTrue($exceptionthrown);
 802      }
 803  
 804      public function test_delete_area_files() {
 805          $user = $this->setup_three_private_files();
 806          $fs = get_file_storage();
 807  
 808          // Get area files with default options.
 809          $areafiles = $fs->get_area_files($user->ctxid, 'user', 'private');
 810          // Should be the two files we added plus the folder.
 811          $this->assertEquals(4, count($areafiles));
 812          $fs->delete_area_files($user->ctxid, 'user', 'private');
 813  
 814          $areafiles = $fs->get_area_files($user->ctxid, 'user', 'private');
 815          // Should be the two files we added plus the folder.
 816          $this->assertEquals(0, count($areafiles));
 817      }
 818  
 819      public function test_delete_area_files_itemid() {
 820          $user = $this->setup_three_private_files();
 821          $fs = get_file_storage();
 822  
 823          // Get area files with default options.
 824          $areafiles = $fs->get_area_files($user->ctxid, 'user', 'private');
 825          // Should be the two files we added plus the folder.
 826          $this->assertEquals(4, count($areafiles));
 827          $fs->delete_area_files($user->ctxid, 'user', 'private', 9999);
 828  
 829          $areafiles = $fs->get_area_files($user->ctxid, 'user', 'private');
 830          $this->assertEquals(4, count($areafiles));
 831      }
 832  
 833      public function test_delete_area_files_select() {
 834          $user = $this->setup_three_private_files();
 835          $fs = get_file_storage();
 836  
 837          // Get area files with default options.
 838          $areafiles = $fs->get_area_files($user->ctxid, 'user', 'private');
 839          // Should be the two files we added plus the folder.
 840          $this->assertEquals(4, count($areafiles));
 841          $fs->delete_area_files_select($user->ctxid, 'user', 'private', '!= :notitemid', array('notitemid'=>9999));
 842  
 843          $areafiles = $fs->get_area_files($user->ctxid, 'user', 'private');
 844          // Should be the two files we added plus the folder.
 845          $this->assertEquals(0, count($areafiles));
 846      }
 847  
 848      public function test_delete_component_files() {
 849          $user = $this->setup_three_private_files();
 850          $fs = get_file_storage();
 851  
 852          $areafiles = $fs->get_area_files($user->ctxid, 'user', 'private');
 853          $this->assertEquals(4, count($areafiles));
 854          $fs->delete_component_files('user');
 855          $areafiles = $fs->get_area_files($user->ctxid, 'user', 'private');
 856          $this->assertEquals(0, count($areafiles));
 857      }
 858  
 859      public function test_create_file_from_url() {
 860          $this->resetAfterTest(true);
 861  
 862          $syscontext = context_system::instance();
 863          $filerecord = array(
 864              'contextid' => $syscontext->id,
 865              'component' => 'core',
 866              'filearea'  => 'unittest',
 867              'itemid'    => 0,
 868              'filepath'  => '/downloadtest/',
 869          );
 870          $url = $this->getExternalTestFileUrl('/test.html');
 871  
 872          $fs = get_file_storage();
 873  
 874          // Test creating file without filename.
 875          $file1 = $fs->create_file_from_url($filerecord, $url);
 876          $this->assertInstanceOf('stored_file', $file1);
 877  
 878          // Set filename.
 879          $filerecord['filename'] = 'unit-test-filename.html';
 880          $file2 = $fs->create_file_from_url($filerecord, $url);
 881          $this->assertInstanceOf('stored_file', $file2);
 882  
 883          // Use temporary file.
 884          $filerecord['filename'] = 'unit-test-with-temp-file.html';
 885          $file3 = $fs->create_file_from_url($filerecord, $url, null, true);
 886          $file3 = $this->assertInstanceOf('stored_file', $file3);
 887      }
 888  
 889      public function test_cron() {
 890          $this->resetAfterTest(true);
 891  
 892          // Note: this is only testing DB compatibility atm, rather than
 893          // that work is done.
 894          $fs = get_file_storage();
 895  
 896          $this->expectOutputRegex('/Cleaning up/');
 897          $fs->cron();
 898      }
 899  
 900      public function test_is_area_empty() {
 901          $user = $this->setup_three_private_files();
 902          $fs = get_file_storage();
 903  
 904          $this->assertFalse($fs->is_area_empty($user->ctxid, 'user', 'private'));
 905  
 906          // File area with madeup itemid should be empty.
 907          $this->assertTrue($fs->is_area_empty($user->ctxid, 'user', 'private', 9999));
 908          // Still empty with dirs included.
 909          $this->assertTrue($fs->is_area_empty($user->ctxid, 'user', 'private', 9999, false));
 910      }
 911  
 912      public function test_move_area_files_to_new_context() {
 913          $this->resetAfterTest(true);
 914  
 915          // Create a course with a page resource.
 916          $course = $this->getDataGenerator()->create_course();
 917          $page1 = $this->getDataGenerator()->create_module('page', array('course'=>$course->id));
 918          $page1context = context_module::instance($page1->cmid);
 919  
 920          // Add a file to the page.
 921          $fs = get_file_storage();
 922          $filerecord = array(
 923              'contextid' => $page1context->id,
 924              'component' => 'mod_page',
 925              'filearea'  => 'content',
 926              'itemid'    => 0,
 927              'filepath'  => '/',
 928              'filename'  => 'unit-test-file.txt',
 929          );
 930  
 931          $originalfile = $fs->create_file_from_string($filerecord, 'Test content');
 932          $this->assertInstanceOf('stored_file', $originalfile);
 933  
 934          $pagefiles = $fs->get_area_files($page1context->id, 'mod_page', 'content', 0, 'sortorder', false);
 935          // Should be one file in filearea.
 936          $this->assertFalse($fs->is_area_empty($page1context->id, 'mod_page', 'content'));
 937  
 938          // Create a new page.
 939          $page2 = $this->getDataGenerator()->create_module('page', array('course'=>$course->id));
 940          $page2context = context_module::instance($page2->cmid);
 941  
 942          // Newly created page area is empty.
 943          $this->assertTrue($fs->is_area_empty($page2context->id, 'mod_page', 'content'));
 944  
 945          // Move the files.
 946          $fs->move_area_files_to_new_context($page1context->id, $page2context->id, 'mod_page', 'content');
 947  
 948          // Page2 filearea should no longer be empty.
 949          $this->assertFalse($fs->is_area_empty($page2context->id, 'mod_page', 'content'));
 950  
 951          // Page1 filearea should now be empty.
 952          $this->assertTrue($fs->is_area_empty($page1context->id, 'mod_page', 'content'));
 953  
 954          $page2files = $fs->get_area_files($page2context->id, 'mod_page', 'content', 0, 'sortorder', false);
 955          $movedfile = reset($page2files);
 956  
 957          // The two files should have the same content hash.
 958          $this->assertEquals($movedfile->get_contenthash(), $originalfile->get_contenthash());
 959      }
 960  
 961      public function test_convert_image() {
 962          global $CFG;
 963  
 964          $this->resetAfterTest(false);
 965  
 966          $filepath = $CFG->dirroot.'/lib/filestorage/tests/fixtures/testimage.jpg';
 967          $syscontext = context_system::instance();
 968          $filerecord = array(
 969              'contextid' => $syscontext->id,
 970              'component' => 'core',
 971              'filearea'  => 'unittest',
 972              'itemid'    => 0,
 973              'filepath'  => '/images/',
 974              'filename'  => 'testimage.jpg',
 975          );
 976  
 977          $fs = get_file_storage();
 978          $original = $fs->create_file_from_pathname($filerecord, $filepath);
 979  
 980          $filerecord['filename'] = 'testimage-converted-10x10.jpg';
 981          $converted = $fs->convert_image($filerecord, $original, 10, 10, true, 100);
 982          $this->assertInstanceOf('stored_file', $converted);
 983  
 984          $filerecord['filename'] = 'testimage-convereted-nosize.jpg';
 985          $converted = $fs->convert_image($filerecord, $original);
 986          $this->assertInstanceOf('stored_file', $converted);
 987      }
 988  
 989      public function test_convert_image_png() {
 990          global $CFG;
 991  
 992          $this->resetAfterTest(false);
 993  
 994          $filepath = $CFG->dirroot.'/lib/filestorage/tests/fixtures/testimage.png';
 995          $syscontext = context_system::instance();
 996          $filerecord = array(
 997              'contextid' => $syscontext->id,
 998              'component' => 'core',
 999              'filearea'  => 'unittest',
1000              'itemid'    => 0,
1001              'filepath'  => '/images/',
1002              'filename'  => 'testimage.png',
1003          );
1004  
1005          $fs = get_file_storage();
1006          $original = $fs->create_file_from_pathname($filerecord, $filepath);
1007  
1008          // Vanilla test.
1009          $filerecord['filename'] = 'testimage-converted-nosize.png';
1010          $vanilla = $fs->convert_image($filerecord, $original);
1011          $this->assertInstanceOf('stored_file', $vanilla);
1012          // Assert that byte 25 has the ascii value 6 for PNG-24.
1013          $this->assertTrue(ord(substr($vanilla->get_content(), 25, 1)) == 6);
1014  
1015          // 10x10 resize test; also testing for a ridiculous quality setting, which
1016          // we should if necessary scale to the 0 - 9 range.
1017          $filerecord['filename'] = 'testimage-converted-10x10.png';
1018          $converted = $fs->convert_image($filerecord, $original, 10, 10, true, 100);
1019          $this->assertInstanceOf('stored_file', $converted);
1020          // Assert that byte 25 has the ascii value 6 for PNG-24.
1021          $this->assertTrue(ord(substr($converted->get_content(), 25, 1)) == 6);
1022  
1023          // Transparency test.
1024          $filerecord['filename'] = 'testimage-converted-102x31.png';
1025          $converted = $fs->convert_image($filerecord, $original, 102, 31, true, 9);
1026          $this->assertInstanceOf('stored_file', $converted);
1027          // Assert that byte 25 has the ascii value 6 for PNG-24.
1028          $this->assertTrue(ord(substr($converted->get_content(), 25, 1)) == 6);
1029  
1030          $originalfile = imagecreatefromstring($original->get_content());
1031          $convertedfile = imagecreatefromstring($converted->get_content());
1032          $vanillafile = imagecreatefromstring($vanilla->get_content());
1033  
1034          $originalcolors = imagecolorsforindex($originalfile, imagecolorat($originalfile, 0, 0));
1035          $convertedcolors = imagecolorsforindex($convertedfile, imagecolorat($convertedfile, 0, 0));
1036          $vanillacolors = imagecolorsforindex($vanillafile, imagecolorat($vanillafile, 0, 0));
1037          $this->assertEquals(count($originalcolors), 4);
1038          $this->assertEquals(count($convertedcolors), 4);
1039          $this->assertEquals(count($vanillacolors), 4);
1040          $this->assertEquals($originalcolors['red'], $convertedcolors['red']);
1041          $this->assertEquals($originalcolors['green'], $convertedcolors['green']);
1042          $this->assertEquals($originalcolors['blue'], $convertedcolors['blue']);
1043          $this->assertEquals($originalcolors['alpha'], $convertedcolors['alpha']);
1044          $this->assertEquals($originalcolors['red'], $vanillacolors['red']);
1045          $this->assertEquals($originalcolors['green'], $vanillacolors['green']);
1046          $this->assertEquals($originalcolors['blue'], $vanillacolors['blue']);
1047          $this->assertEquals($originalcolors['alpha'], $vanillacolors['alpha']);
1048          $this->assertEquals($originalcolors['alpha'], 127);
1049  
1050      }
1051  
1052      private function generate_file_record() {
1053          $syscontext = context_system::instance();
1054          $filerecord = new stdClass();
1055          $filerecord->contextid = $syscontext->id;
1056          $filerecord->component = 'core';
1057          $filerecord->filearea = 'phpunit';
1058          $filerecord->filepath = '/';
1059          $filerecord->filename = 'testfile.txt';
1060          $filerecord->itemid = 0;
1061  
1062          return $filerecord;
1063      }
1064  
1065      /**
1066       * @expectedException        file_exception
1067       */
1068      public function test_create_file_from_storedfile_file_invalid() {
1069          $this->resetAfterTest(true);
1070  
1071          $filerecord = $this->generate_file_record();
1072  
1073          $fs = get_file_storage();
1074  
1075          // Create a file from a file id which doesn't exist.
1076          $fs->create_file_from_storedfile($filerecord,  9999);
1077      }
1078  
1079      /**
1080       * @expectedException        file_exception
1081       * @expectedExceptionMessage Invalid contextid
1082       */
1083      public function test_create_file_from_storedfile_contextid_invalid() {
1084          $this->resetAfterTest(true);
1085  
1086          $filerecord = $this->generate_file_record();
1087  
1088          $fs = get_file_storage();
1089          $file1 = $fs->create_file_from_string($filerecord, 'text contents');
1090          $this->assertInstanceOf('stored_file', $file1);
1091  
1092          $filerecord->filename = 'invalid.txt';
1093          $filerecord->contextid = 'invalid';
1094  
1095          $fs->create_file_from_storedfile($filerecord, $file1->get_id());
1096      }
1097  
1098      /**
1099       * @expectedException        file_exception
1100       * @expectedExceptionMessage Invalid component
1101       */
1102      public function test_create_file_from_storedfile_component_invalid() {
1103          $this->resetAfterTest(true);
1104  
1105          $filerecord = $this->generate_file_record();
1106  
1107          $fs = get_file_storage();
1108          $file1 = $fs->create_file_from_string($filerecord, 'text contents');
1109          $this->assertInstanceOf('stored_file', $file1);
1110  
1111          $filerecord->filename = 'invalid.txt';
1112          $filerecord->component = 'bad/component';
1113  
1114          $fs->create_file_from_storedfile($filerecord, $file1->get_id());
1115      }
1116  
1117      /**
1118       * @expectedException        file_exception
1119       * @expectedExceptionMessage Invalid filearea
1120       */
1121      public function test_create_file_from_storedfile_filearea_invalid() {
1122          $this->resetAfterTest(true);
1123  
1124          $filerecord = $this->generate_file_record();
1125  
1126          $fs = get_file_storage();
1127          $file1 = $fs->create_file_from_string($filerecord, 'text contents');
1128          $this->assertInstanceOf('stored_file', $file1);
1129  
1130          $filerecord->filename = 'invalid.txt';
1131          $filerecord->filearea = 'bad-filearea';
1132  
1133          $fs->create_file_from_storedfile($filerecord, $file1->get_id());
1134      }
1135  
1136      /**
1137       * @expectedException        file_exception
1138       * @expectedExceptionMessage Invalid itemid
1139       */
1140      public function test_create_file_from_storedfile_itemid_invalid() {
1141          $this->resetAfterTest(true);
1142  
1143          $filerecord = $this->generate_file_record();
1144  
1145          $fs = get_file_storage();
1146          $file1 = $fs->create_file_from_string($filerecord, 'text contents');
1147          $this->assertInstanceOf('stored_file', $file1);
1148  
1149          $filerecord->filename = 'invalid.txt';
1150          $filerecord->itemid = 'bad-itemid';
1151  
1152          $fs->create_file_from_storedfile($filerecord, $file1->get_id());
1153      }
1154  
1155      /**
1156       * @expectedException        file_exception
1157       * @expectedExceptionMessage Invalid file path
1158       */
1159      public function test_create_file_from_storedfile_filepath_invalid() {
1160          $this->resetAfterTest(true);
1161  
1162          $filerecord = $this->generate_file_record();
1163  
1164          $fs = get_file_storage();
1165          $file1 = $fs->create_file_from_string($filerecord, 'text contents');
1166          $this->assertInstanceOf('stored_file', $file1);
1167  
1168          $filerecord->filename = 'invalid.txt';
1169          $filerecord->filepath = 'a-/bad/-filepath';
1170  
1171          $fs->create_file_from_storedfile($filerecord, $file1->get_id());
1172      }
1173  
1174      /**
1175       * @expectedException        file_exception
1176       * @expectedExceptionMessage Invalid file name
1177       */
1178      public function test_create_file_from_storedfile_filename_invalid() {
1179          $this->resetAfterTest(true);
1180  
1181          $filerecord = $this->generate_file_record();
1182  
1183          $fs = get_file_storage();
1184          $file1 = $fs->create_file_from_string($filerecord, 'text contents');
1185          $this->assertInstanceOf('stored_file', $file1);
1186  
1187          $filerecord->filename = '';
1188  
1189          $fs->create_file_from_storedfile($filerecord, $file1->get_id());
1190      }
1191  
1192      /**
1193       * @expectedException        file_exception
1194       * @expectedExceptionMessage Invalid file timecreated
1195       */
1196      public function test_create_file_from_storedfile_timecreated_invalid() {
1197          $this->resetAfterTest(true);
1198  
1199          $filerecord = $this->generate_file_record();
1200  
1201          $fs = get_file_storage();
1202          $file1 = $fs->create_file_from_string($filerecord, 'text contents');
1203          $this->assertInstanceOf('stored_file', $file1);
1204  
1205          $filerecord->filename = 'invalid.txt';
1206          $filerecord->timecreated = 'today';
1207  
1208          $fs->create_file_from_storedfile($filerecord, $file1->get_id());
1209      }
1210  
1211      /**
1212       * @expectedException        file_exception
1213       * @expectedExceptionMessage Invalid file timemodified
1214       */
1215      public function test_create_file_from_storedfile_timemodified_invalid() {
1216          $this->resetAfterTest(true);
1217  
1218          $filerecord = $this->generate_file_record();
1219  
1220          $fs = get_file_storage();
1221          $file1 = $fs->create_file_from_string($filerecord, 'text contents');
1222          $this->assertInstanceOf('stored_file', $file1);
1223  
1224          $filerecord->filename = 'invalid.txt';
1225          $filerecord->timemodified  = 'today';
1226  
1227          $fs->create_file_from_storedfile($filerecord, $file1->get_id());
1228      }
1229  
1230      /**
1231       * @expectedException        stored_file_creation_exception
1232       * @expectedExceptionMessage Can not create file "1/core/phpunit/0/testfile.txt"
1233       */
1234      public function test_create_file_from_storedfile_duplicate() {
1235          $this->resetAfterTest(true);
1236  
1237          $filerecord = $this->generate_file_record();
1238  
1239          $fs = get_file_storage();
1240          $file1 = $fs->create_file_from_string($filerecord, 'text contents');
1241          $this->assertInstanceOf('stored_file', $file1);
1242  
1243          // Creating a file validating unique constraint.
1244          $fs->create_file_from_storedfile($filerecord, $file1->get_id());
1245      }
1246  
1247      public function test_create_file_from_storedfile() {
1248          $this->resetAfterTest(true);
1249  
1250          $syscontext = context_system::instance();
1251  
1252          $filerecord = new stdClass();
1253          $filerecord->contextid = $syscontext->id;
1254          $filerecord->component = 'core';
1255          $filerecord->filearea = 'phpunit';
1256          $filerecord->filepath = '/';
1257          $filerecord->filename = 'testfile.txt';
1258          $filerecord->itemid = 0;
1259  
1260          $fs = get_file_storage();
1261  
1262          $file1 = $fs->create_file_from_string($filerecord, 'text contents');
1263          $this->assertInstanceOf('stored_file', $file1);
1264  
1265          $filerecord->filename = 'test-create-file-from-storedfile.txt';
1266          $file2 = $fs->create_file_from_storedfile($filerecord, $file1->get_id());
1267          $this->assertInstanceOf('stored_file', $file2);
1268  
1269          // These will be normalised to current time..
1270          $filerecord->timecreated = -100;
1271          $filerecord->timemodified= -100;
1272          $filerecord->filename = 'test-create-file-from-storedfile-bad-dates.txt';
1273  
1274          $file3 = $fs->create_file_from_storedfile($filerecord, $file1->get_id());
1275          $this->assertInstanceOf('stored_file', $file3);
1276  
1277          $this->assertNotEquals($file3->get_timemodified(), $filerecord->timemodified);
1278          $this->assertNotEquals($file3->get_timecreated(), $filerecord->timecreated);
1279      }
1280  
1281      /**
1282       * @expectedException        file_exception
1283       * @expectedExceptionMessage Invalid contextid
1284       */
1285      public function test_create_file_from_string_contextid_invalid() {
1286          $this->resetAfterTest(true);
1287  
1288          $filerecord = $this->generate_file_record();
1289          $fs = get_file_storage();
1290  
1291          $filerecord->contextid = 'invalid';
1292  
1293          $file1 = $fs->create_file_from_string($filerecord, 'text contents');
1294      }
1295  
1296      /**
1297       * @expectedException        file_exception
1298       * @expectedExceptionMessage Invalid component
1299       */
1300      public function test_create_file_from_string_component_invalid() {
1301          $this->resetAfterTest(true);
1302  
1303          $filerecord = $this->generate_file_record();
1304          $fs = get_file_storage();
1305  
1306          $filerecord->component = 'bad/component';
1307  
1308          $file1 = $fs->create_file_from_string($filerecord, 'text contents');
1309      }
1310  
1311      /**
1312       * @expectedException        file_exception
1313       * @expectedExceptionMessage Invalid filearea
1314       */
1315      public function test_create_file_from_string_filearea_invalid() {
1316          $this->resetAfterTest(true);
1317  
1318          $filerecord = $this->generate_file_record();
1319          $fs = get_file_storage();
1320  
1321          $filerecord->filearea = 'bad-filearea';
1322  
1323          $file1 = $fs->create_file_from_string($filerecord, 'text contents');
1324      }
1325  
1326      /**
1327       * @expectedException        file_exception
1328       * @expectedExceptionMessage Invalid itemid
1329       */
1330      public function test_create_file_from_string_itemid_invalid() {
1331          $this->resetAfterTest(true);
1332  
1333          $filerecord = $this->generate_file_record();
1334          $fs = get_file_storage();
1335  
1336          $filerecord->itemid = 'bad-itemid';
1337  
1338          $file1 = $fs->create_file_from_string($filerecord, 'text contents');
1339      }
1340  
1341      /**
1342       * @expectedException        file_exception
1343       * @expectedExceptionMessage Invalid file path
1344       */
1345      public function test_create_file_from_string_filepath_invalid() {
1346          $this->resetAfterTest(true);
1347  
1348          $filerecord = $this->generate_file_record();
1349          $fs = get_file_storage();
1350  
1351          $filerecord->filepath = 'a-/bad/-filepath';
1352  
1353          $file1 = $fs->create_file_from_string($filerecord, 'text contents');
1354      }
1355  
1356      /**
1357       * @expectedException        file_exception
1358       * @expectedExceptionMessage Invalid file name
1359       */
1360      public function test_create_file_from_string_filename_invalid() {
1361          $this->resetAfterTest(true);
1362  
1363          $filerecord = $this->generate_file_record();
1364          $fs = get_file_storage();
1365  
1366          $filerecord->filename = '';
1367  
1368          $file1 = $fs->create_file_from_string($filerecord, 'text contents');
1369      }
1370  
1371      /**
1372       * @expectedException        file_exception
1373       * @expectedExceptionMessage Invalid file timecreated
1374       */
1375      public function test_create_file_from_string_timecreated_invalid() {
1376          $this->resetAfterTest(true);
1377  
1378          $filerecord = $this->generate_file_record();
1379          $fs = get_file_storage();
1380  
1381          $filerecord->timecreated = 'today';
1382  
1383          $this->expectException('file_exception');
1384          $this->expectExceptionMessage('Invalid file timecreated');
1385          $file1 = $fs->create_file_from_string($filerecord, 'text contents');
1386      }
1387  
1388      /**
1389       * @expectedException        file_exception
1390       * @expectedExceptionMessage Invalid file timemodified
1391       */
1392      public function test_create_file_from_string_timemodified_invalid() {
1393          $this->resetAfterTest(true);
1394  
1395          $filerecord = $this->generate_file_record();
1396          $fs = get_file_storage();
1397  
1398          $filerecord->timemodified  = 'today';
1399  
1400          $file1 = $fs->create_file_from_string($filerecord, 'text contents');
1401      }
1402  
1403      public function test_create_file_from_string_duplicate() {
1404          $this->resetAfterTest(true);
1405  
1406          $filerecord = $this->generate_file_record();
1407          $fs = get_file_storage();
1408  
1409          $file1 = $fs->create_file_from_string($filerecord, 'text contents');
1410  
1411          // Creating a file validating unique constraint.
1412          $this->expectException('stored_file_creation_exception');
1413          $file2 = $fs->create_file_from_string($filerecord, 'text contents');
1414      }
1415  
1416      /**
1417       * @expectedException        file_exception
1418       * @expectedExceptionMessage Invalid contextid
1419       */
1420      public function test_create_file_from_pathname_contextid_invalid() {
1421          global $CFG;
1422          $path = $CFG->dirroot.'/lib/filestorage/tests/fixtures/testimage.jpg';
1423  
1424          $this->resetAfterTest(true);
1425  
1426          $filerecord = $this->generate_file_record();
1427          $fs = get_file_storage();
1428  
1429          $filerecord->contextid = 'invalid';
1430  
1431          $file1 = $fs->create_file_from_pathname($filerecord, $path);
1432      }
1433  
1434      /**
1435       * @expectedException        file_exception
1436       * @expectedExceptionMessage Invalid component
1437       */
1438      public function test_create_file_from_pathname_component_invalid() {
1439          global $CFG;
1440          $path = $CFG->dirroot.'/lib/filestorage/tests/fixtures/testimage.jpg';
1441  
1442          $this->resetAfterTest(true);
1443  
1444          $filerecord = $this->generate_file_record();
1445          $fs = get_file_storage();
1446  
1447          $filerecord->component = 'bad/component';
1448  
1449          $file1 = $fs->create_file_from_pathname($filerecord, $path);
1450      }
1451  
1452      /**
1453       * @expectedException        file_exception
1454       * @expectedExceptionMessage Invalid filearea
1455       */
1456      public function test_create_file_from_pathname_filearea_invalid() {
1457          global $CFG;
1458          $path = $CFG->dirroot.'/lib/filestorage/tests/fixtures/testimage.jpg';
1459  
1460          $this->resetAfterTest(true);
1461  
1462          $filerecord = $this->generate_file_record();
1463          $fs = get_file_storage();
1464  
1465          $filerecord->filearea = 'bad-filearea';
1466  
1467          $file1 = $fs->create_file_from_pathname($filerecord, $path);
1468      }
1469  
1470      /**
1471       * @expectedException        file_exception
1472       * @expectedExceptionMessage Invalid itemid
1473       */
1474      public function test_create_file_from_pathname_itemid_invalid() {
1475          global $CFG;
1476          $path = $CFG->dirroot.'/lib/filestorage/tests/fixtures/testimage.jpg';
1477  
1478          $this->resetAfterTest(true);
1479  
1480          $filerecord = $this->generate_file_record();
1481          $fs = get_file_storage();
1482  
1483          $filerecord->itemid = 'bad-itemid';
1484  
1485           $file1 = $fs->create_file_from_pathname($filerecord, $path);
1486      }
1487  
1488      /**
1489       * @expectedException        file_exception
1490       * @expectedExceptionMessage Invalid file path
1491       */
1492      public function test_create_file_from_pathname_filepath_invalid() {
1493          global $CFG;
1494          $path = $CFG->dirroot.'/lib/filestorage/tests/fixtures/testimage.jpg';
1495  
1496          $this->resetAfterTest(true);
1497  
1498          $filerecord = $this->generate_file_record();
1499          $fs = get_file_storage();
1500  
1501          $filerecord->filepath = 'a-/bad/-filepath';
1502  
1503          $file1 = $fs->create_file_from_pathname($filerecord, $path);
1504      }
1505  
1506      /**
1507       * @expectedException        file_exception
1508       * @expectedExceptionMessage Invalid file name
1509       */
1510      public function test_create_file_from_pathname_filename_invalid() {
1511          global $CFG;
1512          $path = $CFG->dirroot.'/lib/filestorage/tests/fixtures/testimage.jpg';
1513  
1514          $this->resetAfterTest(true);
1515  
1516          $filerecord = $this->generate_file_record();
1517          $fs = get_file_storage();
1518  
1519          $filerecord->filename = '';
1520  
1521          $file1 = $fs->create_file_from_pathname($filerecord, $path);
1522      }
1523  
1524      /**
1525       * @expectedException        file_exception
1526       * @expectedExceptionMessage Invalid file timecreated
1527       */
1528      public function test_create_file_from_pathname_timecreated_invalid() {
1529          global $CFG;
1530          $path = $CFG->dirroot.'/lib/filestorage/tests/fixtures/testimage.jpg';
1531  
1532          $this->resetAfterTest(true);
1533  
1534          $filerecord = $this->generate_file_record();
1535          $fs = get_file_storage();
1536  
1537          $filerecord->timecreated = 'today';
1538  
1539          $file1 = $fs->create_file_from_pathname($filerecord, $path);
1540      }
1541  
1542      /**
1543       * @expectedException        file_exception
1544       * @expectedExceptionMessage Invalid file timemodified
1545       */
1546      public function test_create_file_from_pathname_timemodified_invalid() {
1547          global $CFG;
1548          $path = $CFG->dirroot.'/lib/filestorage/tests/fixtures/testimage.jpg';
1549  
1550          $this->resetAfterTest(true);
1551  
1552          $filerecord = $this->generate_file_record();
1553          $fs = get_file_storage();
1554  
1555          $filerecord->timemodified  = 'today';
1556  
1557          $file1 = $fs->create_file_from_pathname($filerecord, $path);
1558      }
1559  
1560      /**
1561       * @expectedException        stored_file_creation_exception
1562       * @expectedExceptionMessage Can not create file "1/core/phpunit/0/testfile.txt"
1563       */
1564      public function test_create_file_from_pathname_duplicate_file() {
1565          global $CFG;
1566          $this->resetAfterTest(true);
1567  
1568          $path = $CFG->dirroot.'/lib/filestorage/tests/fixtures/testimage.jpg';
1569  
1570          $filerecord = $this->generate_file_record();
1571          $fs = get_file_storage();
1572  
1573          $file1 = $fs->create_file_from_pathname($filerecord, $path);
1574          $this->assertInstanceOf('stored_file', $file1);
1575  
1576          // Creating a file validating unique constraint.
1577          $file2 = $fs->create_file_from_pathname($filerecord, $path);
1578      }
1579  
1580      /**
1581       * Calling stored_file::delete_reference() on a non-reference file throws coding_exception
1582       */
1583      public function test_delete_reference_on_nonreference() {
1584  
1585          $this->resetAfterTest(true);
1586          $user = $this->setup_three_private_files();
1587          $fs = get_file_storage();
1588          $repos = repository::get_instances(array('type'=>'user'));
1589          $repo = reset($repos);
1590  
1591          $file = null;
1592          foreach ($fs->get_area_files($user->ctxid, 'user', 'private') as $areafile) {
1593              if (!$areafile->is_directory()) {
1594                  $file = $areafile;
1595                  break;
1596              }
1597          }
1598          $this->assertInstanceOf('stored_file', $file);
1599          $this->assertFalse($file->is_external_file());
1600  
1601          $this->expectException('coding_exception');
1602          $file->delete_reference();
1603      }
1604  
1605      /**
1606       * Calling stored_file::delete_reference() on a reference file does not affect other
1607       * symlinks to the same original
1608       */
1609      public function test_delete_reference_one_symlink_does_not_rule_them_all() {
1610  
1611          $this->resetAfterTest(true);
1612          $user = $this->setup_three_private_files();
1613          $fs = get_file_storage();
1614          $repos = repository::get_instances(array('type'=>'user'));
1615          $repo = reset($repos);
1616  
1617          // Create two aliases linking the same original.
1618  
1619          $originalfile = null;
1620          foreach ($fs->get_area_files($user->ctxid, 'user', 'private') as $areafile) {
1621              if (!$areafile->is_directory()) {
1622                  $originalfile = $areafile;
1623                  break;
1624              }
1625          }
1626          $this->assertInstanceOf('stored_file', $originalfile);
1627  
1628          // Calling delete_reference() on a non-reference file.
1629  
1630          $originalrecord = array(
1631              'contextid' => $originalfile->get_contextid(),
1632              'component' => $originalfile->get_component(),
1633              'filearea'  => $originalfile->get_filearea(),
1634              'itemid'    => $originalfile->get_itemid(),
1635              'filepath'  => $originalfile->get_filepath(),
1636              'filename'  => $originalfile->get_filename(),
1637          );
1638  
1639          $aliasrecord = $this->generate_file_record();
1640          $aliasrecord->filepath = '/A/';
1641          $aliasrecord->filename = 'symlink.txt';
1642  
1643          $ref = $fs->pack_reference($originalrecord);
1644          $aliasfile1 = $fs->create_file_from_reference($aliasrecord, $repo->id, $ref);
1645  
1646          $aliasrecord->filepath = '/B/';
1647          $aliasrecord->filename = 'symlink.txt';
1648          $ref = $fs->pack_reference($originalrecord);
1649          $aliasfile2 = $fs->create_file_from_reference($aliasrecord, $repo->id, $ref);
1650  
1651          // Refetch A/symlink.txt file.
1652          $symlink1 = $fs->get_file($aliasrecord->contextid, $aliasrecord->component,
1653              $aliasrecord->filearea, $aliasrecord->itemid, '/A/', 'symlink.txt');
1654          $this->assertTrue($symlink1->is_external_file());
1655  
1656          // Unlink the A/symlink.txt file.
1657          $symlink1->delete_reference();
1658          $this->assertFalse($symlink1->is_external_file());
1659  
1660          // Make sure that B/symlink.txt has not been affected.
1661          $symlink2 = $fs->get_file($aliasrecord->contextid, $aliasrecord->component,
1662              $aliasrecord->filearea, $aliasrecord->itemid, '/B/', 'symlink.txt');
1663          $this->assertTrue($symlink2->is_external_file());
1664      }
1665  
1666      /**
1667       * Make sure that when internal file is updated all references to it are
1668       * updated immediately. When it is deleted, the references are converted
1669       * to true copies.
1670       */
1671      public function test_update_reference_internal() {
1672          purge_all_caches();
1673          $this->resetAfterTest(true);
1674          $user = $this->setup_three_private_files();
1675          $fs = get_file_storage();
1676          $repos = repository::get_instances(array('type' => 'user'));
1677          $repo = reset($repos);
1678  
1679          // Create two aliases linking the same original.
1680  
1681          $areafiles = array_values($fs->get_area_files($user->ctxid, 'user', 'private', false, 'filename', false));
1682  
1683          $originalfile = $areafiles[0];
1684          $this->assertInstanceOf('stored_file', $originalfile);
1685          $contenthash = $originalfile->get_contenthash();
1686          $filesize = $originalfile->get_filesize();
1687  
1688          $substitutefile = $areafiles[1];
1689          $this->assertInstanceOf('stored_file', $substitutefile);
1690          $newcontenthash = $substitutefile->get_contenthash();
1691          $newfilesize = $substitutefile->get_filesize();
1692  
1693          $originalrecord = array(
1694              'contextid' => $originalfile->get_contextid(),
1695              'component' => $originalfile->get_component(),
1696              'filearea'  => $originalfile->get_filearea(),
1697              'itemid'    => $originalfile->get_itemid(),
1698              'filepath'  => $originalfile->get_filepath(),
1699              'filename'  => $originalfile->get_filename(),
1700          );
1701  
1702          $aliasrecord = $this->generate_file_record();
1703          $aliasrecord->filepath = '/A/';
1704          $aliasrecord->filename = 'symlink.txt';
1705  
1706          $ref = $fs->pack_reference($originalrecord);
1707          $symlink1 = $fs->create_file_from_reference($aliasrecord, $repo->id, $ref);
1708          // Make sure created alias is a reference and has the same size and contenthash as source.
1709          $this->assertEquals($contenthash, $symlink1->get_contenthash());
1710          $this->assertEquals($filesize, $symlink1->get_filesize());
1711          $this->assertEquals($repo->id, $symlink1->get_repository_id());
1712          $this->assertNotEmpty($symlink1->get_referencefileid());
1713          $referenceid = $symlink1->get_referencefileid();
1714  
1715          $aliasrecord->filepath = '/B/';
1716          $aliasrecord->filename = 'symlink.txt';
1717          $ref = $fs->pack_reference($originalrecord);
1718          $symlink2 = $fs->create_file_from_reference($aliasrecord, $repo->id, $ref);
1719          // Make sure created alias is a reference and has the same size and contenthash as source.
1720          $this->assertEquals($contenthash, $symlink2->get_contenthash());
1721          $this->assertEquals($filesize, $symlink2->get_filesize());
1722          $this->assertEquals($repo->id, $symlink2->get_repository_id());
1723          // Make sure both aliases have the same reference id.
1724          $this->assertEquals($referenceid, $symlink2->get_referencefileid());
1725  
1726          // Overwrite ofiginal file.
1727          $originalfile->replace_file_with($substitutefile);
1728          $this->assertEquals($newcontenthash, $originalfile->get_contenthash());
1729          $this->assertEquals($newfilesize, $originalfile->get_filesize());
1730  
1731          // References to the internal files must be synchronised immediately.
1732          // Refetch A/symlink.txt file.
1733          $symlink1 = $fs->get_file($aliasrecord->contextid, $aliasrecord->component,
1734              $aliasrecord->filearea, $aliasrecord->itemid, '/A/', 'symlink.txt');
1735          $this->assertTrue($symlink1->is_external_file());
1736          $this->assertEquals($newcontenthash, $symlink1->get_contenthash());
1737          $this->assertEquals($newfilesize, $symlink1->get_filesize());
1738          $this->assertEquals($repo->id, $symlink1->get_repository_id());
1739          $this->assertEquals($referenceid, $symlink1->get_referencefileid());
1740  
1741          // Refetch B/symlink.txt file.
1742          $symlink2 = $fs->get_file($aliasrecord->contextid, $aliasrecord->component,
1743              $aliasrecord->filearea, $aliasrecord->itemid, '/B/', 'symlink.txt');
1744          $this->assertTrue($symlink2->is_external_file());
1745          $this->assertEquals($newcontenthash, $symlink2->get_contenthash());
1746          $this->assertEquals($newfilesize, $symlink2->get_filesize());
1747          $this->assertEquals($repo->id, $symlink2->get_repository_id());
1748          $this->assertEquals($referenceid, $symlink2->get_referencefileid());
1749  
1750          // Remove original file.
1751          $originalfile->delete();
1752  
1753          // References must be converted to independend files.
1754          // Refetch A/symlink.txt file.
1755          $symlink1 = $fs->get_file($aliasrecord->contextid, $aliasrecord->component,
1756              $aliasrecord->filearea, $aliasrecord->itemid, '/A/', 'symlink.txt');
1757          $this->assertFalse($symlink1->is_external_file());
1758          $this->assertEquals($newcontenthash, $symlink1->get_contenthash());
1759          $this->assertEquals($newfilesize, $symlink1->get_filesize());
1760          $this->assertNull($symlink1->get_repository_id());
1761          $this->assertNull($symlink1->get_referencefileid());
1762  
1763          // Refetch B/symlink.txt file.
1764          $symlink2 = $fs->get_file($aliasrecord->contextid, $aliasrecord->component,
1765              $aliasrecord->filearea, $aliasrecord->itemid, '/B/', 'symlink.txt');
1766          $this->assertFalse($symlink2->is_external_file());
1767          $this->assertEquals($newcontenthash, $symlink2->get_contenthash());
1768          $this->assertEquals($newfilesize, $symlink2->get_filesize());
1769          $this->assertNull($symlink2->get_repository_id());
1770          $this->assertNull($symlink2->get_referencefileid());
1771      }
1772  
1773      public function test_get_unused_filename() {
1774          global $USER;
1775          $this->resetAfterTest(true);
1776  
1777          $fs = get_file_storage();
1778          $this->setAdminUser();
1779          $contextid = context_user::instance($USER->id)->id;
1780          $component = 'user';
1781          $filearea = 'private';
1782          $itemid = 0;
1783          $filepath = '/';
1784  
1785          // Create some private files.
1786          $file = new stdClass;
1787          $file->contextid = $contextid;
1788          $file->component = 'user';
1789          $file->filearea  = 'private';
1790          $file->itemid    = 0;
1791          $file->filepath  = '/';
1792          $file->source    = 'test';
1793          $filenames = array('foo.txt', 'foo (1).txt', 'foo (20).txt', 'foo (999)', 'bar.jpg', 'What (a cool file).jpg',
1794                  'Hurray! (1).php', 'Hurray! (2).php', 'Hurray! (9a).php', 'Hurray! (abc).php');
1795          foreach ($filenames as $key => $filename) {
1796              $file->filename = $filename;
1797              $userfile = $fs->create_file_from_string($file, "file $key $filename content");
1798              $this->assertInstanceOf('stored_file', $userfile);
1799          }
1800  
1801          // Asserting new generated names.
1802          $newfilename = $fs->get_unused_filename($contextid, $component, $filearea, $itemid, $filepath, 'unused.txt');
1803          $this->assertEquals('unused.txt', $newfilename);
1804          $newfilename = $fs->get_unused_filename($contextid, $component, $filearea, $itemid, $filepath, 'foo.txt');
1805          $this->assertEquals('foo (21).txt', $newfilename);
1806          $newfilename = $fs->get_unused_filename($contextid, $component, $filearea, $itemid, $filepath, 'foo (1).txt');
1807          $this->assertEquals('foo (21).txt', $newfilename);
1808          $newfilename = $fs->get_unused_filename($contextid, $component, $filearea, $itemid, $filepath, 'foo (2).txt');
1809          $this->assertEquals('foo (2).txt', $newfilename);
1810          $newfilename = $fs->get_unused_filename($contextid, $component, $filearea, $itemid, $filepath, 'foo (20).txt');
1811          $this->assertEquals('foo (21).txt', $newfilename);
1812          $newfilename = $fs->get_unused_filename($contextid, $component, $filearea, $itemid, $filepath, 'foo');
1813          $this->assertEquals('foo', $newfilename);
1814          $newfilename = $fs->get_unused_filename($contextid, $component, $filearea, $itemid, $filepath, 'foo (123)');
1815          $this->assertEquals('foo (123)', $newfilename);
1816          $newfilename = $fs->get_unused_filename($contextid, $component, $filearea, $itemid, $filepath, 'foo (999)');
1817          $this->assertEquals('foo (1000)', $newfilename);
1818          $newfilename = $fs->get_unused_filename($contextid, $component, $filearea, $itemid, $filepath, 'bar.png');
1819          $this->assertEquals('bar.png', $newfilename);
1820          $newfilename = $fs->get_unused_filename($contextid, $component, $filearea, $itemid, $filepath, 'bar (12).png');
1821          $this->assertEquals('bar (12).png', $newfilename);
1822          $newfilename = $fs->get_unused_filename($contextid, $component, $filearea, $itemid, $filepath, 'bar.jpg');
1823          $this->assertEquals('bar (1).jpg', $newfilename);
1824          $newfilename = $fs->get_unused_filename($contextid, $component, $filearea, $itemid, $filepath, 'bar (1).jpg');
1825          $this->assertEquals('bar (1).jpg', $newfilename);
1826          $newfilename = $fs->get_unused_filename($contextid, $component, $filearea, $itemid, $filepath, 'What (a cool file).jpg');
1827          $this->assertEquals('What (a cool file) (1).jpg', $newfilename);
1828          $newfilename = $fs->get_unused_filename($contextid, $component, $filearea, $itemid, $filepath, 'Hurray! (1).php');
1829          $this->assertEquals('Hurray! (3).php', $newfilename);
1830  
1831          $this->expectException('coding_exception');
1832          $fs->get_unused_filename($contextid, $component, $filearea, $itemid, $filepath, '');
1833      }
1834  }
1835  
1836  class test_stored_file_inspection extends stored_file {
1837      public static function get_pretected_pathname(stored_file $file) {
1838          return $file->get_pathname_by_contenthash();
1839      }
1840  }


Generated: Thu Aug 11 10:00:09 2016 Cross-referenced by PHPXref 0.7.1