Fri Jul 7 20:46:35 PHT 2006 nimrod.abing@gmail.com * Hide or expose Controller methods as actions. This modification prevents all the methods of the Controller class (and its parent class Object) from being invoked via a URL. It also allows subclasses of the Controller base class to hide all its methods and selectively expose them programmatically. Rationale: This modification aims to provide a consistent way of hiding and exposing a Controller's methods as actions. It is currently possible to create "private" actions in a Controller by starting the method's name with an underscore. If these private actions are invoked via the web app's URL, the core dispatcher is able to filter out these invocations and respond with an error message. There are certain methods in a Controller that should be treated as private such as render(), flash(), beforeFilter(), and many others. However, their names are not prepended with an underscore. This allows them to be called via a URL. Being able to programmatically hide and expose a Controllers methods can be useful in building systems that require access control. For instance by default, a controller can start out with all of its methods hidden. Then depending on some access criteria, methods can be exposed to the user. Full Description: The Controller base class and the core dispatcher has been modified in order to prevent the Controller base methods from being called over a URL. The Controller class now maintains a list of hiddenMethods as a property. This list is initialized upon Controller construction and contains a list of all the methods found in the Controller base class. The core dispatcher checks the action name against the controller's list of hidden methods. If the action name is in the hidden methods list, the dispatcher will generate an error message instead. Controllers that derived from the Controller base class may also make use of this feature by invoking the hideMethods() method with a array of strings containing the names of hidden methods. If hideMethods() is called without any parameters, it will hide *all* of the methods of the current controller class. Methods are exposed by calling the method exposeMethods() with an array of method names to expose as actions. diff -rN old-cake/cake/dispatcher.php new-cake/cake/dispatcher.php 166c166 < if((in_array($params['action'], $classMethods) || in_array(strtolower($params['action']), $classMethods)) && strpos($params['action'], '_', 0) === 0) { --- > if((in_array($params['action'], $classMethods) || in_array(strtolower($params['action']), $classMethods)) && (in_array(strtolower($params['action']), $controller->hiddenMethods) || strpos($params['action'], '_', 0) === 0)) { diff -rN old-cake/cake/libs/controller/controller.php new-cake/cake/libs/controller/controller.php 203a204,210 > * Array of methods names to hide from the dispatcher. By default we hide all > * methods of the Controller class. > * > * @var array > */ > var $hiddenMethods = null; > /** 242a250,255 > > if (!empty($this->hiddenMethods)) { > $this->hiddenMethods = array_unique(array_merge($this->hiddenMethods, get_class_methods('Controller'))); > } else { > $this->hiddenMethods = get_class_methods('Controller'); > } 245a259,285 > * Hide method names from dispatcher, preventing them from being accessed using > * a URL. > * > * @param array $names Method names to hide from dispatcher. If omitted, *all* > * class methods will be hidden. > */ > function hideMethods($names = null) { > if (null === $names) { > $this->hiddenMethods = get_class_methods(get_class($this)); > } > if (!empty($this->hiddenMethods)) { > $this->hiddenMethods = array_unique(array_merge($this->hiddenMethods, $names)); > } else { > $this->hiddenMethods = $names; > } > } > /** > * Exposes methods in the array $names. > * > * @param unknown_type $names Array of method names to expose. > */ > function exposeMethods($names) { > if (!empty($this->hiddenMethods)) { > $this->hiddenMethods = array_diff($this->hiddenMethods, $names); > } > } > /**