173 lines
3.7 KiB
PHP
173 lines
3.7 KiB
PHP
<?php
|
|
/**
|
|
* @brief POP/IMAP Incoming Email Handler
|
|
* @author <a href='https://www.invisioncommunity.com'>Invision Power Services, Inc.</a>
|
|
* @copyright (c) Invision Power Services, Inc.
|
|
* @license https://www.invisioncommunity.com/legal/standards/
|
|
* @package Invision Community
|
|
* @since 21 December 2015
|
|
*/
|
|
|
|
namespace IPS\Email\Incoming;
|
|
|
|
/* To prevent PHP errors (extending class does not exist) revealing path */
|
|
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
|
{
|
|
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
|
exit;
|
|
}
|
|
|
|
/**
|
|
* PHP Email Class
|
|
*/
|
|
class _PopImap
|
|
{
|
|
/**
|
|
* @brief File pointer
|
|
*/
|
|
protected $fh;
|
|
|
|
/**
|
|
* Constructor
|
|
*
|
|
* @param string $server Server name (e.g. pop.example.com)
|
|
* @param bool $sslRequired If SSL is required
|
|
* @param int $port Port
|
|
* @param string $username Username
|
|
* @param string $password Password
|
|
* @return void
|
|
* @throws \IPS\Email\Incoming\PopImapException
|
|
*/
|
|
public function __construct( $server, $sslRequired, $port, $username, $password )
|
|
{
|
|
/* Connect */
|
|
$errorNumber = 0;
|
|
$errorMessage = '';
|
|
$this->fh = @fsockopen( ( $sslRequired ? 'ssl://' : '' ) . $server, $port, $errorNumber, $errorMessage );
|
|
if ( $this->fh === FALSE )
|
|
{
|
|
throw new PopImapException( 'pop3_cant_connect' );
|
|
}
|
|
|
|
/* Set stream preferences */
|
|
stream_set_timeout( $this->fh, \IPS\DEFAULT_REQUEST_TIMEOUT );
|
|
stream_set_blocking( $this->fh, TRUE );
|
|
|
|
/* Get initial response */
|
|
try
|
|
{
|
|
$response = $this->_getLine();
|
|
}
|
|
catch ( PopImapException $e )
|
|
{
|
|
throw new PopImapException( 'pop3_connect_err' );
|
|
}
|
|
|
|
/* Log In */
|
|
try
|
|
{
|
|
$this->_putLine( "USER {$username}" );
|
|
$this->_putLine( "PASS {$password}" );
|
|
}
|
|
catch ( PopImapException $e )
|
|
{
|
|
throw new PopImapException( 'pop3_login_err' );
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get number of emails in inbox
|
|
*
|
|
* @return int
|
|
* @throws \IPS\Email\Incoming\PopImapException
|
|
*/
|
|
public function emailsInInbox()
|
|
{
|
|
$stats = explode( ' ', $this->_putLine( 'STAT' ) );
|
|
return (int) $stats[1];
|
|
}
|
|
|
|
/**
|
|
* Get email
|
|
*
|
|
* @param int $email The email to fetch
|
|
* @return string
|
|
* @throws \IPS\Email\Incoming\PopImapException
|
|
*/
|
|
public function getEmail( $i )
|
|
{
|
|
$this->_putLine( "RETR {$i}" );
|
|
|
|
$message = '';
|
|
while ( $line = $this->_getLine( FALSE ) and !preg_match( "/^\.\r\n/", $line ) )
|
|
{
|
|
$message .= $line;
|
|
}
|
|
|
|
return $message;
|
|
}
|
|
|
|
/**
|
|
* Delete email
|
|
*
|
|
* @param int $email The email to delete
|
|
* @return string
|
|
* @throws \IPS\Email\Incoming\PopImapException
|
|
*/
|
|
public function deleteEmail( $i )
|
|
{
|
|
$this->_putLine( "DELE {$i}" );
|
|
}
|
|
|
|
/**
|
|
* Get Line
|
|
*
|
|
* @param bool $expectOkay The response should start with "+OK"
|
|
* @return string
|
|
*/
|
|
public function _getLine( $expectOkay = TRUE )
|
|
{
|
|
$response = fgets( $this->fh, 512 );
|
|
|
|
$status = socket_get_status( $this->fh );
|
|
if ( $status['timed_out'] )
|
|
{
|
|
throw new \IPS\Email\Incoming\PopImapException( 'TIMEOUT' );
|
|
}
|
|
|
|
if ( $expectOkay and mb_substr( $response, 0, 3 ) !== '+OK' )
|
|
{
|
|
throw new \IPS\Email\Incoming\PopImapException( 'UNEXPECTED_RESPONSE: ' . $response );
|
|
}
|
|
|
|
return $response;
|
|
}
|
|
|
|
/**
|
|
* Put Line
|
|
*
|
|
* @param string $command Command to send
|
|
* @param bool $expectOkay The response should start with "+OK"
|
|
* @return string The response
|
|
*/
|
|
public function _putLine( $command, $expectOkay = TRUE )
|
|
{
|
|
if ( @\fwrite( $this->fh, $command . "\r\n" ) === FALSE )
|
|
{
|
|
throw new \IPS\Email\Incoming\PopImapException( 'COULD_NOT_WRITE' );
|
|
}
|
|
|
|
return $this->_getLine( $expectOkay );
|
|
}
|
|
|
|
/**
|
|
* Destructor
|
|
*
|
|
* @return void
|
|
*/
|
|
public function __destruct()
|
|
{
|
|
$this->_putLine( "QUIT", FALSE );
|
|
fclose( $this->fh );
|
|
}
|
|
} |