Reange and optimize

This commit is contained in:
Mathieu Sanchez 2017-12-19 23:42:09 +01:00
parent cbe1959e4f
commit cb635858f1
25 changed files with 7915 additions and 7839 deletions

View File

@ -1,4 +1,5 @@
<?php <?php
namespace base; namespace base;
use base\API\APIRouter; use base\API\APIRouter;
@ -24,8 +25,7 @@ $urlA = ltrim($parts[0], '/');
$pages = explode( '/', $urlA ); $pages = explode( '/', $urlA );
//Si il y a un / en fin d'url on redirige vers la meme page sans le / //Si il y a un / en fin d'url on redirige vers la meme page sans le /
if (count($pages) > 1 && $pages[count($pages) - 1] == '') if ( count( $pages ) > 1 && $pages[ count( $pages ) - 1 ] == '' ) {
{
$args = ( count( $parts ) > 1 ? '?' . $parts[1] : '' ); $args = ( count( $parts ) > 1 ? '?' . $parts[1] : '' );
header( $_SERVER['SERVER_PROTOCOL'] . ' 301 Moved Permanently' ); header( $_SERVER['SERVER_PROTOCOL'] . ' 301 Moved Permanently' );
header( 'Location: /' . rtrim( $urlA, '/' ) . $args ); header( 'Location: /' . rtrim( $urlA, '/' ) . $args );

View File

@ -10,6 +10,7 @@ class API extends Controller {
/** /**
* API constructor. * API constructor.
*
* @param array $declaredFunctions * @param array $declaredFunctions
*/ */
public function __construct( array $declaredFunctions ) { public function __construct( array $declaredFunctions ) {

View File

@ -8,6 +8,7 @@ class APIError extends Controller {
/** /**
* APIError constructor. * APIError constructor.
*
* @param int $ErrCode * @param int $ErrCode
* @param string $devMessage * @param string $devMessage
* @param string $publicMessage * @param string $publicMessage
@ -78,7 +79,12 @@ class APIError extends Controller {
header( 'Content-Type: application/json' ); header( 'Content-Type: application/json' );
header( $_SERVER['SERVER_PROTOCOL'] . ' ' . $tabCode[ $ErrCode ]['label'] ); header( $_SERVER['SERVER_PROTOCOL'] . ' ' . $tabCode[ $ErrCode ]['label'] );
echo json_encode(['status' => 'echec', 'msg' => $publicMessage, 'devMsg' => $devMessage, 'code' => $code], JSON_PRETTY_PRINT); echo json_encode( [
'status' => 'echec',
'msg' => $publicMessage,
'devMsg' => $devMessage,
'code' => $code
], JSON_PRETTY_PRINT );
exit(); exit();
} }
} }

View File

@ -11,6 +11,7 @@ class APIRouter {
/** /**
* APIRouter constructor. * APIRouter constructor.
*
* @param string $file * @param string $file
* @param string $action * @param string $action
*/ */

View File

@ -13,10 +13,12 @@ class Autoloader {
/** /**
* Inclue le fichier correspondant à notre classe * Inclue le fichier correspondant à notre classe
*
* @param $class string Le nom de la classe à charger * @param $class string Le nom de la classe à charger
*/ */
static function autoload( $class ) { static function autoload( $class ) {
if (preg_match('#^' . Config::NAMESPACE . '\\\(.+)$#', $class, $matches)) if ( preg_match( '#^' . Config::NAMESPACE . '\\\(.+)$#', $class, $matches ) ) {
require 'src/' . str_replace( '\\', '/', $matches[1] ) . '.php'; require 'src/' . str_replace( '\\', '/', $matches[1] ) . '.php';
} }
} }
}

View File

@ -6,6 +6,7 @@ class Error extends Controller {
/** /**
* Error constructor. * Error constructor.
*
* @param int $ErrCode * @param int $ErrCode
* @param string $message * @param string $message
*/ */

View File

@ -8,6 +8,7 @@ class SiteError extends ControllerSite {
/** /**
* SiteError constructor. * SiteError constructor.
*
* @param int $ErrCode * @param int $ErrCode
* @param string $message * @param string $message
*/ */

View File

@ -6,6 +6,7 @@ class SiteRouter {
/** /**
* SiteRouter constructor. * SiteRouter constructor.
*
* @param $pages * @param $pages
*/ */
public function __construct( $pages ) { public function __construct( $pages ) {

View File

@ -23,8 +23,7 @@ class BDD {
self::$bdd = new PDO( 'mysql:host=' . self::SQL_SERVER . ';dbname=' . self::SQL_DB . ';charset=utf8', self::$bdd = new PDO( 'mysql:host=' . self::SQL_SERVER . ';dbname=' . self::SQL_DB . ';charset=utf8',
self::SQL_LOGIN, self::SQL_PASSWORD, $pdo_options ); self::SQL_LOGIN, self::SQL_PASSWORD, $pdo_options );
} } catch ( Exception $e ) {
catch (Exception $e) {
die( 'Erreur : ' . $e->getMessage() ); die( 'Erreur : ' . $e->getMessage() );
} }
} }

File diff suppressed because it is too large Load Diff

View File

@ -6,13 +6,6 @@ use PDO;
class Logs { class Logs {
public $id;
public $level;
public $message;
public $file;
public $line;
public $date;
const ERROR_LEVEL = [ const ERROR_LEVEL = [
1 => 'E_ERROR', 1 => 'E_ERROR',
2 => 'E_WARNING', 2 => 'E_WARNING',
@ -31,9 +24,16 @@ class Logs {
16384 => 'E_USER_DEPRECATED', 16384 => 'E_USER_DEPRECATED',
32767 => 'E_ALL' 32767 => 'E_ALL'
]; ];
public $id;
public $level;
public $message;
public $file;
public $line;
public $date;
/** /**
* Logs constructor. * Logs constructor.
*
* @param int|null $id * @param int|null $id
* @param string|null $level * @param string|null $level
* @param string|null $message * @param string|null $message
@ -41,9 +41,8 @@ class Logs {
* @param string|null $line * @param string|null $line
* @param string|null $date * @param string|null $date
*/ */
public function __construct(int $id = null, string $level = null, string $message = null, string $file = null, string $line = null, string $date = null) public function __construct( int $id = null, string $level = null, string $message = null, string $file = null, string $line = null, string $date = null ) {
{ if ( $id === null ) {
if ($id === NULL) {
return; return;
} }
$this->id = $id; $this->id = $id;
@ -67,7 +66,9 @@ class Logs {
/** /**
* Retourne un tableau des derniers logs (limite en param) * Retourne un tableau des derniers logs (limite en param)
*
* @param int $limit * @param int $limit
*
* @return array * @return array
*/ */
public static function getLastLogs( int $limit ) { public static function getLastLogs( int $limit ) {
@ -90,96 +91,84 @@ class Logs {
/** /**
* @return int * @return int
*/ */
public function getId() public function getId() {
{
return $this->id; return $this->id;
} }
/** /**
* @param int $id * @param int $id
*/ */
public function setId($id) public function setId( $id ) {
{
$this->id = $id; $this->id = $id;
} }
/** /**
* @return string * @return string
*/ */
public function getLevel() public function getLevel() {
{
return $this->level; return $this->level;
} }
/** /**
* @param string $level * @param string $level
*/ */
public function setLevel($level) public function setLevel( $level ) {
{
$this->level = $level; $this->level = $level;
} }
/** /**
* @return string * @return string
*/ */
public function getMessage() public function getMessage() {
{
return htmlspecialchars( $this->message ); return htmlspecialchars( $this->message );
} }
/** /**
* @param string $message * @param string $message
*/ */
public function setMessage($message) public function setMessage( $message ) {
{
$this->message = $message; $this->message = $message;
} }
/** /**
* @return string * @return string
*/ */
public function getFile() public function getFile() {
{
return htmlspecialchars( $this->file ); return htmlspecialchars( $this->file );
} }
/** /**
* @param string $file * @param string $file
*/ */
public function setFile($file) public function setFile( $file ) {
{
$this->file = $file; $this->file = $file;
} }
/** /**
* @return string * @return string
*/ */
public function getLine() public function getLine() {
{
return htmlspecialchars( $this->line ); return htmlspecialchars( $this->line );
} }
/** /**
* @param string $line * @param string $line
*/ */
public function setLine($line) public function setLine( $line ) {
{
$this->line = $line; $this->line = $line;
} }
/** /**
* @return string * @return string
*/ */
public function getDate() public function getDate() {
{
return $this->date; return $this->date;
} }
/** /**
* @param string $date * @param string $date
*/ */
public function setDate($date) public function setDate( $date ) {
{
$this->date = $date; $this->date = $date;
} }
@ -187,8 +176,7 @@ class Logs {
* Retourne le type d'erreur en string (label) * Retourne le type d'erreur en string (label)
* @return string * @return string
*/ */
public function getErrorLabel() public function getErrorLabel() {
{
return htmlspecialchars( self::ERROR_LEVEL[ $this->level ] ); return htmlspecialchars( self::ERROR_LEVEL[ $this->level ] );
} }
} }

View File

@ -6,19 +6,23 @@ class Model {
/** /**
* Crée une reqette d'insertion en base àpartir du nom de la table et d'un tableau associatif et l'exécute * Crée une reqette d'insertion en base àpartir du nom de la table et d'un tableau associatif et l'exécute
*
* @param string $tableName * @param string $tableName
* @param array $data * @param array $data
*
* @return int lastInsertId * @return int lastInsertId
*/ */
public static function insert( string $tableName, array $data ) { public static function insert( string $tableName, array $data ) {
$req = BDD::instance()->prepare( 'INSERT INTO ' . $tableName . ' (' . implode( ', ', array_keys( $data ) ) . ') $req = BDD::instance()->prepare( 'INSERT INTO ' . $tableName . ' (' . implode( ', ', array_keys( $data ) ) . ')
VALUES (' . ':' . implode( ', :', array_keys( $data ) ) . ')' ); VALUES (' . ':' . implode( ', :', array_keys( $data ) ) . ')' );
$req->execute( $data ); $req->execute( $data );
return BDD::lastInsertId(); return BDD::lastInsertId();
} }
/** /**
* Met à jour les données d'une ligne d'un table données * Met à jour les données d'une ligne d'un table données
*
* @param string $tableName * @param string $tableName
* @param array $data * @param array $data
* @param string $idColumn * @param string $idColumn

View File

@ -1,4 +1,3 @@
<script src="/js/jquery-3.2.1.min.js"></script> <script src="/js/jquery-3.2.1.min.js"></script>
<script src="/js/javascript.js?v=<?= base\Config::SITE_JS_VERSION ?>"></script> <script src="/js/javascript.js?v=<?= base\Config::SITE_JS_VERSION ?>"></script>
<link href="/css/style.css?v=<?= base\Config::SITE_CSS_VERSION ?>" rel="stylesheet"> <link href="/css/style.css?v=<?= base\Config::SITE_CSS_VERSION ?>" rel="stylesheet">

View File

@ -21,7 +21,8 @@
<meta property="og:image" content="https://<?= $_SERVER['SERVER_NAME'] . \base\Config::FAVICON_PATH ?>"/> <meta property="og:image" content="https://<?= $_SERVER['SERVER_NAME'] . \base\Config::FAVICON_PATH ?>"/>
<!-- <meta property="fb:app_id" content="1000452166691027" /> --> <!-- <meta property="fb:app_id" content="1000452166691027" /> -->
<link href='https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700%7CRoboto+Condensed:400,700%7CMaterial+Icons' rel='stylesheet' type='text/css'> <link href='https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700%7CRoboto+Condensed:400,700%7CMaterial+Icons'
rel='stylesheet' type='text/css'>
<link href="/css/theme.css?v=<?= base\Config::SITE_CSS_VERSION ?>" rel="stylesheet"> <link href="/css/theme.css?v=<?= base\Config::SITE_CSS_VERSION ?>" rel="stylesheet">
<link href="/css/select2.css" rel="stylesheet"> <link href="/css/select2.css" rel="stylesheet">

View File

@ -4,8 +4,10 @@ include ('src/lib/mail/PHPMailerAutoload.php');
/** /**
* Permet de remplacer les accents et les apostrophes dans l'url * Permet de remplacer les accents et les apostrophes dans l'url
*
* @param string $str l'url à formater * @param string $str l'url à formater
* @param string $encoding * @param string $encoding
*
* @return string * @return string
*/ */
function formatURL( string $str, $encoding = 'utf-8' ) { function formatURL( string $str, $encoding = 'utf-8' ) {
@ -44,11 +46,13 @@ function formatURL (string $str, $encoding = 'utf-8') {
/** /**
* La fonction darkroom() renomme et redimensionne les photos envoyées lors de l'ajout d'un objet. * La fonction darkroom() renomme et redimensionne les photos envoyées lors de l'ajout d'un objet.
*
* @param $img String Chemin absolu de l'image d'origine. * @param $img String Chemin absolu de l'image d'origine.
* @param $to String Chemin absolu de l'image générée (.jpg). * @param $to String Chemin absolu de l'image générée (.jpg).
* @param $width Int Largeur de l'image générée. Si 0, valeur calculée en fonction de $height. * @param $width Int Largeur de l'image générée. Si 0, valeur calculée en fonction de $height.
* @param $height Int Hauteur de l'image génétée. Si 0, valeur calculée en fonction de $width. * @param $height Int Hauteur de l'image génétée. Si 0, valeur calculée en fonction de $width.
* Si $height = 0 et $width = 0, dimensions conservées mais conversion en .jpg * Si $height = 0 et $width = 0, dimensions conservées mais conversion en .jpg
*
* @return bool * @return bool
*/ */
function darkroom( $img, $to, $width = 0, $height = 0, $quality = 100, $useGD = true ) { function darkroom( $img, $to, $width = 0, $height = 0, $quality = 100, $useGD = true ) {
@ -100,15 +104,18 @@ function darkroom($img, $to, $width = 0, $height = 0, $quality = 100, $useGD = t
return true; return true;
} }
return true; return true;
} }
/** /**
* Redéfini la gestion des erreurs * Redéfini la gestion des erreurs
*
* @param $errno * @param $errno
* @param $errstr * @param $errstr
* @param $errfile * @param $errfile
* @param $errline * @param $errline
*
* @return bool|void * @return bool|void
*/ */
function errorHandler( $errno, $errstr, $errfile, $errline ) { function errorHandler( $errno, $errstr, $errfile, $errline ) {
@ -124,6 +131,7 @@ function errorHandler($errno, $errstr, $errfile, $errline) {
new \base\Controller\Site\SiteError( 500 ); new \base\Controller\Site\SiteError( 500 );
/* Ne pas exécuter le gestionnaire interne de PHP */ /* Ne pas exécuter le gestionnaire interne de PHP */
return; return;
} }
@ -219,6 +227,7 @@ function getBrowser() {
/** /**
* @param $string * @param $string
* @param $limit * @param $limit
*
* @return int * @return int
*/ */
function getLimitWord( $string, $limit ) { function getLimitWord( $string, $limit ) {
@ -229,6 +238,7 @@ function getLimitWord($string, $limit) {
while ( $i > 0 && $string[ $i ] != ' ' ) { while ( $i > 0 && $string[ $i ] != ' ' ) {
$i --; $i --;
} }
return $i; return $i;
} }
@ -315,6 +325,7 @@ function email(array $destinataires, string $subject, string $body, string $aute
* @param string $file * @param string $file
* @param int $angle * @param int $angle
* @param string $newName * @param string $newName
*
* @return bool * @return bool
*/ */
function rotateImage( string $file, int $angle, string $newName ) { function rotateImage( string $file, int $angle, string $newName ) {
@ -348,11 +359,13 @@ function rotateImage(string $file, int $angle, string $newName) {
imagedestroy( $image ); imagedestroy( $image );
imagedestroy( $rotate ); imagedestroy( $rotate );
rename( $file, $newName ); rename( $file, $newName );
return true; return true;
} }
/** /**
* @param array $data * @param array $data
*
* @return array * @return array
* Clean toutes les strings dans array en récursif, et filtre pour n'avoir qu'un espaces entre chaque mot * Clean toutes les strings dans array en récursif, et filtre pour n'avoir qu'un espaces entre chaque mot
*/ */
@ -382,15 +395,18 @@ function cleanArray(array $data) {
} }
} }
} }
return $data; return $data;
} }
/** /**
* @param $array * @param $array
*
* @return mixed * @return mixed
*/ */
function endKey( $array ) { function endKey( $array ) {
end( $array ); end( $array );
return key( $array ); return key( $array );
} }

View File

@ -19,10 +19,10 @@
/** /**
* PHPMailer SPL autoloader. * PHPMailer SPL autoloader.
*
* @param string $classname The name of the class to load * @param string $classname The name of the class to load
*/ */
function PHPMailerAutoload($classname) function PHPMailerAutoload( $classname ) {
{
//Can't use __DIR__ as it's only in PHP 5.3+ //Can't use __DIR__ as it's only in PHP 5.3+
$filename = dirname( __FILE__ ) . DIRECTORY_SEPARATOR . 'class.' . strtolower( $classname ) . '.php'; $filename = dirname( __FILE__ ) . DIRECTORY_SEPARATOR . 'class.' . strtolower( $classname ) . '.php';
if ( is_readable( $filename ) ) { if ( is_readable( $filename ) ) {
@ -40,10 +40,10 @@ if (version_compare(PHP_VERSION, '5.1.2', '>=')) {
} else { } else {
/** /**
* Fall back to traditional autoload for old PHP versions * Fall back to traditional autoload for old PHP versions
*
* @param string $classname The name of the class to load * @param string $classname The name of the class to load
*/ */
function __autoload($classname) function __autoload( $classname ) {
{
PHPMailerAutoload( $classname ); PHPMailerAutoload( $classname );
} }
} }

File diff suppressed because it is too large Load Diff

View File

@ -24,8 +24,7 @@
* @author Chris Ryan * @author Chris Ryan
* @author Marcus Bointon <phpmailer@synchromedia.co.uk> * @author Marcus Bointon <phpmailer@synchromedia.co.uk>
*/ */
class SMTP class SMTP {
{
/** /**
* The PHPMailer SMTP version number. * The PHPMailer SMTP version number.
* @var string * @var string
@ -191,61 +190,18 @@ class SMTP
*/ */
protected $last_reply = ''; protected $last_reply = '';
/**
* Output debugging info via a user-selected method.
* @see SMTP::$Debugoutput
* @see SMTP::$do_debug
* @param string $str Debug string to output
* @param integer $level The debug level of this message; see DEBUG_* constants
* @return void
*/
protected function edebug($str, $level = 0)
{
if ($level > $this->do_debug) {
return;
}
//Avoid clash with built-in function names
if (!in_array($this->Debugoutput, array('error_log', 'html', 'echo')) and is_callable($this->Debugoutput)) {
call_user_func($this->Debugoutput, $str, $this->do_debug);
return;
}
switch ($this->Debugoutput) {
case 'error_log':
//Don't output, just log
error_log($str);
break;
case 'html':
//Cleans up output a bit for a better looking, HTML-safe output
echo htmlentities(
preg_replace('/[\r\n]+/', '', $str),
ENT_QUOTES,
'UTF-8'
)
. "<br>\n";
break;
case 'echo':
default:
//Normalize line breaks
$str = preg_replace('/(\r\n|\r|\n)/ms', "\n", $str);
echo gmdate('Y-m-d H:i:s') . "\t" . str_replace(
"\n",
"\n \t ",
trim($str)
)."\n";
}
}
/** /**
* Connect to an SMTP server. * Connect to an SMTP server.
*
* @param string $host SMTP server IP or host name * @param string $host SMTP server IP or host name
* @param integer $port The port number to connect to * @param integer $port The port number to connect to
* @param integer $timeout How long to wait for the connection to open * @param integer $timeout How long to wait for the connection to open
* @param array $options An array of options for stream_context_create() * @param array $options An array of options for stream_context_create()
*
* @access public * @access public
* @return boolean * @return boolean
*/ */
public function connect($host, $port = null, $timeout = 30, $options = array()) public function connect( $host, $port = null, $timeout = 30, $options = array() ) {
{
static $streamok; static $streamok;
//This is enabled by default since 5.0.0 but some providers disable it //This is enabled by default since 5.0.0 but some providers disable it
//Check this once and cache the result //Check this once and cache the result
@ -258,6 +214,7 @@ class SMTP
if ( $this->connected() ) { if ( $this->connected() ) {
// Already connected, generate error // Already connected, generate error
$this->setError( 'Already connected to a server' ); $this->setError( 'Already connected to a server' );
return false; return false;
} }
if ( empty( $port ) ) { if ( empty( $port ) ) {
@ -307,6 +264,7 @@ class SMTP
. ": $errstr ($errno)", . ": $errstr ($errno)",
self::DEBUG_CLIENT self::DEBUG_CLIENT
); );
return false; return false;
} }
$this->edebug( 'Connection: opened', self::DEBUG_CONNECTION ); $this->edebug( 'Connection: opened', self::DEBUG_CONNECTION );
@ -323,16 +281,162 @@ class SMTP
// Get any announcement // Get any announcement
$announce = $this->get_lines(); $announce = $this->get_lines();
$this->edebug( 'SERVER -> CLIENT: ' . $announce, self::DEBUG_SERVER ); $this->edebug( 'SERVER -> CLIENT: ' . $announce, self::DEBUG_SERVER );
return true; return true;
} }
/**
* Check connection state.
* @access public
* @return boolean True if connected.
*/
public function connected() {
if ( is_resource( $this->smtp_conn ) ) {
$sock_status = stream_get_meta_data( $this->smtp_conn );
if ( $sock_status['eof'] ) {
// The socket is valid but we are not connected
$this->edebug(
'SMTP NOTICE: EOF caught while checking if connected',
self::DEBUG_CLIENT
);
$this->close();
return false;
}
return true; // everything looks good
}
return false;
}
/**
* Output debugging info via a user-selected method.
* @see SMTP::$Debugoutput
* @see SMTP::$do_debug
*
* @param string $str Debug string to output
* @param integer $level The debug level of this message; see DEBUG_* constants
*
* @return void
*/
protected function edebug( $str, $level = 0 ) {
if ( $level > $this->do_debug ) {
return;
}
//Avoid clash with built-in function names
if ( ! in_array( $this->Debugoutput, array(
'error_log',
'html',
'echo'
) ) and is_callable( $this->Debugoutput ) ) {
call_user_func( $this->Debugoutput, $str, $this->do_debug );
return;
}
switch ( $this->Debugoutput ) {
case 'error_log':
//Don't output, just log
error_log( $str );
break;
case 'html':
//Cleans up output a bit for a better looking, HTML-safe output
echo htmlentities(
preg_replace( '/[\r\n]+/', '', $str ),
ENT_QUOTES,
'UTF-8'
)
. "<br>\n";
break;
case 'echo':
default:
//Normalize line breaks
$str = preg_replace( '/(\r\n|\r|\n)/ms', "\n", $str );
echo gmdate( 'Y-m-d H:i:s' ) . "\t" . str_replace(
"\n",
"\n \t ",
trim( $str )
) . "\n";
}
}
/**
* Close the socket and clean up the state of the class.
* Don't use this function without first trying to use QUIT.
* @see quit()
* @access public
* @return void
*/
public function close() {
$this->setError( '' );
$this->server_caps = null;
$this->helo_rply = null;
if ( is_resource( $this->smtp_conn ) ) {
// close the connection and cleanup
fclose( $this->smtp_conn );
$this->smtp_conn = null; //Makes for cleaner serialization
$this->edebug( 'Connection: closed', self::DEBUG_CONNECTION );
}
}
/**
* Read the SMTP server's response.
* Either before eof or socket timeout occurs on the operation.
* With SMTP we can tell if we have more lines to read if the
* 4th character is '-' symbol. If it is a space then we don't
* need to read anything else.
* @access protected
* @return string
*/
protected function get_lines() {
// If the connection is bad, give up straight away
if ( ! is_resource( $this->smtp_conn ) ) {
return '';
}
$data = '';
$endtime = 0;
stream_set_timeout( $this->smtp_conn, $this->Timeout );
if ( $this->Timelimit > 0 ) {
$endtime = time() + $this->Timelimit;
}
while ( is_resource( $this->smtp_conn ) && ! feof( $this->smtp_conn ) ) {
$str = @fgets( $this->smtp_conn, 515 );
$this->edebug( "SMTP -> get_lines(): \$data is \"$data\"", self::DEBUG_LOWLEVEL );
$this->edebug( "SMTP -> get_lines(): \$str is \"$str\"", self::DEBUG_LOWLEVEL );
$data .= $str;
// If 4th character is a space, we are done reading, break the loop, micro-optimisation over strlen
if ( ( isset( $str[3] ) and $str[3] == ' ' ) ) {
break;
}
// Timed-out? Log and break
$info = stream_get_meta_data( $this->smtp_conn );
if ( $info['timed_out'] ) {
$this->edebug(
'SMTP -> get_lines(): timed-out (' . $this->Timeout . ' sec)',
self::DEBUG_LOWLEVEL
);
break;
}
// Now check if reads took too long
if ( $endtime and time() > $endtime ) {
$this->edebug(
'SMTP -> get_lines(): timelimit reached (' .
$this->Timelimit . ' sec)',
self::DEBUG_LOWLEVEL
);
break;
}
}
return $data;
}
/** /**
* Initiate a TLS (encrypted) session. * Initiate a TLS (encrypted) session.
* @access public * @access public
* @return boolean * @return boolean
*/ */
public function startTLS() public function startTLS() {
{
if ( ! $this->sendCommand( 'STARTTLS', 'STARTTLS', 220 ) ) { if ( ! $this->sendCommand( 'STARTTLS', 'STARTTLS', 220 ) ) {
return false; return false;
} }
@ -344,19 +448,101 @@ class SMTP
) ) { ) ) {
return false; return false;
} }
return true; return true;
} }
/**
* Send a command to an SMTP server and check its return code.
*
* @param string $command The command name - not sent to the server
* @param string $commandstring The actual command to send
* @param integer|array $expect One or more expected integer success codes
*
* @access protected
* @return boolean True on success.
*/
protected function sendCommand( $command, $commandstring, $expect ) {
if ( ! $this->connected() ) {
$this->setError( "Called $command without being connected" );
return false;
}
//Reject line breaks in all commands
if ( strpos( $commandstring, "\n" ) !== false or strpos( $commandstring, "\r" ) !== false ) {
$this->setError( "Command '$command' contained line breaks" );
return false;
}
$this->client_send( $commandstring . self::CRLF );
$this->last_reply = $this->get_lines();
// Fetch SMTP code and possible error code explanation
$matches = array();
if ( preg_match( "/^([0-9]{3})[ -](?:([0-9]\\.[0-9]\\.[0-9]) )?/", $this->last_reply, $matches ) ) {
$code = $matches[1];
$code_ex = ( count( $matches ) > 2 ? $matches[2] : null );
// Cut off error code from each response line
$detail = preg_replace(
"/{$code}[ -]" . ( $code_ex ? str_replace( '.', '\\.', $code_ex ) . ' ' : '' ) . "/m",
'',
$this->last_reply
);
} else {
// Fall back to simple parsing if regex fails
$code = substr( $this->last_reply, 0, 3 );
$code_ex = null;
$detail = substr( $this->last_reply, 4 );
}
$this->edebug( 'SERVER -> CLIENT: ' . $this->last_reply, self::DEBUG_SERVER );
if ( ! in_array( $code, (array) $expect ) ) {
$this->setError(
"$command command failed",
$detail,
$code,
$code_ex
);
$this->edebug(
'SMTP ERROR: ' . $this->error['error'] . ': ' . $this->last_reply,
self::DEBUG_CLIENT
);
return false;
}
$this->setError( '' );
return true;
}
/**
* Send raw data to the server.
*
* @param string $data The data to send
*
* @access public
* @return integer|boolean The number of bytes sent to the server or false on error
*/
public function client_send( $data ) {
$this->edebug( "CLIENT -> SERVER: $data", self::DEBUG_CLIENT );
return fwrite( $this->smtp_conn, $data );
}
/** /**
* Perform SMTP authentication. * Perform SMTP authentication.
* Must be run after hello(). * Must be run after hello().
* @see hello() * @see hello()
*
* @param string $username The user name * @param string $username The user name
* @param string $password The password * @param string $password The password
* @param string $authtype The auth type (PLAIN, LOGIN, NTLM, CRAM-MD5, XOAUTH2) * @param string $authtype The auth type (PLAIN, LOGIN, NTLM, CRAM-MD5, XOAUTH2)
* @param string $realm The auth realm for NTLM * @param string $realm The auth realm for NTLM
* @param string $workstation The auth workstation for NTLM * @param string $workstation The auth workstation for NTLM
* @param null|OAuth $OAuth An optional OAuth instance (@see PHPMailerOAuth) * @param null|OAuth $OAuth An optional OAuth instance (@see PHPMailerOAuth)
*
* @return bool True if successfully authenticated.* @access public * @return bool True if successfully authenticated.* @access public
*/ */
public function authenticate( public function authenticate(
@ -369,6 +555,7 @@ class SMTP
) { ) {
if ( ! $this->server_caps ) { if ( ! $this->server_caps ) {
$this->setError( 'Authentication is not allowed before HELO/EHLO' ); $this->setError( 'Authentication is not allowed before HELO/EHLO' );
return false; return false;
} }
@ -397,6 +584,7 @@ class SMTP
} }
if ( empty( $authtype ) ) { if ( empty( $authtype ) ) {
$this->setError( 'No supported authentication methods found' ); $this->setError( 'No supported authentication methods found' );
return false; return false;
} }
self::edebug( 'Auth method selected: ' . $authtype, self::DEBUG_LOWLEVEL ); self::edebug( 'Auth method selected: ' . $authtype, self::DEBUG_LOWLEVEL );
@ -404,6 +592,7 @@ class SMTP
if ( ! in_array( $authtype, $this->server_caps['AUTH'] ) ) { if ( ! in_array( $authtype, $this->server_caps['AUTH'] ) ) {
$this->setError( "The requested authentication method \"$authtype\" is not supported by the server" ); $this->setError( "The requested authentication method \"$authtype\" is not supported by the server" );
return false; return false;
} }
} elseif ( empty( $authtype ) ) { } elseif ( empty( $authtype ) ) {
@ -470,6 +659,7 @@ class SMTP
. $this->error['error'], . $this->error['error'],
self::DEBUG_CLIENT self::DEBUG_CLIENT
); );
return false; return false;
} }
//msg1 //msg1
@ -498,6 +688,7 @@ class SMTP
$realm, $realm,
$workstation $workstation
); );
// send encoded username // send encoded username
return $this->sendCommand( 'Username', base64_encode( $msg3 ), 235 ); return $this->sendCommand( 'Username', base64_encode( $msg3 ), 235 );
case 'CRAM-MD5': case 'CRAM-MD5':
@ -515,8 +706,10 @@ class SMTP
return $this->sendCommand( 'Username', base64_encode( $response ), 235 ); return $this->sendCommand( 'Username', base64_encode( $response ), 235 );
default: default:
$this->setError( "Authentication method \"$authtype\" is not supported" ); $this->setError( "Authentication method \"$authtype\" is not supported" );
return false; return false;
} }
return true; return true;
} }
@ -524,13 +717,14 @@ class SMTP
* Calculate an MD5 HMAC hash. * Calculate an MD5 HMAC hash.
* Works like hash_hmac('md5', $data, $key) * Works like hash_hmac('md5', $data, $key)
* in case that function is not available * in case that function is not available
*
* @param string $data The data to hash * @param string $data The data to hash
* @param string $key The key to hash with * @param string $key The key to hash with
*
* @access protected * @access protected
* @return string * @return string
*/ */
protected function hmac($data, $key) protected function hmac( $data, $key ) {
{
if ( function_exists( 'hash_hmac' ) ) { if ( function_exists( 'hash_hmac' ) ) {
return hash_hmac( 'md5', $data, $key ); return hash_hmac( 'md5', $data, $key );
} }
@ -556,49 +750,6 @@ class SMTP
return md5( $k_opad . pack( 'H*', md5( $k_ipad . $data ) ) ); return md5( $k_opad . pack( 'H*', md5( $k_ipad . $data ) ) );
} }
/**
* Check connection state.
* @access public
* @return boolean True if connected.
*/
public function connected()
{
if (is_resource($this->smtp_conn)) {
$sock_status = stream_get_meta_data($this->smtp_conn);
if ($sock_status['eof']) {
// The socket is valid but we are not connected
$this->edebug(
'SMTP NOTICE: EOF caught while checking if connected',
self::DEBUG_CLIENT
);
$this->close();
return false;
}
return true; // everything looks good
}
return false;
}
/**
* Close the socket and clean up the state of the class.
* Don't use this function without first trying to use QUIT.
* @see quit()
* @access public
* @return void
*/
public function close()
{
$this->setError('');
$this->server_caps = null;
$this->helo_rply = null;
if (is_resource($this->smtp_conn)) {
// close the connection and cleanup
fclose($this->smtp_conn);
$this->smtp_conn = null; //Makes for cleaner serialization
$this->edebug('Connection: closed', self::DEBUG_CONNECTION);
}
}
/** /**
* Send an SMTP DATA command. * Send an SMTP DATA command.
* Issues a data command and sends the msg_data to the server, * Issues a data command and sends the msg_data to the server,
@ -607,12 +758,13 @@ class SMTP
* on a single line followed by a <CRLF> with the message headers * on a single line followed by a <CRLF> with the message headers
* and the message body being separated by and additional <CRLF>. * and the message body being separated by and additional <CRLF>.
* Implements rfc 821: DATA <CRLF> * Implements rfc 821: DATA <CRLF>
*
* @param string $msg_data Message data to send * @param string $msg_data Message data to send
*
* @access public * @access public
* @return boolean * @return boolean
*/ */
public function data($msg_data) public function data( $msg_data ) {
{
//This will use the standard timelimit //This will use the standard timelimit
if ( ! $this->sendCommand( 'DATA', 'DATA', 354 ) ) { if ( ! $this->sendCommand( 'DATA', 'DATA', 354 ) ) {
return false; return false;
@ -687,6 +839,7 @@ class SMTP
$result = $this->sendCommand( 'DATA END', '.', 250 ); $result = $this->sendCommand( 'DATA END', '.', 250 );
//Restore timelimit //Restore timelimit
$this->Timelimit = $savetimelimit; $this->Timelimit = $savetimelimit;
return $result; return $result;
} }
@ -696,12 +849,13 @@ class SMTP
* This makes sure that client and server are in a known state. * This makes sure that client and server are in a known state.
* Implements RFC 821: HELO <SP> <domain> <CRLF> * Implements RFC 821: HELO <SP> <domain> <CRLF>
* and RFC 2821 EHLO. * and RFC 2821 EHLO.
*
* @param string $host The host name or IP to connect to * @param string $host The host name or IP to connect to
*
* @access public * @access public
* @return boolean * @return boolean
*/ */
public function hello($host = '') public function hello( $host = '' ) {
{
//Try extended hello first (RFC 2821) //Try extended hello first (RFC 2821)
return (boolean) ( $this->sendHello( 'EHLO', $host ) or $this->sendHello( 'HELO', $host ) ); return (boolean) ( $this->sendHello( 'EHLO', $host ) or $this->sendHello( 'HELO', $host ) );
} }
@ -710,13 +864,14 @@ class SMTP
* Send an SMTP HELO or EHLO command. * Send an SMTP HELO or EHLO command.
* Low-level implementation used by hello() * Low-level implementation used by hello()
* @see hello() * @see hello()
*
* @param string $hello The HELO string * @param string $hello The HELO string
* @param string $host The hostname to say we are * @param string $host The hostname to say we are
*
* @access protected * @access protected
* @return boolean * @return boolean
*/ */
protected function sendHello($hello, $host) protected function sendHello( $hello, $host ) {
{
$noerror = $this->sendCommand( $hello, $hello . ' ' . $host, 250 ); $noerror = $this->sendCommand( $hello, $hello . ' ' . $host, 250 );
$this->helo_rply = $this->last_reply; $this->helo_rply = $this->last_reply;
if ( $noerror ) { if ( $noerror ) {
@ -724,6 +879,7 @@ class SMTP
} else { } else {
$this->server_caps = null; $this->server_caps = null;
} }
return $noerror; return $noerror;
} }
@ -731,10 +887,10 @@ class SMTP
* Parse a reply to HELO/EHLO command to discover server extensions. * Parse a reply to HELO/EHLO command to discover server extensions.
* In case of HELO, the only parameter that can be discovered is a server name. * In case of HELO, the only parameter that can be discovered is a server name.
* @access protected * @access protected
*
* @param string $type - 'HELO' or 'EHLO' * @param string $type - 'HELO' or 'EHLO'
*/ */
protected function parseHelloFields($type) protected function parseHelloFields( $type ) {
{
$this->server_caps = array(); $this->server_caps = array();
$lines = explode( "\n", $this->last_reply ); $lines = explode( "\n", $this->last_reply );
@ -776,13 +932,15 @@ class SMTP
* the mail transaction is started and then one or more recipient * the mail transaction is started and then one or more recipient
* commands may be called followed by a data command. * commands may be called followed by a data command.
* Implements rfc 821: MAIL <SP> FROM:<reverse-path> <CRLF> * Implements rfc 821: MAIL <SP> FROM:<reverse-path> <CRLF>
*
* @param string $from Source address of this message * @param string $from Source address of this message
*
* @access public * @access public
* @return boolean * @return boolean
*/ */
public function mail($from) public function mail( $from ) {
{
$useVerp = ( $this->do_verp ? ' XVERP' : '' ); $useVerp = ( $this->do_verp ? ' XVERP' : '' );
return $this->sendCommand( return $this->sendCommand(
'MAIL FROM', 'MAIL FROM',
'MAIL FROM:<' . $from . '>' . $useVerp, 'MAIL FROM:<' . $from . '>' . $useVerp,
@ -794,18 +952,20 @@ class SMTP
* Send an SMTP QUIT command. * Send an SMTP QUIT command.
* Closes the socket if there is no error or the $close_on_error argument is true. * Closes the socket if there is no error or the $close_on_error argument is true.
* Implements from rfc 821: QUIT <CRLF> * Implements from rfc 821: QUIT <CRLF>
*
* @param boolean $close_on_error Should the connection close if an error occurs? * @param boolean $close_on_error Should the connection close if an error occurs?
*
* @access public * @access public
* @return boolean * @return boolean
*/ */
public function quit($close_on_error = true) public function quit( $close_on_error = true ) {
{
$noerror = $this->sendCommand( 'QUIT', 'QUIT', 221 ); $noerror = $this->sendCommand( 'QUIT', 'QUIT', 221 );
$err = $this->error; //Save any error $err = $this->error; //Save any error
if ( $noerror or $close_on_error ) { if ( $noerror or $close_on_error ) {
$this->close(); $this->close();
$this->error = $err; //Restore any error from the quit command $this->error = $err; //Restore any error from the quit command
} }
return $noerror; return $noerror;
} }
@ -814,12 +974,13 @@ class SMTP
* Sets the TO argument to $toaddr. * Sets the TO argument to $toaddr.
* Returns true if the recipient was accepted false if it was rejected. * Returns true if the recipient was accepted false if it was rejected.
* Implements from rfc 821: RCPT <SP> TO:<forward-path> <CRLF> * Implements from rfc 821: RCPT <SP> TO:<forward-path> <CRLF>
*
* @param string $address The address the message is being sent to * @param string $address The address the message is being sent to
*
* @access public * @access public
* @return boolean * @return boolean
*/ */
public function recipient($address) public function recipient( $address ) {
{
return $this->sendCommand( return $this->sendCommand(
'RCPT TO', 'RCPT TO',
'RCPT TO:<' . $address . '>', 'RCPT TO:<' . $address . '>',
@ -834,71 +995,10 @@ class SMTP
* @access public * @access public
* @return boolean True on success. * @return boolean True on success.
*/ */
public function reset() public function reset() {
{
return $this->sendCommand( 'RSET', 'RSET', 250 ); return $this->sendCommand( 'RSET', 'RSET', 250 );
} }
/**
* Send a command to an SMTP server and check its return code.
* @param string $command The command name - not sent to the server
* @param string $commandstring The actual command to send
* @param integer|array $expect One or more expected integer success codes
* @access protected
* @return boolean True on success.
*/
protected function sendCommand($command, $commandstring, $expect)
{
if (!$this->connected()) {
$this->setError("Called $command without being connected");
return false;
}
//Reject line breaks in all commands
if (strpos($commandstring, "\n") !== false or strpos($commandstring, "\r") !== false) {
$this->setError("Command '$command' contained line breaks");
return false;
}
$this->client_send($commandstring . self::CRLF);
$this->last_reply = $this->get_lines();
// Fetch SMTP code and possible error code explanation
$matches = array();
if (preg_match("/^([0-9]{3})[ -](?:([0-9]\\.[0-9]\\.[0-9]) )?/", $this->last_reply, $matches)) {
$code = $matches[1];
$code_ex = (count($matches) > 2 ? $matches[2] : null);
// Cut off error code from each response line
$detail = preg_replace(
"/{$code}[ -]".($code_ex ? str_replace('.', '\\.', $code_ex).' ' : '')."/m",
'',
$this->last_reply
);
} else {
// Fall back to simple parsing if regex fails
$code = substr($this->last_reply, 0, 3);
$code_ex = null;
$detail = substr($this->last_reply, 4);
}
$this->edebug('SERVER -> CLIENT: ' . $this->last_reply, self::DEBUG_SERVER);
if (!in_array($code, (array)$expect)) {
$this->setError(
"$command command failed",
$detail,
$code,
$code_ex
);
$this->edebug(
'SMTP ERROR: ' . $this->error['error'] . ': ' . $this->last_reply,
self::DEBUG_CLIENT
);
return false;
}
$this->setError('');
return true;
}
/** /**
* Send an SMTP SAML command. * Send an SMTP SAML command.
* Starts a mail transaction from the email address specified in $from. * Starts a mail transaction from the email address specified in $from.
@ -908,23 +1008,25 @@ class SMTP
* will send the message to the users terminal if they are logged * will send the message to the users terminal if they are logged
* in and send them an email. * in and send them an email.
* Implements rfc 821: SAML <SP> FROM:<reverse-path> <CRLF> * Implements rfc 821: SAML <SP> FROM:<reverse-path> <CRLF>
*
* @param string $from The address the message is from * @param string $from The address the message is from
*
* @access public * @access public
* @return boolean * @return boolean
*/ */
public function sendAndMail($from) public function sendAndMail( $from ) {
{
return $this->sendCommand( 'SAML', "SAML FROM:$from", 250 ); return $this->sendCommand( 'SAML', "SAML FROM:$from", 250 );
} }
/** /**
* Send an SMTP VRFY command. * Send an SMTP VRFY command.
*
* @param string $name The name to verify * @param string $name The name to verify
*
* @access public * @access public
* @return boolean * @return boolean
*/ */
public function verify($name) public function verify( $name ) {
{
return $this->sendCommand( 'VRFY', "VRFY $name", array( 250, 251 ) ); return $this->sendCommand( 'VRFY', "VRFY $name", array( 250, 251 ) );
} }
@ -934,8 +1036,7 @@ class SMTP
* @access public * @access public
* @return boolean * @return boolean
*/ */
public function noop() public function noop() {
{
return $this->sendCommand( 'NOOP', 'NOOP', 250 ); return $this->sendCommand( 'NOOP', 'NOOP', 250 );
} }
@ -948,23 +1049,11 @@ class SMTP
* @access public * @access public
* @return boolean * @return boolean
*/ */
public function turn() public function turn() {
{
$this->setError( 'The SMTP TURN command is not implemented' ); $this->setError( 'The SMTP TURN command is not implemented' );
$this->edebug( 'SMTP NOTICE: ' . $this->error['error'], self::DEBUG_CLIENT ); $this->edebug( 'SMTP NOTICE: ' . $this->error['error'], self::DEBUG_CLIENT );
return false;
}
/** return false;
* Send raw data to the server.
* @param string $data The data to send
* @access public
* @return integer|boolean The number of bytes sent to the server or false on error
*/
public function client_send($data)
{
$this->edebug("CLIENT -> SERVER: $data", self::DEBUG_CLIENT);
return fwrite($this->smtp_conn, $data);
} }
/** /**
@ -972,18 +1061,33 @@ class SMTP
* @access public * @access public
* @return array * @return array
*/ */
public function getError() public function getError() {
{
return $this->error; return $this->error;
} }
/**
* Set error messages and codes.
*
* @param string $message The error message
* @param string $detail Further detail on the error
* @param string $smtp_code An associated SMTP error code
* @param string $smtp_code_ex Extended SMTP code
*/
protected function setError( $message, $detail = '', $smtp_code = '', $smtp_code_ex = '' ) {
$this->error = array(
'error' => $message,
'detail' => $detail,
'smtp_code' => $smtp_code,
'smtp_code_ex' => $smtp_code_ex
);
}
/** /**
* Get SMTP extensions available on the server * Get SMTP extensions available on the server
* @access public * @access public
* @return array|null * @return array|null
*/ */
public function getServerExtList() public function getServerExtList() {
{
return $this->server_caps; return $this->server_caps;
} }
@ -1003,13 +1107,15 @@ class SMTP
* - null returned: handshake was not or we don't know about ext (refer to $this->error) * - null returned: handshake was not or we don't know about ext (refer to $this->error)
* - false returned: the requested feature exactly not exists * - false returned: the requested feature exactly not exists
* - positive value returned: the requested feature exists * - positive value returned: the requested feature exists
*
* @param string $name Name of SMTP extension or 'HELO'|'EHLO' * @param string $name Name of SMTP extension or 'HELO'|'EHLO'
*
* @return mixed * @return mixed
*/ */
public function getServerExt($name) public function getServerExt( $name ) {
{
if ( ! $this->server_caps ) { if ( ! $this->server_caps ) {
$this->setError( 'No HELO/EHLO was sent' ); $this->setError( 'No HELO/EHLO was sent' );
return null; return null;
} }
@ -1022,6 +1128,7 @@ class SMTP
return false; return false;
} }
$this->setError( 'HELO handshake was used. Client knows nothing about server extensions' ); $this->setError( 'HELO handshake was used. Client knows nothing about server extensions' );
return null; return null;
} }
@ -1033,69 +1140,16 @@ class SMTP
* @access public * @access public
* @return string * @return string
*/ */
public function getLastReply() public function getLastReply() {
{
return $this->last_reply; return $this->last_reply;
} }
/**
* Read the SMTP server's response.
* Either before eof or socket timeout occurs on the operation.
* With SMTP we can tell if we have more lines to read if the
* 4th character is '-' symbol. If it is a space then we don't
* need to read anything else.
* @access protected
* @return string
*/
protected function get_lines()
{
// If the connection is bad, give up straight away
if (!is_resource($this->smtp_conn)) {
return '';
}
$data = '';
$endtime = 0;
stream_set_timeout($this->smtp_conn, $this->Timeout);
if ($this->Timelimit > 0) {
$endtime = time() + $this->Timelimit;
}
while (is_resource($this->smtp_conn) && !feof($this->smtp_conn)) {
$str = @fgets($this->smtp_conn, 515);
$this->edebug("SMTP -> get_lines(): \$data is \"$data\"", self::DEBUG_LOWLEVEL);
$this->edebug("SMTP -> get_lines(): \$str is \"$str\"", self::DEBUG_LOWLEVEL);
$data .= $str;
// If 4th character is a space, we are done reading, break the loop, micro-optimisation over strlen
if ((isset($str[3]) and $str[3] == ' ')) {
break;
}
// Timed-out? Log and break
$info = stream_get_meta_data($this->smtp_conn);
if ($info['timed_out']) {
$this->edebug(
'SMTP -> get_lines(): timed-out (' . $this->Timeout . ' sec)',
self::DEBUG_LOWLEVEL
);
break;
}
// Now check if reads took too long
if ($endtime and time() > $endtime) {
$this->edebug(
'SMTP -> get_lines(): timelimit reached ('.
$this->Timelimit . ' sec)',
self::DEBUG_LOWLEVEL
);
break;
}
}
return $data;
}
/** /**
* Enable or disable VERP address generation. * Enable or disable VERP address generation.
*
* @param boolean $enabled * @param boolean $enabled
*/ */
public function setVerp($enabled = false) public function setVerp( $enabled = false ) {
{
$this->do_verp = $enabled; $this->do_verp = $enabled;
} }
@ -1103,52 +1157,33 @@ class SMTP
* Get VERP address generation mode. * Get VERP address generation mode.
* @return boolean * @return boolean
*/ */
public function getVerp() public function getVerp() {
{
return $this->do_verp; return $this->do_verp;
} }
/**
* Set error messages and codes.
* @param string $message The error message
* @param string $detail Further detail on the error
* @param string $smtp_code An associated SMTP error code
* @param string $smtp_code_ex Extended SMTP code
*/
protected function setError($message, $detail = '', $smtp_code = '', $smtp_code_ex = '')
{
$this->error = array(
'error' => $message,
'detail' => $detail,
'smtp_code' => $smtp_code,
'smtp_code_ex' => $smtp_code_ex
);
}
/**
* Set debug output method.
* @param string|callable $method The name of the mechanism to use for debugging output, or a callable to handle it.
*/
public function setDebugOutput($method = 'echo')
{
$this->Debugoutput = $method;
}
/** /**
* Get debug output method. * Get debug output method.
* @return string * @return string
*/ */
public function getDebugOutput() public function getDebugOutput() {
{
return $this->Debugoutput; return $this->Debugoutput;
} }
/**
* Set debug output method.
*
* @param string|callable $method The name of the mechanism to use for debugging output, or a callable to handle it.
*/
public function setDebugOutput( $method = 'echo' ) {
$this->Debugoutput = $method;
}
/** /**
* Set debug output level. * Set debug output level.
*
* @param integer $level * @param integer $level
*/ */
public function setDebugLevel($level = 0) public function setDebugLevel( $level = 0 ) {
{
$this->do_debug = $level; $this->do_debug = $level;
} }
@ -1156,26 +1191,24 @@ class SMTP
* Get debug output level. * Get debug output level.
* @return integer * @return integer
*/ */
public function getDebugLevel() public function getDebugLevel() {
{
return $this->do_debug; return $this->do_debug;
} }
/**
* Set SMTP timeout.
* @param integer $timeout
*/
public function setTimeout($timeout = 0)
{
$this->Timeout = $timeout;
}
/** /**
* Get SMTP timeout. * Get SMTP timeout.
* @return integer * @return integer
*/ */
public function getTimeout() public function getTimeout() {
{
return $this->Timeout; return $this->Timeout;
} }
/**
* Set SMTP timeout.
*
* @param integer $timeout
*/
public function setTimeout( $timeout = 0 ) {
$this->Timeout = $timeout;
}
} }

View File

@ -4,7 +4,8 @@
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head> </head>
<body class="body" style="background-color: whitesmoke !important;padding: 40px 0;line-height: 22px;width: 100%;"> <body class="body" style="background-color: whitesmoke !important;padding: 40px 0;line-height: 22px;width: 100%;">
<div class="contain" style="background-color: white;font-family: Arial, Helvetica, sans-serif; font-size: 16px;margin: auto;padding: 20px;max-width: 500px;width: 90%"> <div class="contain"
style="background-color: white;font-family: Arial, Helvetica, sans-serif; font-size: 16px;margin: auto;padding: 20px;max-width: 500px;width: 90%">
</div> </div>
<div style="margin:20px auto;max-width: 500px;text-align: center;width: 90%;"> <div style="margin:20px auto;max-width: 500px;text-align: center;width: 90%;">