diff --git a/admin/code/LeftAndMain.php b/admin/code/LeftAndMain.php
index 24ec06f1a..8885d1311 100644
--- a/admin/code/LeftAndMain.php
+++ b/admin/code/LeftAndMain.php
@@ -134,7 +134,7 @@ class LeftAndMain extends Controller implements PermissionProvider
* @config
* @var string
*/
- private static $help_link = '//userhelp.silverstripe.org/framework/en/3.3';
+ private static $help_link = '//userhelp.silverstripe.org/framework/en/3.5';
/**
* @var array
@@ -347,7 +347,7 @@ class LeftAndMain extends Controller implements PermissionProvider
if (!$formName) {
return (new HTTPResponse('Missing request params', 400));
}
-
+
$formMethod = "get{$formName}";
if (!$this->hasMethod($formMethod)) {
return (new HTTPResponse('Form not found', 404));
@@ -356,7 +356,7 @@ class LeftAndMain extends Controller implements PermissionProvider
if (!$this->hasAction($formName)) {
return (new HTTPResponse('Form not accessible', 401));
}
-
+
if ($itemID) {
$form = $this->{$formMethod}($itemID);
} else {
@@ -579,9 +579,9 @@ class LeftAndMain extends Controller implements PermissionProvider
$htmlEditorConfig->setOption('language', i18n::get_tinymce_lang());
Requirements::customScript("
- window.ss = window.ss || {};
- window.ss.config = " . $this->getCombinedClientConfig() . ";
- ");
+ window.ss = window.ss || {};
+ window.ss.config = " . $this->getCombinedClientConfig() . ";
+ ");
Requirements::javascript(FRAMEWORK_ADMIN_DIR . '/client/dist/js/vendor.js');
Requirements::javascript(FRAMEWORK_ADMIN_DIR . '/client/dist/js/bundle.js');
@@ -1345,8 +1345,7 @@ class LeftAndMain extends Controller implements PermissionProvider
}
$link = Controller::join_links($recordController->Link("show"), $record->ID);
- $html = LeftAndMain_TreeNode::create($record, $link, $this->isCurrentPage($record))
- ->forTemplate() . '';
+ $html = LeftAndMain_TreeNode::create($record, $link, $this->isCurrentPage($record))->forTemplate() ;
$data[$id] = array(
'html' => $html,
@@ -1631,7 +1630,7 @@ class LeftAndMain extends Controller implements PermissionProvider
if ($fields == null) {
user_error(
"getCMSFields() returned null - it should return a FieldList object.
- Perhaps you forgot to put a return statement at the end of your method?",
+ Perhaps you forgot to put a return statement at the end of your method?",
E_USER_ERROR
);
}
@@ -1711,7 +1710,7 @@ class LeftAndMain extends Controller implements PermissionProvider
// Set this if you want to split up tabs into a separate header row
// if($form->Fields()->hasTabset()) {
- // $form->Fields()->findOrMakeTab('Root')->setTemplate('SilverStripe\\Forms\\CMSTabSet');
+ // $form->Fields()->findOrMakeTab('Root')->setTemplate('SilverStripe\\Forms\\CMSTabSet');
// }
// Add a default or custom validator.
@@ -1759,16 +1758,16 @@ class LeftAndMain extends Controller implements PermissionProvider
"EditForm",
new FieldList(
// new HeaderField(
- // 'WelcomeHeader',
- // $this->getApplicationName()
+ // 'WelcomeHeader',
+ // $this->getApplicationName()
// ),
// new LiteralField(
- // 'WelcomeText',
- // sprintf('
%s %s. %s
',
- // _t('LeftAndMain_right_ss.WELCOMETO','Welcome to'),
- // $this->getApplicationName(),
- // _t('CHOOSEPAGE','Please choose an item from the left.')
- // )
+ // 'WelcomeText',
+ // sprintf('%s %s. %s
',
+ // _t('LeftAndMain_right_ss.WELCOMETO','Welcome to'),
+ // $this->getApplicationName(),
+ // _t('CHOOSEPAGE','Please choose an item from the left.')
+ // )
// )
),
new FieldList()
diff --git a/admin/code/LeftAndMain_TreeNode.php b/admin/code/LeftAndMain_TreeNode.php
index 023bfb8b7..7cb7f9160 100644
--- a/admin/code/LeftAndMain_TreeNode.php
+++ b/admin/code/LeftAndMain_TreeNode.php
@@ -2,6 +2,7 @@
namespace SilverStripe\Admin;
+use SilverStripe\View\SSViewer;
use SilverStripe\View\ViewableData;
/**
@@ -76,17 +77,26 @@ class LeftAndMain_TreeNode extends ViewableData
*
* @todo Remove hardcoded assumptions around returning an , by implementing recursive tree node rendering
*
- * @return String
+ * @return string
*/
public function forTemplate()
{
$obj = $this->obj;
- return "ID\" data-id=\"$obj->ID\" data-pagetype=\"$obj->ClassName\" class=\""
- . $this->getClasses() . "\">" . " "
- . "getLink() . "\" title=\"("
- . trim(_t('LeftAndMain.PAGETYPE', 'Page type'), " :") // account for inconsistencies in translations
- . ": " . $obj->i18n_singular_name() . ") $obj->Title\" > " . ($obj->TreeTitle)
- . "";
+
+ return (string)SSViewer::execute_template(
+ 'SilverStripe\\Admin\\Includes\\LeftAndMain_TreeNode',
+ $obj,
+ array(
+ 'Classes' => $this->getClasses(),
+ 'Link' => $this->getLink(),
+ 'Title' => sprintf(
+ '(%s: %s) %s',
+ trim(_t('LeftAndMain.PAGETYPE', 'Page type'), " :"),
+ $obj->i18n_singular_name(),
+ $obj->Title
+ ),
+ )
+ );
}
/**
@@ -118,7 +128,7 @@ class LeftAndMain_TreeNode extends ViewableData
}
$classes .= ' ' . $filterClasses;
}
- return $classes;
+ return $classes ?: '';
}
public function getObj()
diff --git a/admin/templates/SilverStripe/Admin/Includes/LeftAndMain_TreeNode.ss b/admin/templates/SilverStripe/Admin/Includes/LeftAndMain_TreeNode.ss
new file mode 100644
index 000000000..7e4c8ebf8
--- /dev/null
+++ b/admin/templates/SilverStripe/Admin/Includes/LeftAndMain_TreeNode.ss
@@ -0,0 +1,6 @@
+
+
+
+ $TreeTitle
+
+
diff --git a/admin/tests/LeftAndMainTest/TestObject.php b/admin/tests/LeftAndMainTest/TestObject.php
index 4ccdc66ef..5b223a27e 100644
--- a/admin/tests/LeftAndMainTest/TestObject.php
+++ b/admin/tests/LeftAndMainTest/TestObject.php
@@ -24,5 +24,6 @@ class TestObject extends DataObject implements TestOnly
public function CMSTreeClasses()
{
+ return '';
}
}
diff --git a/docs/en/00_Getting_Started/01_Installation/03_Windows.md b/docs/en/00_Getting_Started/01_Installation/03_Windows.md
index 1ea528641..ed9bf0b45 100644
--- a/docs/en/00_Getting_Started/01_Installation/03_Windows.md
+++ b/docs/en/00_Getting_Started/01_Installation/03_Windows.md
@@ -4,9 +4,6 @@ An easy and reliable approach to getting SilverStripe running on Windows is to u
done through [WampServer](http://www.wampserver.com/en/). This can be useful if you are deploying on Linux Apache and
want a Microsoft Windows machine with a very similar environment.
-Note: Installing on Microsoft's IIS webserver through Microsoft WebPI is likely to be easier, see
-[Windows with Web Platform Installer](other_installation_options/windows_platform_installer).
-
## Install WAMP
1. Go to the [WampServer download page](http://www.wampserver.com/en/#download-wrapper).
diff --git a/docs/en/00_Getting_Started/01_Installation/04_Other_installation_Options/Windows_Platform_Installer.md b/docs/en/00_Getting_Started/01_Installation/04_Other_installation_Options/Windows_Platform_Installer.md
deleted file mode 100644
index a9069d208..000000000
--- a/docs/en/00_Getting_Started/01_Installation/04_Other_installation_Options/Windows_Platform_Installer.md
+++ /dev/null
@@ -1,50 +0,0 @@
-# Windows with Web Platform Installer (WebPI)
-
-(Windows XP, 2003, 2008, Vista and 7)
-
-## Installing SilverStripe
-
-* Download and run Microsoft Web Platform Installer (WebPI):
-[![](http://www.silverstripe.org/assets/downloads/webpi/wpiBadgeGreen.png)](http://www.microsoft.com/web/gallery/install.aspx?appsxml=www.microsoft.com%2fweb%2fwebpi%2f2.0%2fWebApplicationList.xml&appid=105)
-
-* In WebPI, select 'SilverStripe' from the 'Content Management System' link
-* Select install. It will install dependancies like MySQL and PHP if you don't have these installed already.
-* Type in the questions it asks you, such as the username/password you set in the above MySQL installation:
-* Everything should be installed, with you seeing the initial webpage
-* And you can log-in to the CMS
-
-## Important: Installation issue on XP
-
-After you've installed SilverStripe on XP using WebPI. You'll need to make a configuration change to get it working.
-
-Specifically, you need to configure XP not to check that a script file exists before executing the script. This is
-necessary for URLs of the form http://localhost/silverstripe/index.php/about-us/ to work.
-
-* Open IIS Administrator
-* Expand the local computer tree node
-* Expand the Web Sites tree node
-* Right click on "Default Web Site" and select "Properties"
-* Select the "Home Directory" Tab.
-* Click the "Configuration Button towards the bottom on the right
-* Select the "Mappings" Tab
-* Find the .php mapping, select it and click the "Edit" button
-* Make sure the check box "Check that file exists" is cleared.
-* Hit OK's all the way back up and restart IIS
-
-## Support
-
-* http://www.silverstripe.org/installing-on-windows-now-easier-thanks-to-microsoft-web-platform-installer/ (This shows
-a beta version of the software)
-* Microsoft Forum: http://forums.iis.net/1155.aspx
-* SilverStripe Installation Issues Forum: http://silverstripe.org/installing-silverstripe/
-
-## Screenshots
-
-![](../../../_images/webpi-2-a-silverstripe-choice.jpg)
-![](../../../_images/webpi-2-b-dependencies.jpg)
-![](../../../_images/webpi-2-c-downloading-and-installaing.jpg)
-![](../../../_images/webpi-2-d-installer-questions-step1.jpg)
-![](../../../_images/webpi-2-e-installer-questions-step2.jpg)
-![](../../../_images/webpi-2-f-success-message.jpg)
-![](../../../_images/webpi-2-g-silverstripe-homepage.jpg)
-![](../../../_images/webpi-2-h-cms-interface-working.jpg)
diff --git a/docs/en/04_Changelogs/rc/3.4.4-rc1.md b/docs/en/04_Changelogs/rc/3.4.4-rc1.md
new file mode 100644
index 000000000..a7d61bd93
--- /dev/null
+++ b/docs/en/04_Changelogs/rc/3.4.4-rc1.md
@@ -0,0 +1,14 @@
+# 3.4.4-rc1
+
+
+
+## Change Log
+
+### Security
+
+ * 2017-01-13 [c6c6c13](https://github.com/silverstripe/silverstripe-framework/commit/c6c6c13fc265aeedf5de7226b3cde39d185ba49d) Unescaped title attribute in LeftAndMain_TreeNode::forTemplate (Daniel Hensby) - See [ss-2017-001](http://www.silverstripe.org/download/security-releases/ss-2017-001)
+
+### Bugfixes
+
+ * 2017-01-16 [17d123a](https://github.com/silverstripe/silverstripe-framework/commit/17d123a3be3a2c9e21845fda89c61f00301f78f5) Ensure correct regeneration of ConfigManifest if only one of the cache files is missing (Stephan Bauer)
+ * 2017-01-10 [5bba726](https://github.com/silverstripe/silverstripe-cms/commit/5bba7264c69b654ac5bcb87769781138be61cb92) Dont attempt to iterate over null in SiteTree::allowedChildren (Daniel Hensby)
diff --git a/docs/en/04_Changelogs/rc/3.5.2-rc1.md b/docs/en/04_Changelogs/rc/3.5.2-rc1.md
new file mode 100644
index 000000000..01d5ce212
--- /dev/null
+++ b/docs/en/04_Changelogs/rc/3.5.2-rc1.md
@@ -0,0 +1,17 @@
+# 3.5.2-rc1
+
+
+
+## Change Log
+
+### Security
+
+ * 2017-01-13 [c6c6c13](https://github.com/silverstripe/silverstripe-framework/commit/c6c6c13fc265aeedf5de7226b3cde39d185ba49d) Unescaped title attribute in LeftAndMain_TreeNode::forTemplate (Daniel Hensby) - See [ss-2017-001](http://www.silverstripe.org/download/security-releases/ss-2017-001)
+
+### Bugfixes
+
+ * 2017-01-24 [c640ade](https://github.com/silverstripe/silverstripe-framework/commit/c640ade9112c703068754c7d7061d646da7307bd) ed iframe postmessage breaking non-string messages (Ruud Arentsen)
+ * 2017-01-16 [17d123a](https://github.com/silverstripe/silverstripe-framework/commit/17d123a3be3a2c9e21845fda89c61f00301f78f5) Ensure correct regeneration of ConfigManifest if only one of the cache files is missing (Stephan Bauer)
+ * 2017-01-14 [1f1fffe](https://github.com/silverstripe/silverstripe-framework/commit/1f1fffe73454930c1aef394e9b106a484e6d59ee) Ensure correct regeneration of ConfigManifest if only one of the cache files is missing (fixes #6467) (Stephan Bauer)
+ * 2017-01-10 [5bba726](https://github.com/silverstripe/silverstripe-cms/commit/5bba7264c69b654ac5bcb87769781138be61cb92) Dont attempt to iterate over null in SiteTree::allowedChildren (Daniel Hensby)
+ * 2016-12-21 [f314b86](https://github.com/silverstripe/silverstripe-framework/commit/f314b86ad804b021cda255e4645e99e8d971fa8a) Temp disable shortcode SPLIT behaviour due to crash (#6436) (Damian Mooyman)
diff --git a/docs/en/05_Contributing/05_Making_A_SilverStripe_Core_Release.md b/docs/en/05_Contributing/05_Making_A_SilverStripe_Core_Release.md
index 600e01e5c..edca6e272 100644
--- a/docs/en/05_Contributing/05_Making_A_SilverStripe_Core_Release.md
+++ b/docs/en/05_Contributing/05_Making_A_SilverStripe_Core_Release.md
@@ -357,36 +357,11 @@ will need to be regularly updated.
forum category. Make this a global read-only sticky, and un-sticky any older release.
* Update the #silverstripe [IRC](https://www.silverstripe.org/community/contributing-to-silverstripe/irc-channel/) topic to include the new release version.
-### Stage 4: Web platform installer release
-
-The web platform installer is available [on the web app gallery](http://www.microsoft.com/web/gallery/silverstripecms.aspx).
-
-In order to update this you will need a Microsoft live account, and have it authorised
-by SilverStripe staff in order to publish these releases.
-
-
-To update this release there is an additional download tool at
-`[https://code.platform.silverstripe.com/silverstripe/webpi](https://code.platform.silverstripe.com/silverstripe/webpi)`
-which will guide you through the process of generating a new zip release.
-
- ./make-package 3.2.4 3.2.4
- aws s3 cp ./silverstripe-3.2.4-webpi.zip s3://silverstripe-ssorg-releases/sssites-ssorg-prod/assets/downloads/webpi/silverstripe-3.2.4-webpi.zip --acl public-read --profile silverstripe
-
-Once you have a new release, update the necessary details at
-[http://www.microsoft.com/web/gallery/appsubmit.aspx?id=57](http://www.microsoft.com/web/gallery/appsubmit.aspx?id=57)
-to submit a new version, including:
-
-* Set the version number
-* Update the release date
-* Submit the package URL
-* Submit the package SHA
-
## See also
* [Release Process](release_process)
* [Translation Process](translation_process)
* [Core committers](core_committers)
-* [WebPI Installer](https://docs.silverstripe.org/en/getting_started/installation/other_installation_options/windows_platform_installer/)
If at any time a release runs into an unsolveable problem contact the
core committers on the [discussion group](https://groups.google.com/forum/#!forum/silverstripe-committers)
diff --git a/src/Core/Convert.php b/src/Core/Convert.php
index 88eff11da..da5b136fc 100644
--- a/src/Core/Convert.php
+++ b/src/Core/Convert.php
@@ -147,26 +147,29 @@ class Convert
}
/**
- * Encode a value as a JSON encoded string.
+ * Encode a value as a JSON encoded string. You can optionally pass a bitmask of
+ * JSON constants as options through to the encode function.
*
- * @param mixed $val Value to be encoded
- * @return string JSON encoded string
+ * @param mixed $val Value to be encoded
+ * @param int $options Optional bitmask of JSON constants
+ * @return string JSON encoded string
*/
- public static function raw2json($val)
+ public static function raw2json($val, $options = 0)
{
- return json_encode($val);
+ return json_encode($val, $options);
}
/**
* Encode an array as a JSON encoded string.
- * THis is an alias to {@link raw2json()}
+ * This is an alias to {@link raw2json()}
*
- * @param array $val Array to convert
- * @return string JSON encoded string
+ * @param array $val Array to convert
+ * @param int $options Optional bitmask of JSON constants
+ * @return string JSON encoded string
*/
- public static function array2json($val)
+ public static function array2json($val, $options = 0)
{
- return self::raw2json($val);
+ return self::raw2json($val, $options);
}
/**
diff --git a/src/Dev/CsvBulkLoader.php b/src/Dev/CsvBulkLoader.php
index 7d809fa7a..878fb2fac 100644
--- a/src/Dev/CsvBulkLoader.php
+++ b/src/Dev/CsvBulkLoader.php
@@ -88,7 +88,11 @@ class CsvBulkLoader extends BulkLoader
@unlink($file);
}
} catch (Exception $e) {
- print "Failed to parse {$last}\n";
+ $failedMessage = sprintf("Failed to parse %s", $last);
+ if (Director::isDev()) {
+ $failedMessage = sprintf($failedMessage . " because %s", $e->getMessage());
+ }
+ print $failedMessage . PHP_EOL;
}
return $result;
diff --git a/src/ORM/Hierarchy/Hierarchy.php b/src/ORM/Hierarchy/Hierarchy.php
index 44539193e..446decd3c 100644
--- a/src/ORM/Hierarchy/Hierarchy.php
+++ b/src/ORM/Hierarchy/Hierarchy.php
@@ -149,7 +149,7 @@ class Hierarchy extends DataExtension
*/
public function getChildrenAsUL(
$attributes = "",
- $titleEval = '"" . $child->Title',
+ $titleEval = '"" . $child->Title . ""',
$extraArg = null,
$limitToMarked = false,
$childrenMethod = "AllChildrenIncludingDeleted",
@@ -202,6 +202,10 @@ class Hierarchy extends DataExtension
} else {
$output .= eval("return $titleEval;");
}
+ $output = trim($output);
+ if (substr($output, -5) == '') {
+ $output = trim(substr($output, 0, -5));
+ }
$output .= "\n";
$numChildren = $child->$numChildrenMethod();
diff --git a/tests/php/Core/ConvertTest.php b/tests/php/Core/ConvertTest.php
index fe920910a..53166e4c7 100644
--- a/tests/php/Core/ConvertTest.php
+++ b/tests/php/Core/ConvertTest.php
@@ -368,6 +368,20 @@ PHP
);
}
+ /**
+ * Test that a context bitmask can be passed through to the json_encode method in {@link Convert::raw2json()}
+ * and in {@link Convert::array2json()}
+ */
+ public function testRaw2JsonWithContext()
+ {
+ $data = array('foo' => 'b"ar');
+ $expected = '{"foo":"b\u0022ar"}';
+ $result = Convert::raw2json($data, JSON_HEX_QUOT);
+ $this->assertSame($expected, $result);
+ $wrapperResult = Convert::array2json($data, JSON_HEX_QUOT);
+ $this->assertSame($expected, $wrapperResult);
+ }
+
/**
* Tests {@link Convert::xml2array()}
*/
diff --git a/tests/php/Forms/TreeDropdownFieldTest.php b/tests/php/Forms/TreeDropdownFieldTest.php
index 14a2c5ce7..de31346dc 100644
--- a/tests/php/Forms/TreeDropdownFieldTest.php
+++ b/tests/php/Forms/TreeDropdownFieldTest.php
@@ -30,8 +30,8 @@ class TreeDropdownFieldTest extends SapphireTest
$cssPath = 'ul.tree li#selector-TestTree-'.$folder1->ID.' li#selector-TestTree-'.$folder1Subfolder1->ID.' a span.item';
$firstResult = $parser->getBySelector($cssPath);
$this->assertEquals(
- (string)$firstResult[0],
$folder1Subfolder1->Name,
+ (string)$firstResult[0],
$folder1Subfolder1->Name.' is found, nested under '.$folder1->Name
);
@@ -39,8 +39,8 @@ class TreeDropdownFieldTest extends SapphireTest
$cssPath = 'ul.tree li#selector-TestTree-'.$subfolder->ID.' a span.item';
$secondResult = $parser->getBySelector($cssPath);
$this->assertEquals(
- (string)$secondResult[0],
$subfolder->Name,
+ (string)$secondResult[0],
$subfolder->Name.' is found at root level'
);
@@ -48,9 +48,8 @@ class TreeDropdownFieldTest extends SapphireTest
$folder2 = $this->objFromFixture(Folder::class, 'folder2');
$cssPath = 'ul.tree li#selector-TestTree-'.$folder2->ID.' a span.item';
$noResult = $parser->getBySelector($cssPath);
- $this->assertEquals(
+ $this->assertEmpty(
$noResult,
- array(),
$folder2.' is not found'
);
@@ -66,8 +65,8 @@ class TreeDropdownFieldTest extends SapphireTest
$cssPath = 'ul.tree li#selector-TestTree-'.$folder1->ID.' li#selector-TestTree-'.$folder1Subfolder1->ID.' a span.item';
$firstResult = $parser->getBySelector($cssPath);
$this->assertEquals(
- (string)$firstResult[0],
$folder1Subfolder1->Name,
+ (string)$firstResult[0],
$folder1Subfolder1->Name.' is found, nested under '.$folder1->Name
);
@@ -76,27 +75,25 @@ class TreeDropdownFieldTest extends SapphireTest
$file2 = $this->objFromFixture(File::class, 'subfolderfile2');
$cssPath = 'ul.tree li#selector-TestTree-'.$subfolder->ID.' li#selector-TestTree-'.$file1->ID.' a';
$firstResult = $parser->getBySelector($cssPath);
- $this->assertGreaterThan(
- 0,
- count($firstResult),
+ $this->assertNotEmpty(
+ $firstResult,
$file1->Name.' with ID '.$file1->ID.' is in search results'
);
$this->assertEquals(
- (string)$firstResult[0],
$file1->Name,
+ (string)$firstResult[0],
$file1->Name.' is found nested under '.$subfolder->Name
);
$cssPath = 'ul.tree li#selector-TestTree-'.$subfolder->ID.' li#selector-TestTree-'.$file2->ID.' a';
$secondResult = $parser->getBySelector($cssPath);
- $this->assertGreaterThan(
- 0,
- count($secondResult),
+ $this->assertNotEmpty(
+ $secondResult,
$file2->Name.' with ID '.$file2->ID.' is in search results'
);
$this->assertEquals(
- (string)$secondResult[0],
$file2->Name,
+ (string)$secondResult[0],
$file2->Name.' is found nested under '.$subfolder->Name
);
@@ -104,9 +101,8 @@ class TreeDropdownFieldTest extends SapphireTest
$file3 = $this->objFromFixture(File::class, 'asdf');
$cssPath = 'ul.tree li#selector-TestTree-'.$file3->ID;
$noResult = $parser->getBySelector($cssPath);
- $this->assertEquals(
+ $this->assertEmpty(
$noResult,
- array(),
$file3->Name.' is not found'
);
}