Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
NEW: Add task to remove/protect _versions folders
- Loading branch information
Aaron Carlino
committed
Sep 24, 2019
1 parent
1df69c4
commit 1308911
Showing
3 changed files
with
328 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
<?php | ||
|
||
namespace SilverStripe\Assets\Dev\Tasks; | ||
|
||
use SilverStripe\Assets\Dev\VersionedFilesMigrator; | ||
use SilverStripe\Dev\BuildTask; | ||
|
||
class VersionedFilesMigrationTask extends BuildTask | ||
{ | ||
const STRATEGY_DELETE = 'delete'; | ||
|
||
const STRATEGY_PROTECT = 'protect'; | ||
|
||
private static $segment = 'migrate-versionedfiles'; | ||
|
||
protected $title = 'Migrate versionedfiles'; | ||
|
||
protected $description = 'If you had the symbiote/silverstripe-versionedfiles module installed on your 3.x site, it | ||
is no longer needed in 4.x as this functionality is provided by default. This task will remove the old _versions | ||
folders or protect them, depending on the strategy you use. Use ?strategy=delete or ?strategy=protect (Apache | ||
only). [Default: delete]'; | ||
|
||
/** | ||
* @param HTTPRequest $request | ||
*/ | ||
public function run($request) | ||
{ | ||
$strategy = $request->getVar('strategy') ?: self::STRATEGY_DELETE; | ||
$migrator = VersionedFilesMigrator::create($strategy, ASSETS_PATH, true); | ||
$migrator->migrate(); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,195 @@ | ||
<?php | ||
|
||
namespace SilverStripe\Assets\Dev; | ||
|
||
use SilverStripe\Assets\Filesystem; | ||
use SilverStripe\Assets\Storage\AssetStore; | ||
use SilverStripe\Control\Director; | ||
use SilverStripe\Control\HTTPRequest; | ||
use SilverStripe\Core\Injector\Injectable; | ||
use SilverStripe\Core\Path; | ||
use SilverStripe\Dev\BuildTask; | ||
use InvalidArgumentException; | ||
use Symfony\Component\Finder\Finder; | ||
use Symfony\Component\Finder\SplFileInfo; | ||
|
||
class VersionedFilesMigrator | ||
{ | ||
use Injectable; | ||
|
||
const STRATEGY_DELETE = 'delete'; | ||
|
||
const STRATEGY_PROTECT = 'protect'; | ||
|
||
/** | ||
* @var array | ||
*/ | ||
private static $dependencies = [ | ||
'finder' => '%$' . Finder::class, | ||
]; | ||
|
||
/** | ||
* @var Finder | ||
*/ | ||
private $finder; | ||
|
||
/** | ||
* @var string | ||
*/ | ||
private $basePath = ASSETS_DIR; | ||
|
||
/** | ||
* @var string | ||
*/ | ||
private $strategy = self::STRATEGY_DELETE; | ||
|
||
/** | ||
* @var bool | ||
*/ | ||
private $showOutput = true; | ||
|
||
/** | ||
* List of logged messages, if $showOutput is false | ||
* @var array | ||
*/ | ||
private $log = []; | ||
|
||
/** | ||
* VersionedFilesMigrationTask constructor. | ||
* @param string $strategy | ||
* @param string $basePath | ||
* @param bool $output | ||
*/ | ||
public function __construct($strategy = self::STRATEGY_DELETE, $basePath = ASSETS_DIR, $output = true) | ||
{ | ||
if (!in_array($strategy, [self::STRATEGY_DELETE, self::STRATEGY_PROTECT])) { | ||
throw new InvalidArgumentException(sprintf( | ||
'Invalid strategy: %s', | ||
$strategy | ||
)); | ||
} | ||
$this->basePath = $basePath; | ||
$this->strategy = $strategy; | ||
$this->showOutput = $output; | ||
} | ||
|
||
/** | ||
* @return void | ||
*/ | ||
public function migrate() | ||
{ | ||
if ($this->strategy === self::STRATEGY_PROTECT) { | ||
$this->doProtect(); | ||
} else { | ||
$this->doDelete(); | ||
} | ||
} | ||
|
||
/** | ||
* @return void | ||
*/ | ||
private function doProtect() | ||
{ | ||
foreach ($this->getVersionDirectories() as $path) { | ||
$htaccessPath = Path::join($path, '.htaccess'); | ||
if (!file_exists($htaccessPath)) { | ||
$content = "Order deny,allow\nDeny from all"; | ||
@file_put_contents($htaccessPath, $content); | ||
if (file_exists($htaccessPath)) { | ||
$this->output("Added .htaccess file to $htaccessPath"); | ||
} else { | ||
$this->output("Failed to add .htaccess file to $htaccessPath"); | ||
} | ||
} | ||
} | ||
} | ||
|
||
/** | ||
* @return void | ||
*/ | ||
private function doDelete() | ||
{ | ||
foreach ($this->getVersionDirectories() as $path) { | ||
if (!is_dir($path)) { | ||
continue; | ||
} | ||
|
||
Filesystem::removeFolder($path); | ||
|
||
if (!is_dir($path)) { | ||
$this->output("Deleted $path"); | ||
} else { | ||
$this->output("Failed to delete $path"); | ||
} | ||
} | ||
} | ||
|
||
/** | ||
* @return array | ||
*/ | ||
private function getVersionDirectories() | ||
{ | ||
$results = $this | ||
->getFinder() | ||
->directories() | ||
->name('_versions') | ||
->in($this->basePath); | ||
|
||
$folders = []; | ||
|
||
/* @var SplFileInfo $result */ | ||
foreach ($results as $result) { | ||
$folders[] = $result->getPathname(); | ||
} | ||
|
||
return $folders; | ||
} | ||
|
||
/** | ||
* @return string | ||
*/ | ||
private function nl() | ||
{ | ||
return Director::is_cli() ? PHP_EOL : "<br />"; | ||
} | ||
|
||
/** | ||
* @param string $msg | ||
*/ | ||
private function output($msg) | ||
{ | ||
if ($this->showOutput) { | ||
echo $msg . $this->nl(); | ||
} else { | ||
$this->log[] = $msg; | ||
} | ||
} | ||
|
||
/** | ||
* @param Finder $finder | ||
* @return $this | ||
*/ | ||
public function setFinder(Finder $finder) | ||
{ | ||
$this->finder = $finder; | ||
|
||
return $this; | ||
} | ||
|
||
/** | ||
* @return Finder | ||
*/ | ||
public function getFinder() | ||
{ | ||
return $this->finder; | ||
} | ||
|
||
/** | ||
* @return array | ||
*/ | ||
public function getLog() | ||
{ | ||
return $this->log; | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
<?php | ||
|
||
namespace SilverStripe\Assets\Tests; | ||
|
||
use SilverStripe\Assets\Dev\Tasks\VersionedFilesMigrationTask; | ||
use Silverstripe\Assets\Dev\TestAssetStore; | ||
use SilverStripe\Assets\Dev\VersionedFilesMigrator; | ||
use SilverStripe\Assets\File; | ||
use SilverStripe\Assets\FileMigrationHelper; | ||
use SilverStripe\Assets\Filesystem; | ||
use SilverStripe\Assets\Flysystem\FlysystemAssetStore; | ||
use SilverStripe\Assets\Folder; | ||
use SilverStripe\Assets\Tests\FileMigrationHelperTest\Extension; | ||
use SilverStripe\Control\HTTPRequest; | ||
use SilverStripe\Core\Config\Config; | ||
use SilverStripe\Core\Path; | ||
use SilverStripe\Dev\SapphireTest; | ||
|
||
class VersionedFilesMigratorTest extends SapphireTest | ||
{ | ||
protected $usesTransactions = false; | ||
|
||
/** | ||
* get the BASE_PATH for this test | ||
* | ||
* @return string | ||
*/ | ||
protected function getBasePath() | ||
{ | ||
return ASSETS_PATH . '/VersionedFilesMigrationTest'; | ||
} | ||
|
||
|
||
public function setUp() | ||
{ | ||
parent::setUp(); | ||
|
||
TestAssetStore::activate('VersionedFilesMigrationTest/assets'); | ||
$dest = TestAssetStore::base_path(); | ||
Filesystem::makeFolder(Path::join($dest, 'folder3')); | ||
Filesystem::makeFolder(Path::join($dest, 'folder2', 'subfolder2')); | ||
|
||
foreach ($this->getTestVersionDirectories() as $path) { | ||
Filesystem::makeFolder($path); | ||
} | ||
} | ||
|
||
public function tearDown() | ||
{ | ||
TestAssetStore::reset(); | ||
Filesystem::removeFolder($this->getBasePath()); | ||
parent::tearDown(); | ||
} | ||
|
||
/** | ||
* Test delete migration | ||
*/ | ||
public function testMigrationDeletes() | ||
{ | ||
$migrator = VersionedFilesMigrator::create( | ||
VersionedFilesMigrator::STRATEGY_DELETE, | ||
TestAssetStore::base_path(), | ||
false | ||
); | ||
$migrator->migrate(); | ||
|
||
foreach ($this->getTestVersionDirectories() as $dir) { | ||
$path = Path::join(BASE_PATH, $dir); | ||
$this->assertFalse(is_dir($path), $dir . ' still exists!'); | ||
} | ||
} | ||
|
||
/** | ||
* Test protect migration | ||
*/ | ||
public function testMigrationProtects() | ||
{ | ||
$migrator = VersionedFilesMigrator::create( | ||
VersionedFilesMigrator::STRATEGY_PROTECT, | ||
TestAssetStore::base_path(), | ||
false | ||
); | ||
$migrator->migrate(); | ||
|
||
foreach ($this->getTestVersionDirectories() as $dir) { | ||
$path = Path::join($dir, '.htaccess'); | ||
$this->assertTrue(file_exists($path), $path . ' does not exist'); | ||
} | ||
} | ||
|
||
private function getTestVersionDirectories() | ||
{ | ||
$base = TestAssetStore::base_path(); | ||
return [ | ||
Path::join($base, 'folder1', '_versions'), | ||
Path::join($base, 'folder2', '_versions'), | ||
Path::join($base, 'folder1', 'subfolder1', '_versions') | ||
]; | ||
} | ||
} |