TYPO3 - 404 custom page never display, only 400 - typo3

Below my website configuration :
TYPO3 6.2
RealURL
I have a www.mysite.com/404/ page, that's work perfectly.
BUT TYPO3 never redirect to it when an error appears, I get a 400 Bad Request page.
I already did :
edit my localconf.php
edit via the "All Configuration" back-end module
Edit the realurl_conf.php
What am I missing ?

I always have something like (in realurl_conf.php):
$TYPO3_CONF_VARS['FE']['pageNotFound_handling'] = 'index.php?id=35';
$TYPO3_CONF_VARS['FE']['pageNotFound_handling_statheader'] = 'HTTP/1.0 404 Not Found';
Hope it helps :)
UPDATE:
<?php
$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['realurl'] = array (
'_DEFAULT' => array (
'init' => array (
'enableCHashCache' => '1',
'appendMissingSlash' => 'ifNotFile',
'enableUrlDecodeCache' => '1',
'enableUrlEncodeCache' => '1',
),
'redirects' => array (
),
'preVars' => array (
'0' => array (
'GETvar' => 'no_cache',
'valueMap' => array (
'nc' => '1',
),
'noMatch' => 'bypass'
),
'1' => array (
'GETvar' => 'L',
'valueMap' => array (
'nl' => '0',
'en' => '2',
'de' => '1',
),
'noMatch' => 'bypass',
),
'2' => array (
'GETvar' => 'lang',
'valueMap' => array (
'de' => 'de',
'en' => 'en',
'nl' => 'nl'
),
'noMatch' => 'bypass',
),
),
'pagePath' => array (
'type' => 'user',
'userFunc' => 'EXT:realurl/class.tx_realurl_advanced.php:&tx_realurl_advanced->main',
'spaceCharacter' => '-',
'languageGetVar' => 'L',
'expireDays' => '7',
'rootpage_id' => $rootpageId,
),
'fixedPostVars' => array(
'newsDetailConfiguration' => array(
array(
'GETvar' => 'tx_news_pi1[action]',
'valueMap' => array(
'detail' => '',
),
'noMatch' => 'bypass'
),
array(
'GETvar' => 'tx_news_pi1[controller]',
'valueMap' => array(
'News' => '',
),
'noMatch' => 'bypass'
),
array(
'GETvar' => 'tx_news_pi1[news]',
'lookUpTable' => array(
'table' => 'tx_news_domain_model_news',
'id_field' => 'uid',
'alias_field' => 'title',
'addWhereClause' => ' AND NOT deleted',
'useUniqueCache' => 1,
'useUniqueCache_conf' => array(
'strtolower' => 1,
'spaceCharacter' => '-'
),
'languageGetVar' => 'L',
'languageExceptionUids' => '',
'languageField' => 'sys_language_uid',
'transOrigPointerField' => 'l10n_parent',
'autoUpdate' => 1,
'expireDays' => 180,
)
)
),
'newsCategoryConfiguration' => array(
array(
'GETvar' => 'tx_news_pi1[overwriteDemand][categories]',
'lookUpTable' => array(
'table' => 'sys_category',
'id_field' => 'uid',
'alias_field' => 'title',
'addWhereClause' => ' AND NOT deleted',
'useUniqueCache' => 1,
'useUniqueCache_conf' => array(
'strtolower' => 1,
'spaceCharacter' => '-'
)
)
)
),
'newsTagConfiguration' => array(
array(
'GETvar' => 'tx_news_pi1[overwriteDemand][tags]',
'lookUpTable' => array(
'table' => 'tx_news_domain_model_tag',
'id_field' => 'uid',
'alias_field' => 'title',
'addWhereClause' => ' AND NOT deleted',
'useUniqueCache' => 1,
'useUniqueCache_conf' => array(
'strtolower' => 1,
'spaceCharacter' => '-'
)
)
)
),
'CompanyDetailConfiguration' => array(
array(
'GETvar' => 'tx_dswmediacompanies_companies[action]',
'valueMap' => array(
'detail' => '',
),
'noMatch' => 'bypass'
),
array(
'GETvar' => 'tx_dswmediacompanies_companies[controller]',
'valueMap' => array(
'Companies' => '',
),
'noMatch' => 'bypass'
),
array(
'GETvar' => 'tx_dswmediacompanies_companies[uid]',
'lookUpTable' => array(
'table' => 'tx_dswmediacompanies_domain_model_companies',
'id_field' => 'uid',
'alias_field' => 'name',
'addWhereClause' => ' AND NOT deleted',
'useUniqueCache' => 1,
'useUniqueCache_conf' => array(
'strtolower' => 1,
'spaceCharacter' => '-'
),
'languageGetVar' => 'L',
'languageExceptionUids' => '',
'languageField' => 'sys_language_uid',
'transOrigPointerField' => 'l10n_parent',
'autoUpdate' => 1,
'expireDays' => 180,
)
)
),
'15' => 'newsDetailConfiguration',
),
'postVarSets' => array (
'_DEFAULT' => array (
'b' => array (
array (
'GETvar' => 'tx_example[uid]',
'lookUpTable' => array (
'table' => 'tx_dswmediacompanies_domain_model_companies',
'id_field' => 'uid',
'alias_field' => 'name',
'addWhereClause' => ' AND NOT deleted',
'useUniqueCache' => '1',
'useUniqueCache_conf' => array (
'strtolower' => '1',
'spaceCharacter' => '-',
),
),
),
array (
'GETvar' => 'tx_example[action]',
'lookUpTable' => array (
'table' => 'tx_example_domain_model_companies',
'id_field' => 'uid',
'alias_field' => 'name',
'addWhereClause' => ' AND NOT deleted',
'useUniqueCache' => '1',
'useUniqueCache_conf' => array (
'strtolower' => '1',
'spaceCharacter' => '-',
),
),
),
),
'controller' => array(
array(
'GETvar' => 'tx_news_pi1[action]',
'noMatch' => 'bypass'
),
array(
'GETvar' => 'tx_news_pi1[controller]',
'noMatch' => 'bypass'
)
),
'dateFilter' => array(
array(
'GETvar' => 'tx_news_pi1[overwriteDemand][year]',
),
array(
'GETvar' => 'tx_news_pi1[overwriteDemand][month]',
),
),
'page' => array(
array(
'GETvar' => 'tx_news_pi1[#widget_0][currentPage]',
),
),
// 'news' => array (
// 0 => array (
// 'GETvar' => 'tx_news_pi1[news]',
// 'lookUpTable' => array (
// 'table' => 'tx_news_domain_model_news',
// 'id_field' => 'uid',
// 'alias_field' => 'title',
// 'useUniqueCache' => 1,
// 'useUniqueCache_conf' => array (
// 'strtolower' => 1,
// 'spaceCharacter' => '-',
// ),
// ),
// ),
// ),
),
),
'fileName' => array (
'defaultToHTMLsuffixOnPrev' => false,
'index' => array (
'rss.xml' => array (
'keyValues' => array (
'type' => '100',
),
),
'rss2.xml' => array (
'keyValues' => array (
'type' => '101',
),
),
'rdf.xml' => array (
'keyValues' => array (
'type' => '102',
),
),
'atom.xml' => array (
'keyValues' => array (
'type' => '103',
),
),
'sitemap.xml' => array (
'keyValues' => array (
'type' => '841132',
),
),
'robots.txt' => array (
'keyValues' => array (
'type' => '841133',
),
),
),
),
),
);
switch($_SERVER['HTTP_HOST']) {
case 'example.nl':
case 'www.example.nl':
$TYPO3_CONF_VARS['FE']['pageNotFound_handling'] = 'index.php?id=4';
$TYPO3_CONF_VARS['FE']['pageNotFound_handling_statheader'] = 'HTTP/1.0 404 Not Found';
$rootpageId = 1;
break;
case 'othersite.nl':
case 'www.othersite.nl':
$TYPO3_CONF_VARS['FE']['pageNotFound_handling'] = 'index.php?id=68';
$TYPO3_CONF_VARS['FE']['pageNotFound_handling_statheader'] = 'HTTP/1.0 404 Not Found';
$rootpageId = 23;
break;
}
?>

Related

Flutter syncfusion bug with StackedColumnSeries

Why do all the elements in the chart not start from zero, but move to the top?
I want to have my own data for each month (text) and they are separated. They can be grouped together, they can also be single.
Code:
SfCartesianChart(
primaryXAxis: CategoryAxis(),
primaryYAxis: NumericAxis(minimum: 0),
series: <ChartSeries>[
StackedColumnSeries<TaskChartInfo, String>(
groupName: 'Group A',
dataSource: chartData,
xValueMapper: (TaskChartInfo sales, _) => "Сент",
yValueMapper: (TaskChartInfo sales, _) => 45),
StackedColumnSeries<TaskChartInfo, String>(
groupName: 'Group B',
dataSource: chartData,
xValueMapper: (TaskChartInfo sales, _) => "Сент",
yValueMapper: (TaskChartInfo sales, _) => 32),
StackedColumnSeries<TaskChartInfo, String>(
groupName: 'Group B',
dataSource: chartData,
name: "Авг",
enableTooltip: true,
xValueMapper: (TaskChartInfo sales, _) => "Авг",
yValueMapper: (TaskChartInfo sales, _) => 45),
StackedColumnSeries<TaskChartInfo, String>(
groupName: 'Group A',
dataSource: chartData,
xValueMapper: (TaskChartInfo sales, _) => "Дек",
yValueMapper: (TaskChartInfo sales, _) => 100),
StackedColumnSeries<TaskChartInfo, String>(
groupName: 'Group B',
dataSource: chartData,
xValueMapper: (TaskChartInfo sales, _) => "Окт",
yValueMapper: (TaskChartInfo sales, _) => 21)
])
Thank you in advance for the answer!
While grouping the stacked series, the series x-values should be same for grouping series. For example, stacked series1 and series 2 have groupName as 'Group A' means, both series should have same x values.
You can achieve the requirement by changing the groupName value.
We have prepared and shared a code snippet below for your reference.
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: SfCartesianChart(
primaryXAxis: CategoryAxis(),
primaryYAxis: NumericAxis(minimum: 0),
series: <ChartSeries>[
StackedColumnSeries<TaskChartInfo, String>(
groupName: 'Group A',
dataSource: chartData,
color: Colors.blueAccent,
xValueMapper: (TaskChartInfo sales, _) => "Сент",
yValueMapper: (TaskChartInfo sales, _) => 45),
StackedColumnSeries<TaskChartInfo, String>(
groupName: 'Group A',
dataSource: chartData,
color: Colors.pinkAccent,
xValueMapper: (TaskChartInfo sales, _) => "Сент",
yValueMapper: (TaskChartInfo sales, _) => 32),
StackedColumnSeries<TaskChartInfo, String>(
groupName: 'Group B',
dataSource: chartData,
name: "Авг",
enableTooltip: true,
color: Colors.redAccent,
xValueMapper: (TaskChartInfo sales, _) => "Авг",
yValueMapper: (TaskChartInfo sales, _) => 45),
StackedColumnSeries<TaskChartInfo, String>(
groupName: 'Group C',
dataSource: chartData,
color: Colors.orangeAccent,
xValueMapper: (TaskChartInfo sales, _) => "Дек",
yValueMapper: (TaskChartInfo sales, _) => 100),
StackedColumnSeries<TaskChartInfo, String>(
groupName: 'Group D',
dataSource: chartData,
color: Colors.greenAccent,
xValueMapper: (TaskChartInfo sales, _) => "Окт",
yValueMapper: (TaskChartInfo sales, _) => 21)
],
)),
);
}
}
class TaskChartInfo {
TaskChartInfo(this.name, this.value);
final String name;
final int value;
}
List<TaskChartInfo> chartData = <TaskChartInfo>[
TaskChartInfo("Сент", 45),
TaskChartInfo("Авг", 32),
TaskChartInfo("Дек", 100),
TaskChartInfo("Окт", 100),
];
ScreenShot:

Editable DataTable only works when being the only Widget in the Scaffold body

I have created a custom DataTable, which is editable in a StatefulWidget. The DataTable only loads and works, when there are no other widgets in the Scaffold body property. For example, when I try to add the DataTable in a Column it won't load.
Any help is appreciated, here's the source code of the main.dart, in case that helps.
import 'package:flutter/material.dart';
void main() {
runApp(
MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Abiturwahlbogen'),
centerTitle: true,
),
body:
Column(
children: const <Widget> [
KursListe(),
],
),
),
),
);
}
class KursListe extends StatefulWidget {
const KursListe({Key? key}) : super(key: key);
#override
State<KursListe> createState() => KursListeState();
}
class KursListeState extends State<KursListe> {
final List<Map> _books = [
{'Kategorie': 'LNG', 'title': 'Deutsch', 'id': 'D', 'LNGFolge': '', 'LNGDauer': '', 'EF.1': '', 'EF.2': '', 'Q1.1': '', 'Q1.2': '', 'Q2.1': '', 'Q2.2': '', 'ABI': '',},
{'Kategorie': 'LNG', 'title': 'Englisch', 'id': 'E', 'LNGFolge': '1', 'LNGDauer': '5', 'EF.1': '', 'EF.2': '', 'Q1.1': '', 'Q1.2': '', 'Q2.1': '', 'Q2.2': '', 'ABI': '',},
{'Kategorie': 'NW', 'title': 'Mathematik', 'id': 'M', 'LNGFolge': '', 'LNGDauer': '', 'EF.1': '', 'EF.2': '', 'Q1.1': '', 'Q1.2': '', 'Q2.1': '', 'Q2.2': '', 'ABI': '',},
{'Kategorie': 'NW', 'title': 'Physik', 'id': 'PH', 'LNGFolge': '', 'LNGDauer': '', 'EF.1': '', 'EF.2': '', 'Q1.1': '', 'Q1.2': '', 'Q2.1': '', 'Q2.2': '', 'ABI': '',},
{'Kategorie': 'GW', 'title': 'Erdkunde', 'id': 'EK', 'LNGFolge': '', 'LNGDauer': '', 'EF.1': '', 'EF.2': '', 'Q1.1': '', 'Q1.2': '', 'Q2.1': '', 'Q2.2': '', 'ABI': '',},
{'Kategorie': 'GW', 'title': 'Geschichte', 'id': 'GE', 'LNGFolge': '', 'LNGDauer': '', 'EF.1': '', 'EF.2': '', 'Q1.1': '', 'Q1.2': '', 'Q2.1': '', 'Q2.2': '', 'ABI': '',},
];
#override
Widget build(BuildContext context) {
return SizedBox(
child: ListView(
children: [_createDataTable()],
));
}
DataTable _createDataTable() {
return DataTable( columnSpacing: 30.0, columns: _createColumns(), rows: _createRows());
}
List<DataColumn> _createColumns() {
return [
const DataColumn(label: Text('Ktg')),
const DataColumn(label: Text('Fach')),
const DataColumn(label: Text('Kürzel')),
const DataColumn(label: Text('Spr-Folge')),
const DataColumn(label: Text('Ab Jg.')),
const DataColumn(label: Text('EF.1')),
const DataColumn(label: Text('EF.2')),
const DataColumn(label: Text('Q1.1')),
const DataColumn(label: Text('Q1.2')),
const DataColumn(label: Text('Q2.1')),
const DataColumn(label: Text('Q2.2')),
const DataColumn(label: Text('Abitur'))
];
}
List<DataRow> _createRows() {
return _books
.map((book) => DataRow(cells: [
DataCell(Text(book['Kategorie'])),
DataCell(Text(book['title'])),
DataCell(Text(book['id'])),
DataCell(Text(book['LNGFolge'])),
DataCell(Text(book['LNGDauer'])),
DataCell(TextButton(onPressed: () {
setState(() {
book['EF.1']= clickConditions(book['EF.1']);
});
},
child: Text(book['EF.1']),
),),
DataCell(TextButton(onPressed: () {
setState(() {
book['EF.2']= clickConditions(book['EF.2']);
});
},
child: Text(book['EF.2']),
),),
DataCell(TextButton(onPressed: () {
setState(() {
book['Q1.1']= clickConditions(book['Q1.1']);
});
},
child: Text(book['Q1.1']),
),),
DataCell(TextButton(onPressed: () {
setState(() {
book['Q1.2']= clickConditions(book['Q1.2']);
});
},
child: Text(book['Q1.2']),
),),
DataCell(TextButton(onPressed: () {
setState(() {
book['Q2.1']= clickConditions(book['Q2.1']);
});
},
child: Text(book['Q2.1']),
),),
DataCell(TextButton(onPressed: () {
setState(() {
book['Q2.2']= clickConditions(book['Q2.2']);
});
},
child: Text(book['Q2.2']),
),),
DataCell(TextButton(onPressed: () {
setState(() {
book['ABI']= clickConditions(book['ABI']);
});
},
child: Text(book['ABI']),
),),
]))
.toList();
}
clickConditions (String s1) {
if (s1=='') {
s1 = 'M';
}
else if (s1=='M') {
s1 = 'S';
}
else {
s1 = '';
}
return s1;
}
}
I have tried to use different Widgets like Containers, but the problem seems to be that the DataTable is not compatible.

How to populate a Flutter dropdown box

How do I populate a Flutter Dropdown box?. I have the following key value pair data.
I want to show the user the value (name) and on click get the ID value
[
{'Id': '1', 'Name': 'item 1'}
{ 'Id': '2', 'Name': 'item 2' }
{ 'Id': '3', 'Name': 'item 3' }
]
Use the map function against the list to generate what you need.
final myMapList = [
{'Id': '1', 'Name': 'item 1'},
{ 'Id': '2', 'Name': 'item 2' },
{ 'Id': '3', 'Name': 'item 3' },
];
String _newValue = myMapList[0]['Id'];
...
DropdownButton<String>(
value: _newValue,
onChanged: (String newValue) {
setState(() {
_newValue = newValue;
});
},
items: myMapList.map(
(Map item) {
return DropdownMenuItem<String>(
value: item['Id'],
child: Text(
item['Name'],
);
}).toList(),),

ion-picker can't get role of button clicked

I can’t seem to get the button role from ion-picker.
I need to know if it was ‘done’ or ‘cancel’.
Any ideas why this is?
I am just padding this out as stackoverflow is asking me to write some more details as my post is mostly code.
They data is just coming back as follows:
{data: undefined, role: undefined}
let opts: PickerOptions = {
cssClass: 'time-picker',
buttons: [
{
text: 'Cancel',
role: 'cancel'
},
{
text: 'Done',
role: 'done'
}
],
columns: [
{
name: 'hour',
options: [
{ text: '01', value: '01' },
{ text: '02', value: '02' },
{ text: '03', value: '03' },
{ text: '04', value: '04' },
{ text: '05', value: '05' },
{ text: '06', value: '06' },
{ text: '07', value: '07' },
{ text: '08', value: '08' },
{ text: '09', value: '09' },
{ text: '10', value: '10' },
{ text: '11', value: '11' },
{ text: '12', value: '12' },
{ text: '13', value: '13' },
{ text: '14', value: '14' },
{ text: '15', value: '15' },
{ text: '16', value: '16' },
{ text: '17', value: '17' },
{ text: '18', value: '18' },
{ text: '19', value: '19' },
{ text: '20', value: '20' },
{ text: '21', value: '21' },
{ text: '22', value: '22' },
{ text: '23', value: '23' },
{ text: '24', value: '24' }
]
},
{
name: 'minute',
options: [
{ text: '00', value: '00' },
{ text: '15', value: '15' },
{ text: '30', value: '30' },
{ text: '45', value: '45' }
]
}
]
};
const picker = await this.pickerCtrl.create(opts);
picker.present();
picker.onDidDismiss().then(async data => {
console.log(data);
const hour = await picker.getColumn('hour');
const minute = await picker.getColumn('minute');
this.onChangeFinishTime((hour.options[hour.selectedIndex].value) as number, minute.options[minute.selectedIndex].value as number);
this.isPickerOpen = false;
});
let pickerAction;
const opts: PickerOptions = {
cssClass: 'time-picker',
buttons: [
{
text: 'Cancel',
role: 'cancel',
handler: value => {
pickerAction = 'cancel';
}
},
{
text: 'Done',
role: 'done',
handler: value => {
pickerAction = 'done';
}
}
],
columns: [
...
const picker = await this.pickerCtrl.create(opts);
picker.present();
picker.onDidDismiss().then(async data => {
if (pickerAction === 'done') {
const hour = await picker.getColumn('hour');
const minute = await picker.getColumn('minute');
this.onChangeFinishTime((hour.options[hour.selectedIndex].value) as number, minute.options[minute.selectedIndex].value as number);
}
this.isPickerOpen = false;
});
You need to move the logic from when the event onDidDismiss() is triggered (which means that the popover has disappeared, regardless of what action made it disappear) to the actual action of clicking the Done button.
This what the handler on Done does here, telling to set the value of the selected entry in the referenced column upon the popover dismissing as a consequence of clicking the Done button.
{data: undefined, role: undefined}
let opts: PickerOptions = {
cssClass: 'time-picker',
buttons: [
{
text: 'Cancel',
role: 'cancel'
},
{
text: 'Done',
handler: () => {
picker.dismiss().then(async data => {
console.log(data);
const hour = await picker.getColumn('hour');
const minute = await picker.getColumn('minute');
this.onChangeFinishTime((hour.options[hour.selectedIndex].value) as number, minute.options[minute.selectedIndex].value as number);
this.isPickerOpen = false;
});
}
}
],
columns: [
{
name: 'hour',
options: [
{ text: '01', value: '01' },
{ text: '02', value: '02' },
{ text: '03', value: '03' },
{ text: '04', value: '04' },
{ text: '05', value: '05' },
{ text: '06', value: '06' },
{ text: '07', value: '07' },
{ text: '08', value: '08' },
{ text: '09', value: '09' },
{ text: '10', value: '10' },
{ text: '11', value: '11' },
{ text: '12', value: '12' },
{ text: '13', value: '13' },
{ text: '14', value: '14' },
{ text: '15', value: '15' },
{ text: '16', value: '16' },
{ text: '17', value: '17' },
{ text: '18', value: '18' },
{ text: '19', value: '19' },
{ text: '20', value: '20' },
{ text: '21', value: '21' },
{ text: '22', value: '22' },
{ text: '23', value: '23' },
{ text: '24', value: '24' }
]
},
{
name: 'minute',
options: [
{ text: '00', value: '00' },
{ text: '15', value: '15' },
{ text: '30', value: '30' },
{ text: '45', value: '45' }
]
}
]
};
const picker = await this.pickerCtrl.create(opts);
picker.present();

Zend 2 Framework Routing

I'm struggling with this problem and can't get over it.
What I want to achieve is a route like this: /rolepermission[/:roleid]/permissions[/:permissionid][/action/:action]
Currently I came up with something like this:
'rolepermission' => array(
'type' => 'literal',
'options' => array(
'route' => '/rolepermission',
'constraints' => array(),
'defaults' => array(
'controller' => 'My\Controller\RolePermission',
'action' => 'index',
),
),
'may_terminate' => true,
'child_routes' => array(
'rolepermissionroleid' => array(
'type' => 'segment',
'options' => array(
'route' => '/[:roleid]',
'constraints' => array(
'roleid' => '[a-zA-Z][a-zA-Z0-9_-]*',
),
'defaults' => array(
'action' => 'detail',
),
),
'may_terminate' => true,
'child_routes' => array(
'rolepermissionpermissions' => array(
'type' => 'literal',
'options' => array(
'route' => '/permissions',
'constraints' => array(),
'defaults' => array(
'action' => 'index'
),
),
'may_terminate' => true,
'child_routes' => array(
'rolepermissionpermissionid' => array(
'type' => 'segment',
'options' => array(
'route' => '/[:permissionid]',
'constraints' => array(
'permissionid' => '[a-zA-Z][a-zA-Z0-9_-]*',
),
'defaults' => array(
),
),
'may_terminate' => true,
'child_routes' => array(
'rolepermissionaction' => array(
'type' => 'segment',
'options' => array(
'route' => '/action/[:action]',
'constraints' => array(
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
),
'defaults' => array(
'action' => 'index'
),
),
'may_terminate' => false,
'child_routes' => array(),
),
),
),
),
),
),
),
),
),
When routing to /rolepermission/permissions I constantly get 'permissions' substituted for :roleid. I'm expecting here nothing to be substituted due to not passing a roleid. What am I doing wrong?
Thanks in advance,
cheers
Solved the problem temporarily by adapting the 'rolepermissionpermissions' child route as following:
'rolepermission' => array(
'type' => 'segment',
'options' => array(
'route' => '/rolepermission',
'constraints' => array(),
'defaults' => array(
'controller' => 'My\Controller\RolePermission',
'action' => 'index',
),
),
'may_terminate' => true,
'child_routes' => array(
'rolepermissionroleid' => array(
'type' => 'segment',
'options' => array(
'route' => '/:roleid',
'constraints' => array(
'roleid' => '[a-zA-Z][a-zA-Z0-9_-]*',
),
'defaults' => array(
'action' => 'detail'
),
),
'may_terminate' => true,
'child_routes' => array(
'rolepermissionpermissionid' => array(
'type' => 'segment',
'options' => array(
'route' => '[/permission/:permissionid]',
'constraints' => array(
'permissionid' => '[a-zA-Z][a-zA-Z0-9_-]*',
),
'defaults' => array(
'action' => 'detail',
),
),
'may_terminate' => true,
'child_routes' => array(
'rolepermissionaction' => array(
'type' => 'segment',
'options' => array(
'route' => '/action/:action',
'constraints' => array(
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
),
'defaults' => array(
'action' => 'detail'
),
),
'may_terminate' => true,
'child_routes' => array(),
),
),
),
),
),
),
),
Although it's indeed not the best solution, this works for now.