Пример #1
0
 /**
  * Install Modules
  *
  * @return void
  */
 public function install_modules()
 {
     //-----------------------------------------
     // INIT
     //-----------------------------------------
     $previous = $_REQUEST['previous'];
     //-----------------------------------------
     // Fetch next 'un
     //-----------------------------------------
     $next = IPSSetUp::fetchNextApplication($previous, '{app}_modules.xml', $this->settings['gb_char_set']);
     //-----------------------------------------
     // Install SYSTEM Templates
     //-----------------------------------------
     if ($next['key']) {
         $output[] = $next['title'] . ": Обновление модулей";
         $_PATH = IPSLib::getAppDir($next['key']) . '/xml/';
         if (is_file($_PATH . $next['key'] . '_modules.xml')) {
             require_once IPS_ROOT_PATH . 'applications/core/modules_admin/applications/applications.php';
             /*noLibHook*/
             $apps = new admin_core_applications_applications();
             $apps->makeRegistryShortcuts($this->registry);
             $this->request['_app'] = $next['key'];
             $apps->moduleImport('', 1, FALSE);
         }
         //-----------------------------------------
         // Done.. so get some more!
         //-----------------------------------------
         $this->_finishStep($output, "Обновление: Модули", 'upgrade&do=modules&previous=' . $next['key']);
     } else {
         //-----------------------------------------
         // Next...
         //-----------------------------------------
         $output[] = "Все модули обновлены";
         $this->_finishStep($output, "Обновление: Модули", 'upgrade&do=settings');
     }
 }
    /**
     * Public install hook so we can use it in the installer and elsewhere
     *
     * @access	public
     * @param	string		XML data
     * @param	boolean		Add message to output->global_message
     * @param	boolean		Allow skins to recache
     * @param	int			Install enabled
     * @return	void
     */
    public function installHook($content, $addMessage = FALSE, $allowSkinRecache = TRUE, $enabled = 1)
    {
        //-----------------------------------------
        // Hooks directory writable?
        //-----------------------------------------
        if (!is_writable(IPS_HOOKS_PATH)) {
            if (!$addMessage) {
                return false;
            }
            $this->registry->output->showError($this->lang->words['h_dir_notwritable'], 111159);
        }
        //-----------------------------------------
        // Got our hooks?
        //-----------------------------------------
        if (!is_array($this->hooks) or !count($this->hooks)) {
            $this->DB->build(array('select' => '*', 'from' => 'core_hooks'));
            $this->DB->execute();
            while ($r = $this->DB->fetch()) {
                $this->hooks[$r['hook_key']] = $r;
            }
        }
        //-----------------------------------------
        // Get xml mah-do-dah
        //-----------------------------------------
        require_once IPS_KERNEL_PATH . 'classXML.php';
        $xml = new classXML(IPS_DOC_CHAR_SET);
        //-----------------------------------------
        // Unpack the datafile
        //-----------------------------------------
        $xml->loadXML($content);
        foreach ($xml->fetchElements('config') as $data) {
            $config = $xml->fetchElementsFromRecord($data);
            if (!count($config)) {
                $this->registry->output->showError($this->lang->words['h_xmlwrong'], 1111);
            }
        }
        //-----------------------------------------
        // Temp
        //-----------------------------------------
        $tempExtraData = unserialize($config['hook_extra_data']);
        //-----------------------------------------
        // Set config
        //-----------------------------------------
        $config = array('hook_name' => $config['hook_name'], 'hook_desc' => $config['hook_desc'], 'hook_author' => $config['hook_author'], 'hook_email' => $config['hook_email'], 'hook_website' => $config['hook_website'], 'hook_update_check' => $config['hook_update_check'], 'hook_requirements' => $config['hook_requirements'], 'hook_version_human' => $config['hook_version_human'], 'hook_version_long' => $config['hook_version_long'], 'hook_key' => $config['hook_key'], 'hook_enabled' => $enabled, 'hook_updated' => time());
        $extra_data = array();
        //-----------------------------------------
        // Set files
        //-----------------------------------------
        $files = array();
        foreach ($xml->fetchElements('hookfiles') as $node) {
            foreach ($xml->fetchElements('file', $node) as $_file) {
                $file = $xml->fetchElementsFromRecord($_file);
                if ($file['hook_type']) {
                    $files[] = array('hook_file_real' => $file['hook_file_real'], 'hook_type' => $file['hook_type'], 'hook_classname' => $file['hook_classname'], 'hook_data' => $file['hook_data'], 'hooks_source' => $file['hooks_source']);
                }
            }
        }
        //-----------------------------------------
        // Set the custom script
        //-----------------------------------------
        $custom = array();
        foreach ($xml->fetchElements('hookextras_custom') as $node) {
            foreach ($xml->fetchElements('file', $node) as $_file) {
                $file = $xml->fetchElementsFromRecord($_file);
                if (count($file)) {
                    $custom = array('filename' => $file['filename'], 'source' => $file['source']);
                }
            }
        }
        //-----------------------------------------
        // Set the settings
        //-----------------------------------------
        $settings = array();
        $settingGroups = array();
        foreach ($xml->fetchElements('hookextras_settings') as $node) {
            foreach ($xml->fetchElements('setting', $node) as $_setting) {
                $setting = $xml->fetchElementsFromRecord($_setting);
                if ($setting['conf_is_title'] == 1) {
                    $settingGroups[] = array('conf_title_title' => $setting['conf_title_title'], 'conf_title_desc' => $setting['conf_title_desc'], 'conf_title_noshow' => $setting['conf_title_noshow'], 'conf_title_keyword' => $setting['conf_title_keyword'], 'conf_title_app' => $setting['conf_title_app'], 'conf_title_tab' => $setting['conf_title_tab']);
                } else {
                    $settings[] = array('conf_title' => $setting['conf_title'], 'conf_description' => $setting['conf_description'], 'conf_group' => $setting['conf_group'], 'conf_type' => $setting['conf_type'], 'conf_key' => $setting['conf_key'], 'conf_default' => $setting['conf_default'], 'conf_extra' => $setting['conf_extra'], 'conf_evalphp' => $setting['conf_evalphp'], 'conf_protected' => $setting['conf_protected'], 'conf_position' => $setting['conf_position'], 'conf_start_group' => $setting['conf_start_group'], 'conf_end_group' => $setting['conf_end_group'], 'conf_add_cache' => $setting['conf_add_cache'], 'conf_title_keyword' => $setting['conf_title_keyword']);
                }
            }
        }
        //-----------------------------------------
        // Set the lang bits
        //-----------------------------------------
        $language = array();
        foreach ($xml->fetchElements('hookextras_language') as $node) {
            foreach ($xml->fetchElements('language', $node) as $_langbit) {
                $langbit = $xml->fetchElementsFromRecord($_langbit);
                $language[] = array('word_app' => $langbit['word_app'], 'word_pack' => $langbit['word_pack'], 'word_key' => $langbit['word_key'], 'word_default' => $langbit['word_default'], 'word_custom' => $langbit['word_custom'], 'word_js' => $langbit['word_js']);
            }
        }
        //-----------------------------------------
        // Set the modules
        //-----------------------------------------
        $modules = array();
        foreach ($xml->fetchElements('hookextras_modules') as $node) {
            foreach ($xml->fetchElements('module', $node) as $_module) {
                $module = $xml->fetchElementsFromRecord($_module);
                $modules[] = array('sys_module_title' => $module['sys_module_title'], 'sys_module_application' => $module['sys_module_application'], 'sys_module_key' => $module['sys_module_key'], 'sys_module_description' => $module['sys_module_description'], 'sys_module_version' => $module['sys_module_version'], 'sys_module_parent' => $module['sys_module_parent'], 'sys_module_protected' => $module['sys_module_protected'], 'sys_module_visible' => $module['sys_module_visible'], 'sys_module_tables' => $module['sys_module_tables'], 'sys_module_hooks' => $module['sys_module_hooks'], 'sys_module_position' => $module['sys_module_position'], 'sys_module_admin' => $module['sys_module_admin']);
            }
        }
        //-----------------------------------------
        // Set the help files
        //-----------------------------------------
        $help = array();
        foreach ($xml->fetchElements('hookextras_help') as $node) {
            foreach ($xml->fetchElements('help', $node) as $_helpfile) {
                $helpfile = $xml->fetchElementsFromRecord($_helpfile);
                $help[] = array('title' => $helpfile['title'], 'text' => $helpfile['text'], 'description' => $helpfile['description'], 'position' => $helpfile['position']);
            }
        }
        //-----------------------------------------
        // Set the templates
        //-----------------------------------------
        $templates = array();
        foreach ($xml->fetchElements('hookextras_templates') as $node) {
            foreach ($xml->fetchElements('templates', $node) as $_template) {
                $template = $xml->fetchElementsFromRecord($_template);
                $templates[] = array('template_set_id' => 0, 'template_group' => $template['template_group'], 'template_content' => $template['template_content'], 'template_name' => $template['template_name'], 'template_data' => $template['template_data'], 'template_updated' => $template['template_updated'], 'template_removable' => $template['template_removable'], 'template_added_to' => $template['template_added_to'], 'template_user_added' => 1, 'template_user_edited' => 0);
            }
        }
        //-----------------------------------------
        // Set the tasks
        //-----------------------------------------
        $tasks = array();
        foreach ($xml->fetchElements('hookextras_tasks') as $node) {
            foreach ($xml->fetchElements('tasks', $node) as $_task) {
                $task = $xml->fetchElementsFromRecord($_task);
                $tasks[] = array('task_title' => $task['task_title'], 'task_file' => $task['task_file'], 'task_week_day' => $task['task_week_day'], 'task_month_day' => $task['task_month_day'], 'task_hour' => $task['task_hour'], 'task_minute' => $task['task_minute'], 'task_cronkey' => $task['task_cronkey'], 'task_log' => $task['task_log'], 'task_description' => $task['task_description'], 'task_enabled' => $task['task_enabled'], 'task_key' => $task['task_key'], 'task_safemode' => $task['task_safemode'], 'task_locked' => $task['task_locked'], 'task_application' => $task['task_application']);
            }
        }
        //-----------------------------------------
        // Set the database changes
        //-----------------------------------------
        $database = array('create' => array(), 'alter' => array(), 'update' => array(), 'insert' => array());
        foreach ($xml->fetchElements('hookextras_database_create') as $node) {
            foreach ($xml->fetchElements('create', $node) as $_table) {
                $table = $xml->fetchElementsFromRecord($_table);
                $database['create'][] = array('name' => $table['name'], 'fields' => $table['fields'], 'tabletype' => $table['tabletype']);
            }
        }
        foreach ($xml->fetchElements('hookextras_database_alter') as $node) {
            foreach ($xml->fetchElements('alter', $node) as $_table) {
                $table = $xml->fetchElementsFromRecord($_table);
                $database['alter'][] = array('altertype' => $table['altertype'], 'table' => $table['table'], 'field' => $table['field'], 'newfield' => $table['newfield'], 'fieldtype' => $table['fieldtype'], 'default' => $table['default']);
            }
        }
        foreach ($xml->fetchElements('hookextras_database_update') as $node) {
            foreach ($xml->fetchElements('update', $node) as $_table) {
                $table = $xml->fetchElementsFromRecord($_table);
                $database['update'][] = array('table' => $table['table'], 'field' => $table['field'], 'newvalue' => $table['newvalue'], 'oldvalue' => $table['oldvalue'], 'where' => $table['where']);
            }
        }
        foreach ($xml->fetchElements('hookextras_database_insert') as $node) {
            foreach ($xml->fetchElements('insert', $node) as $_table) {
                $table = $xml->fetchElementsFromRecord($_table);
                $database['insert'][] = array('table' => $table['table'], 'updates' => $table['updates'], 'fordelete' => $table['fordelete']);
            }
        }
        //-----------------------------------------
        // Set some vars for display tallies
        //-----------------------------------------
        $filesInserted = 0;
        $settingGroupsInserted = 0;
        $settingsInserted = 0;
        $settingsUpdated = 0;
        $languageInserted = 0;
        $languageUpdated = 0;
        $modulesInserted = 0;
        $modulesUpdated = 0;
        $helpInserted = 0;
        $helpUpdated = 0;
        $templatesInserted = 0;
        $templatesUpdated = 0;
        $templateHooks = 0;
        $tasksInserted = 0;
        $tasksUpdated = 0;
        $createQueries = 0;
        $alterQueries = 0;
        $updateQueries = 0;
        $insertQueries = 0;
        //-----------------------------------------
        // Need to recache skins?
        //-----------------------------------------
        foreach ($files as $_f) {
            if ($_f['hook_type'] and $_f['hook_type'] == 'templateHooks') {
                $templateHooks++;
            }
        }
        //-----------------------------------------
        // Insert/update DB records
        //-----------------------------------------
        if ($this->hooks[$config['hook_key']]['hook_id']) {
            //-----------------------------------------
            // Don't change enabled/disabled status
            //-----------------------------------------
            unset($config['hook_enabled']);
            $this->DB->update('core_hooks', $config, 'hook_id=' . $this->hooks[$config['hook_key']]['hook_id']);
            $hook_id = $this->hooks[$config['hook_key']]['hook_id'];
            $extra_data = unserialize($this->hooks[$config['hook_key']]['hook_extra_data']);
        } else {
            $config['hook_installed'] = time();
            $this->hook[$config['hook_key']] = $config;
            $this->DB->insert('core_hooks', $config);
            $hook_id = $this->DB->getInsertId();
            $this->hook[$config['hook_key']]['hook_id'] = $hook_id;
            $extra_data['display'] = $tempExtraData['display'];
        }
        if (count($files)) {
            //-----------------------------------------
            // If we are updating, remove old files
            //-----------------------------------------
            if ($this->hooks[$config['hook_key']]['hook_id']) {
                $this->DB->build(array('select' => 'hook_file_id, hook_file_stored', 'from' => 'core_hooks_files', 'where' => 'hook_hook_id=' . $this->hooks[$config['hook_key']]['hook_id']));
                $outer = $this->DB->execute();
                while ($r = $this->DB->fetch($outer)) {
                    @unlink(IPS_HOOKS_PATH . $r['hook_file_stored']);
                    $this->DB->delete('core_hooks_files', 'hook_file_id=' . $r['hook_file_id']);
                }
            }
            foreach ($files as $file) {
                //-----------------------------------------
                // Store new files
                //-----------------------------------------
                $filename = $file['hook_classname'] . '_' . md5(uniqid(microtime(), true)) . '.php';
                file_put_contents(IPS_HOOKS_PATH . $filename, $file['hooks_source']);
                chmod(IPS_HOOKS_PATH . $filename, 0777);
                $file['hook_file_stored'] = $filename;
                $file['hook_hook_id'] = $hook_id;
                $this->DB->insert('core_hooks_files', $file);
                $filesInserted++;
            }
        }
        //-----------------------------------------
        // Put custom install/uninstall file
        //-----------------------------------------
        if ($custom['source'] and $custom['filename']) {
            file_put_contents(IPS_HOOKS_PATH . "install_" . $custom['filename'], $custom['source']);
        }
        //-----------------------------------------
        // (1) Settings
        //-----------------------------------------
        if (count($settingGroups) or count($settings)) {
            $setting_groups = array();
            $this->DB->build(array('select' => '*', 'from' => 'core_sys_settings_titles', 'order' => 'conf_title_title'));
            $this->DB->execute();
            while ($r = $this->DB->fetch()) {
                $setting_groups[$r['conf_title_id']] = $r;
                $setting_groups_by_key[$r['conf_title_keyword']] = $r;
            }
            //-----------------------------------------
            // Get current settings.
            //-----------------------------------------
            $this->DB->build(array('select' => 'conf_id, conf_key', 'from' => 'core_sys_conf_settings', 'order' => 'conf_id'));
            $this->DB->execute();
            while ($r = $this->DB->fetch()) {
                $cur_settings[$r['conf_key']] = $r['conf_id'];
            }
        }
        if (count($settingGroups)) {
            $need_to_update = array();
            foreach ($settingGroups as $data) {
                if ($data['conf_title_title'] and $data['conf_title_keyword']) {
                    //-----------------------------------------
                    // Get ID based on key
                    //-----------------------------------------
                    $conf_id = $setting_groups_by_key[$data['conf_title_keyword']]['conf_title_id'];
                    $save = array('conf_title_title' => $data['conf_title_title'], 'conf_title_desc' => $data['conf_title_desc'], 'conf_title_keyword' => $data['conf_title_keyword'], 'conf_title_app' => $data['conf_title_app'], 'conf_title_tab' => $data['conf_title_tab'], 'conf_title_noshow' => $data['conf_title_noshow']);
                    //-----------------------------------------
                    // Not got a row, insert first!
                    //-----------------------------------------
                    if (!$conf_id) {
                        $this->DB->insert('core_sys_settings_titles', $save);
                        $conf_id = $this->DB->getInsertId();
                        $settingGroupsInserted++;
                        $extra_data['settingGroups'][] = $conf_id;
                    } else {
                        //-----------------------------------------
                        // Update...
                        //-----------------------------------------
                        $this->DB->update('core_sys_settings_titles', $save, 'conf_title_id=' . $conf_id);
                    }
                    //-----------------------------------------
                    // Update settings cache
                    //-----------------------------------------
                    $save['conf_title_id'] = $conf_id;
                    $setting_groups_by_key[$save['conf_title_keyword']] = $save;
                    $setting_groups[$save['conf_title_id']] = $save;
                    //-----------------------------------------
                    // Set need update...
                    //-----------------------------------------
                    $need_update[] = $conf_id;
                }
            }
        }
        if (count($settings)) {
            foreach ($settings as $idx => $data) {
                $data['conf_group'] = $setting_groups_by_key[$data['conf_title_keyword']]['conf_title_id'];
                //-----------------------------------------
                // Remove from array
                //-----------------------------------------
                unset($data['conf_title_keyword']);
                if ($cur_settings[$data['conf_key']]) {
                    $this->DB->update('core_sys_conf_settings', $data, 'conf_id=' . $cur_settings[$data['conf_key']]);
                    $settingsUpdated++;
                } else {
                    $this->DB->insert('core_sys_conf_settings', $data);
                    $settingsInserted++;
                    $conf_id = $this->DB->getInsertId();
                    $extra_data['settings'][] = $conf_id;
                }
            }
        }
        //-----------------------------------------
        // Update group counts...
        //-----------------------------------------
        if (count($need_update)) {
            foreach ($need_update as $i => $idx) {
                $conf = $this->DB->buildAndFetch(array('select' => 'count(*) as count', 'from' => 'core_sys_conf_settings', 'where' => 'conf_group=' . $idx));
                $count = intval($conf['count']);
                $this->DB->update('core_sys_settings_titles', array('conf_title_count' => $count), 'conf_title_id=' . $idx);
            }
        }
        if (count($settingGroups) or count($settings)) {
            $this->cache->rebuildCache('settings', 'global');
        }
        //-----------------------------------------
        // (2) Languages
        //-----------------------------------------
        if (count($language)) {
            $langPacks = array();
            $this->DB->build(array('select' => 'lang_id', 'from' => 'core_sys_lang'));
            $this->DB->execute();
            while ($r = $this->DB->fetch()) {
                $langPacks[] = $r['lang_id'];
            }
            foreach ($language as $langbit) {
                foreach ($langPacks as $lang_id) {
                    $langbit['lang_id'] = $lang_id;
                    // See if it exists
                    $cnt = $this->DB->buildAndFetch(array('select' => 'word_id', 'from' => 'core_sys_lang_words', 'where' => "lang_id={$lang_id} AND word_app='{$langbit['word_app']}' AND word_key='{$langbit['word_key']}' AND word_pack='{$langbit['word_pack']}'"));
                    if ($cnt['word_id']) {
                        $this->DB->update('core_sys_lang_words', $langbit, 'word_id=' . $cnt['word_id']);
                        $languageUpdated++;
                    } else {
                        $this->DB->insert('core_sys_lang_words', $langbit);
                        $languageInserted++;
                        $word_id = $this->DB->getInsertId();
                        $extra_data['language'][$langbit['word_pack']][] = $langbit['word_key'];
                    }
                }
            }
            require_once IPSLib::getAppDir('core') . '/modules_admin/languages/manage_languages.php';
            $langLib = new admin_core_languages_manage_languages($this->registry);
            $langLib->makeRegistryShortcuts($this->registry);
            foreach ($langPacks as $langId) {
                $langLib->cacheToDisk($langId);
            }
        }
        //-----------------------------------------
        // (3) Modules
        //-----------------------------------------
        if (count($modules)) {
            //-----------------------------------------
            // Get current modules
            //-----------------------------------------
            $this->DB->build(array('select' => '*', 'from' => 'core_sys_module', 'order' => 'sys_module_id'));
            $this->DB->execute();
            while ($r = $this->DB->fetch()) {
                $cur_modules[$r['sys_module_application']][$r['sys_module_key']] = $r['sys_module_id'];
            }
            foreach ($modules as $module) {
                //-----------------------------------------
                // Insert or update?
                //-----------------------------------------
                if ($cur_modules[$module['sys_module_application']][$module['sys_module_key']]) {
                    $this->DB->update('core_sys_module', $module, "sys_module_id=" . $cur_modules[$module['sys_module_application']][$module['sys_module_key']]);
                    $modulesUpdated++;
                } else {
                    $this->DB->insert('core_sys_module', $module);
                    $modulesInserted++;
                    $module_id = $this->DB->getInsertId();
                    $extra_data['modules'][] = $module_id;
                }
            }
            require_once IPSLib::getAppDir('core') . '/modules_admin/applications/applications.php';
            $moduleLib = new admin_core_applications_applications($this->registry);
            $moduleLib->makeRegistryShortcuts($this->registry);
            $moduleLib->moduleRecache();
            $moduleLib->applicationsMenuDataRecache();
        }
        //-----------------------------------------
        // (4) Help Files
        //-----------------------------------------
        if (count($help)) {
            $keys = array();
            $this->DB->build(array('select' => 'title', 'from' => 'faq'));
            $this->DB->execute();
            while ($r = $this->DB->fetch()) {
                $keys[] = $r['title'];
            }
            foreach ($help as $entry) {
                if (in_array($entry['title'], $keys)) {
                    $this->DB->update('faq', $entry, "title='{$entry['title']}'");
                    $helpUpdated++;
                } else {
                    $this->DB->insert('faq', $entry);
                    $helpInserted++;
                    $help_id = $this->DB->getInsertId();
                    $extra_data['help'][] = $help_id;
                }
            }
        }
        //-----------------------------------------
        // (6) Templates
        //-----------------------------------------
        if (count($templates)) {
            $bits = array();
            $this->DB->build(array('select' => 'template_name,template_group', 'from' => 'skin_templates', 'where' => 'template_set_id=0'));
            $this->DB->execute();
            while ($r = $this->DB->fetch()) {
                $bits[$r['template_group']][] = $r['template_name'];
            }
            foreach ($templates as $template) {
                if (is_array($bits[$template['template_group']]) and in_array($template['template_name'], $bits[$template['template_group']])) {
                    $this->DB->update('skin_templates', $template, "template_group='{$template['template_group']}' AND template_name='{$template['template_name']}'");
                    $templatesUpdated++;
                } else {
                    $this->DB->insert('skin_templates', $template);
                    $templatesInserted++;
                    $template_id = $this->DB->getInsertId();
                    $extra_data['templates'][$template['template_group']][] = $template['template_name'];
                }
            }
        }
        //-----------------------------------------
        // (7) Tasks
        //-----------------------------------------
        if (count($tasks)) {
            $keys = array();
            $this->DB->build(array('select' => 'task_key', 'from' => 'task_manager'));
            $this->DB->execute();
            while ($r = $this->DB->fetch()) {
                $keys[] = $r['task_key'];
            }
            foreach ($tasks as $entry) {
                if (in_array($entry['task_key'], $keys)) {
                    $this->DB->update('task_manager', $entry, "task_key='{$entry['task_key']}'");
                    $tasksUpdated++;
                } else {
                    $this->DB->insert('task_manager', $entry);
                    $tasksInserted++;
                    $task_id = $this->DB->getInsertId();
                    $extra_data['tasks'][] = $task_id;
                }
            }
        }
        //-----------------------------------------
        // (8) Create new tables
        //-----------------------------------------
        if (count($database['create'])) {
            foreach ($database['create'] as $create) {
                $query = "CREATE TABLE {$create['name']} (\n\t\t\t\t\t\t\t{$create['fields']}\n\t\t\t\t\t\t\t)";
                if ($tabletype) {
                    $query .= " TYPE=" . $create['tabletype'];
                }
                //-----------------------------------------
                // Fix prefix
                //-----------------------------------------
                $query = preg_replace("#^CREATE TABLE(?:\\s+?)?(\\S+?)#s", "CREATE TABLE " . $this->settings['sql_tbl_prefix'] . "\\1", $query);
                $this->DB->return_die = true;
                $this->DB->query($query);
                $this->DB->return_die = false;
                $createQueries++;
                $extra_data['database']['create'][] = $create;
            }
        }
        //-----------------------------------------
        // (9) Alter tables
        //-----------------------------------------
        if (count($database['alter'])) {
            foreach ($database['alter'] as $alter) {
                $this->DB->return_die = true;
                switch ($alter['altertype']) {
                    case 'remove':
                        $this->DB->dropField($alter['table'], $alter['field']);
                        break;
                    case 'add':
                        $this->DB->addField($alter['table'], $alter['field'], $alter['fieldtype'], $alter['default']);
                        break;
                    case 'change':
                        $this->DB->changeField($alter['table'], $alter['field'], $alter['newfield'], $alter['fieldtype'], $alter['default']);
                        break;
                }
                $this->DB->return_die = false;
                $alterQueries++;
                $extra_data['database']['alter'][] = $alter;
            }
        }
        //-----------------------------------------
        // (10) Run update queries
        //-----------------------------------------
        if (count($database['update'])) {
            foreach ($database['update'] as $update) {
                $this->DB->return_die = true;
                $this->DB->update($update['table'], array($update['field'] => $update['newvalue']), html_entity_decode($update['where'], ENT_QUOTES));
                $this->DB->return_die = false;
                $updateQueries++;
                $extra_data['database']['update'][] = $update;
            }
        }
        //-----------------------------------------
        // (11) Run insert queries
        //-----------------------------------------
        if (!$this->hooks[$config['hook_key']]['hook_id']) {
            if (count($database['insert'])) {
                foreach ($database['insert'] as $insert) {
                    $fields = array();
                    $content = explode(',', $insert['updates']);
                    foreach ($content as $value) {
                        list($field, $toInsert) = explode('=', $value);
                        $fields[$field] = $toInsert;
                    }
                    $this->DB->return_die = true;
                    $this->DB->insert($insert['table'], $fields);
                    $this->DB->return_die = false;
                    $insertQueries++;
                    $extra_data['database']['insert'][] = $insert;
                }
            }
        }
        if ($custom['filename'] and file_exists(IPS_HOOKS_PATH . 'install_' . $custom['filename'])) {
            require_once IPS_HOOKS_PATH . 'install_' . $custom['filename'];
            $classname = str_replace('.php', '', $custom['filename']);
            if (class_exists($classname)) {
                $install = new $classname($this->registry);
                if (method_exists($install, 'install')) {
                    $install->install();
                }
            }
        }
        if (count($extra_data)) {
            $this->DB->update('core_hooks', array('hook_extra_data' => serialize($extra_data)), 'hook_id=' . $hook_id);
        }
        //print_r($config);
        //print_r($files);
        //print_r($custom);
        //print_r($settingGroups);
        //print_r($settings);
        //print_r($language);
        //print_r($modules);
        //print_r($templates);
        //print_r($tasks);
        //print_r($help);
        //print_r($database);
        if ($addMessage) {
            $this->registry->output->global_message = <<<EOF
\t\t{$this->lang->words['h_followacts']}
\t\t<ul>
\t\t\t<li>{$this->lang->words['h_newhookin']}</li>
\t\t\t<li>{$filesInserted} {$this->lang->words['h_filesin']}</li>
\t\t\t<li>{$settingGroupsInserted} {$this->lang->words['h_settinggin']}</li>
\t\t\t<li>{$settingsInserted} {$this->lang->words['h_settingin']}</li>
\t\t\t<li>{$settingsUpdated} {$this->lang->words['h_settingup']}</li>
\t\t\t<li>{$languageInserted} {$this->lang->words['h_langbitin']}</li>
\t\t\t<li>{$languageUpdated} {$this->lang->words['h_langbitup']}</li>
\t\t\t<li>{$modulesInserted} {$this->lang->words['h_modin']}</li>
\t\t\t<li>{$modulesUpdated} {$this->lang->words['h_modup']}</li>
\t\t\t<li>{$helpInserted} {$this->lang->words['h_helpin']}</li>
\t\t\t<li>{$helpUpdated} {$this->lang->words['h_helpup']}</li>
\t\t\t<li>{$templatesInserted} {$this->lang->words['h_tempin']}</li>
\t\t\t<li>{$templatesUpdated} {$this->lang->words['h_tempup']}</li>
\t\t\t<li>{$tasksInserted} {$this->lang->words['h_taskin']}</li>
\t\t\t<li>{$tasksUpdated} {$this->lang->words['h_taskup']}</li>
\t\t\t<li>{$createQueries} {$this->lang->words['h_dbcreated']}</li>
\t\t\t<li>{$alterQueries} {$this->lang->words['h_dbaltered']}</li>
\t\t\t<li>{$updateQueries} {$this->lang->words['h_updateran']}</li>
\t\t\t<li>{$insertQueries} {$this->lang->words['h_insertran']}</li>
\t\t</ul>
EOF;
            //-----------------------------------------
            // Got some skin recaching to do...
            //-----------------------------------------
            if ($allowSkinRecache === TRUE and ($templatesInserted or $templatesUpdated or $templateHooks)) {
                //-----------------------------------------
                // Recache hooks so templates know that there
                // are comments to preserve
                //-----------------------------------------
                $this->rebuildHooksCache();
                //-----------------------------------------
                // Get the libs
                //-----------------------------------------
                require_once IPS_ROOT_PATH . 'sources/classes/skins/skinFunctions.php';
                require_once IPS_ROOT_PATH . 'sources/classes/skins/skinCaching.php';
                $skinCaching = new skinCaching($this->registry);
                //-----------------------------------------
                // Find first skin id
                //-----------------------------------------
                ksort($this->registry->output->allSkins);
                $_skins = $this->registry->output->allSkins;
                $_set = array_shift($_skins);
                $setID = $_set['set_id'];
                $skinCaching->rebuildPHPTemplates($setID);
                /* Fetch next id */
                $nextID = $setID;
                ksort($this->registry->output->allSkins);
                foreach ($this->registry->output->allSkins as $id => $data) {
                    if ($id > $nextID) {
                        $nextID = $id;
                        break;
                    }
                }
                //-----------------------------------------
                // Have more than one skin
                //-----------------------------------------
                if ($nextID != $setID) {
                    //-----------------------------------------
                    // Save hook import messages
                    //-----------------------------------------
                    ipsRegistry::getClass('adminFunctions')->staffSaveCookie('hookResult', $this->registry->output->global_message);
                    //-----------------------------------------
                    // Wipe out the messages
                    //-----------------------------------------
                    $this->registry->output->global_message = '';
                    //-----------------------------------------
                    // Redirect to rebuild skins
                    //-----------------------------------------
                    $this->registry->getClass('class_localization')->loadLanguageFile(array('admin_templates'));
                    $this->registry->output->redirect($this->settings['base_url'] . 'app=core&module=applications&section=hooks&do=skinsRebuild&setID=' . $nextID, $this->lang->words['to_recachedset'] . $this->registry->output->allSkins[$setID]['set_name']);
                }
            }
        }
    }
 /**
  * Install Modules
  *
  * @return void
  */
 public function install_modules()
 {
     //-----------------------------------------
     // INIT
     //-----------------------------------------
     $previous = $_REQUEST['previous'];
     //-----------------------------------------
     // Fetch next 'un
     //-----------------------------------------
     $next = IPSSetUp::fetchNextApplication($previous, '{app}_modules.xml');
     //-----------------------------------------
     // Install SYSTEM Templates
     //-----------------------------------------
     if ($next['key']) {
         $output[] = $next['title'] . ": Upgrading modules...";
         $_PATH = IPSLib::getAppDir($next['key']) . '/xml/';
         if (file_exists($_PATH . $next['key'] . '_modules.xml')) {
             require_once IPS_ROOT_PATH . 'applications/core/modules_admin/applications/applications.php';
             $apps = new admin_core_applications_applications();
             $apps->makeRegistryShortcuts($this->registry);
             $this->request['_app'] = $next['key'];
             $apps->moduleImport('', 1, FALSE);
         }
         //-----------------------------------------
         // Done.. so get some more!
         //-----------------------------------------
         $this->_finishStep($output, "Upgrade: Modules", 'upgrade&do=modules&previous=' . $next['key']);
     } else {
         //-----------------------------------------
         // Next...
         //-----------------------------------------
         $output[] = "All modules upgraded";
         $this->_finishStep($output, "Upgrade: Modules", 'upgrade&do=settings');
     }
 }