Completed
Push — master ( 2fdc96...4f1f24 )
by Damian
12:09
created

FileMigrationHelper::getFilenameArray()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 9
Code Lines 7

Duplication

Lines 0
Ratio 0 %
Metric Value
dl 0
loc 9
rs 9.6666
cc 1
eloc 7
nc 1
nop 0
1
<?php
2
3
use SilverStripe\Filesystem\Storage\AssetStore;
4
5
/**
6
 * Service to help migrate File dataobjects to the new APL.
7
 *
8
 * This service does not alter these records in such a way that prevents downgrading back to 3.x
9
 *
10
 * @package framework
11
 * @subpackage filesystem
12
 */
13
class FileMigrationHelper extends Object {
14
15
	/**
16
	 * Perform migration
17
	 *
18
	 * @param string $base Absolute base path (parent of assets folder). Will default to BASE_PATH
19
	 * @return int Number of files successfully migrated
20
	 */
21
	public function run($base = null) {
22
		if(empty($base)) {
23
			$base = BASE_PATH;
24
		}
25
		// Check if the File dataobject has a "Filename" field.
26
		// If not, cannot migrate
27
		if(!DB::get_schema()->hasField('File', 'Filename')) {
28
			return 0;
29
		}
30
31
		// Set max time and memory limit
32
		increase_time_limit_to();
33
		increase_memory_limit_to();
34
35
		// Loop over all files
36
		$count = 0;
37
		$originalState = \Versioned::get_reading_mode();
38
		\Versioned::reading_stage('Stage');
39
		$filenameMap = $this->getFilenameArray();
40
		foreach($this->getFileQuery() as $file) {
41
			// Get the name of the file to import
42
			$filename = $filenameMap[$file->ID];
43
			$success = $this->migrateFile($base, $file, $filename);
44
			if($success) {
45
				$count++;
46
			}
47
		}
48
		\Versioned::set_reading_mode($originalState);
49
		return $count;
50
	}
51
52
	/**
53
	 * Migrate a single file
54
	 *
55
	 * @param string $base Absolute base path (parent of assets folder)
56
	 * @param File $file
57
	 * @param type $legacyFilename
58
	 * @return bool True if this file is imported successfully
59
	 */
60
	protected function migrateFile($base, File $file, $legacyFilename) {
61
		// Make sure this legacy file actually exists
62
		$path = $base . '/' . $legacyFilename;
63
		if(!file_exists($path)) {
64
			return false;
65
		}
66
67
		// Copy local file into this filesystem
68
		$filename = $file->getFilename();
69
		$result = $file->setFromLocalFile(
70
			$path, $filename, null, null,
71
			array('conflict' => AssetStore::CONFLICT_OVERWRITE)
72
		);
73
74
		// Move file if the APL changes filename value
75
		if($result['Filename'] !== $filename) {
76
			$this->setFilename($result['Filename']);
77
		}
78
79
		// Save and publish
80
		$file->write();
81
		$file->doPublish();
82
		return true;
83
	}
84
85
	/**
86
	 * Get list of File dataobjects to import
87
	 *
88
	 * @return DataList
89
	 */
90
	protected function getFileQuery() {
91
		// Select all records which have a Filename value, but not FileFilename.
92
		return File::get()
93
			->exclude('ClassName', 'Folder')
94
			->filter('FileFilename', array('', null))
95
			->where('"File"."Filename" IS NOT NULL AND "File"."Filename" != \'\''); // Non-orm field
96
	}
97
98
	/**
99
	 * Get map of File IDs to legacy filenames
100
	 *
101
	 * @return array
102
	 */
103
	protected function getFilenameArray() {
104
		// Convert original query, ensuring the legacy "Filename" is included in the result
105
		return $this
106
			->getFileQuery()
107
			->dataQuery()
108
			->selectFromTable('File', array('ID', 'Filename'))
109
			->execute()
110
			->map(); // map ID to Filename
111
	}
112
}
113