diff --git a/core/i18nTextCollector.php b/core/i18nTextCollector.php index b6485afc1..87227be49 100644 --- a/core/i18nTextCollector.php +++ b/core/i18nTextCollector.php @@ -201,9 +201,12 @@ class i18nTextCollector extends Object { $includeName = $reg[1]; $includeFileName = "{$includeName}.ss"; $filePath = SSViewer::getTemplateFileByType($includeName, 'Includes'); - $includeContent = file_get_contents($filePath); + if(!$filePath) $filePath = SSViewer::getTemplateFileByType($includeName, 'main'); + if($filePath) { + $includeContent = file_get_contents($filePath); + $entitiesArr = array_merge($entitiesArr,(array)$this->collectFromTemplate($includeContent, $module, $includeFileName)); + } // @todo Will get massively confused if you include the includer -> infinite loop - $entitiesArr = array_merge($entitiesArr,(array)$this->collectFromTemplate($includeContent, $module, $includeFileName)); } // @todo respect template tags (< % _t() % > instead of _t()) diff --git a/core/i18nTextCollectorTask.php b/core/i18nTextCollectorTask.php index dbb06e129..269282ea5 100644 --- a/core/i18nTextCollectorTask.php +++ b/core/i18nTextCollectorTask.php @@ -25,6 +25,7 @@ class i18nTextCollectorTask extends BuildTask { * @uses DataObject->collectI18nStatics() */ public function run($request) { + set_time_limit(0); $c = new i18nTextCollector(); $restrictModules = ($request->getVar('module')) ? explode(',', $request->getVar('module')) : null; return $c->run($restrictModules); diff --git a/core/model/RedirectorPage.php b/core/model/RedirectorPage.php index a8f117e81..7e9bf980a 100755 --- a/core/model/RedirectorPage.php +++ b/core/model/RedirectorPage.php @@ -62,7 +62,7 @@ class RedirectorPage extends Page { function redirectionLink() { if($this->RedirectionType == 'External') { if($this->ExternalURL) { - return Convert::raw2att($this->ExternalURL); + return $this->ExternalURL; } } else { diff --git a/core/model/SiteTree.php b/core/model/SiteTree.php index 02b054a5d..7c27a57b1 100644 --- a/core/model/SiteTree.php +++ b/core/model/SiteTree.php @@ -1041,6 +1041,18 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid parent::onAfterWrite(); } + function onBeforeDelete() { + parent::onBeforeDelete(); + + // If deleting this page, delete all its children. + if($children = $this->Children()) { + foreach($children as $child) { + $child->delete(); + } + } + } + + function onAfterDelete() { // Need to flush cache to avoid outdated versionnumber references $this->flushCache(); @@ -1389,8 +1401,8 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid } } - if($this->IsDeletedFromStage) { - if($this->can('CMSEdit')) { + if($this->canEdit()) { + if($this->IsDeletedFromStage) { if($this->ExistsOnLive) { // "restore" $actions->push(new FormAction('revert',_t('CMSMain.RESTORE','Restore'))); @@ -1400,13 +1412,11 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid // "restore" $actions->push(new FormAction('restore',_t('CMSMain.RESTORE','Restore'))); } - } - } else { - if($this->canEdit()) { + } else { // "delete" $actions->push($deleteAction = new FormAction('delete',_t('CMSMain.DELETE','Delete from the draft site'))); $deleteAction->addExtraClass('delete'); - + // "save" $actions->push(new FormAction('save',_t('CMSMain.SAVE','Save'))); } diff --git a/css/SelectionGroup.css b/css/SelectionGroup.css index 29018adf6..3d13d5ee0 100644 --- a/css/SelectionGroup.css +++ b/css/SelectionGroup.css @@ -5,9 +5,10 @@ .SelectionGroup li { list-style-type: none; float : left; + width: 100%; clear : both; } -.SelectionGroup li input { +.SelectionGroup li input.selector { width: 20px; float : left; } diff --git a/forms/TextareaField.php b/forms/TextareaField.php index e972c2ecd..3f68b8866 100755 --- a/forms/TextareaField.php +++ b/forms/TextareaField.php @@ -47,7 +47,7 @@ class TextareaField extends FormField { return $this->createTag( 'span', $attributes, - ($this->value) ? Convert::raw2xml($this->value) : '(' . _t('FormField.NONE', 'none') . ')' + (($this->value) ? htmlentities($this->value) : '(' . _t('FormField.NONE', 'none') . ')') ); } else { $attributes = array( @@ -60,7 +60,7 @@ class TextareaField extends FormField { if($this->disabled) $attributes['disabled'] = 'disabled'; - return $this->createTag('textarea', $attributes, Convert::raw2xml($this->value)); + return $this->createTag('textarea', $attributes, htmlentities($this->value)); } } diff --git a/tests/SiteTreeTest.php b/tests/SiteTreeTest.php index 45f61cd55..1d598e6eb 100644 --- a/tests/SiteTreeTest.php +++ b/tests/SiteTreeTest.php @@ -5,7 +5,7 @@ */ class SiteTreeTest extends SapphireTest { static $fixture_file = 'sapphire/tests/SiteTreeTest.yml'; - + /** * Test generation of the URLSegment values. * - Turns things into lowercase-hyphen-format @@ -81,6 +81,8 @@ class SiteTreeTest extends SapphireTest { $checkSiteTree = DataObject::get_one("SiteTree", "\"URLSegment\" = 'get-one-test-page'"); $this->assertEquals("V1", $checkSiteTree->Title); + + Versioned::reading_stage($oldStage); } function testChidrenOfRootAreTopLevelPages() { @@ -189,7 +191,7 @@ class SiteTreeTest extends SapphireTest { $this->assertEquals('Page', $requeriedPage->class); - $page2 = $this->objFromFixture('Page', 'staff'); + $page2 = $this->objFromFixture('Page', 'products'); $page2ID = $page2->ID; $page2->doUnpublish(); $page2->delete(); @@ -203,7 +205,7 @@ class SiteTreeTest extends SapphireTest { Versioned::reading_stage('Stage'); $requeriedPage = DataObject::get_by_id("Page", $page2ID); - $this->assertEquals('Staff', $requeriedPage->Title); + $this->assertEquals('Products', $requeriedPage->Title); $this->assertEquals('Page', $requeriedPage->class); } @@ -219,6 +221,32 @@ class SiteTreeTest extends SapphireTest { // Note: One day, it would be more appropriate to return null instead of false for queries such as these $this->assertFalse(SiteTree::get_by_url("home", "1 = 2")); } + + + function testDeleteFromStageOperatesRecursively() { + $parentPage = $this->objFromFixture('Page', 'about'); + $parentPage->delete(); + + $this->assertFalse($this->objFromFixture('Page', 'about')); + $this->assertFalse($this->objFromFixture('Page', 'staff')); + $this->assertFalse($this->objFromFixture('Page', 'staffduplicate')); + } + + function testDeleteFromLiveOperatesRecursively() { + $this->objFromFixture('Page', 'about')->doPublish(); + $this->objFromFixture('Page', 'staff')->doPublish(); + $this->objFromFixture('Page', 'staffduplicate')->doPublish(); + + + $parentPage = $this->objFromFixture('Page', 'about'); + $parentPage->doDeleteFromLive(); + + Versioned::reading_stage('Live'); + $this->assertFalse($this->objFromFixture('Page', 'about')); + $this->assertFalse($this->objFromFixture('Page', 'staff')); + $this->assertFalse($this->objFromFixture('Page', 'staffduplicate')); + Versioned::reading_stage('Stage'); + } }