mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02: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
|
||||
*/
|
||||
protected $containerField;
|
||||
|
||||
/**
|
||||
* @var array Ordered list of regular expressions,
|
||||
* see {@link setTabPathRewrites()}.
|
||||
*/
|
||||
protected $tabPathRewrites = array();
|
||||
|
||||
public function __construct($items = array()) {
|
||||
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
|
||||
*/
|
||||
public function findOrMakeTab($tabName, $title = null) {
|
||||
// Backwards compatibility measure: Allow rewriting of outdated tab paths
|
||||
$tabName = $this->rewriteTabPath($tabName);
|
||||
|
||||
$parts = explode('.',$tabName);
|
||||
$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.
|
||||
@ -291,6 +300,7 @@ class FieldList extends ArrayList {
|
||||
* @todo Implement similiarly to dataFieldByName() to support nested sets - or merge with dataFields()
|
||||
*/
|
||||
public function fieldByName($name) {
|
||||
$name = $this->rewriteTabPath($name);
|
||||
if(strpos($name,'.') !== false) list($name, $remainder) = explode('.',$name,2);
|
||||
else $remainder = null;
|
||||
|
||||
@ -555,6 +565,59 @@ class FieldList extends ArrayList {
|
||||
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.
|
||||
*/
|
||||
|
@ -789,5 +789,66 @@ class FieldListTest extends SapphireTest {
|
||||
$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…
Reference in New Issue
Block a user