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-2016, Ryan Parman, Sam 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 * @copyright 2004-2016 Ryan Parman, Sam Sneddon, Ryan McCue
37 * @author Ryan Parman
38 * @author Sam Sneddon
39 * @author Ryan McCue
40 * @link http://simplepie.org/ SimplePie
41 * @license http://www.opensource.org/licenses/bsd-license.php BSD License
42 */
43
44/**
45 * Handles creating objects and calling methods
46 *
47 * Access this via {@see SimplePie::get_registry()}
48 *
49 * @package SimplePie
50 */
51class SimplePie_Registry
52{
53	/**
54	 * Default class mapping
55	 *
56	 * Overriding classes *must* subclass these.
57	 *
58	 * @var array
59	 */
60	protected $default = array(
61		'Cache' => 'SimplePie_Cache',
62		'Locator' => 'SimplePie_Locator',
63		'Parser' => 'SimplePie_Parser',
64		'File' => 'SimplePie_File',
65		'Sanitize' => 'SimplePie_Sanitize',
66		'Item' => 'SimplePie_Item',
67		'Author' => 'SimplePie_Author',
68		'Category' => 'SimplePie_Category',
69		'Enclosure' => 'SimplePie_Enclosure',
70		'Caption' => 'SimplePie_Caption',
71		'Copyright' => 'SimplePie_Copyright',
72		'Credit' => 'SimplePie_Credit',
73		'Rating' => 'SimplePie_Rating',
74		'Restriction' => 'SimplePie_Restriction',
75		'Content_Type_Sniffer' => 'SimplePie_Content_Type_Sniffer',
76		'Source' => 'SimplePie_Source',
77		'Misc' => 'SimplePie_Misc',
78		'XML_Declaration_Parser' => 'SimplePie_XML_Declaration_Parser',
79		'Parse_Date' => 'SimplePie_Parse_Date',
80	);
81
82	/**
83	 * Class mapping
84	 *
85	 * @see register()
86	 * @var array
87	 */
88	protected $classes = array();
89
90	/**
91	 * Legacy classes
92	 *
93	 * @see register()
94	 * @var array
95	 */
96	protected $legacy = array();
97
98	/**
99	 * Constructor
100	 *
101	 * No-op
102	 */
103	public function __construct() { }
104
105	/**
106	 * Register a class
107	 *
108	 * @param string $type See {@see $default} for names
109	 * @param string $class Class name, must subclass the corresponding default
110	 * @param bool $legacy Whether to enable legacy support for this class
111	 * @return bool Successfulness
112	 */
113	public function register($type, $class, $legacy = false)
114	{
115		if (!@is_subclass_of($class, $this->default[$type]))
116		{
117			return false;
118		}
119
120		$this->classes[$type] = $class;
121
122		if ($legacy)
123		{
124			$this->legacy[] = $class;
125		}
126
127		return true;
128	}
129
130	/**
131	 * Get the class registered for a type
132	 *
133	 * Where possible, use {@see create()} or {@see call()} instead
134	 *
135	 * @param string $type
136	 * @return string|null
137	 */
138	public function get_class($type)
139	{
140		if (!empty($this->classes[$type]))
141		{
142			return $this->classes[$type];
143		}
144		if (!empty($this->default[$type]))
145		{
146			return $this->default[$type];
147		}
148
149		return null;
150	}
151
152	/**
153	 * Create a new instance of a given type
154	 *
155	 * @param string $type
156	 * @param array $parameters Parameters to pass to the constructor
157	 * @return object Instance of class
158	 */
159	public function &create($type, $parameters = array())
160	{
161		$class = $this->get_class($type);
162
163		if (in_array($class, $this->legacy))
164		{
165			switch ($type)
166			{
167				case 'locator':
168					// Legacy: file, timeout, useragent, file_class, max_checked_feeds, content_type_sniffer_class
169					// Specified: file, timeout, useragent, max_checked_feeds
170					$replacement = array($this->get_class('file'), $parameters[3], $this->get_class('content_type_sniffer'));
171					array_splice($parameters, 3, 1, $replacement);
172					break;
173			}
174		}
175
176		if (!method_exists($class, '__construct'))
177		{
178			$instance = new $class;
179		}
180		else
181		{
182			$reflector = new ReflectionClass($class);
183			$instance = $reflector->newInstanceArgs($parameters);
184		}
185
186		if (method_exists($instance, 'set_registry'))
187		{
188			$instance->set_registry($this);
189		}
190		return $instance;
191	}
192
193	/**
194	 * Call a static method for a type
195	 *
196	 * @param string $type
197	 * @param string $method
198	 * @param array $parameters
199	 * @return mixed
200	 */
201	public function &call($type, $method, $parameters = array())
202	{
203		$class = $this->get_class($type);
204
205		if (in_array($class, $this->legacy))
206		{
207			switch ($type)
208			{
209				case 'Cache':
210					// For backwards compatibility with old non-static
211					// Cache::create() methods
212					if ($method === 'get_handler')
213					{
214						$result = @call_user_func_array(array($class, 'create'), $parameters);
215						return $result;
216					}
217					break;
218			}
219		}
220
221		$result = call_user_func_array(array($class, $method), $parameters);
222		return $result;
223	}
224}
225