<?php

declare(strict_types=1);

/**
 * This file is part of LEPTON Core, released under the GNU GPL
 * Please see LICENSE and COPYING files in your package for details, specially for terms and warranties.
 * 
 * NOTICE:LEPTON CMS Package has several different licenses.
 * Please see the individual license in the header of each single file or info.php of modules and templates.
 *
 * @author          LEPTON Project
 * @copyright       2010-2026 LEPTON Project
 * @link            https://lepton-cms.org
 * @license         https://gnu.org/licenses/gpl.html
 * @license_terms   please see LICENSE and COPYING files in your package
 *
 */

/**
 *  Methods for LEPTON logging in table log
 *
 */
class LEPTON_logging
{
	public LEPTON_database $database;
	public string $log_table = '';
	public string $logged = NULL;
	public array $secure_data = [];
	public int $user_id = 0;
	public string $username = '';
	public array $sUploadMessages = []; // php upload messages for superglobal $_FiLES		
	
	public static $instance;

	/**
	 *	Return the internal instance.
	 *
	 *  @return object  The instance of this class.
	 *
	 */
	public static function getInstance()
	{
		if (null === static::$instance)
		{
			static::$instance = new static();
			static::$instance->initialize();
		}

		return static::$instance;
	}
	
	public function initialize() 
	{
		
		$this->database = LEPTON_database::getInstance();		
		$this->secure_data = array('username','action','log_text');
		$this->log_table = TABLE_PREFIX.'log';
		if(!isset($_SESSION['USER_ID']))
		{
			$this->user_id = -99;
			$this->username = 'LEPTON cms';			
		}
		else
		{
			$this->user_id = $_SESSION['USER_ID'];
			$this->username = $_SESSION['USERNAME'];		
		}

		date_default_timezone_set('Europe/London');		// mysql always uses UTC/0 in standard
		$this->logged = date('Y-m-d H:i:s',time());
		
		global $MESSAGE;
		$this->sUploadMessages = [
			0 => $MESSAGE['UPLOAD_ERR_OK'],
			1 => $MESSAGE['UPLOAD_ERR_INI_SIZE'],
			2 => $MESSAGE['UPLOAD_ERR_FORM_SIZE'],
			3 => $MESSAGE['UPLOAD_ERR_PARTIAL'],
			4 => $MESSAGE['UPLOAD_ERR_NO_FILE'],
			5 => $MESSAGE['unknown_upload_error'],
			6 => $MESSAGE['UPLOAD_ERR_NO_TMP_DIR'],
			7 => $MESSAGE['UPLOAD_ERR_CANT_WRITE'],
			8 => $MESSAGE['UPLOAD_ERR_EXTENSION'],
		];		
		
	}
	
	
    /**
     *  Public function to build and execute a mySQL insert entry.
     *  Use this function/method for not encrypted data.
     *
     *  @param  string  $action     A typical "job"-type that is done (UPDATE,INSERT,DELETE, etc)
     *  @param  string  $log_text   A description , for ecample which ID was handled in which table. You can also use language strings to complete this.
     *
     *  @return bool    False if fails, otherwise true.
     *
     */
    public function insert_entry( $action = 0, $log_text = 0 ) 
    {

        $all_values = array (
            'id'=> NULL,
            'logged'    => $this->logged,
            'user_id'   => $this->user_id,
            'username'  => $this->username,
            'action'    => $action,
            'log_text'  => $log_text
        );
            
        $result = $this->database->build_and_execute( 'INSERT', $this->log_table, $all_values, '');

        if($result === false) {
            echo LEPTON_tools::display($this->database->get_error(),'pre','ui red message');
        }

        $latest_id = $this->database->get_one("SELECT LAST_INSERT_ID() FROM ".$this->log_table." ");
        if($latest_id > 99900)
        {
            echo LEPTON_tools::display('Please contact your admin: log-table is running full','pre','ui red message');
        }
        
        return $result;
    }
	
	
    /**
     *	Public function to display inserted entries.
     *	Use this function/method for not encrypted data.
     *
     *	@return	array of entries
     *
     */
    public function display_entry( $start = 1, $end = 100000 ) 
	{
		
		$entries = array();
		$this->database->execute_query(
			"SELECT * FROM ".$this->log_table." WHERE id BETWEEN ".$start." AND ".$end." ",
			true,
			$entries,
			true
		); 

		return $entries;	
    }	
	
    /**
     *    Public function to build and execute a mySQL insert entry, but encrypted.
     *    Use this function/method for encrypted data only. It uses LEPTON built in functions and parameters.
     *
     *    @param    string    $action       A typical "job"-type that is done (UPDATE,INSERT,DELETE, etc)
     *    @param    string    $log_text     A description , for ecample which ID was handled in which table. You can also use language strings to complete this.
     *
     *    @return    bool    False if fails, otherwise true.
     *
     */
    public function insert_secure_entry( $action = 0, $log_text = 0 ) 
    {
        $all_values = array (
            'id'=> NULL,
            'logged'    => $this->logged,
            'user_id'    => $this->user_id,
            'username'    => $this->username,
            'action'    => $action,
            'log_text'    => $log_text
        );
            
        $result = $this->database->secure_build_and_execute( 'INSERT', $this->log_table, $all_values, '', $this->secure_data);            
    
        if($result === false) {
            echo LEPTON_tools::display($this->database->get_error(),'pre','ui red message');
        }

        $latest_id = $this->database->get_one("SELECT LAST_INSERT_ID() FROM ".$this->log_table." ");
        if($latest_id > 99900) {
            echo LEPTON_tools::display('Please contact your admin: log-table is running full','pre','ui red message');
        }

        return $result;
    }

    /**
     *	Public function to display inserted entries.
     *	Use this function/method for encrypted data.
     *
     *	@return	array of entries
     *
     */
    public function display_secure_entry( $start = 1, $end = 100000 ) 
	{
		
		$entries = array();
		$this->database->secure_execute_query(
			"SELECT * FROM ".$this->log_table." WHERE id BETWEEN ".$start." AND ".$end." ",
			true,
			$entries,
			true,
			$this->secure_data
		); 

		return $entries;	
    }
	
    /**
     *	Public function to check entries.
     *	Use this function/method for all data.
     *
     *	@return	array of manipulated entries
     *
     */
    public function check_entry() 
	{
		$temp = array();
		$this->database->execute_query(
			"SELECT * FROM ".$this->log_table,
			true,
			$temp,
			true
		); 
		
		$entries = array();
		foreach($temp as $entry)
		{
			if($entry['logged'] != $entry['check'] )
			{
				$entries[] = array(
									'id' => $entry['id'],
									'user_id' => $entry['user_id'],
									'logged' => $entry['logged'],
									'check' => $entry['check'],
									'comment' => $entry['comment']
									);
			}
		}
		return $entries;	
    }		
}
