File: 0.01.0a/core/PluginManager.php (View as HTML)

  1: <?php 
  2: /* -------------------------------------------------------------
  3: This file is part of FreeDESK
  4: 
  5: FreeDESK is (C) Copyright 2012 David Cutting
  6: 
  7: FreeDESK is free software: you can redistribute it and/or modify
  8: it under the terms of the GNU General Public License as published by
  9: the Free Software Foundation, either version 3 of the License, or
 10: (at your option) any later version.
 11: 
 12: FreeDESK is distributed in the hope that it will be useful,
 13: but WITHOUT ANY WARRANTY; without even the implied warranty of
 14: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 15: GNU General Public License for more details.
 16: 
 17: You should have received a copy of the GNU General Public License
 18: along with FreeDESK.  If not, see www.gnu.org/licenses
 19: 
 20: For more information see www.purplepixie.org/freedesk/
 21: -------------------------------------------------------------- */
 22: 
 23: /**
 24:  * Plugin class - holds all associated data with generic plugins
 25: **/
 26: class Plugin
 27: {
 28: 	/**
 29: 	 * Name
 30: 	**/
 31: 	var $name;
 32: 	/**
 33: 	 * Version (maj.min only)
 34: 	**/
 35: 	var $version;
 36: 	/**
 37: 	 * Type
 38: 	**/
 39: 	var $type="";
 40: 	/**
 41: 	 * Sub-Type
 42: 	**/
 43: 	var $subtype="";
 44: 	/**
 45: 	 * Class Name
 46: 	**/
 47: 	var $classname="";
 48: 	/**
 49: 	 * Constructor
 50: 	 * @param string $name Name of plugin (optional, default "")
 51: 	 * @param string $version Version of plugin (optional, default "")
 52: 	 * @param string $type Type of plugin (optional, default "")
 53: 	 * @param string $subtype Subtype of plugin (optional, default "")
 54: 	 * @param string $classname Class name of pluging (optional, default "")
 55: 	**/
 56: 	function Plugin($name="",$version="",$type="",$subtype="",$classname="")
 57: 	{
 58: 		$this->name=$name;
 59: 		$this->version=$version;
 60: 		$this->type=$type;
 61: 		$this->subtype=$subtype;
 62: 		$this->classname=$classname;
 63: 	}
 64: }
 65: 
 66: /**
 67:  * Plugin Manager - Handles all run-time-enabled plugins
 68: **/
 69: class PluginManager
 70: {
 71: 	/**
 72: 	 * FreeDESK instance
 73: 	**/
 74: 	private $DESK = null;
 75: 	
 76: 	/**
 77: 	 * Array of registered plugins and components
 78: 	**/
 79: 	private $plugins = array();
 80: 	
 81: 	/**
 82: 	 * Array of plugin modules
 83: 	**/
 84: 	private $pims = array();
 85: 	
 86: 	/**
 87: 	 * PIM Counter
 88: 	**/
 89: 	private $pim_counter = 0;
 90: 	
 91: 	/**
 92: 	 * Array of simple pages
 93: 	**/
 94: 	private $pages = array();
 95: 	
 96: 	/**
 97: 	 * Array of PIM pages
 98: 	**/
 99: 	private $pim_pages = array();
100: 	
101: 	/**
102: 	 * Array of scripts
103: 	**/
104: 	private $scripts = array();
105: 	
106: 	/**
107: 	 * Array of CSS
108: 	**/
109: 	private $css = array();
110: 	
111: 	/**
112: 	 * Array of API modes for PIMS
113: 	**/
114: 	private $pim_api = array();
115: 	
116: 	/**
117: 	 * Array of events registered for PIMS
118: 	**/
119: 	private $pim_events = array();
120: 	
121: 	/**
122: 	 * Installed PIM List
123: 	**/
124: 	private $installed_pims = null;
125: 	
126: 	/**
127: 	 * Constructor
128: 	 * @param mixed $freeDESK FreeDESK instance
129: 	**/
130: 	function PluginManager(&$freeDESK)
131: 	{
132: 		$this->DESK = &$freeDESK;
133: 		$this->DESK->PermissionManager->Register("sysadmin_plugins",false);
134: 	}
135: 	
136: 	/**
137: 	 * Register a plugin
138: 	 * @param mixed $plugin Plugin to register
139: 	**/
140: 	function Register(&$plugin)
141: 	{
142: 		$this->plugins[]=$plugin;
143: 	}
144: 	
145: 	/**
146: 	 * Register a page for display
147: 	 * @param string $id Page identifier
148: 	 * @param string $page Page path (fully-qualified)
149: 	 * @param bool $autoperm Automatically register permission for the page (optional, default true)
150: 	**/
151: 	function RegisterPage($id, $page, $autoperm=true)
152: 	{
153: 		$this->pages[$id]=$page;
154: 		if ($autoperm)
155: 			$this->DESK->PermissionManager->Register("page.".$id,false);
156: 	}
157: 	
158: 	/**
159: 	 * Register a PIM page for use in a PIM
160: 	 * @param string $page Page identifier
161: 	 * @param int $id PIM internal ID
162: 	**/
163: 	function RegisterPIMPage($page, $id)
164: 	{
165: 		$this->pim_pages[$page] = $id;
166: 	}
167: 	
168: 	/**
169: 	 * Register a script for inclusion
170: 	 * @param string $script Web path to script
171: 	**/
172: 	function RegisterScript($script)
173: 	{
174: 		$this->scripts[] = $script;
175: 	}
176: 	
177: 	/**
178: 	 * Register CSS for inclusion (after Skin CSS)
179: 	 * @param string $css Web path to CSS
180: 	**/
181: 	function RegisterCSS($css)
182: 	{
183: 		$this->css[]=$css;
184: 	}
185: 	
186: 	/**
187: 	 * Register an API call for inclusion
188: 	 * @param string $mode API Mode
189: 	 * @param int $id Plugin ID
190: 	**/
191: 	function RegisterPIMAPI($mode, $id)
192: 	{
193: 		$this->pim_api[$mode] = $id;
194: 	}
195: 	
196: 	/**
197: 	 * Perform an API call
198: 	 * @param string $mode API Call
199: 	 * @return bool False if no API call made true if called
200: 	**/
201: 	function API($mode)
202: 	{
203: 		if (isset($this->pim_api[$mode]))
204: 			if (isset($this->pims[$this->pim_api[$mode]]))
205: 			{
206: 				$this->pims[$this->pim_api[$mode]]->API($mode);
207: 				return true;
208: 			}
209: 		return false;
210: 	}
211: 	
212: 	/**
213: 	 * Register an event call to a PIM for calling
214: 	 * @param string $event Event call
215: 	 * @param int $id Plugin ID
216: 	**/
217: 	function RegisterPIMEvent($event, $id)
218: 	{
219: 		if (!isset($this->pim_events[$event]))
220: 			$this->pim_events[$event]=array();
221: 		$this->pim_events[$event][] = $id;
222: 	}
223: 	
224: 	/**
225: 	 * Call an event
226: 	 * @param string $event Event Call
227: 	 * @param array &$data Event data
228: 	**/
229: 	function Event($event, &$data)
230: 	{
231: 		if (isset($this->pim_events[$event]))
232: 		{
233: 			foreach($this->pim_events[$event] as $id)
234: 			{
235: 				$this->pims[$id]->Event($event, &$data);
236: 			}
237: 		}
238: 	}
239: 	
240: 	/**
241: 	 * Get list of scripts
242: 	 * @return array List of scripts
243: 	**/
244: 	function GetScripts()
245: 	{
246: 		return $this->scripts;
247: 	}
248: 	
249: 	/**
250: 	 * Get list of CSS
251: 	 * @return array List of CSS
252: 	**/
253: 	function GetCSS()
254: 	{
255: 		return $this->css;
256: 	}
257: 	
258: 	/**
259: 	 * Get a page by ID
260: 	 * @param string $id Page identifier
261: 	 * @return mixed Page path (fully-qualified) or bool false on failure
262: 	**/
263: 	function GetPage($id)
264: 	{
265: 		if (isset($this->pages[$id]))
266: 			return $this->pages[$id];
267: 		return false;
268: 	}
269: 	
270: 	/**
271: 	 * Call a PIM Page
272: 	 * @param $id Page identifier
273: 	 * @return bool true if exists and called or false if not
274: 	**/
275: 	function PIMPage($id)
276: 	{
277: 		if (isset($this->pim_pages[$id]))
278: 		{
279: 			$pimid = $this->pim_pages[$id];
280: 			if (isset($this->pims[$pimid]))
281: 			{
282: 				$this->pims[$pimid]->Page($id);
283: 				return true;
284: 			}
285: 		}
286: 		return false;
287: 	}
288: 	
289: 	/**
290: 	 * Return all plugins
291: 	 * @return array Array of all plugins
292: 	**/
293: 	function GetAll()
294: 	{
295: 		return $this->plugins;
296: 	}
297: 	
298: 	/**
299: 	 * Return plugins by type
300: 	 * @param string $type Plugin Type
301: 	 * @return array List of plugins
302: 	**/
303: 	function GetType($type)
304: 	{
305: 		$output=array();
306: 		foreach($this->plugins as $plugin)
307: 		{
308: 			if ($plugin->type == $type)
309: 				$output[]=$plugin;
310: 		}
311: 		return $output;
312: 	}
313: 	
314: 	/**
315: 	 * Load a PIM
316: 	 * @param string $pim Plugin Module Directory
317: 	**/
318: 	function LoadPIM($pim)
319: 	{
320: 		$filepath = $this->DESK->BaseDir."plugins/".$pim."/";
321: 		$webpath = $this->DESK->BaseDir."plugins/".$pim."/";
322: 		$id = $this->pim_counter++;
323: 		
324: 		include($filepath.$pim.".php");
325: 		
326: 		$this->pims[$id] = new $pim($this->DESK, $filepath, $webpath, $id);
327: 		$this->pims[$id]->Start();
328: 	}
329: 	
330: 	/**
331: 	 * Load installed PIM list
332: 	**/
333: 	private function LoadInstalledPIMS()
334: 	{
335: 		$q="SELECT * FROM ".$this->DESK->Database->Table("plugins");
336: 		$r=$this->DESK->Database->Query($q);
337: 		
338: 		$this->installed_pims = array();
339: 		
340: 		while ($row = $this->DESK->Database->FetchAssoc($r))
341: 		{
342: 			$this->installed_pims[$row['plugin']] = array(
343: 				"plugin" => $row['plugin'],
344: 				"id" => $row['pluginid'],
345: 				"active" => ($row['active'] == 1) ? true : false );
346: 		}
347: 		
348: 		$this->DESK->Database->Free($r);
349: 	}
350: 	
351: 	/**
352: 	 * Load PIMs (load and start activated PIMs)
353: 	**/
354: 	function LoadPIMS()
355: 	{
356: 		if ($this->installed_pims == null)
357: 			$this->LoadInstalledPIMS();
358: 		foreach($this->installed_pims as $plugin => $data)
359: 		{
360: 			if ($data['active'])
361: 				$this->LoadPIM($plugin);
362: 		}
363: 	}
364: 	
365: 	/**
366: 	 * Get a list of PIMS
367: 	 * @return array list of PIMS
368: 	**/
369: 	function ListPIMS()
370: 	{
371: 		if ($this->installed_pims == null)
372: 			$this->LoadInstalledPIMS();
373: 		
374: 		$out = array();
375: 			
376: 		$handle = opendir("plugins/");
377: 		
378: 		if ($handle !== false)
379: 		{
380: 			while(false !== ($file = readdir($handle)))
381: 			{
382: 				if ($file != "." && $file != ".." && is_dir("plugins/".$file))
383: 				{
384: 				
385: 					if (file_exists("plugins/".$file."/".$file.".php"))
386: 					{
387: 						$out[$file] = array(
388: 							"installed" => isset($this->installed_pims[$file]) ? true : false,
389: 							"data" => isset($this->installed_pims[$file]) ? $this->installed_pims[$file] : array()
390: 							);
391: 					}
392: 				}
393: 			}
394: 		
395: 			closedir($handle);
396: 		}
397: 		return $out;
398: 	}
399: 	
400: 	/**
401: 	 * Install PIM
402: 	 * @param string $plugin Plugin Name
403: 	**/
404: 	function InstallPIM($plugin)
405: 	{
406: 		$path = "plugins/".$plugin."/";
407: 		$file = $path.$plugin.".php";
408: 		include_once($file);
409: 		
410: 		$inst = new $plugin($this->DESK, $path, $path, 9999);
411: 		
412: 		$inst->Install();
413: 		
414: 		$q="INSERT INTO ".$this->DESK->Database->Table("plugins")."(".$this->DESK->Database->Field("plugin").",".$this->DESK->Database->Field("active").")";
415: 		$q.=" VALUES(".$this->DESK->Database->SafeQuote($plugin).",".$this->DESK->Database->Safe("0").")";
416: 		
417: 		$this->DESK->Database->Query($q);
418: 	}
419: 	
420: 	/**
421: 	 * Set a PIM as active or not
422: 	 * @param int $id ID (pluginid in database)
423: 	 * @param bool $active Active flag
424: 	**/
425: 	function ActivatePIM($id, $active)
426: 	{
427: 	
428: 		$q="SELECT * FROM ".$this->DESK->Database->Table("plugins")." WHERE ".$this->DESK->Database->Field("pluginid")."=".$this->DESK->Database->Safe($id);
429: 		$r=$this->DESK->Database->Query($q);
430: 		
431: 		if ($row=$this->DESK->Database->FetchAssoc($r))
432: 		{
433: 			$plugin = $row['plugin'];
434: 			$path = "plugins/".$plugin."/";
435: 			$file = $path.$plugin.".php";
436: 			include_once($file);
437: 		
438: 			$inst = new $plugin($this->DESK, $path, $path, 9999);
439: 			
440: 			if ($active)
441: 				$inst->Activate();
442: 			else
443: 				$inst->Deactivate();
444: 		
445: 			$q="UPDATE ".$this->DESK->Database->Table("plugins")." SET ".$this->DESK->Database->Field("active")."=";
446: 			if ($active)
447: 				$q.="1";
448: 			else
449: 				$q.="0";
450: 			$q.=" WHERE ".$this->DESK->Database->Field("pluginid")."=".$this->DESK->Database->Safe($id);
451: 		
452: 			$this->DESK->Database->Query($q);
453: 		}
454: 		
455: 		$this->DESK->Database->Free($r);
456: 	}
457: 		
458: 		
459: 	/**
460: 	 * Uninstall a PIM
461: 	 * @param int $id ID (pluginid in database)
462: 	**/
463: 	function UninstallPIM($id)
464: 	{
465: 	
466: 		$q="SELECT * FROM ".$this->DESK->Database->Table("plugins")." WHERE ".$this->DESK->Database->Field("pluginid")."=".$this->DESK->Database->Safe($id);
467: 		$r=$this->DESK->Database->Query($q);
468: 		
469: 		if ($row=$this->DESK->Database->FetchAssoc($r))
470: 		{
471: 			$plugin = $row['plugin'];
472: 			$path = "plugins/".$plugin."/";
473: 			$file = $path.$plugin.".php";
474: 			include_once($file);
475: 		
476: 			$inst = new $plugin($this->DESK, $path, $path, 9999);
477: 			
478: 			$inst->Uninstall();
479: 		
480: 			$q="DELETE FROM ".$this->DESK->Database->Table("plugins")." WHERE ".$this->DESK->Database->Field("pluginid")."=".$this->DESK->Database->Safe($id);
481: 		
482: 			$this->DESK->Database->Query($q);
483: 		}
484: 		
485: 		$this->DESK->Database->Free($r);
486: 	}
487: 	
488: 	/**
489: 	 * Call BuildMenu on all PIMs
490: 	**/
491: 	function BuildMenu()
492: 	{
493: 		foreach($this->pims as $id => $pim)
494: 			$pim->BuildMenu();
495: 	}
496: 	
497: }
498: 
499: 
500: ?>
501: