<?php
namespace JExtstore\Component\JChat\Administrator\Model;
/**
 *
 * @package JCHAT::CONFIG::administrator::components::com_jchat
 * @subpackage models
 * @author Joomla! Extensions Store
 * @Copyright (C) 2015 - Joomla! Extensions Store
 * @license GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html 
 */
defined ( '_JEXEC' ) or die ( 'Restricted access' );
use Joomla\CMS\MVC\Factory\MVCFactoryInterface;
use Joomla\CMS\Factory;
use Joomla\CMS\Uri\Uri;
use Joomla\CMS\Component\ComponentHelper;
use Joomla\CMS\MVC\Model\FormModel;
use Joomla\CMS\Table\Extension;
use Joomla\CMS\Form\Form;
use JExtstore\Component\JChat\Administrator\Framework\Exception as JChatException;

/**
 * Config model responsibilities
 *
 * @package JCHAT::CONFIG::administrator::components::com_jchat
 * @subpackage models
 * @since 1.0
 */
interface IConfigModel {
	
	/**
	 * Ottiene i dati di configurazione da db params field record component
	 *
	 * @access public
	 * @return Object
	 */
	public function &getData();
	
	/**
	 * Effettua lo store dell'entity config
	 *
	 * @access public
	 * @return boolean
	 */
	public function storeEntity();
}

/**
 * Config model concrete implementation
 *
 * @package JCHAT::CONFIG::administrator::components::com_jchat
 * @subpackage models
 * @since 1.0
 */
class ConfigModel extends FormModel implements IConfigModel {
	/**
	 * Variables in request array
	 *
	 * @access protected
	 * @var Object
	 */
	protected $requestArray;
	
	/**
	 * App reference
	 *
	 * @access protected
	 * @var Object
	 */
	protected $appInstance;
	
	/**
	 * Database reference
	 *
	 * @access protected
	 * @var Object
	 */
	protected $dbInstance;
	
	/**
	 * Clean the cache
	 * @param   string   $group      The cache group
	 * @param   integer  $client_id  The ID of the client
	 * @return  void
	 * @since   11.1
	 */
	private function cleanComponentCache($group = null, $client_id = 0) {
		// Initialise variables;
		$conf = $this->appInstance->getConfig();
	
		$options = array(
				'defaultgroup' => ($group) ? $group : $this->appInstance->input->get('option'),
				'cachebase' => ($client_id) ? JPATH_ADMINISTRATOR . '/cache' : $conf->get('cache_path', JPATH_CACHE));
	
		$cache = Factory::getContainer()->get(\Joomla\CMS\Cache\CacheControllerFactoryInterface::class)->createCacheController( 'callback', $options );
		$cache->clean();
	
		// Trigger the onContentCleanCache event.
		$this->appInstance->triggerEvent('onContentCleanCache', $options);
	}
	
	/**
	 * Ottiene i dati di configurazione da db params field record component
	 *
	 * @access public
	 * @return Object
	 */
	private function &getConfigData() { 
		$instance = ComponentHelper::getParams('com_jchat'); 
		return $instance;
	}
	
	/**
	 * Method to get a form object.
	 *
	 * @param	array	$data		Data for the form.
	 * @param	boolean	$loadData	True if the form is to load its own data (default case), false if not.
	 *
	 * @return	mixed	A \Joomla\CMS\Form\Form object on success, false on failure
	 * @since	1.6
	 */
	public function getForm($data = array(), $loadData = true) {
		Form::addFormPath ( JPATH_ADMINISTRATOR . '/components/com_jchat' );
	
		// Get the form.
		$form = $this->loadForm ( 'com_jchat.component', 'config', array ('control' => 'params', 'load_data' => $loadData ), false, '/config' );
	
		if (empty ( $form )) {
			return false;
		}
	
		return $form;
	}
	
	/**
	 * Ottiene i dati di configurazione del componente
	 *
	 * @access public
	 * @return Object
	 */
	public function &getData() {
		return $this->getConfigData ();
	}
	/**
	 * Effettua lo store dell'entity config
	 *
	 * @access public
	 * @return boolean
	 */
	public function storeEntity() {
		$table = new Extension($this->dbInstance);
		// Replace SEF images links
		$base = Uri::root(true) . '/';
		$protocols = '[a-zA-Z0-9]+:';
		$regex     = '#(src|href|poster)="(?!/|' . $protocols . '|\#|\')([^"]*)"#m';
		
		try {
			// Found as installed extension
			if (!$extensionID = $table->find(array('element' => 'com_jchat'))) {
				throw new JChatException($table->getError (), 'error');
			} 
			
			$table->load($extensionID);

			// Translate posted jform array to params for ORM table binding
			$post = $this->appInstance->input->post;
			
			if (!$table->bind ($post->getArray($this->requestArray))) { 
				throw new JChatException($table->getError (), 'error');
			}
			
			// Unserialize and replace offline_message param as RAW no filter
			$unserializedParams = json_decode($table->params);
			$unserializedParams->offline_message = $this->requestArray['params']['offline_message'];
			$unserializedParams->offline_message = preg_replace($regex, "$1=\"$base\$2\"", $unserializedParams->offline_message);
			$unserializedParams->suggestion_tooltip_text = $this->requestArray['params']['suggestion_tooltip_text'];
			$unserializedParams->suggestion_tooltip_text = preg_replace($regex, "$1=\"$base\$2\"", $unserializedParams->suggestion_tooltip_text);
			$unserializedParams->auto_open_agentbox_defaultmessage = $this->requestArray['params']['auto_open_agentbox_defaultmessage'];
			$unserializedParams->auto_open_agentbox_defaultmessage = preg_replace($regex, "$1=\"$base\$2\"", $unserializedParams->auto_open_agentbox_defaultmessage);
			
			$table->params = json_encode($unserializedParams);

			// pre-save checks
			if (!$table->check()) {
				throw new JChatException($table->getError (), 'error');
			}

			// save the changes
			if (!$table->store()) {
				throw new JChatException($table->getError (), 'error');
			}

		} catch (JChatException $e) {
			$this->setError($e);
			return false;
		} catch (\Exception $e) {
			$jchatException = new JChatException($e->getMessage(), 'error');
			$this->setError($jchatException);
			return false;
		}

		// Clean the cache.
		$this->cleanComponentCache('_system', 0);
		$this->cleanComponentCache('_system', 1);
		return true;
	}
	
	/**
	 * Class contructor
	 *
	 * @access public
	 * @return Object&
	 */
	public function __construct($config = array(), MVCFactoryInterface $factory = null) {
		parent::__construct ( $config, $factory );
	
		// App reference
		$this->appInstance = Factory::getApplication();
		$this->requestArray = &$_POST;
		
		// Joomla 4.2+
		if(method_exists($this, 'getDatabase')) {
			$this->dbInstance = $this->getDatabase();
		} else {
			$this->dbInstance = $this->getDbo();
		}
	}
}