Pluf Framework

Sign in or create your account | Project List | Help

Pluf Framework Commit Details

Date:2009-04-06 14:11:20 (11 months 10 days ago)
Author:Loïc d'Anterroches
Commit:a7df883a9b6b4e4bd529e6f8c03a811045d1996c
Message:Added the modularization of the URLs.

Files: src/Pluf/Dispatcher.php (2 diffs)
src/Pluf/HTTP/URL.php (2 diffs)
src/Pluf/Tests/Dispatch/Dispatcher.php (1 diff)
src/Pluf/conf/pluf.test.php (1 diff)

Change Details

src/Pluf/Dispatcher.php
107107    /**
108108     * Match a query against the actions controllers.
109109     *
110     * @see Pluf_HTTP_URL_reverse
111     *
110112     * @param Pluf_HTTP_Request Request object
111113     * @return Pluf_HTTP_Response Response object
112114     */
113115    public static function match($req, $firstpass=true)
114116    {
115        // Order the controllers by priority
116        foreach ($GLOBALS['_PX_views'] as $key => $control) {
117            $priority[$key] = $control['priority'];
118        }
119        array_multisort($priority, SORT_ASC, $GLOBALS['_PX_views']);
120117        try {
121            foreach ($GLOBALS['_PX_views'] as $key => $ctl) {
122                $match = array();
123                if (preg_match($ctl['regex'], $req->query, $match)) {
124                    $req->view = array($ctl, $match);
125                    $m = new $ctl['model']();
126                    if (isset($m->{$ctl['method'].'_precond'})) {
127                        // Here we have preconditions to respects. If
128                        // the "answer" is true, then ok go ahead, if
129                        // not then it a response so return it or an
130                        // exception so let it go.
131                        $preconds = $m->{$ctl['method'].'_precond'};
132                        if (!is_array($preconds)) {
133                            $preconds = array($preconds);
134                        }
135                        foreach ($preconds as $precond) {
136                            if (!is_array($precond)) {
137                                $res = call_user_func_array(
138                                              explode('::', $precond),
139                                              array(&$req)
140                                                            );
141                            } else {
142                                $res = call_user_func_array(
143                                              explode('::', $precond[0]),
144                                              array_merge(array(&$req),
145                                                          array_slice($precond, 1))
146                                                            );
147                            }
148                            if ($res !== true) {
149                                return $res;
150                            }
151                        }
152                    }
153                    if (!isset($ctl['params'])) {
154                        return $m->$ctl['method']($req, $match);
118            $views = $GLOBALS['_PX_views'];
119            $to_match = $req->query;
120            $n = count($views);
121            $i = 0;
122            while ($i<$n) {
123                $ctl = $views[$i];
124                if (preg_match($ctl['regex'], $to_match, $match)) {
125                    if (!isset($ctl['sub'])) {
126                        return self::send($req, $ctl, $match);
155127                    } else {
156                        return $m->$ctl['method']($req, $match, $ctl['params']);
128                        // Go in the subtree
129                        $views = $ctl['sub'];
130                        $i = 0;
131                        $n = count($views);
132                        $to_match = substr($to_match, strlen($match[0]));
133                        continue;
157134                    }
158135                }
136                $i++;
159137            }
160138        } catch (Pluf_HTTP_Error404 $e) {
161139            // Need to add a 404 error handler
...... 
177155    }
178156
179157    /**
158     * Call the view found by self::match.
159     *
160     * The called view can throw an exception. This is fine and
161     * normal.
162     *
163     * @param Pluf_HTTP_Request Current request
164     * @param array The url definition matching the request
165     * @param array The match found by preg_match
166     * @return Pluf_HTTP_Response Response object
167     */
168    public static function send($req, $ctl, $match)
169    {
170        $req->view = array($ctl, $match);
171        $m = new $ctl['model']();
172        if (isset($m->{$ctl['method'].'_precond'})) {
173            // Here we have preconditions to respects. If the "answer"
174            // is true, then ok go ahead, if not then it a response so
175            // return it or an exception so let it go.
176            $preconds = $m->{$ctl['method'].'_precond'};
177            if (!is_array($preconds)) {
178                $preconds = array($preconds);
179            }
180            foreach ($preconds as $precond) {
181                if (!is_array($precond)) {
182                    $res = call_user_func_array(
183                                                explode('::', $precond),
184                                                array(&$req)
185                                                );
186                } else {
187                    $res = call_user_func_array(
188                                                explode('::', $precond[0]),
189                                                array_merge(array(&$req),
190                                                            array_slice($precond, 1))
191                                                );
192                }
193                if ($res !== true) {
194                    return $res;
195                }
196            }
197        }
198        if (!isset($ctl['params'])) {
199            return $m->$ctl['method']($req, $match);
200        } else {
201            return $m->$ctl['method']($req, $match, $ctl['params']);
202        }
203    }
204
205    /**
180206     * Load the controllers.
181207     *
182208     * @param string File including the views.
src/Pluf/HTTP/URL.php
105105 */
106106function Pluf_HTTP_URL_reverse($view, $params=array())
107107{
108    $regex = null;
109108    $model = '';
110109    $method = '';
111110    if (false !== strpos($view, '::')) {
112111        list($model, $method) = split('::', $view);
113112    }
114    foreach ($GLOBALS['_PX_views'] as $dview) {
113    $vdef = array($model, $method, $view);
114    $regbase = array('', array());
115    $regbase = Pluf_HTTP_URL_find($GLOBALS['_PX_views'], $vdef, $regbase);
116    if ($regbase === false) {
117        throw new Exception(sprintf('Error, the view: %s has not been found.', $view));
118    }
119    $url = '';
120    foreach ($regbase[1] as $regex) {
121        $url .= Pluf_HTTP_URL_buildReverseUrl($regex, $params);
122    }
123    if (!defined('IN_UNIT_TESTS')) {
124        $url = $regbase[0].$url;
125    }
126    return $url;
127}
128
129
130/**
131 * Go in the list of views to find the matching one.
132 *
133 * @param array Views
134 * @param array View definition array(model, method, name)
135 * @param array Regex of the view up to now and base
136 * @return mixed Regex of the view or false
137 */
138function Pluf_HTTP_URL_find($views, $vdef, $regbase)
139{
140    foreach ($views as $dview) {
115141        if (
116            (isset($dview['name']) && $dview['name'] == $view)
142            (isset($dview['name']) && $dview['name'] == $vdef[2])
117143            or
118            ($dview['model'] == $model && $dview['method'] == $method)
144            ($dview['model'] == $vdef[0] && $dview['method'] == $vdef[1])
119145            ) {
120            $regex = $dview['regex'];
121            break;
146            $regbase[1][] = $dview['regex'];
147            if (!empty($dview['base'])) {
148                $regbase[0] = $dview['base'];
149            }
150            return $regbase;
151        }
152        if (isset($dview['sub'])) {
153            $regbase2 = $regbase;
154            $regbase2[1][] = $dview['regex'];
155            $res = Pluf_HTTP_URL_find($dview['sub'], $vdef, $regbase2);
156            if ($res) {
157                return $res;
158            }
122159        }
123160    }
124    if ($regex === null) {
125        throw new Exception(sprintf('Error, the view: %s has not been found.', $view));
126    }
127    $url = Pluf_HTTP_URL_buildReverseUrl($regex, $params);
128    if (isset($dview['base']) and !defined('IN_UNIT_TESTS')) {
129        $url = $dview['base'].$url;
130    }
131    return $url;
161    return false;
132162}
133163
134164/**
...... 
165195                                'return $a;');
166196        $url = preg_replace_callback($groups, $func, $url_regex);
167197    }
168    $url = substr(substr($url, 2), 0, -2);
169    if (substr($url, -1) !== '$') {
170        return $url;
171    }
172    return substr($url, 0, -1);
198    preg_match('/^#\^?([^#\$]+)/', $url, $matches);
199    return $matches[1];
173200}
src/Pluf/Tests/Dispatch/Dispatcher.php
1<?php
2/* -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3/*
4# ***** BEGIN LICENSE BLOCK *****
5# This file is part of Plume Framework, a simple PHP Application Framework.
6# Copyright (C) 2001-2007 Loic d'Anterroches and contributors.
7#
8# Plume Framework is free software; you can redistribute it and/or modify
9# it under the terms of the GNU Lesser General Public License as published by
10# the Free Software Foundation; either version 2.1 of the License, or
11# (at your option) any later version.
12#
13# Plume Framework is distributed in the hope that it will be useful,
14# but WITHOUT ANY WARRANTY; without even the implied warranty of
15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16# GNU Lesser General Public License for more details.
17#
18# You should have received a copy of the GNU Lesser General Public License
19# along with this program; if not, write to the Free Software
20# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21#
22# ***** END LICENSE BLOCK ***** */
23
24class Pluf_Tests_Dispatch_Dispatcher extends UnitTestCase
25{
26    protected $views = array();
27
28    function __construct()
29    {
30        parent::__construct('Test the dispatching.');
31    }
32
33    function setUp()
34    {
35        $this->views = $GLOBALS['_PX_views'];
36    }
37
38    function tearDown()
39    {
40        $GLOBALS['_PX_views'] = $this->views;
41    }
42
43    function hello()
44    {
45        return true;
46    }
47
48    function testSimple()
49    {
50        $GLOBALS['_PX_views'] = array(
51                 array(
52                       'regex' => '#^/hello/$#',
53                       'base' => '',
54                       'model' => 'Pluf_Tests_Dispatch_Dispatcher',
55                       'method' => 'hello'
56                       )
57                 );
58        $req1 = (object) array('query' => '/hello/'); // match
59        $req2 = (object) array('query' => '/hello'); // match second pass
60        $req3 = (object) array('query' => '/hello/you/'); // no match
61        $this->assertIdentical(true, Pluf_Dispatcher::match($req1));
62        $this->assertIsA(Pluf_Dispatcher::match($req2),
63                         'Pluf_HTTP_Response_Redirect');
64        $this->assertIsA(Pluf_Dispatcher::match($req3),
65                         'Pluf_HTTP_Response_NotFound');
66    }
67
68    function testRecursif()
69    {
70        $GLOBALS['_PX_views'] = array(
71                 array(
72                       'regex' => '#^/hello/#',
73                       'base' => '',
74                       'sub' => array(
75                                      array(
76                                            'regex' => '#^world/$#',
77                                            'base' => '',
78                                            'model' => 'Pluf_Tests_Dispatch_Dispatcher',
79                                            'method' => 'hello'
80                                            )
81                                      )
82                       ));
83        $req1 = (object) array('query' => '/hello/world/'); // match
84        $req2 = (object) array('query' => '/hello/world'); // match second pass
85        $req3 = (object) array('query' => '/hello/you/'); // no match
86        $this->assertIdentical(true, Pluf_Dispatcher::match($req1));
87        $this->assertIsA(Pluf_Dispatcher::match($req2),
88                         'Pluf_HTTP_Response_Redirect');
89        $this->assertIsA(Pluf_Dispatcher::match($req3),
90                         'Pluf_HTTP_Response_NotFound');
91        Pluf::loadFunction('Pluf_HTTP_URL_reverse');
92        $this->assertEqual('/hello/world/',
93                           Pluf_HTTP_URL_reverse('Pluf_Tests_Dispatch_Dispatcher::hello'));
94    }
95
96
97}
src/Pluf/conf/pluf.test.php
3636$cfg['tmp_folder'] = '/tmp';
3737
3838// The folder in which the templates of the application are located.
39$cfg['templates_folder'] = array(dirname(__FILE__).'/../templates');
39$cfg['template_folders'] = array(dirname(__FILE__).'/../templates');
4040
4141$cfg['pluf_use_rowpermission'] = true;
4242

Archive Download the corresponding diff file

Branches:
master