代码之家  ›  专栏  ›  技术社区  ›  Valentin Despa

组件安装:DB函数报告无错误

  •  1
  • Valentin Despa  · 技术社区  · 10 年前

    在尝试安装组件时,我遇到了此错误。

    Component Install: DB function reports no errors

    Error installing component

    3 回复  |  直到 10 年前
        1
  •  3
  •   Valentin Despa    10 年前

    当尝试安装使用SQL更新的组件时,我经常在测试系统上遇到此错误,并且在安装错误时会导致第一次出现错误(即使与SQL无关,清单文件中缺少这样的文件)。

    以下是如何通过手动卸载组件来解决此问题的一些步骤,因为从扩展管理器安装可能会失败。

    查找分机的id (您也可以找到多个条目)

    SELECT * 
    FROM  `#__extensions` 
    WHERE  `name` LIKE  '%myextensionname%'
    LIMIT 0 , 30
    

    从中删除 #__schemas 扩展的条目 哪里 extension_id 是上一个找到的id。同时删除非现有扩展的所有条目:

    删除所有资产 对于您的分机:

    SELECT * 
    FROM  `#__assets` 
    WHERE  `name` LIKE  '%myextensionname%'
    LIMIT 0 , 30
    

    删除所有菜单项:

    选择* 来自 #__menu 哪里 link LIKE“%myextensionname%” 限制0,30

    重新安装。

        2
  •  1
  •   Elin    10 年前

    未经测试,但这是我会使用的一般想法。

    <?php
    /**
     * A JApplicationCli application built on the Joomla Platform
     *
     * To run this place it in the cli folder of your Joomla CMS installation (or adjust the references).
     *
     * @package    Joomla.CleanupFailedInsall
     * @copyright  Copyright (C) 2013 Open Source Matters. All rights reserved.
     * @license    GNU General Public License version 2 or later; see LICENSE
     */
    
    
     /*
      * This application cleans up database leftovers from a failed install
      * 
      * To run from the command line type 
      *     php cleanupfailedinstall.php -e='extensionname'
      */
    
    
    if (!defined('_JEXEC'))
    {
        // Initialize Joomla framework
        define('_JEXEC', 1);
    }
    
    @ini_set('zend.ze1_compatibility_mode', '0');
    error_reporting(E_ALL);
    ini_set('display_errors', 1);
    
    // Load system defines
    if (file_exists(dirname(__DIR__) . '/defines.php'))
    {
        require_once dirname(__DIR__) . '/defines.php';
    }
    
    if (!defined('JPATH_BASE'))
    {
        define('JPATH_BASE', dirname(__DIR__));
    }
    
    if (!defined('_JDEFINES'))
    {
        require_once JPATH_BASE . '/includes/defines.php';
    }
    
    // Get the framework.
    require_once JPATH_LIBRARIES . '/import.php';
    // Get the framework.
    require_once JPATH_LIBRARIES . '/import.legacy.php';
    
    // Bootstrap the CMS libraries.
    require_once JPATH_LIBRARIES . '/cms.php';
    
    // Import the configuration.
    require_once JPATH_CONFIGURATION . '/configuration.php';
    
    // Uncomment this if you want to log
    /*
        // Include the JLog class.
        jimport('joomla.log.log');
    
        // Add the logger.
        JLog::addLogger(
    
        // Pass an array of configuration options
        array(
            // Set the name of the log file
            'text_file' => 'test.log.php',
            // (optional) you can change the directory
            'text_file_path' => 'logs'
         )
        );
    
        // start logging...
        JLog::add('Starting to log');   
    */
    
    /**
     * Cleanup Failed Install
     *
     * @package  Joomla.Shell
     *
     * @since    1.0
     */
    class CleanupFailedInstall extends JApplicationCli
    {
        public function __construct()
        {
    
            // Note, this will throw an exception if there is an error
            // System configuration.
            $config = new JConfig;
    
            // Creating the database connection.
            $this->db = JDatabase::getInstance(
                array(
                    'driver' => $config->dbtype,
                    'host' => $config->host,
                    'user' => $config->user,
                    'password' => $config->password,
                    'database' => $config->db,
                    'prefix' => $config->dbprefix,
                )
            );
    
    
            // Call the parent __construct method so it bootstraps the application class.
            parent::__construct();
            require_once JPATH_CONFIGURATION . '/configuration.php';
        }
    
        /**
         * Entry point for the script
         *
         * @return  void
         *
         * @since   1.0
         */
        public function doExecute()
        {
            // Long args
            $extensionname = $this->input->get('extensionname', null,'STRING');
    
            // Short args
            if (!$extensionname)
            {
                $extensionname = $this->input->get('e', null, 'STRING');
            }
    
            $extensionTable = new JTableExtension();
            $extensionId = $extensionTable->find(array('name', $extensionname));
    
            // This block taken from the platform component install adapter with minor moifications
            // Remove the schema version
            $query = $db->getQuery(true)
                ->delete('#__schemas')
                ->where('extension_id = ' . $extensionId);
            $db->setQuery($query);
            $db->execute();
    
            // Remove the component container in the assets table.
            $asset = JTable::getInstance('Asset');
    
            if ($asset->loadByName($extensionname))
            {
                $asset->delete();
            }
    
            $extenstionTable->delete($extensionId);
                $this->removeAdminMenus($extensionId);
    
            // Remove categories for this component
            $query->clear()
                ->delete('#__categories')
                ->where('extension=' . $db->quote($exensionname), 'OR')
                ->where('extension LIKE ' . $db->quote($extensionname . '.%'));
            $db->setQuery($query);
            $db->execute();
    
            // Clobber any possible pending updates
            $update = JTable::getInstance('update');
            $uid = $update->find(array('element' => $row->element, 'type' => 'component', 'client_id' => 1, 'folder' => ''));
    
            if ($uid)
            {
                $update->delete($uid);
            }
    
        }
    
        /**
         * Taken from the core installer component adapter
         * Method to remove admin menu references to a component
         *
         * @param   object  &$row  Component table object.
         *
         * @return  boolean  True if successful.
         *
         * @since   3.1
         */
        protected function _removeAdminMenus($extensionId)
        {
            $db = JFactory::getDbo();
            $table = JTable::getInstance('menu');
    
    
            // Get the ids of the menu items
            $query = $db->getQuery(true)
                ->select('id')
                ->from('#__menu')
                ->where($db->quoteName('client_id') . ' = 1')
                ->where($db->quoteName('component_id') . ' = ' . (int) $extensionId);
    
            $db->setQuery($query);
    
            $ids = $db->loadColumn();
    
            // Check for error
            if (!empty($ids))
            {
                // Iterate the items to delete each one.
                foreach ($ids as $menuid)
                {
                    if (!$table->delete((int) $menuid))
                    {
                        $this->setError($table->getError());
    
                        return false;
                    }
                }
                // Rebuild the whole tree
                $table->rebuild();
            }
    
            return true;
        }
    }
    
    JApplicationCli::getInstance('CleanupFailedInstall')->execute();
    
        3
  •  0
  •   Valentin Despa    10 年前

    这是@Elin建议的无错误/无错版本(以防有人想进一步讨论)。这个解决方案对我来说不起作用,但我认为它有其道理。

    <?php
    /**
     * A JApplicationCli application built on the Joomla Platform
     *
     * To run this place it in the cli folder of your Joomla CMS installation (or adjust the references).
     *
     * @package    Joomla.CleanupFailedInsall
     * @copyright  Copyright (C) 2013 Open Source Matters. All rights reserved.
     * @license    GNU General Public License version 2 or later; see LICENSE
     */
    
    
     /*
      * This application cleans up database leftovers from a failed install
      * 
      * To run from the command line type 
      *     php cleanupfailedinstall.php -e='extensionname'
      */
    
    
    if (!defined('_JEXEC'))
    {
        // Initialize Joomla framework
        define('_JEXEC', 1);
    }
    
    @ini_set('zend.ze1_compatibility_mode', '0');
    error_reporting(E_ALL);
    ini_set('display_errors', 1);
    
    // Load system defines
    if (file_exists(dirname(__DIR__) . '/defines.php'))
    {
        require_once dirname(__DIR__) . '/defines.php';
    }
    
    if (!defined('JPATH_BASE'))
    {
        define('JPATH_BASE', dirname(__DIR__));
    }
    
    if (!defined('_JDEFINES'))
    {
        require_once JPATH_BASE . '/includes/defines.php';
    }
    
    // Get the framework.
    require_once JPATH_LIBRARIES . '/import.php';
    // Get the framework.
    //require_once JPATH_LIBRARIES . '/import.legacy.php';
    
    // Bootstrap the CMS libraries.
    require_once JPATH_LIBRARIES . '/cms.php';
    
    // Import the configuration.
    require_once JPATH_CONFIGURATION . '/configuration.php';
    
    // Uncomment this if you want to log
    /*
        // Include the JLog class.
        jimport('joomla.log.log');
    
        // Add the logger.
        JLog::addLogger(
    
        // Pass an array of configuration options
        array(
            // Set the name of the log file
            'text_file' => 'test.log.php',
            // (optional) you can change the directory
            'text_file_path' => 'logs'
         )
        );
    
        // start logging...
        JLog::add('Starting to log');   
    */
    
    /**
     * Cleanup Failed Install
     *
     * @package  Joomla.Shell
     *
     * @since    1.0
     */
    class CleanupFailedInstall extends JApplicationCli
    {
        public function __construct()
        {
    
            // Note, this will throw an exception if there is an error
            // System configuration.
            $config = new JConfig;
    
            // Creating the database connection.
            $this->db = JDatabase::getInstance(
                array(
                    'driver' => $config->dbtype,
                    'host' => $config->host,
                    'user' => $config->user,
                    'password' => $config->password,
                    'database' => $config->db,
                    'prefix' => $config->dbprefix,
                )
            );
    
            // Call the parent __construct method so it bootstraps the application class.
            parent::__construct();
            require_once JPATH_CONFIGURATION . '/configuration.php';
        }
    
        /**
         * Entry point for the script
         *
         * @return  void
         *
         * @since   1.0
         */
        public function execute()
        {
    
            // Long args
            $extensionname = $this->input->get('extensionname', 'urlaubsrechner', 'STRING');
    
            // Short args
            if (!$extensionname)
            {
                $extensionname = $this->input->get('e', null, 'STRING');
            }
    
            require_once JPATH_LIBRARIES . '/joomla/database/table/extension.php';
            $extensionTable = new JTableExtension($this->db);
            $extensionId = $extensionTable->find(array('name' => $extensionname));
    
            if (! $extensionId)
            {
                throw new Exception('Could not find extension with name: ' . $extensionname);
            }
    
            // This block taken from the platform component install adapter with minor modifications
            // Remove the schema version
            $query = $this->db->getQuery(true)
                ->delete('#__schemas')
                ->where('extension_id = ' . $extensionId);
            $this->db->setQuery($query);
            $this->db->execute();
    
            // Remove the component container in the assets table.
            $asset = JTable::getInstance('Asset');
    
            if ($asset->loadByName($extensionname))
            {
                $asset->delete();
            }
    
            $extensionTable->delete($extensionId);
                $this->_removeAdminMenus($extensionId);
    
            // Remove categories for this component
            $query->clear()
                ->delete('#__categories')
                ->where('extension=' . $this->db->quote($extensionname), 'OR')
                ->where('extension LIKE ' . $this->db->quote($extensionname . '.%'));
            $this->db->setQuery($query);
            $this->db->execute();
    
            // Clobber any possible pending updates
            $update = JTable::getInstance('update');
            $uid = $update->find(array('element' => $extensionTable->element, 'type' => 'component', 'client_id' => 1, 'folder' => ''));
    
            if ($uid)
            {
                $update->delete($uid);
            }
    
        }
    
        /**
         * Taken from the core installer component adapter
         * Method to remove admin menu references to a component
         *
         * @param   object  &$row  Component table object.
         *
         * @return  boolean  True if successful.
         *
         * @since   3.1
         */
        protected function _removeAdminMenus($extensionId)
        {
            $db = JFactory::getDbo();
            $table = JTable::getInstance('menu');
    
    
            // Get the ids of the menu items
            $query = $db->getQuery(true)
                ->select('id')
                ->from('#__menu')
                ->where($db->quoteName('client_id') . ' = 1')
                ->where($db->quoteName('component_id') . ' = ' . (int) $extensionId);
    
            $db->setQuery($query);
    
            $ids = $db->loadColumn();
    
            // Check for error
            if (!empty($ids))
            {
                // Iterate the items to delete each one.
                foreach ($ids as $menuid)
                {
                    if (!$table->delete((int) $menuid))
                    {
                        $this->setError($table->getError());
    
                        return false;
                    }
                }
                // Rebuild the whole tree
                $table->rebuild();
            }
    
            return true;
        }
    }
    
    JApplicationCli::getInstance('CleanupFailedInstall')->execute();