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