📄 installer.php
字号:
<?php
/**
* @version $Id: installer.php 8682 2007-08-31 18:36:45Z jinx $
* @package Joomla.Framework
* @subpackage Installer
* @copyright Copyright (C) 2005 - 2007 Open Source Matters. All rights reserved.
* @license GNU/GPL, see LICENSE.php
* Joomla! is free software. This version may have been modified pursuant
* to the GNU General Public License, and as distributed it includes or
* is derivative of works licensed under the GNU General Public License or
* other free or open source software licenses.
* See COPYRIGHT.php for copyright notices and details.
*/
// Check to ensure this file is within the rest of the framework
defined('JPATH_BASE') or die();
jimport('joomla.filesystem.*');
/**
* Joomla base installer class
*
* @author Louis Landry <louis.landry@joomla.org>
* @package Joomla.Framework
* @subpackage Installer
* @since 1.5
*/
class JInstaller extends JObject
{
/**
* Array of paths needed by the installer
* @var array
*/
var $_paths = array();
/**
* The installation manifest XML object
* @var object
*/
var $_manifest = null;
/**
* True if existing files can be overwritten
* @var boolean
*/
var $_overwrite = false;
/**
* A database connector object
* @var object
*/
var $_db = null;
/**
* Associative array of package installer handlers
* @var array
*/
var $_adapters = array();
/**
* Stack of installation steps
* - Used for installation rollback
* @var array
*/
var $_stepStack = array();
/**
* The output from the install/uninstall scripts
* @var string
*/
var $message = null;
/**
* Constructor
*
* @access protected
*/
function __construct()
{
$this->_db =& JFactory::getDBO();
}
/**
* Returns a reference to the global Installer object, only creating it
* if it doesn't already exist.
*
* @static
* @return object An installer object
* @since 1.5
*/
function &getInstance()
{
static $instance;
if (!isset ($instance)) {
$instance = new JInstaller();
}
return $instance;
}
/**
* Get the allow overwrite switch
*
* @access public
* @return boolean Allow overwrite switch
* @since 1.5
*/
function getOverwrite()
{
return $this->_overwrite;
}
/**
* Set the allow overwrite switch
*
* @access public
* @param boolean $state Overwrite switch state
* @return boolean Previous value
* @since 1.5
*/
function setOverwrite($state=false)
{
$tmp = $this->_overwrite;
if ($state) {
$this->_overwrite = true;
} else {
$this->_overwrite = false;
}
return $tmp;
}
/**
* Get the database connector object
*
* @access public
* @return object Database connector object
* @since 1.5
*/
function &getDBO()
{
return $this->_db;
}
/**
* Get the installation manifest object
*
* @access public
* @return object Manifest object
* @since 1.5
*/
function &getManifest()
{
if (!is_object($this->_manifest)) {
$this->_findManifest();
}
return $this->_manifest;
}
/**
* Get an installer path by name
*
* @access public
* @param string $name Path name
* @param string $default Default value
* @return string Path
* @since 1.5
*/
function getPath($name, $default=null)
{
return (!empty($this->_paths[$name])) ? $this->_paths[$name] : $default;
}
/**
* Sets an installer path by name
*
* @access public
* @param string $name Path name
* @param string $value Path
* @return void
* @since 1.5
*/
function setPath($name, $value)
{
$this->_paths[$name] = $value;
}
/**
* Pushes a step onto the installer stack for rolling back steps
*
* @access public
* @param array $step Installer step
* @return void
* @since 1.5
*/
function pushStep($step)
{
$this->_stepStack[] = $step;
}
/**
* Set an installer adapter by name
*
* @access public
* @param string $name Adapter name
* @param object $adapter Installer adapter object
* @return boolean True if successful
* @since 1.5
*/
function setAdapter($name, $adapter=null)
{
if (!is_object($adapter)) {
// Try to load the adapter object
jimport('joomla.installer.adapters.'.strtolower($name));
$class = 'JInstaller'.ucfirst($name);
if (!class_exists($class)) {
return false;
}
$adapter = new $class($this);
$adapter->parent =& $this;
}
$this->_adapters[$name] =& $adapter;
return true;
}
/**
* Installation abort method
*
* @access public
* @param string $msg Abort message from the installer
* @param string $type Package type if defined
* @return boolean True if successful
* @since 1.5
*/
function abort($msg=null, $type=null)
{
// Initialize variables
$retval = true;
$step = array_pop($this->_stepStack);
// Raise abort warning
if ($msg) {
JError::raiseWarning(100, $msg);
}
while ($step != null)
{
switch ($step['type'])
{
case 'file' :
// remove the file
$stepval = JFile::delete($step['path']);
break;
case 'folder' :
// remove the folder
$stepval = JFolder::delete($step['path']);
break;
case 'query' :
// placeholder in case this is necessary in the future
break;
default :
if ($type && is_object($this->_adapters[$type])) {
// Build the name of the custom rollback method for the type
$method = '_rollback_'.$step['type'];
// Custom rollback method handler
if (method_exists($this->_adapters[$type], $method)) {
$stepval = $this->_adapters[$type]->$method($step);
}
}
break;
}
// Only set the return value if it is false
if ($stepval === false) {
$retval = false;
}
// Get the next step and continue
$step = array_pop($this->_stepStack);
}
return $retval;
}
/**
* Package installation method
*
* @access public
* @param string $path Path to package source folder
* @return boolean True if successful
* @since 1.5
*/
function install($path=null)
{
if ($path && JFolder::exists($path)) {
$this->setPath('source', $path);
} else {
$this->abort(JText::_('Install path does not exist'));
return false;
}
if (!$this->setupInstall()) {
$this->abort(JText::_('Unable to detect manifest file'));
return false;
}
/*
* LEGACY CHECK
*/
$root =& $this->_manifest->document;
$version = $root->attributes('version');
$rootName = $root->name();
$config = &JFactory::getConfig();
if ((version_compare($version, '1.5', '<') || $rootName == 'mosinstall') && !$config->getValue('config.legacy')) {
$this->abort(JText::_('MUSTENABLELEGACY'));
return false;
}
$type = $root->attributes('type');
// Needed for legacy reasons ... to be deprecated in next minor release
if ($type == 'mambot') {
$type = 'plugin';
}
if (is_object($this->_adapters[$type])) {
return $this->_adapters[$type]->install();
}
return false;
}
/**
* Package update method
*
* @access public
* @param string $path Path to package source folder
* @return boolean True if successful
* @since 1.5
*/
function update($path=null)
{
if ($path && JFolder::exists($path)) {
$this->setPath('source', $path);
} else {
$this->abort(JText::_('Update path does not exist'));
}
if (!$this->setupInstall()) {
return $this->abort(JText::_('Unable to detect manifest file'));
}
/*
* LEGACY CHECK
*/
$root =& $this->_manifest->document;
$version = $root->attributes('version');
$rootName = $root->name();
$config = &JFactory::getConfig();
if ((version_compare($version, '1.5', '<') || $rootName == 'mosinstall') && !$config->getValue('config.legacy')) {
return $this->abort(JText::_('MUSTENABLELEGACY'));
}
$type = $root->attributes('type');
// Needed for legacy reasons ... to be deprecated in next minor release
if ($type == 'mambot') {
$type = 'plugin';
}
if (is_object($this->_adapters[$type])) {
$this->_adapters[$type]->update();
}
}
/**
* Package uninstallation method
*
* @access public
* @param string $type Package type
* @param mixed $identifier Package identifier for adapter
* @param int $cid Application ID
* @return boolean True if successful
* @since 1.5
*/
function uninstall($type, $identifier, $cid=0)
{
if (!isset($this->_adapters[$type]) || !is_object($this->_adapters[$type])) {
if (!$this->setAdapter($type)) {
return false;
}
}
if (is_object($this->_adapters[$type])) {
$this->_adapters[$type]->uninstall($identifier, $cid);
}
}
/**
* Prepare for installation: this method sets the installation directory, finds
* and checks the installation file and verifies the installation type
*
* @access public
* @return boolean True on success
* @since 1.0
*/
function setupInstall()
{
// We need to find the installation manifest file
if (!$this->_findManifest()) {
return false;
}
// Load the adapter(s) for the install manifest
$root =& $this->_manifest->document;
$type = $root->attributes('type');
// Needed for legacy reasons ... to be deprecated in next minor release
if ($type == 'mambot') {
$type = 'plugin';
}
// Lazy load the adapter
if (!isset($this->_adapters[$type]) || !is_object($this->_adapters[$type])) {
if (!$this->setAdapter($type)) {
return false;
}
}
return true;
}
/**
* Backward compatible Method to parse through a queries element of the
* installation manifest file and take appropriate action.
*
* @access public
* @param object $element The xml node to process
* @return mixed Number of queries processed or False on error
* @since 1.5
*/
function parseQueries($element)
{
// Get the database connector object
$db = & $this->_db;
if (!is_a($element, 'JSimpleXMLElement') || !count($element->children())) {
// Either the tag does not exist or has no children therefore we return zero files processed.
return 0;
}
// Get the array of query nodes to process
$queries = $element->children();
if (count($queries) == 0) {
// No queries to process
return 0;
}
// Process each query in the $queries array (children of $tagName).
foreach ($queries as $query)
{
$db->setQuery($query->data());
if (!$db->query()) {
JError::raiseWarning(1, 'JInstaller::install: '.JText::_('SQL Error')." ".$db->stderr(true));
return false;
}
}
return (int) count($queries);
}
/**
* Method to extract the name of a discreet installation sql file from the installation manifest file.
*
* @access public
* @param object $element The xml node to process
* @param string $version The database connector to use
* @return mixed Number of queries processed or False on error
* @since 1.5
*/
function parseSQLFiles($element)
{
// Initialize variables
$queries = array();
$db = & $this->_db;
$dbDriver = strtolower($db->get('name'));
if ($dbDriver == 'mysqli') {
$dbDriver = 'mysql';
}
$dbCharset = ($db->hasUTF()) ? 'utf8' : '';
if (!is_a($element, 'JSimpleXMLElement')) {
// The tag does not exist.
return 0;
}
// Get the array of file nodes to process
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -