Changeset 2550

Show
Ignore:
Timestamp:
07/01/08 09:53:34 (6 months ago)
Author:
david
Message:

merge [2519:2549/branches/0.11]

Location:
trunk
Files:
1 removed
22 modified
1 copied

Legend:

Unmodified
Added
Removed
  • trunk/CHANGELOG

    r2518 r2550  
    1717 
    1818 
    19 0.11.2 RC1 (June ??, 2008) 
     190.11.2 RC2 (July ?, 2008) 
    2020-------------------------- 
    2121 
     22FIX: Exception templates incorrectly fix information about exception origin (#790) (David) 
     23FIX: Markup is escaped by accident in shiny exception template (#791) (David) 
     24FIX: Using '#' in a routing pattern triggers a warning (#789) (Dominik) 
     25 
     26 
     270.11.2 RC1 (June 27, 2008) 
     28-------------------------- 
     29 
     30ADD: Support trimming of input string in AgaviStringValidator (#745) (David) 
     31ADD: Add support for native doctrine model autoloading (#759) (David) 
     32ADD: Add support for doctrine manager attributes (#783) (David) 
     33ADD: Add SecurityUser::hasCredential and SecurityUser::getCredentials for convenience (Noah) (#772) 
    2234ADD: Add convenience methods to AgaviUploadedFile (#607) (David) 
    2335ADD: Allow arrays as values for web request sources. (#675) (David) 
     
    2638ADD: Allow nested routing structures with concatenated name or action attributes in ancestors other than immediate parents (Dominik) (#764) 
    2739 
     40CHG: AgaviController::dispatch() should accept module and action names in the request data argument with routing disabled (#776) (David) 
     41CHG: Routing should not just bail out of execute() if routing is enabled, but no routes are defined (#779) (David) 
     42CHG: Refactor AgaviContext::initialize() and the passing of "profile" (#778) (David) 
     43CHG: Arguments passed to AgaviController::dispatch() should have precedence over routing results (#777) (David) 
     44CHG: Introduce generic AgaviStreamLoggerAppender (#773) (David) 
     45CHG: Make AgaviLoggerAppender an AgaviParameterHolder (#774) (David) 
    2846CHG: Change error class handling in FPF to set classes on elements returned by the respective XPath expressions, not the original elements (#768) (David) 
    2947CHG: Use file locking everywhere files are written (Dominik) (#766) 
    3048 
     49FIX: AgaviValidationManager::hasError() is inconsistent with AgaviValidationManager::getError() regarding severity (#784) (David) 
     50FIX: Routing tests do not reset core.use_routing in tearDown() (#781) (David) 
     51FIX: stdout/stderror log appenders are broken (#751) (David) 
     52FIX: Caching configuration blocks might be merged incorrectly (#755) (David) 
     53FIX: Caching and validation configurations cannot be per-context (#754) (David) 
    3154FIX: Form Population Filter incorrectly inserts XML prolog into HTML documents (#771) (David) 
    3255FIX: Calling move() twice on the same uploaded file will cause a bogus exception (#770) (David) 
     
    227250FIX: WebRouting::gen() ignores 'separator' option when generating existing routes (#545) (David) 
    228251FIX: <route action=".Something" /> confuses template location code (#540) (David) 
    229 FIX: AgaviPropelDatabase returns null in getConnection when used with Propel 1.2 (#538) (Dominik)  
     252FIX: AgaviPropelDatabase returns null in getConnection when used with Propel 1.2 (#538) (Dominik) 
    230253FIX: "shiny" exception template may generate invalid markup if HTML is at first line of code snippet (#537) (David) 
    231254FIX: AgaviToolkit::expandVariables() skips null arguments (#536) (David) 
     
    644667 
    645668- Initial Release 
    646  
  • trunk/RELEASE_NOTES

    r2497 r2550  
    3333 
    3434- Validation severity "none" is now called "silent". 
     35 
     36 
     37Version 0.11.2 - July ??, 2008 
     38============================== 
     39 
     40This maintenance release fixes a number of bugs, comes with several changes to improve consistency, and also features a couple of new features. Some of these include: 
     41 
     42- AgaviStringValidator can now trim an input string. 
     43- AgaviDoctrineDatabase has been improved. 
     44- <setting> elements in settings.xml can now be arrays by using <parameter>s. 
     45- Data returned from a View is now available through $inner in the first template. 
     46- File locking is now used anywhere files are being written (config compilation, caching). 
     47- AgaviValidationManager::hasError() behavior was fixed to be consistent with getError(). 
     48 
     49As always, the CHANGELOG has a comprehensive list of changes. 
    3550 
    3651 
  • trunk/etc/phing/AgaviPackageTask.php

    r2400 r2550  
    102102    $p2->setPackageType('php'); 
    103103    $p2->setPackage('agavi'); 
    104     $p2->addMaintainer('lead', 'david', 'David Zülke', 'dz@bitxtender.com'); 
    105     $p2->addMaintainer('developer', 'dominik', 'Dominik del Bondio', 'ddb@bitxtender.com'); 
     104    $p2->addMaintainer('lead', 'david', 'David Zülke', 'david.zuelke@bitextender.com'); 
     105    $p2->addMaintainer('developer', 'dominik', 'Dominik del Bondio', 'dominik.del.bondio@bitextender.com'); 
     106    $p2->addMaintainer('developer', 'impl', 'Noah Fontes', 'impl@cynigram.com'); 
    106107    $p2->addMaintainer('developer', 'v-dogg', 'Veikko Mäkinen', 'mail@veikkomakinen.com'); 
    107108    $p2->setChannel('pear.agavi.org'); 
  • trunk/src/config/AgaviCachingConfigHandler.class.php

    r2495 r2550  
    5757    foreach($configurations as $cfg) { 
    5858      foreach($cfg->cachings as $caching) { 
    59         if(!AgaviToolkit::literalize($caching->getAttribute('enabled', true))) { 
    60           continue; 
    61         } 
    62          
    6359        $groups = array(); 
    6460        if(isset($caching->groups)) { 
     
    144140        $methods = array_map('trim', explode(' ', $caching->getAttribute('method', '*'))); 
    145141        foreach($methods as $method) { 
    146           $cachings[$method] = array( 
    147             'lifetime' => $caching->getAttribute('lifetime'), 
    148             'groups' => $groups, 
    149             'views' => $views, 
    150             'action_attributes' => $actionAttributes, 
    151             'output_types' => $outputTypes, 
    152           ); 
     142          if(!AgaviToolkit::literalize($caching->getAttribute('enabled', true))) { 
     143            unset($cachings[$method]); 
     144          } else { 
     145            $values = array( 
     146              'lifetime' => $caching->getAttribute('lifetime'), 
     147              'groups' => $groups, 
     148              'views' => $views, 
     149              'action_attributes' => $actionAttributes, 
     150              'output_types' => $outputTypes, 
     151            ); 
     152            $cachings[$method] = $values; 
     153          } 
    153154        } 
    154155      } 
  • trunk/src/config/defaults/autoload.xml

    r2357 r2550  
    116116      <autoload name="AgaviStderrLoggerAppender">%core.agavi_dir%/logging/AgaviStderrLoggerAppender.class.php</autoload> 
    117117      <autoload name="AgaviStdoutLoggerAppender">%core.agavi_dir%/logging/AgaviStdoutLoggerAppender.class.php</autoload> 
     118      <autoload name="AgaviStreamLoggerAppender">%core.agavi_dir%/logging/AgaviStreamLoggerAppender.class.php</autoload> 
    118119      <autoload name="AgaviTimestampLoggerLayout">%core.agavi_dir%/logging/AgaviTimestampLoggerLayout.class.php</autoload> 
    119120 
  • trunk/src/controller/AgaviController.class.php

    r2495 r2550  
    165165  public function dispatch(AgaviRequestDataHolder $arguments = null) 
    166166  { 
     167    $container = null; 
     168     
    167169    try { 
    168170       
    169       $requestData = $this->context->getRequest()->getRequestData(); 
    170       if($arguments !== null) { 
    171         $requestData->merge($arguments); 
    172       } 
     171      $rq = $this->context->getRequest(); 
     172      $rd = $rq->getRequestData(); 
    173173       
    174174      // match routes and assign returned initial execution container 
    175175      $container = $this->context->getRouting()->execute(); 
    176176       
     177      // merge in any arguments given. they need to have precedence over what the routing found 
     178      if($arguments !== null) { 
     179        $rd->merge($arguments); 
     180      } 
     181       
     182      // next, we have to see if the routing did anything useful, i.e. whether or not it was enabled. 
    177183      $moduleName = $container->getModuleName(); 
    178184      $actionName = $container->getActionName(); 
    179        
    180       if($moduleName == null) { 
    181         // no module has been specified 
    182         $container->setModuleName(AgaviConfig::get('actions.default_module')); 
    183         $container->setActionName(AgaviConfig::get('actions.default_action')); 
     185      if(!$moduleName) { 
     186        // no module has been specified; that means the routing did not run, as it would otherwise have the 404 action's module name 
     187         
     188        // lets see if our request data has values for module and action 
     189        $ma = $rq->getParameter('module_accessor'); 
     190        $aa = $rq->getParameter('action_accessor'); 
     191        if($rd->hasParameter($ma) && $rd->hasParameter($aa)) { 
     192          // yup. grab those 
     193          $moduleName = $rd->getParameter($ma); 
     194          $actionName = $rd->getParameter($aa); 
     195        } else { 
     196          // nope. then its time for the default action 
     197          $moduleName = AgaviConfig::get('actions.default_module'); 
     198          $actionName = AgaviConfig::get('actions.default_action'); 
     199        } 
     200         
     201        // so by now we hopefully have something reasonable for module and action names - let's set them on the container 
     202        $container->setModuleName($moduleName); 
     203        $container->setActionName($actionName); 
    184204      } 
    185205       
     
    207227       
    208228    } catch(Exception $e) { 
    209       if(isset($container) && $container instanceof AgaviExecutionContainer) { 
    210         AgaviException::printStackTrace($e, $this->context, $container); 
    211       } else { 
    212         AgaviException::printStackTrace($e, $this->context); 
    213       } 
     229      AgaviException::printStackTrace($e, $this->context, $container); 
    214230    } 
    215231  } 
  • trunk/src/core/AgaviContext.class.php

    r2259 r2550  
    8787  /** 
    8888   * @var        AgaviTranslationManager A TranslationManager instance. 
    89    * @since      0.11.0 
    9089   */ 
    9190  protected $translationManager = null; 
     
    112111 
    113112  /** 
    114    * Clone method, overridden to prevent cloning, there can be only one.  
    115    * 
    116    * @author     Mike Vincent <mike@agavi.org>   
     113   * Clone method, overridden to prevent cloning, there can be only one. 
     114   * 
     115   * @author     Mike Vincent <mike@agavi.org> 
    117116   * @since      0.9.0 
    118117   */ 
     
    120119  { 
    121120    trigger_error('Cloning an AgaviContext instance is not allowed.', E_USER_ERROR); 
    122   }  
    123  
    124   /** 
    125    * Constuctor method, intentionally made private so the context cannot be  
     121  } 
     122 
     123  /** 
     124   * Constuctor method, intentionally made private so the context cannot be 
    126125   * created directly. 
    127126   * 
    128    * @author     Mike Vincent <mike@agavi.org>   
    129    * @since      0.9.0 
    130    */ 
    131   private function __construct()  
    132   { 
    133     // Singleton, setting up the class happens in initialize() 
     127   * @param      string The name of this context. 
     128   * 
     129   * @author     David Zülke <dz@bitxtender.com> 
     130   * @author     Mike Vincent <mike@agavi.org> 
     131   * @since      0.9.0 
     132   */ 
     133  private function __construct($name) 
     134  { 
     135    $this->name = $name; 
    134136  } 
    135137 
     
    245247      if(!isset(self::$instances[$profile])) { 
    246248        $class = __CLASS__; 
    247         self::$instances[$profile] = new $class; 
    248         self::$instances[$profile]->initialize($profile); 
     249        self::$instances[$profile] = new $class($profile); 
     250        self::$instances[$profile]->initialize(); 
    249251      } 
    250252      return self::$instances[$profile]; 
     
    271273   * (re)Initialize the AgaviContext instance. 
    272274   * 
    273    * @param      string A name corresponding to a section of the config 
    274    * 
    275275   * @author     Dominik del Bondio <ddb@bitxtender.com> 
    276276   * @author     David Zülke <dz@bitxtender.com> 
     
    278278   * @since      0.10.0 
    279279   */ 
    280   public function initialize($profile = null) 
    281   { 
    282     if($profile === null) { 
    283       $profile = AgaviConfig::get('core.default_context', 'stdctx'); 
    284     } 
    285      
    286     $profile = strtolower($profile); 
    287      
    288     $this->name = $profile; 
    289      
     280  public function initialize() 
     281  { 
    290282    try { 
    291       include(AgaviConfigCache::checkConfig(AgaviConfig::get('core.config_dir') . '/factories.xml', $profile)); 
     283      include(AgaviConfigCache::checkConfig(AgaviConfig::get('core.config_dir') . '/factories.xml', $this->name)); 
    292284    } catch(Exception $e) { 
    293285      AgaviException::printStackTrace($e, $this); 
  • trunk/src/database/AgaviDoctrineDatabase.class.php

    r2259 r2550  
    116116      } 
    117117       
     118      foreach((array)$this->getParameter('manager_attributes', array()) as $attributeName => $attributeValue) { 
     119        $this->doctrineManager->setAttribute($attributeName, $attributeValue); 
     120      } 
     121       
     122      Doctrine::loadModels($this->getParameter('load_models'));  
     123       
    118124      foreach((array)$this->getParameter('bind_components', array()) as $componentName) { 
    119125        $this->doctrineManager->bindComponent($componentName, $name); 
  • trunk/src/exception/templates/plaintext.php

    r2259 r2550  
    3333// fix stack trace in case it doesn't contain the exception origin as the first entry 
    3434$fixedTrace = $e->getTrace(); 
    35 if(isset($fixedTrace[0]['file']) && $fixedTrace[0]['file'] != $e->getFile() && $fixedTrace[0]['line'] != $e->getLine()) { 
     35if(isset($fixedTrace[0]['file']) && !($fixedTrace[0]['file'] == $e->getFile() && $fixedTrace[0]['line'] == $e->getLine())) { 
    3636  $fixedTrace = array_merge(array(array('file' => $e->getFile(), 'line' => $e->getLine())), $fixedTrace); 
    3737} 
  • trunk/src/exception/templates/shiny.php

    r2486 r2550  
    102102// fix stack trace in case it doesn't contain the exception origin as the first entry 
    103103$fixedTrace = $e->getTrace(); 
    104 if(isset($fixedTrace[0]['file']) && $fixedTrace[0]['file'] != $e->getFile() && $fixedTrace[0]['line'] != $e->getLine()) { 
     104if(isset($fixedTrace[0]['file']) && !($fixedTrace[0]['file'] == $e->getFile() && $fixedTrace[0]['line'] == $e->getLine())) { 
    105105  $fixedTrace = array_merge(array(array('file' => $e->getFile(), 'line' => $e->getLine())), $fixedTrace); 
    106106} 
     
    579579  } 
    580580?> 
    581       <li id="frame<?php echo $i; ?>"<?php if($i > 1): ?> class="hidecode"<?php endif; ?>>at <?php if($i > 1): ?><strong><?php if(isset($trace['class'])): ?><?php echo $trace['class'], htmlspecialchars($trace['type']); ?><?php endif; ?><?php echo $trace['function']; ?><?php if(isset($trace['args'])): ?>(<?php echo buildParamList($trace['args']); ?>)<?php endif; ?></strong><?php else: ?><em>exception origin</em><?php endif; ?><br />in <?php if(isset($trace['file'])): echo htmlspecialchars(str_replace( 
     581      <li id="frame<?php echo $i; ?>"<?php if($i != 2): ?> class="hidecode"<?php endif; ?>>at <?php if($i > 1): ?><strong><?php if(isset($trace['class'])): ?><?php echo $trace['class'], htmlspecialchars($trace['type']); ?><?php endif; ?><?php echo $trace['function']; ?><?php if(isset($trace['args'])): ?>(<?php echo buildParamList($trace['args']); ?>)<?php endif; ?></strong><?php else: ?><em>exception origin</em><?php endif; ?><br />in <?php if(isset($trace['file'])): echo str_replace( 
    582582      array( 
    583583        '_' . AgaviConfig::get('core.module_dir', 'something totally random'), 
     
    598598        '<abbr title="' . AgaviConfig::get('core.agavi_dir') . '">core.agavi_dir</abbr>', 
    599599      ), 
    600 '_' . $trace['file'])); ?> <a href="#frame<?php echo $i; ?>" class="toggle" title="Toggle source code snippet" onclick="this.parentNode.className = this.parentNode.className == 'hidecode' ? '' : 'hidecode'; return false;">line <?php echo $trace['line']; ?></a><ol start="<?php echo $start = $trace['line'] < 4 ? 1 : $trace['line'] - 3; ?>" style="padding-left:<?php echo strlen($start+6)*0.6+2; ?>em"><?php 
     600'_' . $trace['file']); ?> <a href="#frame<?php echo $i; ?>" class="toggle" title="Toggle source code snippet" onclick="this.parentNode.className = this.parentNode.className == 'hidecode' ? '' : 'hidecode'; return false;">line <?php echo $trace['line']; ?></a><ol start="<?php echo $start = $trace['line'] < 4 ? 1 : $trace['line'] - 3; ?>" style="padding-left:<?php echo strlen($start+6)*0.6+2; ?>em"><?php 
    601601$lines = array_slice($highlights[$trace['file']], $start - 1, 7, true); 
    602602foreach($lines as $key => &$line) { 
  • trunk/src/filter/AgaviExecutionFilter.class.php

    r2499 r2550  
    272272      // $lm->log('Caching enabled, configuration file found, loading...'); 
    273273      // no _once please! 
    274       include(AgaviConfigCache::checkConfig($cachingDotXml)); 
     274      include(AgaviConfigCache::checkConfig($cachingDotXml, $this->context->getName())); 
    275275    } 
    276276 
     
    639639        // load validation configuration 
    640640        // do NOT use require_once 
    641         require(AgaviConfigCache::checkConfig($validationConfig)); 
     641        require(AgaviConfigCache::checkConfig($validationConfig, $this->context->getName())); 
    642642      } 
    643643 
  • trunk/src/filter/AgaviFormPopulationFilter.class.php

    r2518 r2550  
    4747  const ENCODING_ISO_8859_1 = 'iso-8859-1'; 
    4848 
     49  /** 
     50   * @var        DOMDocument Our (X)HTML document. 
     51   */ 
    4952  protected $doc; 
     53 
     54  /** 
     55   * @var        DOMXPath Our XPath instance for the document. 
     56   */ 
    5057  protected $xpath; 
    51   protected $ns; 
     58 
     59  /** 
     60   * @var        string The XML NS prefix we're working on with XPath, including 
     61   *                    a colon (or empty string if document has no NS). 
     62   */ 
     63  protected $xmlnsPrefix = ''; 
    5264 
    5365  /** 
     
    151163      if($this->doc->documentElement && $this->doc->documentElement->namespaceURI) { 
    152164        $this->xpath->registerNamespace('html', $this->doc->documentElement->namespaceURI); 
    153         $this->ns = 'html:'; 
     165        $this->xmlnsPrefix = 'html:'; 
    154166      } else { 
    155         $this->ns = ''; 
     167        $this->xmlnsPrefix = ''; 
    156168      } 
    157169    } else { 
    158170      $this->doc->loadHTML($output); 
    159171      $this->xpath = new DomXPath($this->doc); 
    160       $this->ns = ''; 
     172      $this->xmlnsPrefix = ''; 
    161173    } 
    162174 
     
    187199 
    188200    $properXhtml = false; 
    189     foreach($this->xpath->query('//' . $this->ns . 'head/' . $this->ns . 'meta') as $meta) { 
     201    foreach($this->xpath->query(sprintf('//%1$shead/%1$smeta', $this->xmlnsPrefix)) as $meta) { 
    190202      if(strtolower($meta->getAttribute('http-equiv')) == 'content-type') { 
    191203        if($this->doc->encoding === null) { 
     
    221233    } 
    222234 
    223     $base = $this->xpath->query('/' . $this->ns . 'html/' . $this->ns . 'head/' . $this->ns . 'base[@href]'); 
     235    $base = $this->xpath->query(sprintf('/%1$shtml/%1$shead/%1$sbase[@href]', $this->xmlnsPrefix)); 
    224236    if($base->length) { 
    225237      $baseHref = $base->item(0)->getAttribute('href'); 
     
    234246      foreach(array_keys($populate) as $id) { 
    235247        if(is_string($id)) { 
    236           $query[] = '@id="' . $id . '"'; 
     248          $query[] = sprintf('@id="%s"', $id); 
    237249        } 
    238250      } 
    239251      if($query) { 
    240         $forms = $this->xpath->query('//' . $this->ns . 'form[' . implode(' or ', $query) . ']'); 
     252        $forms = $this->xpath->query(sprintf('//%1$sform[%2$s]', $this->xmlnsPrefix, implode(' or ', $query))); 
    241253      } 
    242254    } else { 
    243       $forms = $this->xpath->query('//' . $this->ns . 'form[@action]'); 
     255      $forms = $this->xpath->query(sprintf('//%1$sform[@action]', $this->xmlnsPrefix)); 
    244256    } 
    245257 
     
    276288 
    277289      // build the XPath query 
    278       $query = 'descendant::' . $this->ns . 'textarea[@name] | descendant::' . $this->ns . 'select[@name] | descendant::' . $this->ns . 'input[@name and (not(@type) or @type="text" or (@type="checkbox" and not(contains(@name, "[]"))) or (@type="checkbox" and contains(@name, "[]") and @value) or @type="radio" or @type="password" or @type="file"'; 
     290      $query = sprintf('descendant::%1$stextarea[@name] | descendant::%1$sselect[@name] | descendant::%1$sinput[@name and (not(@type) or @type="text" or (@type="checkbox" and not(contains(@name, "[]"))) or (@type="checkbox" and contains(@name, "[]") and @value) or @type="radio" or @type="password" or @type="file"', $this->xmlnsPrefix); 
    279291      if($cfg['include_hidden_inputs']) { 
    280292        $query .= ' or @type="hidden"'; 
     
    345357          $errorClassElements[] = $element; 
    346358          // all implicit labels 
    347           foreach($this->xpath->query('ancestor::' . $this->ns . 'label[not(@for)]', $element) as $label) { 
     359          foreach($this->xpath->query(sprintf('ancestor::%1$slabel[not(@for)]', $this->xmlnsPrefix), $element) as $label) { 
    348360            $errorClassElements[] = $label; 
    349361          } 
    350362          // and all explicit labels 
    351363          if(($id = $element->getAttribute('id')) != '') { 
    352             foreach($this->xpath->query('descendant::' . $this->ns . 'label[@for="' . $id . '"]', $form) as $label) { 
     364            foreach($this->xpath->query(sprintf('descendant::%1$slabel[@for="%2$s"]', $this->xmlnsPrefix, $id), $form) as $label) { 
    353365              $errorClassElements[] = $label; 
    354366            } 
     
    360372            foreach($cfg['error_class_map'] as $xpathExpression => $errorClassName) { 
    361373              // evaluate each xpath expression 
    362               $errorClassResults = $this->xpath->query(AgaviToolkit::expandVariables($xpathExpression, array('htmlnsPrefix' => $this->ns)), $errorClassElement); 
     374              $errorClassResults = $this->xpath->query(AgaviToolkit::expandVariables($xpathExpression, array('htmlnsPrefix' => $this->xmlnsPrefix)), $errorClassElement); 
    363375              if($errorClassResults && $errorClassResults->length) { 
    364376                // we have results. the xpath expressions are used to locale the actual elements we set the error class on - doesn't necessarily have to be the erroneous element or the label! 
     
    457469          // select elements 
    458470          // yes, we still use XPath because there could be OPTGROUPs 
    459           foreach($this->xpath->query('descendant::' . $this->ns . 'option', $element) as $option) { 
     471          foreach($this->xpath->query(sprintf('descendant::%1$soption', $this->xmlnsPrefix), $element) as $option) { 
    460472            $option->removeAttribute('selected'); 
    461473            if($p->hasParameter($pname) && ($option->getAttribute('value') === $value || ($multiple && is_array($value) && in_array($option->getAttribute('value'), $value)))) { 
     
    633645    $insertSuccessful = false; 
    634646    foreach($rules as $xpathExpression => $errorMessageInfo) { 
    635       $targets = $this->xpath->query(AgaviToolkit::expandVariables($xpathExpression, array('htmlnsPrefix' => $this->ns)), $element); 
     647      $targets = $this->xpath->query(AgaviToolkit::expandVariables($xpathExpression, array('htmlnsPrefix' => $this->xmlnsPrefix)), $element); 
    636648 
    637649      if(!$targets || !$targets->length) { 
  • trunk/src/logging/AgaviFileLoggerAppender.class.php

    r2259 r2550  
    2020 * @subpackage logging 
    2121 * 
     22 * @author     David Zülke <dz@bitxtender.com> 
    2223 * @author     Bob Zoller <bob@agavi.org> 
    2324 * @copyright  Authors 
     
    2829 * @version    $Id$ 
    2930 */ 
    30 class AgaviFileLoggerAppender extends AgaviLoggerAppender 
     31class AgaviFileLoggerAppender extends AgaviStreamLoggerAppender 
    3132{ 
    32   /** 
    33    * @var        The resource of the file this appender is writing to. 
    34    */ 
    35   protected $handle = null; 
    36  
    37   /** 
    38    * @var        The name of the file this appender is writing to. 
    39    */ 
    40   protected $filename = ''; 
    41  
    4233  /** 
    4334   * Initialize the object. 
     
    5142  public function initialize(AgaviContext $context, array $parameters = array()) 
    5243  { 
     44    // for < 0.11.2 BC 
     45    if(isset($parameters['file'])) { 
     46      $parameters['destination'] = $parameters['file']; 
     47      unset($parameters['file']); 
     48    } 
     49     
    5350    parent::initialize($context, $parameters); 
    5451 
    55     if(isset($parameters['file'])) { 
    56       $this->filename = $parameters['file']; 
    57     } 
    5852  } 
    5953 
     
    7165  protected function getHandle() 
    7266  { 
    73     if(is_null($this->handle)) { 
    74       if(!is_writable(dirname($this->filename)) || (file_exists($this->filename) && !is_writable($this->filename)) || !$this->handle = fopen($this->filename, 'a')) { 
    75         throw new AgaviLoggingException('Cannot open file "' . $this->filename . '", please check permissions on file or directory.'); 
    76       } 
     67    $destination = $this->getParameter('destination'); 
     68    if(is_null($this->handle) && (!is_writable(dirname($destination)) || (file_exists($destination) && !is_writable($destination)))) { 
     69      throw new AgaviLoggingException('Cannot open file "' . $destination . '", please check permissions on file or directory.'); 
    7770    } 
    78     return $this->handle; 
    79   } 
    80  
    81   /** 
    82    * Execute the shutdown procedure. 
    83    * 
    84    * If open, close the filehandle.