1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
|
<?php
/**
* Lithium: the most rad php framework
*
* @copyright Copyright 2010, Union of RAD (http://union-of-rad.org)
* @license http://opensource.org/licenses/bsd-license.php The BSD License
*/
/**
* The routes file is where you define your URL structure, which is an important part of the
* [information architecture](http://en.wikipedia.org/wiki/Information_architecture) of your
* application. Here, you can use _routes_ to match up URL pattern strings to a set of parameters,
* usually including a controller and action to dispatch matching requests to. For more information,
* see the `Router` and `Route` classes.
*
* @see lithium\net\http\Router
* @see lithium\net\http\Route
*/
use lithium\net\http\Router;
use lithium\core\Environment;
use app\models\Photo;
/**
* Here, we are connecting `'/'` (the base path) to controller called `'Pages'`,
* its action called `view()`, and we pass a param to select the view file
* to use (in this case, `/views/pages/home.html.php`; see `app\controllers\PagesController`
* for details).
*
* @see app\controllers\PagesController
*/
Router::connect('/', 'Pages::view');
/**
* Connect the rest of `PagesController`'s URLs. This will route URLs like `/pages/about` to
* `PagesController`, rendering `/views/pages/about.html.php` as a static page.
*/
Router::connect('/pages/{:args}', 'Pages::view');
/**
* Add the testing routes. These routes are only connected in non-production environments, and allow
* browser-based access to the test suite for running unit and integration tests for the Lithium
* core, as well as your own application and any other loaded plugins or frameworks. Browse to
* [http://path/to/app/test](/test) to run tests.
*/
if (!Environment::is('production')) {
Router::connect('/test/{:args}', array('controller' => 'lithium\test\Controller'));
Router::connect('/test', array('controller' => 'lithium\test\Controller'));
}
/* These are the login and logout routes */
Router::connect('/login', array('controller' => 'users', 'action' => 'login'));
Router::connect('/logout', array('controller' => 'users', 'action' => 'logout'));
//Pagination route
Router::connect('/{:controller}/{:action}/page:{:page:[0-9]+}');
/**
* Define an anonymous function that we will pass to the router instead of linking to a controller action
* The logic is quite simple:
* Call the version() method on the Photo model class with $request->id (MongoId for image) and a set of options. This is passed as an array to allow adding more options later.
* Finally just return a Response object with the image data as body (this is what version() returns) and the appropriate content type for the file ending.
*
* This method is limited, supports few formats etc but its a good start
*/
$imageSizer = function($request) {
$contentTypeMappings = array(
'jpg' => 'image/jpeg',
'jpeg' => 'image/jpeg',
'png' => 'image/png',
'gif' => 'image/gif'
);
// Generate file based image of this
$imageBody = Photo::version($request->id, array(
'width' => $request->width,
'height' => $request->height
));
return new Response(array(
'headers' => array('Content-type' => $contentTypeMappings[$request->type]),
'body' => $imageBody
));
};
/**
This is a little bit more complicated.
We state that the handler for when this route is matched is the anonymous function we've declared and
we set up a pattern to match our two cases of image urls — both with and without size information.
The regex is quite simple even if it looks complex:
^/image/ <- begin with /image/
(?P<foo>) is for setting up a named capture group. This equals doing {:foo:{pattern}} in Lithium.
So we have 1 capture group named {id} that have to match by 24 signs (mongoid), and an optional part "_{width}x{height}" and finally the filtype.
I'm unsure if the keys array can be handled some other way, but it failed for me without it.
*/
$imageHandlingOptions = array(
'handler' => $imageSizer,
'pattern' => '@^/image/(?P<id>[0-9a-f]{24})(_(?P<width>[0-9]*)x(?P<height>[0-9]*)?)\.(?<type>[a-z]{2,4})@',
'keys' => array('id'=>'id', 'width'=>'width', 'height'=>'height', 'type'=>'type')
);
/**
Finally we connect this as a route. The regex sent as the first param here is overriden by the more complex one we have defined in the options array.
*/
Router::connect('/image/{:id:[0-9a-f]{24}}.jpg', array(), $imageHandlingOptions);
/**
* ### Database object routes
*
* The routes below are used primarily for accessing database objects, where `{:id}` corresponds to
* the primary key of the database object, and can be accessed in the controller as
* `$this->request->id`.
*
* If you're using a relational database, such as MySQL, SQLite or Postgres, where the primary key
* is an integer, uncomment the routes below to enable URLs like `/posts/edit/1138`,
* `/posts/view/1138.json`, etc.
*/
// Router::connect('/{:controller}/{:action}/{:id:\d+}.{:type}', array('id' => null));
// Router::connect('/{:controller}/{:action}/{:id:\d+}');
/**
* If you're using a document-oriented database, such as CouchDB or MongoDB, or another type of
* database which uses 24-character hexidecimal values as primary keys, uncomment the routes below.
*/
Router::connect('/{:controller}/{:action}/{:id:[0-9a-f]{24}}.{:type}', array('id' => null));
Router::connect('/{:controller}/{:action}/{:id:[0-9a-f]{24}}');
/**
* Finally, connect the default route. This route acts as a catch-all, intercepting requests in the
* following forms:
*
* - `/foo/bar`: Routes to `FooController::bar()` with no parameters passed.
* - `/foo/bar/param1/param2`: Routes to `FooController::bar('param1, 'param2')`.
* - `/foo`: Routes to `FooController::index()`, since `'index'` is assumed to be the action if none
* is otherwise specified.
*
* In almost all cases, custom routes should be added above this one, since route-matching works in
* a top-down fashion.
*/
Router::connect('/{:controller}/{:action}/{:args}');
?>
|