1: <?php
2: /*
3: File: xajaxPluginManager.inc.php
4:
5: Contains the xajax plugin manager.
6:
7: Title: xajax plugin manager
8:
9: Please see <copyright.inc.php> for a detailed description, copyright
10: and license information.
11: */
12:
13: /*
14: @package xajax
15: @version $Id: xajaxPluginManager.inc.php 362 2007-05-29 15:32:24Z calltoconstruct $
16: @copyright Copyright (c) 2005-2007 by Jared White & J. Max Wilson
17: @copyright Copyright (c) 2008-2010 by Joseph Woolley, Steffen Konerow, Jared White & J. Max Wilson
18: @license http://www.xajaxproject.org/bsd_license.txt BSD License
19: */
20:
21: //SkipAIO
22: require(dirname(__FILE__) . '/xajaxPlugin.inc.php');
23: //EndSkipAIO
24:
25: /*
26: Class: xajaxPluginManager
27: */
28: final class xajaxPluginManager
29: {
30: /*
31: Array: aRequestPlugins
32: */
33: private $aRequestPlugins;
34:
35: /*
36: Array: aResponsePlugins
37: */
38: private $aResponsePlugins;
39:
40: /*
41: Array: aConfigurable
42: */
43: private $aConfigurable;
44:
45: /*
46: Array: aRegistrars
47: */
48: private $aRegistrars;
49:
50: /*
51: Array: aProcessors
52: */
53: private $aProcessors;
54:
55: /*
56: Array: aClientScriptGenerators
57: */
58: private $aClientScriptGenerators;
59:
60: /*
61: Function: xajaxPluginManager
62:
63: Construct and initialize the one and only xajax plugin manager.
64: */
65: private function __construct()
66: {
67: $this->aRequestPlugins = array();
68: $this->aResponsePlugins = array();
69:
70: $this->aConfigurable = array();
71: $this->aRegistrars = array();
72: $this->aProcessors = array();
73: $this->aClientScriptGenerators = array();
74: }
75:
76: /*
77: Function: getInstance
78:
79: Implementation of the singleton pattern: returns the one and only instance of the
80: xajax plugin manager.
81:
82: Returns:
83:
84: object : a reference to the one and only instance of the
85: plugin manager.
86: */
87: public static function &getInstance()
88: {
89: static $obj;
90: if (!$obj) {
91: $obj = new xajaxPluginManager();
92: }
93: return $obj;
94: }
95:
96: /*
97: Function: loadPlugins
98:
99: Loads plugins from the folders specified.
100:
101: Parameters:
102: $aFolders - (array): Array of folders to check for plugins
103: */
104: public function loadPlugins($aFolders)
105: {
106: foreach ($aFolders as $sFolder) {
107: if (is_dir($sFolder))
108: if ($handle = opendir($sFolder)) {
109: while (!(false === ($sName = readdir($handle)))) {
110: $nLength = strlen($sName);
111: if (8 < $nLength) {
112: $sFileName = substr($sName, 0, $nLength - 8);
113: $sExtension = substr($sName, $nLength - 8, 8);
114: if ('.inc.php' == $sExtension) {
115: require $sFolder . '/' . $sFileName . $sExtension;
116: }
117: }
118: }
119:
120: closedir($handle);
121: }
122: }
123: }
124:
125: /*
126: Function: _insertIntoArray
127:
128: Inserts an entry into an array given the specified priority number.
129: If a plugin already exists with the given priority, the priority is
130: automatically incremented until a free spot is found. The plugin
131: is then inserted into the empty spot in the array.
132:
133: Parameters:
134:
135: $aPlugins - (array): Plugins array
136: $objPlugin - (object): A reference to an instance of a plugin.
137: $nPriority - (number): The desired priority, used to order
138: the plugins.
139:
140: */
141: private function _insertIntoArray(&$aPlugins, $objPlugin, $nPriority)
142: {
143: while (isset($aPlugins[$nPriority]))
144: $nPriority++;
145:
146: $aPlugins[$nPriority] = $objPlugin;
147: }
148:
149: /*
150: Function: registerPlugin
151:
152: Registers a plugin.
153:
154: Parameters:
155:
156: objPlugin - (object): A reference to an instance of a plugin.
157:
158: Note:
159: Below is a table for priorities and their description:
160: 0 thru 999: Plugins that are part of or extensions to the xajax core
161: 1000 thru 8999: User created plugins, typically, these plugins don't care about order
162: 9000 thru 9999: Plugins that generally need to be last or near the end of the plugin list
163: */
164: public function registerPlugin($objPlugin, $nPriority=1000)
165: {
166: if ($objPlugin instanceof xajaxRequestPlugin)
167: {
168: $this->_insertIntoArray($this->aRequestPlugins, $objPlugin, $nPriority);
169:
170: if (method_exists($objPlugin, 'register'))
171: $this->_insertIntoArray($this->aRegistrars, $objPlugin, $nPriority);
172:
173: if (method_exists($objPlugin, 'canProcessRequest'))
174: if (method_exists($objPlugin, 'processRequest'))
175: $this->_insertIntoArray($this->aProcessors, $objPlugin, $nPriority);
176: }
177: else if ( $objPlugin instanceof xajaxResponsePlugin)
178: {
179: $this->aResponsePlugins[] = $objPlugin;
180: }
181: else
182: {
183: //SkipDebug
184: $objLanguageManager = xajaxLanguageManager::getInstance();
185: trigger_error(
186: $objLanguageManager->getText('XJXPM:IPLGERR:01')
187: . get_class($objPlugin)
188: . $objLanguageManager->getText('XJXPM:IPLGERR:02')
189: , E_USER_ERROR
190: );
191: //EndSkipDebug
192: }
193:
194: if (method_exists($objPlugin, 'configure'))
195: $this->_insertIntoArray($this->aConfigurable, $objPlugin, $nPriority);
196:
197: if (method_exists($objPlugin, 'generateClientScript'))
198: $this->_insertIntoArray($this->aClientScriptGenerators, $objPlugin, $nPriority);
199: }
200:
201: /*
202: Function: canProcessRequest
203:
204: Calls each of the request plugins and determines if the
205: current request can be processed by one of them. If no processor identifies
206: the current request, then the request must be for the initial page load.
207:
208: See <xajax->canProcessRequest> for more information.
209: */
210: public function canProcessRequest()
211: {
212: $bHandled = false;
213:
214: $aKeys = array_keys($this->aProcessors);
215: sort($aKeys);
216: foreach ($aKeys as $sKey) {
217: $mResult = $this->aProcessors[$sKey]->canProcessRequest();
218: if (true === $mResult)
219: $bHandled = true;
220: else if (is_string($mResult))
221: return $mResult;
222: }
223:
224: return $bHandled;
225: }
226:
227: /*
228: Function: processRequest
229:
230: Calls each of the request plugins to request that they process the
231: current request. If the plugin processes the request, it will
232: return true.
233: */
234: public function processRequest()
235: {
236: $bHandled = false;
237:
238: $aKeys = array_keys($this->aProcessors);
239: sort($aKeys);
240: foreach ($aKeys as $sKey) {
241: $mResult = $this->aProcessors[$sKey]->processRequest();
242: if (true === $mResult)
243: $bHandled = true;
244: else if (is_string($mResult))
245: return $mResult;
246: }
247:
248: return $bHandled;
249: }
250:
251: /*
252: Function: configure
253:
254: Call each of the request plugins passing along the configuration
255: setting specified.
256:
257: Parameters:
258:
259: sName - (string): The name of the configuration setting to set.
260: mValue - (mixed): The value to be set.
261: */
262: public function configure($sName, $mValue)
263: {
264: $aKeys = array_keys($this->aConfigurable);
265: sort($aKeys);
266: foreach ($aKeys as $sKey)
267: $this->aConfigurable[$sKey]->configure($sName, $mValue);
268: }
269:
270: /*
271: Function: register
272:
273: Call each of the request plugins and give them the opportunity to
274: handle the registration of the specified function, event or callable object.
275:
276: Parameters:
277: $aArgs - (array) :
278: */
279: public function register($aArgs)
280: {
281: $aKeys = array_keys($this->aRegistrars);
282: sort($aKeys);
283: foreach ($aKeys as $sKey)
284: {
285: $objPlugin = $this->aRegistrars[$sKey];
286: $mResult = $objPlugin->register($aArgs);
287: if ( $mResult instanceof xajaxRequest )
288: return $mResult;
289: if (is_array($mResult))
290: return $mResult;
291: if (is_bool($mResult))
292: if (true === $mResult)
293: return true;
294: }
295: //SkipDebug
296: $objLanguageManager = xajaxLanguageManager::getInstance();
297: trigger_error(
298: $objLanguageManager->getText('XJXPM:MRMERR:01')
299: . print_r($aArgs, true)
300: , E_USER_ERROR
301: );
302: //EndSkipDebug
303: }
304:
305: /*
306: Function: generateClientScript
307:
308: Call each of the request and response plugins giving them the
309: opportunity to output some javascript to the page being generated. This
310: is called only when the page is being loaded initially. This is not
311: called when processing a request.
312: */
313: public function generateClientScript()
314: {
315: $aKeys = array_keys($this->aClientScriptGenerators);
316: sort($aKeys);
317: foreach ($aKeys as $sKey)
318: $this->aClientScriptGenerators[$sKey]->generateClientScript();
319: }
320:
321: /*
322: Function: getResponsePlugin
323:
324: Locate the specified response plugin by name and return
325: a reference to it if one exists.
326:
327: Parameters:
328: $sName - (string): Name of the plugin.
329:
330: Returns:
331: mixed : Returns plugin or false if not found.
332: */
333: public function getResponsePlugin($sName)
334: {
335: $aKeys = array_keys($this->aResponsePlugins);
336: sort($aKeys);
337: foreach ($aKeys as $sKey)
338: if ( $this->aResponsePlugins[$sKey] instanceof $sName )
339: return $this->aResponsePlugins[$sKey];
340: $bFailure = false;
341: return $bFailure;
342: }
343:
344: /*
345: Function: getRequestPlugin
346:
347: Locate the specified response plugin by name and return
348: a reference to it if one exists.
349:
350: Parameters:
351: $sName - (string): Name of the plugin.
352:
353: Returns:
354: mixed : Returns plugin or false if not found.
355: */
356: public function getRequestPlugin($sName)
357: {
358: $aKeys = array_keys($this->aRequestPlugins);
359: sort($aKeys);
360: foreach ($aKeys as $sKey) {
361: if ( get_class($this->aRequestPlugins[$sKey]) == $sName ) {
362: return $this->aRequestPlugins[$sKey];
363: }
364: }
365:
366:
367: $bFailure = false;
368: return $bFailure;
369: }
370: }
371: