kolibri-discuss team mailing list archive
-
kolibri-discuss team
-
Mailing list archive
-
Message #00036
[Merge] lp:~asteinlein/kolibri/request+response into lp:kolibri
Anders Steinlein has proposed merging lp:~asteinlein/kolibri/request+response into lp:kolibri.
Requested reviews:
Kolibri Dev (kolibri-dev)
--
https://code.launchpad.net/~asteinlein/kolibri/request+response/+merge/5529
Your team Kolibri Discuss is subscribed to branch lp:kolibri.
=== modified file 'examples/wishlist/actions/Index.php'
--- examples/wishlist/actions/Index.php 2009-04-07 22:06:43 +0000
+++ examples/wishlist/actions/Index.php 2009-04-14 16:50:50 +0000
@@ -4,7 +4,7 @@
* page as the result. We also implement ModelAware so any validation errors when adding items
* are displayed.
*/
-class Index extends ActionSupport implements ModelAware {
+class Index implements MessageAware, ModelAware {
public $model;
public $items;
@@ -16,14 +16,13 @@
$dbSetup = new DatabaseSetup();
if (!$dbSetup->isDone()) {
// Database tables is not set up, so redirect to setup page
- return new RedirectResult($this, '/setup');
+ return new RedirectResponse('/setup');
}
- $items = Models::init('Item');
// Notice that this calls findAll() in the ItemDao class
- $this->items = $items->objects->findAll();
+ $this->items = Models::init('Item')->objects->findAll();
// Path is relative to views directory, extension omitted
- return new XsltResult($this, '/index');
+ return new XsltResponse($this, '/index');
}
}
?>
=== modified file 'examples/wishlist/actions/Setup.php'
--- examples/wishlist/actions/Setup.php 2008-10-20 16:41:10 +0000
+++ examples/wishlist/actions/Setup.php 2009-04-14 16:50:50 +0000
@@ -2,7 +2,7 @@
/**
* Action for the setup page -- prepares database tables.
*/
-class Setup extends ActionSupport {
+class Setup implements MessageAware {
/**
* Displays the setup page if database is not already prepared.
*/
@@ -11,10 +11,10 @@
if ($dbSetup->isDone()) {
$this->msg->setMessage('Database is already prepared.');
- return new RedirectResult($this, '/');
+ return new RedirectResponse('/');
}
- return new XsltResult($this, '/setup');
+ return new XsltResponse($this, '/setup');
}
/**
@@ -24,7 +24,7 @@
$dbSetup = new DatabaseSetup();
$dbSetup->setup();
$this->msg->setMessage('Database prepared. All ready for wishes.');
- return new RedirectResult($this, '/');
+ return new RedirectResponse('/');
}
}
?>
=== modified file 'examples/wishlist/actions/items/Add.php'
--- examples/wishlist/actions/items/Add.php 2009-04-07 20:59:58 +0000
+++ examples/wishlist/actions/items/Add.php 2009-04-14 16:50:50 +0000
@@ -3,7 +3,7 @@
* Action for adding new item. We implement ModelAware to have the model object populated by
* request data, and ValidationAware to have it automatically validated.
*/
-class Add extends ActionSupport implements ModelAware, ValidationAware {
+class Add implements MessageAware, ModelAware, ValidationAware {
/**
* Defines the model class to instantiate, which will be populated with request data and
* put back into this property.
@@ -17,7 +17,7 @@
public function doPost () {
$this->model->save();
$this->msg->setMessage('Item successfully added.');
- return new RedirectResult($this, '/');
+ return new RedirectResponse('/');
}
/**
@@ -29,7 +29,7 @@
public function validationFailed () {
// We could set a custom error message here if we want to override the default. I.e.:
// $this->msg->setMessage('The item could not be added to the wishlist', false);
- return new RedirectResult($this, '/');
+ return new RedirectResponse('/');
}
}
?>
=== modified file 'examples/wishlist/actions/items/Del.php'
--- examples/wishlist/actions/items/Del.php 2008-12-03 02:22:07 +0000
+++ examples/wishlist/actions/items/Del.php 2009-04-14 16:50:50 +0000
@@ -3,12 +3,13 @@
* Action for deleting items. As the item to delete is specified by the last URI element (which does not have
* a matching action file), it is implicitly put in the "id" request parameter.
*/
-class Del extends ActionSupport {
+class Del implements MessageAware {
/**
* TODO: Should really change to POST via form (and thus doPost()).
*/
- public function doGet () {
- $itemName = $this->request['id']; // We could also do $this->request->get('id'), whatever you prefer
+ public function doGet ($request) {
+ // We could also do $this->request->get('id'), whatever you prefer
+ $itemName = $request['id'];
$item = Models::init('Item');
// Tries to load the item (notice that this calls load() in the ItemDao class)
@@ -22,7 +23,8 @@
$this->msg->setMessage("Item with name $itemName not found.", false);
}
- return new RedirectResult($this, '/'); // Redirect back to front page, notice messages are retained
+ // Redirect back to front page, notice messages are retained
+ return new RedirectResponse('/');
}
}
?>
=== modified file 'examples/wishlist/actions/items/Have.php'
--- examples/wishlist/actions/items/Have.php 2008-12-03 02:22:07 +0000
+++ examples/wishlist/actions/items/Have.php 2009-04-14 16:50:50 +0000
@@ -2,11 +2,11 @@
/**
* Action for marking items as received.
*/
-class Have extends ActionSupport {
+class Have implements MessageAware {
// TODO: We should really POST instead...
- public function doGet () {
+ public function doGet ($request) {
$item = Models::init('Item');
- if ($item->objects->load($this->request['id'])) {
+ if ($item->objects->load($request['id'])) {
// Set received date (could of course be done in SQL, but just to show date library in use)
$df = DateFormat::getInstance(DateFormat::ISO_8601_DATE);
$item->received = $df->format(new Date());
@@ -19,7 +19,7 @@
$this->msg->setMessage("Item with name {$this->request['id']} not found.", false);
}
- return new RedirectResult($this, '/');
+ return new RedirectResponse('/');
}
}
?>
=== modified file 'examples/wishlist/conf/config.php'
--- examples/wishlist/conf/config.php 2009-04-07 23:17:37 +0000
+++ examples/wishlist/conf/config.php 2009-04-14 16:50:50 +0000
@@ -4,7 +4,7 @@
* get by calling Config::get('key'), where key is the setting you want to return, i.e. 'mail'.
*/
$config = array(
- 'webRoot' => 'http://localhost', // Must be absolute URI including scheme. No trailing slash!
+ 'webRoot' => 'http://kolibri', // Must be absolute URI including scheme. No trailing slash!
'staticRoot' => '/static', // URI of static resources (can be another host as http://static.example.com)
'locale' => 'en_US.utf8',
'logging' => array(
=== removed file 'src/actions/ActionSupport.php'
--- src/actions/ActionSupport.php 2008-12-09 23:12:48 +0000
+++ src/actions/ActionSupport.php 1970-01-01 00:00:00 +0000
@@ -1,38 +0,0 @@
-<?php
-require(ROOT . '/actions/SessionAware.php');
-require(ROOT . '/actions/MessageAware.php');
-
-/**
- * This class provides support-functionality needed by most actions. It is entirely optional for
- * actions to extend this class, but most will.
- */
-class ActionSupport implements SessionAware, MessageAware {
- /**
- * The processing request.
- * @var Request
- */
- protected $request;
-
- /**
- * The HTTP session, if a <code>SessionInterceptor</code> is in use.
- * @var Session
- */
- public $session;
-
- /**
- * Message facility which may be used to return a message to the user. This is only set if the
- * <code>MessageInterceptor</code> is invoked, else it is empty.
- * @var Message
- */
- public $msg;
-
- /**
- * Constructor.
- *
- * @param Request $request The request object representing the current HTTP request.
- */
- public function __construct ($request) {
- $this->request = $request;
- }
-}
-?>
=== modified file 'src/actions/MessageAware.php'
--- src/actions/MessageAware.php 2008-10-20 16:41:10 +0000
+++ src/actions/MessageAware.php 2009-04-14 16:50:50 +0000
@@ -1,9 +1,9 @@
<?php
/**
- * This interface is used by actions that want to return messages to the user. They must also provide a
- * public <code>$msg</code> property to hold the actual <code>Message</code> instance.
- *
- * @version $Id: MessageAware.php 1493 2008-04-30 00:00:25Z anders $
+ * This interface is used by actions that want to return messages to the user. The
+ * <code>MessageInterceptor</code> must be configured for the action in order to prepare the
+ * message facility for use, which will be set in an implicit <code>$msg</code> property on
+ * the action.
*/
interface MessageAware {}
?>
=== modified file 'src/actions/ParametersAware.php'
--- src/actions/ParametersAware.php 2008-10-20 16:41:10 +0000
+++ src/actions/ParametersAware.php 2009-04-14 16:50:50 +0000
@@ -1,8 +1,8 @@
<?php
/**
- * This interface is used by actions that want properties populated from session and/or request parameters.
- *
- * @version $Id: ParametersAware.php 1518 2008-06-30 23:43:38Z anders $
+ * This interface is used by actions that want properties populated from session and/or request
+ * parameters. The <code>ParametersInterceptor</code> must also be configured for the action
+ * for this to have any effect.
*/
interface ParametersAware {}
?>
=== removed file 'src/actions/SessionAware.php'
--- src/actions/SessionAware.php 2008-10-20 16:41:10 +0000
+++ src/actions/SessionAware.php 1970-01-01 00:00:00 +0000
@@ -1,9 +0,0 @@
-<?php
-/**
- * This interface is used by actions that want access to session data. Actions implementing this interface
- * must also expose a public <code>session</code> property.
- *
- * @version $Id: SessionAware.php 1518 2008-06-30 23:43:38Z anders $
- */
-interface SessionAware {}
-?>
=== modified file 'src/actions/UploadAware.php'
--- src/actions/UploadAware.php 2008-10-20 16:41:10 +0000
+++ src/actions/UploadAware.php 2009-04-14 16:50:50 +0000
@@ -1,9 +1,8 @@
<?php
/**
- * This interface is used by actions that want uploaded files direct put into action instance variables.
- * The <code>UploadInterceptor</code> must be invoked for this to have any effect.
- *
- * @version $Id: UploadAware.php 1538 2008-08-03 22:10:45Z anders $
+ * This interface is used by actions that want uploaded files direct put into action instance
+ * variables, or a property on an exposed model. The <code>UploadInterceptor</code> must be
+ * configured for this to have any effect.
*/
interface UploadAware {}
?>
=== modified file 'src/actions/ValidationAware.php'
--- src/actions/ValidationAware.php 2009-04-12 02:11:21 +0000
+++ src/actions/ValidationAware.php 2009-04-14 16:50:50 +0000
@@ -6,14 +6,14 @@
* validate.
*
* If validation fails the <code>validationFailed()</code> method on the action is called for
- * it to return the response it deems appropriate, which is usually a RedirectResult back to
+ * it to return the response it deems appropriate, which is usually a SeeOtherResponse back to
* the form. If however validation succeeds, normal request processing proceeds.
*/
interface ValidationAware {
/**
- * Called when validation failed. A Result object must be returned, which will be rendered
- * instead of continuing request processing.
+ * Called when validation failed. A <code>Response</code> object must be returned, which
+ * will be rendered instead of continuing request processing.
*/
- public function validationFailed () {}
+ public function validationFailed ();
}
?>
=== modified file 'src/conf/autoload.php'
--- src/conf/autoload.php 2009-04-12 01:09:55 +0000
+++ src/conf/autoload.php 2009-04-14 16:50:50 +0000
@@ -1,52 +1,50 @@
<?php
/*
- * Defines classes that may be loaded upon its first use by __autoload(). They are not automatically
- * loaded unless they are actually used. See <code>UtilsInterceptor</code> for automatic loading of utils.
+ * Defines classes that may be loaded upon its first use by __autoload(). They are not
+ * automatically loaded unless they are actually used. See <code>UtilsInterceptor</code> for
+ * automatic loading of utils.
*/
$autoloadClasses = array(
- 'DefaultActionMapper' => '/core/DefaultActionMapper.php',
- 'ActionSupport' => '/actions/ActionSupport.php',
- 'AuthAware' => '/actions/AuthAware.php',
- 'MessageAware' => '/actions/MessageAware.php',
- 'ModelAware' => '/actions/ModelAware.php',
- 'ParametersAware' => '/actions/ParametersAware.php',
- 'SessionAware' => '/actions/SessionAware.php',
- 'UploadAware' => '/actions/UploadAware.php',
- 'ValidationAware' => '/actions/ValidationAware.php',
- 'DatabaseException' => '/database/DatabaseException.php',
- 'DatabaseFactory' => '/database/DatabaseFactory.php',
- 'ResultSet' => '/database/ResultSet.php',
- 'ResultSetArray' => '/database/ResultSetArray.php',
- 'SqlException' => '/database/SqlException.php',
- 'AbstractInterceptor' => '/interceptors/AbstractInterceptor.php',
- 'AuthInterceptor' => '/interceptors/AuthInterceptor.php',
- 'ErrorInterceptor' => '/interceptors/ErrorInterceptor.php',
- 'Interceptor' => '/interceptors/Interceptor.php',
- 'MessageInterceptor' => '/interceptors/MessageInterceptor.php',
- 'ModelInterceptor' => '/interceptors/ModelInterceptor.php',
- 'ParametersInterceptor' => '/interceptors/ParametersInterceptor.php',
- 'SessionInterceptor' => '/interceptors/SessionInterceptor.php',
- 'UploadInterceptor' => '/interceptors/UploadInterceptor.php',
- 'UtilsInterceptor' => '/interceptors/UtilsInterceptor.php',
- 'ValidationInterceptor' => '/interceptors/ValidationInterceptor.php',
- 'TransactionInterceptor' => '/interceptors/TransactionInterceptor.php',
- 'DataProvided' => '/models/DataProvided.php',
- 'ModelProxy' => '/models/ModelProxy.php',
- 'Models' => '/models/Models.php',
- 'Proxy' => '/models/Proxy.php',
- 'Validateable' => '/models/Validateable.php',
- 'ValidateableModelProxy' => '/models/ValidateableModelProxy.php',
- 'AbstractResult' => '/results/AbstractResult.php',
- 'FileResult' => '/results/FileResult.php',
- 'ForwardResult' => '/results/ForwardResult.php',
- 'JsonResult' => '/results/JsonResult.php',
- 'NotFoundResult' => '/results/NotFoundResult.php',
- 'PhpResult' => '/results/PhpResult.php',
- 'RedirectResult' => '/results/RedirectResult.php',
- 'Result' => '/results/Result.php',
- 'SmartyResult' => '/results/SmartyResult.php',
- 'TextResult' => '/results/TextResult.php',
- 'XsltResult' => '/results/XsltResult.php',
- 'Validator' => '/validation/Validator.php',
- 'ValidationHelper' => '/validation/ValidationHelper.php');
+ 'DefaultActionMapper' => '/core/DefaultActionMapper.php',
+ 'AuthAware' => '/actions/AuthAware.php',
+ 'MessageAware' => '/actions/MessageAware.php',
+ 'ModelAware' => '/actions/ModelAware.php',
+ 'ParametersAware' => '/actions/ParametersAware.php',
+ 'UploadAware' => '/actions/UploadAware.php',
+ 'ValidationAware' => '/actions/ValidationAware.php',
+ 'DatabaseException' => '/database/DatabaseException.php',
+ 'DatabaseFactory' => '/database/DatabaseFactory.php',
+ 'ResultSet' => '/database/ResultSet.php',
+ 'ResultSetArray' => '/database/ResultSetArray.php',
+ 'SqlException' => '/database/SqlException.php',
+ 'AbstractInterceptor' => '/interceptors/AbstractInterceptor.php',
+ 'AuthInterceptor' => '/interceptors/AuthInterceptor.php',
+ 'ErrorInterceptor' => '/interceptors/ErrorInterceptor.php',
+ 'Interceptor' => '/interceptors/Interceptor.php',
+ 'MessageInterceptor' => '/interceptors/MessageInterceptor.php',
+ 'ModelInterceptor' => '/interceptors/ModelInterceptor.php',
+ 'ParametersInterceptor' => '/interceptors/ParametersInterceptor.php',
+ 'SessionInterceptor' => '/interceptors/SessionInterceptor.php',
+ 'UploadInterceptor' => '/interceptors/UploadInterceptor.php',
+ 'UtilsInterceptor' => '/interceptors/UtilsInterceptor.php',
+ 'ValidationInterceptor' => '/interceptors/ValidationInterceptor.php',
+ 'TransactionInterceptor' => '/interceptors/TransactionInterceptor.php',
+ 'DataProvided' => '/models/DataProvided.php',
+ 'ModelProxy' => '/models/ModelProxy.php',
+ 'Models' => '/models/Models.php',
+ 'Proxy' => '/models/Proxy.php',
+ 'Validateable' => '/models/Validateable.php',
+ 'ValidateableModelProxy' => '/models/ValidateableModelProxy.php',
+ 'FileResponse' => '/response/FileResponse.php',
+ 'JsonResponse' => '/response/JsonResponse.php',
+ 'NotFoundResponse' => '/response/NotFoundResponse.php',
+ 'PermanentRedirectResponse' => '/response/PermanentRedirectResponse.php',
+ 'PhpResponse' => '/response/PhpResponse.php',
+ 'RedirectResponse' => '/response/RedirectResponse.php',
+ 'Response' => '/response/Response.php',
+ 'SeeOtherResponse' => '/response/SeeOtherResponse.php',
+ 'SmartyResponse' => '/response/SmartyResponse.php',
+ 'XsltResponse' => '/response/XsltResponse.php',
+ 'Validator' => '/validation/Validator.php',
+ 'ValidationHelper' => '/validation/ValidationHelper.php');
?>
=== modified file 'src/core/Dispatcher.php'
--- src/core/Dispatcher.php 2008-10-20 16:41:10 +0000
+++ src/core/Dispatcher.php 2009-04-10 01:43:31 +0000
@@ -39,7 +39,7 @@
*
* The interceptors mapped to the target action is created and pushed to the dispatcher stack.
*
- * @param Request $request Request object for the interceptors.
+ * @param Request $request Request object.
* @param ActionMapping $actionMapping Mapping to the action to invoke.
* @return Dispatcher
*/
@@ -81,7 +81,7 @@
}
$class = $actionMapping->getActionClass();
- $this->action = new $class($request);
+ $this->action = new $class();
$this->stack = InterceptorFactory::createInterceptors($stack);
}
@@ -108,7 +108,7 @@
return $result;
}
}
- return $this->action->{$this->actionMethod}();
+ return $this->action->{$this->actionMethod}($this->getRequest());
}
public function getRequest () {
=== modified file 'src/core/Request.php'
--- src/core/Request.php 2009-04-03 16:04:34 +0000
+++ src/core/Request.php 2009-04-12 16:32:29 +0000
@@ -22,15 +22,21 @@
* @var string
*/
public $method;
+
+ /**
+ * HTTP session if enabled by a <code>SessionInterceptor</code>.
+ * @var Session
+ */
+ public $session;
/**
- * Creates an instance of this class. GET and POST parameters are merged. If any parameter keys
- * conflicts, POST parameters override GET parameters.
+ * Creates an instance of this class. GET and POST parameters are merged. If any parameter
+ * keys conflicts, POST parameters override GET parameters.
*
- * @param array $get_params GET parameters for this request.
- * @param array $post_params POST parameters for this request.
- * @param string $uri URI of this request. Leave empty to use the actual request URI
- * from the client.
+ * @param array $getParams GET parameters for this request.
+ * @param array $postParams POST parameters for this request.
+ * @param string $uri URI of this request. Leave empty to use the actual request URI
+ * from the client.
*/
public function __construct ($getParams, $postParams, $uri = null) {
$this->params = array_merge($getParams, $postParams);
@@ -84,23 +90,28 @@
}
/**
- * Returns the value of the parameter with the specified key, or <code>NULL</code> if the parameter is
- * not found.
+ * Returns the value of the parameter with the specified key, or <code>null</code> if the
+ * parameter is not found.
*
* @param string $key Key to the parameter to return.
- * @return string Value of the parameter, or <code>NULL</code>.
+ * @return string Value of the parameter, or <code>null</code>.
*/
public function get ($key) {
return (isset($this->params[$key]) ? $this->params[$key] : null);
}
/**
- * Returns all request parameters.
- *
- * @return array Request parameters as key-value pairs.
+ * Returns the value of the specified request header, or <code>null</code> if the header
+ * isn't set set.
+ *
+ * Note that this is currently only a wrapper for $_SERVER, and thus contains more than
+ * only the request headers.
+ *
+ * @param string $header Header to look for.
+ * @param string Value of header, or <code>null</code>.
*/
- public function getAll () {
- return $this->params;
+ public function getHeader ($header) {
+ return (isset($_SERVER[$header]) ? $_SERVER[$header] : null);
}
/**
@@ -122,8 +133,17 @@
}
/**
- * Puts all the supplied parameters into the parameters for this request. Should only be used internally
- * by the framework.
+ * Checks whether this request has a session associated with it.
+ *
+ * @return bool <code>true</code> if session exists, <code>false</code> if not.
+ */
+ public function hasSession () {
+ return isset($this->session);
+ }
+
+ /**
+ * Puts all the supplied parameters into the parameters for this request. Should only be
+ * used internally by the framework.
*
* @param array $params An associated array with parameters.
*/
=== modified file 'src/core/RequestProcessor.php'
--- src/core/RequestProcessor.php 2008-10-20 16:41:10 +0000
+++ src/core/RequestProcessor.php 2009-04-11 23:30:29 +0000
@@ -37,8 +37,6 @@
* Process the request.
*/
public function process () {
- //echo "Processing request [uri: $this->uri] => [action: $this->action_path]...\n";
-
// Map the request to an action
$mapping = $this->mapper->map();
if ($mapping === null) {
=== modified file 'src/core/Session.php'
--- src/core/Session.php 2008-12-09 23:12:48 +0000
+++ src/core/Session.php 2009-04-10 01:43:31 +0000
@@ -30,10 +30,10 @@
}
/**
- * Retrieves a specific session parameter, or NULL if not set.
- *
- * @param mixed $key Session parameter to retrieve.
- * @return mixed The session parameter, or NULL if not set.
+ * Returns the value of the session data with the specified key.
+ *
+ * @param string $key Key to the value to return.
+ * @return string Value of the data, or <code>null</code> if not found.
*/
public function offsetGet ($key) {
return (isset($_SESSION[$key]) ? $_SESSION[$key] : null);
@@ -71,10 +71,10 @@
* Returns the value of the session data with the specified key.
*
* @param string $key Key to the value to return.
- * @return string Value of the data, or <code>FALSE</code> if not found.
+ * @return string Value of the data, or <code>null</code> if not found.
*/
public function get ($key) {
- return (isset($_SESSION[$key]) ? $_SESSION[$key] : false);
+ return (isset($_SESSION[$key]) ? $_SESSION[$key] : null);
}
/**
=== modified file 'src/interceptors/AbstractInterceptor.php'
--- src/interceptors/AbstractInterceptor.php 2008-10-20 16:41:10 +0000
+++ src/interceptors/AbstractInterceptor.php 2009-04-10 01:43:31 +0000
@@ -1,17 +1,16 @@
<?php
/**
- * This is an abstract convenience class for interceptors. It implements empty <code>init()</code> and
- * <code>destroy()</code> methods so subclasses only have to implement <code>intercept()</code>.
- *
- * @version $Id: AbstractInterceptor.php 1492 2008-04-29 23:57:42Z anders $
+ * This is an abstract convenience class for interceptors. It implements empty
+ * <code>init()</code> and <code>destroy()</code> methods so subclasses only have to
+ * implement <code>intercept()</code>.
*/
abstract class AbstractInterceptor implements Interceptor {
/**
- * Creates an interceptor instance. If any configuration is supplied, matching properties are set on
- * the instance. This requires that the concrete interceptor implementation defines the properties as
- * protected or public.
+ * Creates an interceptor instance. If any configuration is supplied, matching properties
+ * are set on the instance. This requires that the concrete interceptor implementation
+ * defines the properties as protected or public.
*
- * @param array $conf Configuration for this interceptor, if any.
+ * @param array $conf Configuration for this interceptor, if any.
*/
public function __construct ($conf = null) {
if ($conf !== null) {
=== modified file 'src/interceptors/AuthInterceptor.php'
--- src/interceptors/AuthInterceptor.php 2008-10-20 16:41:10 +0000
+++ src/interceptors/AuthInterceptor.php 2009-04-14 16:50:50 +0000
@@ -2,10 +2,9 @@
/**
* Interceptor which checks to see if the user making this request is authenticated.
*
- * If the target action is <code>AuthAware</code> and implements the <code>allowedAccess()</code> method,
- * the user is passed to the action for it to determine whether to allow access.
- *
- * @version $Id: AuthInterceptor.php 1537 2008-08-02 19:22:57Z anders $
+ * If session is enabled, the target action is <code>AuthAware</code> and implements the
+ * <code>allowedAccess()</code> method, the user is passed to the action for it to determine
+ * whether to allow access.
*/
class AuthInterceptor extends AbstractInterceptor {
/**
@@ -38,25 +37,30 @@
*/
public function intercept ($dispatcher) {
$action = $dispatcher->getAction();
- $user = $action->session[$this->userKey];
-
- if (!$this->isUserAuthenticated($user)) {
- $action->session['target'] = $dispatcher->getRequest()->getUri();
- if ($action instanceof MessageAware) {
- $action->msg->setMessage('Vennligst logg inn for å komme til siden du forespurte.', false);
+ $request = $dispatcher->getRequest();
+
+ if ($request->hasSession()) {
+ $user = $request->session[$this->userKey];
+
+ if (!$this->isUserAuthenticated($user)) {
+ $request->session['target'] = $request->getUri();
+ if ($action instanceof MessageAware) {
+ $action->msg->setMessage('You must log in to access
+ the page you requested.', false);
+ }
+
+ return $this->denyAccess($dispatcher);
}
- return $this->denyAccess($dispatcher);
- }
+ if ($action instanceof AuthAware) {
+ if (method_exists($action, 'allowedAccess')) {
+ if (!$action->allowedAccess($user)) {
+ if (method_exists($action, 'denyAccess')) {
+ return $action->denyAccess($user);
+ }
- if ($action instanceof AuthAware) {
- if (method_exists($action, 'allowedAccess')) {
- if (!$action->allowedAccess($user)) {
- if (method_exists($action, 'denyAccess')) {
- return $action->denyAccess($user);
+ return $this->denyAccess();
}
-
- return $this->denyAccess($dispatcher);
}
}
}
@@ -66,8 +70,8 @@
/**
* Makes sure the user value found in the session is of the correct type.
*
- * @param mixed $user Session value to make sure represents a user.
- * @return bool TRUE if $user represents an authenticated user, FALSE if not.
+ * @param mixed $user Session value to make sure represents a user.
+ * @return bool TRUE if $user represents an authenticated user, FALSE if not.
*/
private function isUserAuthenticated ($user) {
if ($user !== null) {
@@ -86,8 +90,8 @@
/**
* Denies access by redirecting to the configured login URI.
*/
- private function denyAccess ($dispatcher) {
- return new RedirectResult($dispatcher->getAction(), $this->loginUri);
+ private function denyAccess () {
+ return new RedirectResponse($this->loginUri);
}
}
?>
=== modified file 'src/interceptors/ErrorInterceptor.php'
--- src/interceptors/ErrorInterceptor.php 2008-12-17 15:50:47 +0000
+++ src/interceptors/ErrorInterceptor.php 2009-04-10 01:43:31 +0000
@@ -2,11 +2,9 @@
require(ROOT . '/lib/ErrorHandler.php');
/**
- * Interceptor which prepares and sets an error handler. Any errors triggered or exceptions thrown after
- * this interceptor is invoked will be handled by the error handler defined by this interceptor, unless
- * otherwised catched (for exceptions).
- *
- * TODO: Pluggable error handler. Specify class name by config option?
+ * Interceptor which prepares and sets an error handler. Any errors triggered or exceptions
+ * thrown after this interceptor is invoked will be handled by the error handler defined by
+ * this interceptor, unless otherwised catched (for exceptions).
*/
class ErrorInterceptor extends AbstractInterceptor {
/**
=== modified file 'src/interceptors/Interceptor.php'
--- src/interceptors/Interceptor.php 2008-10-20 16:41:10 +0000
+++ src/interceptors/Interceptor.php 2009-04-10 01:43:31 +0000
@@ -1,13 +1,11 @@
<?php
/**
* This interface defines the contract of an interceptor.
- *
- * @version $Id: Interceptor.php 1478 2008-04-02 14:04:52Z anders $
*/
interface Interceptor {
/**
- * Initializes any resources required by the interceptor before use. This is called for all active
- * interceptors before the first one is invoked.
+ * Initializes any resources required by the interceptor before use. This is called for all
+ * active interceptors before the first one is invoked.
*/
public function init ();
@@ -17,12 +15,13 @@
public function destroy ();
/**
- * Executes this interceptor, by doing some processing before and/or after the rest of the request
- * processing. Interceptors can short-circuit the processing by returning a <code>Result</code> itself,
- * or delegate further processing of the request through <code>$dispatcher->invoke()</code>.
+ * Executes this interceptor, by doing some processing before and/or after the rest of the
+ * request processing. Interceptors can short-circuit the processing by returning a
+ * <code>Result</code> itself, or delegate further processing of the request through
+ * <code>$dispatcher->invoke()</code>.
*
- * @param Dispatcher $dispatcher Dispatcher handling the request processing flow.
- * @return Result The result of the request.
+ * @param Dispatcher $dispatcher Dispatcher handling the request processing flow.
+ * @return Result The result of the request.
*/
public function intercept ($dispatcher);
}
=== modified file 'src/interceptors/MessageInterceptor.php'
--- src/interceptors/MessageInterceptor.php 2009-04-07 22:47:54 +0000
+++ src/interceptors/MessageInterceptor.php 2009-04-14 16:50:50 +0000
@@ -3,7 +3,8 @@
/**
* Interceptor which provides the target action, if <code>MessageAware</code>, with a facility
- * to give the user status messages.
+ * to give the user status messages. The facility is set in an implicit <code>$msg</code>
+ * property on the action.
*/
class MessageInterceptor extends AbstractInterceptor {
/**
@@ -11,12 +12,13 @@
*/
public function intercept ($dispatcher) {
$action = $dispatcher->getAction();
+ $request = $dispatcher->getRequest();
if ($action instanceof MessageAware) {
// If a previous message is set in the session, put it into the action
- if ($action instanceof SessionAware && isset($action->session['message'])) {
- $action->msg = $action->session['message'];
- $action->session->remove('message');
+ if ($request->hasSession() && isset($request->session['message'])) {
+ $action->msg = $request->session['message'];
+ $request->session->remove('message');
}
// Otherwise create a new instance
else {
@@ -28,13 +30,13 @@
/*
* If we are about to redirect and a message has been set, save it temporarily in the
- * session so it can be retrieved in the new location.
+ * session (if present) so it can be retrieved in the new location.
*/
- if ($result instanceof RedirectResult
- && $action instanceof SessionAware
+ if ($result instanceof RedirectResponse
&& $action instanceof MessageAware
- && !$action->msg->isEmpty()) {
- $action->session['message'] = $action->msg;
+ && !$action->msg->isEmpty()
+ && $request->hasSession()) {
+ $request->session['message'] = $action->msg;
}
return $result;
=== modified file 'src/interceptors/ModelInterceptor.php'
--- src/interceptors/ModelInterceptor.php 2009-04-12 01:09:55 +0000
+++ src/interceptors/ModelInterceptor.php 2009-04-14 16:50:50 +0000
@@ -24,6 +24,8 @@
$action = $dispatcher->getAction();
if ($action instanceof ModelAware) {
+ $request = $dispatcher->getRequest();
+
// We depend on a $model-property in ModelAware actions
if (!property_exists($action, 'model')) {
$class = get_class($action);
@@ -37,11 +39,12 @@
* take precedence, to stop any invalid model in the session to override the newly
* POSTed.
*/
- if ($dispatcher->getRequest()->getMethod() == 'GET'
- && $action instanceof SessionAware && isset($action->session['model'])) {
- $action->model = $action->session['model'];
+ if ($request->getMethod() == 'GET'
+ && $request->hasSession()
+ && isset($request->session['model'])) {
+ $action->model = $request->session['model'];
// Model has been extracted, remove it from session
- $action->session->remove('model');
+ $request->session->remove('model');
}
// Otherwise prepare a model from request parameters
else {
@@ -55,7 +58,7 @@
}
if ($model !== null) {
- foreach ($dispatcher->getRequest()->params as $param => $value) {
+ foreach ($request->params as $param => $value) {
if (strpos($param, '::') !== false) {
/*
* Parameter is a property path to inner models. Explode the path
=== modified file 'src/interceptors/ParametersInterceptor.php'
--- src/interceptors/ParametersInterceptor.php 2009-04-03 16:04:34 +0000
+++ src/interceptors/ParametersInterceptor.php 2009-04-10 01:43:31 +0000
@@ -1,9 +1,7 @@
<?php
/**
- * Interceptor which puts session and/or request parameters into corresponding properties of the target
- * action if <code>ParametersAware</code>.
- *
- * @version $Id: ParametersInterceptor.php 1518 2008-06-30 23:43:38Z anders $
+ * Interceptor which puts session and/or request parameters into corresponding properties of
+ * the target action if <code>ParametersAware</code>.
*/
class ParametersInterceptor extends AbstractInterceptor {
/**
@@ -13,11 +11,13 @@
$action = $dispatcher->getAction();
if ($action instanceof ParametersAware) {
- if ($action instanceof SessionAware) {
- $this->populate($action, $action->session);
+ $request = $dispatcher->getRequest();
+
+ $this->populate($action, $request->params);
+
+ if ($request->hasSession()) {
+ $this->populate($action, $request->session);
}
-
- $this->populate($action, $dispatcher->getRequest()->getAll());
}
return $dispatcher->invoke();
=== modified file 'src/interceptors/SessionInterceptor.php'
--- src/interceptors/SessionInterceptor.php 2008-12-08 18:45:30 +0000
+++ src/interceptors/SessionInterceptor.php 2009-04-10 01:43:31 +0000
@@ -2,26 +2,16 @@
require(ROOT . '/core/Session.php');
/**
- * Interceptor which prepares a session for use. A <code>Session</code> object is created and injected
- * into the <code>Request</code>.
- *
- * If the target action is <code>SessionAware</code> the session data is set on the action as well.
- *
- * @version $Id: SessionInterceptor.php 1518 2008-06-30 23:43:38Z anders $
+ * Interceptor which prepares a session for use. A <code>Session</code> object is created and
+ * injected into the <code>Request</code>.
*/
class SessionInterceptor extends AbstractInterceptor {
/**
- * Instantiates a <code>Session</code> object and injects it into the request. If the action is
- * <code>SessionAware</code>, pass in session data.
+ * Invokes and processes the interceptor.
*/
public function intercept ($dispatcher) {
- $action = $dispatcher->getAction();
-
- if ($action instanceof SessionAware) {
- $session = new Session();
- $action->session = $session;
- }
-
+ $session = new Session();
+ $dispatcher->getRequest()->session = $session;
return $dispatcher->invoke();
}
}
=== modified file 'src/interceptors/UploadInterceptor.php'
--- src/interceptors/UploadInterceptor.php 2009-02-22 03:41:01 +0000
+++ src/interceptors/UploadInterceptor.php 2009-04-10 01:43:31 +0000
@@ -2,14 +2,12 @@
require(ROOT . '/lib/UploadFile.php');
/**
- * Interceptor handling file uploads. For each file uploaded a <code>UploadFile</code> object representing
- * the uploaded file is created.
+ * Interceptor handling file uploads.
*
- * If the target action is <code>ModelAware</code> and its model is prepared, each file is set on the
- * model. If on the other hand the action is <code>UploadAware</code>, the files are instead set directly
- * on the action.
- *
- * @version $Id: UploadInterceptor.php 1510 2008-06-17 05:45:50Z anders $
+ * For each file uploaded a <code>UploadFile</code> object representing the uploaded file is
+ * created. If the target action is <code>ModelAware</code> and its model is prepared, each
+ * file is set on the model. If on the other hand the action is <code>UploadAware</code>, the
+ * files are instead set directly on the action.
*/
class UploadInterceptor extends AbstractInterceptor {
/**
@@ -29,13 +27,14 @@
foreach ($_FILES as $param => $file) {
/*
- * Only validate that file(s) were actually uploaded (they can still have errors,
- * which will be contained in the UploadFile).
+ * Only validate that file(s) were actually uploaded (they can still have
+ * errors, which will be contained in the UploadFile).
*/
if (is_array($file['error'])) {
foreach ($file['name'] as $i => $name) {
if ($file['error'][$i] != UPLOAD_ERR_NO_FILE) {
- $files[] = new UploadFile($name, $file['tmp_name'][$i], $file['error'][$i]);
+ $files[] = new UploadFile($name, $file['tmp_name'][$i],
+ $file['error'][$i]);
}
}
if (isset($files)) {
@@ -43,7 +42,8 @@
}
}
else if ($file['error'] != UPLOAD_ERR_NO_FILE) {
- $setOn->$param = new UploadFile($file['name'], $file['tmp_name'], $file['error']);
+ $setOn->$param = new UploadFile($file['name'], $file['tmp_name'],
+ $file['error']);
}
}
}
=== modified file 'src/interceptors/UtilsInterceptor.php'
--- src/interceptors/UtilsInterceptor.php 2008-10-20 16:41:10 +0000
+++ src/interceptors/UtilsInterceptor.php 2009-04-10 01:43:31 +0000
@@ -1,8 +1,6 @@
<?php
/**
* Interceptor which loads utils listed in a <code>loadUtils</code> config setting.
- *
- * @version $Id: UtilsInterceptor.php 1510 2008-06-17 05:45:50Z anders $
*/
class UtilsInterceptor extends AbstractInterceptor {
/**
=== modified file 'src/interceptors/ValidationInterceptor.php'
--- src/interceptors/ValidationInterceptor.php 2009-04-08 15:34:28 +0000
+++ src/interceptors/ValidationInterceptor.php 2009-04-14 16:50:50 +0000
@@ -6,7 +6,7 @@
* which we are to validate in a public <code>$model</code> property. This model is usually
* populated by a <code>ModelInterceptor</code>. If validation fails, the
* <code>validationFailed()</code> method on the action is called for the action to determine
- * the result and set any custom error message.
+ * the response and set any custom error message.
*/
class ValidationInterceptor extends AbstractInterceptor {
/**
@@ -40,11 +40,11 @@
}
/*
- * If the result is a redirect and sessions are enabled, store model for
+ * If the response is a redirect and sessions are enabled, store model for
* retrieval after redirect.
*/
- if ($result instanceof RedirectResult && $action instanceof SessionAware) {
- $action->session['model'] = $action->model;
+ if ($result instanceof RedirectResponse && $dispatcher->getRequest()->hasSession()) {
+ $dispatcher->getRequest()->session['model'] = $action->model;
}
}
=== renamed directory 'src/results' => 'src/response'
=== renamed file 'src/results/FileResult.php' => 'src/response/FileResponse.php'
--- src/results/FileResult.php 2008-12-17 15:50:47 +0000
+++ src/response/FileResponse.php 2009-04-11 23:30:29 +0000
@@ -1,60 +1,64 @@
<?php
/**
- * Implementation of a result set where a file is returned to the client. The contents may come
- * from an actual file on the file system or data passed to this class when it is instantiated.
+ * Response implementation where a file is returned to the client. The contents may come
+ * from an actual file or data passed to this class.
*/
-class FileResult extends AbstractResult {
+class FileResponse extends Response {
private $outputName;
- private $data;
private $dataIsFile;
/**
- * Constructor.
+ * Initialize this response.
*
- * @param object $action Current action.
+ * @param mixed $data File data to return or a file name of the file.
* @param string $mime MIME-type of the file.
* @param string $charset Charset of the file.
- * @param string $data Data contents to return directly or file name of the file.
- * @param bool $isFile <code>TRUE</code> if $data is a file name, <code>FALSE</code> if not.
- * @param string $outputName Optional name to give the returned file, if different from $file when
- * referring to an actual file.
+ * @param bool $isFile <code>true</code> if $data is a file name,
+ * <code>false</code> if not.
+ * @param string $outputName Name to give the returned file. Optional when $file is a file
+ * name.
*/
- public function __construct ($action, $mime, $charset, $data, $isFile = false, $outputName = false) {
- parent::__construct($action, $mime, $charset);
+ public function __construct ($data, $mime, $charset, $isFile = false, $outputName = null) {
+ parent::__construct($data, 200, $mime, $charset);
if (empty($data)) {
- throw new Exception('No data supplied');
- }
-
- $this->data = $data;
- $this->dataIsFile = $isFile;
-
- if (empty($outputName)) {
+ throw new Exception('No file data or file path supplied.');
+ }
+
+ if ($isFile) {
+ if (!file_exists($data)) {
+ throw new Exeption("File $data to return to user does not exist.");
+ }
+ }
+
+ if ($outputName === null) {
// If actual file and no custom file name, set correct file name
if ($isFile) {
$this->outputName = basename($data);
}
else {
- throw new Exception('No output file name given');
+ throw new Exception('No output file name given.');
+ }
}
else {
$this->outputName = $outputName;
}
+
+ $this->dataIsFile = $isFile;
}
/**
* Sends the file to the client.
*/
public function render ($request) {
- header("Content-Type: {$this->contentType}; charset={$this->charset}");
- header("Content-Disposition: attachment; filename=\"{$this->outputName}\"");
+ $this->setHeader('Content-Disposition', "attachment; filename=\"$this->outputName\"");
- if ($this->dataIsFile && is_file($this->data)) {
- header('Content-Length: ' . filesize($this->data));
+ if ($this->dataIsFile) {
+ $this->setHeader('Content-Length', filesize($this->data));
readfile($this->data);
}
else {
- header('Content-Length: ' . mb_strlen($this->data));
+ $this->setHeader('Content-Length', mb_strlen($this->data));
echo $this->data;
}
}
=== renamed file 'src/results/JsonResult.php' => 'src/response/JsonResponse.php'
--- src/results/JsonResult.php 2008-12-17 15:50:47 +0000
+++ src/response/JsonResponse.php 2009-04-11 23:30:29 +0000
@@ -1,29 +1,23 @@
<?php
/**
- * This result renders a JSON response with data to the client.
+ * This response renders the data as a JSON string to the client.
*/
-class JsonResult implements Result {
- private $data;
- private $charset;
-
+class JsonResponse extends Response {
/**
- * Constructor.
+ * Initialize this response.
*
- * @param mixed $data The data en encode in the JSON response..
+ * @param mixed $data The data en encode in the JSON response.
+ * @param int $status HTTP status code. Defaults to 200 OK.
* @param string $charset Charset of the data. Defaults to utf-8.
*/
- public function __construct ($data, $charset = 'utf-8') {
- $this->data = $data;
- $this->charset = $charset;
+ public function __construct ($data, $status = 200, $charset = 'utf-8') {
+ parent::__construct($data, $status, 'application/json', $charset);
}
/**
- * Performs the JSON encoding and returns the result.
- *
- * @param Request $request The request. Disregarded in this implementation.
+ * Performs the JSON encoding and outputs the result.
*/
public function render ($request) {
- header("Content-Type: application/json; charset=$this->charset");
echo json_encode($this->data);
}
}
=== renamed file 'src/results/NotFoundResult.php' => 'src/response/NotFoundResponse.php'
--- src/results/NotFoundResult.php 2008-10-20 16:41:10 +0000
+++ src/response/NotFoundResponse.php 2009-04-11 23:30:29 +0000
@@ -1,21 +1,17 @@
<?php
/**
- * Provides the implementation of a result set which sends a 404 Not Found HTTP status header to
- * the client. A XSL template is used to render a viewable response for the client.
- *
- * @version $Id: NotFoundResult.php 1542 2008-08-12 18:46:42Z anders $
+ * Response implementation which sends a 404 Not Found HTTP status code to the client. A XSL
+ * stylesheet is used to render a viewable response to the user.
*/
-class NotFoundResult extends XsltResult {
-
+class NotFoundResponse extends XsltResponse {
/**
- * Constructor.
+ * Initialize this response.
*
- * @param string $xsl_template Name of XSL file (excluding the extension) to use, relative to
- * the views-directory.
+ * @param string $stylesheet XSL stylesheet to use.
+ * @param int $status HTTP status code. Defaults to 200 OK.
*/
- public function __construct ($action, $xslTemplate = '/404') {
- parent::__construct($action, $xslTemplate);
- header("HTTP/1.1 404 Not Found");
+ public function __construct ($stylesheet = '/404', 404) {
+ parent::__construct(null, $stylesheet);
}
}
?>
=== added file 'src/response/PermanentRedirectResponse.php'
--- src/response/PermanentRedirectResponse.php 1970-01-01 00:00:00 +0000
+++ src/response/PermanentRedirectResponse.php 2009-04-14 16:50:50 +0000
@@ -0,0 +1,15 @@
+<?php
+/**
+ * This is a more specific redirect response, sending a 301 Moved Permanently status code.
+ */
+class PermanentRedirectResponse extends RedirectResponse {
+ /**
+ * Initialize this response.
+ *
+ * @param string $location Location of the redirect relative to the web root.
+ */
+ public function __construct ($location) {
+ parent::__construct($location, 301);
+ }
+}
+?>
=== renamed file 'src/results/PhpResult.php' => 'src/response/PhpResponse.php'
--- src/results/PhpResult.php 2008-12-17 15:50:47 +0000
+++ src/response/PhpResponse.php 2009-04-11 23:30:29 +0000
@@ -1,39 +1,45 @@
<?php
/**
- * Provides the implementation for using a plain PHP file as a template when creating the result.
+ * Provides the implementation of a response using a PHP file as a template for creating
+ * the actual output.
*/
-class PhpResult extends AbstractResult {
+class PhpResult extends Response {
private $phpTemplate;
-
+
/**
- * Constructor.
+ * Initializes this response.
*
- * @param Object $action The action processing the request.
- * @param string $phpTemplate Path to the template, relative to the VIEW_PATH, and excluding the extension.
+ * @param mixed $data Data to expose to the PHP template.
+ * @param string $phpTemplate PHP template to use, relative to VIEW_PATH, omitting the
+ * extension.
+ * @param int $status HTTP status code. Defaults to 200 OK.
+ * @param string $contentType Content type of the response. Defaults to text/html.
*/
- public function __construct ($action, $phpTemplate) {
- parent::__construct($action);
+ public function __construct ($data, $phpTemplate, $status = 200,
+ $contentType = 'text/html') {
+ parent::__construct($data, $status, $contentType);
$this->phpTemplate = VIEW_PATH . "$phpTemplate.php";
-
+
if (!file_exists($this->phpTemplate)) {
throw new Exception("PHP template ({$this->phpTemplate}) does not exist");
}
}
-
+
/**
- * Extracts data from the current action into a sandboxed function scope, while providing
- * direct access to the request object and the application configuration.
- * This sandboxed scope is made available to the PHP template file by including it directly, and
- * collecting it's output which is thus used as the results output.
- *
- * @param Request $request Request object representing the current request.
+ * Extracts the data into a sandboxed function scope, while providing direct access to the
+ * request object and the application configuration. This sandboxed scope is made available
+ * to the PHP template file by including it directly, and collecting it's output which is
+ * thus used as the results output.
*/
public function render ($request) {
- $data = $this->getActionData();
+ $data = array();
+ foreach ($this->data as $key => $value) {
+ $data[$key] = $value;
+ }
- /**
- * Create a sandbox function which extracts all data to it's local scope,
- * instead of letting the view template run inside the PhpResult object scope.
+ /*
+ * Create a sandbox function which extracts all data to it's local scope, instead of
+ * letting the view template run inside the PhpResult object scope.
*/
$sandbox = create_function('$request, $config, $_d, $_t', 'extract($_d); include($_t);');
$sandbox($request, Config::get(), $data, $this->phpTemplate);
=== renamed file 'src/results/RedirectResult.php' => 'src/response/RedirectResponse.php'
--- src/results/RedirectResult.php 2009-04-07 23:17:37 +0000
+++ src/response/RedirectResponse.php 2009-04-14 16:50:50 +0000
@@ -1,29 +1,28 @@
<?php
/**
- * Provides the implementation of a result set which when rendered sends a redirect to the
- * client. It defaults to a 303 (See Other) status code, but this can be overridden.
- */
-class RedirectResult extends AbstractResult {
+ * Provides the implementation of a response which sends a redirect to the client when rendered.
+ * This defaults to a 302 Found status code. While the status code can be overridden, it is
+ * recommended to use a more specific response class where one is availible.
+ */
+class RedirectResponse extends Response {
private $location;
- private $code;
/**
- * Constructor.
+ * Initialize this response.
*
* @param string $location Location of the redirect relative to the web root.
- * @param int $code HTTP status code to use. Defaults to 303.
+ * @param int $status HTTP status code. Defaults to 302 Found.
*/
- public function __construct ($action, $location, $code = 303) {
- parent::__construct($action);
+ public function __construct ($location, $status = 302) {
+ parent::__construct(null, $status);
$this->location = Config::get('webRoot') . $location;
- $this->code = $code;
}
/**
* Sends the redirect to the client.
*/
public function render ($request) {
- header("Location: $this->location", true, $this->code);
+ $this->setHeader('Location', $this->location);
exit;
}
}
=== renamed file 'src/results/AbstractResult.php' => 'src/response/Response.php'
--- src/results/AbstractResult.php 2009-04-03 16:04:34 +0000
+++ src/response/Response.php 2009-04-12 16:32:29 +0000
@@ -1,50 +1,84 @@
<?php
/**
- * Abstract class providing the basic implementation of a result. A result represents the outcome of the
- * request performed, and a response will usually be rendered to the client over HTTP.
+ * Provides a simple implementation of a response. This class can be used directly when
+ * outputting data manually, but a more specialized subclass is often used.
*/
-abstract class AbstractResult implements Result {
- protected $action;
+class Response {
+ protected $data;
+ protected $status;
protected $contentType;
protected $charset;
/**
- * Constructor.
+ * Initializes this response with the supplied response data and meta data. When using this
+ * class explicitly, <code>$data</code> must be a string with the response body, or added
+ * through <code>output()</code>. Template implementations usually expects
+ * <code>$data</code> to be an object or array.
*
- * @param Request $request The request object representing the current HTTP request.
- * @param string $contentType The content type of the rendered result. Default is text/html.
- * @param string $charset The charset of the rendered result. Default is utf-8.
- * @return BaseResult
+ * @param mixed $data Data to use when rendering the output.
+ * @param int $status HTTP status code. Defaults to 200 OK.
+ * @param string $contentType Content type of the response. Defaults to text/html.
+ * @param string $charset Charset of the response. Defaults to utf-8.
*/
- public function __construct ($action, $contentType = 'text/html', $charset = 'utf-8') {
- $this->action = $action;
+ public function __construct ($data = '', $status = 200, $contentType = 'text/html',
+ $charset = 'utf-8') {
+ $this->data = $data;
+ $this->status = $status;
$this->contentType = $contentType;
$this->charset = $charset;
-
- header("Content-Type: $contentType; charset=$charset");
- }
-
- /**
- * Returns the action that created this result.
- *
- * @return object
- */
- public function getAction () {
- return $this->action;
- }
-
- /**
- * Returns exposable data from the action.
- *
- * @return array Data from the action.
- */
- public function getActionData () {
- $data = array();
- foreach ($this->action as $key => $value) {
- $data[$key] = $value;
- }
-
- return $data;
+ $this->setHeader('Content-Type', "$contentType; charset=$charset", $status);
+ }
+
+ /**
+ * Sets a header. If $status is supplied, the HTTP status code is changed to its value.
+ *
+ * @param string $header The header to set.
+ * @param string $value The value to set.
+ * @param int $status New HTTP status code to set, if any.
+ */
+ public final function setHeader ($header, $value, $status = null) {
+ header("$header: $value", true, $status);
+ }
+
+ /**
+ * Checks whether the supplied header has been sent or is about to be sent to the client.
+ *
+ * @param string $header The header to check for.
+ * @return bool
+ */
+ public final function isHeaderSet ($header) {
+ foreach (headers_list() as $headerSent) {
+ if (substr($headerSent, 0, strpos($headerSent, ':')) == $header) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Adds content to output. Any previously added data and the content supplied must both
+ * be string values.
+ *
+ * @param string $content Content to add.
+ * @throws Exception If existing data or content added are not strings.
+ */
+ public function output ($content) {
+ if (!is_string($this->data)) {
+ throw new Exception("Can't add output as previously submittet data
+ is not a string.");
+ }
+ if (!is_string($content)) {
+ throw new Exception("Content to output must be a string value.");
+ }
+
+ $this->data .= $content . "\n";
+ }
+
+ /**
+ * Outputs the response body.
+ */
+ public function render ($request) {
+ echo $this->data;
}
}
?>
=== added file 'src/response/SeeOtherResponse.php'
--- src/response/SeeOtherResponse.php 1970-01-01 00:00:00 +0000
+++ src/response/SeeOtherResponse.php 2009-04-14 16:50:50 +0000
@@ -0,0 +1,17 @@
+<?php
+/**
+ * This is a more specific redirect response, sending a 303 See Other status code. This is
+ * most correctly used when redirecting to another GET location to display the result of a
+ * POST.
+ */
+class SeeOtherResponse extends RedirectResponse {
+ /**
+ * Initialize this response.
+ *
+ * @param string $location Location of the redirect relative to the web root.
+ */
+ public function __construct ($location) {
+ parent::__construct($location, 303);
+ }
+}
+?>
=== renamed file 'src/results/SmartyResult.php' => 'src/response/SmartyResponse.php'
--- src/results/SmartyResult.php 2008-12-17 15:50:47 +0000
+++ src/response/SmartyResponse.php 2009-04-11 23:30:29 +0000
@@ -2,51 +2,51 @@
require('Smarty/Smarty.class.php');
/**
- * Provides the implementation of a result using the Smarty template engine to render the data as (X)HTML.
- * To use this result engine you'll need to have Smarty installed in a directory where PHP searches for
- * include files (include_path). You'll also need to add a 'smarty' section in your application configuration,
- * which defines compileDir at the very least. An example of the configuration section:
+ * Provides the implementation of a response using the Smarty template engine to render the
+ * data as (X)HTML. To use this response engine Smarty must be installed in a directory where
+ * PHP searches for include files (include_path). A 'smarty' section must also exist in your
+ * application configuration, which defines compileDir at the very least. An example of the
+ * configuration section:
*
* 'smarty' => array(
- * 'compileDir' => '', // Full path to a directory writeable by PHP
- * 'cacheDir' => '', // Full path to a directory writeable by PHP, if you want to use Smarty caching
- * 'configDir' => '', // Full path to a directory containing Smarty-specific configuration files
- * 'templateDir' => '' // Full path to a directory overriding the default Kolibri view directory
+ * 'compileDir' => '', // Full path to a PHP-writeable dir
+ * 'cacheDir' => '', // Full path to a PHP-writeable dir, if you want to use Smarty caching
+ * 'configDir' => '', // Full path to a dir containing Smarty-specific configuration files
+ * 'templateDir' => '' // Full path to a dir overriding the default Kolibri view directory
* )
*
- * All configurable directories corresponds to similar Smarty directories, ie. compile_dir and cache_dir.
+ * All configurable directories corresponds to similar Smarty directories, ie. compile_dir and
+ * cache_dir.
*/
-class SmartyResult extends AbstractResult {
+class SmartyResponse extends Response {
private $smartyTemplate;
/**
- * Constructor.
+ * Initialize this response.
*
- * @param Object $action The action processing the request.
- * @param string $template Path to the template, relative to the VIEW_PATH, and excluding the extension.
+ * @param mixed $data Data to pass on to the Smarty template.
+ * @param string $template Smarty template to use, relative to VIEW_DIR, omitting the
+ * extension.
+ * @param int $status HTTP status code. Defaults to 200 OK.
+ * @param string $contentType Content type of the response. Defaults to text/html.
*/
- public function __construct ($action, $template) {
- parent::__construct($action);
-
- // Remove prefixed / for Smarty, since it's standard in Kolibri
- if ($template{0} == '/') $template = substr($template, 1);
-
+ public function __construct ($data, $template, $status = 200, $contentType = 'text/html') {
+ parent::__construct($data, $status, $contentType);
$this->smartyTemplate = "$template.tpl";
+
if (!file_exists(VIEW_PATH . "/$template.tpl")) {
- throw Exception("Smarty template ({$this->smartyTemplate}) does not exist");
+ throw Exception("Smarty template ({$this->smartyTemplate}) does not exist.");
}
}
/**
- * Creates a Smarty template engine instance. Any exposable action data is made available, as well
- * as the request object and application configuration.
- *
- * @param Request $request Request object representing the current request.
+ * Creates a Smarty template engine instance and uses it to render the output. The data
+ * along with the request object and application configuration is exposed to the template.
*/
public function render ($request) {
$conf = Config::get('smarty');
if ($conf === null) {
- throw new Exception('Smarty settings missing from application configuration');
+ throw new Exception('Smarty settings missing from application configuration.');
}
// Configure the Smarty engine
@@ -57,7 +57,11 @@
$smarty->config_dir = (isset($conf['configDir']) ? $conf['configDir'] : '');
// Assign data we want to expose to Smarty
- $smarty->assign($this->getActionData());
+ $data = array();
+ foreach ($this->data as $key => $value) {
+ $data[$key] = $value;
+ }
+ $smarty->assign($data);
$smarty->assign('request', $request);
$smarty->assign('config', Config::get());
=== renamed file 'src/results/XsltResult.php' => 'src/response/XsltResponse.php'
--- src/results/XsltResult.php 2009-04-07 20:25:15 +0000
+++ src/response/XsltResponse.php 2009-04-12 16:32:29 +0000
@@ -1,36 +1,37 @@
<?php
/**
- * Provides the implementation of a result using XSLT to render the data.
- *
- * @version $Id$
- */
-class XsltResult extends AbstractResult {
- private $xslTemplate;
-
+ * Provides the implementation of a response by using XSLT to transform the data server-side
+ * before outputting it.
+ */
+class XsltResponse extends Response {
+ private $stylesheet;
+
/**
- * Constructor.
+ * Initialize this response.
*
- * @param object $action Current action.
- * @param string $xslTemplate Name of XSL file (excluding the extension) to use, relative to
- * the views-directory.
+ * @param mixed $data Data to transform.
+ * @param string $stylesheet XSL stylesheet to use, relative to VIEW_PATH, omitting the
+ * extension.
+ * @param int $status HTTP status code. Defaults to 200 OK.
+ * @param string $contentType Content type of the response. Defaults to text/html.
*/
- public function __construct ($action, $xslTemplate) {
- parent::__construct($action);
+ public function __construct ($data, $stylesheet, $status = 200,
+ $contentType = 'text/html') {
+ parent::__construct($data, $status, $contentType);
+ $this->stylesheet = VIEW_PATH . "$stylesheet.xsl";
+ }
- $this->xslTemplate = VIEW_PATH . "$xslTemplate.xsl";
- }
-
/**
- * Performs the XSL transformations on the XML-data and outputs it.
+ * Generates XML of the data, and performs XSL transformation on it before outputting.
*/
public function render ($request) {
$xmlGenerator = new XmlGenerator();
// Wrap request data in a containing element, <request />
$xmlGenerator->append($request, 'request');
- // Append all action data directly to the root result element
- $xmlGenerator->append($this->action);
-
- $transformer = new XslTransformer($this->xslTemplate);
+ // Append all data directly to the root result element
+ $xmlGenerator->append($this->data);
+
+ $transformer = new XslTransformer($this->stylesheet);
// Add scalar config params to XSLT as parameters
foreach (Config::get() as $key => $value) {
=== removed file 'src/results/ForwardResult.php'
--- src/results/ForwardResult.php 2008-12-17 15:50:47 +0000
+++ src/results/ForwardResult.php 1970-01-01 00:00:00 +0000
@@ -1,58 +0,0 @@
-<?php
-/**
- * Provides a result which forwards the request to another action. After the action has been
- * invoked, a final result is rendered. What final result to render can be specified when
- * instantiating this class. If no result was specified in the instantiation of this class, the
- * result of the action invoked will be rendered.
- *
- * FIXME: This is currently NOT rewritten for Kolibri. Do we really want this at all?
- */
-class ForwardResult extends BaseResult {
- /** Result to render after action invocation, or NULL if the action result is to be rendered. */
- var $end_result;
-
- /**
- * Constructor.
- *
- * @param Request &$request The request object representing the current HTTP request.
- * @param string $uri URI to forward the request to. An action mapper must be able
- * to map this URI to an action, or else nothing is rendered.
- * @param object $end_result Optional result to render after the forward action is complete.
- * If not supplied, the result of the action is rendered.
- * @return BaseResult
- */
- function ForwardResult (&$request, $uri, $end_result = null) {
- parent::BaseResult($request);
-
- // Change the URI of the request
- $this->request->uri = $uri;
-
- if (!empty($end_result)) {
- $this->end_result = $end_result;
- }
- }
-
- /**
- * Maps the target URI specified in this result to an action and dispatches the request. When
- * the action returns we render our end result if provided, or else the result of the action.
- */
- function render() {
- // Map the action we want to forward to
- $mapper = new ActionMapper();
- $mapping = $mapper->map($this->request);
-
- if (!empty($mapping)) {
- $dispatcher = new Dispatcher($this->request, $mapping);
- $result = $dispatcher->invoke();
-
- // Render the end result if we have one, else the result of the invoked action
- if (!empty($this->end_result)) {
- $this->end_result->render();
- }
- else {
- $result->render();
- }
- }
- }
-}
-?>
=== removed file 'src/results/Result.php'
--- src/results/Result.php 2008-12-17 15:50:47 +0000
+++ src/results/Result.php 1970-01-01 00:00:00 +0000
@@ -1,8 +0,0 @@
-<?php
-/**
- * This interface defines the contract of a result.
- */
-interface Result {
- public function render ($request);
-}
-?>
=== removed file 'src/results/TextResult.php'
--- src/results/TextResult.php 2008-12-17 15:50:47 +0000
+++ src/results/TextResult.php 1970-01-01 00:00:00 +0000
@@ -1,24 +0,0 @@
-<?php
-/**
- * Provides the implementation of a result set which sets the content-type to plain text. This
- * will ensure that all output will be sent to the client as-is.
- */
-class TextResult extends AbstractResult {
- private $text;
-
- /**
- * Constructor.
- *
- * @param object $action The current action.
- * @param string $text Text to send to client.
- */
- public function __construct ($action, $text) {
- parent::__construct($action, 'text/plain');
- $this->text = $text;
- }
-
- public function render ($request) {
- echo $this->text;
- }
-}
-?>
Follow ups