<?php
defined('BASEPATH') OR exit('No direct script access allowed');

/**
 * MY_Email - Extension de la librairie Email de CodeIgniter
 * 
 * Ajoute le support de AUTH PLAIN pour les serveurs SMTP comme AhaSend
 * qui ne supportent pas AUTH LOGIN
 * 
 * À placer dans: application/libraries/MY_Email.php
 */
class MY_Email extends CI_Email {

    /**
     * Méthode d'authentification SMTP
     * Valeurs possibles: 'LOGIN', 'PLAIN', 'AUTO'
     * AUTO = essaie PLAIN d'abord, puis LOGIN si échec
     */
    public $smtp_auth_method = 'PLAIN';

    /**
     * Constructeur
     */
    public function __construct(array $config = array())
    {
        parent::__construct($config);
        
        if (isset($config['smtp_auth_method'])) {
            $this->smtp_auth_method = strtoupper($config['smtp_auth_method']);
        }
    }

    /**
     * Initialize preferences
     */
    public function initialize(array $config = array())
    {
        parent::initialize($config);
        
        if (isset($config['smtp_auth_method'])) {
            $this->smtp_auth_method = strtoupper($config['smtp_auth_method']);
        }
        
        return $this;
    }

    /**
     * SMTP Authenticate - Override pour supporter AUTH PLAIN
     *
     * @return bool
     */
    protected function _smtp_authenticate()
    {
        if ( ! $this->_smtp_auth OR ($this->smtp_user === '' && $this->smtp_pass === ''))
        {
            return TRUE;
        }

        // Essayer AUTH PLAIN si configuré ou en mode AUTO
        if ($this->smtp_auth_method === 'PLAIN' || $this->smtp_auth_method === 'AUTO')
        {
            if ($this->_try_auth_plain())
            {
                return TRUE;
            }
            
            // Si PLAIN échoue et qu'on est en mode AUTO, essayer LOGIN
            if ($this->smtp_auth_method === 'AUTO')
            {
                return $this->_try_auth_login();
            }
            
            return FALSE;
        }

        // AUTH LOGIN par défaut
        return $this->_try_auth_login();
    }

    /**
     * Essayer l'authentification AUTH PLAIN
     *
     * @return bool
     */
    protected function _try_auth_plain()
    {
        // AUTH PLAIN envoie les credentials en une seule commande encodée en base64
        // Format: base64(NULL + username + NULL + password)
        $auth_string = base64_encode("\0" . $this->smtp_user . "\0" . $this->smtp_pass);
        
        $this->_send_command('auth', 'AUTH PLAIN ' . $auth_string);
        $reply = $this->_get_smtp_data();
        
        $this->_debug_msg[] = '<pre>'.$reply.'</pre>';
        
        if (strpos($reply, '235') !== 0)
        {
            $this->_set_error_message('lang:email_smtp_auth_un', $reply);
            return FALSE;
        }

        return TRUE;
    }

    /**
     * Essayer l'authentification AUTH LOGIN (méthode originale de CI)
     *
     * @return bool
     */
    protected function _try_auth_login()
    {
        $this->_send_command('auth', 'AUTH LOGIN');
        $reply = $this->_get_smtp_data();
        
        if (strpos($reply, '503') === 0) // Already authenticated
        {
            return TRUE;
        }
        elseif (strpos($reply, '334') !== 0)
        {
            $this->_set_error_message('lang:email_smtp_auth_un', $reply);
            return FALSE;
        }

        $this->_send_command('auth', base64_encode($this->smtp_user));
        $reply = $this->_get_smtp_data();

        if (strpos($reply, '334') !== 0)
        {
            $this->_set_error_message('lang:email_smtp_auth_pw', $reply);
            return FALSE;
        }

        $this->_send_command('auth', base64_encode($this->smtp_pass));
        $reply = $this->_get_smtp_data();

        if (strpos($reply, '235') !== 0)
        {
            $this->_set_error_message('lang:email_smtp_auth_pw', $reply);
            return FALSE;
        }

        return TRUE;
    }

    /**
     * Send SMTP command - Override pour gérer AUTH correctement
     *
     * @param string $cmd
     * @param string $data
     * @return bool
     */
    protected function _send_command($cmd, $data = '')
    {
        switch ($cmd)
        {
            case 'auth':
                $this->_send_data($data);
                return TRUE;
            default:
                return parent::_send_command($cmd, $data);
        }
    }
}
