dbscript
[ class tree: dbscript ] [ index: dbscript ] [ all elements ]

Source for file mapper.php

Documentation is available at mapper.php

  1. <?php
  2.  
  3.   /** 
  4.    * dbscript for PHP 4 & 5 - restful crud framework
  5.    * @version 0.1.2 -- 19-Feb-2007
  6.    * @author Brian Hendrickson <brian@dbscript.net>
  7.    * @link http://dbscript.net/
  8.    * @copyright Copyright 2007 Brian Hendrickson
  9.    * @package dbscript
  10.    * @license http://www.opensource.org/licenses/mit-license.php MIT License
  11.    */
  12.  
  13.   /**
  14.    * URI Mapper
  15.    * 
  16.    * connects the current URI to a Route,
  17.    * establishing the request variable names
  18.    * e.g. my_domain/:resource/:id would map
  19.    * values into $req->resource and $req->id
  20.    * 
  21.    * Usage:
  22.    * <code>
  23.    *   $req = new Mapper();
  24.    * </code>
  25.    * 
  26.    * More info...
  27.    * {@link http://dbscript.net/mapper}
  28.    * 
  29.    * @package dbscript
  30.    * @author Brian Hendrickson <brian@dbscript.net>
  31.    * @access public
  32.    * @return object 
  33.    * @version 0.1.2
  34.    */
  35.  
  36. class Mapper {
  37.   
  38.   /**
  39.    * current URI
  40.    * @var string 
  41.    */
  42.   var $uri;
  43.   
  44.   /**
  45.    * base URI
  46.    * @var string 
  47.    */
  48.   var $base;
  49.  
  50.   /**
  51.    * unmolested regex parts of the URI
  52.    * @var string[] 
  53.    */
  54.   var $values;
  55.   
  56.   /**
  57.    * URI parameter names and values
  58.    * @var string[] 
  59.    */
  60.   var $params;
  61.  
  62.   /**
  63.    * matched Route object
  64.    * @var Route 
  65.    */
  66.   var $activeroute;
  67.  
  68.   /**
  69.    * list of connected Route objects
  70.    * @var Route[] 
  71.    */
  72.   var $routes;
  73.  
  74.   /**
  75.    * list of public methods
  76.    * @var string[] 
  77.    */
  78.  
  79.   /**
  80.    * parameters to (silently) propagate
  81.    * @var string[] 
  82.    */
  83.   var $persisted_vars;
  84.  
  85.   /**
  86.    * path to views
  87.    * @var string 
  88.    */
  89.   var $template_path;
  90.   
  91.   /**
  92.    * path to layouts
  93.    * @var string 
  94.    */
  95.   var $layout_path;
  96.   
  97.   /**
  98.    * id of encrypted Cookie owner
  99.    * @var string 
  100.    */
  101.   var $userid;
  102.  
  103.   /**
  104.    * true if an error has been raised
  105.    * @var boolean 
  106.    */
  107.   var $error;
  108.  
  109.   /**
  110.    * contents of error message
  111.    * @var string 
  112.    */
  113.   var $error_string;
  114.   
  115.   /**
  116.    * database Record object for the current session
  117.    * @var string 
  118.    */
  119.   var $DbSession;
  120.  
  121.   function Mapper({
  122.   
  123.     $this->uri = $this->composite_uri();
  124.     
  125.     preg_match"/^(https?:\/\/)([^\/]+)\/?[^\?]+?[\??]([\w\/\.]+)?/i"$this->uri$this->values );
  126.     
  127.     if (!($this->values))
  128.       preg_match"/^(https?:\/\/)([^\/]+)\/?(([^\?]+))?/i"$this->uri$this->values );
  129.     
  130.     if isset$this->values[3) ) {
  131.       $this->params = explode'/'$this->values[3);
  132.     }
  133.     
  134.     $this->base = substr$this->uri0-);
  135.     $this->routes = array();
  136.     $this->persisted_vars = array();
  137.     $this->allowed_methods = array();
  138.     $this->template_path = '';
  139.     $this->layout_path = '';
  140.     $this->error = false;
  141.     $this->userid = 0;
  142.     
  143.   }
  144.     
  145.   function handle_error$errstr {
  146.     $this->error = true;
  147.     $this->params['error'.= $errstr "\n";
  148.     trigger_before'handle_error'$this$errstr );
  149.   }
  150.   
  151.   function url_for$params$altparams NULL {
  152.     
  153.     $match false;
  154.     $route_match NULL;
  155.     
  156.     if is_string$params ) ) {
  157.       // first var is a route name
  158.       $routename $params;
  159.       $params $altparams;
  160.     }
  161.     
  162.     foreach $this->routes as $r {
  163.       
  164.       $vars array();
  165.       
  166.       foreach $r->patterns as $pos => $str {
  167.         if substr$str0== ':' {
  168.           $vars[substr$str)$pos;
  169.         }
  170.       }
  171.       
  172.       if isset$routename ) ) {
  173.         if $routename == $r->name {
  174.           // a named route was found
  175.           if ($altparams == NULL)
  176.             $params $r->defaults;
  177.           return $r->build_url$params$this->base );
  178.         }
  179.       elseif countarray_intersectarray_keys($vars)array_keys($params) ) ) == count$vars && count($vars== count($params) ) {
  180.         // every pattern in the route exists in the requested params
  181.         
  182.         return $r->build_url$params$this->base );
  183.       else {
  184.         // eh
  185.       }
  186.       
  187.     }
  188.     
  189.     foreach $this->params as $paramkey=>$paramval {
  190.       
  191.       if is_integer$paramkey ) )
  192.         continue;
  193.       
  194.       $params[$paramkey$paramval;
  195.       
  196.       foreach $this->routes as $r {
  197.         
  198.         $vars array();
  199.         
  200.         foreach $r->patterns as $pos => $str {
  201.           if substr$str0== ':' {
  202.             $vars[substr$str)$pos;
  203.           }
  204.         }
  205.         
  206.         if countarray_intersectarray_keys($vars)array_keys($params) ) ) == count$vars && count($vars== count($params) ) {
  207.           return $r->build_url$params$this->base );
  208.         }
  209.       
  210.       // end foreach routes
  211.     
  212.     // end foreach params
  213.  
  214.   }
  215.   
  216.   function link_to$params$altparams NULL {
  217.     $url $this->url_for$params$altparams );
  218.     return "<a href=\"$url\">$url</a>";
  219.   }
  220.   
  221.   function redirect_to$params$altparams NULL {
  222.     header"Location: " $this->url_for($params$altparams) );
  223.   }
  224.  
  225.   function breadcrumbs({
  226.     $controller $this->params['resource'];
  227.     $links array();
  228.     $html "";
  229.  
  230.     $links['<a href="'$this->base .'">Contents</a>';
  231.     
  232.     if isset$this->resource && $this->resource != 'introspection' ))
  233.       $links['<a href="'$this->base .'?'.$this->resource.'">'.ucwords($this->resource).'</a>';
  234.     
  235.     if ( ($this->id != 0&& isset$this->resource && $this->resource != 'introspection' ))
  236.        $links['<a href="'.$this->entry_url($this->id).'">Entry '.ucwords($this->id).'</a>';
  237.     elseif isset$this->resource )  && $this->new_url())
  238.       $links['<a href="'.$this->new_url().'">New '.classify($this->resource).'</a>';
  239.     
  240.     $html "<span>";
  241.     foreach ($links as $key=>$val{
  242.       if ($key 0{
  243.         $html .= " | ";
  244.       }
  245.       $html .= $val;
  246.     }
  247.     $html .= "</span>";
  248.     return $html;
  249.   }
  250.   
  251.   function set_persisted_vars($arr{
  252.     if (is_array($arr))
  253.       $this->persisted_vars = $arr;
  254.   }
  255.   
  256.   function set_filter$name$func$when 'after' {
  257.     aspect_join_functions$func$name$when );
  258.   }
  259.   
  260.   function set_action$method {
  261.     $this->allowed_methods[$method;
  262.   }
  263.   
  264.   function set_param$param$value {
  265.     $this->params[$param$value;
  266.     if (!isset($this->$param))
  267.       $this->$param =$this->params[$param];
  268.   }
  269.   
  270.   function set_layout_path$path {
  271.     $this->layout_path = $path;
  272.   }
  273.     
  274.   function set_template_path$path {
  275.     $this->template_path = $path;
  276.   }
  277.   
  278.   function feed_url({
  279.     $result false;
  280.     if (isset($this->resource))
  281.       $result is_file$this->template_path . $this->resource DIRECTORY_SEPARATOR'_index.atom' );
  282.     if ($result)
  283.       return $this->url_forarray('resource'=>$this->resource'action'=>'index.atom'));
  284.     return $result;
  285.   }
  286.   
  287.   function entry_url$id NULL {
  288.     $result false;
  289.     if (isset($this->resource))
  290.       $result is_file$this->template_path . $this->resource DIRECTORY_SEPARATOR'_entry.xhtml' );
  291.     if (!$result)
  292.       $result is_file$this->template_path . $this->resource DIRECTORY_SEPARATOR'_entry.html' );
  293.     if ($result && ($id != NULL))
  294.       return $this->url_forarray('resource'=>$this->resource'action'=>'entry''id'=>$id));
  295.     if ($result)
  296.       return $this->url_forarray('resource'=>$this->resource'action'=>'entry'));
  297.     return $result;
  298.   }
  299.   
  300.   function new_url({
  301.     $result false;
  302.     if (isset($this->resource))
  303.       $result is_file$this->template_path . $this->resource DIRECTORY_SEPARATOR'_new.xhtml' );
  304.     if (!$result)
  305.       $result is_file$this->template_path . $this->resource DIRECTORY_SEPARATOR'_new.html' );
  306.     if ($result)
  307.       return $this->url_forarray('resource'=>$this->resource'action'=>'new'));
  308.     return $result;
  309.   }
  310.     
  311.   function get_template_path$ext$template null {
  312.     
  313.     if (isset($this->params['resource']))
  314.       $resource $this->params['resource'DIRECTORY_SEPARATOR;
  315.     else
  316.       $resource "";
  317.     
  318.     if ($template == null{
  319.       $partial false;
  320.       $template $this->params['action'];
  321.     else {
  322.       $partial true;
  323.       $template "_" $template;
  324.     }
  325.     
  326.     if ($template == 'get')
  327.       $template 'index';
  328.     
  329.     if (isset($this->params['client_wants']))
  330.       $ext $this->params['client_wants'];
  331.     
  332.     $view $this->template_path . $resource $template "." $ext;
  333.     
  334.     if (!(is_file($view)))
  335.       $view $this->template_path . $template "." $ext;
  336.     
  337.     if (!$partial && !(is_file($view)))
  338.       $view $this->template_path . $resource 'index' "." $ext;
  339.     
  340.     if (!$partial && !(is_file($view)))
  341.       $view $this->template_path . 'index' "." $ext;
  342.     
  343.     if (is_file($view))
  344.       return $view;
  345.     else
  346.       return false;
  347.     
  348.   }
  349.   
  350.   function is_allowed$method {
  351.     return in_array$method$this->allowed_methodstrue );
  352.   }
  353.   
  354.   function connect({
  355.     // Create and connect a new Route to the Mapper
  356.     
  357.     $r new Route();
  358.     
  359.     $args func_get_args();
  360.     
  361.     foreach $args as $idx => $arg {
  362.       
  363.       if is_string$arg ) ) {
  364.         
  365.         $r->patterns explode'/'$arg );
  366.         if count$r->patterns == && $idx == {
  367.           $r->name $r->patterns[0];
  368.         }
  369.         
  370.       elseif is_array$arg ) ) {
  371.         
  372.         foreach $arg as $key => $val {
  373.           if $key == 'requirements' {
  374.             $i 0;
  375.             foreach $r->patterns as $pos => $str {
  376.               if substr$str0== ':' {
  377.                 $r->requirements[$pos$val[$i];
  378.                 $i++;
  379.               }
  380.             }
  381.           else {
  382.             $r->defaults[$key$val;
  383.           }
  384.         }
  385.         
  386.       }
  387.       
  388.     }
  389.     
  390.     $this->routes[$r;
  391.     
  392.   }
  393.   
  394.   function generate$controller='index.php'$action='get' {
  395.     // Generate a route from a set of keywords and return the url
  396.   }
  397.   
  398.   function routematch$url NULL {
  399.     // Match a URL against against one of the routes contained.
  400.     $return false;
  401.     trigger_before'routematch'$this$this->activeroute );
  402.     
  403.     if ($url === NULL$url $this->uri;
  404.     
  405.     foreach $this->routes as $route {
  406.       if ($this->match$url$route )) {
  407.         break;
  408.         $return true;
  409.       }
  410.     }
  411.     
  412.     if isset$this->params['method') ) $this->action $this->method;
  413.     
  414.     if isset$this->params['forward_to') ) $this->controller $this->forward_to;
  415.     
  416.     if (!(strpos($this->action,"."=== false)) // check for period
  417.       $actionsplit split("\."$this->action);
  418.       $this->set_param'action'$actionsplit[0]);
  419.       $this->set_param'client_wants'$actionsplit[1);
  420.     }
  421.     #print $this->resource; exit;
  422.     if (isset($this->resource)) {
  423.       if (!(strpos($this->resource,"."=== false)) // check for period
  424.         $actionsplit split("\."$this->resource);
  425.         $this->set_param'resource'$actionsplit[0]);
  426.         $this->set_param'client_wants'$actionsplit[1);
  427.       }
  428.     }
  429.     
  430.     trigger_after'routematch'$this$this->activeroute );
  431.     
  432.     return $return;
  433.     
  434.   }
  435.   
  436.   function match$url$r {
  437.     
  438.     foreach $r->patterns as $idx => $value {
  439.       if !isset$this->params[$idx) ) ) {
  440.         return false;
  441.       }
  442.     }
  443.     
  444.     $i 0;
  445.     $regx array();
  446.     foreach $r->patterns as $pos => $str {
  447.       if substr$str0== ':' {
  448.         if isset$r->requirements[$pos) ) {
  449.           $regx[$r->requirements[$pos];
  450.         else {
  451.           $regx['(.+)';
  452.         }
  453.         $i++;
  454.       else {
  455.         $regx[$str;
  456.       }
  457.     }
  458.     
  459.     $params $this->params;
  460.     
  461.     while count$params count$regx ) ) {
  462.       array_shift$params );
  463.     }
  464.     
  465.     #print "searching for ". "/\/" . implode( "\/", $regx ) . "/i". " in the string /" .implode( "/", $params )."<br><br>";
  466.     
  467.     if count$r->patterns == {
  468.       $r->match true;
  469.       $pmatches array();
  470.     elseif preg_match"/\/" implode"\/"$regx "/i""/" .implode"/"$params )$pmatches ) ) {
  471.       $this->base = substr$this->uri0-strlen($pmatches[0]));
  472.       $r->match true;
  473.     }
  474.     
  475.     if ($r->match{
  476.       $this->activeroute =$r;
  477.       $this->params = array_merge$_GET$_POST$r->defaults$this->params );
  478.       foreach $this->params as $p=>$v {
  479.         if !isset$this->$p ) ) )
  480.           $this->$p =$this->params[$p];
  481.       }
  482.       foreach $r->patterns as $idx => $val {
  483.         if substr$val0== ':' {
  484.           $val substr$val1);
  485.           if isset$params[$idx) ) $this->params[$val$params[$idx];
  486.         }
  487.       }
  488.       
  489.     }
  490.     return $r->match;
  491.   }
  492.   
  493.   function composite_uri({
  494.     // cross platform URI code by Angsuman Chakraborty
  495.     $port "";
  496.     if isset$_SERVER['HTTPS'&& $_SERVER['HTTPS']=='on' {
  497.       $_SERVER['FULL_URL''https://';
  498.       if $_SERVER['SERVER_PORT']!='443' {
  499.         $port ':' $_SERVER['SERVER_PORT'];
  500.       }
  501.     else {
  502.       $_SERVER['FULL_URL''http://';
  503.       if $_SERVER['SERVER_PORT']!='80' {
  504.         $port ':' $_SERVER['SERVER_PORT'];
  505.       }
  506.     }
  507.     if isset$_SERVER['REQUEST_URI') ) {
  508.       $script $_SERVER['REQUEST_URI'];
  509.     else {
  510.       $script $_SERVER['PHP_SELF'];
  511.       if $_SERVER['QUERY_STRING']>' ' {
  512.         $script .= '?'.$_SERVER['QUERY_STRING'];
  513.       }
  514.     }
  515.     if isset$_SERVER['HTTP_HOST') ) {
  516.       $_SERVER['FULL_URL'.= $_SERVER['HTTP_HOST'$port $script;
  517.     else {
  518.       $_SERVER['FULL_URL'.= $_SERVER['SERVER_NAME'$port $script;
  519.     }
  520.     return $_SERVER['FULL_URL'];
  521.   }
  522.   
  523.   function hasErrors({
  524.     if $this->error === true )
  525.       return true;
  526.     return false;
  527.   }
  528.   
  529.   function propagate({
  530.     $allowed $this->persisted_vars;
  531.     $_SESSION['params'array();
  532.     foreach$this->params as $param=>$val {
  533.       if (in_array($param$allowed)) {
  534.         $_SESSION['params'][$param$val;
  535.       }
  536.     }
  537.   }
  538.   
  539.   function restore({
  540.     if (!(isset($_SESSION['params']))) return false;
  541.     foreach$_SESSION['params'as $param=>$val {
  542.       $this->params[$param$val;
  543.       $this->$param =$this->params[$param];
  544.     }
  545.   }
  546.   
  547. }
  548.  
  549. ?>

Documentation generated on Mon, 19 Feb 2007 10:24:47 -0800 by phpDocumentor 1.3.1