public function testFilePrivate(){
		$src = new \Core\Filestore\Backends\FileLocal('core/tests/ivak_TV_Test_Screen.png');

		$dst = \Core\Filestore\Factory::File('private/tests/ivak_TV_Test_Screen.png');
		// Verify that this is a valid object.
		$this->assertInstanceOf('\Core\Filestore\File', $dst);

		// Make sure it's writable... just because :p
		$src->copyTo($dst);
		$this->assertTrue($dst->exists());
	}
Exemple #2
0
 /**
  * Copy in all the assets for this theme into the assets location.
  *
  * Returns false if nothing changed, else will return an array of all the changes that occured.
  *
  * @param bool $install   Set to false to uninstall the assets instead of installing.
  * @param int  $verbosity 0 for standard output, 1 for real-time, 2 for real-time verbose output.
  *
  * @return false | array
  * @throws \InstallerException
  */
 public function _parseAssets($install = true, $verbosity = 0)
 {
     $assetbase = \Core\Filestore\get_asset_path();
     $coretheme = \ConfigHandler::Get('/theme/selected');
     // WHY is core theme set to blank?!?
     // Damn installer...
     // this happens in the installer.
     if ($coretheme === null) {
         $coretheme = 'default';
     }
     $theme = $this->getKeyName();
     $changes = [];
     foreach ($this->_xmlloader->getElements('/assets/file') as $node) {
         // Cannot install assets if the directory is not setup!
         if (!$this->getAssetDir()) {
             continue;
         }
         $b = $this->getBaseDir();
         // The base filename with the directory.
         $filename = $node->getAttribute('filename');
         // The new theme asset will be installed into the same directory as its theme.
         // This differs from usual components because they just follow whatever theme is currently running.
         //$nf = Core::File($assetbase . $theme . '/' . $filename);
         $trimmedfilename = substr($b . $node->getAttribute('filename'), strlen($this->getAssetDir()));
         $themespecificfilename = $assetbase . $theme . '/' . $trimmedfilename;
         $newfilename = 'assets/' . $trimmedfilename;
         // Before anything, check and see if this file has a custom override file present.
         if (file_exists(ROOT_PDIR . 'themes/custom/' . $newfilename)) {
             // If so, then copy that asset to the custom directory too!
             $f = \Core\Filestore\Factory::File(ROOT_PDIR . 'themes/custom/' . $newfilename);
             $srcname = '!CUSTOM!';
         } else {
             // Otherwise, the local file is guaranteed to be a local file.
             $f = new \Core\Filestore\Backends\FileLocal($b . $filename);
             $srcname = '-theme- ';
         }
         if ($verbosity == 2) {
             CLI::PrintActionStart('Installing ' . $srcname . ' asset ' . $f->getBasename());
         }
         $nf = \Core\Filestore\Factory::File($newfilename);
         /*
         			// The various replacement possibilities for this file.
         			// The new destination must be in the theme-specific directory, this is a
         			// bit of a hack from the usual behaviour of the filestore system.
         			// Since that's designed to return the default if the theme-specific doesn't exist.
         			$replacements = array(
         				// The theme is not default, but the system translated the path to the default directory.
         				// This is because the file doesn't exist in any theme.
         				// This is actually expected behaviour, except unwanted here.
         				'default/' . $trimmedfilename => $theme . '/' . $trimmedfilename,
         				// The theme is not the currently installed, but the system translated the path to the that directory.
         				// This is because the filename is the same as the installed theme, so the system just translated there.
         				// We don't want that.
         				$coretheme . '/' . $trimmedfilename => $theme . '/' . $trimmedfilename,
         			);
         
         
         			foreach($replacements as $k => $v){
         				if($k == $v) continue;
         				if(strpos($nf->getFilename(), $k) !== false){
         					$nf->setFilename( str_replace($k, $v, $nf->getFilename()) );
         				}
         			}
         */
         // Check if this file even needs updated. (this is primarily used for reporting reasons)
         if ($nf->exists() && $nf->identicalTo($f)) {
             //echo "Skipping file, it's identical.<br/>";
             if ($verbosity == 2) {
                 CLI::PrintActionStatus('skip');
             }
             continue;
         } elseif ($nf->exists()) {
             $action = 'Replaced';
         } else {
             $action = 'Installed';
         }
         if (!$f->isReadable()) {
             throw new \InstallerException('Source file [' . $f->getFilename() . '] is not readable.');
         }
         try {
             $f->copyTo($nf, true);
         } catch (\Exception $e) {
             throw new \InstallerException('Unable to copy [' . $f->getFilename() . '] to [' . $nf->getFilename() . ']');
         }
         $change = $action . ' ' . $nf->getFilename();
         $changes[] = $change;
         if ($verbosity == 1) {
             CLI::PrintLine($change);
         } elseif ($verbosity == 2) {
             CLI::PrintActionStatus('ok');
         }
     }
     // If there are custom assets not registered by any application, install them too!
     // This will allow an admin to upload additional css resources and images easily.
     $directory = \Core\Filestore\Factory::Directory('themes/custom/assets');
     $ls = $directory->ls(null, true);
     $baseStrLen = strlen(ROOT_PDIR . '/themes/custom/assets');
     foreach ($ls as $fileOrDir) {
         if ($fileOrDir instanceof File) {
             $newfilename = substr($fileOrDir->getFilename(), $baseStrLen);
             if ($verbosity == 2) {
                 CLI::PrintActionStart('Installing CUSTOM   asset ' . $newfilename);
             }
             $nf = \Core\Filestore\Factory::File('asset/' . $newfilename);
             if ($nf->exists() && $nf->identicalTo($fileOrDir)) {
                 //echo "Skipping file, it's identical.<br/>";
                 if ($verbosity == 2) {
                     CLI::PrintActionStatus('skip');
                 }
                 continue;
             } elseif ($nf->exists()) {
                 $action = 'Replaced';
             } else {
                 $action = 'Installed';
             }
             try {
                 $fileOrDir->copyTo($nf, true);
             } catch (\Exception $e) {
                 throw new \InstallerException('Unable to copy [' . $fileOrDir->getFilename() . '] to [' . $nf->getFilename() . ']');
             }
             $change = $action . ' ' . $nf->getFilename();
             $changes[] = $change;
             if ($verbosity == 1) {
                 CLI::PrintLine($change);
             } elseif ($verbosity == 2) {
                 CLI::PrintActionStatus('ok');
             }
         }
     }
     if (!sizeof($changes)) {
         if ($verbosity > 0) {
             CLI::PrintLine('No changes required');
         }
         return false;
     }
     // Make sure the asset cache is purged!
     \Core\Cache::Delete('asset-resolveurl');
     return $changes;
 }
	public function testImageResizing(){
		// Start with this 1024x768 image.
		$file = new \Core\Filestore\Backends\FileLocal('core/tests/ivak_TV_Test_Screen.png');

		// Basic resize will scale large images down but will not scale small images up.
		$test = $file->getPreviewFile('32x32');
		$this->assertTrue($test->isImage());
		$dimensions = getimagesize($test->getFilename());
		$this->assertEquals(32, $dimensions[0]);
		$this->assertEquals(24, $dimensions[1]);

		// Basic resize will scale down images if one of the dimensions is greater than the requested.
		$test = $file->getPreviewFile('800x800');
		$this->assertTrue($test->isImage());
		$dimensions = getimagesize($test->getFilename());
		$this->assertEquals(800, $dimensions[0]);
		$this->assertEquals(600, $dimensions[1]);

		// Basic resize will NOT scale up an image.
		$test = $file->getPreviewFile('2048x2048');
		$this->assertTrue($test->isImage());
		$dimensions = getimagesize($test->getFilename());
		$this->assertEquals(1024, $dimensions[0]);
		$this->assertEquals(768, $dimensions[1]);

		// Force-Constraint forces the constraint regardless of original image source.
		$test = $file->getPreviewFile('32x32!');
		$this->assertTrue($test->isImage());
		$dimensions = getimagesize($test->getFilename());
		$this->assertEquals(32, $dimensions[0]);
		$this->assertEquals(32, $dimensions[1]);

		// Force-Constraint forces the constraint regardless of original image source.
		$test = $file->getPreviewFile('1040x1040!');
		$this->assertTrue($test->isImage());
		$dimensions = getimagesize($test->getFilename());
		$this->assertEquals(1040, $dimensions[0]);
		$this->assertEquals(1040, $dimensions[1]);

		// Fill area will scale up to match the smallest dimension.
		$test = $file->getPreviewFile('800x800^');
		$this->assertTrue($test->isImage());
		$dimensions = getimagesize($test->getFilename());
		$this->assertEquals(1067, $dimensions[0]);
		$this->assertEquals(800, $dimensions[1]);

		// Fill area will scale up to match the smallest dimension.
		$test = $file->getPreviewFile('1200x1200^');
		$this->assertTrue($test->isImage());
		$dimensions = getimagesize($test->getFilename());
		$this->assertEquals(1600, $dimensions[0]);
		$this->assertEquals(1200, $dimensions[1]);

		// Fill area will scale up to match the smallest dimension.
		$test = $file->getPreviewFile('32x32^');
		$this->assertTrue($test->isImage());
		$dimensions = getimagesize($test->getFilename());
		$this->assertEquals(42, $dimensions[0]);
		$this->assertEquals(32, $dimensions[1]);
	}
	public function testCopyTo() {
		$file = new \Core\Filestore\Backends\FileRemote($this->_testfile);

		// I should be able to copy to a filename.
		// this gets resolved to a local file.
		$copy = $file->copyTo('tmp/tests-fileremotetest-testcopyto.dat');
		$this->assertInstanceOf('\\Core\\Filestore\\File', $copy);
		$this->assertTrue($copy->exists());
		$this->assertTrue($copy->delete());

		// And it should be able to copy to a local file object.
		$copy = new \Core\Filestore\Backends\FileLocal('tmp/tests-fileremotetest-testcopyto.dat');
		$this->assertFalse($copy->exists());
		$file->copyTo($copy);
		$this->assertTrue($copy->exists());
		$this->assertTrue($copy->delete());
	}
	public function testCopyTo() {
		if(!$this->_ftp) $this->markTestSkipped('FTP disabled, skipping tests');

		$file = new \Core\Filestore\Backends\FileFTP('core/tests/updater-testdocument.txt');

		// I should be able to copy to a filename.
		// this gets resolved to a local file.
		$copy = $file->copyTo('tmp/tests-fileremotetest-testcopyto.dat');
		$this->assertInstanceOf('\\Core\\Filestore\\File', $copy);
		$this->assertTrue($copy->exists());
		$this->assertTrue($copy->delete());

		// And it should be able to copy to a local file object.
		$copy = new \Core\Filestore\Backends\FileLocal('tmp/tests-fileremotetest-testcopyto.dat');
		$this->assertFalse($copy->exists());
		$file->copyTo($copy);
		$this->assertTrue($copy->exists());
		$this->assertTrue($copy->delete());
	}
	/**
	 * Copy in all the assets for this component into the assets location.
	 *
	 * Returns false if nothing changed, else will return an array of all the changes that occured.
	 *
	 * @param boolean $install   Set to false to force uninstall/disable mode.
	 * @param int     $verbosity (default 0) 0: standard output, 1: real-time, 2: real-time verbose output.
	 *
	 * @return false | array
	 * @throws InstallerException
	 */
	public function _parseAssets($install = true, $verbosity = 0) {
		$assetbase = CDN_LOCAL_ASSETDIR;
		$theme     = ConfigHandler::Get('/theme/selected');
		$change    = '';
		$changes   = array();

		Core\Utilities\Logger\write_debug('Installing assets for ' . $this->getName());

		foreach ($this->_xmlloader->getElements('/assets/file') as $node) {
			/** @var DOMElement $node */
			$b = $this->getBaseDir();

			// The new file should have a filename identical to the original, with the exception of
			// everything before the filename.. ie: the ROOT_PDIR and the asset directory.
			$newfilename = 'assets/' . substr($b . $node->getAttribute('filename'), strlen($this->getAssetDir()));

			// Before anything, check and see if this file has a custom override file present.
			if(file_exists(ROOT_PDIR . 'themes/custom/' . $newfilename)){
				// If so, then copy that asset to the custom directory too!
				$f = new \Core\Filestore\Backends\FileLocal(ROOT_PDIR . 'themes/custom/' . $newfilename);
				$srcname = '!CUSTOM!';
			}
			elseif(file_exists(ROOT_PDIR . 'themes/' . $theme . '/' . $newfilename)){
				// Allow the currently enabled theme to override assets too.
				$f = new \Core\Filestore\Backends\FileLocal(ROOT_PDIR . 'themes/' . $theme . '/' . $newfilename);
				$srcname = '-theme- ';
			}
			else{
				// Otherwise, the local file is guaranteed to be a local file.
				$f = new \Core\Filestore\Backends\FileLocal($b . $node->getAttribute('filename'));
				$srcname = 'original';
			}

			if($verbosity == 2){
				CLI::PrintActionStart('Installing ' . $srcname . ' asset ' . $f->getBasename());
			}

			$nf = \Core\Filestore\Factory::File($newfilename);
			//var_dump($newfilename, $nf->getFilename(), $nf);

			// If it's null, don't change the path any.
			/*if ($theme === null) {
				// Don't do anything.
			}
			// The new destination must be in the default directory, this is a
			// bit of a hack from the usual behaviour of the filestore system.
			elseif ($theme != 'default' && strpos($nf->getFilename(), $assetbase . $theme) !== false) {
				$nf->setFilename(str_replace($assetbase . $theme, $assetbase . 'default', $nf->getFilename()));
			}*/

			// Check if this file even needs updated. (this is primarily used for reporting reasons)
			$newfileexists    = $nf->exists();
			$newfileidentical = $nf->identicalTo($f);


			if(
				$newfileexists &&
				$newfileidentical &&
				$f instanceof \Core\Filestore\Backends\FileLocal &&
				$nf instanceof \Core\Filestore\Backends\FileLocal &&
				$f->getMTime() != $nf->getMTime()
			){
				// This is a bit of a hack because in 2.6.0 and above, the mtime is duplicated along with the contents.
				// This is to speed up file scans for local -> local disk changes.
				touch($nf->getFilename(), $f->getMTime());
				$change = 'Modified timestamp on ' . $nf->getFilename();
				$changes[] = $change;

				if($verbosity == 1){
					CLI::PrintLine($change);
				}
				elseif($verbosity == 2){
					CLI::PrintActionStatus('ok');
				}

				continue;
			}
			elseif($newfileexists && $newfileidentical){
				// The new file and old file are identical, just continue.

				if($verbosity == 2){
					CLI::PrintActionStatus('skip');
				}

				continue;
			}
			// Otherwise if it exists, I want to be able to inform the user that it was replaced and not just installed.
			elseif ($newfileexists) {
				$action = 'Replaced';
			}
			// Otherwise otherwise, it's a new file.
			else {
				$action = 'Installed';
			}


			try {
				$f->copyTo($nf, true);
			}
			catch (Exception $e) {
				throw new InstallerException('Unable to copy [' . $f->getFilename() . '] to [' . $nf->getFilename() . ']');
			}

			$change = $action . ' ' . $nf->getFilename();
			$changes[] = $change;

			if($verbosity == 1){
				CLI::PrintLine($change);
			}
			elseif($verbosity == 2){
				CLI::PrintActionStatus('ok');
			}
		}

		if (!sizeof($changes)){
			if($verbosity > 0){
				CLI::PrintLine('No changes required');
			}
			return false;
		}

		// Make sure the asset cache is purged!
		\Core\Cache::Delete('core-components');

		return $changes;
	}