<?php
/*
 * Software Name: Eorisis Pixels
 * Software URI: https://eorisis.com/shop/software/joomla/pixels
 * Author: Eorisis
 * Author URI: https://eorisis.com
 * Copyright: Copyright (C) 2011-2025 EORISIS. All Rights Reserved.
 * License: GNU General Public License version 2; See https://eorisis.com/gpl
 * Terms of Service: https://eorisis.com/tos
 */
defined('_JEXEC') or die;

if (version_compare(JVERSION, '3.8', '>='))
{
	JLoader::registerAlias('EorisisFactory', '\\Joomla\\CMS\\Factory');
	JLoader::registerAlias('EorisisInstaller', '\\Joomla\\CMS\\Installer\\Installer');
}
else
{
	JLoader::registerAlias('EorisisFactory', 'JFactory');
	JLoader::registerAlias('EorisisInstaller', 'JInstaller');
}

class com_eorisis_pixelsInstallerScript
{
	const EXTENSION_NAME = 'Pixels';
	const MIN_JVERSION = '3.6.0';
	const PKG_ELEMENT = 'pkg_eorisis_pixels';

	// --------------------------------------------------

	public function preflight($type, $parent) // void|bool
	{
		// Preflight is executed prior to any Joomla install,
		// update or discover_install actions (or uninstall for plugins).
		$type = strtolower($type);

		if ($type == 'uninstall')
		{
			return;
		}

		if (!defined('EORISIS_PKG_INSTALL'))
		{
			if (defined('EORISIS_PKG_INSTALL_ABORT') or $this->is_invalid_install($type))
			{
				return false;
			}
		}

		if (defined('EORISIS_PKG_INSTALL_ABORT') or $this->is_old_jversion())
		{
			return false;
		}
	}

	// --------------------------------------------------

	public function install($parent) // void|bool
	{
		if (!defined('EORISIS_PKG_INSTALL'))
		{
			return false;
		}
	}

	// --------------------------------------------------

	public function update($parent) // void|bool
	{
		if (!defined('EORISIS_PKG_INSTALL'))
		{
			return false;
		}
	}

	// --------------------------------------------------

	public function uninstall($parent) // void
	{
		// Uninstall cannot cause an abort of the Joomla uninstall action
		// returning false does nothing
		// --------------------------------------------------

		if ($this->is_pkg_uninstall($parent))
		{
			return;
		}

		// Uninstall the whole package on Component Uninstall,
		// if the uninstall does not originate from the package installer

		$id = $this->get_package_identifier(self::PKG_ELEMENT);
		if (!$id)
		{
			return;
		}

		$installer = new EorisisInstaller;
		$installer->uninstall('package', $id);
	}

	// --------------------------------------------------

//	public function postflight($type, $parent) {}

	// --------------------------------------------------

	private function is_pkg_uninstall($parent) : bool
	{
		if (version_compare(JVERSION, '3.7', '>='))
		{
			return (bool)$parent->getParent()->get('packageUninstall');
		}

		if (version_compare(JVERSION, '3.6', '<'))
		{
			// 3.6.0 or older are not yet supported
			return true;
		}

		if (!function_exists('debug_backtrace'))
		{
			return false;
		}

		$arr = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
		if (!$arr)
		{
			return false;
		}

		foreach ($arr as $trace)
		{
			if (empty($trace['function']) or empty($trace['file']))
			{
				continue;
			}

			if ($trace['function'] != 'uninstall')
			{
				continue;
			}

			if (strpos((string)$trace['file'], '/libraries/cms/installer/adapter/package.php') !== false)
			{
				return true;
			}
		}
		
		return false;
	}

	// --------------------------------------------------

	private function get_package_identifier(string $element) : int
	{
		$dbo = $this->dbo();
		$query = $dbo->getQuery(true);
		$query->select($dbo->quoteName('extension_id'));
		$query->from($dbo->quoteName('#__extensions'));
		$query->where([
			$dbo->quoteName('type').'='.$dbo->quote('package'),
			$dbo->quoteName('element').'='.$dbo->quote($element)
		]);
		$dbo->setQuery($query);
		$result = $this->get_first_result($dbo);
		return $result['error'] ? 0 : (int)$result['record'];
	}

	// --------------------------------------------------

	private function set_message(string $txt, string $type) // void
	{
		EorisisFactory::getApplication()->enqueueMessage($txt, $type);
	}

	// --------------------------------------------------

	private function is_invalid_install($type) : bool
	{
		if (!in_array($type, ['install','update','discover_install']))
		{
			return false;
		}

		// Display a warning and abort on install, if the install does not originate from the package installer
		$txt  = 'This component is part of a full package and cannot be installed separately. ';
		$txt .= 'You may install <b>Eorisis '.self::EXTENSION_NAME.'</b> <span style="text-decoration:underline">Package</span> instead.<br>';
		$txt .= 'The downloadable archive file is intended to be used as-is at the Joomla Extensions Manager.<br>';
		$txt .= 'This will execute the package installer and perform all tasks required.<br>';
		$txt .= 'DO NOT unzip/extract or upload separate files that are included in the package in order to perform an install or update.<br>';
		$txt .= 'Doing so may lead to errors.<br>';
		$txt .= 'If you are facing trouble with the installation please report it directly at '.$this->support();
		$this->set_message($txt, 'warning');
		define('EORISIS_PKG_INSTALL_ABORT', 1);
		return true;
	}

	// --------------------------------------------------

	private function is_old_jversion() : bool
	{
		if (!version_compare(JVERSION, '2.5.4', '<'))
		{
			return false;
		}

		$txt  = '<b>Eorisis '.self::EXTENSION_NAME.'</b> ';
		$txt .= 'installation cannot continue because you are running Joomla <b>'.JVERSION.'</b>.<br>';
		$txt .= 'The minimum Joomla version for this extension is <b>'.self::MIN_JVERSION.'</b>.<br>';
		$txt .= 'You must upgrade your Joomla before you can install this extension.';
		$this->set_message($txt, 'warning');
		define('EORISIS_PKG_INSTALL_ABORT', 1);
		return true;
	}

	// --------------------------------------------------

	public function dbo()
	{
		static $obj = null;
		if ($obj === null)
		{
			if (version_compare(JVERSION, 4, '>='))
			{
				$obj = EorisisFactory::getContainer()->get('DatabaseDriver');
			}
			else
			{
				$obj = EorisisFactory::getDbo();
			}
		}

		return $obj;
	}

	// --------------------------------------------------

	private function get_first_result($dbo) : array // Do not restrict object for php < 7.2
	{
		$result['record'] = [];
		$result['error'] = '';

		try
		{
			$result['record'] = $dbo->loadResult();
		}
		catch(PDOException $exception)
		{
			$result['error'] = (string)$exception->getMessage();
		}
		catch(Throwable $exception)
		{
			$result['error'] = (string)$exception->getMessage();
		}

		return $result;
	}

	// --------------------------------------------------

	private function support() : string
	{
		$email = 'support@eorisis.com';
		return '<a href="mailto:'.$email.'" target="_top">'.$email.'</a>';
	}
}
