Changeset 3001

Show
Ignore:
Timestamp:
10/08/08 18:28:51 (3 months ago)
Author:
david
Message:

Changed singular/plural handling in AgaviXmlConfigDomElement? convenience methods, closes #878

Location:
branches/1.0
Files:
4 modified

Legend:

Unmodified
Added
Removed
  • branches/1.0/CHANGELOG

    r2983 r3001  
    441.0.0 beta 4 (October ??, 2008) 
    55------------------------------- 
     6 
     7CHG: Change singular/plural handling in AgaviXmlConfigDomElement convenience methods (#878) (David) 
    68 
    79FIX: XInclude failure leads to corrupt exception error message (#877) (David) 
  • branches/1.0/src/config/AgaviConfigHandlersConfigHandler.class.php

    r2727 r3001  
    2323 * 
    2424 * @author     Dominik del Bondio <ddb@bitxtender.com> 
     25 * @author     Noah Fontes <noah.fontes@bitextender.com> 
     26 * @author     David Zülke <david.zuelke@bitextender.com> 
    2527 * @copyright  Authors 
    2628 * @copyright  The Agavi Project 
     
    4951   * @author     Dominik del Bondio <ddb@bitxtender.com> 
    5052   * @author     Noah Fontes <noah.fontes@bitextender.com> 
     53   * @author     David Zülke <david.zuelke@bitextender.com> 
    5154   * @since      0.11.0 
    5255   */ 
     
    6063     
    6164    foreach($document->getConfigurationElements() as $configuration) { 
    62       if(!$configuration->hasChildren('handlers')) { 
     65      if(!$configuration->has('handlers')) { 
    6366        continue; 
    6467      } 
    6568       
    6669      // let's do our fancy work 
    67       foreach($configuration->getChildren('handlers') as $handler) { 
     70      foreach($configuration->get('handlers') as $handler) { 
    6871        $pattern = $handler->getAttribute('pattern'); 
    6972         
     
    7679          AgaviXmlConfigParser::STAGE_COMPILATION => array(), 
    7780        ); 
    78         if($handler->hasChildren('transformations')) { 
    79           foreach($handler->getChildren('transformations') as $transformation) { 
     81        if($handler->has('transformations')) { 
     82          foreach($handler->get('transformations') as $transformation) { 
    8083            $path = AgaviToolkit::literalize($transformation->getValue()); 
    8184            $for = $transformation->getAttribute('for', AgaviXmlConfigParser::STAGE_SINGLE); 
     
    122125          ), 
    123126        ); 
    124         if($handler->hasChildren('validations')) { 
    125           foreach($handler->getChildren('validations') as $validation) { 
     127        if($handler->has('validations')) { 
     128          foreach($handler->get('validations') as $validation) { 
    126129            $path = AgaviToolkit::literalize($validation->getValue()); 
    127130            $type = null; 
     
    158161  } 
    159162   
    160   public function guessValidationType($path) 
     163  /** 
     164   * Convenience method to quickly guess the type of a validation file using its 
     165   * file extension. 
     166   * 
     167   * @param      string The path to the file. 
     168   * 
     169   * @return     string An AgaviXmlConfigParser::VALIDATION_TYPE_* const value. 
     170   * 
     171   * @throws     AgaviException If the type could not be determined. 
     172   * 
     173   * @author     David Zülke <david.zuelke@bitextender.com> 
     174   * @since      1.0.0 
     175   */ 
     176  protected function guessValidationType($path) 
    161177  { 
    162178    switch(pathinfo($path, PATHINFO_EXTENSION)) { 
  • branches/1.0/src/config/AgaviTestSuitesConfigHandler.class.php

    r2893 r3001  
    5858    // loop over <configuration> elements 
    5959    foreach($document->getConfigurationElements() as $configuration) { 
    60       foreach($configuration->getChildren('suites') as $current) { 
     60      foreach($configuration->get('suites') as $current) { 
    6161        $suite =  array('class' => $current->getAttribute('class', 'AgaviTestSuite')); 
    6262        $suite['testfiles'] = array(); 
    63         foreach($current->getChildren('testfiles') as $file) { 
     63        foreach($current->get('testfiles') as $file) { 
    6464          $suite['testfiles'][] = $file->textContent; 
    6565        } 
  • branches/1.0/src/config/util/dom/AgaviXmlConfigDomElement.class.php

    r2942 r3001  
    33class AgaviXmlConfigDomElement extends DOMElement implements IteratorAggregate 
    44{ 
    5   /** 
    6    * Overloaded method for accessing child nodes. Does the pluralizing etc, and 
    7    * provides convenient access through a potentially set default namespace. 
    8    * 
    9    * @param      string The child element name. 
    10    * 
    11    * @return     mixed A DOMNodeList or an AgaviXmlConfigDomElement. 
    12    * 
    13    * @author     David Zülke <dz@bitxtender.com> 
    14    * @since      1.0.0 
    15    */ 
    16   public function __get($name) { 
    17     // TODO: add {namespace}element support 
    18     // should look into the default ns, IMO. otherwise, you gotta use getChild() 
    19     // must use singular/plural handling 
    20   } 
    21    
    22   public function __isset($name) { 
    23     // TODO: add {namespace}element support 
    24     // should look into the default ns, IMO. otherwise, you gotta use hasChild() 
    25   } 
    26    
    275  public function __toString() 
    286  { 
     
    7250   
    7351  /** 
     52   * Convenience method to retrieve child elements of the given name. 
     53   * Accepts singular or plural forms of the name, and will detect and handle 
     54   * parent containers with plural names properly. 
     55   * 
     56   * @param      string The name of the element(s) to check for. 
     57   * @param      string The namespace URI. If null, the document default 
     58   *                    namespace will be used. If an empty string, no namespace 
     59   *                    will be used. 
     60   * 
     61   * @return     DOMNodeList A list of the child elements. 
     62   * 
     63   * @author     David Zülke <david.zuelke@bitextender.com> 
     64   * @since      1.0.0 
     65   */ 
     66  public function get($name, $namespaceUri = null) 
     67  { 
     68    return $this->getChildren($name, $namespaceUri, true); 
     69  } 
     70   
     71  /** 
     72   * Convenience method to check if there are child elements of the given name. 
     73   * Accepts singular or plural forms of the name, and will detect and handle 
     74   * parent containers with plural names properly. 
     75   * 
     76   * @param      string The name of the element(s) to check for. 
     77   * @param      string The namespace URI. If null, the document default 
     78   *                    namespace will be used. If an empty string, no namespace 
     79   *                    will be used. 
     80   * 
     81   * @return     bool True if one or more child elements with the given name 
     82   *                  exist, false otherwise. 
     83   * 
     84   * @author     David Zülke <david.zuelke@bitextender.com> 
     85   * @since      1.0.0 
     86   */ 
     87  public function has($name, $namespaceUri = null) 
     88  { 
     89    return $this->hasChildren($name, $namespaceUri, true); 
     90  } 
     91   
     92  /** 
    7493   * Count the number of child elements with a given name. 
    7594   * 
     
    7897   *                    namespace will be used. If an empty string, no namespace 
    7998   *                    will be used. 
     99   * @param      bool   Whether or not to apply automatic singular/plural 
     100   *                    handling that skips plural container elements. 
    80101   * 
    81102   * @return     int The number of child elements with the given name. 
    82103   * 
    83104   * @author     Noah Fontes <noah.fontes@bitextender.com> 
    84    * @since      1.0.0 
    85    */ 
    86   public function countChildren($name, $namespaceUri = null) 
    87   { 
    88     // check for child elements(!) using XPath 
    89     // if arg is true, then only check for elements from our default namespace 
     105   * @author     David Zülke <david.zuelke@bitextender.com> 
     106   * @since      1.0.0 
     107   */ 
     108  public function countChildren($name, $namespaceUri = null, $pluralMagic = false) 
     109  { 
     110    // if arg is null, then only check for elements from our default namespace 
     111    // if namespace uri is null, use default ns. if empty string, use no ns 
    90112    $namespaceUri = ($namespaceUri === null ? $this->ownerDocument->getDefaultNamespaceUri() : $namespaceUri); 
    91     $singularName = $this->singularize($name); 
    92      
    93     $xpath = $this->ownerDocument->getXpath(); 
    94     if($namespaceUri) { 
    95       return (int)$xpath->evaluate(sprintf('count(child::*[local-name() = "%2$s" and namespace-uri() = "%3$s"]) + count(child::*[local-name() = "%1$s" and namespace-uri() = "%3$s"]/*[local-name() = "%2$s" and namespace-uri() = "%3$s"])', $name, $singularName, $namespaceUri), $this); 
     113     
     114    // init our vars 
     115    $query = ''; 
     116    $singularName = null; 
     117     
     118    if($pluralMagic) { 
     119      // we always assume that we either get plural names, or the singular of the singular is not different from the singular :) 
     120      $singularName = $this->singularize($name); 
     121      if($namespaceUri) { 
     122        $query = 'count(child::*[local-name() = "%2$s" and namespace-uri() = "%3$s"]) + count(child::*[local-name() = "%1$s" and namespace-uri() = "%3$s"]/*[local-name() = "%2$s" and namespace-uri() = "%3$s"])'; 
     123      } else { 
     124        $query = 'count(%1$s/%2$s) + count(%2$s)'; 
     125      } 
    96126    } else { 
    97       return (int)$xpath->evaluate(sprintf('count(%2$s) + count(%1$s/%2$s)', $name, $singularName), $this); 
    98     } 
     127      if($namespaceUri) { 
     128        $query = 'count(child::*[local-name() = "%1$s" and namespace-uri() = "%3$s"])'; 
     129      } else { 
     130        $query = 'count(%1$s)'; 
     131      } 
     132    } 
     133     
     134    return (int)$this->ownerDocument->getXpath()->evaluate(sprintf($query, $name, $singularName, $namespaceUri), $this); 
    99135  } 
    100136   
     
    107143   *                    namespace will be used. If an empty string, no namespace 
    108144   *                    will be used. 
     145   * @param      bool   Whether or not to apply automatic singular/plural 
     146   *                    handling that skips plural container elements. 
    109147   * 
    110148   * @return     bool True if one or more child elements with the given name 
     
    112150   * 
    113151   * @author     Noah Fontes <noah.fontes@bitextender.com> 
    114    * @since      1.0.0 
    115    */ 
    116   public function hasChildren($name, $namespaceUri = null) 
    117   { 
    118     return $this->countChildren($name, $namespaceUri) !== 0; 
     152   * @author     David Zülke <david.zuelke@bitextender.com> 
     153   * @since      1.0.0 
     154   */ 
     155  public function hasChildren($name, $namespaceUri = null, $pluralMagic = false) 
     156  { 
     157    return $this->countChildren($name, $namespaceUri, $pluralMagic) !== 0; 
    119158  } 
    120159   
     
    126165   *                    namespace will be used. If an empty string, no namespace 
    127166   *                    will be used. 
     167   * @param      string Whether or not to apply pluralization magic in selects. 
     168   * @param      bool   Whether or not to apply automatic singular/plural 
     169   *                    handling that skips plural container elements. 
    128170   * 
    129171   * @return     DOMNodeList A list of the child elements. 
    130172   * 
    131173   * @author     Noah Fontes <noah.fontes@bitextender.com> 
    132    * @since      1.0.0 
    133    */ 
    134   public function getChildren($name, $namespaceUri = null) 
    135   { 
    136     // check for child elements(!) using XPath 
    137     // if arg is true, then only check for elements from our default namespace 
     174   * @author     David Zülke <david.zuelke@bitextender.com> 
     175   * @since      1.0.0 
     176   */ 
     177  public function getChildren($name, $namespaceUri = null, $pluralMagic = false) 
     178  { 
     179    // if arg is null, then only check for elements from our default namespace 
    138180    // if namespace uri is null, use default ns. if empty string, use no ns 
    139181    $namespaceUri = ($namespaceUri === null ? $this->ownerDocument->getDefaultNamespaceUri() : $namespaceUri); 
    140     $singularName = $this->singularize($name); 
    141      
    142     $xpath = $this->ownerDocument->getXpath(); 
    143     if($namespaceUri) { 
    144       return $xpath->query(sprintf('child::*[local-name() = "%2$s" and namespace-uri() = "%3$s"] | child::*[local-name() = "%1$s" and namespace-uri() = "%3$s"]/*[local-name() = "%2$s" and namespace-uri() = "%3$s"]', $name, $singularName, $namespaceUri), $this); 
     182     
     183    // init our vars 
     184    $query = ''; 
     185    $singularName = null; 
     186     
     187    if($pluralMagic) { 
     188      // we always assume that we either get plural names, or the singular of the singular is not different from the singular :) 
     189      $singularName = $this->singularize($name); 
     190      if($namespaceUri) { 
     191        $query = 'child::*[local-name() = "%2$s" and namespace-uri() = "%3$s"] | child::*[local-name() = "%1$s" and namespace-uri() = "%3$s"]/*[local-name() = "%2$s" and namespace-uri() = "%3$s"]'; 
     192      } else { 
     193        $query = '%1$s/%2$s | %2$s'; 
     194      } 
    145195    } else { 
    146       return $xpath->query(sprintf('%1$s/%2$s | %2$s', $name, $singularName), $this); 
    147     } 
     196      if($namespaceUri) { 
     197        $query = 'child::*[local-name() = "%1$s" and namespace-uri() = "%3$s"]'; 
     198      } else { 
     199        $query = '%1$s'; 
     200      } 
     201    } 
     202     
     203    return $this->ownerDocument->getXpath()->query(sprintf($query, $name, $singularName, $namespaceUri), $this); 
    148204  } 
    149205   
     
    166222  public function hasChild($name, $namespaceUri = null) 
    167223  { 
     224    return $this->getChild($name, $namespaceUri) !== null; 
     225  } 
     226   
     227  /** 
     228   * Return a single child element with a given name. 
     229   * Only returns anything if there is exactly one child of this name. 
     230   * 
     231   * @param      string The name of the element. 
     232   * @param      string The namespace URI. If null, the document default 
     233   *                    namespace will be used. If an empty string, no namespace 
     234   *                    will be used. 
     235   * 
     236   * @return     DOMElement The child element, or null if none exists. 
     237   * 
     238   * @author     Noah Fontes <noah.fontes@bitextender.com> 
     239   * @author     David Zülke <david.zuelke@bitextender.com> 
     240   * @since      1.0.0 
     241   */ 
     242  public function getChild($name, $namespaceUri = null) 
     243  { 
     244    // if arg is null, then only check for elements from our default namespace 
    168245    // if namespace uri is null, use default ns. if empty string, use no ns 
    169     return $this->countChildren($name, $namespaceUri) === 1; 
    170      
    171     // XXX: not necessary for single elements? 
    172     // remember singular/plural support 
    173   } 
    174    
    175   /** 
    176    * Return a single child element with a given name. 
    177    * 
    178    * @param      string The name of the element. 
    179    * @param      string The namespace URI. If null, the document default 
    180    *                    namespace will be used. If an empty string, no namespace 
    181    *                    will be used. 
    182    * 
    183    * @return     DOMElement The child element, or null if none xists. 
    184    * 
    185    * @author     Noah Fontes <noah.fontes@bitextender.com> 
    186    * @since      1.0.0 
    187    */ 
    188   public function getChild($name, $namespaceUri = null) 
    189   { 
    190     $list = $this->getChildren($name, $namespaceUri); 
    191      
    192     if($list->length > 0) { 
    193       return $list->item(0); 
    194     } 
    195     return null; 
     246    $namespaceUri = ($namespaceUri === null ? $this->ownerDocument->getDefaultNamespaceUri() : $namespaceUri); 
     247     
     248    if($namespaceUri) { 
     249      $query = 'self::node()[count(child::*[local-name() = "%1$s" and namespace-uri() = "%2$s"]) = 1]/*[local-name() = "%1$s" and namespace-uri() = "%2$s"]'; 
     250    } else { 
     251      $query = 'self::node()[count(child::%1$s) = 1]/%1$s'; 
     252    } 
     253     
     254    return $this->ownerDocument->getXpath()->query(sprintf($query, $name, $namespaceUri), $this)->item(0); 
    196255  } 
    197256   
     
    264323  { 
    265324    if($this->ownerDocument->isAgaviConfiguration()) { 
    266       return $this->hasChildren('parameters', AgaviXmlConfigParser::NAMESPACE_AGAVI_ENVELOPE_LATEST); 
     325      return $this->has('parameters', AgaviXmlConfigParser::NAMESPACE_AGAVI_ENVELOPE_LATEST); 
    267326    } 
    268327     
     
    281340   * 
    282341   * @author     Noah Fontes <noah.fontes@bitextender.com> 
     342   * @author     David Zülke <david.zuelke@bitextender.com> 
    283343   * @since      1.0.0 
    284344   */ 
     
    289349     
    290350    if($this->ownerDocument->isAgaviConfiguration()) { 
    291       $elements = $this->getChildren('parameters', AgaviXmlConfigParser::NAMESPACE_AGAVI_ENVELOPE_LATEST); 
     351      $elements = $this->get('parameters', AgaviXmlConfigParser::NAMESPACE_AGAVI_ENVELOPE_LATEST); 
    292352       
    293353      foreach($elements as $element) {