From f823831a639c0b0aa6f7c15550dc011832ad601e Mon Sep 17 00:00:00 2001 From: Igor Nadj Date: Mon, 25 Aug 2014 11:49:38 +1200 Subject: [PATCH 01/77] FIX making minify javascript fail-safe --- tests/view/SSViewerTest.php | 51 +++++++++++++++++++++++++++++ tests/view/themes/javascript/bad.js | 1 + view/Requirements.php | 8 ++++- 3 files changed, 59 insertions(+), 1 deletion(-) create mode 100644 tests/view/themes/javascript/bad.js diff --git a/tests/view/SSViewerTest.php b/tests/view/SSViewerTest.php index 474ea1cf6..6fa2b6b2d 100644 --- a/tests/view/SSViewerTest.php +++ b/tests/view/SSViewerTest.php @@ -103,6 +103,57 @@ class SSViewerTest extends SapphireTest { <% require css($cssFile) %>"); $this->assertFalse((bool)trim($template), "Should be no content in this return."); } + + public function testRequirementsCombine(){ + $oldBackend = Requirements::backend(); + $testBackend = new Requirements_Backend(); + Requirements::set_backend($testBackend); + $combinedTestFilePath = BASE_PATH . '/' . $testBackend->getCombinedFilesFolder() . '/testRequirementsCombine.js'; + + $jsFile = FRAMEWORK_DIR . '/tests/view/themes/javascript/bad.js'; + $jsFileContents = file_get_contents(BASE_PATH . '/' . $jsFile); + Requirements::combine_files('testRequirementsCombine.js', array($jsFile)); + require_once('thirdparty/jsmin/jsmin.php'); + + // first make sure that our test js file causes an exception to be thrown + try{ + $content = JSMin::minify($content); + $this->fail('JSMin did not throw exception on minify bad file: '); + Requirements::set_backend($oldBackend); + return; + }catch(Exception $e){ + // exception thrown... good + } + + // secondly, make sure that requirements combine can handle this and continue safely + @unlink($combinedTestFilePath); + try{ + /* + * Use @ (ignore warning) because a warning would cause php unit to throw an exception and therefore change the execution + * process and mess up the next test. + */ + @Requirements::process_combined_files(); + }catch(Exception $e){ + $this->fail('Requirements::process_combined_files did not catch exception caused by minifying bad js file: '.$e); + Requirements::set_backend($oldBackend); + return; + } + + // and make sure the combined content matches the input content, i.e. no loss of functionality + if(!file_exists($combinedTestFilePath)){ + $this->fail('No combined file was created at expected path: '.$combinedTestFilePath); + Requirements::set_backend($oldBackend); + return; + } + $combinedTestFileContents = file_get_contents($combinedTestFilePath); + $this->assertContains($jsFileContents, $combinedTestFileContents); + + + // reset + Requirements::set_backend($oldBackend); + } + + public function testComments() { $output = $this->render(<<blocked) as $file) { $fileContent = file_get_contents($base . $file); - $fileContent = $this->minifyFile($file, $fileContent); + + try{ + $fileContent = $this->minifyFile($file, $fileContent); + }catch(Exception $e){ + // failed to minify, use unminified + user_error('Failed to minify '.$file.', exception: '.$e->getMessage(), E_USER_WARNING); + } if ($this->write_header_comment) { // write a header comment for each file for easier identification and debugging From 657606e8c8a470139d1d997722fcd5cb3591d274 Mon Sep 17 00:00:00 2001 From: Igor Nadj Date: Wed, 26 Nov 2014 15:27:54 +1300 Subject: [PATCH 02/77] Updating code to allow unit test to use try-catch block to catch warning without stopping code execution inside try --- tests/view/SSViewerTest.php | 17 +++++++++-------- view/Requirements.php | 10 ++++++++-- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/tests/view/SSViewerTest.php b/tests/view/SSViewerTest.php index 6fa2b6b2d..6fa92b795 100644 --- a/tests/view/SSViewerTest.php +++ b/tests/view/SSViewerTest.php @@ -125,20 +125,22 @@ class SSViewerTest extends SapphireTest { // exception thrown... good } - // secondly, make sure that requirements combine can handle this and continue safely + // secondly, make sure that requirements combine throws the correct warning, and only that warning @unlink($combinedTestFilePath); try{ - /* - * Use @ (ignore warning) because a warning would cause php unit to throw an exception and therefore change the execution - * process and mess up the next test. - */ - @Requirements::process_combined_files(); + Requirements::process_combined_files(); + }catch(PHPUnit_Framework_Error_Warning $e){ + if(strstr($e->getMessage(), 'Failed to minify') === false){ + $this->fail('Requirements::process_combined_files raised a warning, which is good, but this is not the expected warning ("Failed to minify..."): '.$e); + Requirements::set_backend($oldBackend); + return; + } }catch(Exception $e){ $this->fail('Requirements::process_combined_files did not catch exception caused by minifying bad js file: '.$e); Requirements::set_backend($oldBackend); return; } - + // and make sure the combined content matches the input content, i.e. no loss of functionality if(!file_exists($combinedTestFilePath)){ $this->fail('No combined file was created at expected path: '.$combinedTestFilePath); @@ -147,7 +149,6 @@ class SSViewerTest extends SapphireTest { } $combinedTestFileContents = file_get_contents($combinedTestFilePath); $this->assertContains($jsFileContents, $combinedTestFileContents); - // reset Requirements::set_backend($oldBackend); diff --git a/view/Requirements.php b/view/Requirements.php index 8952edf0a..a607eb88e 100644 --- a/view/Requirements.php +++ b/view/Requirements.php @@ -1129,6 +1129,7 @@ class Requirements_Backend { if(!$refresh) continue; + $failedToMinify = false; $combinedData = ""; foreach(array_diff($fileList, $this->blocked) as $file) { $fileContent = file_get_contents($base . $file); @@ -1136,8 +1137,7 @@ class Requirements_Backend { try{ $fileContent = $this->minifyFile($file, $fileContent); }catch(Exception $e){ - // failed to minify, use unminified - user_error('Failed to minify '.$file.', exception: '.$e->getMessage(), E_USER_WARNING); + $failedToMinify = true; } if ($this->write_header_comment) { @@ -1156,6 +1156,12 @@ class Requirements_Backend { fclose($fh); unset($fh); } + + if($failedToMinify){ + // Failed to minify, use unminified. This warning is raised at the end to allow code execution + // to complete in case this warning is caught inside a try-catch block. + user_error('Failed to minify '.$file.', exception: '.$e->getMessage(), E_USER_WARNING); + } // Unsuccessful write - just include the regular JS files, rather than the combined one if(!$successfulWrite) { From 77e30d4524810948db262ca674f431338523a180 Mon Sep 17 00:00:00 2001 From: Igor Nadj Date: Wed, 26 Nov 2014 15:31:07 +1300 Subject: [PATCH 03/77] Cleanup, removing redundant returns --- tests/view/SSViewerTest.php | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/tests/view/SSViewerTest.php b/tests/view/SSViewerTest.php index 6fa92b795..7511af1ca 100644 --- a/tests/view/SSViewerTest.php +++ b/tests/view/SSViewerTest.php @@ -114,13 +114,12 @@ class SSViewerTest extends SapphireTest { $jsFileContents = file_get_contents(BASE_PATH . '/' . $jsFile); Requirements::combine_files('testRequirementsCombine.js', array($jsFile)); require_once('thirdparty/jsmin/jsmin.php'); - + // first make sure that our test js file causes an exception to be thrown try{ $content = JSMin::minify($content); - $this->fail('JSMin did not throw exception on minify bad file: '); Requirements::set_backend($oldBackend); - return; + $this->fail('JSMin did not throw exception on minify bad file: '); }catch(Exception $e){ // exception thrown... good } @@ -131,21 +130,18 @@ class SSViewerTest extends SapphireTest { Requirements::process_combined_files(); }catch(PHPUnit_Framework_Error_Warning $e){ if(strstr($e->getMessage(), 'Failed to minify') === false){ - $this->fail('Requirements::process_combined_files raised a warning, which is good, but this is not the expected warning ("Failed to minify..."): '.$e); Requirements::set_backend($oldBackend); - return; + $this->fail('Requirements::process_combined_files raised a warning, which is good, but this is not the expected warning ("Failed to minify..."): '.$e); } }catch(Exception $e){ - $this->fail('Requirements::process_combined_files did not catch exception caused by minifying bad js file: '.$e); Requirements::set_backend($oldBackend); - return; + $this->fail('Requirements::process_combined_files did not catch exception caused by minifying bad js file: '.$e); } // and make sure the combined content matches the input content, i.e. no loss of functionality if(!file_exists($combinedTestFilePath)){ - $this->fail('No combined file was created at expected path: '.$combinedTestFilePath); Requirements::set_backend($oldBackend); - return; + $this->fail('No combined file was created at expected path: '.$combinedTestFilePath); } $combinedTestFileContents = file_get_contents($combinedTestFilePath); $this->assertContains($jsFileContents, $combinedTestFileContents); From 6c6d2172737517a634f1740aa0167f6a8f798d32 Mon Sep 17 00:00:00 2001 From: Antony Thorpe Date: Wed, 3 Dec 2014 16:56:53 +1300 Subject: [PATCH 04/77] Update error-handling.md Add how to log notices (deprecation notifications can help with discovering problems caused by old code). --- docs/en/topics/error-handling.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/docs/en/topics/error-handling.md b/docs/en/topics/error-handling.md index c40650521..88ab7c975 100644 --- a/docs/en/topics/error-handling.md +++ b/docs/en/topics/error-handling.md @@ -58,9 +58,11 @@ added. :::php // log errors and warnings - SS_Log::add_writer(new SS_LogFileWriter('/my/logfile/path'), SS_Log::WARN, '<='); + SS_Log::add_writer(new SS_LogFileWriter('../silverstripe-errors-warnings.log'), SS_Log::WARN, '<='); // or just errors - SS_Log::add_writer(new SS_LogFileWriter('/my/logfile/path'), SS_Log::ERR); + SS_Log::add_writer(new SS_LogFileWriter('../silverstripe-errors.log'), SS_Log::ERR); + // or notices (e.g. for Deprecation Notifications) + SS_Log::add_writer(new SS_LogFileWriter('../silverstripe-errors-notices.log'), SS_Log::NOTICE); ### From PHP @@ -84,4 +86,4 @@ You can send both fatal errors and warnings in your code to a specified email-ad // log errors and warnings SS_Log::add_writer(new SS_LogEmailWriter('admin@domain.com'), SS_Log::WARN, '<='); // or just errors - SS_Log::add_writer(new SS_LogEmailWriter('admin@domain.com'), SS_Log::ERR); \ No newline at end of file + SS_Log::add_writer(new SS_LogEmailWriter('admin@domain.com'), SS_Log::ERR); From ab24ed3bea46c0d3c0a7b770236816753fcca97b Mon Sep 17 00:00:00 2001 From: "Elvinas L." Date: Tue, 13 Jan 2015 15:31:17 +0200 Subject: [PATCH 05/77] FIX. Use i18n_plural_name() instead of plural_name() --- admin/code/SecurityAdmin.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/admin/code/SecurityAdmin.php b/admin/code/SecurityAdmin.php index 2e71de0bc..85c96ccf3 100755 --- a/admin/code/SecurityAdmin.php +++ b/admin/code/SecurityAdmin.php @@ -281,7 +281,7 @@ class SecurityAdmin extends LeftAndMain implements PermissionProvider { $firstCrumb = $crumbs->shift(); if($params['FieldName'] == 'Groups') { $crumbs->unshift(new ArrayData(array( - 'Title' => singleton('Group')->plural_name(), + 'Title' => singleton('Group')->i18n_plural_name(), 'Link' => $this->Link('groups') ))); } elseif($params['FieldName'] == 'Users') { From d28edd09ce9223ede8d7bd30a981b972ce143df7 Mon Sep 17 00:00:00 2001 From: ProzacJellybeans Date: Wed, 14 Jan 2015 15:34:20 +1300 Subject: [PATCH 06/77] Extending site - RSS correction Instructions needed to be given on flushing more frequently, not just on template editing --- docs/en/01_Tutorials/02_Extending_A_Basic_Site.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/en/01_Tutorials/02_Extending_A_Basic_Site.md b/docs/en/01_Tutorials/02_Extending_A_Basic_Site.md index 2eb6faaef..d7f9fefef 100644 --- a/docs/en/01_Tutorials/02_Extending_A_Basic_Site.md +++ b/docs/en/01_Tutorials/02_Extending_A_Basic_Site.md @@ -409,6 +409,9 @@ An RSS feed is something that no news section should be without. SilverStripe ma } +Ensure that when you have input the code to implement an RSS feed; flush the webpage afterwards +(add ?flush=all on the end of your URL) + This function creates an RSS feed of all the news articles, and outputs it to the browser. If we go to [http://localhost/your_site_name/news/rss](http://localhost/your_site_name/news/rss) we should see our RSS feed. When there is more to a URL after a page's base URL, "rss" in this case, SilverStripe will call the function with that name on the controller if it exists. Depending on your browser, you should see something like the picture below. If your browser doesn't support RSS, you will most likely see the XML output instead. For more on RSS, see `[api:RSSFeed]` From 32ce85d9f4590ce56ee3a7979407acd3d23e8263 Mon Sep 17 00:00:00 2001 From: "Elvinas L." Date: Thu, 15 Jan 2015 15:09:32 +0200 Subject: [PATCH 07/77] FIX. Summary fields can't be translated fieldLabels() now can find these fields and translate them. --- security/Member.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/security/Member.php b/security/Member.php index fbe04dc8e..886cf783e 100644 --- a/security/Member.php +++ b/security/Member.php @@ -99,9 +99,9 @@ class Member extends DataObject implements TemplateGlobalProvider { ); private static $summary_fields = array( - 'FirstName' => 'First Name', - 'Surname' => 'Last Name', - 'Email' => 'Email', + 'FirstName', + 'Surname', + 'Email', ); /** From 8b1aa5f1d72dc9a6630601ac5f58b34b43def71c Mon Sep 17 00:00:00 2001 From: ProzacJellybeans Date: Fri, 16 Jan 2015 11:45:44 +1300 Subject: [PATCH 08/77] Extending site - RSS correction Rewrote the reason as to why the website needs to be flushed more frequently --- docs/en/01_Tutorials/02_Extending_A_Basic_Site.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/en/01_Tutorials/02_Extending_A_Basic_Site.md b/docs/en/01_Tutorials/02_Extending_A_Basic_Site.md index d7f9fefef..3f78a8eee 100644 --- a/docs/en/01_Tutorials/02_Extending_A_Basic_Site.md +++ b/docs/en/01_Tutorials/02_Extending_A_Basic_Site.md @@ -246,7 +246,7 @@ page layout. ### ArticlePage Template First, the template for displaying a single article: -**themes/simple/templates/Layout/ArticlePage.ss** +**themes/simple/templates/Layout/ArticlePage.ss** :::ss @@ -410,7 +410,7 @@ An RSS feed is something that no news section should be without. SilverStripe ma Ensure that when you have input the code to implement an RSS feed; flush the webpage afterwards -(add ?flush=all on the end of your URL) +(add ?flush=all on the end of your URL). This is because allowed_actions has changed. This function creates an RSS feed of all the news articles, and outputs it to the browser. If we go to [http://localhost/your_site_name/news/rss](http://localhost/your_site_name/news/rss) we should see our RSS feed. When there is more to a URL after a page's base URL, "rss" in this case, SilverStripe will call the function with that name on the controller if it exists. From 77ebdc22fadc0d4b0daa887068c9b719f8ec617f Mon Sep 17 00:00:00 2001 From: Loz Calver Date: Mon, 19 Jan 2015 20:38:08 +0000 Subject: [PATCH 09/77] FIX: DataObject::db returned fields in incorrect order, with incorrect data types fixes #3802 --- model/DataObject.php | 9 +++++++-- tests/model/DataObjectTest.php | 10 ++++++++++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/model/DataObject.php b/model/DataObject.php index 0bd7b19dd..4a666c91c 100644 --- a/model/DataObject.php +++ b/model/DataObject.php @@ -1666,9 +1666,14 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity */ public function db($fieldName = null) { $classes = ClassInfo::ancestry($this, true); - $items = array(); - foreach(array_reverse($classes) as $class) { + // If we're looking for a specific field, we want to hit subclasses first as they may override field types + if($fieldName) { + $classes = array_reverse($classes); + } + + $items = array(); + foreach($classes as $class) { if(isset(self::$_cache_db[$class])) { $dbItems = self::$_cache_db[$class]; } else { diff --git a/tests/model/DataObjectTest.php b/tests/model/DataObjectTest.php index 275e643d6..8daffecce 100644 --- a/tests/model/DataObjectTest.php +++ b/tests/model/DataObjectTest.php @@ -38,9 +38,19 @@ class DataObjectTest extends SapphireTest { $this->assertEquals('Text', $obj->db('Comment')); $obj = new DataObjectTest_ExtendedTeamComment(); + $dbFields = $obj->db(); // Assert overloaded fields have correct data type $this->assertEquals('HTMLText', $obj->db('Comment')); + $this->assertEquals('HTMLText', $dbFields['Comment'], + 'Calls to DataObject::db without a field specified return correct data types'); + + // assertEquals doesn't verify the order of array elements, so access keys manually to check order: + // expected: array('Name' => 'Varchar', 'Comment' => 'HTMLText') + reset($dbFields); + $this->assertEquals('Name', key($dbFields), 'DataObject::db returns fields in correct order'); + next($dbFields); + $this->assertEquals('Comment', key($dbFields), 'DataObject::db returns fields in correct order'); } public function testValidObjectsForBaseFields() { From 12621153592ab14abdc54c420098a66d0ea09331 Mon Sep 17 00:00:00 2001 From: Corey Sewell Date: Tue, 20 Jan 2015 13:21:12 +1300 Subject: [PATCH 10/77] Fix #3794 Fix #3794 --- dev/install/install.php5 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev/install/install.php5 b/dev/install/install.php5 index d57431947..8b77230b5 100755 --- a/dev/install/install.php5 +++ b/dev/install/install.php5 @@ -1494,7 +1494,7 @@ HTML; if($base != '.') $baseClause = "RewriteBase '$base'\n"; else $baseClause = ""; - if(strpos(strtolower(php_sapi_name()), "cgi") !== false) $cgiClause = "RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization},L]\n"; + if(strpos(strtolower(php_sapi_name()), "cgi") !== false) $cgiClause = "RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]\n"; else $cgiClause = ""; $modulePath = FRAMEWORK_NAME; $rewrite = << Date: Tue, 20 Jan 2015 14:23:53 +0000 Subject: [PATCH 11/77] Update 01_Image.md Ive added this to show you can change the color of the padding area --- docs/en/02_Developer_Guides/14_Files/01_Image.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/02_Developer_Guides/14_Files/01_Image.md b/docs/en/02_Developer_Guides/14_Files/01_Image.md index 682183362..bd3b4537a 100644 --- a/docs/en/02_Developer_Guides/14_Files/01_Image.md +++ b/docs/en/02_Developer_Guides/14_Files/01_Image.md @@ -97,7 +97,7 @@ For output of an image tag with the image automatically resized to 80px width, y $Image.SetSize(80,80) // returns a 80x80px padded image $Image.SetRatioSize(80,80) // Returns an image scaled proportional, with its greatest diameter scaled to 80px $Image.CroppedImage(80,80) // Returns an 80x80 image cropped from the center. - $Image.PaddedImage(80, 80) // Returns an 80x80 image. Unused space is padded white. No crop. No stretching + $Image.PaddedImage(80, 80, FFFFFF) // Returns an 80x80 image. Unused space is padded white. No crop. No stretching $Image.Width // returns width of image $Image.Height // returns height of image $Image.Orientation // returns Orientation From 3de82ce8dc6adc38936838c2537878a8926657f1 Mon Sep 17 00:00:00 2001 From: Cam Findlay Date: Wed, 21 Jan 2015 15:27:22 +1300 Subject: [PATCH 12/77] DOCS Fixed link to yaml config docs. --- docs/en/02_Developer_Guides/09_Security/00_Member.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/02_Developer_Guides/09_Security/00_Member.md b/docs/en/02_Developer_Guides/09_Security/00_Member.md index 93e03d334..e30a3112d 100644 --- a/docs/en/02_Developer_Guides/09_Security/00_Member.md +++ b/docs/en/02_Developer_Guides/09_Security/00_Member.md @@ -91,7 +91,7 @@ and another subclass for the same email-address in the address-database. Using inheritance to add extra behaviour or data fields to a member is limiting, because you can only inherit from 1 class. A better way is to use role extensions to add this behaviour. Add the following to your -`[config.yml](/topics/configuration)`. +`[config.yml](/developer_guides/configuration/configuration/#configuration-yaml-syntax-and-rules)`. :::yml Member: From 037c3a1847b6470f5a1badd58f114dff10715b5c Mon Sep 17 00:00:00 2001 From: Cam Findlay Date: Thu, 22 Jan 2015 08:40:33 +1300 Subject: [PATCH 13/77] DOCS Fix missing changelogs --- docs/en/04_Changelogs/3.0.10.md | 26 ++++++++++ docs/en/04_Changelogs/3.0.11.md | 19 ++++++++ docs/en/04_Changelogs/3.1.3.md | 29 +++++++++++ docs/en/04_Changelogs/3.1.4.md | 46 ++++++++++++++++++ docs/en/04_Changelogs/3.1.5.md | 67 ++++++++++++++++++++++++++ docs/en/04_Changelogs/rc/3.0.10-rc1.md | 25 ++++++++++ docs/en/04_Changelogs/rc/3.0.11-rc1.md | 19 ++++++++ docs/en/04_Changelogs/rc/3.0.9-rc1.md | 12 +++++ docs/en/04_Changelogs/rc/3.1.3-rc1.md | 29 +++++++++++ docs/en/04_Changelogs/rc/3.1.3-rc2.md | 12 +++++ docs/en/04_Changelogs/rc/3.1.4-rc1.md | 44 +++++++++++++++++ docs/en/04_Changelogs/rc/3.1.5-rc1.md | 67 ++++++++++++++++++++++++++ 12 files changed, 395 insertions(+) create mode 100644 docs/en/04_Changelogs/3.0.10.md create mode 100644 docs/en/04_Changelogs/3.0.11.md create mode 100644 docs/en/04_Changelogs/3.1.3.md create mode 100644 docs/en/04_Changelogs/3.1.4.md create mode 100644 docs/en/04_Changelogs/3.1.5.md create mode 100644 docs/en/04_Changelogs/rc/3.0.10-rc1.md create mode 100644 docs/en/04_Changelogs/rc/3.0.11-rc1.md create mode 100644 docs/en/04_Changelogs/rc/3.0.9-rc1.md create mode 100644 docs/en/04_Changelogs/rc/3.1.3-rc1.md create mode 100644 docs/en/04_Changelogs/rc/3.1.3-rc2.md create mode 100644 docs/en/04_Changelogs/rc/3.1.4-rc1.md create mode 100644 docs/en/04_Changelogs/rc/3.1.5-rc1.md diff --git a/docs/en/04_Changelogs/3.0.10.md b/docs/en/04_Changelogs/3.0.10.md new file mode 100644 index 000000000..8e06089aa --- /dev/null +++ b/docs/en/04_Changelogs/3.0.10.md @@ -0,0 +1,26 @@ +# 3.0.10 + +## Upgrading + + * If relying on partial caching of content between logged in users, be aware that the cache is now automatically + segmented based on both the current member ID, and the versioned reading mode. If this is not an appropriate + method (such as if the same content is served to logged in users within partial caching) then it is necessary + to adjust the config value of `SSViewer.global_key` to something more or less sensitive. + +## Security + + * [BUG Fix issue with versioned dataobjects being cached between stages](https://github.com/silverstripe/silverstripe-framework/commit/4415a75d9304a3930b9c28763fc092299640c685) - See [announcement SS-2014-007](http://www.silverstripe.org/ss-2014-007-confidentiality-breach-can-occur-between-draft-and-live-modes/) + * [BUG Fix encoding of JS redirection script](https://github.com/silverstripe/silverstripe-framework/commit/f8e3bbe3ae3f29f22d85abb73cea033659511168) - See [announcement SS-2014-006](http://www.silverstripe.org/ss-2014-006-xss-in-returnurl-redirection/) + * [Amends solution to SS-2014-006](https://github.com/silverstripe/silverstripe-framework/commit/5b0a96979484fad12e11ce69aef98feda57b321f) + * [FIX Prevent SQLi when no URL filters are applied](https://github.com/silverstripe/silverstripe-cms/commit/114df8a3a5e4800ef7586c5d9c8d79798fd2a11d) - See [announcement SS-2014-004](http://www.silverstripe.org/ss-2014-004-sql-injection-in-sitetree-with-custom-urlsegmentfilter-rules/) + * [FIX Do now allow arbitary class creation in CMS](https://github.com/silverstripe/silverstripe-cms/commit/bf9b22fd4331a6f78cec12a75262f570b025ec2d) - See [announcement SS-2014-005](http://www.silverstripe.org/ss-2014-005-arbitrary-class-creation-in-cms-backend/) + +## General + + * [Rewrote usages of error suppression operator](https://github.com/silverstripe/silverstripe-framework/commit/6d5d3d8cb7e69e0b37471b1e34077211b0f631fe) + +## Changelog + + * [framework](https://github.com/silverstripe/silverstripe-framework/releases/tag/3.0.10) + * [cms](https://github.com/silverstripe/silverstripe-cms/releases/tag/3.0.10) + * [installer](https://github.com/silverstripe/silverstripe-installer/releases/tag/3.0.10) diff --git a/docs/en/04_Changelogs/3.0.11.md b/docs/en/04_Changelogs/3.0.11.md new file mode 100644 index 000000000..71191bd7e --- /dev/null +++ b/docs/en/04_Changelogs/3.0.11.md @@ -0,0 +1,19 @@ +# 3.0.11 + +Minor security release + +## Security + + * 2014-04-16 [9d74bc4](https://github.com/silverstripe/sapphire/commit/9d74bc4) Potential DoS exploit in TinyMCE - See [announcement SS-2014-009](http://www.silverstripe.org/ss-2014-009-potential-dos-exploit-in-tinymce/) + * 2014-05-05 [9bfeffd](https://github.com/silverstripe/silverstripe-framework/commit/9bfeffd) Injection / Filesystem vulnerability in generatesecuretoken - See [announcement SS-2014-010](http://www.silverstripe.org/ss-2014-010-injection-filesystem-vulnerability-in-generatesecuretoken/) + * 2014-05-07 [0099a18](https://github.com/silverstripe/silverstripe-framework/commit/0099a18) Folder filename injection - See [announcement SS-2014-011](http://www.silverstripe.org/ss-2014-011-folder-filename-injection/) + +### Bugfixes + + * 2013-06-20 [f2c4a62](https://github.com/silverstripe/sapphire/commit/f2c4a62) ConfirmedPasswordField used to expose existing hash (Hamish Friedlander) + +## Changelog + + * [framework](https://github.com/silverstripe/silverstripe-framework/releases/tag/3.0.11) + * [cms](https://github.com/silverstripe/silverstripe-cms/releases/tag/3.0.11) + * [installer](https://github.com/silverstripe/silverstripe-installer/releases/tag/3.0.11) diff --git a/docs/en/04_Changelogs/3.1.3.md b/docs/en/04_Changelogs/3.1.3.md new file mode 100644 index 000000000..d43eb42fb --- /dev/null +++ b/docs/en/04_Changelogs/3.1.3.md @@ -0,0 +1,29 @@ +# 3.1.3 + +## Overview + + * Security: Require ADMIN for ?flush=1&isDev=1 ([SS-2014-001](http://www.silverstripe.org/ss-2014-001-require-admin-for-flush1-and-isdev1)) + * Security: XSS in third party library (SWFUpload) ([SS-2014-002](http://www.silverstripe.org/ss-2014-002-xss-in-third-party-library-swfupload/)) + * Security: SiteTree.ExtraMeta allows JavaScript for malicious CMS authors ([SS-2014-003](http://www.silverstripe.org/ss-2014-003-extrameta-allows-javascript-for-malicious-cms-authors-/)) + * Better loading performance when using multiple `UploadField` instances + * Option for `force_js_to_bottom` on `Requirements` class (ignoring inline `"; + $title = Director::isDev() + ? "{$urlATT}... (output started on {$file}, line {$line})" + : "{$urlATT}..."; + echo <<Redirecting to {$title}

+ +"; +EOT + ; } else { $line = $file = null; if(!headers_sent($file, $line)) { From 647f921c0826d62af263dad4daf2d5425c12ace1 Mon Sep 17 00:00:00 2001 From: unclecheese Date: Thu, 5 Feb 2015 16:25:07 +1300 Subject: [PATCH 39/77] MINOR: Add lesson 8 --- docs/en/01_Tutorials/index.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/en/01_Tutorials/index.md b/docs/en/01_Tutorials/index.md index 0065d7bd2..395174b9b 100644 --- a/docs/en/01_Tutorials/index.md +++ b/docs/en/01_Tutorials/index.md @@ -16,6 +16,7 @@ These include video screencasts, written tutorials and code examples to get you * [Lesson 5: The holder/page pattern](http://www.silverstripe.org/learn/lessons/lesson-5-the-holderpage-pattern/) * [Lesson 6: Adding Custom Fields to a Page](http://www.silverstripe.org/learn/lessons/lesson-6-adding-custom-fields-to-a-page/) * [Lesson 7: Working with Files and Images](http://www.silverstripe.org/learn/lessons/lesson-7-working-with-files-and-images/) +* [Lesson 8: Introduction to the ORM](http://www.silverstripe.org/learn/lessons/lesson-8-introduction-to-the-orm) ## Help: If you get stuck From 9720b4939d144f865581ae4675884a28fe0486f2 Mon Sep 17 00:00:00 2001 From: Cam Findlay Date: Fri, 6 Feb 2015 20:37:50 +1300 Subject: [PATCH 40/77] DOCS Fixed link on issues and bugs --- docs/en/05_Contributing/00_Issues_and_Bugs.md | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/docs/en/05_Contributing/00_Issues_and_Bugs.md b/docs/en/05_Contributing/00_Issues_and_Bugs.md index 3ce05e953..a5d45cdf9 100644 --- a/docs/en/05_Contributing/00_Issues_and_Bugs.md +++ b/docs/en/05_Contributing/00_Issues_and_Bugs.md @@ -16,11 +16,11 @@ well written bug reports can be half of the solution already! Before submitting a bug: - * Ask for assistance on the [forums](http://silverstripe.org/forums), [core mailinglist](http://groups.google.com/group/silverstripe-dev) or on [IRC](http://silverstripe.org/irc) if you're unsure if its really a bug. + * Ask for assistance on the [forums](http://www.silverstripe.org/community/forums/), [core mailinglist](http://groups.google.com/group/silverstripe-dev) or on [IRC](http://irc.silverstripe.org/) if you're unsure if its really a bug. * Search for similar, existing tickets * Is this a security issue? Please follow our separate reporting guidelines below. - * Is this a issue with the core framework or cms? Modules have their own issue trackers (see [silverstripe.org/modules](http://www.silverstripe.org/modules)) - * Try to reproduce your issue on a [clean installation](http://doc.silverstripe.org/framework/en/installation/composer#using-development-versions), maybe the bug has already been fixed on an unreleased branch? + * Is this a issue with the core framework or cms? Modules have their own issue trackers (see [silverstripe.org/modules](http://www.silverstripe.org/modules/)) + * Try to reproduce your issue on a [clean installation](/getting_started/composer#using-development-versions), maybe the bug has already been fixed on an unreleased branch? * The bugtracker is not the place to discuss enhancements, please use the forums or mailinglist. Only log enhancement tickets if they gather a large interest in the community and the enhancement is likely to be implemented in the next couple of months. @@ -30,7 +30,7 @@ If the issue does look like a new bug: * [Create a new ticket](https://github.com/silverstripe/silverstripe-framework/issues/new) * Describe the steps required to reproduce your issue, and the expected outcome. Unit tests, screenshots and screencasts can help here. * Describe your environment as detailed as possible: SilverStripe version, Browser, PHP version, Operating System, any installed SilverStripe modules. - * *(optional)* [Submit a pull request](/misc/contributing/code) which fixes the issue. + * *(optional)* [Submit a pull request](/contributing/code/#step-by-step-from-forking-to-sending-the-pull-request) which fixes the issue. Lastly, don't get your hopes up too high. Unless your issue is a blocker affecting a large number of users, don't expect SilverStripe developers to jump @@ -42,24 +42,24 @@ problem can collaborate with you to develop a fix.
Please don't file "feature requests" as Github issues. If there's a new feature you'd like to see in SilverStripe, you either need to write it yourself (and -[submit a pull request](/misc/contributing/code)) or convince somebody else to +[submit a pull request](/contributing/code/#step-by-step-from-forking-to-sending-the-pull-request) or convince somebody else to write it for you. Any "wishlist" type issues without code attached can be expected to be closed as soon as they're reviewed.
In order to gain interest and feedback in your feature, we encourage you to -present it to the community through the [forums](http://silverstripe.org/forums), +present it to the community through the [forums](http://www.silverstripe.org/community/forums), [core mailinglist](http://groups.google.com/group/silverstripe-dev) or on -[IRC](http://silverstripe.org/irc). +[IRC](http://irc.silverstripe.org/). ## Reporting Security Issues -Report security issues to [security@silverstripe.com](mailto:security@silverstripe.com). -See our "[Release Process](release-process)" documentation for more info, and -read our guide on [how to write secure code](/topics/security). +Report security issues to [security@silverstripe.org](mailto:security@silverstripe.org). +See our "[Release Process](/contributing/release_process/#security-releases)" documentation for more info, and +read our guide on [how to write secure code](/developer_guides/security/secure_coding/). ## Sharing your Opinion -* [silverstripe.org/forums](http://silverstripe.org/forums): Forums on silverstripe.org -* [silverstripe-dev](http://groups.google.com/group/silverstripe-dev): Core development mailinglist -* [silverstripe-documentation](http://groups.google.com/group/silverstripe-translators): Translation team mailing list +* [silverstripe.org/forums](http://www.silverstripe.org/community/forums/): Forums on silverstripe.org +* [silverstripe-dev](http://groups.google.com/group/silverstripe-dev/): Core development mailinglist +* [silverstripe-documentation](http://groups.google.com/group/silverstripe-translators/): Translation team mailing list From a0f9535dd42d9085c2c84800c77f1ddb47a4ef08 Mon Sep 17 00:00:00 2001 From: Daniel Hensby Date: Fri, 6 Feb 2015 10:58:01 +0000 Subject: [PATCH 41/77] FIX issue where empty composite fields created a fieldlist with empty items --- forms/CompositeField.php | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/forms/CompositeField.php b/forms/CompositeField.php index f47d3aa2e..3bd6e9d34 100644 --- a/forms/CompositeField.php +++ b/forms/CompositeField.php @@ -47,13 +47,14 @@ class CompositeField extends FormField { if($children instanceof FieldList) { $this->children = $children; } elseif(is_array($children)) { - $this->children = new FieldList($children); + $this->children = new FieldList($children); } else { - $children = is_array(func_get_args()) ? func_get_args() : array(); - $this->children = new FieldList($children); + //filter out null/empty items + $children = array_filter(func_get_args()); + $this->children = new FieldList($children); } $this->children->setContainerField($this); - + // Skipping FormField::__construct(), but we have to make sure this // doesn't count as a broken constructor $this->brokenOnConstruct = false; From d68435e97858dfcb96742fd0b6597a381f33ca62 Mon Sep 17 00:00:00 2001 From: Daniel Hensby Date: Fri, 6 Feb 2015 11:00:00 +0000 Subject: [PATCH 42/77] FIX SelectionGroup no longer shows empty FieldLists --- templates/forms/SelectionGroup.ss | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/templates/forms/SelectionGroup.ss b/templates/forms/SelectionGroup.ss index 14737897c..8201cf936 100644 --- a/templates/forms/SelectionGroup.ss +++ b/templates/forms/SelectionGroup.ss @@ -13,7 +13,10 @@
    <% loop $FieldSet %> - {$RadioButton}{$RadioLabel}{$FieldHolder} + {$RadioButton}{$RadioLabel} + <% if $FieldList %> + $FieldHolder + <% end_if %> <% end_loop %>
From 74ec7e413f343e1f1cda4fa13a6dc1ce35183b9b Mon Sep 17 00:00:00 2001 From: Daniel Hensby Date: Sat, 7 Feb 2015 14:33:12 +0000 Subject: [PATCH 43/77] DOCS Updating contributing version --- docs/en/05_Contributing/01_Code.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/05_Contributing/01_Code.md b/docs/en/05_Contributing/01_Code.md index 4b6438a38..4d3e26091 100644 --- a/docs/en/05_Contributing/01_Code.md +++ b/docs/en/05_Contributing/01_Code.md @@ -18,7 +18,7 @@ We ask for this so that the ownership in the license is clear and unambiguous, a 1. Install the project through composer. The process is described in detail in "[Installation through Composer](../../installation/composer#contributing)". - composer create-project --keep-vcs --dev silverstripe/installer ./my/website/folder 3.0.x-dev + composer create-project --keep-vcs --dev silverstripe/installer ./my/website/folder 3.1.x-dev 2. Edit the `composer.json`. Remove the `@stable` markers from the core modules in there. Add your fork URLs, in this example a fork of the `cms` module on the `sminnee` github account From a7be8003e066bfb80bb6e281cf421a7f7fe8d268 Mon Sep 17 00:00:00 2001 From: Nick Date: Mon, 9 Feb 2015 22:55:59 +1300 Subject: [PATCH 44/77] Fix some broken links for flushable and errors in the caching code examples --- docs/en/02_Developer_Guides/08_Performance/01_Caching.md | 4 ++-- .../02_Developer_Guides/16_Execution_Pipeline/01_Flushable.md | 2 +- .../02_Developer_Guides/16_Execution_Pipeline/02_Manifests.md | 2 +- docs/en/02_Developer_Guides/16_Execution_Pipeline/index.md | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/en/02_Developer_Guides/08_Performance/01_Caching.md b/docs/en/02_Developer_Guides/08_Performance/01_Caching.md index 91a08140d..578d895ac 100644 --- a/docs/en/02_Developer_Guides/08_Performance/01_Caching.md +++ b/docs/en/02_Developer_Guides/08_Performance/01_Caching.md @@ -51,7 +51,7 @@ The returned object is of type `Zend_Cache`. $cache = SS_Cache::factory('foo'); if (!($result = $cache->load($cachekey))) { $result = caluate some how; - $cache->save($result); + $cache->save($result, $cachekey); } return $result; @@ -103,7 +103,7 @@ which can provide better performance, including APC, Xcache, ZendServer, Memcach If `?flush=1` is requested in the URL, e.g. http://mysite.com?flush=1, this will trigger a call to `flush()` on any classes that implement the `Flushable` interface. Using this, you can trigger your caches to clean. -See [reference documentation on Flushable](/reference/flushable) for implementation details. +See [reference documentation on Flushable](/developer_guides/execution_pipeline/flushable/) for implementation details. ### Memcached diff --git a/docs/en/02_Developer_Guides/16_Execution_Pipeline/01_Flushable.md b/docs/en/02_Developer_Guides/16_Execution_Pipeline/01_Flushable.md index 9872257eb..e46ef19b5 100644 --- a/docs/en/02_Developer_Guides/16_Execution_Pipeline/01_Flushable.md +++ b/docs/en/02_Developer_Guides/16_Execution_Pipeline/01_Flushable.md @@ -31,7 +31,7 @@ This example uses `[api:SS_Cache]` in some custom code, and the same cache is cl $something = $cache->load('mykey'); if(!$something) { $something = 'value to be cached'; - $cache->save($something); + $cache->save($something, 'mykey'); } return $something; } diff --git a/docs/en/02_Developer_Guides/16_Execution_Pipeline/02_Manifests.md b/docs/en/02_Developer_Guides/16_Execution_Pipeline/02_Manifests.md index 269382e26..694d5190a 100644 --- a/docs/en/02_Developer_Guides/16_Execution_Pipeline/02_Manifests.md +++ b/docs/en/02_Developer_Guides/16_Execution_Pipeline/02_Manifests.md @@ -76,7 +76,7 @@ The chapter on [configuration](/topics/configuration) has more details. ## Flushing If a `?flush=1` query parameter is added to a URL, a call to `flush()` will be triggered -on any classes that implement the [Flushable](/reference/flushable) interface. +on any classes that implement the [Flushable](flushable) interface. This enables developers to clear [manifest caches](manifests), for example when adding new templates or PHP classes. Note that you need to be in [dev mode](/getting_started/environment_management) diff --git a/docs/en/02_Developer_Guides/16_Execution_Pipeline/index.md b/docs/en/02_Developer_Guides/16_Execution_Pipeline/index.md index e250b8b9b..45310ae44 100644 --- a/docs/en/02_Developer_Guides/16_Execution_Pipeline/index.md +++ b/docs/en/02_Developer_Guides/16_Execution_Pipeline/index.md @@ -130,7 +130,7 @@ The ["Request Filters" documentation](../controller/request_filters) shows you h ## Flushing Manifests If a `?flush=1` query parameter is added to a URL, a call to `flush()` will be triggered -on any classes that implement the [Flushable](/reference/flushable) interface. +on any classes that implement the [Flushable](flushable) interface. This enables developers to clear [manifest caches](manifests), for example when adding new templates or PHP classes. Note that you need to be in [dev mode](/getting_started/environment_management) From 9fd57ea4f61c387906622330e28638d1c300927a Mon Sep 17 00:00:00 2001 From: Daniel Hensby Date: Mon, 9 Feb 2015 16:24:25 +0000 Subject: [PATCH 45/77] MINOR SS_Query properties now protected --- model/Query.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/model/Query.php b/model/Query.php index 7765775e7..9a1067afc 100644 --- a/model/Query.php +++ b/model/Query.php @@ -23,22 +23,22 @@ abstract class SS_Query implements Iterator { * * @var array */ - private $currentRecord = null; - + protected $currentRecord = null; + /** * The number of the current row in the interator. * * @var int */ - private $rowNum = -1; - + protected $rowNum = -1; + /** * Flag to keep track of whether iteration has begun, to prevent unnecessary * seeks. * * @var boolean */ - private $queryHasBegun = false; + protected $queryHasBegun = false; /** * Return an array containing all the values from a specific column. If no From 0a19d882d3ffc0a9762872d8ef04fea936064e47 Mon Sep 17 00:00:00 2001 From: Christopher Pitt Date: Tue, 10 Feb 2015 09:16:18 +1300 Subject: [PATCH 46/77] Update index.md 404 fix --- docs/en/01_Tutorials/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/01_Tutorials/index.md b/docs/en/01_Tutorials/index.md index 395174b9b..1cf924ecb 100644 --- a/docs/en/01_Tutorials/index.md +++ b/docs/en/01_Tutorials/index.md @@ -11,7 +11,7 @@ These include video screencasts, written tutorials and code examples to get you * [How to set up a local development environment in SilverStripe](https://vimeo.com/108861537) * [Lesson 1: Creating your first theme](http://www.silverstripe.org/learn/lessons/lesson-1-creating-your-first-theme/) * [Lesson 2: Migrating static templates into your theme](http://www.silverstripe.org/learn/lessons/lesson-2-migrating-static-templates-into-your-theme/) -* [Lesson 3: Adding dynamic content](http://www.silverstripe.org/learn/lessons/lesson-3/) +* [Lesson 3: Adding dynamic content](http://www.silverstripe.org/learn/lessons/lesson-3-adding-dynamic-content/) * [Lesson 4: Working with multiple templates](http://www.silverstripe.org/learn/lessons/lesson-4-working-with-multiple-templates/) * [Lesson 5: The holder/page pattern](http://www.silverstripe.org/learn/lessons/lesson-5-the-holderpage-pattern/) * [Lesson 6: Adding Custom Fields to a Page](http://www.silverstripe.org/learn/lessons/lesson-6-adding-custom-fields-to-a-page/) From e96d40d391e433eba5ea2627624c2679ad1e5dd4 Mon Sep 17 00:00:00 2001 From: gavin bruce Date: Tue, 10 Feb 2015 14:30:29 +1000 Subject: [PATCH 47/77] Update 00_Partial_Caching.md Spelling mistake fix. --- .../02_Developer_Guides/08_Performance/00_Partial_Caching.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/en/02_Developer_Guides/08_Performance/00_Partial_Caching.md b/docs/en/02_Developer_Guides/08_Performance/00_Partial_Caching.md index c2836e24e..e50d3c1be 100644 --- a/docs/en/02_Developer_Guides/08_Performance/00_Partial_Caching.md +++ b/docs/en/02_Developer_Guides/08_Performance/00_Partial_Caching.md @@ -159,7 +159,7 @@ To cache the contents of a page for all anonymous users, but dynamically calcula ## Uncached -Yhe template tag 'uncached' can be used - it is the exact equivalent of a cached block with an if condition that always +The template tag 'uncached' can be used - it is the exact equivalent of a cached block with an if condition that always returns false. The key and conditionals in an uncached tag are ignored, so you can easily temporarily disable a particular cache block by changing just the tag, leaving the key and conditional intact. @@ -235,4 +235,4 @@ Can be re-written as: <% end_loop %> <% end_cached %> - <% end_cached %> \ No newline at end of file + <% end_cached %> From d555b5b26ee97f574c862e62c040d33a965a8736 Mon Sep 17 00:00:00 2001 From: Aden Fraser Date: Wed, 11 Feb 2015 15:19:08 +0000 Subject: [PATCH 48/77] Fixed JS error in lib.js (fixes #3481) --- admin/javascript/lib.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/admin/javascript/lib.js b/admin/javascript/lib.js index a8ad7b6d2..3524c9724 100644 --- a/admin/javascript/lib.js +++ b/admin/javascript/lib.js @@ -194,8 +194,8 @@ // For embedded pages, remove the dialog hash key as in getFilePath(), // otherwise the Data Url won't match the id of the embedded Page. return u.hash.split( dialogHashKey )[0].replace( /^#/, "" ); - } else if ( path.isSameDomain( u, documentBase ) ) { - return u.hrefNoHash.replace( documentBase.domain, "" ); + } else if ( path.isSameDomain( u, document ) ) { + return u.hrefNoHash.replace( document.domain, "" ); } return absUrl; }, @@ -227,7 +227,7 @@ //return a url path with the window's location protocol/hostname/pathname removed clean: function( url ) { - return url.replace( documentBase.domain, "" ); + return url.replace( document.domain, "" ); }, //just return the url without an initial # @@ -244,7 +244,7 @@ //could be mailto, etc isExternal: function( url ) { var u = path.parseUrl( url ); - return u.protocol && u.domain !== documentUrl.domain ? true : false; + return u.protocol && u.domain !== document.domain ? true : false; }, hasProtocol: function( url ) { From eed709384d4791d3467dcc79809d6f66a7de21e0 Mon Sep 17 00:00:00 2001 From: Loz Calver Date: Thu, 22 Jan 2015 10:33:38 +0000 Subject: [PATCH 49/77] FIX: dev/build not flushing manifests if site is in a subfolder --- core/Core.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/Core.php b/core/Core.php index df2c7f802..7a5158d8b 100644 --- a/core/Core.php +++ b/core/Core.php @@ -96,7 +96,7 @@ Injector::set_inst($injector); // The coupling is a hack, but it removes an annoying bug where new classes // referenced in _config.php files can be referenced during the build process. $requestURL = isset($_REQUEST['url']) ? trim($_REQUEST['url'], '/') : false; -$flush = (isset($_GET['flush']) || $requestURL == 'dev/build' || $requestURL == BASE_URL . '/dev/build'); +$flush = (isset($_GET['flush']) || $requestURL === trim(BASE_URL . '/dev/build', '/')); global $manifest; $manifest = new SS_ClassManifest(BASE_PATH, false, $flush); From 0ec53d8fdd7a895014d5deb7819faa9c22966d11 Mon Sep 17 00:00:00 2001 From: 3Dgoo Date: Thu, 12 Feb 2015 14:39:54 +1030 Subject: [PATCH 50/77] sort method comments fixed missing single quote --- model/DataList.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/model/DataList.php b/model/DataList.php index 0f7b387af..3e2408ef1 100644 --- a/model/DataList.php +++ b/model/DataList.php @@ -244,7 +244,7 @@ class DataList extends ViewableData implements SS_List, SS_Filterable, SS_Sortab * @example $list = $list->sort('Name'); // default ASC sorting * @example $list = $list->sort('Name DESC'); // DESC sorting * @example $list = $list->sort('Name', 'ASC'); - * @example $list = $list->sort(array('Name'=>'ASC,'Age'=>'DESC')); + * @example $list = $list->sort(array('Name'=>'ASC', 'Age'=>'DESC')); * * @param String|array Escaped SQL statement. If passed as array, all keys and values are assumed to be escaped. * @return DataList From 921891943775b0a78ae223afde5bca218ad8dea8 Mon Sep 17 00:00:00 2001 From: Uncle Cheese Date: Thu, 12 Feb 2015 17:15:53 +1300 Subject: [PATCH 51/77] Several changes to deprecate old tutorials --- docs/en/01_Tutorials/01_Building_A_Basic_Site.md | 3 +++ docs/en/01_Tutorials/02_Extending_A_Basic_Site.md | 4 ++++ docs/en/01_Tutorials/05_Dataobject_Relationship_Management.md | 4 ++++ docs/en/01_Tutorials/index.md | 2 -- docs/en/index.md | 2 +- 5 files changed, 12 insertions(+), 3 deletions(-) diff --git a/docs/en/01_Tutorials/01_Building_A_Basic_Site.md b/docs/en/01_Tutorials/01_Building_A_Basic_Site.md index 1317de48c..4c8b84819 100644 --- a/docs/en/01_Tutorials/01_Building_A_Basic_Site.md +++ b/docs/en/01_Tutorials/01_Building_A_Basic_Site.md @@ -1,6 +1,9 @@ title: Building a basic site summary: An overview of the SilverStripe installation and an introduction to creating a web page. +
+This tutorial is deprecated, and has been replaced by Lessons 1, 2, 3, and 4 in the [Lessons section](http://www.silverstripe.org/learn/lessons) +
# Tutorial 1 - Building a Basic Site ## Overview diff --git a/docs/en/01_Tutorials/02_Extending_A_Basic_Site.md b/docs/en/01_Tutorials/02_Extending_A_Basic_Site.md index 87775f2f8..5a7fb60cd 100644 --- a/docs/en/01_Tutorials/02_Extending_A_Basic_Site.md +++ b/docs/en/01_Tutorials/02_Extending_A_Basic_Site.md @@ -1,6 +1,10 @@ title: Extending a basic site summary: Building on tutorial 1, a look at storing data in SilverStripe and creating a latest news feed. +
+This tutorial is deprecated, and has been replaced by Lessons 4, 5, and 6 in the [Lessons section](http://www.silverstripe.org/learn/lessons) +
+ # Tutorial 2 - Extending a basic site ## Overview diff --git a/docs/en/01_Tutorials/05_Dataobject_Relationship_Management.md b/docs/en/01_Tutorials/05_Dataobject_Relationship_Management.md index cac565c1b..1696369ec 100644 --- a/docs/en/01_Tutorials/05_Dataobject_Relationship_Management.md +++ b/docs/en/01_Tutorials/05_Dataobject_Relationship_Management.md @@ -1,6 +1,10 @@ title: DataObject Relationship Management summary: Learn how to create custom DataObjects and how to build interfaces for managing that data. +
+This tutorial is deprecated, and has been replaced by Lessons 7, 8, 9, and 10 in the [Lessons section](http://www.silverstripe.org/learn/lessons) +
+ # Tutorial 5 - Dataobject Relationship Management ## Overview diff --git a/docs/en/01_Tutorials/index.md b/docs/en/01_Tutorials/index.md index 1cf924ecb..daa53cc5b 100644 --- a/docs/en/01_Tutorials/index.md +++ b/docs/en/01_Tutorials/index.md @@ -3,8 +3,6 @@ introduction: The tutorials below take a step by step look at how to build a Sil ## Written Tutorials -[CHILDREN] - ## Video lessons These include video screencasts, written tutorials and code examples to get you started working with SilverStripe websites. diff --git a/docs/en/index.md b/docs/en/index.md index 635283d56..20c777d41 100644 --- a/docs/en/index.md +++ b/docs/en/index.md @@ -28,7 +28,7 @@ discussed on the [core mailinglist](https://groups.google.com/forum/#!forum/silv ## Building your first SilverStripe Web application Once you have completed the [Getting Started](/getting_started) guide and have got SilverStripe -installed and running, the following [Tutorials](/tutorials) will lead through the basics and core concepts of +installed and running, the following [Tutorials](http://silverstripe.org/learn/lessons) will lead through the basics and core concepts of SilverStripe. Make sure you know the basic concepts of PHP5 before attempting to follow the tutorials. If you have not programmed with PHP5 be sure to read the [Introduction to PHP5 (zend.com)](http://devzone.zend.com/6/php-101--php-for-the-absolute-beginner). From 047fe3a410624f34d617e4577669c4c7db52613b Mon Sep 17 00:00:00 2001 From: JorisDebonnet Date: Thu, 12 Feb 2015 02:20:54 +0100 Subject: [PATCH 52/77] BUG Include php version in default cache folder name Update CoreTest.php --- core/TempPath.php | 5 +++-- tests/core/CoreTest.php | 28 ++++++++++++++++------------ 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/core/TempPath.php b/core/TempPath.php index b64f2609d..93ae274db 100644 --- a/core/TempPath.php +++ b/core/TempPath.php @@ -64,8 +64,9 @@ function getTempParentFolder($base = null) { } // failing the above, try finding a namespaced silverstripe-cache dir in the system temp - $cacheFolder = DIRECTORY_SEPARATOR . 'silverstripe-cache' . str_replace(array(' ', '/', ':', '\\'), '-', $base); - $tempPath = sys_get_temp_dir() . $cacheFolder; + $tempPath = sys_get_temp_dir() . DIRECTORY_SEPARATOR . + 'silverstripe-cache-php' . preg_replace('/[^\w-\.+]+/', '-', PHP_VERSION) . + str_replace(array(' ', '/', ':', '\\'), '-', $base); if(!@file_exists($tempPath)) { $oldUMask = umask(0); $worked = @mkdir($tempPath, 0777); diff --git a/tests/core/CoreTest.php b/tests/core/CoreTest.php index a6e6df99c..3fa928cbb 100644 --- a/tests/core/CoreTest.php +++ b/tests/core/CoreTest.php @@ -22,20 +22,22 @@ class CoreTest extends SapphireTest { $this->assertEquals(getTempFolder(BASE_PATH), $this->tempPath . DIRECTORY_SEPARATOR . $user); } else { $user = getTempFolderUsername(); + $base = sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'silverstripe-cache-php' . + preg_replace('/[^\w-\.+]+/', '-', PHP_VERSION); // A typical Windows location for where sites are stored on IIS - $this->assertEquals(sys_get_temp_dir() . DIRECTORY_SEPARATOR . - 'silverstripe-cacheC--inetpub-wwwroot-silverstripe-test-project' . DIRECTORY_SEPARATOR . $user, + $this->assertEquals( + $base . 'C--inetpub-wwwroot-silverstripe-test-project' . DIRECTORY_SEPARATOR . $user, getTempFolder('C:\\inetpub\\wwwroot\\silverstripe-test-project')); // A typical Mac OS X location for where sites are stored - $this->assertEquals(sys_get_temp_dir() . DIRECTORY_SEPARATOR . - 'silverstripe-cache-Users-joebloggs-Sites-silverstripe-test-project' . DIRECTORY_SEPARATOR . $user, + $this->assertEquals( + $base . '-Users-joebloggs-Sites-silverstripe-test-project' . DIRECTORY_SEPARATOR . $user, getTempFolder('/Users/joebloggs/Sites/silverstripe-test-project')); // A typical Linux location for where sites are stored - $this->assertEquals(sys_get_temp_dir() . DIRECTORY_SEPARATOR . - 'silverstripe-cache-var-www-silverstripe-test-project' . DIRECTORY_SEPARATOR . $user, + $this->assertEquals( + $base . '-var-www-silverstripe-test-project' . DIRECTORY_SEPARATOR . $user, getTempFolder('/var/www/silverstripe-test-project')); } } @@ -43,17 +45,19 @@ class CoreTest extends SapphireTest { public function tearDown() { parent::tearDown(); $user = getTempFolderUsername(); + $base = sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'silverstripe-cache-php' . + preg_replace('/[^\w-\.+]+/', '-', PHP_VERSION); foreach(array( - 'silverstripe-cacheC--inetpub-wwwroot-silverstripe-test-project', - 'silverstripe-cache-Users-joebloggs-Sites-silverstripe-test-project', - 'silverstripe-cache-var-www-silverstripe-test-project' + 'C--inetpub-wwwroot-silverstripe-test-project', + '-Users-joebloggs-Sites-silverstripe-test-project', + '-cache-var-www-silverstripe-test-project' ) as $dir) { - $path = sys_get_temp_dir().DIRECTORY_SEPARATOR.$dir; + $path = $base . $dir; if(file_exists($path)) { rmdir($path . DIRECTORY_SEPARATOR . $user); rmdir($path); + } } - } - } + } } From c88ddef477f7581e4c2134242021481e8d995885 Mon Sep 17 00:00:00 2001 From: Uncle Cheese Date: Fri, 13 Feb 2015 00:41:29 +1300 Subject: [PATCH 53/77] add new lessons 9, 10 remove tutorials from home page --- docs/en/01_Tutorials/index.md | 7 ++++++- docs/en/index.md | 1 - 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/docs/en/01_Tutorials/index.md b/docs/en/01_Tutorials/index.md index daa53cc5b..c2b4be94e 100644 --- a/docs/en/01_Tutorials/index.md +++ b/docs/en/01_Tutorials/index.md @@ -2,7 +2,10 @@ title: Tutorials introduction: The tutorials below take a step by step look at how to build a SilverStripe application. ## Written Tutorials - +
+These tutorials are deprecated, and have been replaced by the new [Lessons](http://silverstripe.org/learn/lessons) section. +
+[CHIDLREN] ## Video lessons These include video screencasts, written tutorials and code examples to get you started working with SilverStripe websites. @@ -15,6 +18,8 @@ These include video screencasts, written tutorials and code examples to get you * [Lesson 6: Adding Custom Fields to a Page](http://www.silverstripe.org/learn/lessons/lesson-6-adding-custom-fields-to-a-page/) * [Lesson 7: Working with Files and Images](http://www.silverstripe.org/learn/lessons/lesson-7-working-with-files-and-images/) * [Lesson 8: Introduction to the ORM](http://www.silverstripe.org/learn/lessons/lesson-8-introduction-to-the-orm) +* [Lesson 9: Data Relationships - $has_many](http://www.silverstripe.org/learn/lessons/lesson-9-working-with-data-relationships-has-many) +* [Lesson 10: Introduction to the ORM](http://www.silverstripe.org/learn/lessons/lesson-10-working-with-data-relationships-many-many) ## Help: If you get stuck diff --git a/docs/en/index.md b/docs/en/index.md index 20c777d41..b72d3add5 100644 --- a/docs/en/index.md +++ b/docs/en/index.md @@ -33,7 +33,6 @@ SilverStripe. Make sure you know the basic concepts of PHP5 before attempting to follow the tutorials. If you have not programmed with PHP5 be sure to read the [Introduction to PHP5 (zend.com)](http://devzone.zend.com/6/php-101--php-for-the-absolute-beginner). -[CHILDREN Folder=01_Tutorials] ## SilverStripe Concepts From 96962a92cfa64eeb65f412cdddf3aa7110dd96bf Mon Sep 17 00:00:00 2001 From: Stephan Bauer Date: Thu, 12 Feb 2015 15:21:55 +0100 Subject: [PATCH 54/77] Changed cache_dir to respect TEMP_FOLDER --- thirdparty/tinymce/tiny_mce_gzip.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/thirdparty/tinymce/tiny_mce_gzip.php b/thirdparty/tinymce/tiny_mce_gzip.php index d07fe1b5f..c93571522 100755 --- a/thirdparty/tinymce/tiny_mce_gzip.php +++ b/thirdparty/tinymce/tiny_mce_gzip.php @@ -12,14 +12,14 @@ $frameworkPath = rtrim(dirname(dirname(dirname(__FILE__))), DIRECTORY_SEPARATOR); $basePath = rtrim(dirname($frameworkPath), DIRECTORY_SEPARATOR); -require_once $frameworkPath . '/core/TempPath.php'; +require_once $frameworkPath . '/core/Constants.php'; // Handle incoming request if it's a script call if (TinyMCE_Compressor::getParam("js")) { // Default settings $tinyMCECompressor = new TinyMCE_Compressor(array( // CUSTOM SilverStripe - 'cache_dir' => getTempFolder($basePath) + 'cache_dir' => TEMP_FOLDER // CUSTOM END )); From 36dbd4f8a10ac2e35d378d4635178b2ec9794844 Mon Sep 17 00:00:00 2001 From: LiamW Date: Thu, 12 Feb 2015 14:16:05 -0500 Subject: [PATCH 55/77] Update 11_Scaffolding.md Noticed the call to the tab is wrong. --- docs/en/02_Developer_Guides/00_Model/11_Scaffolding.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/02_Developer_Guides/00_Model/11_Scaffolding.md b/docs/en/02_Developer_Guides/00_Model/11_Scaffolding.md index f0d64e644..f66d57d15 100644 --- a/docs/en/02_Developer_Guides/00_Model/11_Scaffolding.md +++ b/docs/en/02_Developer_Guides/00_Model/11_Scaffolding.md @@ -39,7 +39,7 @@ To fully customise your form fields, start with an empty FieldList. public function getCMSFields() { $fields = FieldList::create( - TabSet::create("Root", + TabSet::create("Root.Main", CheckboxSetField::create('IsActive','Is active?'), TextField::create('Title'), TextareaField::create('Content') From 518045257e32be90781a853ab187428ff4c00948 Mon Sep 17 00:00:00 2001 From: Damian Mooyman Date: Thu, 3 Apr 2014 09:33:18 +1300 Subject: [PATCH 56/77] BUG Fixed handling of numbers in certain locales. Fixes #2161 --- forms/FormField.php | 3 +- forms/NumericField.php | 116 +++++++++++++---- tests/forms/NumericFieldTest.php | 210 ++++++++++++++++++++++++++++--- 3 files changed, 290 insertions(+), 39 deletions(-) diff --git a/forms/FormField.php b/forms/FormField.php index 40fdba1c2..693c50253 100644 --- a/forms/FormField.php +++ b/forms/FormField.php @@ -423,6 +423,7 @@ class FormField extends RequestHandler { * Set the field value. * * @param mixed $value + * @param mixed $data Optional data source passed in by {@see Form::loadDataFrom} * @return FormField Self reference */ public function setValue($value) { @@ -444,7 +445,7 @@ class FormField extends RequestHandler { * have to worry about linking the two. */ public function setForm($form) { - $this->form = $form; + $this->form = $form; return $this; } diff --git a/forms/NumericField.php b/forms/NumericField.php index d6219074b..4fd615b2a 100644 --- a/forms/NumericField.php +++ b/forms/NumericField.php @@ -2,13 +2,63 @@ /** * Text input field with validation for numeric values. Supports validating - * the numeric value as to the {@link i18n::get_locale()} value. + * the numeric value as to the {@link i18n::get_locale()} value, or an + * overridden locale specific to this field. * * @package forms * @subpackage fields-formattedinput */ class NumericField extends TextField { + /** + * Override locale for this field + * + * @var string + */ + protected $locale = null; + + public function setValue($value, $data = array()) { + require_once "Zend/Locale/Format.php"; + + // If passing in a non-string number, or a value + // directly from a dataobject then localise this number + if ((is_numeric($value) && !is_string($value)) || + ($value && $data instanceof DataObject) + ){ + $locale = new Zend_Locale($this->getLocale()); + $this->value = Zend_Locale_Format::toNumber($value, array('locale' => $locale)); + } else { + // If an invalid number, store it anyway, but validate() will fail + $this->value = $this->clean($value); + } + return $this; + } + + /** + * In some cases and locales, validation expects non-breaking spaces + * + * @param string $input + * @return string The input value, with all spaces replaced with non-breaking spaces + */ + protected function clean($input) { + $nbsp = html_entity_decode(' ', null, 'UTF-8'); + return str_replace(' ', $nbsp, trim($input)); + } + + /** + * Determine if the current value is a valid number in the current locale + * + * @return bool + */ + protected function isNumeric() { + require_once "Zend/Locale/Format.php"; + $locale = new Zend_Locale($this->getLocale()); + return Zend_Locale_Format::isNumber( + $this->clean($this->value), + array('locale' => $locale) + ); + } + public function Type() { return 'numeric text'; } @@ -18,31 +68,33 @@ class NumericField extends TextField { return true; } - require_once THIRDPARTY_PATH."/Zend/Locale/Format.php"; + if($this->isNumeric()) return true; - $valid = Zend_Locale_Format::isNumber( - trim($this->value), - array('locale' => i18n::get_locale()) + $validator->validationError( + $this->name, + _t( + 'NumericField.VALIDATION', "'{value}' is not a number, only numbers can be accepted for this field", + array('value' => $this->value) + ), + "validation" ); - - if(!$valid) { - $validator->validationError( - $this->name, - _t( - 'NumericField.VALIDATION', "'{value}' is not a number, only numbers can be accepted for this field", - array('value' => $this->value) - ), - "validation" - ); - - return false; - } - - return true; + return false; } - + + /** + * Extracts the number value from the localised string value + * + * @return string number value + */ public function dataValue() { - return (is_numeric($this->value)) ? $this->value : 0; + require_once "Zend/Locale/Format.php"; + if(!$this->isNumeric()) return 0; + $locale = new Zend_Locale($this->getLocale()); + $number = Zend_Locale_Format::getNumber( + $this->clean($this->value), + array('locale' => $locale) + ); + return $number; } /** @@ -54,6 +106,26 @@ class NumericField extends TextField { return $field; } + /** + * Gets the current locale this field is set to + * + * @return string + */ + public function getLocale() { + return $this->locale ?: i18n::get_locale(); + } + + /** + * Override the locale for this field + * + * @param string $locale + * @return $this + */ + public function setLocale($locale) { + $this->locale = $locale; + return $this; + } + } class NumericField_Readonly extends ReadonlyField { diff --git a/tests/forms/NumericFieldTest.php b/tests/forms/NumericFieldTest.php index a7fd5ad27..c7c549107 100644 --- a/tests/forms/NumericFieldTest.php +++ b/tests/forms/NumericFieldTest.php @@ -8,34 +8,212 @@ class NumericFieldTest extends SapphireTest { protected $usesDatabase = false; - public function testValidator() { - i18n::set_locale('en_US'); + /** + * In some cases and locales, validation expects non-breaking spaces. + * + * Duplicates non-public NumericField::clean method + * + * @param string $input + * @return string The input value, with all spaces replaced with non-breaking spaces + */ + protected function clean($input) { + $nbsp = html_entity_decode(' ', null, 'UTF-8'); + return str_replace(' ', $nbsp, trim($input)); + } + protected function checkInputValidation($locale, $tests) { + i18n::set_locale($locale); $field = new NumericField('Number'); - $field->setValue('12.00'); - $validator = new RequiredFields('Number'); - $this->assertTrue($field->validate($validator)); - $field->setValue('12,00'); - $this->assertFalse($field->validate($validator)); + foreach($tests as $input => $output) { + // Both decimal and thousands B + $field->setValue($input); + if($output === false) { + $this->assertFalse( + $field->validate($validator), + "Expect validation to fail for input $input in locale $locale" + ); + $this->assertEquals( + 0, + $field->dataValue(), + "Expect invalid value to be rewritten to 0 in locale $locale" + ); + + // Even invalid values shouldn't be rewritten + $this->assertEquals( + $this->clean($input), + $field->Value(), + "Expected input $input to be saved in the field in locale $locale" + ); + } else { + $this->assertTrue( + $field->validate($validator), + "Expect validation to succeed for $input in locale $locale" + ); + $this->assertEquals( + $output, + $field->dataValue(), + "Expect value $input to be mapped to $output in locale $locale" + ); + } + } + } + + /** + * Test that data loaded in via Form::loadDataFrom(DataObject) will populate the field correctly, + * and can format the database value appropriately for the frontend + * + * @param string $locale + * @param array $tests + */ + public function checkDataFormatting($locale, $tests) { + i18n::set_locale($locale); + $field = new NumericField('Number'); + $form = new Form(new Controller(), 'Form', new FieldList($field), new FieldList()); + $dataObject = new NumericFieldTest_Object(); + + foreach($tests as $input => $output) { + // Given a dataobject as a context, the field should assume the field value is not localised + $dataObject->Number = (string)$input; + $form->loadDataFrom($dataObject, Form::MERGE_CLEAR_MISSING); + + // Test value + $this->assertEquals( + $input, + $field->dataValue(), + "Expected $input loaded via dataobject to be left intact in locale $locale" + ); + + // Test expected formatted value (Substitute nbsp for spaces) + $this->assertEquals( + $this->clean($output), + $field->Value(), + "Expected $input to be formatted as $output in locale $locale" + ); + } + } + + /** + * German locale values (same as dutch) + */ + public function testGermanLocales() { + $this->checkDataFormatting('de_DE', $formatting = array( + '13000' => "13.000", + '15' => '15', + '12.0' => '12,0', + '12.1' => '12,1', + '14000.5' => "14.000,5", + )); + + $this->checkDataFormatting('nl_NL', $formatting); + + $this->checkInputValidation('de_DE', $validation = array( + '13000' => 13000, + '12,00' => 12.00, + '12.00' => false, + '11 000' => false, + '11.000' => 11000, + '11,000' => 11.0, + '15 000,5' => false, + '15 000.5' => false, + '15.000,5' => 15000.5, + '15,000.5' => false, + )); + + $this->checkInputValidation('nl_NL', $validation); + } + + /** + * French locale values + */ + public function testFrenchLocales() { + $this->checkDataFormatting('fr_FR', array( + '13000' => "13 000", + '15' => '15', + '12.0' => '12,0', + '12.1' => '12,1', + '14000.5' => "14 000,5", + )); + + $this->checkInputValidation('fr_FR', array( + '13000' => 13000, + '12,00' => 12.00, + '12.00' => false, + '11 000' => 11000, + '11.000' => false, + '11,000' => 11.000, + '15 000,5' => 15000.5, + '15 000.5' => false, + '15.000,5' => false, + '15,000.5' => false, + )); + } + + /** + * US locale values + */ + public function testUSLocales() { + $this->checkDataFormatting('en_US', array( + '13000' => "13,000", + '15' => '15', + '12.0' => '12.0', + '12.1' => '12.1', + '14000.5' => "14,000.5", + )); + + $this->checkInputValidation('en_US', array( + '13000' => 13000, + '12,00' => false, + '12.00' => 12.00, + '11 000' => false, + '11.000' => 11.0, + '11,000' => 11000, + '15 000,5' => false, + '15 000.5' => false, + '15.000,5' => false, + '15,000.5' => 15000.5, + )); + } + + /** + * Test empty values + */ + public function testEmptyValidator() { + i18n::set_locale('en_US'); + $field = new NumericField('Number'); + $validator = new RequiredFields('Number'); + + // Treats '0' as given for the sake of required fields $field->setValue('0'); $this->assertTrue($field->validate($validator)); + $this->assertEquals(0, $field->dataValue()); + + // Treat literal 0 + $field->setValue(0); + $this->assertTrue($field->validate($validator)); + $this->assertEquals(0, $field->dataValue()); + + // Should fail the 'required but not given' test + $field->setValue(''); + $this->assertFalse($field->validate($validator)); $field->setValue(false); $this->assertFalse($field->validate($validator)); + } - i18n::set_locale('de_DE'); - $field->setValue('12,00'); - $validator = new RequiredFields(); - $this->assertTrue($field->validate($validator)); - - $field->setValue('12.00'); - $this->assertFalse($field->validate($validator)); - - $field->setValue(0); + public function testReadonly() { + i18n::set_locale('en_US'); + $field = new NumericField('Number'); $this->assertRegExp("#]+>\s*0\s*<\/span>#", "".$field->performReadonlyTransformation()->Field().""); } } + +class NumericFieldTest_Object extends DataObject implements TestOnly { + + private static $db = array( + 'Number' => 'Float' + ); +} \ No newline at end of file From 89c14d079d3a130d6c4029af596262528ce53925 Mon Sep 17 00:00:00 2001 From: Daniel Hensby Date: Sat, 7 Feb 2015 23:00:36 +0000 Subject: [PATCH 57/77] Making TreeMultiSelectField consistent with parent class NEW TreeDropdownField sanatiser helper added Use config for default_cast of objects FIX Determine if Diffed value should be escaped Forcing casting for core DB fields Fixing permissions labels --- forms/TreeDropdownField.php | 26 +++++++++++++++--- forms/TreeMultiselectField.php | 34 ++++++++++-------------- forms/gridfield/GridFieldPrintButton.php | 4 +++ javascript/TreeDropdownField.js | 8 +++--- model/DataDifferencer.php | 9 +++++-- model/DataObject.php | 2 ++ security/PermissionCheckboxSetField.php | 8 +++--- templates/forms/TreeDropdownField.ss | 3 ++- view/ViewableData.php | 6 ++--- 9 files changed, 64 insertions(+), 36 deletions(-) diff --git a/forms/TreeDropdownField.php b/forms/TreeDropdownField.php index 2f9f5d623..8cf46c78b 100644 --- a/forms/TreeDropdownField.php +++ b/forms/TreeDropdownField.php @@ -94,12 +94,32 @@ class TreeDropdownField extends FormField { $this->keyField = $keyField; $this->labelField = $labelField; $this->showSearch = $showSearch; - + + $this->addExtraClass('single'); + parent::__construct($name, $title); } - + /** - * Set the ID of the root node of the tree. This defaults to 0 - i.e. + * Helper for the front end to know if we should escape the label value + * + * @return bool Whether the label field should be escaped + */ + public function getEscapeLabelField() { + // be defensive + $escape = true; + $sourceClass = $this->getSourceObject(); + //if it's an array, then it's an explicit set of values and we have to assume they've escaped their values already + //if the field is cast as XML, then we don't need to escape + if (is_array($sourceClass) || (is_a($sourceClass, 'ViewableData', true) && singleton($sourceClass)->escapeTypeForField($this->getLabelField()) == 'xml')) { + $escape = false; + } + + return $escape; + } + + /** + * Set the ID of the root node of the tree. This defaults to 0 - i.e. * displays the whole tree. * * @param int $ID diff --git a/forms/TreeMultiselectField.php b/forms/TreeMultiselectField.php index 029ac84ce..1757f7b55 100644 --- a/forms/TreeMultiselectField.php +++ b/forms/TreeMultiselectField.php @@ -46,6 +46,8 @@ class TreeMultiselectField extends TreeDropdownField { public function __construct($name, $title=null, $sourceObject="Group", $keyField="ID", $labelField="Title") { parent::__construct($name, $title, $sourceObject, $keyField, $labelField); + $this->removeExtraClass('single'); + $this->addExtraClass('multiple'); $this->value = 'unchanged'; } @@ -103,7 +105,11 @@ class TreeMultiselectField extends TreeDropdownField { if($items && count($items)) { foreach($items as $id => $item) { - $titleArray[] = $item->Title; + $title = $item->Title; + if ($item instanceof ViewableData && $item->escapeTypeForField('Title') != 'xml') { + $title = Convert::raw2xml($title); + } + $titleArray[] = $title; $idArray[] = $item->ID; } @@ -118,30 +124,18 @@ class TreeMultiselectField extends TreeDropdownField { $dataUrlTree = ''; if ($this->form){ $dataUrlTree = $this->Link('tree'); - if (isset($idArray) && count($idArray)){ + if (!empty($idArray)){ $dataUrlTree = Controller::join_links($dataUrlTree, '?forceValue='.implode(',',$idArray)); } } - return FormField::create_tag( - 'div', - array ( - 'id' => "TreeDropdownField_{$this->id()}", - 'class' => 'TreeDropdownField multiple' . ($this->extraClass() ? " {$this->extraClass()}" : '') - . ($this->showSearch ? " searchable" : ''), - 'data-url-tree' => $dataUrlTree, - 'data-title' => $title, - 'title' => $this->getDescription() - ), - FormField::create_tag( - 'input', - array ( - 'id' => $this->id(), - 'type' => 'hidden', - 'name' => $this->name, - 'value' => $value - ) + $properties = array_merge( + $properties, + array( + 'Title' => $title, + 'Link' => $dataUrlTree, ) ); + return $this->customise($properties)->renderWith('TreeDropdownField'); } /** diff --git a/forms/gridfield/GridFieldPrintButton.php b/forms/gridfield/GridFieldPrintButton.php index 217ea09cb..653620b11 100644 --- a/forms/gridfield/GridFieldPrintButton.php +++ b/forms/gridfield/GridFieldPrintButton.php @@ -192,6 +192,10 @@ class GridFieldPrintButton implements GridField_HTMLProvider, GridField_ActionPr foreach($printColumns as $field => $label) { $value = $gridField->getDataFieldValue($item, $field); + if ($item->escapeTypeForField('Title') != 'xml') { + $value = Convert::raw2xml($value); + } + $itemRow->push(new ArrayData(array( "CellString" => $value, ))); diff --git a/javascript/TreeDropdownField.js b/javascript/TreeDropdownField.js index c30e67a2c..b3d1bca59 100644 --- a/javascript/TreeDropdownField.js +++ b/javascript/TreeDropdownField.js @@ -139,9 +139,11 @@ }, setTitle: function(title) { title = title || this.data('title') || strings.fieldTitle; - - this.find('.treedropdownfield-title').html(title); - this.data('title', title); // separate view from storage (important for search cancellation) + + var func = this.data('escape-label-field') ? 'text' : 'html'; + + this.find('.treedropdownfield-title')[func](title); + this.data('title', title); // separate view from storage (important for search cancellation) }, getTitle: function() { return this.find('.treedropdownfield-title').text(); diff --git a/model/DataDifferencer.php b/model/DataDifferencer.php index 36c0b4643..a69216c69 100644 --- a/model/DataDifferencer.php +++ b/model/DataDifferencer.php @@ -85,10 +85,15 @@ class DataDifferencer extends ViewableData { if(in_array($field, $this->ignoredFields)) continue; if(in_array($field, array_keys($hasOnes))) continue; + $escape = false; + if ($this->toRecord->escapeTypeForField($field) != 'xml') { + $escape = true; + } if(!$this->fromRecord) { - $diffed->setField($field, "" . $this->toRecord->$field . ""); + $val = $escape ? Convert::raw2xml($this->toRecord->$field) : $this->toRecord->$field; + $diffed->setField($field, "" . $val . ""); } else if($this->fromRecord->$field != $this->toRecord->$field) { - $diffed->setField($field, Diff::compareHTML($this->fromRecord->$field, $this->toRecord->$field)); + $diffed->setField($field, Diff::compareHTML($this->fromRecord->$field, $this->toRecord->$field, $escape)); } } diff --git a/model/DataObject.php b/model/DataObject.php index 4a666c91c..cea18d6ed 100644 --- a/model/DataObject.php +++ b/model/DataObject.php @@ -3435,6 +3435,8 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity * @var array */ private static $casting = array( + "ID" => 'Int', + "ClassName" => 'Varchar', "LastEdited" => "SS_Datetime", "Created" => "SS_Datetime", "Title" => 'Text', diff --git a/security/PermissionCheckboxSetField.php b/security/PermissionCheckboxSetField.php index d3b7ab151..c4ade0bb0 100644 --- a/security/PermissionCheckboxSetField.php +++ b/security/PermissionCheckboxSetField.php @@ -99,7 +99,7 @@ class PermissionCheckboxSetField extends FormField { if(!isset($uninheritedCodes[$permission->Code])) $uninheritedCodes[$permission->Code] = array(); $uninheritedCodes[$permission->Code][] = _t( 'PermissionCheckboxSetField.AssignedTo', 'assigned to "{title}"', - array('title' => $record->Title) + array('title' => $record->dbObject('Title')->forTemplate()) ); } @@ -115,7 +115,7 @@ class PermissionCheckboxSetField extends FormField { 'PermissionCheckboxSetField.FromRole', 'inherited from role "{title}"', 'A permission inherited from a certain permission role', - array('title' => $role->Title) + array('title' => $role->dbObject('Title')->forTemplate()) ); } } @@ -134,7 +134,7 @@ class PermissionCheckboxSetField extends FormField { 'PermissionCheckboxSetField.FromRoleOnGroup', 'inherited from role "%s" on group "%s"', 'A permission inherited from a role on a certain group', - array('roletitle' => $role->Title, 'grouptitle' => $parent->Title) + array('roletitle' => $role->dbObject('Title')->forTemplate(), 'grouptitle' => $parent->dbObject('Title')->forTemplate()) ); } } @@ -149,7 +149,7 @@ class PermissionCheckboxSetField extends FormField { 'PermissionCheckboxSetField.FromGroup', 'inherited from group "{title}"', 'A permission inherited from a certain group', - array('title' => $parent->Title) + array('title' => $parent->dbObject('Title')->forTemplate()) ); } } diff --git a/templates/forms/TreeDropdownField.ss b/templates/forms/TreeDropdownField.ss index 8b37d2f2b..f8d84a67a 100644 --- a/templates/forms/TreeDropdownField.ss +++ b/templates/forms/TreeDropdownField.ss @@ -1,7 +1,8 @@
title="$Description.ATT"<% end_if %> <% if $Metadata %>data-metadata="$Metadata.ATT"<% end_if %>> diff --git a/view/ViewableData.php b/view/ViewableData.php index 7a6cf5b4c..dda8c653d 100644 --- a/view/ViewableData.php +++ b/view/ViewableData.php @@ -274,12 +274,12 @@ class ViewableData extends Object implements IteratorAggregate { */ public function escapeTypeForField($field) { if(!$class = $this->castingClass($field)) { - $class = self::$default_cast; + $class = $this->config()->get('default_cast'); } - + return Config::inst()->get($class, 'escape_type', Config::FIRST_SET); } - + /** * Save the casting cache for this object (including data from any failovers) into a variable * From 1db08bac88f9330dc4e6dda1ae08628f245a5212 Mon Sep 17 00:00:00 2001 From: Damian Mooyman Date: Tue, 10 Feb 2015 18:01:19 +1300 Subject: [PATCH 58/77] BUG Fix FormAction title encoding BUG Fix TreeMultiSelectField using the wrong label BUG Fix encoding of selected title on TreeDropdownField BUG Fix DataDifferencer trying to compare non-comparable fields (non-dbfield objects) BUG: Fix issue with TreeMultiSelectField not saving BUG: Fix issue with GridFieldPrintButton ENHANCEMENT Instead of using multiple api calls to encode dbfield values, delegate this operation to the individual fields via forTemplate Instead of using a new API to communicate html encoding to treeselect, just ensure all content is HTML encoded, and enable html_titles in jstree. --- docs/en/04_Changelogs/rc/3.1.10-rc1.md | 15 ++++++ forms/FormAction.php | 63 ++++++++++++++++++++---- forms/TreeDropdownField.php | 53 +++++++------------- forms/TreeMultiselectField.php | 20 ++++---- forms/gridfield/GridFieldPrintButton.php | 2 +- javascript/TreeDropdownField.js | 9 ++-- model/DataDifferencer.php | 26 +++++++--- templates/forms/FormAction.ss | 2 +- templates/forms/TreeDropdownField.ss | 5 +- tests/model/DataDifferencerTest.php | 10 +--- view/ViewableData.php | 8 ++- 11 files changed, 126 insertions(+), 87 deletions(-) create mode 100644 docs/en/04_Changelogs/rc/3.1.10-rc1.md diff --git a/docs/en/04_Changelogs/rc/3.1.10-rc1.md b/docs/en/04_Changelogs/rc/3.1.10-rc1.md new file mode 100644 index 000000000..1bfcd1c01 --- /dev/null +++ b/docs/en/04_Changelogs/rc/3.1.10-rc1.md @@ -0,0 +1,15 @@ +# 3.1.10-rc1 + +## Upgrading + +### Form Actions + +Form action titles are now safely XML encoded, although this was an implicit assumption, it is now explicitly enforced. +XML encoding titles will not cause an error, but is deprecated at framework 4.0. FormAction buttons with custom HTML +content should be assigned using the `FormAction::setButtonContent` method instead. + +## Changelog + + * [framework](https://github.com/silverstripe/silverstripe-framework/releases/tag/3.1.10-rc1) + * [cms](https://github.com/silverstripe/silverstripe-cms/releases/tag/3.1.10-rc1) + * [installer](https://github.com/silverstripe/silverstripe-installer/releases/tag/3.1.10-rc1) diff --git a/forms/FormAction.php b/forms/FormAction.php index 32c79cd3f..d9ddeb7e0 100644 --- a/forms/FormAction.php +++ b/forms/FormAction.php @@ -17,31 +17,47 @@ */ class FormAction extends FormField { + /** + * Action name, normally prefixed with 'action_' + * + * @var string + */ protected $action; /** * Enables the use of <% else %> diff --git a/templates/forms/TreeDropdownField.ss b/templates/forms/TreeDropdownField.ss index f8d84a67a..e5d2345b2 100644 --- a/templates/forms/TreeDropdownField.ss +++ b/templates/forms/TreeDropdownField.ss @@ -1,8 +1,7 @@
title="$Description.ATT"<% end_if %> <% if $Metadata %>data-metadata="$Metadata.ATT"<% end_if %>> diff --git a/tests/model/DataDifferencerTest.php b/tests/model/DataDifferencerTest.php index b0c20bb01..e1e0d87a0 100644 --- a/tests/model/DataDifferencerTest.php +++ b/tests/model/DataDifferencerTest.php @@ -17,7 +17,7 @@ class DataDifferencerTest extends SapphireTest { public function testArrayValues() { $obj1 = $this->objFromFixture('DataDifferencerTest_Object', 'obj1'); // create a new version - $obj1->Choices = array('a'); + $obj1->Choices = 'a'; $obj1->write(); $obj1v1 = Versioned::get_version('DataDifferencerTest_Object', $obj1->ID, $obj1->Version-1); $obj1v2 = Versioned::get_version('DataDifferencerTest_Object', $obj1->ID, $obj1->Version); @@ -88,14 +88,6 @@ class DataDifferencerTest_Object extends DataObject implements TestOnly { return $fields; } - public function getChoices() { - return explode(',', $this->getField('Choices')); - } - - public function setChoices($val) { - $this->setField('Choices', (is_array($val)) ? implode(',', $val) : $val); - } - } class DataDifferencerTest_HasOneRelationObject extends DataObject implements TestOnly { diff --git a/view/ViewableData.php b/view/ViewableData.php index dda8c653d..fb1584ddb 100644 --- a/view/ViewableData.php +++ b/view/ViewableData.php @@ -273,9 +273,7 @@ class ViewableData extends Object implements IteratorAggregate { * @return string 'xml'|'raw' */ public function escapeTypeForField($field) { - if(!$class = $this->castingClass($field)) { - $class = $this->config()->get('default_cast'); - } + $class = $this->castingClass($field) ?: $this->config()->default_cast; return Config::inst()->get($class, 'escape_type', Config::FIRST_SET); } @@ -367,7 +365,7 @@ class ViewableData extends Object implements IteratorAggregate { if(!is_object($value) && ($this->castingClass($fieldName) || $forceReturnedObject)) { if(!$castConstructor = $this->castingHelper($fieldName)) { - $castConstructor = $this->stat('default_cast'); + $castConstructor = $this->config()->default_cast; } $valueObject = Object::create_from_string($castConstructor, $fieldName); @@ -382,7 +380,7 @@ class ViewableData extends Object implements IteratorAggregate { } if(!is_object($value) && $forceReturnedObject) { - $default = Config::inst()->get('ViewableData', 'default_cast', Config::FIRST_SET); + $default = $this->config()->default_cast; $castedValue = new $default($fieldName); $castedValue->setValue($value); $value = $castedValue; From f9a61a68028b6eb89bac311d0c8c172fc40f945f Mon Sep 17 00:00:00 2001 From: Ben Speakman Date: Fri, 13 Feb 2015 10:10:52 +0000 Subject: [PATCH 59/77] Use double quotes to escape quotes in CSV export Resolves #3895 --- forms/gridfield/GridFieldExportButton.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/forms/gridfield/GridFieldExportButton.php b/forms/gridfield/GridFieldExportButton.php index f6fed92f4..7e853a05c 100644 --- a/forms/gridfield/GridFieldExportButton.php +++ b/forms/gridfield/GridFieldExportButton.php @@ -149,7 +149,7 @@ class GridFieldExportButton implements GridField_HTMLProvider, GridField_ActionP } $value = str_replace(array("\r", "\n"), "\n", $value); - $columnData[] = '"' . str_replace('"', '\"', $value) . '"'; + $columnData[] = '"' . str_replace('"', '""', $value) . '"'; } $fileData .= implode($separator, $columnData); $fileData .= "\n"; From eb98b003b726b7ce0e15731f68fe7c8ca558d28d Mon Sep 17 00:00:00 2001 From: zauberfisch Date: Fri, 13 Feb 2015 23:30:29 +0000 Subject: [PATCH 60/77] Fixed looking for _ss_environment.php in root dir and removed redundant code --- core/Constants.php | 11 +++++--- dev/install/install.php5 | 58 ++++------------------------------------ 2 files changed, 12 insertions(+), 57 deletions(-) diff --git a/core/Constants.php b/core/Constants.php index eb98ce9ff..d54993c31 100644 --- a/core/Constants.php +++ b/core/Constants.php @@ -49,7 +49,7 @@ if ($dirsToCheck[0] == $dirsToCheck[1]) { foreach ($dirsToCheck as $dir) { //check this dir and every parent dir (until we hit the base of the drive) // or until we hit a dir we can't read - do { + while(true) { //add the trailing slash we need to concatenate properly $dir .= DIRECTORY_SEPARATOR; //if it's readable, go ahead @@ -66,11 +66,14 @@ foreach ($dirsToCheck as $dir) { //break out of the while loop, we can't read the dir break; } + if (dirname($dir) == $dir) { + // here we need to check that the path of the last dir and the next one are + // not the same, if they are, we have hit the root of the drive + break; + } //go up a directory $dir = dirname($dir); - //here we need to check that the path of the last dir and the next one are - // not the same, if they are, we have hit the root of the drive - } while (dirname($dir) != $dir); + } } /////////////////////////////////////////////////////////////////////////////// diff --git a/dev/install/install.php5 b/dev/install/install.php5 index 8b77230b5..ba806539e 100755 --- a/dev/install/install.php5 +++ b/dev/install/install.php5 @@ -31,60 +31,12 @@ if(function_exists('session_start') && !session_id()) { session_start(); } -/** - * Include _ss_environment.php file - */ -$usingEnv = false; -$envFileExists = false; -//define the name of the environment file -$envFile = '_ss_environment.php'; -//define the dirs to start scanning from (have to add the trailing slash) -// we're going to check the realpath AND the path as the script sees it -$dirsToCheck = array( - realpath('.'), - dirname($_SERVER['SCRIPT_FILENAME']) -); -//if they are the same, remove one of them -if($dirsToCheck[0] == $dirsToCheck[1]) { - unset($dirsToCheck[1]); -} -foreach($dirsToCheck as $dir) { -//check this dir and every parent dir (until we hit the base of the drive) - // or until we hit a dir we can't read - do { - //add the trailing slash we need to concatenate properly - $dir .= DIRECTORY_SEPARATOR; - //if it's readable, go ahead - if(@is_readable($dir)) { - //if the file exists, then we include it, set relevant vars and break out - if(file_exists($dir . $envFile)) { - include_once($dir . $envFile); - $envFileExists = true; - //legacy variable assignment - $usingEnv = true; - //break out of BOTH loops because we found the $envFile - break(2); - } - } else { - //break out of the while loop, we can't read the dir - break; - } - //go up a directory - $dir = dirname($dir); - //here we need to check that the path of the last dir and the next one are -// not the same, if they are, we have hit the root of the drive - } while(dirname($dir) != $dir); -} - -if($envFileExists) { - if(!empty($_REQUEST['useEnv'])) { - $usingEnv = true; - } else { - $usingEnv = false; - } -} - require_once FRAMEWORK_NAME . '/core/Constants.php'; // this also includes TempPath.php + +$usingEnv = false; +$envFileExists = defined('SS_ENVIRONMENT_FILE'); +$usingEnv = $envFileExists && !empty($_REQUEST['useEnv']); + require_once FRAMEWORK_NAME . '/dev/install/DatabaseConfigurationHelper.php'; require_once FRAMEWORK_NAME . '/dev/install/DatabaseAdapterRegistry.php'; From aa5c9ca2467e47c60fe7d5c5f7ac060606c77346 Mon Sep 17 00:00:00 2001 From: Cam Findlay Date: Mon, 16 Feb 2015 10:28:52 +1300 Subject: [PATCH 61/77] DOCS Reference to ensure contributors read over the Code of conduct --- docs/en/05_Contributing/index.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/en/05_Contributing/index.md b/docs/en/05_Contributing/index.md index 9c8c2a427..1ff09d388 100644 --- a/docs/en/05_Contributing/index.md +++ b/docs/en/05_Contributing/index.md @@ -2,6 +2,7 @@ title: Contributing introduction: Any open source product is only as good as the community behind it. You can participate by sharing code, ideas, or simply helping others. No matter what your skill level is, every contribution counts. ## House rules for everybody contributing to SilverStripe + * Read over the SilverStripe Community [Code of Conduct](code_of_conduct) * Ask questions on the [forum](http://silverstripe.org/community/forums), and stick to more high-level discussions on the [core mailinglist](https://groups.google.com/forum/#!forum/silverstripe-dev) * Make sure you know how to [raise good bug reports](issues_and_bugs) * Everybody can contribute to SilverStripe! If you do, ensure you can [submit solid pull requests](code) From bf0104644bd54c4032f9aa1b5b2fb5a6bb4b5d06 Mon Sep 17 00:00:00 2001 From: Damian Mooyman Date: Mon, 16 Feb 2015 11:55:17 +1300 Subject: [PATCH 62/77] Update translations --- lang/id.yml | 94 +++++++++++++++++++++++++++++++++++++++++++++++++++++ lang/lt.yml | 20 ++++++------ 2 files changed, 104 insertions(+), 10 deletions(-) diff --git a/lang/id.yml b/lang/id.yml index d9d8e8fec..493906f69 100644 --- a/lang/id.yml +++ b/lang/id.yml @@ -1,4 +1,16 @@ id: + AssetAdmin: + NEWFOLDER: Berkas baru + AssetTableField: + FILENAME: Nama berkas + FOLDER: Map + TITLE: Judul + AssetUploadField: + EDITALL: 'Ubah seluruhnya' + EDITANDORGANIZE: 'Ubah dan atur' + EDITINFO: 'Ubah berkas' + FILES: Berkas + TOTAL: Total BBCodeParser: ALIGNEMENT: Penjajaran barisan ALIGNEMENTEXAMPLE: 'jajar kanan' @@ -44,18 +56,50 @@ id: DataObject: PLURALNAME: 'Objek-objek Data' SINGULARNAME: 'Objek Data' + Date: + DAY: hari + DAYS: hari + HOUR: jam + HOURS: jam + LessThanMinuteAgo: 'kurang dari semenit' + MIN: menit + MINS: menit + MONTH: bulan + MONTHS: bulan + SEC: detik + SECS: detik + TIMEDIFFAGO: '{difference} lalu' + YEAR: tahun + YEARS: tahun DateField: NOTSET: 'tidak diset' TODAY: hari ini + VALIDDATEFORMAT2: 'Mohon masukkan format tanggal yang valid ({format})' + DatetimeField: + NOTSET: 'Tidak diset' DropdownField: CHOOSE: (Pilih) + CHOOSESEARCH: '(Pilih or Cari)' + EmailField: + VALIDATION: 'Mohon masukkan alamat surel' + Enum: + ANY: Lain File: Content: Isi + CssType: 'Berkas CSS' + DocType: 'Dokumen Word' Filename: Nama File + HtlType: 'Berkas HTML' + HtmlType: 'Berkas HTML' + IcoType: 'Ikon gambar' NOFILESIZE: 'Ukuran file adalah nol bytes.' Name: Nama PLURALNAME: File-file + SINGULARNAME: Berkas Title: Judul + Folder: + PLURALNAME: Map + SINGULARNAME: Map ForgotPasswordEmail_ss: HELLO: Hai TEXT1: 'Inilah' @@ -68,6 +112,16 @@ id: VALIDATOR: Pengesah FormField: NONE: tidak ada + GridAction: + DELETE_DESCRIPTION: Hapus + Delete: Hapus + GridField: + Add: 'Tambah {name}' + Filter: Saring + FilterBy: 'Saring dengan' + Find: Temukan + LinkExisting: 'Tautan tersedia' + NewRecord: 'Baru %s' Group: Code: 'Kode Grup' DefaultGroupTitleAdministrators: Pengurus @@ -133,12 +187,39 @@ id: db_NumVisit: 'Jumlah Kunjungan' db_Password: Kata sandi db_PasswordExpiry: 'Tanggal Kata Sandi Berakhir' + MemberDatetimeOptionsetField: + TWODIGITDAY: 'Dua digit bulan' + TWODIGITHOUR: 'Dua angka jam (00 ke 23)' + TWODIGITYEAR: 'Dua-angka tahun' + MemberImportForm: + ResultCreated: 'Membuat {count} anggota' + ResultDeleted: 'Menghapus %d anggota' + ResultNone: 'Tidak ada perubahan' + MemberPassword: + PLURALNAME: 'Kata kunci anggota' + MemberTableField: + APPLY_FILTER: 'Terapkan saring' + ModelAdmin: + DELETE: Hapus + DELETEDRECORDS: 'Menghapus {count} rekod' + Title: 'Model Data' + ModelAdmin_ImportSpec_ss: + IMPORTSPECFIELDS: 'Kolom database' + IMPORTSPECRELATIONS: Hubungan + ModelAdmin_Tools_ss: + FILTER: Saring + IMPORT: Impor + ModelSidebar_ss: + IMPORT_TAB_HEADER: Impor + SEARCHLISTINGS: Cari MoneyField: FIELDLABELAMOUNT: Jumlah FIELDLABELCURRENCY: Mata Uang Permission: AdminGroup: Pengurus FULLADMINRIGHTS: 'Hak-hak administratif yang penuh' + PermissionRole: + Title: Judul PhoneNumberField: VALIDATION: 'Harap masukkan nomor telepon yang valid' Security: @@ -162,5 +243,18 @@ id: ToggleField: LESS: kurang MORE: lebih + UploadField: + DOEDIT: Simpan + EDIT: Ubah + EDITINFO: 'Ubah berkas ini' + FIELDNOTSET: 'Informasi berkas tidak ditemukan' + FROMCOMPUTER: 'Dari komputermu' + FROMCOMPUTERINFO: 'Pilih dari berkas' + FROMFILES: 'Dari berkas' + OVERWRITEWARNING: 'Berkas dengan nama yang sama sudah ada' + REMOVE: Memindahkan + STARTALL: 'Jalankan semua' + Saved: Disimpan + UPLOADSINTO: 'simpan ke /{path}' Versioned: has_many_Versions: Versi-versi diff --git a/lang/lt.yml b/lang/lt.yml index db41ef5a6..4e507f063 100644 --- a/lang/lt.yml +++ b/lang/lt.yml @@ -75,7 +75,7 @@ lt: ChangePasswordEmail_ss: CHANGEPASSWORDTEXT1: 'Jūs pakeitėte slaptažodį' CHANGEPASSWORDTEXT2: 'Nuo šiol galite naudoti šiuos prisijungimo duomenis:' - EMAIL: E. paštas + EMAIL: El. paštas HELLO: Sveiki PASSWORD: Slaptažodis ConfirmedPasswordField: @@ -173,7 +173,7 @@ lt: Form: CSRF_FAILED_MESSAGE: "Iškilo techninė problema. Prašome paspausti mygtuką Atgal,\nperkraukite naršyklės langą ir bandykite vėl." FIELDISREQUIRED: '{name} yra privalomas' - SubmitBtnLabel: Eiti + SubmitBtnLabel: Vykdyti VALIDATIONCREDITNUMBER: 'Prašome įsitikinti, ar teisingai suvedėte kreditinės kortelės numerį {number}' VALIDATIONNOTUNIQUE: 'Įvesta reikšmė nėra unikali' VALIDATIONPASSWORDSDONTMATCH: 'Nesutampa slaptažodžiai' @@ -184,14 +184,14 @@ lt: CSRF_EXPIRED_MESSAGE: 'Jūsų prisijungimas nebegalioja. Prašome iš naujo išsaugoti duomenis.' FormField: Example: 'pvz. %s' - NONE: niekas + NONE: nėra GridAction: DELETE_DESCRIPTION: Ištrinti Delete: Ištrinti UnlinkRelation: Atkabinti GridField: Add: 'Sukurti {name}' - Filter: Filtras + Filter: Filtruoti FilterBy: 'Filtruoti pagal ' Find: Rasti LEVELUP: 'Aukštyn' @@ -303,10 +303,10 @@ lt: DELETED: Ištrinta. DropdownBatchActionsDefault: Veiksmai HELP: Pagalba - PAGETYPE: 'Puslapio tipas:' + PAGETYPE: 'Puslapio tipas: ' PERMAGAIN: 'Jūs atsijungėte. Norėdami vėl prisijungti, įveskite savo duomenis į žemiau esančius laukelius.' PERMALREADY: 'Deja, Jūs negalite patekti į šią TVS dalį. Jeigu norite prisijungti kitu vartotoju, tai atlikite žemiau' - PERMDEFAULT: 'Pasirinkite prisijungimo būda ir suveskite prisijungimo duomenis' + PERMDEFAULT: 'Pasirinkite prisijungimo būdą ir suveskite prisijungimo duomenis' PLEASESAVE: 'Prašome išsaugoti puslapį: Šis puslapis negali būti atnaujintas, nes jis dar nėra išsaugotas.' PreviewButton: Peržiūra REORGANISATIONSUCCESSFUL: 'Puslapių medis pertvarkytas sėkmingai.' @@ -474,7 +474,7 @@ lt: LOGGEDOUT: 'Jūs atsijungėte. Norėdami vėl prisijungti, įveskite savo duomenis į žemiau esančius laukelius.' LOGIN: 'Prisijungti' LOSTPASSWORDHEADER: 'Slaptažodžio atstatymas' - NOTEPAGESECURED: 'Šis puslapis yra apsaugotas. Įveskite savo prisijungimo duomenis, esančius žemiau.' + NOTEPAGESECURED: 'Šis puslapis yra apsaugotas. Įveskite savo duomenis į žemiau esančius laukelius.' NOTERESETLINKINVALID: '

Neteisinga arba negaliojanti slaptažodžio atstatymo nuoroda.

Galite atsisiųsti naują čia arba pasikeisti slaptažodį po to, kai prisijungsite.

' NOTERESETPASSWORD: 'Įveskite savo e. pašto adresą ir atsiųsime slaptažodžio atstatymui skirtą nuorodą' PASSWORDSENTHEADER: 'Slaptažodžio atstatymo nuoroda nusiųsta į ''{email}''' @@ -490,7 +490,7 @@ lt: IMPORTUSERS: 'Importuoti vartotojus' MEMBERS: Nariai MENUTITLE: Saugumas - MemberListCaution: 'Dėmesio: Pašalinus vartotojus ir šio sąrašo, jie bus pašalinti iš visų grupių ir duomenų bazės.' + MemberListCaution: 'Dėmesio: Pašalinus vartotojus iš šio sąrašo, jie bus pašalinti ir iš visų grupių, bei duomenų bazės.' NEWGROUP: 'Nauja grupė' PERMISSIONS: Leidimai ROLES: Rolės @@ -499,9 +499,9 @@ lt: Users: Vartotojai SecurityAdmin_MemberImportForm: BtnImport: 'Importuoti iš CSV' - FileFieldLabel: 'CSV byla (Leidžiami plėtiniai: *.csv)' + FileFieldLabel: 'CSV byla (leidžiami plėtiniai: *.csv)' SilverStripeNavigator: - Auto: Automatiškai + Auto: Automatinis ChangeViewMode: 'Pakeisti peržiūros rėžimą' Desktop: Kompiuteris DualWindowView: 'Du langai' From 9a97cbc255d7681e068347a95b4790037ab599d3 Mon Sep 17 00:00:00 2001 From: Damian Mooyman Date: Mon, 16 Feb 2015 16:39:01 +1300 Subject: [PATCH 63/77] Added 3.1.10-rc1 changelog --- docs/en/04_Changelogs/rc/3.1.10-rc1.md | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/docs/en/04_Changelogs/rc/3.1.10-rc1.md b/docs/en/04_Changelogs/rc/3.1.10-rc1.md index 1bfcd1c01..f960bf019 100644 --- a/docs/en/04_Changelogs/rc/3.1.10-rc1.md +++ b/docs/en/04_Changelogs/rc/3.1.10-rc1.md @@ -8,6 +8,31 @@ Form action titles are now safely XML encoded, although this was an implicit ass XML encoding titles will not cause an error, but is deprecated at framework 4.0. FormAction buttons with custom HTML content should be assigned using the `FormAction::setButtonContent` method instead. +### Features and Enhancements + + * 2015-01-22 [2e4bf9a](https://github.com/silverstripe/sapphire/commit/2e4bf9a) Update sake to reference new docs (Cam Findlay) + +### Bugfixes + + * 2015-02-12 [047fe3a](https://github.com/silverstripe/sapphire/commit/047fe3a) Include php version in default cache folder name Update CoreTest.php (JorisDebonnet) + * 2015-02-10 [1db08ba](https://github.com/silverstripe/sapphire/commit/1db08ba) Fix FormAction title encoding BUG Fix TreeMultiSelectField using the wrong label BUG Fix encoding of selected title on TreeDropdownField BUG Fix DataDifferencer trying to compare non-comparable fields (non-dbfield objects) BUG: Fix issue with TreeMultiSelectField not saving BUG: Fix issue with GridFieldPrintButton ENHANCEMENT Instead of using multiple api calls to encode dbfield values, delegate this operation to the individual fields via forTemplate Instead of using a new API to communicate html encoding to treeselect, just ensure all content is HTML encoded, and enable html_titles in jstree. (Damian Mooyman) + * 2015-02-08 [a530085](https://github.com/silverstripe/silverstripe-cms/commit/a530085) External redirects shouldnt show in preview pane (Daniel Hensby) + * 2015-02-06 [d68435e](https://github.com/silverstripe/sapphire/commit/d68435e) SelectionGroup no longer shows empty FieldLists (Daniel Hensby) + * 2015-02-06 [a0f9535](https://github.com/silverstripe/sapphire/commit/a0f9535) issue where empty composite fields created a fieldlist with empty items (Daniel Hensby) + * 2015-02-05 [70e0d60](https://github.com/silverstripe/sapphire/commit/70e0d60) Fix developer output in redirection script (Damian Mooyman) + * 2015-02-03 [abd1e6b](https://github.com/silverstripe/sapphire/commit/abd1e6b) GridFieldExportButton should honour can method. (Will Rossiter) + * 2015-01-22 [eed7093](https://github.com/silverstripe/sapphire/commit/eed7093) dev/build not flushing manifests if site is in a subfolder (Loz Calver) + * 2015-01-22 [7733c43](https://github.com/silverstripe/silverstripe-cms/commit/7733c43) Correctly sanitise Title (Michael Strong) + * 2015-01-19 [77ebdc2](https://github.com/silverstripe/sapphire/commit/77ebdc2) DataObject::db returned fields in incorrect order, with incorrect data types (Loz Calver) + * 2015-01-15 [32ce85d](https://github.com/silverstripe/sapphire/commit/32ce85d) . Summary fields can't be translated (Elvinas L.) + * 2015-01-13 [2861e7c](https://github.com/silverstripe/sapphire/commit/2861e7c) insert media trims whitespace fixes #845 (Emma O'Keefe) + * 2015-01-13 [2e6e8af](https://github.com/silverstripe/sapphire/commit/2e6e8af) insert media trims whitespace - fixes #845 (Emma O'Keefe) + * 2015-01-09 [ef237f6](https://github.com/silverstripe/sapphire/commit/ef237f6) Expands the CMS' centre-pane when collapsed and it's clicked. (Russell Michell) + * 2014-10-24 [9d78eb7](https://github.com/silverstripe/sapphire/commit/9d78eb7) Fix BasicAuth not resetting failed login counts on authentication (Damian Mooyman) + * 2014-10-16 [e4ddb4b](https://github.com/silverstripe/sapphire/commit/e4ddb4b) Ensure query string in X-Backurl is encoded (fixes #3563) (Loz Calver) + * 2014-08-25 [f823831](https://github.com/silverstripe/sapphire/commit/f823831) making minify javascript fail-safe (Igor Nadj) + * 2014-04-03 [5180452](https://github.com/silverstripe/sapphire/commit/5180452) Fixed handling of numbers in certain locales. Fixes #2161 (Damian Mooyman) + ## Changelog * [framework](https://github.com/silverstripe/silverstripe-framework/releases/tag/3.1.10-rc1) From 9e600e9e0c186cf94c6bcaa0e366ffc11f855e02 Mon Sep 17 00:00:00 2001 From: Daniel Hensby Date: Mon, 16 Feb 2015 07:56:04 +0000 Subject: [PATCH 64/77] Removing redundant var declaration --- dev/install/install.php5 | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/dev/install/install.php5 b/dev/install/install.php5 index ba806539e..8febc03b5 100755 --- a/dev/install/install.php5 +++ b/dev/install/install.php5 @@ -31,9 +31,8 @@ if(function_exists('session_start') && !session_id()) { session_start(); } -require_once FRAMEWORK_NAME . '/core/Constants.php'; // this also includes TempPath.php +require_once FRAMEWORK_NAME . '/core/Constants.php'; // this also includes TempPath.php; -$usingEnv = false; $envFileExists = defined('SS_ENVIRONMENT_FILE'); $usingEnv = $envFileExists && !empty($_REQUEST['useEnv']); From 998c055676c4a98da31173d8bfa8a858facbf8cb Mon Sep 17 00:00:00 2001 From: Loz Calver Date: Fri, 13 Feb 2015 10:48:33 +0000 Subject: [PATCH 65/77] FIX: Misleading error message in SSViewer Better error message if theme is disabled DRY! --- view/SSViewer.php | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/view/SSViewer.php b/view/SSViewer.php index 0bfd23c29..8a4ebf052 100644 --- a/view/SSViewer.php +++ b/view/SSViewer.php @@ -778,12 +778,14 @@ class SSViewer implements Flushable { if(!$this->chosenTemplates) { $templateList = (is_array($templateList)) ? $templateList : array($templateList); - user_error( - "None of these templates can be found in theme '" - . Config::inst()->get('SSViewer', 'theme') . "': " - . implode(".ss, ", $templateList) . ".ss", - E_USER_WARNING - ); + $message = 'None of the following templates could be found'; + if(!$theme) { + $message .= ' (no theme in use)'; + } else { + $message .= ' in theme "' . $theme . '"'; + } + + user_error($message . ': ' . implode(".ss, ", $templateList) . ".ss", E_USER_WARNING); } } From 5d35650cbb4c34a3113e55433944f303c4fadd88 Mon Sep 17 00:00:00 2001 From: Daniel Hensby Date: Mon, 16 Feb 2015 13:58:57 +0000 Subject: [PATCH 66/77] DOCS Removing redundant PHP syntax declaration --- docs/en/00_Getting_Started/05_Coding_Conventions.md | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/en/00_Getting_Started/05_Coding_Conventions.md b/docs/en/00_Getting_Started/05_Coding_Conventions.md index 6e88827f2..b920efe0a 100644 --- a/docs/en/00_Getting_Started/05_Coding_Conventions.md +++ b/docs/en/00_Getting_Started/05_Coding_Conventions.md @@ -254,7 +254,6 @@ Keep the opening brace on the same line as the statement. // ... } - :::php // bad public function bar() { From 9971de6eff3e26aca7db9fbf876b93eb02faf517 Mon Sep 17 00:00:00 2001 From: Phill Price Date: Mon, 16 Feb 2015 20:19:53 +0000 Subject: [PATCH 67/77] Update InlineFormAction.php typo fix --- forms/InlineFormAction.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/forms/InlineFormAction.php b/forms/InlineFormAction.php index 58d7de909..d1e5cb6be 100644 --- a/forms/InlineFormAction.php +++ b/forms/InlineFormAction.php @@ -1,7 +1,7 @@ Date: Tue, 17 Feb 2015 04:33:40 +0000 Subject: [PATCH 68/77] Fixed infinity loop when searching _ss_environment --- core/Constants.php | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/core/Constants.php b/core/Constants.php index d54993c31..574773fc9 100644 --- a/core/Constants.php +++ b/core/Constants.php @@ -50,13 +50,11 @@ foreach ($dirsToCheck as $dir) { //check this dir and every parent dir (until we hit the base of the drive) // or until we hit a dir we can't read while(true) { - //add the trailing slash we need to concatenate properly - $dir .= DIRECTORY_SEPARATOR; //if it's readable, go ahead if (@is_readable($dir)) { //if the file exists, then we include it, set relevant vars and break out - if (file_exists($dir . $envFile)) { - define('SS_ENVIRONMENT_FILE', $dir . $envFile); + if (file_exists($dir . DIRECTORY_SEPARATOR . $envFile)) { + define('SS_ENVIRONMENT_FILE', $dir . DIRECTORY_SEPARATOR . $envFile); include_once(SS_ENVIRONMENT_FILE); //break out of BOTH loops because we found the $envFile break(2); From fab44dce75e4c95e9aba78828e92b81db0b2e749 Mon Sep 17 00:00:00 2001 From: Damian Mooyman Date: Tue, 17 Feb 2015 18:05:16 +1300 Subject: [PATCH 69/77] Added 3.1.10-rc2 changelog --- docs/en/04_Changelogs/rc/3.1.10-rc2.md | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 docs/en/04_Changelogs/rc/3.1.10-rc2.md diff --git a/docs/en/04_Changelogs/rc/3.1.10-rc2.md b/docs/en/04_Changelogs/rc/3.1.10-rc2.md new file mode 100644 index 000000000..cb52b2e42 --- /dev/null +++ b/docs/en/04_Changelogs/rc/3.1.10-rc2.md @@ -0,0 +1,11 @@ +# 3.1.10-rc2 + +## Bugfixes + + * 2015-02-17 [aa77e12](https://github.com/silverstripe/sapphire/commit/aa77e12) Fixed infinity loop when searching _ss_environment (Zauberfish) + +## Changelog + + * [framework](https://github.com/silverstripe/silverstripe-framework/releases/tag/3.1.10-rc2) + * [cms](https://github.com/silverstripe/silverstripe-cms/releases/tag/3.1.10-rc2) + * [installer](https://github.com/silverstripe/silverstripe-installer/releases/tag/3.1.10-rc2) From 907944cdf39adcd144ae3c5b7c09f019cae8cd6f Mon Sep 17 00:00:00 2001 From: Phill Price Date: Mon, 16 Feb 2015 20:26:36 +0000 Subject: [PATCH 70/77] Update CheckboxSetField.php Updated example to work in api - as DropdownField does. --- forms/CheckboxSetField.php | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/forms/CheckboxSetField.php b/forms/CheckboxSetField.php index 61460dabf..ca1033f53 100644 --- a/forms/CheckboxSetField.php +++ b/forms/CheckboxSetField.php @@ -6,18 +6,18 @@ * the same. * * Example: - * + * * new CheckboxSetField( - * $name = "topics", - * $title = "I am interested in the following topics", - * $source = array( - * "1" => "Technology", - * "2" => "Gardening", - * "3" => "Cooking", - * "4" => "Sports" - * ), - * $value = "1" - * ) + * $name = "topics", + * $title = "I am interested in the following topics", + * $source = array( + * "1" => "Technology", + * "2" => "Gardening", + * "3" => "Cooking", + * "4" => "Sports" + * ), + * $value = "1" + * ); * * * Saving From 0fd6b8eaca161f37b9b3fe0d60e6f1e82e9a83d7 Mon Sep 17 00:00:00 2001 From: Cam Findlay Date: Wed, 18 Feb 2015 11:13:02 +1300 Subject: [PATCH 71/77] DOCS Mention the option of Environment files for WAMP users Once you get a few sites under your belt most devs would likely turn to using environment files to names DB credentials. This introduces this a bit earlier to get them used to the simple idea of an environment file. Eventually I'd like to rewrite the installer to generate this over storing in the _config.php. --- docs/en/00_Getting_Started/01_Installation/03_Windows.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) 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 cc59f5733..ba685e489 100644 --- a/docs/en/00_Getting_Started/01_Installation/03_Windows.md +++ b/docs/en/00_Getting_Started/01_Installation/03_Windows.md @@ -40,8 +40,10 @@ $ composer create-project silverstripe/installer ./silverstripe * Unpack the archive into `C:\wamp\www` * Rename the unpacked directory from `C:\wamp\www\silverstripe-vX.X.X` to `C:\wamp\www\silverstripe` -### Install and configure -* Visit `http://localhost/silverstripe` - you will see SilverStripe's installation screen. +## Install and configure +* Option 1: Environment file - Set up a file named _ss_environment.php either in the webroot or a directory above webroot and setup as per the [Environment Management process](/getting_started/environment_management). + +* Option 2: Installer - Visit `http://localhost/silverstripe` - you will see SilverStripe's installation screen. * You should be able to click "Install SilverStripe" and the installer will do its thing. It takes a minute or two. * Once the installer has finished, visit `http://localhost/silverstripe`. You should see your new SilverStripe site's home page. @@ -61,4 +63,4 @@ alternatives for incoming connection". Make sure that it is de-selected. Right clicked on the installation folder and go to Permissions > Security > Users > Advanced and give the user full control. -3. If you find you are having issues with URL rewriting. Remove the index.php file that is bundled with SilverStripe. As we are using Apache web server's URL rewriting this file is not required (and in fact can result in problems when using apache 2.4+ as in the latest versions of WAMP). The other option is to enable the mod_access_compat module for apache which improves compatibility of newer versions of Apache with SilverStripe. \ No newline at end of file +3. If you find you are having issues with URL rewriting. Remove the index.php file that is bundled with SilverStripe. As we are using Apache web server's URL rewriting this file is not required (and in fact can result in problems when using apache 2.4+ as in the latest versions of WAMP). The other option is to enable the mod_access_compat module for apache which improves compatibility of newer versions of Apache with SilverStripe. From 4ccb0bc8585ebbb1c45138dd015542e2d413bae1 Mon Sep 17 00:00:00 2001 From: muskie9 Date: Tue, 17 Feb 2015 16:28:02 -0600 Subject: [PATCH 72/77] Update Common Problems with mod_rewrite issue --- .../01_Installation/05_Common_Problems.md | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/docs/en/00_Getting_Started/01_Installation/05_Common_Problems.md b/docs/en/00_Getting_Started/01_Installation/05_Common_Problems.md index 2a5270594..ebfed3a73 100644 --- a/docs/en/00_Getting_Started/01_Installation/05_Common_Problems.md +++ b/docs/en/00_Getting_Started/01_Installation/05_Common_Problems.md @@ -25,6 +25,20 @@ On "live" environments, the `?isDev=1` solution is preferred, as it means that y (and potentially security sensitive) PHP errors as well.
+## mod_rewrite isn't working but it's installed (prior to SilverStripe 3.1.11) + +Due to some changes to `mod_dir` in [Apache 2.4](http://httpd.apache.org/docs/current/mod/mod_dir.html#DirectoryCheckHandler) (precedence of handlers), index.php gets added to the URLs as soon as you navigate to the homepage of your site. Further requests are then handled by index.php rather than `mod_rewrite` (framework/main.php). To fix this place the following within the `mod_rewrite` section of your .htaccess file: + +``` + + # Turn off index.php handling requests to the homepage fixes issue in apache >=2.4 + + DirectoryIndex disabled + +# ------ # + +``` + ## My templates don't update on page refresh Putting ?flush=1 on the end of any SilverStripe URL will clear out all cached content; this is a pretty common solution @@ -108,4 +122,4 @@ foreach($files as $name => $file){ $matched = true; } } -``` \ No newline at end of file +``` From 666075d56cef46d26dc5226fe4ab3d546a3217ef Mon Sep 17 00:00:00 2001 From: Cam Findlay Date: Wed, 18 Feb 2015 11:34:03 +1300 Subject: [PATCH 73/77] DOCS Mention the mod_dir changes to Windows WAMP users WAMP Server likely comes with Apache 2.4 so is very relevant to have this instruction available as a troubleshoot. --- .../01_Installation/03_Windows.md | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) 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 ba685e489..5eaa68884 100644 --- a/docs/en/00_Getting_Started/01_Installation/03_Windows.md +++ b/docs/en/00_Getting_Started/01_Installation/03_Windows.md @@ -63,4 +63,16 @@ alternatives for incoming connection". Make sure that it is de-selected. Right clicked on the installation folder and go to Permissions > Security > Users > Advanced and give the user full control. -3. If you find you are having issues with URL rewriting. Remove the index.php file that is bundled with SilverStripe. As we are using Apache web server's URL rewriting this file is not required (and in fact can result in problems when using apache 2.4+ as in the latest versions of WAMP). The other option is to enable the mod_access_compat module for apache which improves compatibility of newer versions of Apache with SilverStripe. +3. Apache rewrite (mod_rewrite) isn't working and it's installed (prior to SilverStripe 3.1.11) + +Due to some changes to `mod_dir` in [Apache 2.4](http://httpd.apache.org/docs/current/mod/mod_dir.html#DirectoryCheckHandler) (precedence of handlers), index.php gets added to the URLs as soon as you navigate to the homepage of your site. Further requests are then handled by index.php rather than `mod_rewrite` (framework/main.php). To fix this place the following within the `mod_rewrite` section of your .htaccess file: + +``` + + # Turn off index.php handling requests to the homepage fixes issue in apache >=2.4 + + DirectoryIndex disabled + +# ------ # + +``` From 5047143e7b8d1733fac9d79da39de00a91e49db1 Mon Sep 17 00:00:00 2001 From: Fred Condo Date: Wed, 18 Feb 2015 10:30:07 -0800 Subject: [PATCH 74/77] Correct return statements in SS_HTTPResponse - setBody failed to return a value; it now returns $this as related methods do - getHeader had an extra, unreachable return statement; removed --- control/HTTPResponse.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/control/HTTPResponse.php b/control/HTTPResponse.php index dbcfec613..1df15f913 100644 --- a/control/HTTPResponse.php +++ b/control/HTTPResponse.php @@ -161,6 +161,7 @@ class SS_HTTPResponse { */ public function setBody($body) { $this->body = $body ? (string)$body : $body; // Don't type-cast false-ish values, eg null is null not '' + return $this; } /** @@ -191,7 +192,6 @@ class SS_HTTPResponse { public function getHeader($header) { if(isset($this->headers[$header])) return $this->headers[$header]; - return null; } /** From c302edc4e72dd93ac2c7d9bbf0ee42d2d74cd48b Mon Sep 17 00:00:00 2001 From: Damian Mooyman Date: Thu, 19 Feb 2015 12:37:16 +1300 Subject: [PATCH 75/77] Added 3.1.10 changelog --- docs/en/04_Changelogs/3.1.10.md | 57 +++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 docs/en/04_Changelogs/3.1.10.md diff --git a/docs/en/04_Changelogs/3.1.10.md b/docs/en/04_Changelogs/3.1.10.md new file mode 100644 index 000000000..04a3303a8 --- /dev/null +++ b/docs/en/04_Changelogs/3.1.10.md @@ -0,0 +1,57 @@ +# 3.1.10 + +## Upgrading + +### Form Actions + +Form action titles are now safely XML encoded, although this was an implicit assumption, it is now explicitly enforced. +XML encoding titles will not cause an error, but is deprecated at framework 4.0. FormAction buttons with custom HTML +content should be assigned using the `FormAction::setButtonContent` method instead. + +## Security + +Several medium and some low level security XSS (cross site scripting) vulnerabilites have been closed in this release. +All users of SilverStripe framework 3.1.9 and below are advised to upgrade. + + * 2015-02-10 [1db08ba](https://github.com/silverstripe/sapphire/commit/1db08ba) Fix FormAction title encoding (Damian Mooyman) - + See announcement [ss-2015-007](http://www.silverstripe.org/software/download/security-releases/ss-2015-007) + * 2015-02-10 [1db08ba](https://github.com/silverstripe/sapphire/commit/1db08ba) Core CMS XSS Vulnerability Fixes (Damian Mooyman) - + See announcements + [ss-2015-003](http://www.silverstripe.org/software/download/security-releases/ss-2015-003), + [ss-2015-004](http://www.silverstripe.org/software/download/security-releases/ss-2015-004), + [ss-2015-006](http://www.silverstripe.org/software/download/security-releases/ss-2015-006) + * 2015-01-22 [7733c43](https://github.com/silverstripe/silverstripe-cms/commit/7733c43) Correctly sanitise Title (Michael Strong) - + See announcement [SS-2015-005](http://www.silverstripe.org/software/download/security-releases/ss-2015-005) + * 2015-02-05 [70e0d60](https://github.com/silverstripe/sapphire/commit/70e0d60) Fix developer output in redirection script (Damian Mooyman) - + See announcement [SS-2015-001](http://www.silverstripe.org/software/download/security-releases/ss-2015-001) + +### Features and Enhancements + + * 2015-01-22 [2e4bf9a](https://github.com/silverstripe/sapphire/commit/2e4bf9a) Update sake to reference new docs (Cam Findlay) + +### Bugfixes + + * 2015-02-17 [aa77e12](https://github.com/silverstripe/sapphire/commit/aa77e12) Fixed infinity loop when searching _ss_environment (Zauberfish) + * 2015-02-12 [047fe3a](https://github.com/silverstripe/sapphire/commit/047fe3a) Include php version in default cache folder name Update CoreTest.php (JorisDebonnet) + * 2015-02-08 [a530085](https://github.com/silverstripe/silverstripe-cms/commit/a530085) External redirects shouldnt show in preview pane (Daniel Hensby) + * 2015-02-06 [d68435e](https://github.com/silverstripe/sapphire/commit/d68435e) SelectionGroup no longer shows empty FieldLists (Daniel Hensby) + * 2015-02-06 [a0f9535](https://github.com/silverstripe/sapphire/commit/a0f9535) issue where empty composite fields created a fieldlist with empty items (Daniel Hensby) + * 2015-02-03 [abd1e6b](https://github.com/silverstripe/sapphire/commit/abd1e6b) GridFieldExportButton should honour can method. (Will Rossiter) + * 2015-01-22 [eed7093](https://github.com/silverstripe/sapphire/commit/eed7093) dev/build not flushing manifests if site is in a subfolder (Loz Calver) + * 2015-01-19 [77ebdc2](https://github.com/silverstripe/sapphire/commit/77ebdc2) DataObject::db returned fields in incorrect order, with incorrect data types (Loz Calver) + * 2015-01-15 [32ce85d](https://github.com/silverstripe/sapphire/commit/32ce85d) . Summary fields can't be translated (Elvinas L.) + * 2015-01-13 [2e6e8af](https://github.com/silverstripe/sapphire/commit/2e6e8af) insert media trims whitespace - fixes #845 (Emma O'Keefe) + * 2015-01-13 [2861e7c](https://github.com/silverstripe/sapphire/commit/2861e7c) insert media trims whitespace fixes #845 (Emma O'Keefe) + * 2015-01-09 [ef237f6](https://github.com/silverstripe/sapphire/commit/ef237f6) Expands the CMS' centre-pane when collapsed and it's clicked. (Russell Michell) + * 2014-10-24 [9d78eb7](https://github.com/silverstripe/sapphire/commit/9d78eb7) Fix BasicAuth not resetting failed login counts on authentication (Damian Mooyman) + * 2014-10-16 [e4ddb4b](https://github.com/silverstripe/sapphire/commit/e4ddb4b) Ensure query string in X-Backurl is encoded (fixes #3563) (Loz Calver) + * 2014-08-25 [f823831](https://github.com/silverstripe/sapphire/commit/f823831) making minify javascript fail-safe (Igor Nadj) + * 2014-04-03 [5180452](https://github.com/silverstripe/sapphire/commit/5180452) Fixed handling of numbers in certain locales. Fixes #2161 (Damian Mooyman) + + +## Changelog + + * [framework](https://github.com/silverstripe/silverstripe-framework/releases/tag/3.1.10) + * [cms](https://github.com/silverstripe/silverstripe-cms/releases/tag/3.1.10) + * [installer](https://github.com/silverstripe/silverstripe-installer/releases/tag/3.1.10) + From 1e5519cf1ae8137d63dfe930f9854ed28e08f0bc Mon Sep 17 00:00:00 2001 From: Damian Mooyman Date: Thu, 19 Feb 2015 13:16:40 +1300 Subject: [PATCH 76/77] Reformat changelog --- docs/en/04_Changelogs/3.1.10.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/en/04_Changelogs/3.1.10.md b/docs/en/04_Changelogs/3.1.10.md index 04a3303a8..f3ba68e3d 100644 --- a/docs/en/04_Changelogs/3.1.10.md +++ b/docs/en/04_Changelogs/3.1.10.md @@ -14,16 +14,16 @@ Several medium and some low level security XSS (cross site scripting) vulnerabil All users of SilverStripe framework 3.1.9 and below are advised to upgrade. * 2015-02-10 [1db08ba](https://github.com/silverstripe/sapphire/commit/1db08ba) Fix FormAction title encoding (Damian Mooyman) - - See announcement [ss-2015-007](http://www.silverstripe.org/software/download/security-releases/ss-2015-007) + See announcement [ss-2015-007](http://www.silverstripe.org/software/download/security-releases/ss-2015-007) * 2015-02-10 [1db08ba](https://github.com/silverstripe/sapphire/commit/1db08ba) Core CMS XSS Vulnerability Fixes (Damian Mooyman) - - See announcements - [ss-2015-003](http://www.silverstripe.org/software/download/security-releases/ss-2015-003), - [ss-2015-004](http://www.silverstripe.org/software/download/security-releases/ss-2015-004), - [ss-2015-006](http://www.silverstripe.org/software/download/security-releases/ss-2015-006) + See announcements + [ss-2015-003](http://www.silverstripe.org/software/download/security-releases/ss-2015-003), + [ss-2015-004](http://www.silverstripe.org/software/download/security-releases/ss-2015-004), + [ss-2015-006](http://www.silverstripe.org/software/download/security-releases/ss-2015-006) * 2015-01-22 [7733c43](https://github.com/silverstripe/silverstripe-cms/commit/7733c43) Correctly sanitise Title (Michael Strong) - - See announcement [SS-2015-005](http://www.silverstripe.org/software/download/security-releases/ss-2015-005) + See announcement [SS-2015-005](http://www.silverstripe.org/software/download/security-releases/ss-2015-005) * 2015-02-05 [70e0d60](https://github.com/silverstripe/sapphire/commit/70e0d60) Fix developer output in redirection script (Damian Mooyman) - - See announcement [SS-2015-001](http://www.silverstripe.org/software/download/security-releases/ss-2015-001) + See announcement [SS-2015-001](http://www.silverstripe.org/software/download/security-releases/ss-2015-001) ### Features and Enhancements From 5cda017424121e6cd9cbd134f122d0352fd3b73c Mon Sep 17 00:00:00 2001 From: Nic Date: Wed, 18 Feb 2015 20:47:57 -0600 Subject: [PATCH 77/77] Update index.md to link to how-to's for 3 tutorials/recipies --- docs/en/02_Developer_Guides/06_Testing/index.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/en/02_Developer_Guides/06_Testing/index.md b/docs/en/02_Developer_Guides/06_Testing/index.md index 34673853a..6d826d73d 100644 --- a/docs/en/02_Developer_Guides/06_Testing/index.md +++ b/docs/en/02_Developer_Guides/06_Testing/index.md @@ -78,9 +78,9 @@ You will generally write two different kinds of test classes. Tutorials and recipes for creating tests using the SilverStripe framework: -* [Creating a SilverStripe test](creating-a-silverstripe-test): Writing tests to check core data objects -* [Creating a functional test](creating-a-functional-test): An overview of functional tests and how to write a functional test -* [Testing Outgoing Email](testing-email): An overview of the built-in email testing code +* [Creating a SilverStripe test](how_tos/write_a_sapphiretest): Writing tests to check core data objects +* [Creating a functional test](how_tos/write_a_functionaltest): An overview of functional tests and how to write a functional test +* [Testing Outgoing Email](how_tos/testing_email): An overview of the built-in email testing code ## Running Tests