Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

API: Add sync_blacklisted_patterns for configuring files to skip in s…

…ync tasks

Fixes http://open.silverstripe.org/ticket/6210.

Replaces the hardcoded file patterns from Folder::syncChildren() with a new static Filesystem::$sync_blacklisted_patterns to describe files and folder names to skip when running Folder::sync().

Added unit test for Folder::sync()

Extended Folder::sync() to report on the number of file / folders skipped.
  • Loading branch information...
commit 1a36bb628ede6121d8a7aae49e915e39b5f9c279 1 parent d6733ca
Will Rossiter wilr authored
19 filesystem/Filesystem.php
View
@@ -19,9 +19,28 @@ class Filesystem extends Object {
*/
private static $folder_create_mask = 02775;
+ /**
+ * @var int
+ */
protected static $cache_folderModTime;
/**
+ * @config
+ *
+ * Array of file / folder regex expressions to exclude from the
+ * {@link Filesystem::sync()}
+ *
+ * @var array
+ */
+ private static $sync_blacklisted_patterns = array(
+ "/^\./",
+ "/^_combinedfiles$/i",
+ "/^_resampled$/i",
+ "/^web.config/i",
+ "/^Thumbs(.)/"
+ );
+
+ /**
* Create a folder on the filesystem, recursively.
* Uses {@link Filesystem::$folder_create_mask} to set filesystem permissions.
* Use {@link Folder::findOrMake()} to create a {@link Folder} database
34 filesystem/Folder.php
View
@@ -80,12 +80,14 @@ public static function find_or_make($folderPath) {
}
/**
- * Syncronise the file database with the actual content of the assets folder
+ * Synchronize the file database with the actual content of the assets
+ * folder.
*/
public function syncChildren() {
$parentID = (int)$this->ID; // parentID = 0 on the singleton, used as the 'root node';
$added = 0;
$deleted = 0;
+ $skipped = 0;
// First, merge any children that are duplicates
$duplicateChildrenNames = DB::query("SELECT \"Name\" FROM \"File\""
@@ -113,6 +115,7 @@ public function syncChildren() {
// We don't use DataObject so that things like subsites doesn't muck with this.
$dbChildren = DB::query("SELECT * FROM \"File\" WHERE \"ParentID\" = $parentID");
$hasDbChild = array();
+
if($dbChildren) {
foreach($dbChildren as $dbChild) {
$className = $dbChild['ClassName'];
@@ -120,6 +123,7 @@ public function syncChildren() {
$hasDbChild[$dbChild['Name']] = new $className($dbChild);
}
}
+
$unwantedDbChildren = $hasDbChild;
// if we're syncing a folder with no ID, we assume we're syncing the root assets folder
@@ -135,13 +139,28 @@ public function syncChildren() {
if(file_exists($baseDir)) {
$actualChildren = scandir($baseDir);
+ $ignoreRules = Config::inst()->get('Filesystem', 'sync_blacklisted_patterns');
+
foreach($actualChildren as $actualChild) {
- if($actualChild[0] == '.' || $actualChild[0] == '_' || substr($actualChild,0,6) == 'Thumbs'
- || $actualChild == 'web.config') {
+ if($ignoreRules) {
+ $skip = false;
+
+ foreach($ignoreRules as $rule) {
+ if(preg_match($rule, $actualChild)) {
+ $skip = true;
+
+ break;
+ }
+ }
+
+ if($skip) {
+ $skipped++;
- continue;
+ continue;
+ }
}
+
// A record with a bad class type doesn't deserve to exist. It must be purged!
if(isset($hasDbChild[$actualChild])) {
$child = $hasDbChild[$actualChild];
@@ -166,6 +185,7 @@ public function syncChildren() {
$childResult = $child->syncChildren();
$added += $childResult['added'];
$deleted += $childResult['deleted'];
+ $skipped += $childResult['skipped'];
}
// Clean up the child record from memory after use. Important!
@@ -182,7 +202,11 @@ public function syncChildren() {
DB::query("DELETE FROM \"File\" WHERE \"ID\" = $this->ID");
}
- return array('added' => $added, 'deleted' => $deleted);
+ return array(
+ 'added' => $added,
+ 'deleted' => $deleted,
+ 'skipped' => $skipped
+ );
}
/**
44 tests/filesystem/FolderTest.php
View
@@ -293,5 +293,49 @@ public function tearDown() {
parent::tearDown();
}
+
+ public function testSyncedChildren() {
+ mkdir(ASSETS_PATH ."/FolderTest");
+ mkdir(ASSETS_PATH ."/FolderTest/sync");
+
+ $files = array(
+ '.htaccess',
+ '.git',
+ 'web.config',
+ '.DS_Store',
+ '_my_synced_file.txt'
+ );
+
+ $folders = array(
+ '_combinedfiles',
+ '_resampled',
+ '_testsync'
+ );
+
+ foreach($files as $file) {
+ $fh = fopen(ASSETS_PATH."/FolderTest/sync/$file", "w");
+ fwrite($fh, 'test');
+ fclose($fh);
+ }
+
+ foreach($folders as $folder) {
+ mkdir(ASSETS_PATH ."/FolderTest/sync/". $folder);
+ }
+
+ $folder = Folder::find_or_make('/FolderTest/sync');
+ $result = $folder->syncChildren();
+
+ $this->assertEquals(10, $result['skipped']);
+ $this->assertEquals(2, $result['added']);
+
+ // folder with a path of _test should exist
+ $this->assertEquals(1, Folder::get()->filter(array(
+ 'Name' => '_testsync'
+ ))->count());
+
+ $this->assertEquals(1, File::get()->filter(array(
+ 'Name' => '_my_synced_file.txt'
+ ))->count());
+ }
}
Please sign in to comment.
Something went wrong with that request. Please try again.