Skip to content

Instantly share code, notes, and snippets.

@larscwallin
Created September 14, 2011 14:02
Show Gist options
  • Save larscwallin/1216634 to your computer and use it in GitHub Desktop.
Save larscwallin/1216634 to your computer and use it in GitHub Desktop.
simplx.controller, now with url routing
SIMPLX Controller V0.7
UPDATE 111109
NEW FEATURES:
- Added a whole bunch of modResource fields to the Request object. This means that you can route on stuff like:
pagetitle
template
parent
template
createdby
createdon
editedby
editedon
class_key
uri
content_type
published
pub_date
unpub_date
alias
isfolder
type
templatename
UPDATE 111028
NEW FEATURES:
- The Plugin now supports Property Sets
This is very cool as it makes it possible to run different configurations, e.g. Routing Tables, at
different System Events. The Plugin Property Set has the exact same signature as the Snippet set.
UPDATE 111017
NEW FEATURES:
- Routing Instructions now take default parameters. Very handy!
Example: "GET":["modapi.modchunk.get",{"myproperty":"My default value"}]
The previous, simple Instruction assignment of course still works
"GET":"modapi.modchunk.default"
UPDATE 111015
NEW FEATURES:
- Now supports regular expressions :D By default, the separator which tells the controller to use regex is "?". See the REST table below for an example.
- You no longer have to specify a default routing constraint. If none is found the controller defaults to using the first constraint item in the routing table.
- Loads of fixes :)
* IMPORTANT: You need to get the new SimplxRequest Gist also (https://gist.github.com/1216951).
UPDATE 111005
NEW FEATURES:
- Better structure to the Routing Table definition by adding named object collections ("constraints","rules","conditions") instead of implicit type naming.
This means that you can basically encode the json and get this interface:
$context = $routingtable->constraints->web;
$header = $context->header;
if($header->rules->content-type){
print 'Hey, I can route on Content-Type!';
}
I will however shortly make a proper OO PHP Class to manage the Routing Tables.
FIXES:
- Default routing was broken. I have done a whole bunch of unit testing cases and it seems to be working now.
<html>
<head>
</head>
<body>
<h1>SIMPLX Controller 0.7</h1>
<h3>About</h3>
<p>
</p>
</body>
</html>
{
"contexts":{
"web":{
"constraints":{
"header":{
"rules":{
"header:content-type":{
"conditions":{
"text/xml":"modapi.modchunk.default"
}
}
}
}
}
}
}
}
{
"contexts":{
"web":{
"constraints":{
"query.id=1":{
"rules":{
"method":{
"conditions":{
"GET":"modapi.modchunk.get",
"*":"modapi.modchunk.default"
}
},
"*":"modapi.modchunk.default"
},
"*":"modapi.modchunk.default"
},
"*":"modapi.modchunk.default"
}
}
}
}
{
"contexts":{
"web":{
"constraints":{
"query":{
"rules":{
"query.id":{
"conditions":{
"1":"modapi.modchunk.get",
"2":"modapi.modchunk.update"
}
}
}
}
}
}
}
}
{
"contexts":{
"web":{
"constraints":{
"path?/modChunk/i":{
"rules":{
"method":{
"conditions":{
"GET":"modapi.modchunk.get",
"*":["modapi.modchunk.default",{"activity":"defaultCondition"}]
}
},
"*":["modapi.modchunk.default",{"activity":"defaultRule"}]
}
},
"*":["modapi.constraint.default",{"activity":"defaultConstraint"}]
}
}
}
}
<?php
/*
MODx Snippet simplx.controller
Version 111108
*/
require_once($modx->getOption('core_path').'components/simplx/request/simplx.request.php');
$activeProcesses = array();
$parseError = false;
$routingTableObject = isset($routingTableObject) ? $routingTableObject : false;
$requestObject = isset($requestObject) ? $requestObject : SimplxRequest::getRequest();
$fielddelimiter = isset($fielddelimiter) ? $fielddelimiter : '.';
$valuedelimiter = isset($valuedelimiter) ? $valuedelimiter : '=';
$patterndelimiter = isset($patterndelimiter) ? $patterndelimiter : '?';
$routingConstraintField = '';
$constraintRoutingRules = '';
$defaultruletoken = isset($defaultruletoken) ? $defaultruletoken : '*';
$defaultconstrainttoken = isset($defaultconstrainttoken) ? $defaultconstrainttoken : '*';
$currentResource = $modx->resource;
$currentResourceArray = array();
SimplxRequest::$fieldDelimiter = $fielddelimiter;
SimplxRequest::$valueDelimiter = $valuedelimiter;
if($currentResource instanceof modResource){
SimplxRequest::addSection('modresource');
$currentResourceArray['pagetitle'] = $currentResource->get('pagetitle');
$currentResourceArray['template'] = $currentResource->get('template');
$currentResourceArray['parent'] = $currentResource->get('parent');
$currentResourceArray['template'] = $currentResource->get('template');
$currentResourceArray['createdby'] = $currentResource->get('createdby');
$currentResourceArray['createdon'] = $currentResource->get('createdon');
$currentResourceArray['editedby'] = $currentResource->get('editedby');
$currentResourceArray['editedon'] = $currentResource->get('editedon');
$currentResourceArray['class_key'] = $currentResource->get('class_key');
$currentResourceArray['uri'] = $currentResource->get('uri');
$currentResourceArray['content_type'] = $currentResource->get('content_type');
$currentResourceArray['published'] = $currentResource->get('published');
$currentResourceArray['pub_date'] = $currentResource->get('pub_date');
$currentResourceArray['unpub_date'] = $currentResource->get('unpub_date');
$currentResourceArray['alias'] = $currentResource->get('alias');
$currentResourceArray['isfolder'] = $currentResource->get('isfolder');
$currentResourceArray['type'] = $currentResource->get('type');
$currentResourceArray['templatename'] = $currentResource->getOne('Template')->get('templatename');
SimplxRequest::setSection('modresource',$currentResourceArray);
}
/*
Before anything else, we need to make sure that we have a routingtable set. If not, theres
no need to continue.
*/
if(!$routingtable){
$modx->log(modX::LOG_LEVEL_ERROR, 'SIMPLX_Controller: No Routing Table was specified. Exiting.');
return false;
}
/*
Save the original log level so we can revert back to this when exiting the Controller.
*/
$originalLogLevel = $modx->getLogLevel();
if($debugmode){
$modx->setLogLevel(modX::LOG_LEVEL_DEBUG);
}
if(!$requestObject){
$modx->log(modX::LOG_LEVEL_ERROR, 'SIMPLX_Controller: Error getting SimplxRequest object.');
return false;
}
if(!$parseError){
/*
Get the JSON serialized routing table
*/
$routingTableObject = $modx->cacheManager->get($routingtable);
if(!$routingTableObject){
$routingTableObject = $modx->getObject('modChunk',array('name' => $routingtable ));
$routingTableObject = $routingTableObject->getContent();
$modx->cacheManager->set($routingtable,$routingTableObject);
}
$routingTableError = false;
$routingTableLookupError = false;
try{
$routingTableObject = json_decode($routingTableObject,true);
/*
Get initial request scope to parse (path,uri,cookie,header,query,form etc)
First, check the if we have a Snippet parameter to use.
*/
if(!$routingconstraint || $routingconstraint == ''){
/*
No routing constraint parameter was passed to us, so lets look for a default instruction in the routing table.
*/
if(array_key_exists('routingconstraint',$routingTableObject)){
$routingconstraint = $routingTableObject['routingconstraint'];
}else{
//$modx->log(modX::LOG_LEVEL_ERROR, 'SIMPLX_Controller: Error, no routing constraint was specified.');
//return false;
$routingconstraint = null;
}
}
/*
Get the contexts collection from the decoded array
*/
$routingTableObject = $routingTableObject['contexts'];
$routingTableError = false;
}catch(Exception $e){
$modx->log(modX::LOG_LEVEL_ERROR, 'SIMPLX_Controller: Error loading routing table.');
return false;
}
if(!$routingTableError){
$routingContextKey = $modx->context->key;
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, '----------------------------------------------------------');
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'SIMPLX_Controller: Starting the Controller. Using Routing Table "'.$routingtable.'", Constraint "'.$routingconstraint.'", Field Delimiter "'.$fielddelimiter.'" and Value Delimiter "'.$valuedelimiter.'".');
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'SIMPLX_Controller: Using "'.$defaultconstrainttoken.'" as default constraint.');
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'SIMPLX_Controller: Checking if the current MODx Context "'.$routingContextKey.'" is included in the Routing Table.');
/*
Check if the routing table has any instructions for the current context.
*/
if(array_key_exists($routingContextKey,$routingTableObject)){
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'SIMPLX_Controller: Checking if the current MODx Context "'.$routingContextKey.'" has any rules for constraint "'.$routingconstraint.'".');
/*
Ok the Context is in the routing table. Get the actual context array.
*/
$routingContext = $routingTableObject[$routingContextKey];
if(count($routingContext)<1){
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'SIMPLX_Controller: The Context "'.$routingContextKey.'" is in the Routing Table but has no rules. Exiting Controller.');
return true;
}
/*
Get the initial item using the default constraint (path, form, query, cookie, header etc)
*/
/*
If we have no default routing constraint we simply use the first constraint in the context.
*/
if(!isset($routingconstraint)){
$routingconstraint = array_keys($routingContext['constraints']);
$routingconstraint = $routingconstraint[0];
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'SIMPLX_Controller: We have no default routing constraint so we use the first constraint in the context "'.$routingconstraint.'".');
}
$routingConstraintField = SimplxRequest::lookup($routingconstraint);
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'SIMPLX_Controller: Got the following result from the constraint lookup: "'.$routingConstraintField.'".');
if(is_array($routingConstraintField)){
/*
The location is an array which means that we will be looking for a routing instruction in the
table which is equal to the value of the constraint; i.e, if the constraint is "headers" we can
expect to find something like this in the table :
"header":{
"my-header":"mysnippet"
}
*/
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'SIMPLX_Controller: The constraint "'.$routingconstraint.'" is a collection of routes.');
$defaultconstrainttoken = $defaultruletoken;
}else{
/*
We now add the default constraint as a prefix to the result of the lookup and try to find this entry
in the routing table.
*/
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'SIMPLX_Controller: The constraint "'.$routingconstraint.'" is a one dimensional request field.');
/*
The constraints in the table can be expressed as paths, or, as paths with a specified request field, i.e.
"headers:content-type>application/soap+xml". This is however overridden if the routing table has a path-only
constraint "headers:content-type".
*/
if(!array_key_exists($routingconstraint,$routingContext['constraints'])){
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'SIMPLX_Controller: Using "'.$routingconstraint.'" plus field "'.$routingConstraintField.'" as constraint.');
$defaultconstrainttoken = ($routingconstraint.$valuedelimiter.$defaultruletoken);
$routingconstraint = ($routingconstraint.$valuedelimiter.$routingConstraintField);
}else{
$defaultconstrainttoken = $defaultruletoken;
}
}
/*
Check if the Context has any instructions for the constraint.
*/
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'SIMPLX_Controller: Check if the Context has any rules for the constraint.');
if(isset($routingConstraintField) && (array_key_exists($routingconstraint,$routingContext['constraints']) || array_key_exists($defaultconstrainttoken,$routingContext['constraints']))){
// Mental note: Remove bad code below asap.
if(array_key_exists($routingconstraint,$routingContext['constraints'])){
/*
Ok theres a routing instructions for the constraint. Now we get all the
rule the constraint.
*/
$constraintRoutingRules = $routingContext['constraints'][$routingconstraint];
/*
If the $constraintRoutingRules variable is not an array this means that there is only *one*
rule for the constraint and that the variable actually contains an instruction.
This means that we can run it and exit.
*/
if(!is_array($constraintRoutingRules)){
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'The constraint had only one single rule/instruction "'.$constraintRoutingRules.'". Running Snippet and exiting.');
$modx->runSnippet($constraintRoutingRules,array());
return true;
}
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'Ok there are routing rules for constraint "'.$routingconstraint.'"');
/*
Go through the $requestObject object and look for instructions for each parameter
*/
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'Lets go through the rules to see if we find a match.');
foreach ($constraintRoutingRules['rules'] as $rule => $conditions) {
/*
Look if there is a name match for the current request parameter in the
current location list
*/
/*
If the key is the default action for the rule, we skip it til later in case we dont find any other match.
*/
if($rule != $defaultruletoken){
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'The matching rule is now "'.$rule.'". Lets check for possible conditions.');
$requestRuleMatch = SimplxRequest::lookup($rule);
if($requestRuleMatch){
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'The conditions for rule "'.$rule.'" is "'.$requestRuleMatch.'"');
if(is_array($conditions)){
// Get the actual conditions which are located in a nested array
$conditions = $conditions['conditions'];
/*
For each parameter there can be different values which in turn have different
routing instructions in the location list.
Lets search for a value match.
*/
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'There are instructions for the rule "'.$rule.'", lets look for a match to "'.$requestRuleMatch.'".');
//if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'This is the collection of instructions for this rule: "'.json_encode($instructions).'".');
$ruleInstruction = $conditions[$requestRuleMatch];
/*
Check if there was a valid instruction present
*/
if($ruleInstruction != ""){
/*
Good lets run the Snippet which was in the instruction and exit
*/
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'Found a matching instruction for rule "'.$rule.'" condition "'.$requestRuleMatch.'".');
if(is_array($ruleInstruction)){
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'The instruction has default parameters "'.json_encode($ruleInstruction[1]).'" condition "'.$requestRuleMatch.'". Running Snippet "'.$ruleInstruction[0].'" for "'.$rule.'", then exiting.');
$result = $modx->runSnippet($ruleInstruction[0],$ruleInstruction[1]);
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'The instruction returned "'.json_encode($result).'"');
return true;
}else{
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'The instruction has no default parameters. Running Snippet "'.$ruleInstruction.'", then exiting.');
$result = $modx->runSnippet($ruleInstruction,array());
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'The instruction returned "'.json_encode($result).'"');
return true;
}
}else{
/*
No instruction was specified for this rule. Lets look and
see if there is a default instruction. The default instruction is has a key of '*'.
*/
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'There was no instruction for rule "'.$requestRuleMatch.'". Checking default.');
$defaultInstruction = $conditions[$defaultruletoken];
if($defaultInstruction != ""){
/*
Good lets run the Snippet which was in the default instruction and exit
*/
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'A default instruction was found for rule "'.$rule.'".');
if(is_array($defaultInstruction)){
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'The instruction has default parameters "'.json_encode($defaultInstruction[1]).'" condition "'.$requestRuleMatch.'". Running Snippet "'.$defaultInstruction[0].'".');
$result = $modx->runSnippet($defaultInstruction[0],$defaultInstruction[1]);
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'The instruction returned "'.json_encode($result).'"');
return true;
}else{
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'The instruction has no default parameters. Running Snippet "'.$defaultInstruction.'", then exiting.');
$result = $modx->runSnippet($defaultInstruction,array());
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'The instruction returned "'.json_encode($result).'"');
return true;
}
//$modx->runSnippet($defaultInstruction);
return true;
}else{
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'No matching instruction or default was found for rule "'.$rule.'". Exiting.');
return true;
} // if($defaultInstruction != "")
} // if($ruleInstruction != "")
}else{
/*
There was only one single instruction for this rule.
*/
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'There was only one single instruction for rule "'.$rule.'". Running "'.$conditions.'"');
$modx->runSnippet($conditions);
return true;
} //if(is_array($conditions))
}else{
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'No condition was found for the rule "'.$rule.'".');
} // if($requestRuleMatch)
}else{
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'Found a default rule that we might use.');
} //if($rule != $defaultconstrainttoken)
} // End of foreach
/*
If we got this far we have a default rule for the constraint to check out.
*/
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'No matching rule was found. Lets look for a default instruction for the default constraint');
/*
If we got this far, lets look for the instruction for the default constraint
*/
$constraintDefaultRules = $constraintRoutingRules['rules'][$defaultruletoken];
if(is_array($constraintDefaultRules)){
if(array_key_exists($defaultruletoken,$constraintDefaultRules)){
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'Found a default instruction for the default constraint: "'.json_encode($constraintDefaultRules));
$defaultInstruction = $constraintDefaultRules[$defaultruletoken];
if($defaultInstruction){
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'Running default instruction for constraint:'.$routingConstraint);
if(is_array($defaultInstruction)){
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'The instruction has default parameters "'.json_encode($defaultInstruction[1]).'" condition "'.$requestRuleMatch.'". Running Snippet "'.$defaultInstruction[0].'".');
$result = $modx->runSnippet($defaultInstruction[0],$defaultInstruction[1]);
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'The instruction returned "'.json_encode($result).'"');
return true;
}else{
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'The instruction has no default parameters. Running Snippet "'.$defaultInstruction.'", then exiting.');
$result = $modx->runSnippet($defaultInstruction,array());
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'The instruction returned "'.json_encode($result).'"');
return true;
}
}else{
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'There was no default action for "'.$routingconstraint.'"');
return true;
}
}
}else{
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'Running default action "'.$constraintDefaultRules.'" for constraint:'.$routingconstraint);
$modx->runSnippet($constraintDefaultRules);
return true;
}
}else{
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'No matching rule was found. Lets look for a default instruction for the default constraint');
/*
If we got this far, lets look for the instruction for the default constraint
*/
$constraintRoutingRules = $routingContext['constraints'][$defaultconstrainttoken];
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, json_encode($constraintRoutingRules));
if(is_array($constraintRoutingRules)){
if(array_key_exists($defaultconstrainttoken,$constraintRoutingRules)){
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'Found a default instruction for the default constraint: "'.json_encode($constraintRoutingRules));
$defaultInstruction = $constraintRoutingRules[$defaultconstrainttoken];
if($defaultInstruction){
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'Running default action "'.$defaultInstruction.'" for constraint:'.$routingConstraint);
if(is_array($defaultInstruction)){
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'The instruction has default parameters "'.json_encode($defaultInstruction[1]).'" condition "'.$requestRuleMatch.'". Running Snippet "'.$defaultInstruction[0].'".');
$result = $modx->runSnippet($defaultInstruction[0],$defaultInstruction[1]);
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'The instruction returned "'.json_encode($result).'"');
return true;
}else{
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'The instruction has no default parameters. Running Snippet "'.$defaultInstruction.'", then exiting.');
$result = $modx->runSnippet($defaultInstruction,array());
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'The instruction returned "'.json_encode($result).'"');
return true;
}
}else{
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'There was no default instruction for "'.$routingconstraint.'"');
return true;
}
}
}else{
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'Running default instruction "'.$constraintRoutingRules.'" for constraint:'.$routingconstraint);
if(is_array($constraintRoutingRules)){
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'The instruction has default parameters "'.json_encode($constraintRoutingRules[1]).'" condition "'.$requestRuleMatch.'". Running Snippet "'.$defaultInstruction[0].'".');
$result = $modx->runSnippet($constraintRoutingRules[0],$constraintRoutingRules[1]);
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'The instruction returned "'.json_encode($result).'"');
return true;
}else{
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'The instruction has no default parameters. Running Snippet "'.$defaultInstruction.'", then exiting.');
$result = $modx->runSnippet($constraintRoutingRules,array());
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'The instruction returned "'.json_encode($result).'"');
return true;
}
}
} // if(array_key_exists($routingconstraint,$routingContext)
}else{
/*
Check for a default instruction for the current context
*/
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'Looking for default instruction for the Context.');
if(array_key_exists($defaultruletoken,$routingContext['constraints'])){
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'Found default instruction for the Context.');
$defaultRules = $routingContext['constraints'][$defaultruletoken];
if(is_array($defaultRules)){
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'Got more than one Rule "'.json_encode($defaultRules).'".');
/*
Check if theres a default condition for the default rule.
*/
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'The instruction has default parameters "'.json_encode($defaultRules[1]).'". Running Snippet "'.$$defaultRules[0].'".');
$defaultInstruction = $defaultRules[$defaultruletoken];
$result = $modx->runSnippet($defaultRules[0],$defaultRules[1]);
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'The instruction returned "'.json_encode($result).'"');
return true;
/*
if(array_key_exists($defaultruletoken,$defaultRules)){
$defaultInstruction = $defaultRules[$defaultruletoken];
if(is_array($defaultInstruction)){
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'The instruction has default parameters "'.json_encode($defaultInstruction[1]).'" condition "'.$requestRuleMatch.'". Running Snippet "'.$defaultInstruction[0].'".');
$result = $modx->runSnippet($defaultInstruction[0],$defaultInstruction[1]);
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'The instruction returned "'.json_encode($result).'"');
return true;
}else{
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'The instruction has no default parameters. Running Snippet "'.$defaultInstruction.'", then exiting.');
$result = $modx->runSnippet($defaultInstruction,array());
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'The instruction returned "'.json_encode($result).'"');
return true;
}
}else{
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'The instruction has no default parameters. Running Snippet "'.$defaultInstruction.'", then exiting.');
$result = $modx->runSnippet($defaultInstruction,array());
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'The instruction returned "'.json_encode($result).'"');
return true;
}
*/
}else{
/*
If the default Rule is not an Array, we can assume that its really an Instruction.
*/
if($defaultRules){
$defaultInstruction = $defaultRules;
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'The instruction has no default parameters. Running Snippet "'.$defaultInstruction.'", then exiting.');
$result = $modx->runSnippet($defaultInstruction,array());
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'The instruction returned "'.json_encode($result).'"');
return true;
} // if(is_array($defaultInstruction))
} // if(is_array($defaultInstruction))
}else{
return;
} // if(array_key_exists('*',$routingContext))
} // if(array_key_exists($routingConstraint,$routingContext))
}else{
return;
} // if(array_key_exists($routingContextKey,$routingTableObject))
}else{
return;
} //if(!$routingTableError)​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​
}else{
return;
} // if(!$parseError)
function simplx_controller_getRoutingTable($routingtable){
global $modx;
$routingTableObject = $modx->cacheManager->get($routingtable);
if(!$routingTableObject){
/*
Get the JSON serialized routing table
*/
$routingTableObject = $modx->getObject('modChunk',array('name' => $routingtable ));
$routingTableObject = $routingTableObject->getContent();
$modx->cacheManager->set($routingtable,$routingTableObject);
}
return $routingTableObject;
}
[{"name":"routingtable","desc":"*Required* This must have the name of the Chunk which serves as default Routing Table.","xtype":"textfield","options":[],"value":"simplx.controller.routingtable.rest","lexicon":null,"overridden":false,"desc_trans":"*Required* This must have the name of the Chunk which serves as default Routing Table.","menu":null},{"name":"routingconstraint","desc":"*Optional* The Routing Constraint tells the Controller which Request field to initially use as routing rule. Possible values include \"path\", \"headers\", \"cookies\", \"query\", \"form\" etc","xtype":"textfield","options":[],"value":"","lexicon":null,"overridden":false,"desc_trans":"*Optional* The Routing Constraint tells the Controller which Request field to initially use as routing rule. Possible values include \"path\", \"headers\", \"cookies\", \"query\", \"form\" etc","menu":null},{"name":"debugmode","desc":"Should the Controller output its debug log?","xtype":"combo-boolean","options":[],"value":true,"lexicon":null,"overridden":false,"desc_trans":"Should the Controller output its debug log?","menu":null},{"name":"fielddelimiter","desc":"This is the token that separates Request fields from values, ie in \"header:content-type>text/html\", \":\" is a field delimiter.","xtype":"textfield","options":[],"value":".","lexicon":null,"overridden":false,"desc_trans":"This is the token that separates Request fields from values, ie in \"header:content-type>text/html\", \":\" is a field delimiter.","menu":null},{"name":"defaultruletoken","desc":"This is the char that symbolizes the default rule for a specific constraint. This is by default '*'.","xtype":"textfield","options":[],"value":"*","lexicon":null,"overridden":false,"desc_trans":"This is the char that symbolizes the default rule for a specific constraint. This is by default '*'.","menu":null},{"name":"valuedelimiter","desc":"This is the token that separates Request fields from values, ie in \"header:content-type>text/html\", \">\" is a value delimiter.","xtype":"textfield","options":[],"value":"=","lexicon":null,"overridden":false,"desc_trans":"This is the token that separates Request fields from values, ie in \"header:content-type>text/html\", \">\" is a value delimiter.","menu":null},{"name":"patterndelimiter","desc":"","xtype":"textfield","options":[],"value":"?","lexicon":null,"overridden":false,"desc_trans":"","menu":null}]
<?php
/*
MODx Plugin simplx_controller
Version 111028
The SIMPLX Controller is a routing Plugin/Snippet for MODx Revolution developed by Lars C Wallin.
The Plugin catches the HTTP Request on for example,
- onWebPageInit
- onManagerPageInit
,loads a routing table specified Chunk and checks its rules to decide which Snippet to run.
While it's a simple enough concept, it packs great power! You can set routing rules on any information
contained in the HTTP Request such as header fields, url, urn, form fields, querystrings etc.
It's like a generic controller++ :)
*/
/*
Probably not needed, but lets check so that the $scriptProperties variable isnt null.
*/
if(!$scriptProperties){
$scriptProperties = array();
}
/*
Now lets call the controller Snippet. The controller will get different config options
from the $scriptProperties array, which in turn gets its content from the current System Event.
You can easily change all config by just clicking on the System Event, scrolling down to desired
Event, and change Property Set for that specific Event.
*/
$modx->runSnippet('simplx.controller',$scriptProperties);
<?php
/*
**
** DEVELOPMENT VERSION - NOT FOR ANY KIND OF DEPLOYMENT!
**
*/
require_once($modx->getOption('core_path').'components/simplx/request/simplx.request.php');
$activeProcesses = array();
$parseError = false;
$routingTableObject = isset($routingTableObject) ? $routingTableObject : false;
$requestObject = isset($requestObject) ? $requestObject : SimplxRequest::getRequest();
$fielddelimiter = isset($fielddelimiter) ? $fielddelimiter : '.';
$valuedelimiter = isset($valuedelimiter) ? $valuedelimiter : '=';
$patterndelimiter = isset($patterndelimiter) ? $patterndelimiter : '?';
$routingConstraintField = '';
$constraintRoutingRules = '';
$defaultruletoken = isset($defaultruletoken) ? $defaultruletoken : '*';
$defaultconstrainttoken = isset($defaultconstrainttoken) ? $defaultconstrainttoken : '*';
SimplxRequest::$fieldDelimiter = $fielddelimiter;
SimplxRequest::$valueDelimiter = $valuedelimiter;
/*
Save the original log level so we can revert back to this when exiting the Controller.
*/
$originalLogLevel = $modx->getLogLevel();
if($debugmode){
$modx->setLogLevel(modX::LOG_LEVEL_DEBUG);
}
if(!$requestObject){
$modx->log(modX::LOG_LEVEL_ERROR, 'SIMPLX_Controller: Error getting SimplxRequest object.');
return false;
}
if(!$parseError){
/*
Get the JSON serialized routing table
*/
simplx_controller_getRoutingTable($routingtable);
/*
$routingTableObject = $modx->cacheManager->get($routingtable);
if(!$routingTableObject){
$routingTableObject = $modx->getObject('modChunk',array('name' => $routingtable ));
$routingTableObject = $routingTableObject->getContent();
$modx->cacheManager->set($routingtable,$routingTableObject);
}
$routingTableError = false;
$routingTableLookupError = false;
*/
if($routingTableObject){
//$routingTableObject = json_decode($routingTableObject,true);
/*
Get initial request scope to parse (path,uri,cookie,header,query,form etc)
First, check the if we have a Snippet parameter to use.
*/
if(!$routingconstraint || $routingconstraint == ''){
/*
No routing constraint parameter was passed to us, so lets look for a default instruction in the routing table.
*/
if(array_key_exists('routingconstraint',$routingTableObject)){
$routingconstraint = $routingTableObject['routingconstraint'];
}else{
//$modx->log(modX::LOG_LEVEL_ERROR, 'SIMPLX_Controller: Error, no routing constraint was specified.');
//return false;
$routingconstraint = null;
}
}
/*
Get the contexts collection from the decoded array
*/
$routingTableObject = $routingTableObject['contexts'];
$routingTableError = false;
}else{
$modx->log(modX::LOG_LEVEL_ERROR, 'SIMPLX_Controller: Error loading routing table.');
return false;
}
if(!$routingTableError){
$routingContextKey = $modx->context->key;
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, '----------------------------------------------------------');
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'SIMPLX_Controller: Starting the Controller. Using Routing Table "'.$routingtable.'", Constraint "'.$routingconstraint.'", Field Delimiter "'.$fielddelimiter.'" and Value Delimiter "'.$valuedelimiter.'".');
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'SIMPLX_Controller: Using "'.$defaultconstrainttoken.'" as default constraint.');
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'SIMPLX_Controller: Checking if the current MODx Context "'.$routingContextKey.'" is included in the Routing Table.');
/*
Check if the routing table has any instructions for the current context.
*/
$routingContext = simplx_routingTable_getContext($routingContextKey);
if($routingContext){
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'SIMPLX_Controller: Checking if the current MODx Context "'.$routingContextKey.'" has any rules for constraint "'.$routingconstraint.'".');
if(count($routingContext)<1){
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'SIMPLX_Controller: The Context "'.$routingContextKey.'" is in the Routing Table but has no rules. Exiting Controller.');
return true;
}
/*
Get the initial item using the default constraint (path, form, query, cookie, header etc)
*/
/*
If we have no default routing constraint we simply use the first constraint in the context.
*/
if(!isset($routingconstraint)){
$routingconstraint = array_keys($routingContext['constraints']);
$routingconstraint = $routingconstraint[0];
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'SIMPLX_Controller: We have no default routing constraint so we use the first constraint in the context "'.$routingconstraint.'".');
}
$routingConstraintField = SimplxRequest::lookup($routingconstraint);
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'SIMPLX_Controller: Got the following result from the constraint lookup: "'.$routingConstraintField.'".');
if(is_array($routingConstraintField)){
/*
The location is an array which means that we will be looking for a routing instruction in the
table which is equal to the value of the constraint; i.e, if the constraint is "headers" we can
expect to find something like this in the table :
"header":{
"my-header":"mysnippet"
}
*/
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'SIMPLX_Controller: The constraint "'.$routingconstraint.'" is a collection of routes.');
$defaultconstrainttoken = $defaultruletoken;
}else{
/*
We now add the default constraint as a prefix to the result of the lookup and try to find this entry
in the routing table.
*/
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'SIMPLX_Controller: The constraint "'.$routingconstraint.'" is a one dimensional request field.');
/*
The constraints in the table can be expressed as paths, or, as paths with a specified request field, i.e.
"headers:content-type>application/soap+xml". This is however overridden if the routing table has a path-only
constraint "headers:content-type".
*/
if(!array_key_exists($routingconstraint,$routingContext['constraints'])){
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'SIMPLX_Controller: Using "'.$routingconstraint.'" plus field "'.$routingConstraintField.'" as constraint.');
$defaultconstrainttoken = ($routingconstraint.$valuedelimiter.$defaultruletoken);
$routingconstraint = ($routingconstraint.$valuedelimiter.$routingConstraintField);
}else{
$defaultconstrainttoken = $defaultruletoken;
}
}
/*
Check if the Context has any instructions for the constraint.
*/
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'SIMPLX_Controller: Check if the Context has any rules for the constraint.');
if(isset($routingConstraintField) && (array_key_exists($routingconstraint,$routingContext['constraints']) || array_key_exists($defaultconstrainttoken,$routingContext['constraints']))){
// Mental note: Remove bad code below asap.
if(array_key_exists($routingconstraint,$routingContext['constraints'])){
/*
Ok theres a routing instructions for the constraint. Now we get all the
rule the constraint.
*/
$constraintRoutingRules = $routingContext['constraints'][$routingconstraint];
/*
If the $constraintRoutingRules variable is not an array this means that there is only *one*
rule for the constraint and that the variable actually contains an instruction.
This means that we can run it and exit.
*/
if(!is_array($constraintRoutingRules)){
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'The constraint had only one single rule/instruction "'.$constraintRoutingRules.'". Running Snippet and exiting.');
$modx->runSnippet($constraintRoutingRules,array());
return true;
}
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'Ok there are routing rules for constraint "'.$routingconstraint.'"');
/*
Go through the $requestObject object and look for instructions for each parameter
*/
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'Lets go through the rules to see if we find a match.');
foreach ($constraintRoutingRules['rules'] as $rule => $conditions) {
/*
Look if there is a name match for the current request parameter in the
current location list
*/
/*
If the key is the default action for the rule, we skip it til later in case we dont find any other match.
*/
if($rule != $defaultruletoken){
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'The matching rule is now "'.$rule.'". Lets check for possible conditions.');
$requestRuleMatch = SimplxRequest::lookup($rule);
if($requestRuleMatch){
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'The conditions for rule "'.$rule.'" is "'.$requestRuleMatch.'"');
if(is_array($conditions)){
// Get the actual conditions which are located in a nested array
$conditions = $conditions['conditions'];
/*
For each parameter there can be different values which in turn have different
routing instructions in the location list.
Lets search for a value match.
*/
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'There are instructions for the rule "'.$rule.'", lets look for a match to "'.$requestRuleMatch.'".');
//if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'This is the collection of instructions for this rule: "'.json_encode($instructions).'".');
$ruleInstruction = $conditions[$requestRuleMatch];
/*
Check if there was a valid instruction present
*/
if($ruleInstruction != ""){
/*
Good lets run the Snippet which was in the instruction and exit
*/
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'Found a matching instruction for rule "'.$rule.'" condition "'.$requestRuleMatch.'".');
if(is_array($ruleInstruction)){
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'The instruction has default parameters "'.json_encode($ruleInstruction[1]).'" condition "'.$requestRuleMatch.'". Running Snippet "'.$ruleInstruction[0].'" for "'.$rule.'", then exiting.');
$result = $modx->runSnippet($ruleInstruction[0],$ruleInstruction[1]);
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'The instruction returned "'.json_encode($result).'"');
return true;
}else{
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'The instruction has no default parameters. Running Snippet "'.$ruleInstruction.'", then exiting.');
$result = $modx->runSnippet($ruleInstruction,array());
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'The instruction returned "'.json_encode($result).'"');
return true;
}
}else{
/*
No instruction was specified for this rule. Lets look and
see if there is a default instruction. The default instruction is has a key of '*'.
*/
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'There was no instruction for rule "'.$requestRuleMatch.'". Checking default.');
$defaultInstruction = $conditions[$defaultruletoken];
if($defaultInstruction != ""){
/*
Good lets run the Snippet which was in the default instruction and exit
*/
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'A default instruction was found for rule "'.$rule.'".');
if(is_array($defaultInstruction)){
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'The instruction has default parameters "'.json_encode($defaultInstruction[1]).'" condition "'.$requestRuleMatch.'". Running Snippet "'.$defaultInstruction[0].'".');
$result = $modx->runSnippet($defaultInstruction[0],$defaultInstruction[1]);
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'The instruction returned "'.json_encode($result).'"');
return true;
}else{
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'The instruction has no default parameters. Running Snippet "'.$defaultInstruction.'", then exiting.');
$result = $modx->runSnippet($defaultInstruction,array());
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'The instruction returned "'.json_encode($result).'"');
return true;
}
//$modx->runSnippet($defaultInstruction);
return true;
}else{
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'No matching instruction or default was found for rule "'.$rule.'". Exiting.');
return true;
} // if($defaultInstruction != "")
} // if($ruleInstruction != "")
}else{
/*
There was only one single instruction for this rule.
*/
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'There was only one single instruction for rule "'.$rule.'". Running "'.$conditions.'"');
$modx->runSnippet($conditions);
return true;
} //if(is_array($conditions))
}else{
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'No condition was found for the rule "'.$rule.'".');
} // if($requestRuleMatch)
}else{
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'Found a default rule that we might use.');
} //if($rule != $defaultconstrainttoken)
} // End of foreach
/*
If we got this far we have a default rule for the constraint to check out.
*/
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'No matching rule was found. Lets look for a default instruction for the default constraint');
/*
If we got this far, lets look for the instruction for the default constraint
*/
$constraintDefaultRules = $constraintRoutingRules['rules'][$defaultruletoken];
if(is_array($constraintDefaultRules)){
if(array_key_exists($defaultruletoken,$constraintDefaultRules)){
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'Found a default instruction for the default constraint: "'.json_encode($constraintDefaultRules));
$defaultInstruction = $constraintDefaultRules[$defaultruletoken];
if($defaultInstruction){
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'Running default instruction for constraint:'.$routingConstraint);
if(is_array($defaultInstruction)){
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'The instruction has default parameters "'.json_encode($defaultInstruction[1]).'" condition "'.$requestRuleMatch.'". Running Snippet "'.$defaultInstruction[0].'".');
$result = $modx->runSnippet($defaultInstruction[0],$defaultInstruction[1]);
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'The instruction returned "'.json_encode($result).'"');
return true;
}else{
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'The instruction has no default parameters. Running Snippet "'.$defaultInstruction.'", then exiting.');
$result = $modx->runSnippet($defaultInstruction,array());
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'The instruction returned "'.json_encode($result).'"');
return true;
}
}else{
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'There was no default action for "'.$routingconstraint.'"');
return true;
}
}
}else{
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'Running default action "'.$constraintDefaultRules.'" for constraint:'.$routingconstraint);
$modx->runSnippet($constraintDefaultRules);
return true;
}
}else{
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'No matching rule was found. Lets look for a default instruction for the default constraint');
/*
If we got this far, lets look for the instruction for the default constraint
*/
$constraintRoutingRules = $routingContext['constraints'][$defaultconstrainttoken];
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, json_encode($constraintRoutingRules));
if(is_array($constraintRoutingRules)){
if(array_key_exists($defaultconstrainttoken,$constraintRoutingRules)){
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'Found a default instruction for the default constraint: "'.json_encode($constraintRoutingRules));
$defaultInstruction = $constraintRoutingRules[$defaultconstrainttoken];
if($defaultInstruction){
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'Running default action "'.$defaultInstruction.'" for constraint:'.$routingConstraint);
if(is_array($defaultInstruction)){
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'The instruction has default parameters "'.json_encode($defaultInstruction[1]).'" condition "'.$requestRuleMatch.'". Running Snippet "'.$defaultInstruction[0].'".');
$result = $modx->runSnippet($defaultInstruction[0],$defaultInstruction[1]);
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'The instruction returned "'.json_encode($result).'"');
return true;
}else{
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'The instruction has no default parameters. Running Snippet "'.$defaultInstruction.'", then exiting.');
$result = $modx->runSnippet($defaultInstruction,array());
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'The instruction returned "'.json_encode($result).'"');
return true;
}
}else{
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'There was no default instruction for "'.$routingconstraint.'"');
return true;
}
}
}else{
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'Running default instruction "'.$constraintRoutingRules.'" for constraint:'.$routingconstraint);
if(is_array($constraintRoutingRules)){
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'The instruction has default parameters "'.json_encode($constraintRoutingRules[1]).'" condition "'.$requestRuleMatch.'". Running Snippet "'.$defaultInstruction[0].'".');
$result = $modx->runSnippet($constraintRoutingRules[0],$constraintRoutingRules[1]);
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'The instruction returned "'.json_encode($result).'"');
return true;
}else{
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'The instruction has no default parameters. Running Snippet "'.$defaultInstruction.'", then exiting.');
$result = $modx->runSnippet($constraintRoutingRules,array());
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'The instruction returned "'.json_encode($result).'"');
return true;
}
}
} // if(array_key_exists($routingconstraint,$routingContext)
}else{
/*
Check for a default instruction for the current context
*/
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'Looking for default instruction for the Context.');
if(array_key_exists($defaultruletoken,$routingContext['constraints'])){
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'Found default instruction for the Context.');
$defaultRules = $routingContext['constraints'][$defaultruletoken];
if(is_array($defaultRules)){
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'Got more than one Rule "'.json_encode($defaultRules).'".');
/*
Check if theres a default condition for the default rule.
*/
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'The instruction has default parameters "'.json_encode($defaultRules[1]).'". Running Snippet "'.$$defaultRules[0].'".');
$defaultInstruction = $defaultRules[$defaultruletoken];
$result = $modx->runSnippet($defaultRules[0],$defaultRules[1]);
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'The instruction returned "'.json_encode($result).'"');
return true;
/*
if(array_key_exists($defaultruletoken,$defaultRules)){
$defaultInstruction = $defaultRules[$defaultruletoken];
if(is_array($defaultInstruction)){
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'The instruction has default parameters "'.json_encode($defaultInstruction[1]).'" condition "'.$requestRuleMatch.'". Running Snippet "'.$defaultInstruction[0].'".');
$result = $modx->runSnippet($defaultInstruction[0],$defaultInstruction[1]);
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'The instruction returned "'.json_encode($result).'"');
return true;
}else{
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'The instruction has no default parameters. Running Snippet "'.$defaultInstruction.'", then exiting.');
$result = $modx->runSnippet($defaultInstruction,array());
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'The instruction returned "'.json_encode($result).'"');
return true;
}
}else{
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'The instruction has no default parameters. Running Snippet "'.$defaultInstruction.'", then exiting.');
$result = $modx->runSnippet($defaultInstruction,array());
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'The instruction returned "'.json_encode($result).'"');
return true;
}
*/
}else{
/*
If the default Rule is not an Array, we can assume that its really an Instruction.
*/
if($defaultRules){
$defaultInstruction = $defaultRules;
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'The instruction has no default parameters. Running Snippet "'.$defaultInstruction.'", then exiting.');
$result = $modx->runSnippet($defaultInstruction,array());
if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'The instruction returned "'.json_encode($result).'"');
return true;
} // if(is_array($defaultInstruction))
} // if(is_array($defaultInstruction))
}else{
return;
} // if(array_key_exists('*',$routingContext))
} // if(array_key_exists($routingConstraint,$routingContext))
}else{
return;
} // if(array_key_exists($routingContextKey,$routingTableObject))
}else{
return;
} //if(!$routingTableError)​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​
}else{
return;
} // if(!$parseError)
function simplx_controller_parseContext($context){
global $modx;
}
function simplx_controller_parseConstraint($constraint){
global $modx;
}
function simplx_controller_parseRule($rule){
global $modx;
}
function simplx_controller_parseCondition($condition){
global $modx;
}
function simplx_controller_parseInstruction($instruction){
global $modx;
}
function simplx_controller_setRoutingTable($table){
global $modx;
}
function simplx_controller_setRequestMessage($request){
global $modx;
}
function simplx_routingTable_getContext($contextName){
global $modx;
if(array_key_exists($contextName,$routingTableObject)){
/*
Ok the Context is in the routing table. Get the actual context array.
*/
$routingContext = $routingTableObject[$contextName];
}else{
return false;
}
}
function simplx_controller_getRoutingTable($routingtable){
global $modx;
$routingTableObject = $modx->cacheManager->get($routingtable);
if(!$routingTableObject){
/*
Get the JSON serialized routing table
*/
$routingTableObject = $modx->getObject('modChunk',array('name' => $routingtable ));
$routingTableObject = $routingTableObject->getContent();
$modx->cacheManager->set($routingtable,$routingTableObject);
}
$routingTableError = false;
$routingTableLookupError = false;
$routingTableObject = json_decode($routingTableObject,true);
if($routingTableObject){
return $routingTableObject;
}else{
return false;
}
}
class simplxRoutingTable{
private $state;
protected $contexts = array();
protected $initialConstraint;
protected $name;
protected $routingTableObject;
protected $fielddelimiter;
protected $valuedelimiter;
protected $patterndelimiter;
protected $routingConstraintField;
protected $constraintRoutingRules;
protected $defaultruletoken;
protected $defaultconstrainttoken;
public function _construct($routingtable = null){
global $modx;
if(isset($routingtable)){
if(is_array($routingtable)){
$this->state = $routingtable;
$this->contexts = $this->state['contexts'];
/*
Check if the state is valid. It should always have at least one Constraint
*/
if(!$this->contexts){
return false;
}
$this->initialConstraint = $this->state['initialconstraint'] ? $this->state['initialconstraint'] : '';
$this->name = $this->state['name'] ? $this->routingTableObject['name'] : '';
$this->fieldDelimiter = isset($this->state['fielddelimiter']) ? $this->state['fielddelimiter'] : '.';
$this->valueDelimiter = isset($this->state['valuedelimiter']) ? $this->state['valuedelimiter'] : '=';
$this->patternDelimiter = isset($this->state['patterndelimiter']) ? $this->state['patterndelimiter'] : '?';
$this->defaultRuleToken = isset($this->state['$defaultruletoken']) ? $this->state['$defaultruletoken'] : '*';
$this->defaultConstraintToken = isset($this->state['defaultconstrainttoken']) ? $this->state['defaultconstrainttoken'] : '*';
}else{
$routingTableObject = $modx->cacheManager->get($routingtable);
if(!$routingTableObject){
/*
Get the JSON serialized routing table
*/
$$this->state = $modx->getObject('modChunk',array('name' => $routingtable ));
$this->state = $routingTableObject->getContent();
$modx->cacheManager->set($routingtable,$this->state);
}
$this->state = json_decode($routingtable,true);
/*
Check so that the $routingTableObject was decoded to a valid php array.
*/
if(is_array($this->state)){
$this->contexts = $this->state['contexts'];
/*
Check if the state is valid. It should always have at least one Constraint
*/
if(!$this->contexts){
return false;
}
$this->initialConstraint = $this->state['initialconstraint'] ? $this->state['initialconstraint'] : '';
$this->name = $this->state['name'] ? $this->routingTableObject['name'] : '';
$this->fieldDelimiter = isset($this->state['fielddelimiter']) ? $this->state['fielddelimiter'] : '.';
$this->valueDelimiter = isset($this->state['valuedelimiter']) ? $this->state['valuedelimiter'] : '=';
$this->patternDelimiter = isset($this->state['patterndelimiter']) ? $this->state['patterndelimiter'] : '?';
$this->defaultRuleToken = isset($this->state['$defaultruletoken']) ? $this->state['$defaultruletoken'] : '*';
$this->defaultConstraintToken = isset($this->state['defaultconstrainttoken']) ? $this->state['defaultconstrainttoken'] : '*';
// So far so good
return true;
}else{
return false;
}
}
}
}
/*
Context related methods
*/
public function getContext($name){
if(isset($name)){
}
}
public function setContext($value){
if(isset($value)){
}
}
public function saveContext($state){
if(isset($state)){
}
}
public function deleteContext($name){
if(isset($name)){
}
}
public function getContexts(){
}
public function save($name){
/*
The $name argument makes it possible to "save as" or clone.
*/
if(isset($name)){
}
}
}
class simplxRoutingCondition{
private $state;
public function _construct($state = null){
global $modx;
if(isset($state)){
if(is_array($state)){
$this->state = $state;
//$this->contexts = $this->state['contexts'];
/*
Check if the state is valid. It should always have at least one Constraint
*/
if(!$this->contexts){
return false;
}
//$this->initialConstraint = $this->state['initialconstraint'] ? $this->state['initialconstraint'] : '';
}else{
$this->state = json_decode($state,true);
/*
Check so that the $routingTableObject was decoded to a valid php array.
*/
if(is_array($this->state)){
/*
Check if the state is valid. It should always have at least one Constraint
*/
if(!$this->contexts){
return false;
}
$this->key = $this->state[0];
// So far so good
return true;
}else{
return false;
}
}
}
}
/*
Context related methods
*/
public function getContext($name){
if(isset($name)){
}
}
public function setContext($value){
if(isset($value)){
}
}
public function saveContext($state){
if(isset($state)){
}
}
public function deleteContext($name){
if(isset($name)){
}
}
public function getContexts(){
}
public function save($name){
/*
The $name argument makes it possible to "save as" or clone.
*/
if(isset($name)){
}
}
}
@enminc
Copy link

enminc commented Mar 25, 2013

Larsc,

Do you have the complete simplx.controller (0.8.0-beta4) package on github anywhere. I have made a slight adjustment to the latest source code version to allow for a (*) wildcard context and would like to place a pull request.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment