Framwork:sb Magic Model
From Surebert wiki
Contents |
Overview
sb_Magic_Model instances hijack Gateway requests and map the urls of /model/action to class/method. You can think of it as a model/controller hybrid. It breaks the concept of mvc but works with little overhead when you want a common interface to call model properties both from the client and server side with little to no extra scripting.
E.g. if class Car implemented sb_Magic_Model than /car/paint would create an instance of Car and serve the results of its paint method
Before any data is returned to the output buffer it passes through the instances filter_output($out) method which can be used to string replace swear words out, log data being served etc.
Arguments
By default all classes which implement sb_Magic_Model serve all of their public methods in the url format /class/action. Any additional arguments are passed after additional slashes as an array to the constuctor. e.g. /car/paint/1/3 would pass an array with the values 1 and 3 to the __constructor of the Car's instance. This is a good place for passing IDs in order to load the data about the instance from the database in the __construct method.
Input and Method Properties
Each public method has additional magic model properties which can be defined in the phpdocs of the methods themselves. These properties include:
- @servable (true | false) Determines if the method is accessible via URL. True by default
- @input_as_array (true | false) Determines if arguments are passed in order or as a named hash like GET and POST
- @http_method (get | post) Determines which type of data is passed to the method POST or GET
input_as_array
For the following two examples we are assuming the url is /car/paint?color=ACACAC&detail=1
A method that has input_as_array true would receive input like like
php code
/** * @servable true * @input_as_array true */ public function some_method($input){ //$input['color'] = 'ACACAC'; //$input['detail'] = '1'; }
While a method that has @input_as_array set to false would receive input values in the order they came with the keys. In this case the order of the arguments is very important and should only be used when you can be sure of the order.
php code
/** * @servable true * @input_as_array false */ public function some_method($color, $detail){ //$color = 'ACACAC'; //$detail = '1'; }
Example
php code
<?php /** * An example magic model class representing a car */ class Car implements sb_Magic_Model{ /** * Receives the arguments as an array * e.g. in /car/paint/1/4 $args[0] = 1 and $args[1] = 4 * @param <type> $args */ public function __construct($args){ if(is_numeric($args[0])){ $this->id = $args[0]; //load car data from database... } } /** * Change the car's paint color * @param $color Hex value #ACACAC of the color * @http_method get Accepts get data */ public function paint($color){ //validate color if(preg_match('/^[a-f0-9]{6}$/i', $color)){ //you could save new color to db here .... //set the color property $this->color = $color; return true; } else { throw(new Exception('Car color must be a valid HEX value with the #.')); } } /** * All return statements from sb_Magic_Model served methods pass * through $this->filter_out() before going into the output buffer * @param string $out * @return string */ public function filter_output($out){ $request = new sb_Ajax_Response($out); return $request->dispatch(); } } ?>
__call magic model methods that don't exist
When a magic model method is called that does not exist it will first look to see if you defined the model's __call method. If so it will pass the request there. Otherwise, it will look for a view/template that matches and serve that.