Refactor Horde_Feed to remove the static HTTP client, and to inject it
authorChuck Hagenbuch <chuck@horde.org>
Wed, 30 Sep 2009 04:14:38 +0000 (00:14 -0400)
committerChuck Hagenbuch <chuck@horde.org>
Wed, 30 Sep 2009 04:14:38 +0000 (00:14 -0400)
instead. Also use the method override support in the HTTP client instead of
hardcoding it at the feed level.

framework/Feed/lib/Horde/Feed.php
framework/Feed/lib/Horde/Feed/Atom.php
framework/Feed/lib/Horde/Feed/Base.php
framework/Feed/lib/Horde/Feed/Entry/Atom.php
framework/Feed/lib/Horde/Feed/Entry/Base.php

index eebc21a..52cfdba 100644 (file)
 class Horde_Feed
 {
     /**
-     * HTTP client object to use for accessing feeds
-     * @var Horde_Http_Client
-     */
-    protected static $_httpClient = null;
-
-    /**
-     * Override HTTP PUT and DELETE request methods?
-     * @var boolean
-     */
-    protected static $_httpMethodOverride = false;
-
-    /**
-     * Set the HTTP client instance
-     *
-     * Sets the HTTP client object to use for retrieving the feeds. If none
-     * is set, the default Horde_Http_Client will be used.
-     *
-     * @param Horde_Http_Client $httpClient
-     */
-    public static function setHttpClient($httpClient)
-    {
-        self::$_httpClient = $httpClient;
-    }
-
-    /**
-     * Gets the HTTP client object.
-     *
-     * @return Horde_Http_Client
-     */
-    public static function getHttpClient()
-    {
-        if (!self::$_httpClient) {
-            self::$_httpClient = new Horde_Http_Client;
-        }
-
-        return self::$_httpClient;
-    }
-
-    /**
-     * Toggle using POST instead of PUT and DELETE HTTP methods.
-     *
-     * Some feed implementations do not accept PUT and DELETE HTTP methods, or
-     * they can't be used because of proxies or other measures. This allows
-     * turning on using POST where PUT and DELETE would normally be used; in
-     * addition, an X-Method-Override header will be sent with a value of PUT or
-     * DELETE as appropriate.
-     *
-     * @param boolean $override  Whether to override PUT and DELETE.
-     */
-    public static function setHttpMethodOverride($override = true)
-    {
-        self::$_httpMethodOverride = $override;
-    }
-
-    /**
-     * Get the HTTP override state
-     *
-     * @return boolean
-     */
-    public static function getHttpMethodOverride()
-    {
-        return self::$_httpMethodOverride;
-    }
-
-    /**
      * Create a Feed object based on a DOMDocument.
      *
      * @param DOMDocument $doc The DOMDocument object to import.
@@ -159,17 +94,21 @@ class Horde_Feed
      * Read a feed located at $uri
      *
      * @param string $uri The URI to fetch the feed from.
+     * @param Horde_Http_Client $httpclient The HTTP client to use.
      *
      * @throws Horde_Feed_Exception
      *
      * @return Horde_Feed_Base
      */
-    public static function readUri($uri)
+    public static function readUri($uri, Horde_Http_Client $httpclient = null)
     {
-        $client = self::getHttpClient();
+        if (is_null($httpclient)) {
+            $httpclient = new Horde_Http_Client();
+        }
+
         try {
-            $response = $client->get($uri);
-        } catch (Horde_Http_Client_Exception $e) {
+            $response = $httpclient->get($uri);
+        } catch (Horde_Http_Exception $e) {
             throw new Horde_Feed_Exception('Error reading feed: ' . $e->getMessage());
         }
         if ($response->code != 200) {
@@ -204,5 +143,4 @@ class Horde_Feed
 
         return self::create($doc);
     }
-
 }
index e7bc5c8..f9cc58a 100644 (file)
@@ -104,5 +104,4 @@ class Horde_Feed_Atom extends Horde_Feed_Base
 
         return null;
     }
-
 }
index 40f9475..dc9d8c0 100644 (file)
@@ -30,6 +30,11 @@ abstract class Horde_Feed_Base extends Horde_Xml_Element_List
     protected $_uri;
 
     /**
+     * @var Horde_Http_Client
+     */
+    protected $_httpClient;
+
+    /**
      * Feed constructor
      *
      * The Horde_Feed_Base constructor takes the URI of a feed or a
@@ -40,10 +45,15 @@ abstract class Horde_Feed_Base extends Horde_Xml_Element_List
      * @param mixed $xml The feed as a string, a DOMElement, or null.
      * @param string $uri The full URI of the feed, or null if unknown.
      */
-    public function __construct($xml = null, $uri = null)
+    public function __construct($xml = null, $uri = null, Horde_Http_Client $httpClient = null)
     {
         $this->_uri = $uri;
 
+        if (is_null($httpClient)) {
+            $httpClient = new Horde_Http_Client();
+        }
+        $this->_httpClient = $httpClient;
+
         try {
             parent::__construct($xml);
         } catch (Horde_Xml_Element_Exception $e) {
@@ -78,4 +88,16 @@ abstract class Horde_Feed_Base extends Horde_Xml_Element_List
         }
     }
 
+    /**
+     * Required by the Iterator interface.
+     *
+     * @internal
+     *
+     * @return mixed The current row, or null if no rows.
+     */
+    public function current()
+    {
+        return new $this->_listItemClassName(
+            $this->_listItems[$this->_listItemIndex], $this->_httpClient);
+    }
 }
index 3f6ccd5..384a56e 100644 (file)
@@ -6,17 +6,17 @@
  * Copyright 2007-2009 The Horde Project (http://www.horde.org/)
  *
  * @category Horde
- * @package Horde_Feed
+ * @package  Horde_Feed
  */
 
 /**
  * Concrete class for working with Atom entries.
  *
  * @category Horde
- * @package Horde_Feed
+ * @package  Horde_Feed
  */
-class Horde_Feed_Entry_Atom extends Horde_Feed_Entry_Base {
-
+class Horde_Feed_Entry_Atom extends Horde_Feed_Entry_Base
+{
     /**
      * The XML string for an "empty" Atom entry.
      *
@@ -55,15 +55,8 @@ class Horde_Feed_Entry_Atom extends Horde_Feed_Entry_Base {
         }
 
         // DELETE
-        $client = Horde_Feed::getHttpClient();
         do {
-            $client->setUri($deleteUri);
-            if (Horde_Feed::getHttpMethodOverride()) {
-                $client->setHeader('X-HTTP-Method-Override', 'DELETE');
-                $response = $client->post();
-            } else {
-                $response = $client->delete();
-            }
+            $response = $this->_httpClient->delete($deleteUri);
             switch ((int)$response->code / 100) {
             // Success
             case 2:
@@ -103,8 +96,7 @@ class Horde_Feed_Entry_Atom extends Horde_Feed_Entry_Base {
      */
     public function save($postUri = null)
     {
-        $client = Horde_Feed::getHttpClient();
-        $client->setHeaders('Content-Type', 'application/atom+xml');
+        $headers = array('Content-Type' => 'application/atom+xml');
 
         if ($this->id()) {
             // If id is set, look for link rel="edit" in the
@@ -114,13 +106,7 @@ class Horde_Feed_Entry_Atom extends Horde_Feed_Entry_Base {
                 throw new Horde_Feed_Exception('Cannot edit entry; no link rel="edit" is present.');
             }
 
-            $client->uri = $editUri;
-            if (Horde_Feed::getHttpMethodOverride()) {
-                $client->setHeaders('X-HTTP-Method-Override', 'PUT');
-                $response = $client->post($this->saveXml());
-            } else {
-                $response = $client->put($this->saveXml());
-            }
+            $response = $this->_httpClient->put($editUri, $this->saveXml(), $headers);
             if ($response->code !== 200) {
                 throw new Horde_Feed_Exception('Expected response code 200, got ' . $response->code);
             }
@@ -128,8 +114,7 @@ class Horde_Feed_Entry_Atom extends Horde_Feed_Entry_Base {
             if ($postUri === null) {
                 throw new Horde_Feed_Exception('PostURI must be specified to save new entries.');
             }
-            $client->uri = $postUri;
-            $response = $client->post($this->saveXml());
+            $response = $this->_httpClient->post($postUri, $this->saveXml(), $headers);
             if ($response->code !== 201) {
                 throw new Horde_Feed_Exception('Expected response code 201, got ' . $response->code);
             }
@@ -204,5 +189,4 @@ class Horde_Feed_Entry_Atom extends Horde_Feed_Entry_Base {
 
         return null;
     }
-
 }
index 526fb8f..d146308 100644 (file)
 abstract class Horde_Feed_Entry_Base extends Horde_Xml_Element
 {
     /**
+     * @var Horde_Http_Client
+     */
+    protected $_httpClient;
+
+    /**
      * Handle null or array values for $this->_element by initializing
      * with $this->_emptyXml, and importing the array with
      * Horde_Xml_Element::fromArray() if necessary.
@@ -26,10 +31,15 @@ abstract class Horde_Feed_Entry_Base extends Horde_Xml_Element
      * @see Horde_Xml_Element::__wakeup
      * @see Horde_Xml_Element::fromArray
      */
-    public function __construct($element = null)
+    public function __construct($element = null, Horde_Http_Client $httpClient = null)
     {
         $this->_element = $element;
 
+        if (is_null($httpClient)) {
+            $httpClient = new Horde_Http_Client();
+        }
+        $this->_httpClient = $httpClient;
+
         // If we've been passed an array, we'll store it for importing
         // after initializing with the default "empty" feed XML.
         $importArray = null;
@@ -46,5 +56,4 @@ abstract class Horde_Feed_Entry_Base extends Horde_Xml_Element
             $this->fromArray($importArray);
         }
     }
-
 }