Browse Source

* Committing the Zend_Log factory proposal changes
* Zend_Log_Writer_Mail is unfinished and is awaiting suggestions (Zend_Mail::factory() ?)

git-svn-id: http://framework.zend.com/svn/framework/standard/trunk@19545 44c647ce-9c0f-0410-b52a-842ac1e357ba

dynom 16 years ago
parent
commit
7b3cd0f5b3

+ 169 - 3
library/Zend/Log.php

@@ -59,6 +59,19 @@ class Zend_Log
     protected $_extras = array();
 
     /**
+     *
+     * @var string
+     */
+    protected $_defaultWriterNamespace = 'Zend_Log_Writer';
+
+    /**
+     *
+     * @var string
+     */
+    protected $_defaultFilterNamespace = 'Zend_Log_Filter';
+
+
+    /**
      * Class constructor.  Create a new logger
      *
      * @param Zend_Log_Writer_Abstract|null  $writer  default writer
@@ -74,6 +87,143 @@ class Zend_Log
     }
 
     /**
+     * Factory to construct the logger and one or more writers
+     * based on the configuration array
+     *
+     * @param mixed Array or instance of Zend_Config
+     * @return Zend_Log
+     */
+    static public function factory($config = array())
+    {
+        if ($config instanceof Zend_Config) {
+            $config = $config->toArray();
+        }
+
+        if (!is_array($config) || empty($config)) {
+            require_once 'Zend_Log_Exception.php';
+            throw new Zend_Log_Exception('Configuration must be an array or instance of Zend_Config');
+        }
+
+        $log = new Zend_Log;
+        
+        if (!is_array(current($config))) {
+            $log->addWriter(current($config));
+
+        } else {
+
+            foreach($config as $writer) {
+                $log->addWriter($writer);
+            }
+        }
+
+        return $log;
+    }
+
+
+    /**
+     * Construct a writer object based on a configuration array
+     *
+     * @param array $spec config array with writer spec
+     * @return Zend_Log_Writer_Abstract
+     */
+    protected function _constructWriterFromConfig($config)
+    {
+        $writer = $this->_constructFromConfig('writer', $config, $this->_defaultWriterNamespace);
+
+        if (! $writer instanceof Zend_Log_Writer_Abstract) {
+            require_once 'Zend/Log/Exception.php';
+            throw new Zend_Log_Exception("{$writerName} does not extend Zend_Log_Writer_Abstract!");
+        }
+
+        if (isset($config['filterName'])) {
+            $filter = $this->_constructFilterFromConfig($config);
+            $writer->addFilter($filter);
+        }
+
+        return $writer;
+    }
+
+    /**
+     * Construct filter object from configuration array or Zend_Config object
+     *
+     * @param mixed $config Zend_Config or Array
+     * @return Zend_Log_Filter_Interface
+     */
+    protected function _constructFilterFromConfig($config)
+    {
+        $filter = $this->_constructFromConfig('filter', $config, $this->_defaultFilterNamespace);
+
+        if (! $filter instanceof Zend_Log_Filter_Interface) {
+            require_once 'Zend/Log/Exception.php';
+            throw new Zend_Log_Exception("{$filterName} does not implement Zend_Log_Filter_Interface");
+        }
+
+        return $filter;
+    }
+
+    /**
+     * Construct a filter or writer from config
+     * 
+     * @param string $type 'writer' of 'filter'
+     * @param mixed $config Zend_Config or Array
+     * @param string $namespace
+     * @return object
+     */
+    protected function _constructFromConfig($type, $config, $namespace) 
+    {
+        if ($config instanceof Zend_Config) {
+            $config = $config->toArray();
+        }
+
+        if (!is_array($config) || empty($config)) {
+            require_once 'Zend_Log_Exception.php';
+            throw new Zend_Log_Exception(
+                'Configuration must be an array or instance of Zend_Config'
+            );
+        }
+
+        $params = isset($config[ $type .'Params' ]) ? $config[ $type .'Params' ] : array();
+        $className = $this->getClassName($config, $type, $namespace);
+        Zend_Loader::loadClass($className);
+
+        $reflection = new ReflectionClass($className);
+        if (!$reflection->implementsInterface('Zend_Log_FactoryInterface'))
+        {        
+            throw new Zend_Log_Exception(
+                'Driver does not implement Zend_Log_FactoryInterface and can not be constructed from config.'
+            );
+        }
+
+        return call_user_func(array($className, 'factory'), $params);
+    }
+
+    /**
+     * Get the writer or filter full classname
+     *
+     * @param array $config
+     * @param string $type filter|writer
+     * @param string $defaultNamespace
+     * @return string full classname
+     */
+    protected function getClassName($config, $type, $defaultNamespace)
+    {
+        if (!isset($config[ $type . 'Name' ])) {
+            require_once 'Zend/Log/Exception.php';
+            throw new Zend_Log_Exception("Specify {$type}Name in the configuration array");
+        }
+        $className = $config[ $type . 'Name' ];
+
+        $namespace = $defaultNamespace;
+        if (isset($config[ $type . 'Namespace' ])) {
+            $namespace = $config[ $type . 'Namespace' ];
+        }
+
+        $fullClassName = strtolower($namespace . '_' . $className);
+        $fullClassName = str_replace(' ', '_', ucwords(str_replace('_', ' ', $fullClassName)));
+        return $fullClassName;
+    }
+
+    /**
      * Class destructor.  Shutdown log writers
      *
      * @return void
@@ -221,7 +371,11 @@ class Zend_Log
             /** @see Zend_Log_Filter_Priority */
             require_once 'Zend/Log/Filter/Priority.php';
             $filter = new Zend_Log_Filter_Priority($filter);
-        } elseif(!is_object($filter) || ! $filter instanceof Zend_Log_Filter_Interface) {
+
+        } elseif ($filter instanceof Zend_Config || is_array($filter)) {
+            $filter = $this->_constructFilterFromConfig($filter);
+
+        } elseif(! $filter instanceof Zend_Log_Filter_Interface) {
             /** @see Zend_Log_Exception */
             require_once 'Zend/Log/Exception.php';
             throw new Zend_Log_Exception('Invalid filter provided');
@@ -234,11 +388,23 @@ class Zend_Log
      * Add a writer.  A writer is responsible for taking a log
      * message and writing it out to storage.
      *
-     * @param  Zend_Log_Writer_Abstract $writer
+     * @param  mixed $writer Zend_Log_Writer_Abstract or Config array
      * @return void
      */
-    public function addWriter(Zend_Log_Writer_Abstract $writer)
+    public function addWriter($writer)
     {
+        if ( is_array($writer) || $writer instanceof  Zend_Config) {
+            $writer = $this->_constructWriterFromConfig($writer);
+        }
+
+        if(! $writer instanceof Zend_Log_Writer_Abstract) {
+            require_once 'Zend/Log/Exception.php';
+            throw new Zend_Log_Exception(
+              'Writer must be an instance of Zend_Log_Writer_Abstract ' .
+              'or you should pass a configuration array'
+            );
+        }
+
         $this->_writers[] = $writer;
     }
 

+ 39 - 0
library/Zend/Log/FactoryInterface.php

@@ -0,0 +1,39 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category   Zend
+ * @package    Zend_Log
+ * @copyright  Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ * @version    $Id$
+ */
+
+/**
+ * @category   Zend
+ * @package    Zend_Log
+ * @copyright  Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ * @version    $Id$
+ */
+interface Zend_Log_FactoryInterface
+{
+    
+    /**
+     * Construct a Zend_Log driver
+     * 
+     * @param mixed $config
+     * @return Zend_Log_FactoryInterface
+     */
+    static public function factory($config);
+}

+ 54 - 0
library/Zend/Log/Filter/Abstract.php

@@ -0,0 +1,54 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category   Zend
+ * @package    Zend_Log
+ * @subpackage Writer
+ * @copyright  Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ * @version    $Id$
+ */
+
+/**
+ * @category   Zend
+ * @package    Zend_Log
+ * @subpackage Writer
+ * @copyright  Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ * @version    $Id$
+ */
+abstract class Zend_Log_Filter_Abstract 
+    implements Zend_Log_Filter_Interface, Zend_Log_FactoryInterface
+{
+    /**
+     * Validate and optionally convert the config to array
+     * 
+     * @exception Zend_Log_Exception
+     * @param mixed $config Zend_Config or Array
+     * @return array
+     */
+    static protected function _parseConfig($config)
+    {
+        if ($config instanceof Zend_Config) {
+            $config = $config->asArray();
+        }
+
+        if (!is_array($config)) {
+            require_once 'Zend/Log/Exception.php';
+            throw new Zend_Log_Exception('Configuration must be an array or instance of Zend_Config');
+        }
+
+        return $config;
+    }
+}

+ 18 - 1
library/Zend/Log/Filter/Message.php

@@ -31,7 +31,7 @@ require_once 'Zend/Log/Filter/Interface.php';
  * @license    http://framework.zend.com/license/new-bsd     New BSD License
  * @version    $Id$
  */
-class Zend_Log_Filter_Message implements Zend_Log_Filter_Interface
+class Zend_Log_Filter_Message extends Zend_Log_Filter_Abstract
 {
     /**
      * @var string
@@ -54,6 +54,23 @@ class Zend_Log_Filter_Message implements Zend_Log_Filter_Interface
     }
 
     /**
+     * Create a new instance of Zend_Log_Filter_Message
+     * 
+     * @exception Zend_Log_Exception
+     * @param mixed $config
+     * @return Zend_Log_Filter_Message
+     */
+    static public function factory($config) 
+    {
+        $config = self::_parseConfig($config);
+        $config = $config + array('regexp'=>NULL);
+
+        return new self(
+            $config['regexp']
+        );
+    }
+
+    /**
      * Returns TRUE to accept the message, FALSE to block it.
      *
      * @param  array    $event    event data

+ 26 - 3
library/Zend/Log/Filter/Priority.php

@@ -31,7 +31,7 @@ require_once 'Zend/Log/Filter/Interface.php';
  * @license    http://framework.zend.com/license/new-bsd     New BSD License
  * @version    $Id$
  */
-class Zend_Log_Filter_Priority implements Zend_Log_Filter_Interface
+class Zend_Log_Filter_Priority extends Zend_Log_Filter_Abstract
 {
     /**
      * @var integer
@@ -51,7 +51,7 @@ class Zend_Log_Filter_Priority implements Zend_Log_Filter_Interface
      * @param  string   $operator  Comparison operator
      * @throws Zend_Log_Exception
      */
-    public function __construct($priority, $operator = '<=')
+    public function __construct($priority, $operator = NULL)
     {
         if (! is_integer($priority)) {
             require_once 'Zend/Log/Exception.php';
@@ -59,7 +59,30 @@ class Zend_Log_Filter_Priority implements Zend_Log_Filter_Interface
         }
 
         $this->_priority = $priority;
-        $this->_operator = $operator;
+        $this->_operator = is_null($operator) ? '<=' : $operator;
+    }
+
+    /**
+     * Create a new instance of Zend_Log_Filter_Priority
+     * 
+     * @exception Zend_Log_Exception
+     * @param mixed $config
+     * @return Zend_Log_Filter_Priority
+     */
+    static public function factory($config) 
+    {
+        $config = self::_parseConfig($config);
+        $config = $config + array('priority'=>NULL, 'operator'=>NULL);
+
+        // Add support for constants
+        if (is_string($config['priority'])) {
+            $config['priority'] = constant($config['priority']);
+        }
+
+        return new self(
+            $config['priority'], 
+            $config['operator']
+        );
     }
 
     /**

+ 12 - 1
library/Zend/Log/Filter/Suppress.php

@@ -31,7 +31,7 @@ require_once 'Zend/Log/Filter/Interface.php';
  * @license    http://framework.zend.com/license/new-bsd     New BSD License
  * @version    $Id$
  */
-class Zend_Log_Filter_Suppress implements Zend_Log_Filter_Interface
+class Zend_Log_Filter_Suppress extends Zend_Log_Filter_Abstract
 {
     /**
      * @var boolean
@@ -63,4 +63,15 @@ class Zend_Log_Filter_Suppress implements Zend_Log_Filter_Interface
         return $this->_accept;
     }
 
+    /**
+     * Create a new instance of Zend_Log_Filter_Suppress
+     * 
+     * @exception Zend_Log_Exception
+     * @param mixed $config
+     * @return Zend_Log_Filter_Suppress
+     */
+    static public function factory($config)
+    {
+        return new self($config);
+    }
 }

+ 23 - 1
library/Zend/Log/Writer/Abstract.php

@@ -31,7 +31,7 @@ require_once 'Zend/Log/Filter/Priority.php';
  * @license    http://framework.zend.com/license/new-bsd     New BSD License
  * @version    $Id$
  */
-abstract class Zend_Log_Writer_Abstract
+abstract class Zend_Log_Writer_Abstract implements Zend_Log_FactoryInterface
 {
     /**
      * @var array of Zend_Log_Filter_Interface
@@ -104,4 +104,26 @@ abstract class Zend_Log_Writer_Abstract
      */
     abstract protected function _write($event);
 
+    /**
+     * Validate and optionally convert the config to array
+     * 
+     * @exception Zend_Log_Exception
+     * @param mixed $config Zend_Config or Array
+     * @return array
+     */
+    static protected function _parseConfig($config)
+    {
+        if ($config instanceof Zend_Config) {
+            $config = $config->asArray();
+        }
+
+        if (!is_array($config)) {
+            require_once 'Zend/Log/Exception.php';
+            throw new Zend_Log_Exception(
+				'Configuration must be an array or instance of Zend_Config'
+			);
+        }
+
+        return $config;
+    }
 }

+ 23 - 0
library/Zend/Log/Writer/Db.php

@@ -67,6 +67,29 @@ class Zend_Log_Writer_Db extends Zend_Log_Writer_Abstract
     }
 
     /**
+     * Create a new instance of Zend_Log_Writer_Db
+     * 
+     * @exception Zend_Log_Exception
+     * @param mixed $config
+     * @return Zend_Log_Writer_Db
+     */
+    static public function factory($config)
+    {
+        $config = self::_parseConfig($config);
+        $config = $config + array('db'=>NULL, 'table'=>NULL, 'columnMap'=>NULL);
+        
+        if (isset($config['columnmap'])) {
+            $config['columnMap'] = $config['columnmap'];
+        }
+        
+        return new self(
+            $config['db'],
+            $config['table'],
+            $config['columnMap']
+        );
+    }
+
+    /**
      * Formatting is not possible on this writer
      */
     public function setFormatter($formatter)

+ 12 - 0
library/Zend/Log/Writer/Firebug.php

@@ -80,6 +80,18 @@ class Zend_Log_Writer_Firebug extends Zend_Log_Writer_Abstract
 
         $this->_formatter = new Zend_Log_Formatter_Firebug();
     }
+   
+    /**
+     * Create a new instance of Zend_Log_Writer_Firebug
+     * 
+     * @exception Zend_Log_Exception
+     * @param mixed $config
+     * @return Zend_Log_Writer_Firebug
+     */
+    static public function factory($config)
+    {
+        return new self($config);
+    }
 
     /**
      * Enable or disable the log writer.

+ 19 - 0
library/Zend/Log/Writer/Mail.php

@@ -117,6 +117,25 @@ class Zend_Log_Writer_Mail extends Zend_Log_Writer_Abstract
         $this->_layout    = $layout;
         $this->_formatter = new Zend_Log_Formatter_Simple();
     }
+    
+    /**
+     * Create a new instance of Zend_Log_Writer_Mail
+     * 
+     * @exception Zend_Log_Exception
+     * @param mixed $config
+     * @return Zend_Log_Writer_Mail
+     */
+    static public function factory($config)
+    {
+        throw new Zend_Exception('TODO: Implement');
+//        $config = self::_parseConfig($config);
+//        $config = $config + array('mail'=>NULL, 'layout'=>NULL);
+//        
+//        return new self(
+//            $config['mail'],
+//            $config['layout']
+//        );
+    }
 
     /**
      * Places event line into array of lines to be used as message body.

+ 12 - 0
library/Zend/Log/Writer/Mock.php

@@ -63,4 +63,16 @@ class Zend_Log_Writer_Mock extends Zend_Log_Writer_Abstract
     {
         $this->shutdown = true;
     }
+
+    /**
+     * Create a new instance of Zend_Log_Writer_Mock
+     * 
+     * @exception Zend_Log_Exception
+     * @param mixed $config
+     * @return Zend_Log_Writer_Mock
+     */
+    static public function factory($config) 
+    {
+        return new self( self::_parseConfig($config) );
+    }
 }

+ 14 - 1
library/Zend/Log/Writer/Null.php

@@ -42,5 +42,18 @@ class Zend_Log_Writer_Null extends Zend_Log_Writer_Abstract
     protected function _write($event)
     {
     }
-
+    
+    /**
+     * Create a new instance of Zend_Log_Writer_Null
+     * 
+     * @exception Zend_Log_Exception
+     * @param mixed $config
+     * @return Zend_Log_Writer_Null
+     */
+    static public function factory($config)
+    {
+        return new self(
+            self::_parseConfig($config)
+        );
+    }
 }

+ 30 - 1
library/Zend/Log/Writer/Stream.php

@@ -48,8 +48,13 @@ class Zend_Log_Writer_Stream extends Zend_Log_Writer_Abstract
      * @param  streamOrUrl     Stream or URL to open as a stream
      * @param  mode            Mode, only applicable if a URL is given
      */
-    public function __construct($streamOrUrl, $mode = 'a')
+    public function __construct($streamOrUrl, $mode = NULL)
     {
+        // Setting the default
+        if ($mode === NULL) {
+            $mode = 'a';
+        }
+
         if (is_resource($streamOrUrl)) {
             if (get_resource_type($streamOrUrl) != 'stream') {
                 require_once 'Zend/Log/Exception.php';
@@ -63,6 +68,10 @@ class Zend_Log_Writer_Stream extends Zend_Log_Writer_Abstract
 
             $this->_stream = $streamOrUrl;
         } else {
+            if (is_array($streamOrUrl) && isset($streamOrUrl['stream'])) {
+                $streamOrUrl = $streamOrUrl['stream'];
+            }
+
             if (! $this->_stream = @fopen($streamOrUrl, $mode, false)) {
                 require_once 'Zend/Log/Exception.php';
                 $msg = "\"$streamOrUrl\" cannot be opened with mode \"$mode\"";
@@ -72,7 +81,27 @@ class Zend_Log_Writer_Stream extends Zend_Log_Writer_Abstract
 
         $this->_formatter = new Zend_Log_Formatter_Simple();
     }
+    
+    /**
+     * Create a new instance of Zend_Log_Writer_Mock
+     * 
+     * @exception Zend_Log_Exception
+     * @param mixed $config
+     * @return Zend_Log_Writer_Mock
+     */
+    static public function factory($config)
+    {
+        $config = self::_parseConfig($config);
+        $config = $config + array('stream'=>NULL, 'mode'=>NULL);
 
+        $streamOrUrl = isset($config['url']) ? $config['url'] : $config['stream']; 
+        
+        return new self(
+            $streamOrUrl, 
+            $config['mode']
+        );
+    }
+    
     /**
      * Close the stream resource.
      *

+ 14 - 0
library/Zend/Log/Writer/Syslog.php

@@ -95,6 +95,20 @@ class Zend_Log_Writer_Syslog extends Zend_Log_Writer_Abstract
         }
         $this->_initializeSyslog();
     }
+    
+    /**
+     * Create a new instance of Zend_Log_Writer_Syslog
+     * 
+     * @exception Zend_Log_Exception
+     * @param mixed $config
+     * @return Zend_Log_Writer_Syslog
+     */
+    static public function factory($config)
+    {
+        return new self(
+            self::_parseConfig($config)
+        );
+    }
 
     /**
      * Initialize syslog / set application name and facility