<?php
/**
 * @version		$Id: helper.php 20196 2011-01-09 02:40:25Z ian $
 * @package		Joomla.Framework
 * @subpackage	Plugin
 * @copyright	Copyright (C) 2005 - 2011 Open Source Matters, Inc. All rights reserved.
 * @license		GNU General Public License version 2 or later; see LICENSE.txt
 */

// No direct access.
defined('JPATH_BASE') or die;

/**
 * Plugin helper class
 *
 * @package		Joomla.Framework
 * @subpackage	Plugin
 * @since		1.5
 */
abstract class JPluginHelper
{
	/**
	 * Get the plugin data of a specific type if no specific plugin is specified
	 * otherwise only the specific plugin data is returned.
	 *
	 * @param	string	$type	The plugin type, relates to the sub-directory in the plugins directory.
	 * @param	string	$plugin	The plugin name.
	 *
	 * @return	mixed	An array of plugin data objects, or a plugin data object.
	 * @since	1.5
	 */
	public static function getPlugin($type, $plugin = null)
	{
		$result		= array();
		$plugins	= self::_load();

		// Find the correct plugin(s) to return.
		if (!$plugin) {
			foreach($plugins as $p) {
				// Is this the right plugin?
				if ($p->type == $type) {
					$result[] = $p;
				}
			}
		} else {
			foreach($plugins as $p) {
				// Is this plugin in the right group?
				if ($p->type == $type && $p->name == $plugin) {
					$result = $p;
					break;
				}
			}
		}

		return $result;
	}

	/**
	 * Checks if a plugin is enabled.
	 *
	 * @param	string	$type	The plugin type, relates to the sub-directory in the plugins directory.
	 * @param	string	$plugin	The plugin name.
	 *
	 * @return	boolean
	 * @since	1.5
	 */
	public static function isEnabled($type, $plugin = null)
	{
		$result = self::getPlugin($type, $plugin);
		return (!empty($result));
	}

	/**
	 * Loads all the plugin files for a particular type if no specific plugin is specified
	 * otherwise only the specific pugin is loaded.
	 *
	 * @param	string		$type	The plugin type, relates to the sub-directory in the plugins directory.
	 * @param	string		$plugin	The plugin name.
	 * @param	boolean		$autocreate
	 * @param	JDispatcher	$dispatcher	Optionally allows the plugin to use a different dispatcher.
	 *
	 * @return	boolean		True on success.
	 * @since	1.5
	 */
	public static function importPlugin($type, $plugin = null, $autocreate = true, $dispatcher = null)
	{
		static $loaded = Array();

		// check for the default args, if so we can optimise cheaply
		$defaults = false;
		if (is_null($plugin) && $autocreate == true && is_null($dispatcher)) {
			$defaults = true;
		}

		if (!isset($loaded[$type]) || !$defaults) {
			$results = null;

			// Load the plugins from the database.
			$plugins = self::_load();

			// Get the specified plugin(s).
			for ($i = 0, $t = count($plugins); $i < $t; $i++) {
				if ($plugins[$i]->type == $type && ($plugins[$i]->name == $plugin ||  $plugin === null)) {
					self::_import($plugins[$i], $autocreate, $dispatcher);
					$results = true;
				}
 			}

			// bail out early if we're not using default args
			if(!$defaults) {
				return $results;
			}
			$loaded[$type] = $results;
		}

		return $loaded[$type];
	}

	/**
	 * Loads the plugin file.
	 *
	 * @param	JPlugin		$plugin		The plugin.
	 * @param	boolean		$autocreate
	 * @param	JDispatcher	$dispatcher	Optionally allows the plugin to use a different dispatcher.
	 *
	 * @return	boolean		True on success.
	 * @since	1.5
	 */
	protected static function _import(&$plugin, $autocreate = true, $dispatcher = null)
	{
		static $paths = array();

		$plugin->type = preg_replace('/[^A-Z0-9_\.-]/i', '', $plugin->type);
		$plugin->name = preg_replace('/[^A-Z0-9_\.-]/i', '', $plugin->name);

		$legacypath	= JPATH_PLUGINS.DS.$plugin->type.DS.$plugin->name.'.php';
		$path = JPATH_PLUGINS.DS.$plugin->type.DS.$plugin->name.DS.$plugin->name.'.php';

		if (!isset( $paths[$path] ) || !isset($paths[$legacypath])) {
			$pathExists = file_exists($path);
			if ($pathExists || file_exists($legacypath)) {
				$path = $pathExists ? $path : $legacypath;

				jimport('joomla.plugin.plugin');
				if (!isset($paths[$path])) {
					require_once $path;
				}
				$paths[$path] = true;

				if ($autocreate) {
					// Makes sure we have an event dispatcher
					if (!is_object($dispatcher)) {
						$dispatcher = JDispatcher::getInstance();
					}

					$className = 'plg'.$plugin->type.$plugin->name;
					if (class_exists($className)) {
						// Load the plugin from the database.
						$plugin = self::getPlugin($plugin->type, $plugin->name);

						// Instantiate and register the plugin.
						new $className($dispatcher, (array)($plugin));
					}
				}
			} else {
				$paths[$path] = false;
			}
		}
	}

	/**
	 * Loads the published plugins.
	 *
	 * @return	void
	 * @since	1.5
	 */
	protected static function _load()
	{
		static $plugins;

		if (isset($plugins)) {
			return $plugins;
		}

		$user	= JFactory::getUser();
		$cache 	= JFactory::getCache('com_plugins', '');

		$levels = implode(',', $user->getAuthorisedViewLevels());

		if (!$plugins = $cache->get($levels)) {
			$db		= JFactory::getDbo();
			$query	= $db->getQuery(true);

			$query->select('folder AS type, element AS name, params')
				->from('#__extensions')
				->where('enabled >= 1')
				->where('type ='.$db->Quote('plugin'))
				->where('state >= 0')
				->where('access IN ('.$levels.')')
				->order('ordering');

			$plugins = $db->setQuery($query)
				->loadObjectList();

			if ($error = $db->getErrorMsg()) {
				JError::raiseWarning(500, $error);
				return false;
			}

			$cache->store($plugins, $levels);
		}

		return $plugins;
	}
}