Your IP : 216.73.216.130


Current Path : /home/magalijoj/www/blog/inc/core/
Upload File :
Current File : /home/magalijoj/www/blog/inc/core/class.dc.modules.php

<?php
# ***** BEGIN LICENSE BLOCK *****
# This file is part of DotClear.
# Copyright (c) 2005 Olivier Meunier and contributors. All rights
# reserved.
#
# DotClear is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
# 
# DotClear is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public License
# along with DotClear; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
#
# ***** END LICENSE BLOCK *****

/**
@ingroup DC_CORE
@brief Modules handler

Provides an object to handle modules (themes or plugins). An instance of this
class is provided by dcCore $plugins property and used for plugins.
*/
class dcModules
{
	private $path;
	private $ns;
	private $modules = array();
	
	private $id;
	private $mroot;
	
	# Inclusion variables
	private static $superglobals = array('GLOBALS','_SERVER','_GET','_POST','_COOKIE','_FILES','_ENV','_REQUEST','_SESSION');
	private static $_k;
	private static $_n;
	
	public $core;	///< <b>dcCore</b>	dcCore instance
	
	/**
	Object constructor.
	
	@param	core		<b>dcCore</b>	dcCore instance
	*/
	public function __construct(&$core)
	{
		$this->core =& $core;
	}
	
	/**
	Loads modules. <var>$path</var> could be a separated list of paths
	(path separator depends on your OS).
	
	<var>$ns</var> indicates if an additionnal file needs to be loaded on plugin
	load, value could be:
	- admin (loads module's _admin.php)
	- public (loads module's _public.php)
	- xmlrpc (loads module's _xmlrpc.php)
	
	<var>$lang</var> indicates if we need to load a lang file on plugin
	loading.
	*/
	public function loadModules($path,$ns=null,$lang=null)
	{
		$this->path = explode(PATH_SEPARATOR,$path);
		$this->ns = $ns;
		
		foreach ($this->path as $root)
		{
			if (!is_dir($root) || !is_readable($root)) {
				continue;
			}
			
			if (substr($root,-1) != '/') {
				$root .= '/';
			}
			
			if (($d = @dir($root)) === false) {
				continue;
			}
			
			while (($entry = $d->read()) !== false)
			{
				$full_entry = $root.'/'.$entry;
				
				if ($entry != '.' && $entry != '..' && is_dir($full_entry)
				&& file_exists($full_entry.'/_define.php')
				&& !file_exists($full_entry.'/_disabled'))
				{
					$this->id = $entry;
					$this->mroot = $full_entry;
					require $full_entry.'/_define.php';
					$this->id = null;
					$this->mroot = null;
				}
			}
			$d->close();
		}
		
		# Sort plugins
		uasort($this->modules,array($this,'sortModules'));
		
		# Load translation, _prepend and ns_file
		foreach ($this->modules as $id => $m)
		{
			if (file_exists($m['root'].'/_prepend.php'))
			{
				$r = require $m['root'].'/_prepend.php';
				
				# If _prepend.php file returns null (ie. it has a void return statement)
				if (is_null($r)) {
					continue;
				}
				unset($r);
			}
			
			$this->loadModuleL10N($id,$lang,'main');
			$this->loadNsFile($id,$ns);
		}
	}
	
	/**
	This method registers a module in modules list. You should use this to
	register a new module.
	
	<var>$permissions</var> is a comma separated list of permissions for your
	module. If <var>$permissions</var> is null, only super admin has access to
	this module.
	
	<var>$priority</var> is an integer. Modules are sorted by priority and name.
	Lowest priority comes first.
	
	@param	name			<b>string</b>		Module name
	@param	desc			<b>string</b>		Module description
	@param	author		<b>string</b>		Module author name
	@param	version		<b>string</b>		Module version
	@param	permissions	<b>string</b>		Module permissions
	@param	priority		<b>integer</b>		Module priority
	*/
	public function registerModule($name,$desc,$author,$version,$permissions=null,$priority=1000)
	{
		if ($this->ns == 'admin') {
			if ($permissions == '' && !$this->core->auth->isSuperAdmin()) {
				return;
			} elseif (!$this->core->auth->check($permissions,$this->core->blog->id)) {
				return;
			}
		}
		
		if ($this->id) {
			$this->modules[$this->id] = array(
			'root' => $this->mroot,
			'name' => $name,
			'desc' => $desc,
			'author' => $author,
			'version' => $version,
			'permissions' => $permissions,
			'priority' => $priority === null ? 1000 : (integer) $priority
			);
		}
	}
	
	/**
	This method installs all modules having a _install file.
	
	@see dcModules::installModule
	*/
	public function installModules()
	{
		$res = array('success'=>array(),'failure'=>array());
		foreach ($this->modules as $id => &$m)
		{
			$i = $this->installModule($id,$msg);
			if ($i === true) {
				$res['success'][$id] = true;
			} elseif ($i === false) {
				$res['failure'][$id] = $msg;
			}
		}
		
		return $res;
	}
	
	/**
	This method installs module with ID <var>$id</var> and having a _install
	file. This file should throw exception on failure or true if it installs
	successfully.
	
	<var>$msg</var> is an out parameter that handle installer message.
	
	@param	id		<b>string</b>		Module ID
	@param	msg		<b>string</b>		Module installer message
	@return	<b>boolean</b>
	*/
	public function installModule($id,&$msg)
	{
		try {
			$i = $this->loadModuleFile($this->modules[$id]['root'].'/_install.php');
			if ($i === true) {
				return true;
			}
		} catch (Exception $e) {
			$msg = $e->getMessage();
			return false;
		}
		
		return null;
	}
	
	/**
	This method will search for file <var>$file</var> in language
	<var>$lang</var> for module <var>$id</var>.
	
	<var>$file</var> should not have any extension.
	
	@param	id		<b>string</b>		Module ID
	@param	lang		<b>string</b>		Language code
	@param	file		<b>string</b>		File name (without extension)
	*/
	public function loadModuleL10N($id,$lang,$file)
	{
		if (!$lang || !isset($this->modules[$id])) {
			return;
		}
		
		$lfile = $this->modules[$id]['root'].'/locales/%s/%s';
		if (l10n::set(sprintf($lfile,$lang,$file)) === false && $lang != 'en') {
			l10n::set(sprintf($lfile,'en',$file));
		}
	}
	
	/**
	Returns all modules associative array or only one module if <var>$id</var>
	is present.
	
	@param	id		<b>string</b>		Optionnal module ID
	@return	<b>array</b>
	*/
	public function getModules($id=null)
	{
		if ($id && isset($this->modules[$id])) {
			return $this->modules[$id];
		}
		return $this->modules;
	}
	
	/**
	Returns true if the module with ID <var>$id</var> exists.
	
	@param	id		<b>string</b>		Module ID
	@return	<b>boolean</b>
	*/
	public function moduleExists($id)
	{
		return isset($this->modules[$id]);
	}
	
	/**
	Returns root path for module with ID <var>$id</var>.
	
	@param	id		<b>string</b>		Module ID
	@return	<b>string</b>
	*/
	public function moduleRoot($id)
	{
		return $this->moduleInfo($id,'root');
	}
	
	/**
	Returns a module information that could be:
	- root
	- name
	- desc
	- author
	- version
	- permissions
	- priority
	
	@param	id		<b>string</b>		Module ID
	@param	info		<b>string</b>		Information to retrieve
	@return	<b>string</b>
	*/
	public function moduleInfo($id,$info)
	{
		return isset($this->modules[$id][$info]) ? $this->modules[$id][$info] : null;
	}
	
	/**
	Loads namespace <var>$ns</var> specific files for all modules.
	
	@param	ns		<b>string</b>		Namespace name
	*/
	public function loadNsFiles($ns=null)
	{
		foreach ($this->modules as $k => $v) {
			$this->loadNsFile($k,$ns);
		}
	}
	
	/**
	Loads namespace <var>$ns</var> specific file for module with ID
	<var>$id</var>
	
	@param	id		<b>string</b>		Module ID
	@param	ns		<b>string</b>		Namespace name
	*/
	public function loadNsFile($id,$ns=null)
	{
		switch ($ns) {
			case 'admin':
				$this->loadModuleFile($this->modules[$id]['root'].'/_admin.php');
				break;
			case 'public':
				$this->loadModuleFile($this->modules[$id]['root'].'/_public.php');
				break;
			case 'xmlrpc':
				$this->loadModuleFile($this->modules[$id]['root'].'/_xmlrpc.php');
				break;
		}
	}
	
	private function loadModuleFile($________)
	{
		if (!file_exists($________)) {
			return;
		}
		
		self::$_k = array_keys($GLOBALS);
		
		foreach (self::$_k as self::$_n) {
			if (!in_array(self::$_n,self::$superglobals)) {
				global ${self::$_n};
			}
		}
		
		return require $________;
	}
	
	private function sortModules($a,$b)
	{
		if ($a['priority'] == $b['priority']) {
			return strcasecmp($a['name'],$b['name']);
		}
		
		return ($a['priority'] < $b['priority']) ? -1 : 1;
	}
}
?>