/** * Fetch Apps XML Information File * * @access public * @param string Application Directory * @param string Character set (used for ACP) * @return array ..of data */ public static function fetchXmlAppInformation($app, $charset = '') { /* INIT */ $info = array(); /* Fetch core writeable files */ require_once IPS_KERNEL_PATH . 'classXML.php'; /*noLibHook*/ $xml = new classXML($charset ? $charset : IPSSetUp::charSet); try { if (is_file(IPSLib::getAppDir($app) . '/xml/information.xml')) { $xml->load(IPSLib::getAppDir($app) . '/xml/information.xml'); /* Fetch general information */ foreach ($xml->fetchElements('data') as $xmlelement) { //TERANOTE: remove this code below after making sure it doesn't cause issues the new way /*$data = $xml->fetchElementsFromRecord( $xmlelement ); $info['name'] = $data['name']; $info['title'] = $data['name']; $info['author'] = $data['author']; $info['description'] = $data['description']; $info['public_name'] = $data['public_name']; $info['disabledatinstall'] = ( $data['disabledatinstall'] ) ? 1 : 0; $info['key'] = $app; $info['ipskey'] = $data['ipskey']; $info['hide_tab'] = $data['hide_tab'];*/ $info = $xml->fetchElementsFromRecord($xmlelement); /* Sort some things */ $info['title'] = $info['name']; $info['disabledatinstall'] = intval($info['disabledatinstall']); $info['hide_tab'] = intval($info['hide_tab']); $info['key'] = $app; } /* Fetch template information */ foreach ($xml->fetchElements('template') as $template) { $name = $xml->fetchItem($template); $match = $xml->fetchAttribute($template, 'match'); if ($name) { $info['templates'][$name] = $match; } } } return $info; } catch (Exception $error) { $this->registry->output->addError(IPS_ROOT_PATH . 'applications/' . $app . '/xml/information.xml'); return FALSE; } }
/** * Import a single app * * @access public * @param string App * @param string Skin key to import * @param int Set ID * @param boolean Set the edited / added flags to 0 (from install, upgrade) * @return mixed bool, or array of info */ public function importTemplateAppXML($app, $skinKey, $setID = 0, $ignoreAddedEditedFlag = false) { //----------------------------------------- // INIT //----------------------------------------- $templateGroups = array(); $templates = array(); $fileXML = IPSLib::getAppDir($app) . '/xml/' . $app . '_' . $skinKey . '_templates.xml'; $infoXML = IPSLib::getAppDir($app) . '/xml/information.xml'; $return = array('updateCount' => 0, 'insertCount' => 0, 'updateBits' => array(), 'insertBits' => array()); if (!file_exists($fileXML)) { return $return; } if (!$setID and $skinKey != 'root') { /* Figure out correct set ID based on key */ $skinSetData = $this->DB->buildAndFetch(array('select' => '*', 'from' => 'skin_collections', 'where' => "set_key='" . $skinKey . "'")); $setID = $skinSetData['set_id']; } /* Set ignore flag correctly */ if (!empty($skinKey) and in_array($skinKey, array('root', 'lofi', 'xmlskin'))) { $ignoreAddedEditedFlag = true; } //----------------------------------------- // XML //----------------------------------------- require_once IPS_KERNEL_PATH . 'classXML.php'; $xml = new classXML(IPS_DOC_CHAR_SET); //----------------------------------------- // Get information file //----------------------------------------- $xml->load($infoXML); foreach ($xml->fetchElements('template') as $template) { $name = $xml->fetchItem($template); $match = $xml->fetchAttribute($template, 'match'); if ($name) { $templateGroups[$name] = $match; } } if (!is_array($templateGroups) or !count($templateGroups)) { $this->_addMessage("Nothing to export for " . $app); return FALSE; } //----------------------------------------- // Fetch templates //----------------------------------------- $_templates = $this->fetchTemplates($setID, 'allNoContent'); $_MASTER = $this->fetchTemplates(0, 'allNoContent'); //----------------------------------------- // Loop through... //----------------------------------------- foreach ($_templates as $group => $data) { $_okToGo = FALSE; foreach ($templateGroups as $name => $match) { if ($match == 'contains') { if (stristr($group, $name)) { $_okToGo = TRUE; break; } } else { if ($group == $name) { $_okToGo = TRUE; } } } if ($_okToGo === TRUE) { foreach ($data as $name => $templateData) { $templates[$group][$name] = $templateData; } } } //----------------------------------------- // Wipe the master skins //----------------------------------------- if ($setID == 0) { $this->DB->delete('skin_templates', "template_set_id=0 AND template_group IN ('" . implode("','", array_keys($templates)) . "') AND template_user_added=0 AND template_added_to=0"); /* Now wipe the array so we enforce creation */ unset($templates); } //----------------------------------------- // Now grab the actual XML files //----------------------------------------- $xml->load($fileXML); foreach ($xml->fetchElements('template') as $templatexml) { $data = $xml->fetchElementsFromRecord($templatexml); /* Figure out if this is added by a user or not */ if ($ignoreAddedEditedFlag === TRUE) { $isAdded = 0; $isEdited = 0; } else { $isAdded = (is_array($_MASTER[$data['template_group']][strtolower($data['template_name'])]) and !$_MASTER[$data['template_group']][strtolower($data['template_name'])]['template_user_added']) ? 0 : 1; $isEdited = 1; } if (is_array($templates[$data['template_group']][strtolower($data['template_name'])]) and $templates[$data['template_group']][strtolower($data['template_name'])]['template_set_id'] == $setID) { /* Update.. */ $return['updateCount']++; $return['updateBits'][] = $data['template_name']; $this->DB->update('skin_templates', array('template_content' => $data['template_content'], 'template_data' => $data['template_data'], 'template_user_edited' => $isEdited, 'template_user_added' => $isAdded, 'template_updated' => time()), 'template_set_id=' . $setID . " AND template_group='" . $data['template_group'] . "' AND template_name='" . $data['template_name'] . "'"); } else { /* Add... */ $return['insertCount']++; $return['insertBits'][] = $data['template_name']; $this->DB->insert('skin_templates', array('template_set_id' => $setID, 'template_group' => $data['template_group'], 'template_content' => $data['template_content'], 'template_name' => $data['template_name'], 'template_data' => $data['template_data'], 'template_removable' => $setID ? $data['template_removable'] : 0, 'template_added_to' => $setID, 'template_user_edited' => $isEdited, 'template_user_added' => $isAdded, 'template_updated' => time())); } } return $return; }
/** * Remove an application * * @return @e void [Outputs to screen] */ public function applicationRemove() { //-------------------------------------------- // INIT //-------------------------------------------- $app_id = intval($this->request['app_id']); //----------------------------------------- // Got an application? //----------------------------------------- $application = $this->DB->buildAndFetch(array('select' => '*', 'from' => 'core_applications', 'where' => 'app_id=' . $app_id)); if (!$application['app_id']) { $this->registry->output->global_message = $this->lang->words['a_noid']; $this->applicationsOverview(); return; } //----------------------------------------- // Protected? //----------------------------------------- if (!IN_DEV and $application['app_protected']) { $this->registry->output->global_message = $this->lang->words['a_protectapp']; $this->applicationsOverview(); return; } //----------------------------------------- // Remove Settings //----------------------------------------- $this->DB->build(array('select' => '*', 'from' => 'core_sys_settings_titles', 'where' => "conf_title_app='{$application['app_directory']}'")); $this->DB->execute(); $conf_title_id = array(); while ($r = $this->DB->fetch()) { $conf_title_id[] = $r['conf_title_id']; } if (count($conf_title_id)) { $this->DB->delete('core_sys_conf_settings', 'conf_group IN(' . implode(',', $conf_title_id) . ')'); } $this->DB->delete('core_sys_settings_titles', "conf_title_app='{$application['app_directory']}'"); $settingsFile = IPSLib::getAppDir($application['app_directory']) . '/xml/' . $application['app_directory'] . '_settings.xml'; if (is_file($settingsFile)) { require_once IPS_KERNEL_PATH . 'classXML.php'; /*noLibHook*/ $xml = new classXML(IPS_DOC_CHAR_SET); $xml->load($settingsFile); $keys = array(); foreach ($xml->fetchElements('setting') as $setting) { $entry = $xml->fetchElementsFromRecord($setting); if ($entry['conf_is_title']) { continue; } $keys[] = "'{$entry['conf_key']}'"; } if (!empty($keys)) { $this->DB->delete('core_sys_conf_settings', 'conf_key IN(' . implode(',', $keys) . ')'); } } //----------------------------------------- // Remove Application Caches //----------------------------------------- $_file = IPSLib::getAppDir($application['app_directory']) . '/extensions/coreVariables.php'; if (is_file($_file)) { $CACHE = array(); require $_file; /*noLibHook*/ if (is_array($CACHE) and count($CACHE)) { foreach ($CACHE as $key => $data) { $this->DB->delete('cache_store', "cs_key='{$key}'"); } } } //----------------------------------------- // Remove tables //----------------------------------------- $_file = IPSLib::getAppDir($application['app_directory']) . '/setup/versions/install/sql/' . $application['app_directory'] . '_' . ipsRegistry::dbFunctions()->getDriverType() . '_tables.php'; if (is_file($_file)) { $TABLE = array(); require $_file; /*noLibHook*/ foreach ($TABLE as $q) { //----------------------------------------- // Capture create tables first //----------------------------------------- preg_match("/CREATE TABLE (\\S+)(\\s)?\\(/", $q, $match); if ($match[1]) { $_table = preg_replace('#^' . ipsRegistry::dbFunctions()->getPrefix() . "(\\S+)#", "\\1", $match[1]); $this->DB->dropTable($_table); } else { //----------------------------------------- // Then capture alter tables //----------------------------------------- preg_match("/ALTER TABLE (\\S+)\\sADD\\s(\\S+)\\s/i", $q, $match); if ($match[1] and $match[2]) { $_table = preg_replace('#^' . ipsRegistry::dbFunctions()->getPrefix() . "(\\S+)#", "\\1", $match[1]); $_field = $match[2]; /* check for field */ if ($this->DB->checkForField($_field, $_table)) { $this->DB->dropField($_table, $_field); } } } } } //----------------------------------------- // Check for uninstall sql //----------------------------------------- /* Any "extra" configs required for this driver? */ if (is_file(IPS_ROOT_PATH . 'setup/sql/' . $this->settings['sql_driver'] . '_install.php')) { require_once IPS_ROOT_PATH . 'setup/sql/' . $this->settings['sql_driver'] . '_install.php'; /*noLibHook*/ $extra_install = new install_extra($this->registry); } $_file = IPSLib::getAppDir($application['app_directory']) . '/setup/versions/install/sql/' . $application['app_directory'] . '_' . ipsRegistry::dbFunctions()->getDriverType() . '_uninstall.php'; if (is_file($_file)) { $QUERY = array(); require $_file; /*noLibHook*/ if (is_array($QUERY) and count($QUERY)) { foreach ($QUERY as $q) { if ($extra_install and method_exists($extra_install, 'process_query_create')) { $q = $extra_install->process_query_create($q); } $this->DB->query($q); } } } //----------------------------------------- // Remove Misc Stuff //----------------------------------------- $this->DB->delete('core_sys_lang_words', "word_app='{$application['app_directory']}'"); $this->DB->delete('task_manager', "task_application='{$application['app_directory']}'"); $this->DB->delete('permission_index', "app='{$application['app_directory']}'"); $this->DB->delete('reputation_index', "app='{$application['app_directory']}'"); $this->DB->delete('reputation_cache', "app='{$application['app_directory']}'"); $this->DB->delete('core_tags', "tag_meta_app='{$application['app_directory']}'"); $this->DB->delete('faq', "app='{$application['app_directory']}'"); $this->DB->delete('custom_bbcode', "bbcode_app='{$application['app_directory']}'"); $this->DB->delete('upgrade_history', "upgrade_app='{$application['app_directory']}'"); $this->DB->delete('core_like_cache', "like_cache_app='{$application['app_directory']}'"); $this->DB->delete('core_like', "like_app='{$application['app_directory']}'"); $this->DB->delete('core_item_markers', "item_app='{$application['app_directory']}'"); //----------------------------------------- // Report center.. //----------------------------------------- $plugin = $this->DB->buildAndFetch(array('select' => '*', 'from' => 'rc_classes', 'where' => "app='{$application['app_directory']}'")); if ($plugin['com_id']) { $this->DB->build(array('select' => '*', 'from' => 'rc_reports_index', 'where' => 'rc_class=' . $plugin['com_id'])); $outer = $this->DB->execute(); while ($r = $this->DB->fetch($outer)) { $this->DB->delete('rc_reports', "rid=" . $r['id']); $this->DB->delete('rc_comments', "rid=" . $r['id']); } $this->DB->delete('rc_reports_index', 'rc_class=' . $plugin['com_id']); $this->DB->delete('rc_classes', 'com_id=' . $plugin['com_id']); } //----------------------------------------- // Attachments //----------------------------------------- $_plugins = array(); try { foreach (new DirectoryIterator(IPSLib::getAppDir($application['app_directory']) . '/extensions/attachments/') as $file) { if (!$file->isDot() && $file->isFile()) { if (preg_match("/^plugin_(.+?)\\.php\$/", $file->getFileName(), $matches)) { $_plugins[] = $matches[1]; } } } if (count($_plugins)) { foreach ($_plugins as $_plugin) { $this->DB->build(array('select' => '*', 'from' => 'attachments', 'where' => "attach_rel_module='{$_plugin}'")); $outer = $this->DB->execute(); while ($r = $this->DB->fetch($outer)) { if (is_file($this->settings['upload_dir'] . "/" . $r['attach_location'])) { @unlink($this->settings['upload_dir'] . "/" . $r['attach_location']); } } $this->DB->delete('attachments', "attach_rel_module='{$_plugin}'"); } } } catch (Exception $e) { } //----------------------------------------- // Get all hook files //----------------------------------------- if (is_dir(IPSLib::getAppDir($application['app_directory']) . '/xml/hooks')) { $files = scandir(IPSLib::getAppDir($application['app_directory']) . '/xml/hooks'); $hooks = array(); require_once IPS_KERNEL_PATH . 'classXML.php'; /*noLibHook*/ $xml = new classXML(IPS_DOC_CHAR_SET); if (count($files) and is_array($files)) { foreach ($files as $_hookFile) { if ($_hookFile != '.' and $_hookFile != '..' and preg_match("/(\\.xml)\$/", $_hookFile)) { $xml->loadXML(file_get_contents(IPSLib::getAppDir($application['app_directory']) . '/xml/hooks/' . $_hookFile)); foreach ($xml->fetchElements('config') as $data) { $config = $xml->fetchElementsFromRecord($data); if (!count($config)) { continue; } else { $hooks[] = $config['hook_key']; } } } } } if (count($hooks)) { foreach ($hooks as $hook) { $hook = $this->DB->buildAndFetch(array('select' => '*', 'from' => 'core_hooks', 'where' => "hook_key='" . $hook . "'")); if (!$hook['hook_id']) { continue; } $this->DB->delete('core_hooks', "hook_id={$hook['hook_id']}"); /* Get associated files */ $this->DB->build(array('select' => 'hook_file_stored', 'from' => 'core_hooks_files', 'where' => 'hook_hook_id=' . $hook['hook_id'])); $this->DB->execute(); while ($r = $this->DB->fetch()) { @unlink(IPS_HOOKS_PATH . $r['hook_file_stored']); } /* Delete hook file entries */ $this->DB->delete('core_hooks_files', "hook_hook_id={$hook['hook_id']}"); } $this->cache->rebuildCache('hooks', 'global'); } } //----------------------------------------- // Remove Files //----------------------------------------- /* Languages */ try { foreach (new DirectoryIterator(DOC_IPS_ROOT_PATH . 'cache/lang_cache/') as $dir) { if (!$dir->isDot() && intval($dir->getFileName())) { foreach (new DirectoryIterator(DOC_IPS_ROOT_PATH . 'cache/lang_cache/' . $dir->getFileName() . '/') as $file) { if (!$file->isDot()) { if (preg_match("/^({$application['app_directory']}_)/", $file->getFileName())) { unlink($file->getPathName()); } } } } } } catch (Exception $e) { } /* Remove Skins */ if (is_file(IPSLib::getAppDir($application['app_directory']) . '/xml/information.xml')) { require_once IPS_KERNEL_PATH . 'classXML.php'; /*noLibHook*/ $xml = new classXML($this->settings['gb_char_set']); $xml->load(IPSLib::getAppDir($application['app_directory']) . '/xml/information.xml'); if (is_object($xml->fetchElements('template'))) { foreach ($xml->fetchElements('template') as $template) { $name = $xml->fetchItem($template); $match = $xml->fetchAttribute($template, 'match'); if ($name) { $templateGroups[$name] = $match; } } } if (is_array($templateGroups) and count($templateGroups)) { /* Loop through skin directories */ try { foreach (new DirectoryIterator(IPS_CACHE_PATH . 'cache/skin_cache/') as $dir) { if (preg_match("/^(cacheid_)/", $dir->getFileName())) { foreach (new DirectoryIterator(IPS_CACHE_PATH . 'cache/skin_cache/' . $dir->getFileName() . '/') as $file) { if (!$file->isDot()) { foreach ($templateGroups as $name => $match) { if ($match == 'contains') { if (stristr($file->getFileName(), $name)) { unlink($file->getPathName()); } } else { if ($file->getFileName() == $name . '.php') { unlink($file->getPathName()); } } } } } } } } catch (Exception $e) { } /* Delete from database */ foreach ($templateGroups as $name => $match) { if ($match == 'contains') { $this->DB->delete('skin_templates', "template_group LIKE '%{$name}%'"); $this->DB->delete('skin_templates_previous', "p_template_group LIKE '%{$name}%'"); $this->DB->delete('skin_cache', "cache_type='phptemplate' AND cache_value_1 LIKE '%{$name}%'"); } else { $this->DB->delete('skin_templates', "template_group='{$name}'"); $this->DB->delete('skin_templates_previous', "p_template_group='{$name}'"); $this->DB->delete('skin_cache', "cache_type='phptemplate' AND cache_value_1='{$name}'"); } } } } /* CSS files */ $css_files = array(); $this->DB->build(array('select' => '*', 'from' => 'skin_css', 'where' => "css_app='" . $application['app_directory'] . "'")); $this->DB->execute(); while ($r = $this->DB->fetch()) { $css_files[$r['css_group']] = $r['css_group']; } if (count($css_files)) { $this->DB->delete('skin_css', "css_app='" . $application['app_directory'] . "'"); $this->DB->delete('skin_cache', "cache_type='css' AND cache_value_1 IN('" . implode("','", $css_files) . "')"); try { foreach (new DirectoryIterator(DOC_IPS_ROOT_PATH . PUBLIC_DIRECTORY . '/style_css/') as $dir) { if (preg_match("/^(css_)/", $dir->getFileName())) { foreach (new DirectoryIterator(DOC_IPS_ROOT_PATH . PUBLIC_DIRECTORY . '/style_css/' . $dir->getFileName() . '/') as $file) { if (!$file->isDot()) { foreach ($css_files as $css_file) { if ($file->getFileName() == $css_file . '.css') { unlink($file->getPathName()); } } } } } } } catch (Exception $e) { } } //----------------------------------------- // Remove Modules //----------------------------------------- $this->DB->delete('core_sys_module', "sys_module_application='{$application['app_directory']}'"); //----------------------------------------- // Remove Application //----------------------------------------- $this->DB->delete('core_applications', 'app_id=' . $app_id); //----------------------------------------- // Recache //----------------------------------------- $this->moduleRecacheAll(1); $this->cache->rebuildCache('settings', 'global'); $this->cache->rebuildCache('notifications', 'global'); /* Delete from upgrade */ $this->DB->delete('upgrade_history', "upgrade_app='{$application['app_directory']}'"); //----------------------------------------- // FURL templates //----------------------------------------- try { IPSLib::cacheFurlTemplates(); IPSLib::cacheGlobalCaches(); } catch (Exception $e) { } //----------------------------------------- // Sphinx involved? //----------------------------------------- if ($this->settings['search_method'] == 'sphinx') { $this->registry->output->global_message .= sprintf($this->lang->words['rebuild_sphinx'], $this->settings['_base_url']); } //----------------------------------------- // Done... //----------------------------------------- $this->registry->output->global_message = $this->lang->words['a_appremoved']; $this->registry->output->silentRedirectWithMessage($this->settings['base_url'] . $this->form_code . '&do=applications_overview'); }
/** * Fetch Apps XML Information File * * @access public * @param string Application Directory * @return array ..of data */ public static function fetchXmlAppInformation($app) { /* INIT */ $info = array(); /* Fetch core writeable files */ require_once IPS_KERNEL_PATH . 'classXML.php'; $xml = new classXML(IPSSetUp::charSet); try { $xml->load(IPSLib::getAppDir($app) . '/xml/information.xml'); /* Fetch general information */ foreach ($xml->fetchElements('data') as $xmlelement) { $data = $xml->fetchElementsFromRecord($xmlelement); $info['name'] = $data['name']; $info['title'] = $data['name']; $info['author'] = $data['author']; $info['description'] = $data['description']; $info['public_name'] = $data['public_name']; $info['disabledatinstall'] = $data['disabledatinstall'] ? 1 : 0; $info['key'] = $app; $info['ipskey'] = $data['ipskey']; $info['hide_tab'] = $data['hide_tab']; } /* Fetch template information */ foreach ($xml->fetchElements('template') as $template) { $name = $xml->fetchItem($template); $match = $xml->fetchAttribute($template, 'match'); if ($name) { $info['templates'][$name] = $match; } } return $info; } catch (Exception $error) { $this->registry->output->addError(IPS_ROOT_PATH . 'applications/' . $app . '/xml/information.xml'); return FALSE; } }