Changeset 174

Show
Ignore:
Timestamp:
03/13/06 21:10:15 (6 years ago)
Author:
haas
Message:

ActionController? doc done

Location:
trunk/trax
Files:
1 added
6 modified

Legend:

Unmodified
Added
Removed
  • trunk/trax/test/ActionControllerTest.php

    r163 r174  
    100100        $ac = new ActionController; 
    101101        //  this URL doesn't match any route 
    102         $_SERVER['REDIRECT_URL'] = '~haas/foo/bar'; 
     102        $_SERVER['REDIRECT_URL'] = '/~haas/foo/bar'; 
    103103        $this->assertFalse($ac->recognize_route()); 
    104104        //  this URL matches but the controller doesn't exist 
    105         $_SERVER['REDIRECT_URL'] = '~haas/nocontroller/foo/bar'; 
     105        $_SERVER['REDIRECT_URL'] = '/~haas/nocontroller/foo/bar'; 
    106106        $this->assertFalse($ac->recognize_route()); 
    107107        //  this URL matches and the controller is where it should be 
    108         $_SERVER['REDIRECT_URL'] = '~haas/products/bar'; 
     108        $_SERVER['REDIRECT_URL'] = '/~haas/products/bar'; 
    109109        $this->assertTrue($ac->recognize_route()); 
    110110    } 
     
    155155        $ac = new ActionController; 
    156156        //  this URL doesn't match any route 
    157         $_SERVER['REDIRECT_URL'] = '~haas/foo/bar'; 
     157        $_SERVER['REDIRECT_URL'] = '/~haas/foo/bar'; 
    158158        try { 
    159159            $ac->process_route(); 
     
    180180        $ac = new ActionController; 
    181181        //  this URL matches default route 
    182         $_SERVER['REDIRECT_URL'] = '~haas/nocontroller/foo/bar'; 
     182        $_SERVER['REDIRECT_URL'] = '/~haas/nocontroller/foo/bar'; 
    183183        try { 
    184184            $ac->process_route(); 
     
    207207        //  this URL matches default route, but the controller 
    208208        //  file doesn't have a Noclass class 
    209         $_SERVER['REDIRECT_URL'] = '~haas/noclass/foo/bar'; 
     209        $_SERVER['REDIRECT_URL'] = '/~haas/noclass/foo/bar'; 
    210210        try { 
    211211            $ac->process_route(); 
     
    234234//        $ac = new ActionController; 
    235235//        //  should invoke CatalogController 
    236 //        $_SERVER['REDIRECT_URL'] = '~haas/products/bar'; 
     236//        $_SERVER['REDIRECT_URL'] = '/~haas/products/bar'; 
    237237//        $ac->process_route(); 
    238238//        // Remove the following line when you implement this test. 
  • trunk/trax/tutorials/PHPonTrax/ActionController.cls

    r159 r174  
    1515 <refsect1 id="{@id intro}"> 
    1616  <title>Introduction</title> 
     17  <para>The {@link ActionController} base class does the 
     18  following:</para> 
     19  <orderedlist> 
     20    <listitem>Accepts a URL as input</listitem> 
     21    <listitem>Translates the URL into a controller and action</listitem> 
     22    <listitem>Creates the indicated controller object (which is a subclass 
     23      of ActionController) and calls its action method</listitem> 
     24    <listitem>Redirects to another URL or renders the output of the 
     25    action method</listitem>  
     26  </orderedlist> 
    1727 </refsect1> 
    18  <refsect1 id="{@id filters}"> 
    19   <title>Filters</title> 
     28 <refsect1 is="{@id url}"> 
     29  <title>URL Processing</title> 
     30 
     31  <para> 
     32   When Apache receives an HTTP request addressed to a Trax 
     33   application, 
     34{@link http://httpd.apache.org/docs/2.0/mod/mod_rewrite.html Apache mod_rewrite} 
     35   is invoked and rewrites the request to invoke Trax file 
     36   <literal>dispatch.php</literal>.  At this time the URL which was 
     37   input to the rewrite rules is in 
     38{@link http://www.php.net/manual/en/reserved.variables.php#reserved.variables.server $_SERVER}['REDIRECT_URL'].   
     39   <literal>dispatch.php</literal> creates a new {@link Dispatcher} 
     40   object and calls its  
     41   {@link Dispatcher::dispatch() dispatch()} method. dispatch() 
     42   restores the state of the session identified by a cookie in the 
     43   request, or creates a session if none exists.  Then it creates a 
     44   new ActionController object and calls its 
     45   {@link ActionController::process_route() <literal>process_route()</literal>}  
     46   method.  
     47  </para> 
     48 
     49  <para> 
     50   The word "route" is used in Trax to describe a rule which 
     51   translates some URL into a particular controller object and method. 
     52   When <literal>process_route()</literal> receives control, it calls 
     53   {@link ActionController::recognize_route() recognize_route()} to 
     54   parse the URL into controller, action and id 
     55   components. recognize_route() calls 
     56   {@link ActionController::load_router() load_router()} to load the 
     57   "routing table", which is a list of one or more 
     58   <literal>$router->connect()</literal> calls, from 
     59   {@link routes.php <literal>config/routes.php</literal>}.   
     60   This list of calls define the rules for translating a URL into a 
     61   controller and action. 
     62  </para> 
     63 
     64  <para> 
     65   The translation rules work as follows:  Starting with the first 
     66   rule in <literal>routes.php</literal>, each rule is tested against 
     67   the URL to see  
     68   whether the rule matches.  If a rule does not match, then the next 
     69   rule in the table is tested in turn, until a rule matches or the 
     70   table is exhausted.  If no matching rule is found, 
     71   recognize_route() tests the last route in the table to see whether 
     72   it is the default route <literal>:controller/:action/:id</literal> 
     73   .  If the last route is the default route, then 
     74   <literal>recognize_route()</literal> 
     75   returns it as a match, even if it does not in fact match.  But if 
     76   there is no matching route and the last route in the table is not 
     77   the default route, then recognize_route() returns 'failure' which is 
     78   equivalent to HTTP code '404&nbsp;Not&nbsp;found'. 
     79  </para> 
     80 
     81  <para> 
     82   Each entry in the route table contains two parts: 
     83   <orderedlist> 
     84    <listitem> 
     85     A <important>path</important>, which is a character string to 
     86     test against the URL. 
     87    </listitem> 
     88    <listitem> 
     89     <important>Parameters</important>, which are not tested against 
     90     the URL and aren't involved unless the 
     91     <important>path</important> part of the entry matches the URL. 
     92     <important>Parameters</important> are optional (and frequently 
     93     omitted). 
     94    </listitem> 
     95   </orderedlist> 
     96   A <important>path</important> is a series of substrings separated 
     97   by '/' (forward slash) characters.  Each of these substrings can 
     98   contain any character except '/'.  The <important>path</important> 
     99   does not begin or end with '/'.  A substring may not be the null 
     100   (no characters) string, but it is legal for the entire 
     101   path to be the null string. Each substring is one of the following: 
     102   <itemizedlist> 
     103    <listitem><literal>:controller</literal></listitem> 
     104    <listitem><literal>:action</literal></listitem> 
     105    <listitem><literal>:id</literal></listitem> 
     106    <listitem>A 
     107     {@link http://www.php.net/manual/en/ref.pcre.php Perl regular expression} 
     108     that does not begin with ':' (colon)</listitem> 
     109   </itemizedlist> 
     110   The following are legal <important>path</important> values: 
     111   <itemizedlist> 
     112    <listitem><literal>:controller/:action/:id</literal> 
     113     This is the default <important>path</important>. It matches URLs 
     114     like <literal>word1/word2/word3</literal></listitem> 
     115    <listitem><literal>catalog/product/:action/:id</literal> 
     116     Remember that <literal>catalog</literal> is a Perl regular 
     117     expression that matches <literal>catalog</literal>, and 
     118     <literal>product</literal> is a Perl regular expression that 
     119     matches <literal>product</literal>, so this 
     120     <important>path</important> matches URLs like  
     121     <literal>catalog/product/word1/word2</literal></listitem> 
     122    <listitem><literal>''</literal> matches '' (the empty string as a  
     123     <important>path</important> value matches the empty string as a 
     124     URL).</listitem> 
     125    <listitem><literal>member/name=.*</literal> matches URLs like 
     126     <literal>member/name=</literal> or 
     127     <literal>member/name=Tom.Jones</literal> or 
     128     <literal>member/name=Smith,J/since=1987/type=full</literal> etc. 
     129    </listitem> 
     130   </itemizedlist> 
     131   <literal>:controller</literal>, <literal>:action</literal> and 
     132   <literal>:id</literal> may each appear at most once in a  
     133   <important>path</important>. 
     134  </para> 
     135 
     136  <para> 
     137   After the URL has been matched to a <important>path</important>, 
     138   the next step is to extract the name of the controller and action 
     139   to be invoked on this URL.  These must be valid names in the PHP 
     140   language consisting only of lower-case alphameric characters and 
     141   '_' (underscore), because the controller name will translate 
     142   directly into a file name and a class name, and the action name 
     143   will be used as the name of a method in that class.  The controller 
     144   and action names come from the route that matches the URL. 
     145  </para> 
     146 
     147  <para> 
     148   There are two places that a route can specify a controller or 
     149   action name: as part of the <important>path</important>, or in the  
     150   <important>parameters</important>.  The 
     151   <important>parameters</important> are the optional second part of a 
     152   route.  The value of <important>parameters</important> is an array 
     153   with key values that may be <literal>:controller</literal> or 
     154   <literal>:action</literal>.  The following are legal 
     155   <important>parameters</important> values: 
     156   <itemizedlist> 
     157    <listitem><literal>array(':controller' => 
     158     'new_product')</literal></listitem>  
     159    <listitem><literal>array(':action' => 'enter')</literal></listitem> 
     160    <listitem><literal>array(':controller' => 'membership', ':action 
     161     => 'new')</literal></listitem>  
     162   </itemizedlist>     
     163  </para> 
     164 
     165  <para> 
     166   When a URL matches a route, the controller name is extracted as 
     167   follows:  First, if the <important>parameters</important> array 
     168   exists and has an element whose key is 
     169   <literal>:controller</literal>, then the value of that element is 
     170   used as the controller name.  If no <literal>:controller</literal> 
     171   is specified by the <important>parameters</important>, then the 
     172   <important>path</important> is tested for a substring whose value 
     173   is <literal>:controller</literal>.  If found, then the part of the 
     174   URL which matched that substring is used as the controller value. 
     175   A controller value must be specified by either the 
     176   <important>parameters</important> or the 
     177   <important>path</important>.  The action name is extracted by the 
     178   same process, substituting <literal>:action</literal> for  
     179   <literal>:controller</literal>.  If the 
     180   <important>path</important> has a substring <literal>:id</literal>, 
     181   then the part of the URL which matched that substring is forced to 
     182   lower case and the result assigned to 
     183   <literal>$_REQUEST['id']</literal>. 
     184  </para> 
     185 
     186  <para> 
     187   If <literal>routes.php</literal> contains the following: 
     188   <example> 
     189router->connect('',array(':controller' => 'home')); 
     190router->connect('product\?.*', 
     191                array(':controller' => 'catalog', ':action' => 'find')); 
     192router->connect(':controller/:action/:id'); 
     193   </example> 
     194   Then URLs will match routes as follows: 
     195   <itemizedlist>     
     196    <listitem>URL <literal>''</literal> (no characters) will select 
     197     controller <literal>home</literal>, action not specified. 
     198    </listitem> 
     199    <listitem>URL <literal>product?item=4317</literal> will select 
     200     controller <literal>catalog</literal>, action 
     201     <literal>find</literal> 
     202    </listitem> 
     203    <listitem>URL <literal>cart/add/4317</literal> will select 
     204     controller <literal>cart</literal>, action <literal>add</literal> 
     205    </listitem> 
     206   </itemizedlist>     
     207  </para> 
     208 
     209 </refsect1> 
     210 <refsect1 is="{@id action}"> 
     211  <title>Action Call</title> 
     212  <para>When the names of the controller and action have been 
     213   successfully determined from the URL, the associated filesystem 
     214   paths are constructed and relevant files are loaded. 
     215   First file <literal>app/controllers/application.php</literal> is 
     216   loaded if it exists. This file contains the definition of the 
     217   {@link ApplicationController} class, which extends 
     218   <literal>ActionController</literal>. 
     219   <literal>ApplicationController</literal> contains properties and 
     220   methods used by all the controller classes, which should extend 
     221   <literal>ApplicationController</literal> . 
     222   Then the controller name is used to find the file and class 
     223   containing the selected controller.  By Trax naming conventions,  
     224   if the controller name is 
     225   <arg choice="tute-comment">controller&nbsp;name</arg> 
     226   then the controller file name is 
     227   <arg choice="tute-comment">controller_name</arg><literal>_controller.php</literal> 
     228   and the controller class name is 
     229   <arg choice="tute-comment">ControllerName</arg> .  So for a 
     230   "catalog&nbsp;item" controller, the controller file name is 
     231   <literal>catalog_item_controller</literal> and the controller class 
     232   name is <literal>CatalogItem</literal>. 
     233   The controller file is loaded and a new object of the controller 
     234   class is created. 
     235  </para> 
     236 
     237  <para> 
     238   Next any needed helper files are loaded.  Helper files contain PHP 
     239   code which helps prepare the output of an action method for 
     240   viewing. If file 
     241   <literal>application_helper.php</literal> exists, it is loaded. 
     242   <literal>application_helper.php</literal> contains 
     243   helpers that apply to every controller in the application. 
     244   Then the controller-specific helper file 
     245   <arg choice="tute-comment">controller_name</arg><literal>_helper.php</literal> 
     246   is loaded if it exists.  Finally any extra helper files, as 
     247   specified by calls to {@link ActionController::add_helper()}, are 
     248   loaded. 
     249  </para> 
     250 
     251  <para> 
     252   When controller and helper files have been loaded, the before 
     253   filters are executed (<important>FIXME:</important> We should check 
     254   return but don't).  Next the controller object is tested for the 
     255   presence of a method with the name of the action as determined from 
     256   the URL. If such a method exists, it is called; if  
     257   no such method exists, then the controller object is tested 
     258   for the presence of a method named <literal>index()</literal>. 
     259   If such a method exists it is called, otherwise the request fails 
     260   with 404&nbsp;Unknown&nbsp;action. If an action method was found 
     261   and called, the after filters are executed. 
     262  </para> 
     263 
     264  <refsect2 id="{@id helpers}"> 
     265   <title>Helper Loading</title> 
     266   <para>Helpers are classes that provide view logic.  They exist to 
     267    hold view logic that would otherwise need to be added to a 
     268    template or controller.  Helper services that are applicable to 
     269    the entire application go into 
     270    <literal>application_helper.php</literal>, while 
     271    controller-specific helper functions go into a helper file named 
     272    after the controller, as  
     273    <arg choice="tute-comment">controller_name</arg><literal>_helper.php</literal>  
     274    . Helper classes are written as subclasses of class {@link Helpers}, 
     275    which has a number of methods widely used by helper 
     276    subclasses.  You can add a helper to an 
     277    <literal>ActionController</literal> object by calling its 
     278    {@link ActionController::add_helper() add_helper()}  
     279    method, passing the name of the helper as an argument. 
     280   </para> 
     281 
     282   <para> 
     283    A number of predefined helper classes are distributed with Trax: 
     284    <itemizedlist> 
     285     <listitem>{@link ActiveRecordHelper}</listitem> 
     286     <listitem>{@link AssetTagHelper}</listitem> 
     287     <listitem>{@link DateHelper}</listitem> 
     288     <listitem>{@link FormHelper}</listitem> 
     289     <listitem>{@link FormTagHelper}</listitem> 
     290     <listitem>{@link JavaScriptHelper}</listitem> 
     291     <listitem>{@link UrlHelper}</listitem> 
     292    </itemizedlist> 
     293    These classes are <important>not</important> automatically loaded, 
     294    you have to load them explicitly. 
     295   </para> 
     296   <para></para> 
     297  </refsect2> 
     298 
     299  <refsect2 id="{@id filters}"> 
     300   <title>Filters</title> 
    20301 
    21302   <para>Filters enable controllers to run shared pre and post 
     
    30311    for a pre-processing <samp>before_filter</samp> to halt the processing 
    31312    before the intended action is processed by returning false or 
    32     performing a redirect or render.  This is especially useful for 
     313    performing a redirect or render. (FIXME: we don't implement this) 
     314    This is especially useful for 
    33315    filters like authentication where you're not interested in 
    34316    allowing the action to be  performed if the proper credentials are 
    35317    not in order.</para> 
    36318 
    37    <refsect2 id="{@id filter_inherit}"> 
     319   <refsect3 id="{@id filter_inherit}"> 
    38320    <title>Filter inheritance</title> 
    39321 
     
    66348     audit method is called, then the verify_credentials method. If the 
    67349     audit method returns false, then verify_credentials and the 
    68      intended action are never called.</para> 
    69     </refsect2> 
    70  
    71     <refsect2 id="{@id filter_types}"> 
     350     intended action are never called.  <important>FIXME: 
     351     This is currently broken.</important></para> 
     352    </refsect3> 
     353 
     354    <refsect3 id="{@id filter_types}"> 
    72355     <title>Filter types</title> 
    73356 
     
    120403      have to be a block; any object that responds to call and returns 1 
    121404      or -1 on arity will do (such as a Proc or an Method object).</para> 
    122     </refsect2> 
    123  
    124     <refsect2 id="{@id filter_skip}"> 
     405    </refsect3> 
     406 
     407    <refsect3 id="{@id filter_skip}"> 
    125408     <title>Filter chain skipping</title> 
    126409 
     
    142425} 
    143426     </example> 
    144     </refsect2> 
    145  
    146     <refsect2 id="{@id filter_conditions}"> 
     427    </refsect3> 
     428 
     429    <refsect3 id="{@id filter_conditions}"> 
    147430     <title>Filter conditions</title> 
    148431 
     
    169452      condition must come first and be placed in parentheses.</para> 
    170453  
    171    <example> 
     454    <example> 
    172455class UserPreferences extends ActionController 
    173456{ 
     
    175458    ... 
    176459} 
    177   </example> 
     460    </example> 
     461   </refsect3> 
    178462  </refsect2> 
     463 </refsect1> 
     464 <refsect1 id="{@id render}"> 
     465  <title>Redirect Browser or Render Output</title> 
     466 
     467  <para>After the controller object's action method has returned to 
     468   <literal>ActionController::process_route()</literal> and the after 
     469   filters have been executed, the controller object is examined for 
     470   a property named <literal>redirect_to</literal>.  If this 
     471   property exists and has a value, it means that the action method 
     472   has decided to redirect the user's browser to a different URL.  The 
     473   value of the <literal>redirect_to</literal> property is passed to 
     474   {@link ActionController::redirect_to() <literal>redirect_to()</literal>} 
     475   which outputs a header redirecting the browser, then calls 
     476   {@link http://www.php.net/manual/en/function.exit.php exit} .</para> 
     477 
     478  <para> 
     479   If the action didn't redirect the browser, it should have provided 
     480   output to send to the browser.  This is in the form of explicit 
     481   output produced by calls to 
     482   {@link http://www.php.net/manual/en/function.echo.php echo}, 
     483   {@link http://www.php.net/manual/en/function.print.php print} or 
     484   {@link http://www.php.net/manual/en/function.printf.php printf} , 
     485   plus any properties of the controller object that are referenced in 
     486   the layout. <literal>ActionController::process_route()</literal> 
     487   collects all output produced by the controller's action method 
     488   in the output buffer, for presentation within a layout. 
     489  </para> 
     490 
     491  <para> 
     492   If the controller object has a property 
     493   <literal>render_text</literal> which contains a string, then this 
     494   string is sent directly to the browser and all output and view 
     495   files are ignored. 
     496  </para> 
     497 
     498  <para> 
     499   If <literal>render_text</literal> is undefined or empty, then the 
     500   saved output of the controller's action method is to be rendered. 
     501   A <important>view file</important> determined by the action is 
     502   found and included.  The view file for an action is 
     503   <literal>app/views/</literal><arg choice="tute-comment">controller_name/action_name</arg><literal>.phtml</literal> . 
     504   This file contains HTML, which goes to the output buffer after the 
     505   action method's output.  The output buffer is now assigned to 
     506   $content_for_layout.  Finally the layout file is loaded.  The 
     507   view file and layout file both contain HTML with 
     508   {@link http://www.php.net/manual/en/language.basic-syntax.php embedded PHP} 
     509   expressions to present action method output to the user. 
     510  </para> 
    179511 </refsect1> 
    180512<!-- 
  • trunk/trax/tutorials/PHPonTrax/PHPonTrax.pkg

    r165 r174  
    269269     To: 
    270270     <example> 
    271 RewriteRule ^(.*)$ ~haas/dispatch.php?$1 [QSA,L] 
     271RewriteRule ^(.*)$ /~haas/dispatch.php?$1 [QSA,L] 
    272272     </example> 
    273273     </listitem> 
     
    303303     <listitem> 
    304304     With your favorite editor, open file 
    305      ~/trax/config/environment.php and change the line that defines 
    306      TRAX_URL_PREFIX to: 
     305     <literal>~/trax/config/environment.php</literal> and change the 
     306     line that defines <literal>TRAX_URL_PREFIX</literal> to: 
    307307     <example> 
    308308define("TRAX_URL_PREFIX", "~haas"); 
    309309     </example> 
    310      </listitem> 
    311  
    312      <listitem> 
    313      Change file permissions on the log files in ~/trax/log so that 
    314      Apache can write to them: 
     310     Also edit the line that defines <literal>TRAX_PUBLIC</literal> to 
     311     change <literal>public</literal> to <literal>public_html</literal>. 
     312     </listitem> 
     313 
     314     <listitem> 
     315     Change file permissions on the log files in 
     316     <literal>~/trax/log</literal> so that Apache can write to them: 
    315317     <example> 
    316318$ <important>su -</important> 
     
    393395  <refsect2 id="{@id ref_defines}"> 
    394396   <title>Defines</title> 
     397   All the definitions below are set in file 
     398  {@link environment.php config/environment.php} 
    395399   <itemizedlist> 
     400 
     401    <listitem><command>DEBUG</command> 
     402     <cmdsynopsis>boolean set to true if TRAX_MODE is 'development', 
     403     false otherwise.  Determines whether PHP error messages should be 
     404     sent to the browser; true means show error messages on the 
     405     browser as well as the error log, false means send error messages 
     406     to only the error log.  Implemented by calling 
     407     {@link http://www.php.net/ini_set ini_set()} 
     408     at the time DEBUG is defined. 
     409     </cmdsynopsis> 
     410    </listitem> 
     411 
     412    <listitem><command>PHP_LIB_ROOT</command> 
     413     <cmdsynopsis>Directory containing PHP libraries.  This directory 
     414     will be added to the PHP 
     415     {@link http://www.php.net/manual/en/ini.core.php#ini.include-path include path}. 
     416     </cmdsynopsis> 
     417    </listitem> 
     418 
     419    <listitem><command>TRAX_LIB_ROOT</command> 
     420     <cmdsynopsis>Directory containing Trax libraries.  Set to a 
     421     subdirectory of TRAX_ROOT or PHP_LIB_ROOT and added to the PHP 
     422     {@link http://www.php.net/manual/en/ini.core.php#ini.include-path include path}. 
     423     </cmdsynopsis> 
     424    </listitem> 
    396425 
    397426    <listitem><command>TRAX_MODE</command> 
     
    401430    </listitem> 
    402431 
     432    <listitem><command>TRAX_PATH_SEPERATOR</command> 
     433     <cmdsynopsis>Character to use as the separator when defining the 
     434     PHP include path. ';' for Windows, otherwise ':'. 
     435     </cmdsynopsis> 
     436    </listitem> 
     437 
     438    <listitem><command>TRAX_PUBLIC</command> 
     439     <cmdsynopsis>Subdirectory of the user's home directory referenced 
     440     by the Apache configuration variable <literal>UserDir</literal>. 
     441     </cmdsynopsis> 
     442    </listitem> 
     443 
     444    <listitem><command>TRAX_ROOT</command> 
     445     <cmdsynopsis>Filesystem path to the top of the Trax file tree. 
     446     </cmdsynopsis> 
     447    </listitem> 
     448 
     449    <listitem><command>TRAX_URL_PREFIX</command> 
     450     <cmdsynopsis>That part of a URL which refers to a Trax 
     451     application that comes after the domain name and before the 
     452     controller.  Usually empty.  In the case of a Trax application in 
     453     the home directory of user <literal>username</literal>, 
     454     <command>TRAX_URL_PREFIX</command> would be set to  
     455     '<literal>~username</literal>'. 
     456     </cmdsynopsis> 
     457    </listitem> 
     458 
    403459    <listitem><command>TRAX_VIEWS_EXTENTION</command> 
    404      <cmdsynopsis>file extension for views</cmdsynopsis> 
    405     </listitem> 
    406  
    407     <listitem><command></command> 
    408      <cmdsynopsis> 
    409      </cmdsynopsis> 
    410     </listitem> 
    411  
    412     <listitem><command></command> 
    413      <cmdsynopsis> 
    414      </cmdsynopsis> 
    415     </listitem> 
    416  
    417     <listitem><command></command> 
    418      <cmdsynopsis> 
    419      </cmdsynopsis> 
    420     </listitem> 
    421  
    422     <listitem><command></command> 
    423      <cmdsynopsis> 
    424      </cmdsynopsis> 
    425     </listitem> 
    426  
    427     <listitem><command></command> 
    428      <cmdsynopsis> 
    429      </cmdsynopsis> 
     460     <cmdsynopsis>File extension for views, default 
     461     'phtml'.</cmdsynopsis> 
    430462    </listitem> 
    431463 
  • trunk/trax/vendor/trax/action_controller.php

    r167 r174  
    3232 *  Action controller 
    3333 * 
    34  *  <p><b>Filters</b></p> 
     34 *  <p>The ActionController base class operates as follows:</p> 
     35 *  <ol> 
     36 *    <li>Accept a URL as input</li> 
     37 *    <li>Translate the URL into a controller and action</li> 
     38 *    <li>Create the indicated controller object (which is a subclass 
     39 *      of ActionController) and call its action method</li> 
     40 *    <li>Render the output of the action method</li> 
     41 *    <li>Redirect to the next URL</li> 
     42 *  </ol> 
    3543 * 
    36  *  <p>Filters enable controllers to run shared pre and post 
    37  *  processing code for its actions. These filters can be used to do 
    38  *  authentication, caching, or auditing before the intended action is 
    39  *  performed. Or to do localization or output compression after the 
    40  *  action has been performed.</p> 
    41  * 
    42  *  <p>Filters have access to the request, response, and all the 
    43  *  instance variables set by other filters in the chain or by the 
    44  *  action (in the case of after filters). Additionally, it's possible 
    45  *  for a pre-processing <samp>before_filter</samp> to halt the processing 
    46  *  before the intended action is processed by returning false or 
    47  *  performing a redirect or render.  This is especially useful for 
    48  *  filters like authentication where you're not interested in 
    49  *  allowing the action to be  performed if the proper credentials are 
    50  *  not in order.</p> 
    51  * 
    52  *  <p><b>Filter inheritance</b></p> 
    53  * 
    54  *  <p>Controller inheritance hierarchies share filters downwards, but 
    55  *  subclasses can also add new filters without affecting the 
    56  *  superclass. For example:</p> 
    57  * 
    58  *  <pre> 
    59  *   class BankController extends ActionController 
    60  *   { 
    61  *     $this->before_filter = audit(); 
    62  * 
    63  *     private function audit() { 
    64  *       <i>record the action and parameters in an audit log</i> 
    65  *     } 
    66  *   } 
    67  * 
    68  *   class VaultController extends BankController 
    69  *   { 
    70  *     $this->before_filter = verify_credentials(); 
    71  * 
    72  *     private function verify_credentials() { 
    73  *       <i>make sure the user is allowed into the vault</i> 
    74  *     } 
    75  *   } 
    76  *  </pre> 
    77  * 
    78  *  <p>Now any actions performed on the BankController will have the 
    79  *  audit method called before. On the VaultController, first the 
    80  *  audit method is called, then the verify_credentials method. If the 
    81  *  audit method returns false, then verify_credentials and the 
    82  *  intended action are never called.</p> 
    83  * 
    84  *  <p><b>Filter types</b></p> 
    85  * 
    86  *  <p>A filter can take one of three forms: method reference 
    87  *  (symbol), external class, or inline method (proc). The first is the 
    88  *  most common and works by referencing a protected or private method 
    89  *  somewhere in the inheritance hierarchy of the controller by use of 
    90  *  a symbol. In the bank example above, both BankController and 
    91  *  VaultController use this form.</p> 
    92  * 
    93  *  <p>Using an external class makes for more easily reused generic 
    94  *  filters, such as output compression. External filter classes are 
    95  *  implemented by having a static +filter+ method on any class and 
    96  *  then passing this class to the filter method. Example:</p> 
    97  * 
    98  *  <pre> 
    99  *   class OutputCompressionFilter 
    100  *   { 
    101  *     static functionfilter(controller) { 
    102  *       controller.response.body = compress(controller.response.body) 
    103  *     } 
    104  *   } 
    105  * 
    106  *   class NewspaperController extends ActionController 
    107  *   { 
    108  *     $this->after_filter = OutputCompressionFilter; 
    109  *   } 
    110  *  </pre> 
    111  * 
    112  *  <p>The filter method is passed the controller instance and is 
    113  *  hence granted access to all aspects of the controller and can 
    114  *  manipulate them as it sees fit.</p> 
    115  * 
    116  *  <p>The inline method (using a proc) can be used to quickly do 
    117  *  something small that doesn't require a lot of explanation.  Or 
    118  *  just as a quick test. It works like this:</p> 
    119  * 
    120  *  <pre> 
    121  *   class WeblogController extends ActionController 
    122  *   { 
    123  *     before_filter { |controller| false if controller.params["stop_action"] } 
    124  *   } 
    125  *  </pre> 
    126  * 
    127  *  <p>As you can see, the block expects to be passed the controller 
    128  *  after it has assigned the request to the internal variables.  This 
    129  *  means that the block has access to both the request and response 
    130  *  objects complete with convenience methods for params, session, 
    131  *  template, and assigns. Note: The inline method doesn't strictly 
    132  *  have to be a block; any object that responds to call and returns 1 
    133  *  or -1 on arity will do (such as a Proc or an Method object).</p> 
    134  * 
    135  *  <p><b>Filter chain skipping</b></p> 
    136  * 
    137  *  <p>Some times its convenient to specify a filter chain in a superclass  
    138  *  that'll hold true for the majority of the subclasses, but not necessarily 
    139  *  all of them. The subclasses that behave in exception can then specify 
    140  *  which filters they would like to be relieved of. Examples</p> 
    141  * 
    142  *  <pre> 
    143  *   class ApplicationController extends ActionController 
    144  *   { 
    145  *     $this->before_filter = authenticate(); 
    146  *   } 
    147  * 
    148  *   class WeblogController extends ApplicationController 
    149  *   { 
    150  *      // will run the authenticate() filter 
    151  *   } 
    152  *  </pre> 
    153  * 
    154  *  <p><b>Filter conditions</b></p> 
    155  * 
    156  *  <p>Filters can be limited to run for only specific actions. This 
    157  *  can be expressed either by listing the actions to exclude or 
    158  *  the actions to include when executing the filter. Available 
    159  *  conditions are +:only+ or +:except+, both of which accept an 
    160  *  arbitrary number of method references. For example:</p> 
    161  * 
    162  *  <pre> 
    163  *   class Journal extends ActionController 
    164  *   { 
    165  *     // only require authentication if the current action is edit or delete 
    166  *     before_filter :authorize, :only => [ :edit, :delete ] 
    167  *     
    168  *     private function authorize() { 
    169  *      // redirect to login unless authenticated 
    170  *     } 
    171  *   } 
    172  *  </pre> 
    173  *  
    174  *  <p>When setting conditions on inline method (proc) filters the 
    175  *  condition must come first and be placed in parentheses.</p> 
    176  * 
    177  *  <pre> 
    178  *   class UserPreferences extends ActionController 
    179  *   { 
    180  *     before_filter(:except => :new) { ? some proc ... } 
    181  *  * ... 
    182  *   } 
    183  *  </pre> 
     44 *  For details see the 
     45 *  {@tutorial PHPonTrax/ActionController.cls class tutorial} 
    18446 */ 
    18547class ActionController { 
     
    20264 
    20365    /** 
    204      *  @todo Document this attribute 
     66     *  Value of :id parsed from URL then forced to lower case 
     67     * 
     68     *  Set by {@link recognize_route()} 
     69     *  @var string 
    20570     */ 
    20671    private $id; 
     
    22388 
    22489    /** 
     90     *  Filesystem path to ../app/helpers/<i>extras</i> directory 
     91     * 
     92     *  Set by {@link recognize_route()}, {@link set_paths()} 
     93     *  @var string 
     94     */ 
     95    private $helpers_path; 
     96 
     97    /** 
    22598     *  Filesystem path to ../app/helpers/ directory 
    22699     * 
     
    228101     *  @var string 
    229102     */ 
    230     private $helpers_path; 
    231  
    232     /** 
    233      *  @todo Document this attribute 
    234      */ 
    235103    private $helpers_base_path; 
    236104 
    237105    /** 
    238      *  Filesystem path to ../app/layouts/ directory 
    239      * 
    240      *  Set by {@link recognize_route()} 
    241      *  @todo <b>FIXME:</> declare $layouts_base_path 
     106     *  Filesystem path to ../app/views/layouts/<i>extras</i> directory 
     107     * 
     108     *  Set by {@link recognize_route()}, {@link set_paths()} 
    242109     *  @var string 
    243110     */ 
    244111    private $layouts_path; 
     112 
     113    /** 
     114     *  Filesystem path to ../app/views/layouts/ directory 
     115     * 
     116     *  Set by {@link recognize_route()} 
     117     *  @var string 
     118     */ 
     119    private $layouts_base_path; 
    245120 
    246121    /** 
     
    263138 
    264139    /** 
    265      *  @todo Document this attribute 
     140     *  Filesystem path to the controllername_helper.php file 
     141     * 
     142     *  Set by {@link recognize_route()} 
     143     *  @var string 
    266144     */ 
    267145    private $helper_file; 
     
    306184 
    307185    /** 
     186     *  List of additional helper files for this controller object 
     187     * 
     188     *  Set by {@link add_helper()} 
     189     *  @var string[] 
     190     */ 
     191    private $helpers = array(); 
     192 
     193    /** 
     194     *  List of filters to execute before calling action method 
     195     * 
     196     *  Set by {@link add_before_filters() 
     197     *  @var string[] 
     198     */ 
     199    private $before_filters = array(); 
     200 
     201    /** 
     202     *  List of filters to execute after calling action method 
     203     * 
     204     *  Set by {@link add_after_filters() 
     205     *  @var string[] 
     206     */ 
     207    private $after_filters = array();      
     208 
     209    /** 
    308210     *  @todo Document this attribute 
    309211     */ 
    310     private $helpers = array(); 
     212    protected $before_filter = null; 
    311213 
    312214    /** 
    313215     *  @todo Document this attribute 
    314216     */ 
    315     private $before_filters = array(); 
    316  
    317     /** 
    318      *  @todo Document this attribute 
    319      */ 
    320     private $after_filters = array();      
    321  
    322     /** 
    323      *  @todo Document this attribute 
    324      */ 
    325     protected $before_filter = null; 
    326  
    327     /** 
    328      *  @todo Document this attribute 
    329      */ 
    330217    protected $after_filter = null; 
    331218 
     
    340227 
    341228    /** 
    342      *  @todo Document this attribute 
     229     *  Filesystem path to the view file selected for this action 
     230     * 
     231     *  Set by {@link process_route() 
     232     *  @var string 
    343233     */ 
    344234    public $view_file; 
     
    371261    /** 
    372262     *  @todo Document this attribute 
     263     *  @todo <b>FIXME:</b> Not referenced in this class - is it used 
     264     *        by subclasses?  If so, for what? 
    373265     */ 
    374266    public $asset_host = null; 
    375267 
    376268    /** 
    377      *  @todo Document this attribute 
     269     *  File extension appended to view files 
     270     * 
     271     *  Set from a define in {@link environment.php}.  Usually phtml 
     272     *  @var string 
    378273     */ 
    379274    public $views_file_extention = TRAX_VIEWS_EXTENTION; 
     
    462357     *  Convert URL to controller, action and id 
    463358     * 
    464      *  Parse the URL in $_SERVER['REDIRECT_URL'] into elements. 
     359     *  Parse the URL in 
     360     *  {@link 
     361     *  http://www.php.net/manual/en/reserved.variables.php#reserved.variables.server $_SERVER}['REDIRECT_URL'] 
     362     *  into elements. 
    465363     *  Compute filesystem paths to the various components used by the 
    466364     *  URL and store the paths in object private variables. 
     
    499397        # current url 
    500398        $browser_url = $_SERVER['REDIRECT_URL']; 
     399        //error_log('browser url='.$browser_url); 
    501400        # strip off url prefix, if any 
    502401        if(!is_null(TRAX_URL_PREFIX)) { 
    503             $browser_url = str_replace(TRAX_URL_PREFIX,"",$browser_url); 
    504         } 
     402            // FIXME: Do we know for sure that the 
     403            // initial '/' will be there? 
     404            $browser_url = str_replace('/'.TRAX_URL_PREFIX,"",$browser_url); 
     405        } 
     406        //error_log('browser url='.$browser_url); 
    505407 
    506408        # strip leading slash 
     409        // FIXME: Do we know for sure that the 
     410        // initial '/' will be there? 
    507411        $browser_url = substr($browser_url,1); 
     412        //error_log('browser url='.$browser_url); 
    508413 
    509414        # strip trailing slash (if any) 
     
    511416            $browser_url = substr($browser_url, 0, -1); 
    512417        } 
     418        //error_log('browser url='.$browser_url); 
    513419 
    514420        if($browser_url) { 
     
    528434 
    529435            $route = $this->router->find_route($browser_url); 
     436 
     437            //  find_route() returns an array if it finds a path that 
     438            //  matches the URL, null if no match found 
    530439            if(is_array($route)) { 
    531440                $this->set_paths(); 
     
    538447                    $this->controller = strtolower($this->url_path[@array_search(":controller", $route_path)]); 
    539448                } 
    540  
     449                //error_log('controller='.$this->controller); 
    541450                if(@array_key_exists(":action",$route_params)) { 
    542451                    $this->action = $route_params[':action']; 
     
    546455                    $this->action = strtolower($this->url_path[@array_search(":action", $route_path)]); 
    547456                } 
    548  
     457                //error_log('action='.$this->action); 
     458                //  FIXME: RoR uses :name as a keyword parameter, id 
     459                //  is not treated as a special case. 
     460                //  Do we want to do the same? 
    549461                if(@in_array(":id",$route_path) 
    550462                   && array_key_exists(@array_search(":id", $route_path), 
     
    555467                    } 
    556468                } 
    557  
     469                //error_log('id='.$this->id); 
    558470                $this->views_path .= "/" . $this->controller; 
    559471                $this->controller_file = $this->controllers_path . "/" .  $this->controller . "_controller.php"; 
     
    573485 
    574486    /** 
    575      *  @todo Document this method 
     487     *  Parse URL, extract controller and action and execute them 
     488     * 
    576489     *  @uses $action 
    577490     *  @uses $application_controller_file 
     
    591504     *  @uses raise() 
    592505     *  @uses ScaffoldController 
    593      *  @uses Session::unset() 
     506     *  @uses Session::unset_var() 
    594507     *  @uses $view_file 
    595508     *  @uses $views_file_extention 
     
    599512    function process_route() { 
    600513 
     514        $render_layout = true; 
    601515        # First try to load the routes and setup the paths to everything 
    602516        if(!$this->loaded) { 
     
    616530        } 
    617531 
    618         error_log('process_route() controller="'.$this->controller 
    619                   .'"  action="'.$this->action.'"'); 
     532        //error_log('process_route() controller="'.$this->controller 
     533        //          .'"  action="'.$this->action.'"'); 
    620534        # Include the controller file and execute action 
    621535        // FIXME: redundant, recognize_route() already test for file exists 
    622         if(file_exists($this->controller_file)) { 
     536        if (file_exists($this->controller_file)) { 
    623537            include_once($this->controller_file); 
    624538            if(class_exists($this->controller_class,false)) { 
     
    633547                    $GLOBALS['current_action_name'] = $this->action; 
    634548                    $GLOBALS['current_controller_object'] =& $this->controller_object; 
    635                     error_log('$GLOBALS[\'current_action_name\']=' 
    636                               .$GLOBALS['current_action_name']); 
    637                     error_log('$GLOBALS[\'current_controller_name\']=' 
    638                               .$GLOBALS['current_controller_name']); 
    639                     error_log('$GLOBALS[\'current_controller_path\']=' 
    640                               .$GLOBALS['current_controller_path']); 
     549                    // error_log('$GLOBALS[\'current_action_name\']=' 
     550                    //           .$GLOBALS['current_action_name']); 
     551                    // error_log('$GLOBALS[\'current_controller_name\']=' 
     552                    //           .$GLOBALS['current_controller_name']); 
     553                    // error_log('$GLOBALS[\'current_controller_path\']=' 
     554                    //           .$GLOBALS['current_controller_path']); 
    641555                } 
    642556 
    643557                # Which layout should we use? 
    644558                $layout_file = $this->determine_layout(); 
    645                 error_log('layout_file="'.$layout_file.'"'); 
    646                 # Check if there is any defined scaffolding to load 
     559                // error_log('layout_file="'.$layout_file.'"'); 
     560                // # Check if there is any defined scaffolding to load 
    647561                if(isset($this->controller_object->scaffold)) { 
    648562                    $scaffold = $this->controller_object->scaffold; 
     
    694608                # Call the controller method based on the URL 
    695609                $this->execute_before_filters(); 
     610                // FIXME: shouldn't we check return here? 
    696611                if(method_exists($this->controller_object, $this->action)) { 
    697                     error_log('controller has method "'.$this->action.'"'); 
     612                    //error_log('controller has method "'.$this->action.'"'); 
    698613                    $action = $this->action; 
    699614                    $this->controller_object->$action(); 
    700615                } elseif(file_exists($this->views_path . "/" . $this->action . "." . $this->views_file_extention)) { 
    701                     error_log('views file "'.$this->action.'"'); 
     616                    // error_log('views file "'.$this->action.'"'); 
    702617                    $action = $this->action; 
    703618                } elseif(method_exists($this->controller_object, "index")) { 
    704                     error_log('calling index()'); 
     619                    //error_log('calling index()'); 
    705620                    $this->controller_object->index(); 
    706621                } else { 
    707                     error_log('no action'); 
     622                    //error_log('no action'); 
    708623                    $this->raise("No action responded to ".$this->action, "Unknown action", "404"); 
    709624                } 
     
    714629                    && $this->controller_object->redirect_to != '') { 
    715630                    $this->redirect_to($this->controller_object->redirect_to); 
     631                    //  redirect_to() exits instead of returning 
    716632                } else { 
    717633                    # Pull all the class vars out and turn them from $this->var to $var 
     
    725641                    # If this isn't a scaffolding then get the view file to include 
    726642                    if(!isset($scaffold)) {  
     643                        // error_log('not scaffolding, looking for view file'); 
    727644                        # Normal processing of the view 
    728645                        if(isset($this->controller_object->render_action) 
     
    735652                            $this->view_file = $this->views_path . "/" . "index" . "." . $this->views_file_extention; 
    736653                        } 
     654                        // error_log('view file='.$this->view_file); 
    737655                    } 
    738656 
     
    748666                    ob_end_clean(); 
    749667 
     668                    //error_log('layout file='.$layout_file 
     669                    //          .'  render_layout=' 
     670                    //          .var_export($render_layout,true)); 
    750671                    if(file_exists($layout_file) && $render_layout !== false) { 
    751672                        # render the layout 
     
    765686        } 
    766687 
     688        // error_log('keep flash='.var_export($this->keep_flash,true)); 
    767689        if(!$this->keep_flash) { 
    768690            # Nuke the flash 
     
    774696 
    775697    /** 
    776      *  @todo Document this method 
     698     *  Extend the search path for components 
     699     * 
     700     *  On entry, $url_path is set according to the browser's URL and  
     701     *  $controllers_path has been set according to the configuration 
     702     *  in {@link environment.php config/environment.php} .  Examine 
     703     *  the $controllers_path directory for files or directories that 
     704     *  match any component of the URL.  If one is found, add that 
     705     *  component to all paths.  Replace the contents of $url_path 
     706     *  with the list of URL components that did NOT match any files 
     707     *  or directories. 
    777708     *  @uses $added_path 
    778709     *  @uses $controllers_path 
    779710     *  @uses $helpers_path 
    780      *  @uses $layous_path 
     711     *  @uses $layouts_path 
    781712     *  @uses $views_path 
    782713     *  @uses $url_path 
     714     *  @todo <b>FIXME:</b> Creating a file or directory in 
     715     *        app/controllers with the same name as a controller, action or 
     716     *        other URL element will hijack the browser! 
    783717     */ 
    784718    function set_paths() { 
     
    808742    /** 
    809743     *  Execute the before filters 
     744     *  @uses $before_filters 
    810745     */ 
    811746    function execute_before_filters() { 
     
    825760     *  one filter function, or array of strings with the names of 
    826761     *  several filter functions. 
     762     *  @uses $before_filters 
    827763     */ 
    828764    function add_before_filter($filter_function_name) { 
     
    840776    } 
    841777 
     778    /** 
     779     *  Execute the after filters 
     780     *  @uses $after_filters 
     781     */ 
    842782    function execute_after_filters() { 
    843783        if(count($this->controller_object->after_filters) > 0) { 
     
    857797     *  one filter function, or array of strings with the names of 
    858798     *  several filter functions. 
     799     *  @uses $after_filters 
    859800     */ 
    860801    function add_after_filter($filter_function_name) { 
     
    872813    } 
    873814 
     815    /** 
     816     *  Add a helper to the list of helpers used by a controller 
     817     *  object 
     818     * 
     819     *  @param $helper_name string Name of a helper to add to the list 
     820     *  @uses  $helpers 
     821     *  @uses  $controller_object 
     822     */ 
    874823    function add_helper($helper_name) { 
    875824        if(!in_array($helper_name, $this->controller_object->helpers)) { 
     
    969918 
    970919    /** 
    971      *  @todo Document this method 
     920     *  Select a layout file based on the controller object 
     921     * 
    972922     *  @uses $controller_object 
    973923     *  @uses $layouts_base_path 
     
    979929        # I guess you don't want any layout 
    980930        if($this->controller_object->layout == "null") { 
     931            //error_log('controller->layout absent'); 
    981932            return null; 
    982933        } 
     
    1015966 
    1016967    /** 
    1017      * Redirects the browser to the target specified in options. This parameter can take one of three forms: 
    1018      *  
    1019      *     * Array: The URL will be generated by calling url_for() with the options. 
    1020      *     * String starting with protocol:// (like http://): Is passed straight through as the target for redirection. 
    1021      *     * String not containing a protocol: The current protocol and host is prepended to the string. 
    1022      *     * back: Back to the page that issued the request. Useful for forms that are triggered from multiple places. Short-hand for redirect_to(request.env["HTTP_REFERER"]) 
    1023      *  
    1024      * Examples: 
    1025      *  
    1026      *   redirect_to(array(":action" => "show", ":id" => 5)) 
    1027      *   redirect_to("http://www.rubyonrails.org") 
    1028      *   redirect_to("/images/screenshot.jpg") 
    1029      *   redirect_to("back") 
    1030      * 
    1031      * @param mixed $options array or string url   
     968     *  Redirect the browser to a specified target 
     969     * 
     970     *  Redirect the browser to the target specified in $options. This 
     971     *  parameter can take one of three forms: 
     972     *  <ul> 
     973     *    <li>Array: The URL will be generated by calling 
     974     *      {@link url_for()} with the options.</li> 
     975     *    <li>String starting with a protocol:// (like http://): Is 
     976     *      passed straight through as the target for redirection.</li> 
     977     *    <li>String not containing a protocol: The current protocol 
     978     *      and host is prepended to the string.</li> 
     979     *    <li>back: Back to the page that issued the request. Useful 
     980     *      for forms that are triggered from multiple 
     981     *      places. Short-hand for redirect_to(request.env["HTTP_REFERER"])  
     982     *   </ul> 
     983     * 
     984     *  Examples: 
     985     *  <ul> 
     986     *    <li>redirect_to(array(":action" => "show", ":id" => 5))</li> 
     987     *    <li>redirect_to("http://www.rubyonrails.org")</li> 
     988     *    <li>redirect_to("/images/screenshot.jpg")</li> 
     989     *    <li>redirect_to("back")</li> 
     990     *  </ul> 
     991     * 
     992     *  @param mixed $options array or string url   
     993     *  @todo <b>FIXME:</b> Make header configurable 
    1032994     */     
    1033995    function redirect_to($options = null) { 
  • trunk/trax/vendor/trax/router.php

    r162 r174  
    106106     *  empty string, it matches a path that is an empty string. 
    107107     *  Otherwise, try to match $url to the path part of the table 
    108      *  entry according to {@link http://www.php.net/manual/en/ref.pcre.php Perl regular expression} 
    109      *  rules.  Return the first matching route to the caller, and 
    110      *  also save a copy in {@link $selected_route}. 
     108     *  entry according to 
     109     *  {@link http://www.php.net/manual/en/ref.pcre.php Perl regular expression} 
     110     *  rules.  If a matching route is found, return it any to the caller, and 
     111     *  also save a copy in {@link $selected_route}; if no matching 
     112     *  route is found return null. 
    111113     *  @param string $url 
    112114     *  @uses build_route_regexp() 
     
    115117     *  @uses $routes_count 
    116118     *  @uses $selected_route 
    117      *  @return string[] Selected route. Path is in return['path'], 
     119     *  @return mixed Matching route or null. Path is in return['path'], 
    118120     *                   params in return['params'], 
    119121     */ 
    120122    function find_route($url) { 
     123        //error_log('url='.$url); 
    121124        // ensure at least one route (the default route) exists 
    122125        if($this->routes_count == 0) { 
     
    130133            unset($reg_exp); 
    131134            $route_regexp = $this->build_route_regexp($route['path']); 
     135            //error_log("route regexp=/$route_regexp/"); 
    132136            if($url == "" && $route_regexp == "") { 
     137                //error_log('selected'); 
    133138                $this->selected_route = $route; 
    134139                break; 
    135140            } elseif(preg_match("/$route_regexp/",$url) && $route_regexp != "") { 
     141                //error_log('selected'); 
    136142                $this->selected_route = $route; 
    137143                break; 
    138144            } elseif($route['path'] == $this->default_route_path) { 
     145                //error_log('defaulted'); 
    139146                $this->selected_route = $route; 
    140147                break; 
    141148            } 
    142149        } 
    143  
     150        //error_log('selected route='.var_export($this->selected_route,true)); 
    144151        return $this->selected_route; 
    145152    }                                 // function find_route($url) 
     
    148155     *  Build a regular expression that matches a route 
    149156     * 
    150      *  <b>FIXME:</b> Should this method be private? 
     157     *  @todo <b>FIXME:</b> Should this method be private? 
     158     *  @todo <b>FIXME:</b> Shouldn't the regexp match be the same as 
     159     *  for a PHP variable name? '[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*' 
    151160     *  @param string $route_path  A route path. 
    152161     *  @return string Regular expression that matches the route in 
     
    161170            $route_path = explode("/",$route_path); 
    162171        } 
    163         //        echo "route path:\n"; 
    164         //        var_dump($route_path); 
     172        //error_log("route path:\n".var_export($route_path,true)); 
    165173        if(count($route_path) > 0) { 
    166174            foreach($route_path as $path_element) { 
     
    175183            } 
    176184        } 
    177  
    178185        return $route_regexp; 
    179186    } 
  • trunk/trax/vendor/trax/session.php

    r159 r174  
    172172            $key .= $_SERVER['REMOTE_ADDR']; 
    173173        } 
     174        // error_log('get_hash() returns '.md5($key)); 
    174175        return md5($key); 
    175176    } 
     
    242243     */ 
    243244    function unset_var($key) { 
    244         if(self::is_valid_host()) { 
     245         // error_log('Session::unset_var("'.$key.'")'); 
     246        if(self::is_valid_host()) { 
     247            // error_log('before unsetting SESSION='.var_export($_SESSION,true)); 
    245248            unset($_SESSION[self::get_hash()][$key]); 
     249            // error_log('after unsetting SESSION='.var_export($_SESSION,true)); 
    246250        } 
    247251    }