mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 12:05:37 +00:00
ENHANCEMENT FieldList->setTabPathRewrites() for better backwards compatibility (see #7261)
This commit is contained in:
parent
f546ab2a70
commit
8c9560d288
@ -25,6 +25,12 @@ class FieldList extends ArrayList {
|
|||||||
* @todo Documentation
|
* @todo Documentation
|
||||||
*/
|
*/
|
||||||
protected $containerField;
|
protected $containerField;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array Ordered list of regular expressions,
|
||||||
|
* see {@link setTabPathRewrites()}.
|
||||||
|
*/
|
||||||
|
protected $tabPathRewrites = array();
|
||||||
|
|
||||||
public function __construct($items = array()) {
|
public function __construct($items = array()) {
|
||||||
if (!is_array($items) || func_num_args() > 1) {
|
if (!is_array($items) || func_num_args() > 1) {
|
||||||
@ -255,6 +261,9 @@ class FieldList extends ArrayList {
|
|||||||
* @return Tab The found or newly created Tab instance
|
* @return Tab The found or newly created Tab instance
|
||||||
*/
|
*/
|
||||||
public function findOrMakeTab($tabName, $title = null) {
|
public function findOrMakeTab($tabName, $title = null) {
|
||||||
|
// Backwards compatibility measure: Allow rewriting of outdated tab paths
|
||||||
|
$tabName = $this->rewriteTabPath($tabName);
|
||||||
|
|
||||||
$parts = explode('.',$tabName);
|
$parts = explode('.',$tabName);
|
||||||
$last_idx = count($parts) - 1;
|
$last_idx = count($parts) - 1;
|
||||||
// We could have made this recursive, but I've chosen to keep all the logic code within FieldList rather than add it to TabSet and Tab too.
|
// We could have made this recursive, but I've chosen to keep all the logic code within FieldList rather than add it to TabSet and Tab too.
|
||||||
@ -291,6 +300,7 @@ class FieldList extends ArrayList {
|
|||||||
* @todo Implement similiarly to dataFieldByName() to support nested sets - or merge with dataFields()
|
* @todo Implement similiarly to dataFieldByName() to support nested sets - or merge with dataFields()
|
||||||
*/
|
*/
|
||||||
public function fieldByName($name) {
|
public function fieldByName($name) {
|
||||||
|
$name = $this->rewriteTabPath($name);
|
||||||
if(strpos($name,'.') !== false) list($name, $remainder) = explode('.',$name,2);
|
if(strpos($name,'.') !== false) list($name, $remainder) = explode('.',$name,2);
|
||||||
else $remainder = null;
|
else $remainder = null;
|
||||||
|
|
||||||
@ -555,6 +565,59 @@ class FieldList extends ArrayList {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ordered list of regular expressions
|
||||||
|
* matching a tab path, to their rewrite rule (through preg_replace()).
|
||||||
|
* Mainly used for backwards compatibility.
|
||||||
|
* Ensure that more specific rules are placed earlier in the list,
|
||||||
|
* and that tabs with children are accounted for in the rule sets.
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
* $fields->setTabPathRewriting(array(
|
||||||
|
* // Rewrite specific innermost tab
|
||||||
|
* '/^Root\.Content\.Main$/' => 'Root.Content',
|
||||||
|
* // Rewrite all innermost tabs
|
||||||
|
* '/^Root\.Content\.([^.]+)$/' => 'Root.\\1',
|
||||||
|
* ));
|
||||||
|
*
|
||||||
|
* @param array $rewrites
|
||||||
|
*/
|
||||||
|
public function setTabPathRewrites($rewrites) {
|
||||||
|
$this->tabPathRewrites = $rewrites;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getTabPathRewrites() {
|
||||||
|
return $this->tabPathRewrites;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Support function for backwards compatibility purposes.
|
||||||
|
* Caution: Volatile API, might be removed in 3.1 or later.
|
||||||
|
*
|
||||||
|
* @param String $tabname Path to a tab, e.g. "Root.Content.Main"
|
||||||
|
* @return String Rewritten path, based on {@link tabPathRewrites}
|
||||||
|
*/
|
||||||
|
protected function rewriteTabPath($name) {
|
||||||
|
$isRunningTest = (class_exists('SapphireTest', false) && SapphireTest::is_running_test());
|
||||||
|
foreach($this->getTabPathRewrites() as $regex => $replace) {
|
||||||
|
if(preg_match($regex, $name)) {
|
||||||
|
$newName = preg_replace($regex, $replace, $name);
|
||||||
|
Deprecation::notice('3.0.0', sprintf(
|
||||||
|
'Using outdated tab path "%s", please use the new location "%s" instead',
|
||||||
|
$name,
|
||||||
|
$newName
|
||||||
|
));
|
||||||
|
return $newName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// No match found, return original path
|
||||||
|
return $name;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default template rendering of a FieldList will concatenate all FieldHolder values.
|
* Default template rendering of a FieldList will concatenate all FieldHolder values.
|
||||||
*/
|
*/
|
||||||
|
@ -789,5 +789,66 @@ class FieldListTest extends SapphireTest {
|
|||||||
$this->assertNotNull($visible->dataFieldByName('D2'));
|
$this->assertNotNull($visible->dataFieldByName('D2'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function testRewriteTabPath() {
|
||||||
|
$fields = new FieldList(
|
||||||
|
new Tabset("Root",
|
||||||
|
$tab1Level1 = new Tab("Tab1Level1",
|
||||||
|
$tab1Level2 = new Tab("Tab1Level2"),
|
||||||
|
$tab2Level2 = new Tab("Tab2Level2")
|
||||||
|
),
|
||||||
|
$tab2Level1 = new Tab("Tab2Level1")
|
||||||
|
)
|
||||||
|
);
|
||||||
|
$fields->setTabPathRewrites(array(
|
||||||
|
'/Root\.Tab1Level1\.([^.]+)$/' => 'Root.Tab1Level1Renamed.\\1',
|
||||||
|
'/Root\.Tab1Level1$/' => 'Root.Tab1Level1Renamed',
|
||||||
|
));
|
||||||
|
$method = new ReflectionMethod($fields, 'rewriteTabPath');
|
||||||
|
$method->setAccessible(true);
|
||||||
|
$this->assertEquals(
|
||||||
|
'Root.Tab1Level1Renamed',
|
||||||
|
$method->invoke($fields, 'Root.Tab1Level1Renamed'),
|
||||||
|
"Doesn't rewrite new name"
|
||||||
|
);
|
||||||
|
$this->assertEquals(
|
||||||
|
'Root.Tab1Level1Renamed',
|
||||||
|
$method->invoke($fields, 'Root.Tab1Level1'),
|
||||||
|
'Direct aliasing on toplevel'
|
||||||
|
);
|
||||||
|
$this->assertEquals(
|
||||||
|
'Root.Tab1Level1Renamed.Tab1Level2',
|
||||||
|
$method->invoke($fields, 'Root.Tab1Level1.Tab1Level2'),
|
||||||
|
'Indirect aliasing on toplevel'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function testRewriteTabPathFindOrMakeTab() {
|
||||||
|
$fields = new FieldList(
|
||||||
|
new Tabset("Root",
|
||||||
|
$tab1Level1 = new Tab("Tab1Level1Renamed",
|
||||||
|
$tab1Level2 = new Tab("Tab1Level2"),
|
||||||
|
$tab2Level2 = new Tab("Tab2Level2")
|
||||||
|
),
|
||||||
|
$tab2Level1 = new Tab("Tab2Level1")
|
||||||
|
)
|
||||||
|
);
|
||||||
|
$fields->setTabPathRewrites(array(
|
||||||
|
'/Root\.Tab1Level1\.([^.]+)$/' => 'Root.Tab1Level1Renamed.\\1',
|
||||||
|
'/Root\.Tab1Level1$/' => 'Root.Tab1Level1Renamed',
|
||||||
|
));
|
||||||
|
|
||||||
|
$this->assertEquals($tab1Level1, $fields->findOrMakeTab('Root.Tab1Level1'),
|
||||||
|
'findOrMakeTab() with toplevel tab under old name'
|
||||||
|
);
|
||||||
|
$this->assertEquals($tab1Level1, $fields->findOrMakeTab('Root.Tab1Level1Renamed'),
|
||||||
|
'findOrMakeTab() with toplevel tab under new name'
|
||||||
|
);
|
||||||
|
$this->assertEquals($tab1Level2, $fields->findOrMakeTab('Root.Tab1Level1.Tab1Level2'),
|
||||||
|
'findOrMakeTab() with nested tab under old parent tab name'
|
||||||
|
);
|
||||||
|
$this->assertEquals($tab1Level2, $fields->findOrMakeTab('Root.Tab1Level1Renamed.Tab1Level2'),
|
||||||
|
'findOrMakeTab() with nested tab under new parent tab name'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user