<?php
/**
* @package		Komento
* @copyright	Copyright (C) Stack Ideas Sdn Bhd. All rights reserved.
* @license		GNU/GPL, see LICENSE.php
* Komento is free software. This version may have been modified pursuant
* to the GNU General Public License, and as distributed it includes or
* is derivative of works licensed under the GNU General Public License or
* other free or open source software licenses.
* See COPYRIGHT.php for copyright notices and details.
*/
use Joomla\CMS\Factory;
use Joomla\CMS\Language\Text;
use Joomla\CMS\Installer\InstallerHelper;
use Joomla\Registry\Registry;

defined('_JEXEC') or die('Unauthorized Access');

require_once(__DIR__ . '/controller.php');

class KomentoControllerInstallPost extends KomentoSetupController
{
	/**
	 * Post installation process
	 *
	 * @since	3.0
	 * @access	public
	 */
	public function execute()
	{
		$results = array();

		// Get the api key so that we can store it
		$key = $this->input->get('apikey', '', 'default');

		// Skip this when we are on development mode
		if ($this->isDevelopment()) {
			return $this->output($this->getResultObj('COM_KOMENTO_INSTALLATION_DEVELOPER_MODE', true));
		}

		// Update api key
		$this->updateConfig('main_apikey', SI_KEY);

		$results[] = $this->initConfig(); 

		// ACL rules needs to be created first before anything else
		$results[] = $this->initACL();

		$this->updateAdminMenu();

		// Purge captcha records
		$this->purgeCaptcha();

		// Update the manifest_cache in #__extensions table
		$this->updateManifestCache();

		// Delete the komento from the Updates table
		$this->deleteUpdateRecord();

		// Ensure the site MUST enable Komento system plugin now #384
		$this->activateSystemPlugin();

		// Force-write the corrected foundry sidebar.php regardless of installed foundry version
		$this->fixFoundrySidebar();

		$message = '';

		foreach ($results as $obj) {

			if ($obj === false) {
				continue;
			}

			$class = $obj->state ? 'success' : 'error';
			$message .= '<div class="text-' . $class . '">' . $obj->message . '</div>';
		}

		$this->setInfo($message, true);
		return $this->output();
	}

        /**
        * Update the manifest cache
        *
        * @since   3.0
        * @access  public
        */
        public function updateManifestCache()
        {	
	$db = Factory::getDbo();
	$extensionId = $this->getKomentoComponentId();
	
	$manifestPath = JPATH_ADMINISTRATOR . '/components/com_komento/komento.xml';
	
	if (!is_file($manifestPath)) {
		return false;
	}
	
	// Parse XML manifest manually
	$xml = simplexml_load_file($manifestPath);
	
	if ($xml === false) {
		return false;
	}
	
	$manifest_details = [
		'name' => (string) $xml->name,
		'type' => 'component',
		'creationDate' => (string) $xml->creationDate,
		'author' => (string) $xml->author,
		'copyright' => (string) $xml->copyright,
		'authorEmail' => (string) $xml->authorEmail,
		'authorUrl' => (string) $xml->authorUrl,
		'version' => (string) $xml->version,
		'description' => (string) $xml->description,
		'group' => '',
	];
	
	$manifest = json_encode($manifest_details);
	
	// Update using direct database query (modern approach)
	$query = $db->getQuery(true)
		->update($db->quoteName('#__extensions'))
		->set($db->quoteName('manifest_cache') . ' = ' . $db->quote($manifest))
		->where($db->quoteName('extension_id') . ' = ' . $db->quote($extensionId));
	
	$db->setQuery($query);
	
	try {
		$db->execute();
		return true;
	} catch (\Exception $e) {
		return false;
	}
        }

	/**
	 * Delete record in updates table
	 *
	 * @since   3.0
	 * @access  public
	 */
	public function deleteUpdateRecord()
	{
		$this->engine();

		$db = KT::db();

		$query = 'DELETE FROM ' . $db->quoteName('#__updates') . ' WHERE ' . $db->quoteName('extension_id') . '=' . $db->Quote($this->getKomentoComponentId());
		$db->setQuery($query);
		$db->execute();
	}

	/**
	 * Update admin menu
	 *
	 * @since   3.0
	 * @access  public
	 */
	public function updateAdminMenu()
	{	
		$this->engine();

		$db = KT::db();

		$komentoComponentId = $this->getKomentoComponentId();

		if ($komentoComponentId) {
			$query	= 'UPDATE '. $db->quoteName('#__menu')
					. ' SET ' . $db->quoteName('component_id') . ' = ' . $db->quote($komentoComponentId)
					. ' WHERE ' . $db->quoteName('client_id') . ' = ' . $db->quote(1)
					. ' AND ' . $db->quoteName('title') . ' LIKE ' . $db->quote('com_komento%')
					. ' AND ' . $db->quoteName('component_id') . ' != ' . $komentoComponentId;
			$db->setQuery($query);
			$db->execute();
		}
	}

	/**
	 * Update components config
	 *
	 * @since   3.0
	 * @access  public
	 */
	public function initConfig()
	{
		$this->engine();

		$db = KT::db();

		$query	= 'SELECT COUNT(1) FROM ' . $db->quoteName('#__komento_configs')
				. ' WHERE ' . $db->quoteName('name') . ' = ' . $db->quote('config');

		$db->setQuery($query);

		// If this is a fresh new installation OR upgrade from 2.x
		// Here we also need to check if this is upgrade from 2.x, we need to migrate the config over.
		if (!$db->loadResult()) {
			$file = JPATH_ADMINISTRATOR . '/components/com_komento/defaults/configuration.json';

			$content = file_get_contents($file);
			$registry = new Registry($content);

			$obj = new stdClass();
			$obj->name	= 'config';
			$obj->params = $registry->toString();

			$db->insertObject('#__komento_configs', $obj);
		}

		// Once the config is initialized, we need to update it based on any requirement
		// For Joomla2.5, the komento_jquery has to be enabled. 
		$joomlaVersion = $this->getJoomlaVersion();
		
		if ($joomlaVersion < '3.0') {
			$this->updateConfig('komento_jquery', '1');
		}

		return $this->getResultObj(Text::_('COM_KOMENTO_INSTALLATION_CONFIG_INITIALIZED'), true);
	}

	/**
	 * Update the ACL for Komento
	 *
	 * @since	3.0
	 * @access	public
	 */
	public function initACL()
	{
		$this->engine();

		// Skip this when we are on development mode
		if ($this->isDevelopment()) {
			return;
		}

		$db = KT::db();

		// Check if the table is already there
		$query = 'SELECT COUNT(*) FROM ' . $db->quoteName('#__komento_acl');
		$db->setQuery($query);

		if (!$db->loadResult()) {
			
			$usergroupsPath = JPATH_ADMINISTRATOR . '/components/com_komento/defaults/usergroupsacl.json';

			// If the file doesn't exist, quit.
			if (!is_file($usergroupsPath)) {
				return false;
			}

			$contents = file_get_contents($usergroupsPath);

			$usergroups = json_decode($contents);

			$jversion = 'j30';

			foreach ($usergroups->rules as $usergroup => $rules) {
				if (isset($usergroups->mapping->$jversion->$usergroup)) {
					$gid = $usergroups->mapping->$jversion->$usergroup;

					$string = json_encode($rules);

					$query = 'INSERT INTO ' . $db->quoteName('#__komento_acl') . ' VALUES (null, ' . $db->quote($gid) . ', ' . $db->quote('usergroup') . ', ' . $db->quote($string) . ')';

					$db->setQuery($query);
					$db->execute();
				}
			}
		}

		return $this->getResultObj(Text::_('COM_KOMENTO_INSTALLATION_ACL_INITIALIZED'), true);
	}

	public function purgeCaptcha()
	{
		$this->engine();

		$db = KT::db();
		
		$query = 'SELECT COUNT(1) FROM ' . $db->quoteName('#__komento_captcha');
		$db->setQuery($query);

		// If this is a NOT fresh installation
		if ($db->loadResult()) {
			$query = 'DELETE FROM ' . $db->quoteName('#__komento_captcha');

			$db->setQuery($query);
			$db->execute();
		}
	}

	public function getJoomlaVersion()
	{
		$jVerArr = explode('.', JVERSION);
		$jVersion = $jVerArr[0] . '.' . $jVerArr[1];

		return $jVersion;
	}

	public function getKomentoComponentId()
	{
		$this->engine();
		
		$db = KT::db();

		$query 	= 'SELECT ' . $db->quoteName('extension_id')
			. ' FROM ' . $db->quoteName('#__extensions')
			. ' WHERE `element`=' . $db->Quote('com_komento')
			. ' AND `type`=' . $db->Quote('component');

		$db->setQuery($query);

		return $db->loadResult();
	}

	/**
	 * Update the ACL for Komento
	 *
	 * @since	3.1.3
	 * @access	public
	 */
	public function activateSystemPlugin()
	{
		$this->engine();

		// Skip this when we are on development mode
		if ($this->isDevelopment()) {
			return false;
		}

		$db = KT::db();
		$query = array();

		$query[] = 'SELECT `enabled` FROM ' . $db->qn('#__extensions');
		$query[] = 'WHERE ' . $db->qn('folder') . '=' . $db->Quote('system');
		$query[] = 'AND ' . $db->qn('element') . '=' . $db->Quote('komento');

		$query = implode(' ', $query);

		$db->setQuery($query);
		$isEnabled = $db->loadResult();

		if ($isEnabled) {
			return false;
		}

		$query = array();

		$query[] = 'UPDATE ' . $db->qn('#__extensions') . ' SET ' . $db->qn('enabled') . '=' . $db->Quote('1');
		$query[] = 'WHERE ' . $db->qn('folder') . '=' . $db->Quote('system');
		$query[] = 'AND ' . $db->qn('element') . '=' . $db->Quote('komento');

		$query = implode(' ', $query);

		$db->setQuery($query);
		$state = $db->execute();

		return true;

	}

	/**
	 * Force-write the corrected foundry sidebar.php so the admin icon is always correct.
	 * libraries/foundry is a package shared by every CRE8 product on a site, so Joomla's
	 * installer can skip overwriting it if another product's pkg_foundry (with its own
	 * hardcoded icon reference) was installed there more recently at the same version.
	 *
	 * @since	5.0.2
	 * @access	public
	 */
	public function fixFoundrySidebar()
	{
		$target = JPATH_LIBRARIES . '/foundry/themes/html/admin/sidebar.php';

		if (!is_dir(dirname($target))) {
			return false;
		}

		$content = <<<'EOT'
<?php
/**
* @package		Foundry
* @copyright	Copyright (C) Stack Ideas Sdn Bhd. All rights reserved.
* @license		GNU/GPL, see LICENSE.php
* Foundry is free software. This version may have been modified pursuant
* to the GNU General Public License, and as distributed it includes or
* is derivative of works licensed under the GNU General Public License or
* other free or open source software licenses.
* See COPYRIGHT.php for copyright notices and details.
*/
use Joomla\CMS\Language\Text;
use Joomla\CMS\Uri\Uri;

defined('_JEXEC') or die('Unauthorized Access');
?>
<div class="container-nav hidden" data-fd-container-nav>
	<a class="nav-sidebar-toggle" data-bp-toggle="collapse" data-target=".app-sidebar-collapse">
		<i class="fa fa-bars"></i>
		<span><?php echo Text::_('FD_MENU');?></span>
	</a>
	<a class="nav-subhead-toggle" data-target=".subhead-collapse">
		<i class="fa fa-cog"></i>
		<span><?php echo Text::_('FD_OPTIONS');?></span>
	</a>
</div>

<?php if (FH::isJoomla4()) { ?>
<div class="hidden" data-fd-j4-sidebar>
	<li class="item item-level-1">
		<a class="has-arrow" href="javascript:void(0);" aria-expanded="false" data-fd-back-extension>
			<span class="icon-">
				<img src="<?php echo rtrim(Uri::root(), '/');?>/media/<?php echo $this->fd->getComponentName();?>/images/cre8_comments-icon.svg" style="width: 18px;height: 18px;">
			</span>

			<span class="sidebar-item-title"><?php echo $this->fd->getExtensionTitle();?></span>
		</a>
	</li>
</div>
<?php } ?>

<div class="app-sidebar app-sidebar-collapse" data-fd-sidebar>
	<ul class="app-sidebar-nav">
		<?php if (FH::isJoomla4()) { ?>
		<li class="sidebar-item sidebar-item--joomla-4-btn">
			<a href="javascript:void(0);" data-fd-back-joomla>
				<i class="fa fa-chevron-left"></i> <span class="app-sidebar-item-title"><?php echo Text::_('FD_BACK');?></span>
			</a>
		</li>
		<?php } ?>

		<?php foreach ($menus as $menu) { ?>
		<li class="sidebar-item
			<?php echo isset($menu->childs) && $menu->childs ? 'dropdown' : '';?>
			<?php echo $menu->isActive ? ' active' : '';?>"
			data-fd-sidebar-item
		>

			<a href="<?php echo $menu->childs ? 'javascript:void(0);' : $menu->link;?>" data-fd-sidebar-parent
				data-childs="<?php echo isset($menu->childs) && $menu->childs ? '1' : '0';?>"
			>
				<i class="<?php echo $menu->icon;?>"></i>&nbsp;<span class="sidebar-item-title"><?php echo Text::_($menu->title); ?></span>
				<span class="badge
				<?php echo !$menu->isActive && $menu->count > 0 ? 'block' : 'hidden';?>
				<?php echo $menu->isActive && $menu->childs ? 'hidden' : 'block';?>
				" data-fd-parent-badge>&nbsp;</span>
			</a>

			<?php if ($menu->childs) { ?>
			<ul class="dropdown-menu" role="menu">
				<?php foreach ($menu->childs as $child) { ?>
				<li class="<?php echo $child->isActive ? 'active' : '';?>">
					<a href="<?php echo $child->link;?>">
						<span class="app-sidebar-item-title"><?php echo Text::_($child->title);?></span>

						<?php if ($child->count) { ?>
						<span class="badge <?php echo $child->count > 0 ? 'has-counter block' : 'hidden';?>">&nbsp;</span>
						<?php } ?>
					</a>
				</li>
				<?php } ?>
			</ul>
			<?php } ?>
		</li>
		<?php } ?>
	</ul>
</div>
EOT;

		file_put_contents($target, $content);

		return true;
	}
}
