Changeset 1949

Show
Ignore:
Timestamp:
05/23/07 23:46:15 (20 months ago)
Author:
david
Message:

merging in changes from branch 'david-xml_config_handlers'

Location:
branches/0.11
Files:
21 modified
17 copied

Legend:

Unmodified
Added
Removed
  • branches/0.11/samples/app/config/factories.xml

    r1910 r1949  
    1818    <logger_manager class="AgaviLoggerManager" /> 
    1919     
    20     <request class="AgaviWebRequest"> 
    21       <parameter name="throw_exception_when_locked">false</parameter> 
    22     </request> 
     20    <request class="AgaviWebRequest" /> 
    2321     
    2422    <response class="AgaviWebResponse" /> 
     
    5250  <configuration context="soap"> 
    5351     
    54     <controller class="AgaviSoapController"> 
    55       <parameter name="wsdl">%core.app_dir%/data/test.wsdl</parameter> 
    56       <parameter name="options"> 
    57         <parameter name="uri">http://localhost</parameter> 
    58       </parameter> 
    59     </controller> 
     52    <controller class="AgaviSoapController" /> 
    6053     
    6154    <request class="AgaviSoapRequest" /> 
     
    6356    <response class="AgaviSoapResponse" /> 
    6457     
    65     <routing class="AgaviWebserviceRouting" /> 
     58    <routing class="AgaviSoapRouting"> 
     59      <parameter name="wsdl_generator"> 
     60        <parameter name="soap"> 
     61          <parameter name="address"> 
     62            <parameter name="location">http://localhost/~dzuelke/_projects/agavi/branches/david-xml_config_handlers/samples/pub/soap.php</parameter> 
     63          </parameter> 
     64        </parameter> 
     65      </parameter> 
     66    </routing> 
     67     
     68    <user class="AgaviSecurityUser" /> 
     69     
     70  </configuration> 
     71   
     72  <configuration context="wsdl"> 
     73     
     74    <storage class="AgaviSessionStorage"> 
     75      <parameter name="auto_start">false</parameter> 
     76    </storage> 
     77     
     78    <user class="AgaviSecurityUser" /> 
    6679     
    6780  </configuration> 
     
    7386    <response class="AgaviXmlrpcepiphpResponse" /> 
    7487     
    75     <routing class="AgaviWebserviceRouting" /> 
     88    <routing class="AgaviXmlrpcepiphpRouting" /> 
     89     
     90    <user class="AgaviSecurityUser" /> 
    7691     
    7792  </configuration> 
  • branches/0.11/samples/app/config/output_types.xml

    r1910 r1949  
    7979  </configuration> 
    8080 
     81  <configuration context="wsdl"> 
     82    <output_types default="wsdl"> 
     83       
     84      <output_type name="wsdl"> 
     85        <parameter name="http_headers"> 
     86          <parameter name="Content-Type">text/xml; charset=UTF-8</parameter> 
     87        </parameter> 
     88      </output_type> 
     89       
     90    </output_types> 
     91  </configuration> 
     92 
    8193</configurations> 
  • branches/0.11/samples/app/config/routing.xml

    r1910 r1949  
    11<?xml version="1.0" encoding="UTF-8"?> 
    2 <?xml-stylesheet type="application/xsl+xml" href="#yay"?> 
    3 <configurations xmlns="http://agavi.org/agavi/1.0/config"> 
    4    
    5   <xsl:stylesheet id="yay" version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    6  
    7     <xsl:output indent="yes" method="xml" /> 
    8  
    9     <xsl:key name="no-localized-patterns" match="route" use="pattern[@locale]" /> 
    10  
    11     <xsl:template match="/configurations/configuration"> 
    12       <xsl:apply-templates select="key('no-localized-patterns', route)" /> 
    13     </xsl:template> 
    14  
    15     <xsl:template match="@* | node() "> 
    16       <xsl:copy> 
    17         <xsl:apply-templates select="@* | node() " /> 
    18       </xsl:copy> 
    19     </xsl:template> 
    20  
    21   </xsl:stylesheet> 
    22   <sandbox> 
    23  
    24   </sandbox> 
     2<configurations xmlns="http://agavi.org/agavi/1.0/config" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:yay="http://agavi.org/sampleapp" targetNamespace="http://agavi.org/sampleapp"> 
    253   
    264  <configuration context="web"> 
     
    6442    <routes> 
    6543      <!-- SOAP calls include the name of a remote method to call. The WebserviceRouting applies patterns to this method name, not to the URL of the request. We set the request method to "read" here so executeRead() is run in the Action. --> 
    66       <route pattern="^getItemPrice$" module="Default" action="SearchEngineSpam" method="read" /> 
     44      <route pattern="^getItemPrice$" module="Default" action="SearchEngineSpam" method="read"> 
     45        <wsdl:input> 
     46          <wsdl:part name="name" type="xsd:string" /> 
     47        </wsdl:input> 
     48        <wsdl:output> 
     49          <wsdl:part name="price" type="xsd:float" /> 
     50        </wsdl:output> 
     51      </route> 
     52    </routes> 
     53  </configuration> 
     54   
     55  <configuration context="wsdl"> 
     56    <routes> 
     57      <route pattern="(dummy:.*)" module="Default" action="SendWsdl" /> 
    6758    </routes> 
    6859  </configuration> 
  • branches/0.11/samples/pub/soap-test.php

    r1898 r1949  
    99<?php 
    1010 
    11 define('USE_WSDL', true); 
    12  
    1311if(!isset($_GET['item'])) { 
    1412  $_GET['item'] = 'nonsense'; 
    1513} 
    1614 
    17 if(USE_WSDL) { 
    18    
    19   ini_set('soap.wsdl_cache_enabled', 0); 
    20    
    21   // this test.wsdl contains the URL to the service. You have to edit it to match your setup. 
    22   $client = new SoapClient('../app/data/test.wsdl', array( 
    23     /* so we can get last request and response */ 
    24     'trace' => true, 
    25   )); 
    26    
    27   try { 
    28     $result = $client->getItemPrice($_GET['item']); 
    29   } catch(SoapFault $e) { 
    30     $result = $e->__toString(); 
    31   } 
    32    
    33 } else { 
    34    
    35   $client = new SoapClient(null, array(  
    36     "location" => "http://localhost/~dzuelke/_projects/agavi/branches/0.11/samples/pub/soap.php",  
    37     "uri"      => "getItemPrice",  
    38     "style"    => SOAP_RPC,  
    39     "use"      => SOAP_ENCODED  
    40   ));  
     15ini_set('soap.wsdl_cache_enabled', 0); 
    4116 
    42   $result = $client->__call(  
    43     /* SOAP Method Name */  
    44     "getItemPrice",  
    45     /* Parameters */  
    46     array(  
    47       new SoapParam(  
    48         /* Parameter Value */  
    49         $_GET['item'],  
    50         /* Parameter Name */  
    51         "name" 
    52       ) 
    53     ),  
    54     /* Options */  
    55     array(  
    56       /* so we can get last request and response */ 
    57       'trace' => true, 
    58       /* SOAP Method Namespace */  
    59       "uri" => "urn:agavi-sampleapp",  
    60       /* SOAPAction HTTP Header for SOAP Method */  
    61       "soapaction" => "urn:agavi-sampleapp#getItemPrice"  
    62     ) 
    63   ); 
     17// this test.wsdl contains the URL to the service. You have to edit it to match your setup. 
     18$client = new SoapClient('http://localhost/~dzuelke/_projects/agavi/branches/david-xml_config_handlers/samples/pub/wsdl.php', array( 
     19  /* so we can get last request and response */ 
     20  'trace' => true, 
     21)); 
    6422 
     23try { 
     24  $result = $client->getItemPrice('nonsense'); 
     25} catch(SoapFault $e) { 
     26  $result = $e->__toString(); 
    6527} 
    6628 
  • branches/0.11/src/config/AgaviConfigCache.class.php

    r1914 r1949  
    5656   * @since      0.9.0 
    5757   */ 
    58   private static function callHandler($handler, $config, $cache, $context) 
    59   { 
    60  
     58  private static function callHandler($name, $config, $cache, $context) 
     59  { 
    6160    if(self::$handlers === null) { 
    6261      // we need to load the handlers first 
     
    6463      self::loadConfigHandlers(); 
    6564    } 
    66  
     65     
    6766    // grab the base name of the handler 
    68     $basename = basename($handler); 
    69  
    70     if(isset(self::$handlers[$handler])) { 
     67    $basename = basename($name); 
     68     
     69    $handlerInfo = null; 
     70     
     71    if(isset(self::$handlers[$name])) { 
    7172      // we have a handler associated with the full configuration path 
    72       // call the handler and retrieve the cache data 
    73       $data = self::$handlers[$handler]->execute($config, $context); 
    74       self::writeCacheFile($config, $cache, $data, false); 
    75       return; 
     73      $handlerInfo = self::$handlers[$name]; 
    7674    } elseif(isset(self::$handlers[$basename])) { 
    7775      // we have a handler associated with the configuration base name 
    78       // call the handler and retrieve the cache data 
    79       $data = self::$handlers[$basename]->execute($config, $context); 
    80       self::writeCacheFile($config, $cache, $data, false); 
    81       return; 
     76      $handlerInfo = self::$handlers[$basename]; 
    8277    } else { 
    8378      // let's see if we have any wildcard handlers registered that match 
    8479      // this basename 
    85       foreach(self::$handlers as $key => $handlerInstance)  { 
     80      foreach(self::$handlers as $key => $value)  { 
    8681        // replace wildcard chars in the configuration and create the pattern 
    8782        $pattern = sprintf('#%s#', str_replace('\*', '.*?', preg_quote($key))); 
    88  
    89         if(preg_match($pattern, $handler)) { 
    90           // call the handler and retrieve the cache data 
    91           $data = $handlerInstance->execute($config, $context); 
    92           self::writeCacheFile($config, $cache, $data, false); 
    93           return; 
     83         
     84        if(preg_match($pattern, $name)) { 
     85          $handlerInfo = $value; 
     86          break; 
    9487        } 
    9588      } 
    9689    } 
    97  
    98     // we do not have a registered handler for this file 
    99     $error = 'Configuration file "%s" does not have a registered handler'; 
    100     $error = sprintf($error, $config); 
    101     throw new AgaviConfigurationException($error); 
     90     
     91    if($handlerInfo === null) { 
     92      // we do not have a registered handler for this file 
     93      $error = 'Configuration file "%s" does not have a registered handler'; 
     94      $error = sprintf($error, $config); 
     95      throw new AgaviConfigurationException($error); 
     96    } 
     97     
     98    // call the handler and retrieve the cache data 
     99    $handler = new $handlerInfo['class']; 
     100    if($handler instanceof AgaviIXmlConfigHandler) { 
     101      // a new-style config handler 
     102      // it does not parse the config itself; instead, it is given an array of parsed DOM documents (with parents!) 
     103      $parser = new AgaviXmlConfigParser(); 
     104      $docs = $parser->parseAll($config, $handlerInfo['validation']); 
     105       
     106      if($context !== null) { 
     107        $context = AgaviContext::getInstance($context); 
     108      } 
     109       
     110      $handler->initialize($context, $handlerInfo['parameters']); 
     111       
     112      try { 
     113        $data = $handler->execute($docs); 
     114      } catch(AgaviException $e) { 
     115        throw new $e(sprintf("Compliation of configuration file '%s' failed for the following reason(s):\n\n%s", $config, $e->getMessage())); 
     116      } 
     117    } else { 
     118      $validationFile = null; 
     119      if(isset($handlerInfo['validation'][AgaviXmlConfigParser::VALIDATION_TYPE_XMLSCHEMA][0])) { 
     120        $validationFile = $handlerInfo['validation'][AgaviXmlConfigParser::VALIDATION_TYPE_XMLSCHEMA][0]; 
     121      } 
     122      $handler->initialize($validationFile, null, $handlerInfo['parameters']); 
     123      $data = $handler->execute($config, $context); 
     124    } 
     125     
     126    self::writeCacheFile($config, $cache, $data, false); 
    102127  } 
    103128 
     
    135160    $cache = self::getCacheName($config, $context); 
    136161 
    137     if(!is_readable($cache) || filemtime($filename) > filemtime($cache))  { 
     162    if(self::isModified($filename, $cache)) { 
    138163      // configuration file has changed so we need to reparse it 
    139164      self::callHandler($config, $filename, $cache, $context); 
     
    141166 
    142167    return $cache; 
    143  
     168  } 
     169   
     170  /** 
     171   * Check if the cached version of a file is up to date. 
     172   * 
     173   * @param      string The source file. 
     174   * @param      string The name of the cached version. 
     175   * 
     176   * @return     bool Whether or not the cached file must be updated. 
     177   * 
     178   * @author     David Zülke <dz@bitxtender.com> 
     179   * @since      0.11.0 
     180   */ 
     181  public static function isModified($filename, $cachename) 
     182  { 
     183    return (!is_readable($cachename) || filemtime($filename) > filemtime($cachename)); 
    144184  } 
    145185 
     
    234274    // since we only need the parser and handlers when the config is not cached 
    235275    // it is sufficient to include them at this stage 
     276    require(AgaviConfig::get('core.agavi_dir') . '/config/AgaviILegacyConfigHandler.interface.php'); 
     277    require(AgaviConfig::get('core.agavi_dir') . '/config/AgaviIXmlConfigHandler.interface.php'); 
     278    require(AgaviConfig::get('core.agavi_dir') . '/config/AgaviBaseConfigHandler.class.php'); 
     279    require(AgaviConfig::get('core.agavi_dir') . '/config/AgaviConfigHandler.class.php'); 
     280    require(AgaviConfig::get('core.agavi_dir') . '/config/AgaviXmlConfigHandler.class.php'); 
     281    require(AgaviConfig::get('core.agavi_dir') . '/config/AgaviAutoloadConfigHandler.class.php'); 
    236282    require(AgaviConfig::get('core.agavi_dir') . '/config/AgaviConfigHandlersConfigHandler.class.php'); 
    237283    require(AgaviConfig::get('core.agavi_dir') . '/config/AgaviConfigValueHolder.class.php'); 
     
    240286 
    241287    // manually create our config_handlers.xml handler 
    242     self::$handlers['config_handlers.xml'] = new AgaviConfigHandlersConfigHandler(); 
    243     self::$handlers['config_handlers.xml']->initialize(AgaviConfig::get('core.agavi_dir') . '/config/xsd/config_handlers.xsd'); 
     288    self::$handlers['config_handlers.xml'] = array( 
     289      'class' => 'AgaviConfigHandlersConfigHandler',  
     290      'parameters' => array( 
     291      ), 
     292      'validation' => array( 
     293        AgaviXmlConfigParser::VALIDATION_TYPE_XMLSCHEMA => array( 
     294          AgaviConfig::get('core.agavi_dir') . '/config/xsd/config_handlers.xsd', 
     295        ), 
     296      ), 
     297    ); 
    244298 
    245299    $cfg = AgaviConfig::get('core.config_dir') . '/config_handlers.xml'; 
     
    265319   * @since      0.9.0 
    266320   */ 
    267   private static function writeCacheFile($config, $cache, &$data, $append) 
     321  public static function writeCacheFile($config, $cache, $data, $append = false) 
    268322  { 
    269323    $perms = fileperms(AgaviConfig::get('core.cache_dir')) ^ 0x4000; 
     
    303357   *             extension couldn't be found. 
    304358   * 
     359   * @deprecated New-style config handlers don't call this method anymore. 
     360   * 
    305361   * @author     Dominik del Bondio <ddb@bitxtender.com> 
     362   * @author     David Zülke <dz@bitxtender.com> 
    306363   * @since      0.11.0 
    307364   */ 
    308   public static function parseConfig($config, $autoloadParser = true, $validateFile = null, $parserClass = null) 
    309   { 
    310     static $parsers = array(); 
    311  
    312     if($parserClass) { 
    313       $parser = new $parserClass(); 
    314       return $parser->parse($config, $validateFile); 
    315     } else { 
    316       $path = pathinfo($config); 
    317       $ext = ucfirst(strtolower($path['extension'])); 
    318       if(!isset($parsers[$ext])) { 
    319         $class = $ext . 'ConfigParser'; 
    320         if(!class_exists($class, $autoloadParser)) { 
    321           $class = 'Agavi' . $class; 
    322           if(!class_exists($class, $autoloadParser)) { 
    323             throw new AgaviConfigurationException('Couldn\'t find parser for file extension .' . $path['extension']); 
    324           } 
    325         } 
    326  
    327         $parsers[$ext] = new $class(); 
    328       } 
    329  
    330       return $parsers[$ext]->parse($config, $validateFile); 
    331     } 
    332   } 
    333  
     365  public static function parseConfig($config, $autoloadParser = true, $validationFile = null, $parserClass = null) 
     366  { 
     367    $parser = new AgaviConfigParser(); 
     368     
     369    return $parser->parse($config, $validationFile); 
     370  } 
    334371} 
    335372 
  • branches/0.11/src/config/AgaviConfigHandler.class.php

    r1846 r1949  
    3333 * @version    $Id$ 
    3434 */ 
    35 abstract class AgaviConfigHandler extends AgaviParameterHolder 
     35abstract class AgaviConfigHandler extends AgaviBaseConfigHandler implements AgaviILegacyConfigHandler 
    3636{ 
    37   /** 
    38    * @var        string An absolute filesystem path to a validation filename. 
    39    */ 
    40   protected $validationFile = null; 
    41  
    42   /** 
    43    * @var        string A class name of the class which should be used to parse 
    44    *                    Input files of this config handler. 
    45    */ 
    46   protected $parser = null; 
    47  
    48   /** 
    49    * Retrieves the stored validation filename. 
    50    * 
    51    * @return     string An absolute filesystem path to a validation filename. 
    52    * 
    53    * @author     Dominik del Bondio <ddb@bitxtender.com> 
    54    * @since      0.11.0 
    55    */ 
    56   public function getValidationFile() 
    57   { 
    58     return $this->validationFile; 
    59   } 
    60  
    61   /** 
    62    * Retrieve the parameter node values of the given item's parameters element. 
    63    * 
    64    * @param      ConfigValueHolder The node that contains a parameters chiild. 
    65    * @param      array             As associative array of parameters that will 
    66    *                               be overwritten if appropriate. 
    67    * @param      boolean           Whether or not values should be literalized. 
    68    * 
    69    * @return     array An associative array of parameters 
    70    * 
    71    * @author     Dominik del Bondio <ddb@bitxtender.com> 
    72    * @since      0.11.0 
    73    */ 
    74   protected function getItemParameters($itemNode, $oldValues = array(), $literalize = true) 
    75   { 
    76     $data = array(); 
    77     if($itemNode->hasChildren('parameters')) { 
    78       foreach($itemNode->parameters as $node) { 
    79         if(!$node->hasAttribute('name')) { 
    80           // create a new entry in in the array and get they key of the new 
    81           // created entry (the last in the array). The value doesn't matter 
    82           // since it will be overwritten anyways 
    83           $data[] = 0; 
    84           end($data); 
    85           $name = key($data); 
    86         } else { 
    87           $name = $node->getAttribute('name'); 
    88         } 
    89         if($node->hasChildren('parameters')) { 
    90           $data[$name] = (isset($oldValues[$name]) && is_array($oldValues[$name])) ? $oldValues[$name] : array(); 
    91           $data[$name] = $this->getItemParameters($node, $data[$name], $literalize); 
    92         } else { 
    93           $data[$name] = $literalize ? $this->literalize($node->getValue()) : $node->getValue(); 
    94         } 
    95       } 
    96     } 
    97     // we can NOT use array_merge here, since it would break numeric keys 
    98     foreach($data as $key => $value) { 
    99       $oldValues[$key] = $value; 
    100     } 
    101     return $oldValues; 
    102   } 
    103  
    104   /** 
    105    * Execute this configuration handler. 
    106    * 
    107    * @param      string An absolute filesystem path to a configuration file. 
    108    * @param      string Name of the executing context (if any). 
    109    * 
    110    * @return     string Data to be written to a cache file. 
    111    * 
    112    * @throws     <b>AgaviUnreadableException</b> If a requested configuration 
    113    *                                             file does not exist or is not 
    114    *                                             readable. 
    115    * @throws     <b>AgaviParseException</b> If a requested configuration file is 
    116    *                                        improperly formatted. 
    117    * 
    118    * @author     Sean Kerr <skerr@mojavi.org> 
    119    * @since      0.9.0 
    120    */ 
    121   abstract function execute($config, $context = null); 
    122  
    123   /** 
    124    * Generate the code for returning from execute(). 
    125    * 
    126    * @param      mixed A string with the code, or an array of code lines. 
    127    * 
    128    * @return     string PHP code. 
    129    * 
    130    * @author     David Zuelke <dz@bitxtender.com> 
    131    * @since      0.11.0 
    132    */ 
    133   protected function generate($code) 
    134   { 
    135     if(is_array($code)) { 
    136       $code = implode("\n", $code); 
    137     } 
    138      
    139     return sprintf( 
    140       "<?php\n\n// This is a compiled Agavi configuration file\n// Generated by: %s\n// Date: %s\n\n%s\n\n?>", 
    141       get_class($this), 
    142       date('c'), 
    143       $code 
    144     ); 
    145   } 
    146    
    14737  /** 
    14838   * Initialize this ConfigHandler. 
     
    16555    $this->setParameters($parameters); 
    16656  } 
    167  
    168   /** 
    169    * Literalize a string value. 
    170    * 
    171    * @param      string The value to literalize. 
    172    * 
    173    * @return     string A literalized value. 
    174    * 
    175    * @author     Sean Kerr <skerr@mojavi.org> 
    176    * @author     Dominik del Bondio <ddb@bitxtender.com> 
    177    * @since      0.9.0 
    178    */ 
    179   public static function literalize($value) 
    180   { 
    181     if($value == null) { 
    182       // null value 
    183       return null; 
    184     } 
    185  
    186     if(!is_string($value)) { 
    187       return $value; 
    188     } 
    189  
    190     // lowercase our value for comparison 
    191     $value  = trim($value); 
    192     $lvalue = strtolower($value); 
    193  
    194     if($lvalue == 'on' || $lvalue == 'yes' || $lvalue == 'true') { 
    195  
    196       // replace values 'on' and 'yes' with a boolean true value 
    197       return true; 
    198  
    199     } elseif($lvalue == 'off' || $lvalue == 'no' || $lvalue == 'false') { 
    200  
    201       // replace values 'off' and 'no' with a boolean false value 
    202       return false; 
    203  
    204     } elseif(!is_numeric($value)) { 
    205  
    206       return self::replaceConstants($value); 
    207  
    208     } 
    209  
    210     // numeric value 
    211     return $value; 
    212  
    213   } 
    214