Completed
Push — master ( a0480c...0e2999 )
by Werner
27:34 queued 11:57
created
code/RootFolder.php 1 patch
Indentation   +142 added lines, -142 removed lines patch added patch discarded remove patch
@@ -9,146 +9,146 @@
 block discarded – undo
9 9
  */
10 10
 class RootFolder extends DataExtension
11 11
 {
12
-    private static $has_one = array(
13
-        'RootFolder' => 'Folder',
14
-    );
15
-
16
-    /**
17
-     * @var array exclude this page types and class names
18
-     */
19
-    private static $ignored_classes = array('VirtualPage', 'ErrorPage');
20
-
21
-    /**
22
-     * @var bool should folders be created for translated objects?
23
-     */
24
-    private static $create_folder_for_translations = false;
25
-
26
-    /**
27
-     * @var string default root for all folders; may be overwritten in config of decorated class
28
-     */
29
-    private static $folder_root = 'Articles';
30
-
31
-    public function onAfterWrite()
32
-    {
33
-        if ($this->owner->ID) {
34
-            $this->checkFolder();
35
-        }
36
-    }
37
-
38
-    /**
39
-     * Creates a folder for a page as a subfolder of the parent page
40
-     * You can exclude page types by setting $ignored_classes in config
41
-     *
42
-     * Doesn't create folders for translated pages by default.
43
-     *
44
-     * @TODO doesn't check if page is moved to another parent
45
-     */
46
-    public function checkFolder()
47
-    {
48
-        $ignoredPageTypes = Config::inst()->get($this->class, 'ignored_classes');
49
-
50
-        foreach ($ignoredPageTypes as $pagetype) {
51
-            if (is_a($this->owner, $pagetype)) {
52
-                return;
53
-            }
54
-        }
55
-
56
-        if (class_exists('Translatable')
57
-            && $this->owner->Locale !== Translatable::default_locale()
58
-            && !Config::inst()->get($this->class, 'create_folder_for_translations')
59
-        ) {
60
-            return;
61
-        }
62
-
63
-        if (!$this->owner->RootFolderID) {
64
-            $this->createRootFolder();
65
-        } else {
66
-            $this->updateRootFolder();
67
-        }
68
-    }
69
-
70
-    /**
71
-     * Does the work of creating a new RootFolder, saves the relation in the extended DataObject
72
-     */
73
-    protected function createRootFolder()
74
-    {
75
-        //get path to parent folder
76
-        $parent = $this->owner->hasExtension('Hierarchy')
77
-            ? $this->owner->getParent()
78
-            : null;
79
-        if (is_a($parent, 'Page') && $parentFolder = $parent->RootFolder()) {
80
-            $folderRoot = $parent->getRootFolderName();
81
-        } else {
82
-            //fallback to classes folder_root which is defined in your config.yml
83
-            $folderRoot = $this->getFolderRoot() . '/';
84
-        }
85
-
86
-        if ($folderRoot == '/') {
87
-            $folderRoot = getFolderRoot() . '/';
88
-        }
89
-
90
-        $folder = Folder::find_or_make($folderRoot . $this->owner->URLSegment);
91
-        $folder->Title = $this->owner->Title;
92
-        $folder->setName($this->owner->URLSegment);
93
-        $folder->write();
94
-
95
-        $this->owner->RootFolderID = $folder->ID;
96
-        $this->owner->write();
97
-    }
98
-
99
-    /**
100
-     * Does the work of updating the folder if the URLSegment or ParentID is changed.
101
-     * if both it does two writes...
102
-     *
103
-     * @todo: rethink moving subfolders as it may timeout on real large trees
104
-     */
105
-    protected function updateRootFolder()
106
-    {
107
-        $rootFolder = $this->owner->RootFolder();
108
-        if ($this->owner->isChanged('URLSegment') && $this->owner->URLSegment) {
109
-            $rootFolder->setName($this->owner->URLSegment);
110
-            $rootFolder->write();
111
-        }
112
-
113
-        if ($this->owner->isChanged('ParentID') && $this->owner->ParentID > 0) {
114
-            $oldParentID = $rootFolder->ParentID;
115
-            $newParentID = $this->owner->Parent()->RootFolderID;
116
-            if ($oldParentID !== $newParentID && $newParentID !== $rootFolder->ID) {
117
-                $rootFolder->setParentID($newParentID);
118
-                $rootFolder->write();
119
-            }
120
-        }
121
-    }
122
-
123
-    /**
124
-     * Returns the folder root for the current root folder, e.g. 'Articles',
125
-     * if a config $folder_root is defined in the decorated class.
126
-     *
127
-     * Falls back to global config
128
-     */
129
-    public function getFolderRoot()
130
-    {
131
-        return ($this->owner->config()->get('folder_root'))
132
-            ? $this->owner->config()->get('folder_root')
133
-            : Config::inst()->get($this->class, 'folder_root');
134
-    }
135
-
136
-
137
-    /**
138
-     * Helper function to return the name of the RootFolder for setting in @link UploadField or @link GridFieldBulkUpload
139
-     * By default relative to /assets/
140
-     *
141
-     * @param bool $relativeToAssetsDir
142
-     */
143
-    public function getRootFolderName($relativeToAssetsDir = true)
144
-    {
145
-        if ($this->owner->RootFolderID) {
146
-            return $relativeToAssetsDir
147
-                ? str_replace(ASSETS_DIR . '/', '', $this->owner->RootFolder()->getRelativePath())
148
-                : $this->owner->RootFolder()->getRelativePath();
149
-        } else {
150
-            //use folder root as fallback for now
151
-            return $this->getFolderRoot();
152
-        }
153
-    }
12
+	private static $has_one = array(
13
+		'RootFolder' => 'Folder',
14
+	);
15
+
16
+	/**
17
+	 * @var array exclude this page types and class names
18
+	 */
19
+	private static $ignored_classes = array('VirtualPage', 'ErrorPage');
20
+
21
+	/**
22
+	 * @var bool should folders be created for translated objects?
23
+	 */
24
+	private static $create_folder_for_translations = false;
25
+
26
+	/**
27
+	 * @var string default root for all folders; may be overwritten in config of decorated class
28
+	 */
29
+	private static $folder_root = 'Articles';
30
+
31
+	public function onAfterWrite()
32
+	{
33
+		if ($this->owner->ID) {
34
+			$this->checkFolder();
35
+		}
36
+	}
37
+
38
+	/**
39
+	 * Creates a folder for a page as a subfolder of the parent page
40
+	 * You can exclude page types by setting $ignored_classes in config
41
+	 *
42
+	 * Doesn't create folders for translated pages by default.
43
+	 *
44
+	 * @TODO doesn't check if page is moved to another parent
45
+	 */
46
+	public function checkFolder()
47
+	{
48
+		$ignoredPageTypes = Config::inst()->get($this->class, 'ignored_classes');
49
+
50
+		foreach ($ignoredPageTypes as $pagetype) {
51
+			if (is_a($this->owner, $pagetype)) {
52
+				return;
53
+			}
54
+		}
55
+
56
+		if (class_exists('Translatable')
57
+			&& $this->owner->Locale !== Translatable::default_locale()
58
+			&& !Config::inst()->get($this->class, 'create_folder_for_translations')
59
+		) {
60
+			return;
61
+		}
62
+
63
+		if (!$this->owner->RootFolderID) {
64
+			$this->createRootFolder();
65
+		} else {
66
+			$this->updateRootFolder();
67
+		}
68
+	}
69
+
70
+	/**
71
+	 * Does the work of creating a new RootFolder, saves the relation in the extended DataObject
72
+	 */
73
+	protected function createRootFolder()
74
+	{
75
+		//get path to parent folder
76
+		$parent = $this->owner->hasExtension('Hierarchy')
77
+			? $this->owner->getParent()
78
+			: null;
79
+		if (is_a($parent, 'Page') && $parentFolder = $parent->RootFolder()) {
80
+			$folderRoot = $parent->getRootFolderName();
81
+		} else {
82
+			//fallback to classes folder_root which is defined in your config.yml
83
+			$folderRoot = $this->getFolderRoot() . '/';
84
+		}
85
+
86
+		if ($folderRoot == '/') {
87
+			$folderRoot = getFolderRoot() . '/';
88
+		}
89
+
90
+		$folder = Folder::find_or_make($folderRoot . $this->owner->URLSegment);
91
+		$folder->Title = $this->owner->Title;
92
+		$folder->setName($this->owner->URLSegment);
93
+		$folder->write();
94
+
95
+		$this->owner->RootFolderID = $folder->ID;
96
+		$this->owner->write();
97
+	}
98
+
99
+	/**
100
+	 * Does the work of updating the folder if the URLSegment or ParentID is changed.
101
+	 * if both it does two writes...
102
+	 *
103
+	 * @todo: rethink moving subfolders as it may timeout on real large trees
104
+	 */
105
+	protected function updateRootFolder()
106
+	{
107
+		$rootFolder = $this->owner->RootFolder();
108
+		if ($this->owner->isChanged('URLSegment') && $this->owner->URLSegment) {
109
+			$rootFolder->setName($this->owner->URLSegment);
110
+			$rootFolder->write();
111
+		}
112
+
113
+		if ($this->owner->isChanged('ParentID') && $this->owner->ParentID > 0) {
114
+			$oldParentID = $rootFolder->ParentID;
115
+			$newParentID = $this->owner->Parent()->RootFolderID;
116
+			if ($oldParentID !== $newParentID && $newParentID !== $rootFolder->ID) {
117
+				$rootFolder->setParentID($newParentID);
118
+				$rootFolder->write();
119
+			}
120
+		}
121
+	}
122
+
123
+	/**
124
+	 * Returns the folder root for the current root folder, e.g. 'Articles',
125
+	 * if a config $folder_root is defined in the decorated class.
126
+	 *
127
+	 * Falls back to global config
128
+	 */
129
+	public function getFolderRoot()
130
+	{
131
+		return ($this->owner->config()->get('folder_root'))
132
+			? $this->owner->config()->get('folder_root')
133
+			: Config::inst()->get($this->class, 'folder_root');
134
+	}
135
+
136
+
137
+	/**
138
+	 * Helper function to return the name of the RootFolder for setting in @link UploadField or @link GridFieldBulkUpload
139
+	 * By default relative to /assets/
140
+	 *
141
+	 * @param bool $relativeToAssetsDir
142
+	 */
143
+	public function getRootFolderName($relativeToAssetsDir = true)
144
+	{
145
+		if ($this->owner->RootFolderID) {
146
+			return $relativeToAssetsDir
147
+				? str_replace(ASSETS_DIR . '/', '', $this->owner->RootFolder()->getRelativePath())
148
+				: $this->owner->RootFolder()->getRelativePath();
149
+		} else {
150
+			//use folder root as fallback for now
151
+			return $this->getFolderRoot();
152
+		}
153
+	}
154 154
 }
Please login to merge, or discard this patch.
tests/RootFolderTest.php 1 patch
Indentation   +130 added lines, -130 removed lines patch added patch discarded remove patch
@@ -6,134 +6,134 @@
 block discarded – undo
6 6
 class RootFolderTest extends SapphireTest
7 7
 {
8 8
 
9
-    protected static $fixture_file = 'RootFolderTest.yml';
10
-
11
-    /**
12
-     * Check if a folder is generated and saved when a page is saved.
13
-     */
14
-    public function testCreateFolder()
15
-    {
16
-        $page = Page::create();
17
-        $this->assertEquals(0, $page->RootFolderID, 'a new Page should not have a folder yet');
18
-
19
-        $page->Title = 'Create Page Test';
20
-
21
-        $page->write();
22
-
23
-        $this->assertNotEquals(0, $page->RootFolderID, 'a page should have a folder after saving');
24
-
25
-        $folder = $page->RootFolder();
26
-
27
-        $this->assertEquals($page->URLSegment, $folder->Name, 'Page URLSegment and Folder Title should be the same');
28
-        $path = ASSETS_DIR . '/' . $root = Config::inst()->get('RootFolder', 'folder_root') . '/'
29
-                . $page->URLSegment . '/';
30
-
31
-        $this->assertEquals(
32
-            $path,
33
-            $folder->getRelativePath(),
34
-            'folder path should be assets/Articles/' . $page->URLSegment
35
-        );
36
-    }
37
-
38
-    /**
39
-     * Checks if the folder will be updated when saving a page and changing the URLSegment
40
-     */
41
-    public function testUpdateFolder()
42
-    {
43
-        $page1 = $this->objFromFixture('Page', 'page1');
44
-        $folder = $page1->RootFolder();
45
-
46
-        $this->assertEquals($page1->URLSegment, $folder->Name, 'Page URLSegment and Folder Title should be the same');
47
-
48
-        $page1->URLSegment = ('updatedpage');
49
-        $page1->write();
50
-
51
-        $folder = $page1->RootFolder(); //reload folder after saving
52
-        $this->assertEquals('updatedpage', $folder->Name, 'Folder name should be updated after saving a page');
53
-        $this->assertEquals(
54
-            $page1->URLSegment,
55
-            $folder->Name,
56
-            'Page URLSegment and Folder Title should be the same, even after updating'
57
-        );
58
-    }
59
-
60
-    /**
61
-     * Checks if no folder is created for ignored page types, e.g. VirtualPage or ErrorPage
62
-     */
63
-    public function testIgnoredPageTypes()
64
-    {
65
-        $ignoredPageTypes = Config::inst()->get('RootFolder', 'ignored_classes');
66
-
67
-        foreach ($ignoredPageTypes as $type) {
68
-            $page = $type::create();
69
-
70
-            $page->write();
71
-            $this->assertEquals(
72
-                0,
73
-                $page->RootFolderID,
74
-                'Ignored page type ' . $type . ' should not have a RootFolderID'
75
-            );
76
-        }
77
-    }
78
-
79
-    /**
80
-     * Check if subpage's folder is a subfolder of parent page
81
-     */
82
-    public function testHierarchy()
83
-    {
84
-        $parent = $this->objFromFixture('Page', 'parentpage');
85
-        $child = $this->objFromFixture('Page', 'subpage');
86
-
87
-        //test if fixtures are set up properly
88
-        $this->assertEquals($parent->ID, $child->ParentID, 'subpage should be a child of parentpage');
89
-
90
-        $this->assertEquals(
91
-            $parent->RootFolderID,
92
-            $child->RootFolder()->ParentID,
93
-            'rootfolder2 should be a child of rootfolder 1'
94
-        );
95
-
96
-        $newPage = Page::create();
97
-        $newPage->ParentID = $parent->ID;
98
-        $newPage->Title = 'Hierarchy Test';
99
-        $newPage->urlSegment = 'hierarchy-test';
100
-        $newPage->write();
101
-
102
-        $this->assertEquals(
103
-            $parent->RootFolderID,
104
-            $newPage->RootFolder()->ParentID,
105
-            'new folder should be a child of page1 folder'
106
-        );
107
-    }
108
-
109
-    /**
110
-     * Checks if getRootFolderName() works properly
111
-     */
112
-    public function testGetRootFolderName()
113
-    {
114
-        $parent = $this->objFromFixture('Page', 'parentpage');
115
-        $child = $this->objFromFixture('Page', 'subpage');
116
-
117
-        //test if fixtures are set up properly
118
-        $this->assertEquals($parent->ID, $child->ParentID, 'subpage should be a child of parentpage');
119
-
120
-        $this->assertStringEndsWith(
121
-            $child->RootFolder()->Name . '/',
122
-            $child->getRootFolderName(),
123
-            'FolderName should be at the end of getRootFolderName()'
124
-        );
125
-
126
-        $root = Config::inst()->get('RootFolder', 'folder_root');
127
-        $this->assertStringStartsWith(
128
-            $root . '/' . $parent->RootFolder()->Name,
129
-            $child->getRootFolderName(),
130
-            'Parents FolderName should be at the beginning of getRootFolderName()'
131
-        );
132
-
133
-        $this->assertStringStartsWith(
134
-            ASSETS_DIR,
135
-            $child->getRootFolderName(false),
136
-            'ASSETS_DIR should be at the beginning of getRootFolderName(false)'
137
-        );
138
-    }
9
+	protected static $fixture_file = 'RootFolderTest.yml';
10
+
11
+	/**
12
+	 * Check if a folder is generated and saved when a page is saved.
13
+	 */
14
+	public function testCreateFolder()
15
+	{
16
+		$page = Page::create();
17
+		$this->assertEquals(0, $page->RootFolderID, 'a new Page should not have a folder yet');
18
+
19
+		$page->Title = 'Create Page Test';
20
+
21
+		$page->write();
22
+
23
+		$this->assertNotEquals(0, $page->RootFolderID, 'a page should have a folder after saving');
24
+
25
+		$folder = $page->RootFolder();
26
+
27
+		$this->assertEquals($page->URLSegment, $folder->Name, 'Page URLSegment and Folder Title should be the same');
28
+		$path = ASSETS_DIR . '/' . $root = Config::inst()->get('RootFolder', 'folder_root') . '/'
29
+				. $page->URLSegment . '/';
30
+
31
+		$this->assertEquals(
32
+			$path,
33
+			$folder->getRelativePath(),
34
+			'folder path should be assets/Articles/' . $page->URLSegment
35
+		);
36
+	}
37
+
38
+	/**
39
+	 * Checks if the folder will be updated when saving a page and changing the URLSegment
40
+	 */
41
+	public function testUpdateFolder()
42
+	{
43
+		$page1 = $this->objFromFixture('Page', 'page1');
44
+		$folder = $page1->RootFolder();
45
+
46
+		$this->assertEquals($page1->URLSegment, $folder->Name, 'Page URLSegment and Folder Title should be the same');
47
+
48
+		$page1->URLSegment = ('updatedpage');
49
+		$page1->write();
50
+
51
+		$folder = $page1->RootFolder(); //reload folder after saving
52
+		$this->assertEquals('updatedpage', $folder->Name, 'Folder name should be updated after saving a page');
53
+		$this->assertEquals(
54
+			$page1->URLSegment,
55
+			$folder->Name,
56
+			'Page URLSegment and Folder Title should be the same, even after updating'
57
+		);
58
+	}
59
+
60
+	/**
61
+	 * Checks if no folder is created for ignored page types, e.g. VirtualPage or ErrorPage
62
+	 */
63
+	public function testIgnoredPageTypes()
64
+	{
65
+		$ignoredPageTypes = Config::inst()->get('RootFolder', 'ignored_classes');
66
+
67
+		foreach ($ignoredPageTypes as $type) {
68
+			$page = $type::create();
69
+
70
+			$page->write();
71
+			$this->assertEquals(
72
+				0,
73
+				$page->RootFolderID,
74
+				'Ignored page type ' . $type . ' should not have a RootFolderID'
75
+			);
76
+		}
77
+	}
78
+
79
+	/**
80
+	 * Check if subpage's folder is a subfolder of parent page
81
+	 */
82
+	public function testHierarchy()
83
+	{
84
+		$parent = $this->objFromFixture('Page', 'parentpage');
85
+		$child = $this->objFromFixture('Page', 'subpage');
86
+
87
+		//test if fixtures are set up properly
88
+		$this->assertEquals($parent->ID, $child->ParentID, 'subpage should be a child of parentpage');
89
+
90
+		$this->assertEquals(
91
+			$parent->RootFolderID,
92
+			$child->RootFolder()->ParentID,
93
+			'rootfolder2 should be a child of rootfolder 1'
94
+		);
95
+
96
+		$newPage = Page::create();
97
+		$newPage->ParentID = $parent->ID;
98
+		$newPage->Title = 'Hierarchy Test';
99
+		$newPage->urlSegment = 'hierarchy-test';
100
+		$newPage->write();
101
+
102
+		$this->assertEquals(
103
+			$parent->RootFolderID,
104
+			$newPage->RootFolder()->ParentID,
105
+			'new folder should be a child of page1 folder'
106
+		);
107
+	}
108
+
109
+	/**
110
+	 * Checks if getRootFolderName() works properly
111
+	 */
112
+	public function testGetRootFolderName()
113
+	{
114
+		$parent = $this->objFromFixture('Page', 'parentpage');
115
+		$child = $this->objFromFixture('Page', 'subpage');
116
+
117
+		//test if fixtures are set up properly
118
+		$this->assertEquals($parent->ID, $child->ParentID, 'subpage should be a child of parentpage');
119
+
120
+		$this->assertStringEndsWith(
121
+			$child->RootFolder()->Name . '/',
122
+			$child->getRootFolderName(),
123
+			'FolderName should be at the end of getRootFolderName()'
124
+		);
125
+
126
+		$root = Config::inst()->get('RootFolder', 'folder_root');
127
+		$this->assertStringStartsWith(
128
+			$root . '/' . $parent->RootFolder()->Name,
129
+			$child->getRootFolderName(),
130
+			'Parents FolderName should be at the beginning of getRootFolderName()'
131
+		);
132
+
133
+		$this->assertStringStartsWith(
134
+			ASSETS_DIR,
135
+			$child->getRootFolderName(false),
136
+			'ASSETS_DIR should be at the beginning of getRootFolderName(false)'
137
+		);
138
+	}
139 139
 }
Please login to merge, or discard this patch.