I have this problem with Slim framework. I have class Template that have render method and I want for Slim to render objects of this class if they are returned by route handlers
$app->get('/test', function() {
return new Template('main', function() use ($error) {
return array(
'content' => "Hello"
);
});
});
it work I created child class (in System.php)
class System extends Slim {
function __constructor() {
Slim::__construct();
}
private function auto_render_fun($callable) {
$app = $this;
return function() use ($callable, $app) {
$args = func_get_args();
$ret = call_user_func_array($callable, $args);
if ($ret instanceof Template) {
//render Template - Slim ignore return value
$app->response()->body($ret->render());
}
};
}
protected function mapRoute($args) {
$last = count($args)-1;
$args[$last] = $this->auto_render_fun($args[$last]);
return Slim::mapRoute($args);
}
}
I wanted to do the same thing with notFound
$app->notFound(function () use ($app) {
$response = $app->response();
$response['Content-Type'] = 'text/html';
return new Template('main', function() {
return array('content' => new Template('error_404', null));
});
});
so I’ve overwritten notFound function to wrap Closure and render it’s return value
First I try to use smaller code
public function notFound($callable = null) {
if (!is_null(($callable))) {
$this->router->notFound($this->auto_render_fun($callable));
} else {
Slim::notFound();
}
}
I also try this (copy and modify old code).
public function notFound($callable = null) {
if ( !is_null($callable) ) {
$this->router->notFound($this->auto_render_fun($callable));
// $this->router->notFound($callable); // old line
} else {
ob_start();
$customNotFoundHandler = $this->router->notFound();
if ( is_callable($customNotFoundHandler) ) {
call_user_func($customNotFoundHandler);
} else {
call_user_func(array($this, 'defaultNotFound'));
}
$this->halt(404, ob_get_clean());
}
}
but the reason why it didn’t work is that it trow Slim_Exception_Stop that’s suppose to be cached by Slim here is that line for code that call $this->notFound();
https://github.com/codeguy/Slim/blob/master/Slim/Slim.php#L1160
it’s inside try..catch.
Here is stack trace (I cached it inside notFound function – but it should be handled in Slim class).
Slim_Exception_Stop in file libs/Slim/Slim/Slim.php at 862
0: Slim->stop() in libs/Slim/Slim/Slim.php at 882
1: Slim->halt(integer, string) in libs/System.php at 187
2: System->notFound() in libs/Slim/Slim/Slim.php at 1161
3: Slim->call() in libs/Slim/Slim/Middleware/Flash.php at 84
4: Slim_Middleware_Flash->call() in libs/Slim/Slim/Middleware/MethodOverride.php at 91
5: Slim_Middleware_MethodOverride->call() in libs/Slim/Slim/Middleware/PrettyExceptions.php at 65
6: Slim_Middleware_PrettyExceptions->call() in libs/Slim/Slim/Middleware/PrettyExceptions.php at 65
7: Slim_Middleware_PrettyExceptions->call() in libs/Slim/Slim/Slim.php at 1098
8: Slim->run() in index.php at 573
Ok, I found the reason, exception was handled as it should but there was not content. I wrongly assume that it’s something with Classes, but simply the Slim code have bugs.
function overwrite data that you use in the handler like this
won’t work, function not found should look like this