diff --git a/_config/routes.yml b/_config/routes.yml index 947adfbe7..32161642e 100644 --- a/_config/routes.yml +++ b/_config/routes.yml @@ -9,8 +9,8 @@ Director: Name: coreroutes Before: '*' After: - - framework/routes#rootroutes - - cms/routes#modelascontrollerroutes + - '#rootroutes' + - '#modelascontrollerroutes' --- Director: rules: @@ -25,9 +25,9 @@ Director: Name: adminroutes Before: '*' After: - - framework/routes#rootroutes - - framework/routes#coreroutes - - cms/routes#modelascontrollerroutes + - '#rootroutes' + - '#coreroutes' + - '#modelascontrollerroutes' --- Director: rules: diff --git a/admin/code/LeftAndMain.php b/admin/code/LeftAndMain.php index e789450cc..622a69b16 100644 --- a/admin/code/LeftAndMain.php +++ b/admin/code/LeftAndMain.php @@ -753,9 +753,9 @@ class LeftAndMain extends Controller implements PermissionProvider { $next = $prev = null; $className = $this->stat('tree_class'); - $next = DataObject::get($className, 'ParentID = '.$record->ParentID.' AND Sort > '.$record->Sort)->first(); + $next = DataObject::get($className)->filter('ParentID', $record->ParentID)->filter('Sort:GreaterThan', $record->Sort)->first(); if (!$next) { - $prev = DataObject::get($className, 'ParentID = '.$record->ParentID.' AND Sort < '.$record->Sort)->reverse()->first(); + $prev = DataObject::get($className)->filter('ParentID', $record->ParentID)->filter('Sort:LessThan', $record->Sort)->reverse()->first(); } $link = Controller::join_links($recordController->Link("show"), $record->ID); @@ -1615,4 +1615,4 @@ class LeftAndMain_TreeNode extends ViewableData { return $this; } -} \ No newline at end of file +} diff --git a/admin/css/screen.css b/admin/css/screen.css index b6439b8f2..99ca2d49d 100644 --- a/admin/css/screen.css +++ b/admin/css/screen.css @@ -180,7 +180,6 @@ form.small .field input.text, form.small .field textarea, form.small .field sele .field .chzn-container-single .chzn-single:hover, .field .chzn-container-single .chzn-single:focus, .field .chzn-container-single .chzn-single:active { text-decoration: none; outline: none; } .field .chzn-container-single .chzn-single div { width: 24px; } .field .chzn-container-single .chzn-single div b { background-position: 4px 0px; } -.field input.hasDatepicker { width: 50%; max-width: 96px; } .field input.month, .field input.day, .field input.year { width: 56px; } .field input.time { width: 64px; } .field.remove-splitter { border-bottom: none; box-shadow: none; } @@ -210,8 +209,9 @@ form.small .field input.text, form.small .field textarea, form.small .field sele .cms .ss-ui-loading-icon { background: url(../../images/network-save.gif) no-repeat; display: block; width: 16px; height: 16px; } /** ---------------------------------------------------- Grouped form fields ---------------------------------------------------- */ -.fieldgroup .fieldgroup-field { float: left; display: block; width: 184px; padding: 8px 0 0 8px; } +.fieldgroup .fieldgroup-field { float: left; display: block; padding: 8px 0 0 8px; } .fieldgroup .fieldgroup-field .field { border: none; padding-bottom: 0; } +.fieldgroup.stacked .fieldgroup-field { float: none; } .ss-toggle { margin-bottom: 8px; } .ss-toggle .ui-accordion-header { font-weight: bold; } @@ -393,13 +393,6 @@ body.cms { overflow: hidden; } .cms-content-tools.filter { padding: 0 !important; } .cms-content-tools .cms-panel-header { clear: both; margin: 0 0 7px; line-height: 24px; border-bottom: 1px solid rgba(201, 205, 206, 0.8); -webkit-box-shadow: 0 1px 0 rgba(255, 255, 255, 0.8); -moz-box-shadow: 0 1px 0 rgba(255, 255, 255, 0.8); -o-box-shadow: 0 1px 0 rgba(255, 255, 255, 0.8); box-shadow: 0 1px 0 rgba(255, 255, 255, 0.8); } .cms-content-tools .cms-panel-content { width: 176px; padding: 8px 8px 0; overflow: auto; height: 100%; } -.cms-content-tools .cms-panel-content .dropdown select { width: 160px; } -.cms-content-tools .cms-panel-content #LastEditedFrom { -webkit-box-shadow: none; -moz-box-shadow: none; box-shadow: none; } -.cms-content-tools .cms-panel-content #LastEditedFrom input { width: 160px; } -.cms-content-tools .cms-panel-content #LastEditedFrom input.hasDatepicker { max-width: 160px; } -.cms-content-tools .cms-panel-content #LastEditedTo { -webkit-box-shadow: none; -moz-box-shadow: none; box-shadow: none; } -.cms-content-tools .cms-panel-content #LastEditedTo input { width: 160px; } -.cms-content-tools .cms-panel-content #LastEditedTo input.hasDatepicker { max-width: 160px; } .cms-content-tools .cms-panel-content .Actions .ss-ui-action-constructive { margin-right: 5px; } .cms-content-tools .cms-content-header { background-color: #748d9d; background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjUwJSIgeTE9IjAlIiB4Mj0iNTAlIiB5Mj0iMTAwJSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2IwYmVjNyIvPjxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0iIzc0OGQ5ZCIvPjwvbGluZWFyR3JhZGllbnQ+PC9kZWZzPjxyZWN0IHg9IjAiIHk9IjAiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9InVybCgjZ3JhZCkiIC8+PC9zdmc+IA=='); background-size: 100%; background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #b0bec7), color-stop(100%, #748d9d)); background-image: -webkit-linear-gradient(#b0bec7, #748d9d); background-image: -moz-linear-gradient(#b0bec7, #748d9d); background-image: -o-linear-gradient(#b0bec7, #748d9d); background-image: linear-gradient(#b0bec7, #748d9d); } .cms-content-tools .cms-content-header h2 { text-shadow: #5c7382 -1px -1px 0; width: 176px; color: white; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; -o-text-overflow: ellipsis; } @@ -413,7 +406,7 @@ body.cms { overflow: hidden; } .cms-content-tools .field input.text, .cms-content-tools .field select, .cms-content-tools .field textarea { padding: 5px; font-size: 11px; } .cms-content-tools .field.checkbox { padding: 0 8px 0; } .cms-content-tools .field.checkbox input { margin: 2px 0; } -.cms-content-tools .fieldgroup .fieldgroup-field { width: auto; padding: 0; } +.cms-content-tools .fieldgroup .fieldgroup-field { padding: 0; } .cms-content-tools .fieldgroup .fieldgroup-field .field { margin: 0; padding: 0; } .cms-content-tools table { margin: 8px -4px; } .cms-content-tools table thead th { color: #1f1f1f; font-weight: bold; line-height: 16px; font-size: 11px; padding: 4px; } diff --git a/admin/javascript/LeftAndMain.Preview.js b/admin/javascript/LeftAndMain.Preview.js index 2fc7f65c1..d421250c2 100644 --- a/admin/javascript/LeftAndMain.Preview.js +++ b/admin/javascript/LeftAndMain.Preview.js @@ -67,7 +67,10 @@ if(this.is('.is-collapsed')) return; // var url = ui.xmlhttp.getResponseHeader('x-frontend-url'); - var url = $('.cms-edit-form').find(':input[name=PreviewURL],:input[name=StageURLSegment]').val(); + var url = $('.cms-edit-form') + .find(':input[name=PreviewURL],:input[name=StageLink],:input[name=LiveLink]') + .filter(function() {return $(this).val() !== '';}) + .val(); if(url) { this.loadUrl(url); this.unblock(); @@ -138,9 +141,17 @@ var href = links[i].getAttribute('href'); if(!href) continue; - // Disable external links - if (href.match(/^http:\/\//)) links[i].setAttribute('href', 'javascript:false'); + // Open external links in new window to avoid "escaping" the + // internal page context in the preview iframe, + // which is important to stay in for the CMS logic. + if (href.match(/^http:\/\//)) links[i].setAttribute('target', '_blank'); } + + // Hide duplicate navigator, as it replicates existing UI in the CMS + var navi = doc.getElementById('SilverStripeNavigator'); + if(navi) navi.style.display = 'none'; + var naviMsg = doc.getElementById('SilverStripeNavigatorMessage'); + if(naviMsg) naviMsg.style.display = 'none'; }, expand: function(inclMenu) { @@ -164,7 +175,7 @@ var self = this, containerEl = this.getLayoutContainer(), contentEl = containerEl.find('.cms-content'); this.addClass('east').removeClass('center').addClass('is-collapsed').width(10); // this.css('overflow', 'hidden'); - contentEl.addClass('center').show(); + contentEl.addClass('center').show().css('visibility', 'visible'); this.find('iframe').hide(); this.find('.cms-preview-toggle a').html('«'); this.find('.cms-preview-controls').hide(); @@ -286,7 +297,11 @@ onclick: function(e) { e.preventDefault(); - var preview = $('.cms-preview'), url = $('.cms-edit-form').find(':input[name=PreviewURL],:input[name=StageURLSegment]').val(); + var preview = $('.cms-preview'), + url = $('.cms-edit-form') + .find(':input[name=PreviewURL],:input[name=StageLink],:input[name=LiveLink]') + .filter(function() {return $(this).val() !== '';}) + .val(); if(url) { preview.loadUrl(url); preview.unblock(); diff --git a/admin/javascript/LeftAndMain.Tree.js b/admin/javascript/LeftAndMain.Tree.js index bfa8b5b3d..101f93fe0 100644 --- a/admin/javascript/LeftAndMain.Tree.js +++ b/admin/javascript/LeftAndMain.Tree.js @@ -307,6 +307,7 @@ if(id) { node = this.getNodeByID(id); if(node.length) { + this.jstree('deselect_all'); this.jstree('select_node', node); } else { // If form is showing an ID that doesn't exist in the tree, diff --git a/admin/scss/_forms.scss b/admin/scss/_forms.scss index 302d7b381..db718a2fb 100644 --- a/admin/scss/_forms.scss +++ b/admin/scss/_forms.scss @@ -236,11 +236,6 @@ form.small .field, .field.small { } /* Date Fields */ - input.hasDatepicker { - width: 50%; - max-width: ($grid-x * 12); - } - input.month, input.day, input.year { width: ($grid-x * 7); } @@ -443,7 +438,6 @@ form.small .field, .field.small { .fieldgroup-field { float: left; display: block; - width: $grid-x * 23; padding: $grid-y 0 0 $grid-x; &.odd { @@ -459,6 +453,12 @@ form.small .field, .field.small { padding-bottom: 0; } } + + &.stacked { + .fieldgroup-field { + float: none; + } + } } .ss-toggle { diff --git a/admin/scss/_style.scss b/admin/scss/_style.scss index 6573c368c..d5fedf3fc 100644 --- a/admin/scss/_style.scss +++ b/admin/scss/_style.scss @@ -692,27 +692,7 @@ body.cms { padding: $grid-x $grid-x 0; overflow: auto; height:100%; - .dropdown select { - width:$grid-x * 20; - } - #LastEditedFrom { - @include box-shadow(none); - input { - width:$grid-x * 20; - &.hasDatepicker { - max-width:$grid-x * 20; - } - } - } - #LastEditedTo { - @include box-shadow(none); - input { - width:$grid-x * 20; - &.hasDatepicker { - max-width:$grid-x * 20; - } - } - } + .Actions .ss-ui-action-constructive { margin-right:5px; //accounts for the scrollbar in the filter - keeps the actions on one line instead of wrapping onto two. } @@ -785,7 +765,6 @@ body.cms { .fieldgroup { .fieldgroup-field { - width: auto; padding: 0; .field { diff --git a/core/Object.php b/core/Object.php index 1b7f98a07..60c6cc758 100755 --- a/core/Object.php +++ b/core/Object.php @@ -274,8 +274,6 @@ abstract class Object { * Get the value of a static property of a class, even in that property is declared protected (but not private), without any inheritance, * merging or parent lookup if it doesn't exist on the given class. * - * If using PHP 5.4, we can do this using $foo::$bar syntax. PHP 5.3 uses ReflectionClass to get the static properties instead. - * * @static * @param $class - The class to get the static from * @param $name - The property to get from the class @@ -283,7 +281,7 @@ abstract class Object { * @return any - The value of the static property $name on class $class, or $default if that property is not defined */ public static function static_lookup($class, $name, $default = null) { - if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 4 && is_subclass_of($class, 'Object')) { + if (is_subclass_of($class, 'Object')) { if (isset($class::$$name)) { $parent = get_parent_class($class); if (!$parent || !isset($parent::$$name) || $parent::$$name !== $class::$$name) return $class::$$name; diff --git a/core/manifest/ConfigManifest.php b/core/manifest/ConfigManifest.php index 076bc98e2..1bc033879 100644 --- a/core/manifest/ConfigManifest.php +++ b/core/manifest/ConfigManifest.php @@ -223,11 +223,12 @@ class SS_ConfigManifest { // For each, parse out into module/file#name, and set any missing to "*" $header[$order] = array(); foreach($orderparts as $part) { - preg_match('! (\*|\w+) (?:\/(\*|\w+) (?:\*|\#(\w+))? )? !x', $part, $match); + preg_match('! (?P\*|\w+)? (\/ (?P\*|\w+))? (\# (?P\*|\w+))? !x', $part, $match); + $header[$order][] = array( - 'module' => $match[1], - 'file' => isset($match[2]) ? $match[2] : '*', - 'name' => isset($match[3]) ? $match[3] : '*' + 'module' => isset($match['module']) && $match['module'] ? $match['module'] : '*', + 'file' => isset($match['file']) && $match['file'] ? $match['file'] : '*', + 'name' => isset($match['fragment']) && $match['fragment'] ? $match['fragment'] : '*' ); } } @@ -289,7 +290,7 @@ class SS_ConfigManifest { echo $res; } - throw $e; + user_error('Based on their before & after rules two fragments both need to be before/after each other', E_USER_ERROR); } } diff --git a/templates/forms/FieldGroup_DefaultFieldHolder.ss b/templates/forms/FieldGroup_DefaultFieldHolder.ss new file mode 100644 index 000000000..cb9478322 --- /dev/null +++ b/templates/forms/FieldGroup_DefaultFieldHolder.ss @@ -0,0 +1,7 @@ +
id="$ID"<% end_if %>> + <% loop FieldList %> +
+ $FieldHolder +
+ <% end_loop %> +
\ No newline at end of file diff --git a/tests/model/MySQLDatabaseTest.php b/tests/model/MySQLDatabaseTest.php index 1cac2ad14..33e3da5dc 100644 --- a/tests/model/MySQLDatabaseTest.php +++ b/tests/model/MySQLDatabaseTest.php @@ -17,7 +17,7 @@ class MySQLDatabaseTest extends SapphireTest { 'MultiEnum3' => 'MultiEnum("A, B, C, D","A, B")', ); } - + $this->markTestSkipped('This test requires the Config API to be immutable'); parent::setUp(); } @@ -27,7 +27,6 @@ class MySQLDatabaseTest extends SapphireTest { function testFieldsDontRerequestChanges() { // These are MySQL specific :-S if(DB::getConn() instanceof MySQLDatabase) { - $db = DB::getConn(); DB::quiet();