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');
+ }
}