1 <?php
  2 /**
  3  * SimplePie
  4  *
  5  * A PHP-Based RSS and Atom Feed Framework.
  6  * Takes the hard work out of managing a complete RSS/Atom solution.
  7  *
  8  * Copyright (c) 2004-2012, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors
  9  * All rights reserved.
 10  *
 11  * Redistribution and use in source and binary forms, with or without modification, are
 12  * permitted provided that the following conditions are met:
 13  *
 14  *  * Redistributions of source code must retain the above copyright notice, this list of
 15  *    conditions and the following disclaimer.
 16  *
 17  *  * Redistributions in binary form must reproduce the above copyright notice, this list
 18  *    of conditions and the following disclaimer in the documentation and/or other materials
 19  *    provided with the distribution.
 20  *
 21  *  * Neither the name of the SimplePie Team nor the names of its contributors may be used
 22  *    to endorse or promote products derived from this software without specific prior
 23  *    written permission.
 24  *
 25  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
 26  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
 27  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS
 28  * AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 29  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 30  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 31  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 32  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 33  * POSSIBILITY OF SUCH DAMAGE.
 34  *
 35  * @package SimplePie
 36  * @version 1.3.1
 37  * @copyright 2004-2012 Ryan Parman, Geoffrey Sneddon, Ryan McCue
 38  * @author Ryan Parman
 39  * @author Geoffrey Sneddon
 40  * @author Ryan McCue
 41  * @link http://simplepie.org/ SimplePie
 42  * @license http://www.opensource.org/licenses/bsd-license.php BSD License
 43  */
 44 
 45 /**
 46  * Handles creating objects and calling methods
 47  *
 48  * Access this via {@see SimplePie::get_registry()}
 49  *
 50  * @package SimplePie
 51  */
 52 class SimplePie_Registry
 53 {
 54     /**
 55      * Default class mapping
 56      *
 57      * Overriding classes *must* subclass these.
 58      *
 59      * @var array
 60      */
 61     protected $default = array(
 62         'Cache' => 'SimplePie_Cache',
 63         'Locator' => 'SimplePie_Locator',
 64         'Parser' => 'SimplePie_Parser',
 65         'File' => 'SimplePie_File',
 66         'Sanitize' => 'SimplePie_Sanitize',
 67         'Item' => 'SimplePie_Item',
 68         'Author' => 'SimplePie_Author',
 69         'Category' => 'SimplePie_Category',
 70         'Enclosure' => 'SimplePie_Enclosure',
 71         'Caption' => 'SimplePie_Caption',
 72         'Copyright' => 'SimplePie_Copyright',
 73         'Credit' => 'SimplePie_Credit',
 74         'Rating' => 'SimplePie_Rating',
 75         'Restriction' => 'SimplePie_Restriction',
 76         'Content_Type_Sniffer' => 'SimplePie_Content_Type_Sniffer',
 77         'Source' => 'SimplePie_Source',
 78         'Misc' => 'SimplePie_Misc',
 79         'XML_Declaration_Parser' => 'SimplePie_XML_Declaration_Parser',
 80         'Parse_Date' => 'SimplePie_Parse_Date',
 81     );
 82 
 83     /**
 84      * Class mapping
 85      *
 86      * @see register()
 87      * @var array
 88      */
 89     protected $classes = array();
 90 
 91     /**
 92      * Legacy classes
 93      *
 94      * @see register()
 95      * @var array
 96      */
 97     protected $legacy = array();
 98 
 99     /**
100      * Constructor
101      *
102      * No-op
103      */
104     public function __construct() { }
105 
106     /**
107      * Register a class
108      *
109      * @param string $type See {@see $default} for names
110      * @param string $class Class name, must subclass the corresponding default
111      * @param bool $legacy Whether to enable legacy support for this class
112      * @return bool Successfulness
113      */
114     public function register($type, $class, $legacy = false)
115     {
116         if (!is_subclass_of($class, $this->default[$type]))
117         {
118             return false;
119         }
120 
121         $this->classes[$type] = $class;
122 
123         if ($legacy)
124         {
125             $this->legacy[] = $class;
126         }
127 
128         return true;
129     }
130 
131     /**
132      * Get the class registered for a type
133      *
134      * Where possible, use {@see create()} or {@see call()} instead
135      *
136      * @param string $type
137      * @return string|null
138      */
139     public function get_class($type)
140     {
141         if (!empty($this->classes[$type]))
142         {
143             return $this->classes[$type];
144         }
145         if (!empty($this->default[$type]))
146         {
147             return $this->default[$type];
148         }
149 
150         return null;
151     }
152 
153     /**
154      * Create a new instance of a given type
155      *
156      * @param string $type
157      * @param array $parameters Parameters to pass to the constructor
158      * @return object Instance of class
159      */
160     public function &create($type, $parameters = array())
161     {
162         $class = $this->get_class($type);
163 
164         if (in_array($class, $this->legacy))
165         {
166             switch ($type)
167             {
168                 case 'locator':
169                     // Legacy: file, timeout, useragent, file_class, max_checked_feeds, content_type_sniffer_class
170                     // Specified: file, timeout, useragent, max_checked_feeds
171                     $replacement = array($this->get_class('file'), $parameters[3], $this->get_class('content_type_sniffer'));
172                     array_splice($parameters, 3, 1, $replacement);
173                     break;
174             }
175         }
176 
177         if (!method_exists($class, '__construct'))
178         {
179             $instance = new $class;
180         }
181         else
182         {
183             $reflector = new ReflectionClass($class);
184             $instance = $reflector->newInstanceArgs($parameters);
185         }
186 
187         if (method_exists($instance, 'set_registry'))
188         {
189             $instance->set_registry($this);
190         }
191         return $instance;
192     }
193 
194     /**
195      * Call a static method for a type
196      *
197      * @param string $type
198      * @param string $method
199      * @param array $parameters
200      * @return mixed
201      */
202     public function &call($type, $method, $parameters = array())
203     {
204         $class = $this->get_class($type);
205 
206         if (in_array($class, $this->legacy))
207         {
208             switch ($type)
209             {
210                 case 'Cache':
211                     // For backwards compatibility with old non-static
212                     // Cache::create() methods
213                     if ($method === 'get_handler')
214                     {
215                         $result = @call_user_func_array(array($class, 'create'), $parameters);
216                         return $result;
217                     }
218                     break;
219             }
220         }
221 
222         $result = call_user_func_array(array($class, $method), $parameters);
223         return $result;
224     }
225 }