Josh --
Just wanted to follow up on your questions. The Before and After annotations are now in Recess edge so your code for Issue 1 should work if you pull the latest commits.
I've been working on the doc's for 'Core' functionality that cover implementing annotations, wrappable methods, before, after, etc. that I will push up later today. Wanted to offer some insights on !Before and !After while we're in-context, though.
With Recess 0.20 (edge, currently) there are key methods on framework classes that are wrappable. This means that you can 'wrap' an invocation of the method with objects that implement IWrapper (have a before() and after() method). !Before and !After are short-cut annotations that allow you to wrap wrappable methods without the trouble of writing an IWrapper.
Simple example:
class MyModel extends Model {
/** !Before insert, update, delete */
function echoBefore() {
echo 'Called before!';
}
/** !After insert */
function echoAfter($result) {
echo 'Called after!';
if($result) {
echo 'Success!';
} else {
echo 'Failure!';
}
}
}
In this example you see echoBefore() registering to be called before all calls to insert, update, and delete. So calling $model->insert() will echo 'Called before!', then it will perform the insert operation, and finally it will call echoAfter. If you were to call $model->delete() only 'Called before!' would be echoed because 'delete' is not registered in the !After annotation in echoAfter.
Notice there are no arguments in echoBefore, this is because the method it wraps, insert, takes no arguments. Also notice that echoAfter takes one argument $result. This is the return value of the wrapped method.
More complex example:
class MyController extends Controller {
/** !Before serve */
function authenticate(Request $request) {
// do some authentication
if(!$authenticated) {
Library::import('recess.http.responses.ForbiddenResponse');
return new ForbiddenResponse($request);
}
}
/** !Before serve */
function echoBefore(Request $request) {
echo 'called before serve!';
}
/** !After serve */
function addSomeViewVariable(Response $response) {
$response->data['somevar'] = 'some val';
return $response;
}
/** !After serve */
function changeSomeViewVariable(Response $response) {
$response->data['somevar'] = 'some other val';
return $response;
}
}
In this example there is a short-circuit response in the authenticate method. If you return a value from a method called using !Before this will short-circuit the before chain and return this value to the caller. Also notice that because serve($request) takes one parameter, all methods that are wrapped using !Before must also take the $request parameter. The final note on !Before (also applies to !After) is that methods will be called in the order they are registered. So in this case the call chain looks like: authenticate, echoBefore, wrappedServe, addSomeViewVariable, changeSomeViewVariable.
Finally, this example shows off the ability to manipulate a return value with !After. If you return a value from a method registered After a wrapped method call, its value will replace the wrapped methods' return value. Unlike the short-circuit behavior in !Before, though, this new return value will continue being passed down the !After chain. There is no way to short-circuit out of the !After chain. Thus, in the above example, when the Response finally gets sent to the view the variable named $somevar will be set to 'some other val'.
If you find yourself using the same logic across classes with methods using !Before and !After you've got a great candidate for creating your own custom annotation and wrapper. I'll follow up with a link to this in the documentation when it goes on-line shortly.
-Kris