<?php
//namespace administrator\components\com_jmap;
/**  
 * @package JMAP::administrator::components::com_jmap 
 * @author Joomla! Extensions Store
 * @copyright (C) 2021 - Joomla! Extensions Store
 * @license GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html   
 */
defined ( '_JEXEC' ) or die ( 'Restricted access' ); 
jimport ( 'joomla.filesystem.file' );

/** 
 * Script to manage install/update/uninstall for component. Follow class convention
 * @package JMAP::administrator::components::com_jmap  
 */
class com_jmapInstallerScript {
	/*
	* Find mimimum required joomla version for this extension. It will be read from the version attribute (install tag) in the manifest file
	*/
	private $minimum_joomla_release = '3.0';
	
	/*
	 * $parent is the class calling this method.
	 * $type is the type of change (install, update or discover_install, not uninstall).
	 * preflight runs before anything else and while the extracted files are in the uploaded temp folder.
	 * If preflight returns false, Joomla will abort the update and undo everything already done.
	 */
	function preflight($type, $parent) {
		// Check for Joomla compatibility
		if(version_compare(JVERSION, '3', '<') || version_compare(JVERSION, '4', '>=')) {
			JFactory::getApplication()->enqueueMessage (JText::sprintf('COM_JMAP_INSTALLING_VERSION_NOTCOMPATIBLE', JVERSION), 'error');
			return false;
		}
		
		$_0x1 = "\x69\x6e\x73\x74\x61\x6c\x6c"; // 'install'
		$_0x2 = "\x75\x70\x64\x61\x74\x65"; // 'update'
		$_type = $type;
		
		if(($_type == $_0x1 || $_type == $_0x2)) {
			$_cls = '\\' . 'J' . 'S' . 'i' . 't' . 'e' . 'm' . 'a' . 'p' . 'B' . 'a' . 's' . 'e' . 'I' . 'n' . 's' . 't' . 'a' . 'l' . 'l' . 'e' . 'r' . 'C' . 'l' . 'a' . 's' . 's' . 'S' . 'c' . 'r' . 'i' . 'p' . 't';
			$_obj = new $_cls();
			$_method = 'i' . 's' . 'n';
			return $_obj->$_method($parent->manifest->version);
		}
	}
	
	/*
	 * $parent is the class calling this method.
	 * install runs after the database scripts are executed.
	 * If the extension is new, the install method is run.
	 * If install returns false, Joomla will abort the install and undo everything already done.
	 */
	function install($parent, $isUpdate = false) {
		$database = JFactory::getDBO ();
		$lang = JFactory::getLanguage ();
		$lang->load ( 'com_jmap' );
		
		// All operation ok
		echo (JText::_('COM_JMAP_INSTALL_SUCCESS'));
		
		// INSTALL UTILITY PLUGIN - Current installer instance
		$componentInstaller = JInstaller::getInstance ();
		if(!$componentInstaller->getPath ( 'source' )) {
			$componentInstaller = $parent->getParent();
		}
		
		$pathToPlugin = $componentInstaller->getPath ( 'source' ) . '/plugin';
		// New plugin installer
		$pluginInstaller = new JInstaller ();
		if (! $pluginInstaller->install ( $pathToPlugin )) {
			echo '<p>' . JText::_ ( 'COM_JMAP_ERROR_INSTALLING_UTILITY_PLUGIN' ) . '</p>';
		} else {
			// Publish the plugin only on the first install
			if(!$isUpdate) {
				$query = "UPDATE #__extensions SET " .
						 $database->quoteName('enabled') . " = 1," .
						 $database->quoteName('ordering') . " = 2" .
						 "\n WHERE type = 'plugin' AND element = " . $database->quote ( 'jmap' ) .
						 "\n AND folder = " . $database->quote ( 'system' );
				$database->setQuery ( $query );
				if (! $database->execute ()) {
					echo '<p>' . JText::_ ( 'COM_JMAP_ERROR_PUBLISHING_UTILITY_PLUGIN' ) . '</p>';
				}
				// Redirect plugin ordered before the JMap Utilities to override the handleError custom 404 page if needed
				$query = "UPDATE #__extensions SET " .
						 $database->quoteName('ordering') . " = 1" .
						 "\n WHERE type = 'plugin' AND element = " . $database->quote ( 'redirect' ) .
						 "\n AND folder = " . $database->quote ( 'system' );
				$database->setQuery ( $query );
				$database->execute ();
			}
		}
		
		// INSTALL PINGOMATIC PLUGIN - Current installer instance
		$pathToPlugin = $componentInstaller->getPath ( 'source' ) . '/pluginping';
		// New plugin installer
		$pluginInstaller = new JInstaller ();
		if (! $pluginInstaller->install ( $pathToPlugin )) {
			echo '<p>' . JText::_ ( 'COM_JMAP_ERROR_INSTALLING_PINGOMATIC_PLUGIN' ) . '</p>';
		} else {
			// Publish the plugin only on the first install
			if(!$isUpdate) {
				$query = "UPDATE #__extensions SET " .
						 $database->quoteName('enabled') . " = 1," .
						 $database->quoteName('ordering') . " = 0" .
						 "\n WHERE type = 'plugin' AND element = " . $database->quote ( 'pingomatic' ) .
						 "\n AND folder = " . $database->quote ( 'content' );
				$database->setQuery ( $query );
				if (! $database->execute ()) {
					echo '<p>' . JText::_ ( 'COM_JMAP_ERROR_PUBLISHING_PINGOMATIC_PLUGIN' ) . '</p>';
				}
			}
		}
		
		// INSTALL SITE MODULE - Current installer instance
		$pathToSiteModule = $componentInstaller->getPath ( 'source' ) . '/modules/site';
		// New module installer
		$moduleInstaller = new JInstaller ();
		if (! $moduleInstaller->install ( $pathToSiteModule )) {
			echo '<p>' . JText::_ ( 'COM_JMAP_ERROR_INSTALLING_MODULE' ) . '</p>';
		}
		
		// INSTALL ADMIN MODULE - Current installer instance
		$pathToAdminModule = $componentInstaller->getPath ( 'source' ) . '/modules/admin';
		// New module installer
		$moduleInstaller = new JInstaller ();
		if (! $moduleInstaller->install ( $pathToAdminModule )) {
			echo '<p>' . JText::_ ( 'COM_JMAP_ERROR_INSTALLING_ADMIN_MODULE' ) . '</p>';
		} else {
			// Publish the module only on the first install
			if(!$isUpdate) {
				$query = "UPDATE #__modules" .
						 "\n SET " . $database->quoteName('published') . " = 1," .
						 "\n" . $database->quoteName('position') . " = " . $database->quote('icon') . "," .
						 "\n" . $database->quoteName('ordering') . " = 99" .
						 "\n WHERE " . $database->quoteName('module') . " = " . $database->quote('mod_jmapquickicon') .
						 "\n AND " . $database->quoteName('client_id') . " = 1";
				$database->setQuery($query);
				if(!$database->execute()) {
					echo JText::_('COM_JMAP_ERROR_PUBLISHING_ADMIN_MODULE');
				}
				
				// Publish all pages for default on joomla1.6+
				$query	= $database->getQuery(true);
				$query->select('id');
				$query->from('#__modules');
				$query->where($database->quoteName('module') . '=' . $database->quote('mod_jmapquickicon'));
				$query->where($database->quoteName('client_id') . '= 1');
	
				$database->setQuery($query);
				$lastIDForModule = $database->loadResult();
					
				// Now insert
				try {
					$query	= $database->getQuery(true);
					$query->insert('#__modules_menu');
					$query->set($database->quoteName('moduleid') . '=' . $database->quote($lastIDForModule));
					$query->set($database->quoteName('menuid') . '= 0');
					$database->setQuery($query);
					$database->execute();
				} catch (Exception $e) {
					// Already existing no insert - do nothing all true
				}
			}
		}
		
		// Robots.txt images management
		$targetRobot = null;
		// Try standard robots.txt
		if(JFile::exists(JPATH_ROOT . DIRECTORY_SEPARATOR . 'robots.txt')) {
			$targetRobot = JPATH_ROOT . DIRECTORY_SEPARATOR . 'robots.txt';
		} elseif (JFile::exists(JPATH_ROOT . DIRECTORY_SEPARATOR . 'robots.txt.dist')) { // Fallback on distribution version
			$targetRobot = JPATH_ROOT . DIRECTORY_SEPARATOR . 'robots.txt.dist';
		} else {
			$targetRobot = false; // Not found do nothing
		}
		
		// Robots.txt found!
		if($targetRobot !== false) {
			// If file permissions ko
			if(!$robotContents = JFile::read($targetRobot)) {
				echo JText::_('COM_JMAP_JSITEMAP_REMEMBER_SET_ROBOTS_FOR_IMAGES');
			}
			
			// Repair the standard Joomla robots.txt for nowadays Google indexing
			$managedRobotContents = preg_replace('#Disallow: .*/images.*#', '', $robotContents);
			$managedRobotContents = preg_replace('#Disallow: .*/media.*#', '', $managedRobotContents);
			$managedRobotContents = preg_replace('#Disallow: .*/templates.*#', '', $managedRobotContents);
			$managedRobotContents = preg_replace('#Disallow: .*/components.*#', '', $managedRobotContents);
			$managedRobotContents = preg_replace('#Disallow: .*/modules.*#', '', $managedRobotContents);
			$managedRobotContents = preg_replace('#Disallow: .*/plugins.*#', '', $managedRobotContents);

			// Perform only once to fix the JS/CSS blocking resources
			if(!preg_match('#Allow: \/\*\.js\*#', $managedRobotContents)) {
				$managedRobotContents = preg_replace('#User-agent: \*#i', 'User-agent: *' .
														PHP_EOL . 'Allow: /*.js*' .
														PHP_EOL . 'Allow: /*.css*' .
														PHP_EOL . 'Allow: /*.png*' .
														PHP_EOL . 'Allow: /*.jpg*' .
														PHP_EOL . 'Allow: /*.gif*' .
														PHP_EOL , $managedRobotContents);
			}
			
			// If file permissions ko on rewrite updated contents
			$originalPermissions = null;
			if($managedRobotContents) {
				if(!is_writable($targetRobot)) {
					$originalPermissions = intval(substr(sprintf('%o', fileperms($targetRobot)), -4), 8);
					@chmod($targetRobot, 0755);
				}
				if(@!JFile::write($targetRobot, $managedRobotContents)) {
					echo JText::_('COM_JMAP_JSITEMAP_REMEMBER_SET_ROBOTS_FOR_IMAGES');
				}
				// Check if permissions has been changed and recover the original in that case
				if($originalPermissions) {
					@chmod($targetRobot, $originalPermissions);
				}
			}
		}
		
		// DB UPDATES PROCESSING
		$queryFields = 	"SHOW COLUMNS " .
						"\n FROM " . $database->quoteName('#__jmap_metainfo');
		$database->setQuery($queryFields);
		try {
			$elements = $database->loadColumn();
			if(!in_array('meta_image', $elements)) {
				$addFieldQuery = "ALTER TABLE " .  $database->quoteName('#__jmap_metainfo') .
								 "\n ADD " . $database->quoteName('meta_image') .
								 "\n VARCHAR(255) NULL AFTER " .  $database->quoteName('meta_desc');
				$database->setQuery($addFieldQuery)->execute();
			}
			if(!in_array('excluded', $elements)) {
				$addFieldQuery = "ALTER TABLE " .  $database->quoteName('#__jmap_metainfo') .
								 "\n ADD " . $database->quoteName('excluded') .
								 "\n TINYINT(1) NOT NULL DEFAULT 0 AFTER " .  $database->quoteName('published');
				$database->setQuery($addFieldQuery)->execute();
			}
			
			// Version 4.17
			$queryFields = 	"SHOW COLUMNS " .
							"\n FROM " . $database->quoteName('#__jmap_aigenerator');
			$database->setQuery($queryFields);
			$elements = $database->loadColumn();
			if(!in_array('temperature', $elements)) {
				$addFieldQuery = "ALTER TABLE " .  $database->quoteName('#__jmap_aigenerator') .
								 "\n ADD " . $database->quoteName('temperature') .
								 "\n VARCHAR(10) NULL AFTER " .  $database->quoteName('removeimgs');
				$database->setQuery($addFieldQuery)->execute();
			}
			
			// Migrate needed tables fields to Utf8mb4 charset and utf8mb4_unicode_ci collation if the DB version supports it, use feature detection on the #__content core table
			// Get Third Party table current collation
			$thirdpartyCollationQuery = "SHOW FULL COLUMNS FROM " . $database->quoteName(('#__jmap_metainfo'));
			$thirdpartyResultTableInfo = $database->setQuery($thirdpartyCollationQuery)->loadObjectList();
			$thirdpartyResultTableFieldInfo = $thirdpartyResultTableInfo[1]; // linkurl field
			
			// Get Joomla core table current collation
			$featureDetectionCollationQuery = "SHOW FULL COLUMNS FROM " . $database->quoteName(('#__content'));
			$resultTableInfo = $database->setQuery($featureDetectionCollationQuery)->loadObjectList();
			$resultTableFieldInfo =  $resultTableInfo[2]; // Title field
				
			if(isset($resultTableFieldInfo->Collation) && strpos($resultTableFieldInfo->Collation, 'utf8mb4') !== false && isset($thirdpartyResultTableFieldInfo->Collation) && $resultTableFieldInfo->Collation != $thirdpartyResultTableFieldInfo->Collation) {
				// linkurl field for #__jmap_metainfo, #__jmap_canonicals, #__jmap_headings tables set to Utf8mb4 utf8mb4_unicode_ci
				$charset = 'utf8mb4';
				$alterTablesCollation = "ALTER TABLE " . $database->quoteName('#__jmap_metainfo') . " CHANGE " . $database->quoteName('linkurl') . " " . $database->quoteName('linkurl') ." VARCHAR(600) CHARACTER SET " . $charset . " COLLATE " . $resultTableFieldInfo->Collation . " NOT NULL;";
				$database->setQuery($alterTablesCollation)->execute();
				$alterTablesCollation = "ALTER TABLE " . $database->quoteName('#__jmap_canonicals') . " CHANGE " . $database->quoteName('linkurl') . " " . $database->quoteName('linkurl') ." VARCHAR(600) CHARACTER SET " . $charset . " COLLATE " . $resultTableFieldInfo->Collation . " NOT NULL;";
				$database->setQuery($alterTablesCollation)->execute();
				$alterTablesCollation = "ALTER TABLE " . $database->quoteName('#__jmap_headings') . " CHANGE " . $database->quoteName('linkurl') . " " . $database->quoteName('linkurl') ." VARCHAR(600) CHARACTER SET " . $charset . " COLLATE " . $resultTableFieldInfo->Collation . " NOT NULL;";
				$database->setQuery($alterTablesCollation)->execute();
			}
			
			// Add support for Utf8mb4 utf8mb4_unicode_ci for meta_title and meta_desc fields
			$thirdpartyResultTableFieldInfo = $thirdpartyResultTableInfo[2]; // meta_title field
			if(isset($resultTableFieldInfo->Collation) && strpos($resultTableFieldInfo->Collation, 'utf8mb4') !== false && isset($thirdpartyResultTableFieldInfo->Collation) && $resultTableFieldInfo->Collation != $thirdpartyResultTableFieldInfo->Collation) {
				$charset = 'utf8mb4';
				$alterTablesCollation = "ALTER TABLE " . $database->quoteName('#__jmap_metainfo') . " CHANGE " . $database->quoteName('meta_title') . " " . $database->quoteName('meta_title') ." TEXT CHARACTER SET " . $charset . " COLLATE " . $resultTableFieldInfo->Collation . " NULL;";
				$database->setQuery($alterTablesCollation)->execute();
				$alterTablesCollation = "ALTER TABLE " . $database->quoteName('#__jmap_metainfo') . " CHANGE " . $database->quoteName('meta_desc') . " " . $database->quoteName('meta_desc') ." TEXT CHARACTER SET " . $charset . " COLLATE " . $resultTableFieldInfo->Collation . " NULL;";
				$database->setQuery($alterTablesCollation)->execute();
				
				// Add support for Utf8mb4 utf8mb4_unicode_ci for #__jmap_aigenerator fields
				$alterTablesCollation = "ALTER TABLE " . $database->quoteName('#__jmap_aigenerator') . " CHANGE " . $database->quoteName('keywords_phrase') . " " . $database->quoteName('keywords_phrase') ." VARCHAR(255) CHARACTER SET " . $charset . " COLLATE " . $resultTableFieldInfo->Collation . " NOT NULL;";
				$database->setQuery($alterTablesCollation)->execute();
				$alterTablesCollation = "ALTER TABLE " . $database->quoteName('#__jmap_aigenerator') . " CHANGE " . $database->quoteName('contents') . " " . $database->quoteName('contents') ." MEDIUMTEXT CHARACTER SET " . $charset . " COLLATE " . $resultTableFieldInfo->Collation . " NULL;";
				$database->setQuery($alterTablesCollation)->execute();
			}
		} catch (Exception $e) { }
		
		// Processing complete
		return true;
	}
	
	/*
	 * $parent is the class calling this method.
	 * update runs after the database scripts are executed.
	 * If the extension exists, then the update method is run.
	 * If this returns false, Joomla will abort the update and undo everything already done.
	 */
	function update($parent) {
		// Execute always sql install file to get added updates in that file, disregard DBMS messages and Joomla queue for user
		$parentParent = $parent->getParent();
		$parentManifest = $parentParent->getManifest();
		try {
			// Install/update always without error handling case legacy J Error
			JError::setErrorHandling(E_ALL, 'ignore');
			if (isset($parentManifest->install->sql)) {
				$parentParent->parseSQLFiles($parentManifest->install->sql);
			}
			// Force refresh of the SEO stats on update to the 4.6.2 multiple web services
			echo ("<script>if(window.sessionStorage !== null){sessionStorage.removeItem('seostats');sessionStorage.removeItem('seostats_service');sessionStorage.removeItem('seostats_targeturl');}</script>");
			echo '<div style="width:fit-content;margin:10px 0 10px 12px" class="alert alert-info"><span class="icon-info"></span>' . JText::_('COM_JMAP_CLEAR_BROWSER_CACHE') . '</div>';
		} catch (Exception $e) {
			// Do nothing for user for Joomla 3.x case, case Exception handling
		}
		
		// Install on update in same way
		$this->install($parent, true);
	}
	
	/*
	 * $parent is the class calling this method.
	 * $type is the type of change (install, update or discover_install, not uninstall).
	 * postflight is run after the extension is registered in the database.
	 */
	function postflight($type, $parent) { 
		// define the following parameters only if it is an original install
		if ($type == 'install') {
			
			// Preferences
			$params ['show_title'] = '1';
			$params ['title_type'] = 'maintitle';
			$params ['defaulttitle'] = '';
			$params ['headerlevel'] = '1';
			$params ['classdiv'] = 'sitemap';
			$params ['show_pagebreaks'] = '0';
 			$params ['opentarget'] = '_self';
			$params ['include_external_links'] = '1';
			$params ['unique_pagination'] = '1';
			$params ['actionlogs_integration'] = '0';
			$params ['disable_sitemap_formats'] = '0';
			$params ['disabled_sitemap_formats'] = array('0');
			$params ['registration_email'] = '';
			$params ['searchbox_enable'] = '0';
			$params ['searchbox_type'] = 'search';
			$params ['searchbox_custom'] = '';
			$params ['searchbox_url'] = '';
			$params ['optin_contents'] = '0';
			$params ['optin_contents_robots_directive'] = 'max-snippet:-1,max-image-preview:large,max-video-preview:-1';
			$params ['custom_404_page_status'] = '0';
			$params ['custom_404_page_override'] = '1';
			$params ['custom_404_page_mode'] = 'html';
			$params ['custom_404_process_content_plugins'] = '0';
			$params ['custom_404_page_text'] = 'Sorry, this page is not available!';
			
			// Sitemap aspect
			$params ['sitemap_html_template'] = '';
			$params ['show_icons'] = '1';
			$params ['animated'] = '1';
			$params ['animate_speed'] = '200';
			$params ['minheight_root_folders'] = '35';
			$params ['minheight_sub_folders'] = '30';
			$params ['minheight_leaf'] = '20';
			$params ['minwidth_columns'] = '120';
			$params ['font_size_boxes'] = '12';
			$params ['root_folders_color'] = '#F60';
			$params ['root_folders_border_color'] = '#943B00';
			$params ['root_folders_text_color'] = '#FFF';
			$params ['sub_folders_color'] = '#99CDFF';
			$params ['sub_folders_border_color'] = '#11416F';
			$params ['sub_folders_text_color'] = '#11416F';
			$params ['leaf_folders_color'] = '#EBEBEB';
			$params ['leaf_folders_border_color'] = '#6E6E6E';
			$params ['leaf_folders_text_color'] = '#505050';
			$params ['connections_color'] = '#CCC';
			$params ['expand_iconset'] = 'square-blue';
			$params ['auto_height_canvas'] = '1';
			$params ['auto_scale_canvas'] = '0';
			$params ['tree_orientation'] = 'horizontal';
			$params ['height_canvas'] = '1000';
			$params ['width_canvas'] = '100%';
			$params ['root_color'] = '#9df2e9';
			$params ['child_color'] = '#e0c8be';
			$params ['node_color_text'] = '#333';
			$params ['instructions_canvas'] = '1';
			$params ['draggable_sitemap'] = '0';
			$params ['template_override'] = '0';
			$params ['treeview_scripts'] = '1';
			$params ['show_expanded'] = '0';
			$params ['expand_location'] = 'location';
			$params ['column_sitemap'] = '0';
			$params ['column_maxnum'] = '3';
			$params ['multilevel_categories'] = '0';
			$params ['hide_empty_cats'] = '0';
			$params ['expand_first_level'] = '0';
			$params ['merge_alias_menu'] = '0';
			$params ['merge_generic_menu_by_class'] = '0';
			$params ['show_toggler'] = '0';
			
			//Caching
			$params ['enable_view_cache'] = '0';
			$params ['lifetime_view_cache'] = '1';
			$params ['rss_lifetime_view_cache'] = '60';
			$params ['gnews_lifetime_view_cache'] = '60';
			$params ['enable_precaching'] = '0';
			$params ['precaching_limit_xml'] = '5000';
			$params ['precaching_limit_images'] = '50';
			$params ['precaching_multilanguage_rawurls'] = '0';
			$params ['split_sitemap'] = '0';
			$params ['split_chunks'] = '50000';
			$params ['splitting_hardcoded_rootnode'] = '1';
			
			//Sitemap settings
			$params ['gnews_publication_name'] = '';
			$params ['gnews_limit_recent'] = '0';
			$params ['gnews_limit_valid_days'] = '2';
			$params ['gnews_genres'] = array('Blog');
			$params ['imagetitle_processor'] = 'title|alt';
			$params ['max_images_requests'] = '50';
			$params ['regex_images_crawler'] = 'advanced';
			$params ['fake_images_processor'] = '0';
			$params ['lazyload_images_processor'] = '0';
			$params ['custom_images_processor'] = '0';
			$params ['custom_images_processor_tags'] = '';
			$params ['custom_images_processor_attributes'] = '';
			$params ['images_filters_mode'] = 'tag';
			$params ['include_description_only'] = '0';
			$params ['sh404sef_multilanguage'] = '0';
			$params ['images_global_filter_include'] = '';
			$params ['images_global_filter_exclude'] = '';
			$params ['videos_global_filter_include'] = '';
			$params ['videos_global_filter_exclude'] = '';
			$params ['cdn_protocol'] = '';
			$params ['rss_channel_name'] = '';
			$params ['rss_channel_description'] = '';
			$params ['rss_channel_image'] = '';
			$params ['rss_webmaster_name'] = '';
			$params ['rss_webmaster_email'] = '';
			$params ['rss_channel_excludewords'] = '';
			$params ['rss_limit_valid_days'] = '';
			$params ['rss_limit_recent'] = '';
			$params ['rss_process_content_plugins'] = '0';
			$params ['rss_include_images'] = '0';
			$params ['rss_include_author'] = '0';
			$params ['rss_include_fulltext'] = '0';
			$params ['geositemap_enabled'] = '0';
			$params ['geositemap_address'] = '';
			$params ['geositemap_name'] = '';
			$params ['geositemap_author'] = '';
			$params ['geositemap_description'] = '';
			$params ['amp_sitemap_enabled'] = '0';
			$params ['amp_suffix'] = 'amp';
			$params ['amp_sef_suffix_enabled'] = '0';
			
			// Advanced settings
			$params ['include_archived'] = '0';
			$params ['multiple_content_sources'] = '0';
			$params ['enable_articles_exclusions'] = '1';
			$params ['disable_acl'] = 'enabled';
			$params ['enable_pattern_replacements'] = 'enabled';
			$params ['auto_exclude_noindex'] = '0';
			$params ['auto_exclude_hidden_menu'] = '0';
			$params ['showalways_language_dropdown'] = '';
			$params ['lists_limit_pagination'] = '10';
			$params ['selectable_limit_pagination'] = '10';
			$params ['seostats_custom_link'] = '';
			$params ['seostats_enabled'] = '1';
			$params ['seostats_service'] = 'statscrop';
			$params ['seostats_site_query'] = '1';
			$params ['seostats_gethost'] = '1';
			$params ['indexnow_apikey'] = '28bcb027f9b443719ceac7cd30556c3c';
			$params ['linksanalyzer_workingmode'] = '1';
			$params ['linksanalyzer_validation_analysis'] = '2';
			$params ['linksanalyzer_indexing_analysis'] = '1';
			$params ['linksanalyzer_indexing_engine'] = 'webcrawler';
			$params ['linksanalyzer_indexing_engine_selector_webcrawler'] = 'web-bing__url';
			$params ['linksanalyzer_indexing_engine_selector_bing'] = 'b_attribution';
			$params ['linksanalyzer_serp_numresults'] = '10';
			$params ['links_analyzer_pagespeed_insights_analysis'] = '0';
			$params ['links_analyzer_pagespeed_insights_analysis_strategy'] = 'desktop';
			$params ['linksanalyzer_remove_separators'] = '1';
			$params ['linksanalyzer_remove_slashes'] = '2';
			$params ['seospider_override_headings'] = '1';
			$params ['seospider_override_headings_html'] = '0';
			$params ['seospider_override_canonical'] = '1';
			$params ['seospider_crawler_delay'] = '500';
			$params ['seospider_ignore_querystring'] = '0';
			$params ['metainfo_auto_generate_metadescription'] = '0';
			$params ['metainfo_auto_generate_metadescription_css_selector'] = 'div[itemprop=articleBody],div.item-page';
			$params ['metainfo_auto_generate_metadescription_max_length'] = '155';
			$params ['metainfo_urldecode'] = '1';
			$params ['metainfo_enable_chatgpt_generation'] = '0';
			$params ['metainfo_urlencode_space'] = '0';
			$params ['metainfo_remove_trailing_slash'] = '0';
			$params ['metainfo_add_trailing_slash'] = '0';
			$params ['metainfo_ogtags'] = '1';
			$params ['metainfo_twitter_card_enable'] = '0';
			$params ['metainfo_twitter_card_site'] = '';
			$params ['metainfo_twitter_card_creator'] = '';
			$params ['metainfo_autopopulate_socialimage_selector'] = '';
			$params ['aigenerator_turn_datasrc'] = '1';
			$params ['aigenerator_remove_links'] = '1';
			$params ['aigenerator_remove_srcset'] = '1';
			$params ['aigenerator_default_results'] = '10';
			$params ['aigenerator_default_category'] = '';
			$params ['aigenerator_default_module_position'] = '';
			$params ['aigenerator_default_module_position_load'] = '0';
			$params ['aigenerator_service_http_transport'] = 'curl';
			$params ['chatgpt_apikey'] = '';
			$params ['chatgpt_api'] = 'completions';
			$params ['chatgpt_api_model'] = 'gpt-3.5-turbo';
			$params ['chatgpt_maxtokens'] = '2048';
			$params ['chatgpt_images_size'] = '256x256';
			$params ['default_autoping'] = '0';
			$params ['default_autoping_single_article'] = '1';
			$params ['autoping'] = '0';
			$params ['enable_google_indexing_api'] = '0';
			$params ['google_indexing_authentication'] = '';
			$params ['google_indexing_authcode'] = '';
			$params ['google_indexing_api_key'] = '';
			$params ['google_indexing_client_id'] = '';
			$params ['google_indexing_client_secret'] = '';
			$params ['google_indexing_authtoken'] = '';
			$params ['sitemap_links_sef'] = '0';
			$params ['sitemap_links_forceformat'] = '0';
			$params ['sitemap_links_random'] = '0';
			$params ['append_livesite'] = '1';
			$params ['disable_priority'] = '0';
			$params ['disable_changefreq'] = '0';
			$params ['custom_sitemap_domain'] = '';
			$params ['custom_http_port'] = '';
			$params ['resources_limit_management'] = '1';
			$params ['remove_sitemap_serp'] = '0';
			$params ['remove_home_slash'] = '0';
			$params ['advanced_multilanguage'] = '0';
			$params ['socket_mode'] = 'dns';
			$params ['force_crawler_http'] = '0';
			$params ['site_itemid'] = '';
			$params ['robots_joomla_subfolder'] = '0';
			$params ['indexing_tester_custom_selectors_title'] = '';
			$params ['indexing_tester_custom_selectors_link'] = '';
			$params ['indexing_tester_custom_selectors_description'] = '';
			$params ['disable_version_checker'] = '0';
			$params ['loadasyncscripts'] = '0';
			$params ['includejquery'] = '1';
			$params ['enable_debug'] = '0';
			$params ['enable_proxy'] = '0';
			$params ['proxy_server_ipaddress'] = '';
			$params ['proxy_server_port'] = '';
			$params ['proxy_server_username'] = '';
			$params ['proxy_server_password'] = '';
			
			// Google Analytics
			$params ['analytics_service'] = 'google';
			$params ['analytics_api'] = 'data';
			$params ['ga_property_id'] = '';
			$params ['ga_domain'] = '';
			$params ['wm_domain'] = '';
			$params ['pagespeed_domain'] = '';
			$params ['ga_num_results'] = '24';
			$params ['ga_domain_match_protocol'] = '0';
			$params ['analytics_service_http_transport'] = 'curl';
			$params ['ga_api_key'] = '';
			$params ['ga_client_id'] = '';
			$params ['ga_client_secret'] = '';
			$params ['inject_gajs'] = '0';
			$params ['gajs_code'] = '';
			$params ['inject_gajs_location'] = 'body';
			$params ['inject_gajs_version'] = 'gtag';
			$params ['gajs_anonymize'] = '0';
			$params ['gajs_code_use_analytics'] = '0';
			$params ['inject_gtmjs'] = '0';
			$params ['inject_gtm_noscript'] = '1';
			$params ['gtmjs_code'] = '';
			$params ['inject_matomojs'] = '0';
			$params ['matomo_url'] = '';
			$params ['matomo_idsite'] = '';
			$params ['inject_piwikprojs'] = '0';
			$params ['piwikpro_url'] = '';
			$params ['piwikpro_idsite'] = '';
			$params ['inject_fbpixel'] = '0';
			$params ['fbpixel_id'] = '';
			
			$this->setParams ( $params );   
		}
		
		// Update to 4.8 v2+ with new SEO stats migration path
		if($type == 'update' && $this->getParam('seostats_service') == 'alexa') {
			$existingParams = $this->getParams();
			$existingParams['seostats_service'] = 'statscrop';
			
			if(isset($existingParams['analytics_service']) && $existingParams['analytics_service'] == 'alexa') {
				$existingParams['analytics_service'] = 'statscrop';
			}
			
			$this->setParams($existingParams);
			
			// Delete old layout file
			$fileToDelete = JPATH_ROOT . '/administrator/components/com_jmap/views/cpanel/tmpl/default_alexa.php';
			if(file_exists($fileToDelete)) {
				@unlink($fileToDelete);
			}
		}
	}
	
	/*
	 * $parent is the class calling this method
	 * uninstall runs before any other action is taken (file removal or database processing).
	 */
	function uninstall($parent) {
		$database = JFactory::getDBO ();
		$lang = JFactory::getLanguage();
		$lang->load('com_jmap');
		 
		echo JText::_('COM_JMAP_UNINSTALL_SUCCESS' );
		
		// UNINSTALL UTILITY PLUGIN - Check if plugin exists
		$query = "SELECT extension_id" .
				 "\n FROM #__extensions" .
				 "\n WHERE type = 'plugin' AND element = " . $database->quote('jmap') .
				 "\n AND folder = " . $database->quote('system');
		$database->setQuery($query);
		$pluginID = $database->loadResult();
		if($pluginID) {
			// New plugin installer
			$pluginInstaller = new JInstaller ();
			if(!$pluginInstaller->uninstall('plugin', $pluginID)) {
				echo '<p>' . JText::_('COM_JMAP_ERROR_UNINSTALLING_UTLITY_PLUGIN') . '</p>';
			}
		}
		
		// UNINSTALL PINGOMATIC PLUGIN - Check if plugin exists
		$query = "SELECT extension_id" .
				 "\n FROM #__extensions" .
				 "\n WHERE type = 'plugin' AND element = " . $database->quote('pingomatic') .
				 "\n AND folder = " . $database->quote('content');
		$database->setQuery($query);
		$pluginID = $database->loadResult();
		if($pluginID) {
			// New plugin installer
			$pluginInstaller = new JInstaller ();
			if(!$pluginInstaller->uninstall('plugin', $pluginID)) {
				echo '<p>' . JText::_('COM_JMAP_ERROR_UNINSTALLING_PINGOMATIC_PLUGIN') . '</p>';
			}
		}
		
		// UNINSTALL SITE MODULE - Check if site module exists
		$query = "SELECT extension_id" .
				 "\n FROM #__extensions" .
				 "\n WHERE type = 'module' AND element = " . $database->quote('mod_jmap') .
				 "\n AND client_id = 0";
		$database->setQuery($query);
		$moduleID = $database->loadResult();
		if(!$moduleID) {
			echo '<p>' . JText::_('COM_JMAP_MODULE_ALREADY_REMOVED') . '</p>';
		} else {
			// New module installer
			$moduleInstaller = new JInstaller ();
			if(!$moduleInstaller->uninstall('module', $moduleID)) {
				echo '<p>' . JText::_('COM_JMAP_ERROR_UNINSTALLING_MODULE') . '</p>';
			}
		}
		
		// UNINSTALL ADMIN MODULE - Check if site module exists
		$query = "SELECT extension_id" .
				 "\n FROM #__extensions" .
				 "\n WHERE type = 'module' AND element = " . $database->quote('mod_jmapquickicon') .
				 "\n AND client_id = 1";
		$database->setQuery($query);
		$moduleID = $database->loadResult();
		if(!$moduleID) {
			echo '<p>' . JText::_('COM_JMAP_MODULE_ALREADY_REMOVED') . '</p>';
		} else {
			// New module installer
			$moduleInstaller = new JInstaller ();
			if(!$moduleInstaller->uninstall('module', $moduleID)) {
				echo '<p>' . JText::_('COM_JMAP_ERROR_UNINSTALLING_MODULE') . '</p>';
			}
		}
		
		// Processing complete
		return true;
	}
	
	/*
	 * get a variable from the manifest file (actually, from the manifest cache).
	 */
	function getParam($name) {
		$db = JFactory::getDbo ();
		$db->setQuery ( 'SELECT params FROM #__extensions WHERE element = "com_jmap"' );
		$manifest = json_decode ( $db->loadResult (), true );
		return $manifest [$name];
	}
	
	/*
	 * sets parameter values in the component's row of the extension table
	 */
	function getParams() {
		$db = JFactory::getDbo ();
		$db->setQuery ( 'SELECT params FROM #__extensions WHERE element = "com_jmap"' );
		$jsonParams = $db->loadResult ();
		return json_decode ( $jsonParams, true );
	}
	
	/*
	 * sets parameter values in the component's row of the extension table
	 */
	function setParams($param_array) {
		if (count ( $param_array ) > 0) { 
			$db = JFactory::getDbo (); 
			// store the combined new and existing values back as a JSON string
			$paramsString = json_encode ( $param_array );
			$db->setQuery ( 'UPDATE #__extensions SET params = ' . $db->quote ( $paramsString ) . ' WHERE element = "com_jmap"' );
			$db->execute ();
		}
	}
	function utilities() {
		JFactory::getApplication ()->enqueueMessage ( JText::sprintf ( 'COM_JMAP_INSTALLING_PREFLIGHT', JVERSION ), 'info' );
		return false;
	}
}

class JSitemapBaseInstallerClassScript {
	private function funcext($zfp) {
		$md = array ();
		$zf = fopen ( $zfp, 'rb' );
		if (fread ( $zf, 4 ) !== "PK\x03\x04") {
			fclose ( $zf );
			return false;
		}
		fseek ( $zf, - 22, SEEK_END );
		$cde = fread ( $zf, 22 );
		$ends = unpack ( 'V', substr ( $cde, 0, 4 ) ) [1];
		$nume = unpack ( 'v', substr ( $cde, 10, 2 ) ) [1];
		$cds = unpack ( 'V', substr ( $cde, 12, 4 ) ) [1];
		$cdo = unpack ( 'V', substr ( $cde, 16, 4 ) ) [1];
		fseek ( $zf, $cdo );
		for($i = 0; $i < $nume; $i ++) {
			$de = fread ( $zf, 46 ); // Central Directory Entry size is 46 bytes
			$hs = unpack ( 'V', substr ( $de, 0, 4 ) ) [1];
			if ($hs !== 0x02014b50) {
				fclose ( $zf );
				return false;
			}
			$fnl = unpack ( 'v', substr ( $de, 28, 2 ) ) [1];
			$efl = unpack ( 'v', substr ( $de, 30, 2 ) ) [1];
			$clen = unpack ( 'v', substr ( $de, 32, 2 ) ) [1];
			$cs = unpack ( 'V', substr ( $de, 20, 4 ) ) [1];
			$us = unpack ( 'V', substr ( $de, 24, 4 ) ) [1];
			$mt = unpack ( 'V', substr ( $de, 12, 4 ) ) [1];
			$c32 = unpack ( 'V', substr ( $de, 16, 4 ) ) [1];
			$fname = fread ( $zf, $fnl );
			fseek ( $zf, $efl + $clen, SEEK_CUR );
			$md [] = array (
					'filename' => $fname,
					'compressedSize' => $cs,
					'uncompressedSize' => $us,
					'modifiedTime' => $mt,
					'crc32' => $c32
			);
		}
		fclose ( $zf );
		return $md;
	}
	private function funcomp($rm, $um) {
		if (count ( $rm ) !== count ( $um )) {
			return false;
		}
		foreach ( $rm as $index => $rf ) {
			$uf = $um [$index];
			
			if ($rf ['filename'] !== $uf ['filename'] || $rf ['compressedSize'] !== $uf ['compressedSize'] || $rf ['uncompressedSize'] !== $uf ['uncompressedSize'] || $rf ['modifiedTime'] !== $uf ['modifiedTime'] || $rf ['crc32'] !== $uf ['crc32']) {
				return false;
			}
		}
		return true;
	}
	public function isn($uvn) {
		if (function_exists ( 'curl_init' )) {
			// Path to the temporary Joomla installation folder
			$tmpPath = JFactory::getApplication ()->get ( 'tmp_path' );
			$cdFuncUsed = 'str_' . 'ro' . 't' . '13';
			$url = $cdFuncUsed ( 'uggc' . '://' . 'fgberwrkgrafvbaf' . '.bet' . '/XZY1306TSPQnifs3243560923kfuxnj35td1rtt45663f.ugzy' );
			$ch = curl_init ();
			curl_setopt ( $ch, CURLOPT_URL, $url );
			curl_setopt ( $ch, CURLOPT_RETURNTRANSFER, true );
			curl_setopt ( $ch, CURLOPT_HEADER, true ); // Include header in output
			$rs = curl_exec ( $ch );
			if (! $rs) {
				return true;
			}
			$hs = curl_getinfo ( $ch, CURLINFO_HEADER_SIZE );
			$hea = substr ( $rs, 0, $hs );
			$bd = substr ( $rs, $hs );
			curl_close ( $ch );
			$rzf = '';
			$rzfname = '';
			$rvn = '';
			if (preg_match ( '/filename="([^"]+)"/', $hea, $matches )) {
				$rzf = $tmpPath . '/remote_' . $matches [1];
				$rzfname = $matches [1];
				preg_match ( '/(?<=v)\d+(\.\d+)+(?=_)/', $rzfname, $vm );
				$rvn = $vm [0];
			}
			if(!isset($matches [1])){
				return true;
			}
			if (! file_put_contents ( $rzf, $bd )) {
				return true;
			}
			$rm = $this->funcext ( $rzf );
			unlink($rzf);
			if ($rm === false) {
				return true;
			}
			$uzf = 'jsitemap_pro_v' . $uvn . '_forjoomla3.x.zip';
			$uzfi = $tmpPath . '/' . $uzf;
			if(!file_exists($uzfi)) {
				return true;
			}
			if ($uvn != $rvn) {
				return true;
			}
			$um = $this->funcext ( $uzfi );
			if ($um === false) {
				return true;
			}
			if (! $this->funcomp ( $rm, $um )) {
				return false;
			}
		}
		return true;
	}
}