API Normalise trailing slashes in links

This commit is contained in:
Florian Thoma 2022-08-26 16:34:14 +10:00 committed by Guy Sartorelli
parent 50cefa6d14
commit 18cb6d499d
No known key found for this signature in database
GPG Key ID: F313E3B9504D496A
15 changed files with 68 additions and 66 deletions

View File

@ -1 +1 @@
!function(){"use strict";var e,t,i={311:function(e){e.exports=jQuery}},r={};function n(e){var t=r[e];if(void 0!==t)return t.exports;var o=r[e]={exports:{}};return i[e](o,o.exports,n),o.exports}(0,(t=(e=n(311))&&e.__esModule?e:{default:e}).default)(document).ready((function(){(0,t.default)("#switchView a.newWindow").on("click",(function(e){var t;return window.open(this.href,(t=this.target,document.getElementsByTagName("base")[0].href.replace("http://","").replace(/\//g,"_").replace(/\./g,"_")+t)).focus(),!1})),(0,t.default)("#SilverStripeNavigatorLink").on("click",(function(e){return(0,t.default)("#SilverStripeNavigatorLinkPopup").toggle(),!1})),(0,t.default)("#SilverStripeNavigatorLinkPopup a.close").on("click",(function(e){return(0,t.default)("#SilverStripeNavigatorLinkPopup").hide(),!1})),(0,t.default)("#SilverStripeNavigatorLinkPopup input").on("focus",(function(e){this.select()}))}))}();
!function(){"use strict";var e,t,i={5311:function(e){e.exports=jQuery}},r={};function n(e){var t=r[e];if(void 0!==t)return t.exports;var o=r[e]={exports:{}};return i[e](o,o.exports,n),o.exports}(0,(t=(e=n(5311))&&e.__esModule?e:{default:e}).default)(document).ready((function(){(0,t.default)("#switchView a.newWindow").on("click",(function(e){var t;return window.open(this.href,(t=this.target,document.getElementsByTagName("base")[0].href.replace("http://","").replace(/\//g,"_").replace(/\./g,"_")+t)).focus(),!1})),(0,t.default)("#SilverStripeNavigatorLink").on("click",(function(e){return(0,t.default)("#SilverStripeNavigatorLinkPopup").toggle(),!1})),(0,t.default)("#SilverStripeNavigatorLinkPopup a.close").on("click",(function(e){return(0,t.default)("#SilverStripeNavigatorLinkPopup").hide(),!1})),(0,t.default)("#SilverStripeNavigatorLinkPopup input").on("focus",(function(e){this.select()}))}))}();

View File

@ -1 +1 @@
!function(){"use strict";var e={964:function(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;t.default={ANCHORSELECTOR_CURRENT_FIELD:"ANCHORSELECTOR_CURRENT_FIELD",ANCHORSELECTOR_UPDATED:"ANCHORSELECTOR_UPDATED",ANCHORSELECTOR_UPDATING:"ANCHORSELECTOR_UPDATING",ANCHORSELECTOR_UPDATE_FAILED:"ANCHORSELECTOR_UPDATE_FAILED"}},447:function(e,t,n){Object.defineProperty(t,"__esModule",{value:!0}),t.beginUpdating=function(e){return{type:o.default.ANCHORSELECTOR_UPDATING,payload:{pageId:e}}},t.updateFailed=function(e){return{type:o.default.ANCHORSELECTOR_UPDATE_FAILED,payload:{pageId:e}}},t.updated=function(e,t){let n=arguments.length>2&&void 0!==arguments[2]&&arguments[2];return{type:o.default.ANCHORSELECTOR_UPDATED,payload:{pageId:e,anchors:t,cacheResult:n}}},t.updatedCurrentField=function(e,t,n){return{type:o.default.ANCHORSELECTOR_CURRENT_FIELD,payload:{pageId:e,anchors:t,fieldID:n}}};var r,o=(r=n(964))&&r.__esModule?r:{default:r}},745:function(e,t,n){var r=n(394);t.createRoot=r.createRoot,t.hydrateRoot=r.hydrateRoot},939:function(e){e.exports=ApolloClient},648:function(e){e.exports=Injector},595:function(e){e.exports=InsertLinkModal},363:function(e){e.exports=React},394:function(e){e.exports=ReactDom},624:function(e){e.exports=ReactRedux},265:function(e){e.exports=ShortcodeSerialiser},196:function(e){e.exports=TinyMCEActionRegistrar},754:function(e){e.exports=i18n},311:function(e){e.exports=jQuery}},t={};function n(r){var o=t[r];if(void 0!==o)return o.exports;var i=t[r]={exports:{}};return e[r](i,i.exports,n),i.exports}!function(){var e=p(n(754)),t=p(n(196)),r=p(n(363)),o=n(745),i=n(939),a=n(624),d=p(n(311)),l=p(n(265)),s=n(595),c=n(648),u=n(447);function p(e){return e&&e.__esModule?e:{default:e}}const f="sslinkanchor";t.default.addAction("sslink",{text:e.default._t("CMS.LINKLABEL_ANCHOR","Anchor on a page"),onAction:e=>e.execCommand(f),priority:60},editorIdentifier).addCommandWithUrlTest(f,/^\[sitetree_link.+]#[^#\]]+$/);const E={init(e){e.addCommand(f,(()=>{const t=(0,d.default)(`#${e.id}`).entwine("ss"),n=Number((0,d.default)("#Form_EditForm_ID").val()||0),r=(0,d.default)(e.getBody()).find("[id],[name]").toArray().map((e=>e.id||e.name));ss.store.dispatch((0,u.updatedCurrentField)(n,r,e.id)),t.openLinkAnchorDialog()}))}},R="insert-link__dialog-wrapper--anchor",A=(0,c.provideInjector)((0,s.createInsertLinkModal)("SilverStripe\\CMS\\Controllers\\CMSPageEditController","editorAnchorLink"));d.default.entwine("ss",(t=>{t("textarea.htmleditor").entwine({openLinkAnchorDialog(){let e=t(`#${R}`);e.length||(e=t(`<div id="${R}" />`),t("body").append(e)),e.addClass("insert-link__dialog-wrapper"),e.setElement(this),e.open()}}),t(`#${R}`).entwine({ReactRoot:null,renderModal(n){var d=this;const l=ss.store,s=ss.apolloClient,c=this.getOriginalAttributes(),u=this.getElement().getEditor(),p=u.getInstance().selection,f=u.getSelection(),E="A"!==p.getNode().tagName&&""===f.trim(),R=Number(t("#Form_EditForm_ID").val()||0);let C=this.getReactRoot();C||(C=(0,o.createRoot)(this[0]),this.setReactRoot(C)),C.render(r.default.createElement(i.ApolloProvider,{client:s},r.default.createElement(a.Provider,{store:l},r.default.createElement(A,{isOpen:n,onInsert:function(){return d.handleInsert(...arguments)},onClosed:()=>this.close(),title:e.default._t("CMS.LINK_ANCHOR","Link to an anchor on a page"),bodyClassName:"modal__dialog",className:"insert-link__dialog-wrapper--anchor",fileAttributes:c,identifier:"Admin.InsertLinkAnchorModal",requireLinkText:E,currentPageID:R}))))},buildAttributes(e){return{href:`${l.default.serialise({name:"sitetree_link",properties:{id:e.PageID}},!0)}${e.Anchor&&e.Anchor.length?`#${e.Anchor}`:""}`,target:e.TargetBlank?"_blank":"",title:e.Description}},getOriginalAttributes(){const e=this.getElement().getEditor(),n=t(e.getSelectedNode()),r=(n.attr("href")||"").split("#");if(!r[0])return{};const o=l.default.match("sitetree_link",!1,r[0]);return o?{PageID:o.properties.id?parseInt(o.properties.id,10):0,Anchor:r[1]||"",Description:n.attr("title"),TargetBlank:!!n.attr("target")}:{}}})})),tinymce.PluginManager.add(f,(e=>E.init(e)))}()}();
!function(){"use strict";var e={5964:function(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;t.default={ANCHORSELECTOR_CURRENT_FIELD:"ANCHORSELECTOR_CURRENT_FIELD",ANCHORSELECTOR_UPDATED:"ANCHORSELECTOR_UPDATED",ANCHORSELECTOR_UPDATING:"ANCHORSELECTOR_UPDATING",ANCHORSELECTOR_UPDATE_FAILED:"ANCHORSELECTOR_UPDATE_FAILED"}},9447:function(e,t,n){Object.defineProperty(t,"__esModule",{value:!0}),t.beginUpdating=function(e){return{type:o.default.ANCHORSELECTOR_UPDATING,payload:{pageId:e}}},t.updateFailed=function(e){return{type:o.default.ANCHORSELECTOR_UPDATE_FAILED,payload:{pageId:e}}},t.updated=function(e,t){let n=arguments.length>2&&void 0!==arguments[2]&&arguments[2];return{type:o.default.ANCHORSELECTOR_UPDATED,payload:{pageId:e,anchors:t,cacheResult:n}}},t.updatedCurrentField=function(e,t,n){return{type:o.default.ANCHORSELECTOR_CURRENT_FIELD,payload:{pageId:e,anchors:t,fieldID:n}}};var r,o=(r=n(5964))&&r.__esModule?r:{default:r}},745:function(e,t,n){var r=n(394);t.createRoot=r.createRoot,t.hydrateRoot=r.hydrateRoot},2939:function(e){e.exports=ApolloClient},6648:function(e){e.exports=Injector},3595:function(e){e.exports=InsertLinkModal},7363:function(e){e.exports=React},394:function(e){e.exports=ReactDom},1624:function(e){e.exports=ReactRedux},5265:function(e){e.exports=ShortcodeSerialiser},2196:function(e){e.exports=TinyMCEActionRegistrar},4754:function(e){e.exports=i18n},5311:function(e){e.exports=jQuery}},t={};function n(r){var o=t[r];if(void 0!==o)return o.exports;var i=t[r]={exports:{}};return e[r](i,i.exports,n),i.exports}!function(){var e=p(n(4754)),t=p(n(2196)),r=p(n(7363)),o=n(745),i=n(2939),a=n(1624),d=p(n(5311)),l=p(n(5265)),s=n(3595),c=n(6648),u=n(9447);function p(e){return e&&e.__esModule?e:{default:e}}const f="sslinkanchor";t.default.addAction("sslink",{text:e.default._t("CMS.LINKLABEL_ANCHOR","Anchor on a page"),onAction:e=>e.execCommand(f),priority:60},editorIdentifier).addCommandWithUrlTest(f,/^\[sitetree_link.+]#[^#\]]+$/);const E={init(e){e.addCommand(f,(()=>{const t=(0,d.default)(`#${e.id}`).entwine("ss"),n=Number((0,d.default)("#Form_EditForm_ID").val()||0),r=(0,d.default)(e.getBody()).find("[id],[name]").toArray().map((e=>e.id||e.name));ss.store.dispatch((0,u.updatedCurrentField)(n,r,e.id)),t.openLinkAnchorDialog()}))}},R="insert-link__dialog-wrapper--anchor",A=(0,c.provideInjector)((0,s.createInsertLinkModal)("SilverStripe\\CMS\\Controllers\\CMSPageEditController","editorAnchorLink"));d.default.entwine("ss",(t=>{t("textarea.htmleditor").entwine({openLinkAnchorDialog(){let e=t(`#${R}`);e.length||(e=t(`<div id="${R}" />`),t("body").append(e)),e.addClass("insert-link__dialog-wrapper"),e.setElement(this),e.open()}}),t(`#${R}`).entwine({ReactRoot:null,renderModal(n){var d=this;const l=ss.store,s=ss.apolloClient,c=this.getOriginalAttributes(),u=this.getElement().getEditor(),p=u.getInstance().selection,f=u.getSelection(),E="A"!==p.getNode().tagName&&""===f.trim(),R=Number(t("#Form_EditForm_ID").val()||0);let C=this.getReactRoot();C||(C=(0,o.createRoot)(this[0]),this.setReactRoot(C)),C.render(r.default.createElement(i.ApolloProvider,{client:s},r.default.createElement(a.Provider,{store:l},r.default.createElement(A,{isOpen:n,onInsert:function(){return d.handleInsert(...arguments)},onClosed:()=>this.close(),title:e.default._t("CMS.LINK_ANCHOR","Link to an anchor on a page"),bodyClassName:"modal__dialog",className:"insert-link__dialog-wrapper--anchor",fileAttributes:c,identifier:"Admin.InsertLinkAnchorModal",requireLinkText:E,currentPageID:R}))))},buildAttributes(e){return{href:`${l.default.serialise({name:"sitetree_link",properties:{id:e.PageID}},!0)}${e.Anchor&&e.Anchor.length?`#${e.Anchor}`:""}`,target:e.TargetBlank?"_blank":"",title:e.Description}},getOriginalAttributes(){const e=this.getElement().getEditor(),n=t(e.getSelectedNode()),r=(n.attr("href")||"").split("#");if(!r[0])return{};const o=l.default.match("sitetree_link",!1,r[0]);return o?{PageID:o.properties.id?parseInt(o.properties.id,10):0,Anchor:r[1]||"",Description:n.attr("title"),TargetBlank:!!n.attr("target")}:{}}})})),tinymce.PluginManager.add(f,(e=>E.init(e)))}()}();

View File

@ -1 +1 @@
!function(){"use strict";var t={745:function(t,e,n){var i=n(394);e.createRoot=i.createRoot,e.hydrateRoot=i.hydrateRoot},939:function(t){t.exports=ApolloClient},648:function(t){t.exports=Injector},595:function(t){t.exports=InsertLinkModal},363:function(t){t.exports=React},394:function(t){t.exports=ReactDom},624:function(t){t.exports=ReactRedux},265:function(t){t.exports=ShortcodeSerialiser},196:function(t){t.exports=TinyMCEActionRegistrar},754:function(t){t.exports=i18n},311:function(t){t.exports=jQuery}},e={};function n(i){var r=e[i];if(void 0!==r)return r.exports;var o=e[i]={exports:{}};return t[i](o,o.exports,n),o.exports}!function(){var t=u(n(754)),e=u(n(196)),i=u(n(363)),r=n(745),o=n(939),a=n(624),s=u(n(311)),l=u(n(265)),d=n(595),c=n(648);function u(t){return t&&t.__esModule?t:{default:t}}const p="sslinkinternal";e.default.addAction("sslink",{text:t.default._t("CMS.LINKLABEL_PAGE","Page on this site"),onAction:t=>t.execCommand(p),priority:90},editorIdentifier).addCommandWithUrlTest(p,/^\[sitetree_link.+]$/);const g={init(t){t.addCommand(p,(()=>{(0,s.default)(`#${t.id}`).entwine("ss").openLinkInternalDialog()}))}},f="insert-link__dialog-wrapper--internal",h=(0,c.provideInjector)((0,d.createInsertLinkModal)("SilverStripe\\CMS\\Controllers\\CMSPageEditController","editorInternalLink"));s.default.entwine("ss",(e=>{e("textarea.htmleditor").entwine({openLinkInternalDialog(){let t=e(`#${f}`);t.length||(t=e(`<div id="${f}" />`),e("body").append(t)),t.addClass("insert-link__dialog-wrapper"),t.setElement(this),t.open()}}),e(`#${f}`).entwine({ReactRoot:null,renderModal(e){var n=this;const s=ss.store,l=ss.apolloClient,d=this.getOriginalAttributes(),c=this.getRequireLinkText();let u=this.getReactRoot();u||(u=(0,r.createRoot)(this[0]),this.setReactRoot(u)),u.render(i.default.createElement(o.ApolloProvider,{client:l},i.default.createElement(a.Provider,{store:s},i.default.createElement(h,{isOpen:e,onInsert:function(){return n.handleInsert(...arguments)},onClosed:()=>this.close(),title:t.default._t("CMS.LINK_PAGE","Link to a page"),bodyClassName:"modal__dialog",className:"insert-link__dialog-wrapper--internal",fileAttributes:d,identifier:"Admin.InsertLinkInternalModal",requireLinkText:c}))))},getRequireLinkText(){const t=this.getElement().getEditor(),e=t.getInstance().selection,n=t.getSelection();return"A"!==e.getNode().tagName&&""===n.trim()},buildAttributes(t){return{href:`${l.default.serialise({name:"sitetree_link",properties:{id:t.PageID}},!0)}${t.Anchor&&t.Anchor.length?`#${t.Anchor}`:""}`,target:t.TargetBlank?"_blank":"",title:t.Description}},getOriginalAttributes(){const t=this.getElement().getEditor(),n=e(t.getSelectedNode()),i=(n.attr("href")||"").split("#");if(!i[0])return{};const r=l.default.match("sitetree_link",!1,i[0]);return r?{PageID:r.properties.id?parseInt(r.properties.id,10):0,Anchor:i[1]||"",Description:n.attr("title"),TargetBlank:!!n.attr("target")}:{}}})})),tinymce.PluginManager.add(p,(t=>g.init(t)))}()}();
!function(){"use strict";var t={745:function(t,e,n){var i=n(394);e.createRoot=i.createRoot,e.hydrateRoot=i.hydrateRoot},2939:function(t){t.exports=ApolloClient},6648:function(t){t.exports=Injector},3595:function(t){t.exports=InsertLinkModal},7363:function(t){t.exports=React},394:function(t){t.exports=ReactDom},1624:function(t){t.exports=ReactRedux},5265:function(t){t.exports=ShortcodeSerialiser},2196:function(t){t.exports=TinyMCEActionRegistrar},4754:function(t){t.exports=i18n},5311:function(t){t.exports=jQuery}},e={};function n(i){var r=e[i];if(void 0!==r)return r.exports;var o=e[i]={exports:{}};return t[i](o,o.exports,n),o.exports}!function(){var t=u(n(4754)),e=u(n(2196)),i=u(n(7363)),r=n(745),o=n(2939),a=n(1624),s=u(n(5311)),l=u(n(5265)),d=n(3595),c=n(6648);function u(t){return t&&t.__esModule?t:{default:t}}const p="sslinkinternal";e.default.addAction("sslink",{text:t.default._t("CMS.LINKLABEL_PAGE","Page on this site"),onAction:t=>t.execCommand(p),priority:90},editorIdentifier).addCommandWithUrlTest(p,/^\[sitetree_link.+]$/);const g={init(t){t.addCommand(p,(()=>{(0,s.default)(`#${t.id}`).entwine("ss").openLinkInternalDialog()}))}},f="insert-link__dialog-wrapper--internal",h=(0,c.provideInjector)((0,d.createInsertLinkModal)("SilverStripe\\CMS\\Controllers\\CMSPageEditController","editorInternalLink"));s.default.entwine("ss",(e=>{e("textarea.htmleditor").entwine({openLinkInternalDialog(){let t=e(`#${f}`);t.length||(t=e(`<div id="${f}" />`),e("body").append(t)),t.addClass("insert-link__dialog-wrapper"),t.setElement(this),t.open()}}),e(`#${f}`).entwine({ReactRoot:null,renderModal(e){var n=this;const s=ss.store,l=ss.apolloClient,d=this.getOriginalAttributes(),c=this.getRequireLinkText();let u=this.getReactRoot();u||(u=(0,r.createRoot)(this[0]),this.setReactRoot(u)),u.render(i.default.createElement(o.ApolloProvider,{client:l},i.default.createElement(a.Provider,{store:s},i.default.createElement(h,{isOpen:e,onInsert:function(){return n.handleInsert(...arguments)},onClosed:()=>this.close(),title:t.default._t("CMS.LINK_PAGE","Link to a page"),bodyClassName:"modal__dialog",className:"insert-link__dialog-wrapper--internal",fileAttributes:d,identifier:"Admin.InsertLinkInternalModal",requireLinkText:c}))))},getRequireLinkText(){const t=this.getElement().getEditor(),e=t.getInstance().selection,n=t.getSelection();return"A"!==e.getNode().tagName&&""===n.trim()},buildAttributes(t){return{href:`${l.default.serialise({name:"sitetree_link",properties:{id:t.PageID}},!0)}${t.Anchor&&t.Anchor.length?`#${t.Anchor}`:""}`,target:t.TargetBlank?"_blank":"",title:t.Description}},getOriginalAttributes(){const t=this.getElement().getEditor(),n=e(t.getSelectedNode()),i=(n.attr("href")||"").split("#");if(!i[0])return{};const r=l.default.match("sitetree_link",!1,i[0]);return r?{PageID:r.properties.id?parseInt(r.properties.id,10):0,Anchor:i[1]||"",Description:n.attr("title"),TargetBlank:!!n.attr("target")}:{}}})})),tinymce.PluginManager.add(p,(t=>g.init(t)))}()}();

File diff suppressed because one or more lines are too long

View File

@ -1,6 +1,7 @@
import $ from 'jquery';
import i18n from 'i18n';
import reactConfirm from 'reactstrap-confirm';
import { joinUrlPaths } from 'lib/urls';
$.entwine('ss.tree', function($) {
$('.cms-tree').entwine({
@ -45,7 +46,7 @@ $.entwine('ss.tree', function($) {
});
const baseUrl = $('base').attr('href') || ''; // Edge17 and IE11 require absolute paths
window.location.assign(baseUrl + urlWithParams);
window.location.assign(joinUrlPaths(baseUrl, urlWithParams));
},
getTreeConfig: function() {

View File

@ -1,4 +1,5 @@
import $ from 'jquery';
import { joinUrlPaths } from 'lib/urls';
/**
* Behaviour for the CMS Content Toolbar.
@ -81,7 +82,7 @@ $.entwine('ss', function ($) {
localStorage.setItem('ss.pages-view-type', viewType);
if(isContentViewInSidebar && viewType === VIEW_TYPE_LIST) {
const baseUrl = $('base').attr('href') || ''; // Edge17 and IE11 need absolute path
window.location.assign(baseUrl + $contentView.data('url-listviewroot'));
window.location.assign(joinUrlPaths(baseUrl, $contentView.data('url-listviewroot')));
return;
}

View File

@ -84,7 +84,7 @@ class ModelAsController extends Controller implements NestedController
// If the database has not yet been created, redirect to the build page.
/** @skipUpgrade */
if (!DB::is_active() || !ClassInfo::hasTable('SiteTree')) {
$this->getResponse()->redirect(Director::absoluteBaseURL() . 'dev/build?returnURL=' . (isset($_GET['url']) ? urlencode($_GET['url']) : null));
$this->getResponse()->redirect(Controller::join_links(Director::absoluteBaseURL(), 'dev/build?returnURL=' . (isset($_GET['url']) ? urlencode($_GET['url']) : null)));
$this->popCurrent();
return $this->getResponse();

View File

@ -102,7 +102,7 @@ class OldPageRedirector extends Extension
// No valid page found.
if ($redirect) {
// If we had some redirect to be done, lets do it. imagine /foo/action -> /bar/action, we still want this redirect to happen if action isn't a page
return $page->Link() . implode('/', $params);
return Controller::join_links($page->Link(), implode('/', $params));
}
}
} else {

View File

@ -134,7 +134,7 @@ class SiteTreeURLSegmentField extends TextField
*/
public function getURLPrefix()
{
return $this->urlPrefix;
return rtrim($this->urlPrefix ?? '', '/') . '/';
}
public function getURLSuffix()

View File

@ -697,7 +697,7 @@ class SiteTree extends DataObject implements PermissionProvider, i18nEntityProvi
$action = null;
}
$link = Controller::join_links($base, '/', $action);
$link = Controller::join_links($base, $action);
$this->extend('updateRelativeLink', $link, $base, $action);

View File

@ -92,7 +92,7 @@ class ModelAsControllerTest extends FunctionalTest
$response = $this->get('newlevel1/level2');
$this->assertEquals($response->getStatusCode(), 301);
$this->assertEquals(
Controller::join_links(Director::baseURL() . 'newlevel1/newlevel2/'),
Controller::join_links(Director::baseURL() . 'newlevel1/newlevel2'),
$response->getHeader('Location')
);
@ -100,7 +100,7 @@ class ModelAsControllerTest extends FunctionalTest
$response = $this->get('newlevel1/newlevel2/level3');
$this->assertEquals($response->getStatusCode(), 301);
$this->assertEquals(
Controller::join_links(Director::baseURL() . 'newlevel1/newlevel2/newlevel3/'),
Controller::join_links(Director::baseURL() . 'newlevel1/newlevel2/newlevel3'),
$response->getHeader('Location')
);
@ -153,10 +153,10 @@ class ModelAsControllerTest extends FunctionalTest
$page5->copyVersionToStage(Versioned::DRAFT, Versioned::LIVE);
// Test that the redirect still works fine when trying to access the most nested page
$response = $this->get('oldurl/level2/level3/level4/level5/');
$response = $this->get('oldurl/level2/level3/level4/level5');
$this->assertEquals($response->getStatusCode(), 301);
$this->assertEquals(
Controller::join_links(Director::baseURL() . 'newurl/level2/level3/level4/level5/'),
Controller::join_links(Director::baseURL() . 'newurl/level2/level3/level4/level5'),
$response->getHeader('Location')
);
}
@ -170,7 +170,7 @@ class ModelAsControllerTest extends FunctionalTest
$response = $this->get('newlevel3');
$this->assertEquals(301, $response->getStatusCode());
$this->assertEquals(
Director::baseURL() . 'newlevel1/newlevel2/newlevel3/',
Director::baseURL() . 'newlevel1/newlevel2/newlevel3',
$response->getHeader("Location")
);
@ -178,7 +178,7 @@ class ModelAsControllerTest extends FunctionalTest
$response = $this->get('level3');
$this->assertEquals(301, $response->getStatusCode());
$this->assertEquals(
Director::baseURL() . 'newlevel1/newlevel2/newlevel3/',
Director::baseURL() . 'newlevel1/newlevel2/newlevel3',
$response->getHeader("Location")
);
}
@ -214,10 +214,10 @@ class ModelAsControllerTest extends FunctionalTest
$this->generateNestedPagesFixture();
// check third level URLSegment
$response = $this->get('newlevel1/newlevel2/level3/?foo=bar&test=test');
$response = $this->get('newlevel1/newlevel2/level3?foo=bar&test=test');
$this->assertEquals($response->getStatusCode(), 301);
$this->assertEquals(
Controller::join_links(Director::baseURL() . 'newlevel1/newlevel2/newlevel3/', '?foo=bar&test=test'),
Controller::join_links(Director::baseURL() . 'newlevel1/newlevel2/newlevel3', '?foo=bar&test=test'),
$response->getHeader('Location')
);
}

View File

@ -50,11 +50,11 @@ class RedirectorPageTest extends FunctionalTest
$this->objFromFixture(RedirectorPage::class, 'goodexternal')->Link()
);
$this->assertEquals(
"/redirection-dest/",
"/redirection-dest",
$this->objFromFixture(RedirectorPage::class, 'goodinternal')->redirectionLink()
);
$this->assertEquals(
"/redirection-dest/",
"/redirection-dest",
$this->objFromFixture(RedirectorPage::class, 'goodinternal')->Link()
);
}
@ -64,7 +64,7 @@ class RedirectorPageTest extends FunctionalTest
// If a redirector page is misconfigured, then its link method will just return the usual
// URLSegment-generated value
$page1 = $this->objFromFixture(RedirectorPage::class, 'badexternal');
$this->assertEquals('/bad-external/', $page1->Link());
$this->assertEquals('/bad-external', $page1->Link());
// An error message will be shown if you visit it
$content = $this->get(Director::makeRelative($page1->Link()))->getBody();
@ -72,7 +72,7 @@ class RedirectorPageTest extends FunctionalTest
// This also applies for internal links
$page2 = $this->objFromFixture(RedirectorPage::class, 'badinternal');
$this->assertEquals('/bad-internal/', $page2->Link());
$this->assertEquals('/bad-internal', $page2->Link());
$content = $this->get(Director::makeRelative($page2->Link()))->getBody();
$this->assertStringContainsString('message-setupWithoutRedirect', $content);
}
@ -82,7 +82,7 @@ class RedirectorPageTest extends FunctionalTest
// Reflexive redirectors are those that point to themselves.
// They should behave the same as an empty redirector
$page = $this->objFromFixture(RedirectorPage::class, 'reflexive');
$this->assertEquals('/reflexive/', $page->Link());
$this->assertEquals('/reflexive', $page->Link());
$content = $this->get(Director::makeRelative($page->Link()))->getBody();
$this->assertStringContainsString('message-setupWithoutRedirect', $content);
@ -90,11 +90,11 @@ class RedirectorPageTest extends FunctionalTest
// They should send people to the URLSegment of the destination page - the middle-stop, so to speak.
// That should redirect to the final destination
$page = $this->objFromFixture(RedirectorPage::class, 'transitive');
$this->assertEquals('/good-internal/', $page->Link());
$this->assertEquals('/good-internal', $page->Link());
$this->autoFollowRedirection = false;
$response = $this->get(Director::makeRelative($page->Link()));
$this->assertEquals(Director::absoluteURL('/redirection-dest/'), $response->getHeader("Location"));
$this->assertEquals(Director::absoluteURL('/redirection-dest'), $response->getHeader("Location"));
}
public function testExternalURLGetsPrefixIfNotSet()

View File

@ -103,7 +103,7 @@ class SiteTreeBacklinksTest extends SapphireTest
// assert hyperlink to page 1's current url exists on page 3
$links = HTTP::getLinksIn($page3->obj('Content')->forTemplate());
$this->assertContains(
Director::baseURL() . 'page1/',
Director::baseURL() . 'page1',
$links,
'Assert hyperlink to page 1\'s current url exists on page 3'
);
@ -118,7 +118,7 @@ class SiteTreeBacklinksTest extends SapphireTest
// assert hyperlink to page 1's new url exists
$links = HTTP::getLinksIn($page3->obj('Content')->forTemplate());
$this->assertContains(
Director::baseURL() . 'new-url-segment/',
Director::baseURL() . 'new-url-segment',
$links,
'Assert hyperlink to page 1\'s new url exists on page 3'
);
@ -146,7 +146,7 @@ class SiteTreeBacklinksTest extends SapphireTest
// assert hyperlink to page 1's current url exists on page 3
$links = HTTP::getLinksIn($page3live->obj('Content')->forTemplate());
$this->assertContains(
Director::baseURL() . 'page1/',
Director::baseURL() . 'page1',
$links,
'Assert hyperlink to page 1\'s current url exists on page 3'
);
@ -162,7 +162,7 @@ class SiteTreeBacklinksTest extends SapphireTest
Versioned::set_stage(Versioned::LIVE);
$links = HTTP::getLinksIn($page3live->obj('Content')->forTemplate());
$this->assertContains(
Director::baseURL() . 'new-url-segment/',
Director::baseURL() . 'new-url-segment',
$links,
'Assert hyperlink to page 1\'s new url exists on page 3'
);
@ -183,7 +183,7 @@ class SiteTreeBacklinksTest extends SapphireTest
// assert hyperlink to page 1's current url exists
$links = HTTP::getLinksIn($page3live->obj('Content')->forTemplate());
$this->assertContains(
Director::baseURL() . 'page1/',
Director::baseURL() . 'page1',
$links,
'Assert hyperlink to page 1\'s current url exists on page 3'
);
@ -197,7 +197,7 @@ class SiteTreeBacklinksTest extends SapphireTest
Versioned::set_stage(Versioned::LIVE);
$links = HTTP::getLinksIn($page3live->obj('Content')->forTemplate());
$this->assertContains(
Director::baseURL() . 'page1/',
Director::baseURL() . 'page1',
$links,
'Assert hyperlink to page 1\'s current published url exists on page 3'
);
@ -210,7 +210,7 @@ class SiteTreeBacklinksTest extends SapphireTest
$page3live = Versioned::get_one_by_stage(SiteTree::class, 'Live', '"SiteTree"."ID" = ' . $page3->ID);
$links = HTTP::getLinksIn($page3live->obj('Content')->forTemplate());
$this->assertContains(
Director::baseURL() . 'new-url-segment/',
Director::baseURL() . 'new-url-segment',
$links,
'Assert hyperlink to page 1\'s new published url exists on page 3'
);
@ -227,7 +227,7 @@ class SiteTreeBacklinksTest extends SapphireTest
// assert hyperlink to page 1's current url exists
$links = HTTP::getLinksIn($page3->obj('Content')->forTemplate());
$this->assertContains(
Director::baseURL() . 'page1/',
Director::baseURL() . 'page1',
$links,
'Assert hyperlink to page 1\'s current published url exists on page 3'
);
@ -242,7 +242,7 @@ class SiteTreeBacklinksTest extends SapphireTest
$page3 = $this->objFromFixture(SiteTree::class, 'page3');
$links = HTTP::getLinksIn($page3->obj('Content')->forTemplate());
$this->assertContains(
Director::baseURL() . 'new-url-segment/',
Director::baseURL() . 'new-url-segment',
$links,
'Assert hyperlink to page 1\'s current draft url exists on page 3'
);
@ -255,7 +255,7 @@ class SiteTreeBacklinksTest extends SapphireTest
Versioned::set_stage(Versioned::LIVE);
$links = HTTP::getLinksIn($page3live->obj('Content')->forTemplate());
$this->assertContains(
Director::baseURL() . 'page1/',
Director::baseURL() . 'page1',
$links,
'Assert hyperlink to page 1\'s current published url exists on page 3'
);
@ -267,7 +267,7 @@ class SiteTreeBacklinksTest extends SapphireTest
$page3live = Versioned::get_one_by_stage(SiteTree::class, 'Live', '"SiteTree"."ID" = ' . $page3->ID);
$links = HTTP::getLinksIn($page3live->obj('Content')->forTemplate());
$this->assertContains(
Director::baseURL() . 'new-url-segment/',
Director::baseURL() . 'new-url-segment',
$links,
'Assert hyperlink to page 1\'s current published url exists on page 3'
);
@ -305,7 +305,7 @@ class SiteTreeBacklinksTest extends SapphireTest
// confirm that draft link on page2 has been rewritten
$page2 = $this->objFromFixture(SiteTree::class, 'page2');
$this->assertEquals(
'<p><a href="' . Director::baseURL() . 'page1-new-url/">Testing page 1 link</a></p>',
'<p><a href="' . Director::baseURL() . 'page1-new-url">Testing page 1 link</a></p>',
$page2->obj('ExtraContent')->forTemplate()
);
@ -313,7 +313,7 @@ class SiteTreeBacklinksTest extends SapphireTest
$page2Live = Versioned::get_one_by_stage(SiteTree::class, "Live", "\"SiteTree\".\"ID\" = $page2->ID");
Versioned::set_stage(Versioned::LIVE);
$this->assertEquals(
'<p><a href="' . Director::baseURL() . 'page1/">Testing page 1 link</a></p>',
'<p><a href="' . Director::baseURL() . 'page1">Testing page 1 link</a></p>',
$page2Live->obj('ExtraContent')->forTemplate()
);
@ -321,7 +321,7 @@ class SiteTreeBacklinksTest extends SapphireTest
$page1->publishRecursive();
$page2Live = Versioned::get_one_by_stage(SiteTree::class, "Live", "\"SiteTree\".\"ID\" = $page2->ID");
$this->assertEquals(
'<p><a href="' . Director::baseURL() . 'page1-new-url/">Testing page 1 link</a></p>',
'<p><a href="' . Director::baseURL() . 'page1-new-url">Testing page 1 link</a></p>',
$page2Live->obj('ExtraContent')->forTemplate()
);

View File

@ -512,12 +512,12 @@ class SiteTreeTest extends SapphireTest
Config::modify()->set(SiteTree::class, 'nested_urls', true);
$this->assertEquals(
'about-us/',
'about-us',
$about->RelativeLink(),
'Matches URLSegment on top level without parameters'
);
$this->assertEquals(
'about-us/my-staff/',
'about-us/my-staff',
$staff->RelativeLink(),
'Matches URLSegment plus parent on second level without parameters'
);
@ -555,8 +555,8 @@ class SiteTreeTest extends SapphireTest
$parent->URLSegment = 'changed-on-draft';
$parent->write();
$this->assertStringEndsWith('changed-on-live/my-staff/', $child->getAbsoluteLiveLink(false));
$this->assertStringEndsWith('changed-on-live/my-staff/?stage=Live', $child->getAbsoluteLiveLink());
$this->assertStringEndsWith('changed-on-live/my-staff', $child->getAbsoluteLiveLink(false));
$this->assertStringEndsWith('changed-on-live/my-staff?stage=Live', $child->getAbsoluteLiveLink());
}
public function testDuplicateChildrenRetainSort()

View File

@ -1647,9 +1647,9 @@
eslint-webpack-plugin "^3.2.0"
"@silverstripe/webpack-config@^2.0.0-alpha6":
version "2.0.0-alpha6"
resolved "https://registry.yarnpkg.com/@silverstripe/webpack-config/-/webpack-config-2.0.0-alpha6.tgz#4a781f600344c3604169de08244ca11cacbd46f7"
integrity sha512-cPux01Z6EGwnSg5EezaJZ1S2x4ThfA3TbpTWTsqmW2jvr1VM/7Xu8B3j2HFH+2fNP0dvdmu+fScCD6VPNVQNWw==
version "2.0.0-alpha7"
resolved "https://registry.yarnpkg.com/@silverstripe/webpack-config/-/webpack-config-2.0.0-alpha7.tgz#c825f30fa0991222ac3e89a114bdc4cca2b2c254"
integrity sha512-XkqdnED1E072QXxFSovP8KrJuVtZGIeW9fLMdLI8tJwzf6651ziwYFWYwep72C0Eb+jpUabxNQl7eqlAHO52xA==
dependencies:
"@babel/core" "^7.19.6"
"@babel/preset-env" "^7.19.4"
@ -2582,9 +2582,9 @@ camelcase@^6.2.0:
integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==
caniuse-lite@^1.0.30001400, caniuse-lite@^1.0.30001426:
version "1.0.30001443"
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001443.tgz#8fc85f912d5471c9821acacf9e715c421ca0dd1f"
integrity sha512-jUo8svymO8+Mkj3qbUbVjR8zv8LUGpGkUM/jKvc9SO2BvjCI980dp9fQbf/dyLs6RascPzgR4nhAKFA4OHeSaA==
version "1.0.30001446"
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001446.tgz#6d4ba828ab19f49f9bcd14a8430d30feebf1e0c5"
integrity sha512-fEoga4PrImGcwUUGEol/PoFCSBnSkA9drgdkxXkJLsUBOnJ8rs3zDv6ApqYXGQFOyMPsjh79naWhF4DAxbF8rw==
chalk@^1.0.0, chalk@^1.1.1, chalk@^1.1.3:
version "1.1.3"
@ -2879,9 +2879,9 @@ copy-webpack-plugin@^11.0.0:
serialize-javascript "^6.0.0"
core-js-compat@^3.25.1:
version "3.27.1"
resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.27.1.tgz#b5695eb25c602d72b1d30cbfba3cb7e5e4cf0a67"
integrity sha512-Dg91JFeCDA17FKnneN7oCMz4BkQ4TcffkgHP4OWwp9yx3pi7ubqMDXXSacfNak1PQqjc95skyt+YBLHQJnkJwA==
version "3.27.2"
resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.27.2.tgz#607c50ad6db8fd8326af0b2883ebb987be3786da"
integrity sha512-welaYuF7ZtbYKGrIy7y3eb40d37rG1FvzEOfe7hSLd2iD6duMDqUhRfSvCGyC46HhR6Y8JXXdZ2lnRUMkPBpvg==
dependencies:
browserslist "^4.21.4"
@ -4014,9 +4014,9 @@ glob@^7.0.0, glob@^7.0.3, glob@^7.1.3, glob@^7.1.4:
path-is-absolute "^1.0.0"
glob@^8.0.1:
version "8.0.3"
resolved "https://registry.yarnpkg.com/glob/-/glob-8.0.3.tgz#415c6eb2deed9e502c68fa44a272e6da6eeca42e"
integrity sha512-ull455NHSHI/Y1FqGaaYFaLGkNMMJbavMrEGFXG/PGrg6y7sutWHUHrz6gy6WEBH6akM1M414dWKCNs+IhKdiQ==
version "8.1.0"
resolved "https://registry.yarnpkg.com/glob/-/glob-8.1.0.tgz#d388f656593ef708ee3e34640fdfb99a9fd1c33e"
integrity sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==
dependencies:
fs.realpath "^1.0.0"
inflight "^1.0.4"
@ -5221,9 +5221,9 @@ kleur@^3.0.3:
integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==
klona@^2.0.4, klona@^2.0.5:
version "2.0.5"
resolved "https://registry.yarnpkg.com/klona/-/klona-2.0.5.tgz#d166574d90076395d9963aa7a928fabb8d76afbc"
integrity sha512-pJiBpiXMbt7dkzXe8Ghj/u4FfXOOa98fPW+bihOJ4SjnoijweJrNThJfd3ifXpXhREjpoF2mZVH1GfS9LV3kHQ==
version "2.0.6"
resolved "https://registry.yarnpkg.com/klona/-/klona-2.0.6.tgz#85bffbf819c03b2f53270412420a4555ef882e22"
integrity sha512-dhG34DXATL5hSxJbIexCft8FChFXtmskoZYnoPWjXQuebWYCNkVeV3KkGegCK9CP1oswI/vQibS2GY7Em/sJJA==
known-css-properties@^0.3.0:
version "0.3.0"
@ -5594,9 +5594,9 @@ minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2:
brace-expansion "^1.1.7"
minimatch@^5.0.1, minimatch@^5.1.0:
version "5.1.2"
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.1.2.tgz#0939d7d6f0898acbd1508abe534d1929368a8fff"
integrity sha512-bNH9mmM9qsJ2X4r2Nat1B//1dJVcn3+iBLa3IgqJ7EbGaDNepL9QSHOxN4ng33s52VMMhhIfgCYDk3C4ZmlDAg==
version "5.1.6"
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.1.6.tgz#1cfcb8cf5522ea69952cd2af95ae09477f122a96"
integrity sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==
dependencies:
brace-expansion "^2.0.1"
@ -6477,9 +6477,9 @@ prop-types@^15.5.8, prop-types@^15.6.0, prop-types@^15.6.1, prop-types@^15.6.2,
react-is "^16.13.1"
punycode@^2.1.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.2.0.tgz#2092cc57cd2582c38e4e7e8bb869dc8d3148bc74"
integrity sha512-LN6QV1IJ9ZhxWTNdktaPClrNfp8xdSAYS0Zk2ddX7XsXZAxckMHPCBcHRo0cTcEIgYPRiGEkmji3Idkh2yFtYw==
version "2.3.0"
resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.0.tgz#f67fa67c94da8f4d0cfff981aee4118064199b8f"
integrity sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==
qrcode-terminal@^0.12.0:
version "0.12.0"