PHP Unexpected End of File [duplicate] - php

This question already has answers here:
PHP - unexpected end of file
(3 answers)
Closed 8 years ago.
I am getting an unexpected end of file error on the last line of this code, I have run it through www.phpcodechecker.com (Which I have found do be very reliable). What am I doing wrong? PHP version 5.5.9
<?php
/*
Hurricane Control Panel © 2014, a web control panel
by Hurricane Development of http://www.HurricaneDevelopment.com
is licenced under a Creative Commons
Attribution-NoDerivatives 4.0 International License
Permissions beyond the scope of this licence
may be available at http://creativecommons.org/licenses/by-nd/4.0/
*/
Defined("_HEXEC") or die ("This file may not be accessed directly");
class VARS {
public static $errors = false;
public static $extraJS = false;
public static $scriptJS = false;
public static $extraCSS = false;
}
abstract class GeneralUTIL {
/**
* Error functions
**/
public static function addErr($err) {
VARS::$errors[] = $err;
}
public static function logger($content,$level = LOGGER_INFO) {
if (!file_exists("logs")) {
mkdir("logs");
}
$scanned_directory = array_diff(scandir("logs",SCANDIR_SORT_DESCENDING), array('..', '.'));
$logs = false;
if (sizeof($scanned_directory) == 0) {
file_put_contents("logs/log.1", "", LOCK_EX);
chmod("logs/log.1",0600);
$logid = 1;
} else {
foreach ($scanned_directory as $key => $value) {
if (strpos($value,"log.") !== false) {
$logs[] = $value;
}
}
$logid = explode(".", $logs[0]);
$logid = $logid[1];
if (filesize("logs/log." . $logid) >= 200000) {
$logid = ((int) $logid) + 1;
file_put_contents("logs/log." . $logid, "", LOCK_EX);
chmod("logs/log." . $logid,0600);
}
}
date_default_timezone_set("America/New_York");
$d = getdate();
file_put_contents("logs/log." . $logid, "{$d['mon']}/{$d['mday']}/{$d['year']} {$d['hours']}:{$d['minutes']}:{$d['seconds']} $level $content \n", FILE_APPEND | LOCK_EX);
}
public static function sha512($password,$salt = null) {
if ($salt == null) {
$cost = 50000;
$salt = strtr(base64_encode(mcrypt_create_iv(16, MCRYPT_DEV_URANDOM)), '+', '.');
$salt = sprintf('$6$rounds=%d$', $cost) . $salt;
}
return crypt($password, $salt);
}
public static function matchSha512($password,$hash) {
if (crypt($password, $hash) === $hash) {
return true;
}
return false;
}
}
class PluginUTIL extends GeneralUTIL {
public static function addJS($jsPath) {
$debugArray = debug_backtrace();
$pluginAlias = UTIL::getBetween($debugArray[0]['file'],"/plugins/plugin_","/");
if ($pluginAlias == false) {
UTIL::addErr("The addJS Method was not called from a registered plugin");
return false;
}
$pluginLoader = new Plugins();
$pluginLoader->loadPlugins();
$plugins = $pluginLoader->getPluginsArray();
foreach ($plugins as $id => $pluginArray) {
if ($pluginArray['alias'] == $pluginAlias) {
VARS::$extraJS[] = PATH . "plugins/plugin_" . $pluginAlias . "/" . $jsPath;
return true;
}
}
}
public static function addScriptJS($script) {
VARS::$scriptJS = $script;
}
public static function addCSS($cssPath) {
$debugArray = debug_backtrace();
$pluginAlias = UTIL::getBetween($debugArray[0]['file'],"/plugins/plugin_","/");
if ($pluginAlias == false) {
UTIL::addErr("The addCSS Method was not called from a registered plugin");
return false;
}
$pluginLoader = new Plugins();
$pluginLoader->loadPlugins();
$plugins = $pluginLoader->getPluginsArray();
foreach ($plugins as $id => $pluginArray) {
if ($pluginArray['alias'] == $pluginAlias) {
VARS::$extraCSS[] = PATH . "plugins/plugin_" . $pluginAlias . "/" . $cssPath;
return true;
}
}
}
}
class UTIL extends GeneralUTIL {
public static function displayErrors($output) {
if (VARS::$errors != false && is_array(VARS::$errors)) {
$output = str_replace("<div id='errors' class='alert alert-danger'></div>","<div id='errors' class='alert alert-danger'><h1>Uh Oh. Some errors occured!</h1>" . implode("<br>",VARS::$errors) . "</div>",$output);
} else {
$output = str_replace("<div id='errors' class='alert alert-danger'></div>","",$output);
}
return $output;
}
/**
* Custom JS /CSS functions
**/
public static function addCustomJSFromPath($path) {
VARS::$extraJS[] = PATH . $path;
}
public static function includeCustomJS() {
if (VARS::$extraJS != false && is_array(VARS::$extraJS)) {
foreach (VARS::$extraJS as $key => $path): ?>
<script src="<?php echo $path; ?>"></script>
<?php endforeach;
}
if (VARS::$scriptJS != false): ?>
<script type="text/javascript">
<?php echo VARS::$scriptJS; ?>
</script>
<? endif;
}
public static function includeCustomCSS($output) {
if (VARS::$extraCSS != false && is_array(VARS::$extraCSS)) {
$css = "";
foreach (VARS::$extraCSS as $key => $path):
$css .= "<link rel=\"stylesheet\" type=\"text/css\" href=\"$path\">\n";
endforeach;
$output = str_replace("CUSTOMCSSAREAHERE",$css,$output);
} else {
$output = str_replace("CUSTOMCSSAREAHERE","",$output);
}
return $output;
}
/**
* Get Between two strings function
**/
public static function getBetween($content,$start,$end) {
if (preg_match('/' . str_replace("/","\\/", $start) . '(.*?)' . str_replace("/","\\/", $end) . '/',$content, $res) === false) {
return false;
}
return $res[1];
}
/**
* Redirect page function
**/
public static function redirect($location, $code = '302') {
switch($code) {
case '301';
header("HTTP/1.1 301 Moved Permanently");
break;
case '303';
header("HTTP/1.1 303 See Other");
break;
case '404';
header('HTTP/1.1 404 Not Found');
break;
}
//remove any & in the url to prevent any problems
$location = str_replace('&', '&', $location);
header("Location: $location");
//kill the script from running and output a link for browsers which enable turning off header redirects *cough Opera cough* :P
exit('If you were not redirected automatically please click here');
}
}
?>

Change this
<? endif;
to this
<?php endif;
inside UTIL::includeCustomJS

Related

Echo specific field from rsform in directory view

my first post here after actively using the site for ages.
I am trying to set up a directory view through RSFORM on my company intranet site. Everything is done, but in directory view i would like to echo the value of one selector in the form (the selector is hidden in the form, and viewable in edit). So when you edit this selector after form submission, it will echo this value to a spesific area of the directory (adds it to class for the whole row).
But I cant figure out how to get spesific field values..
I tried this
echo $this->$field(FIELD_NAME);
The code section is like this
<?php if ($this->items) { ?>
<?php foreach ($this->items as $i => $item) { ?>
<tr class="row<?php echo $i % 2; ?> directoryRow **<?php echo $this->$field(FIELD_NAME); ?>**">
<?php if ($this->directory->enablecsv) { ?>
<td align="center" class="center directoryGrid"><?php echo JHtml::_('grid.id', $i, $item->SubmissionId); ?></td>
<?php } ?>
<?php foreach ($this->viewableFields as $field) { ?>
<td align="center" class="center directoryCol directoryCol<?php echo $this->getFilteredName($field->FieldName); ?>"><?php echo $this->getValue($item, $field); ?></td>
<?php } ?>
This is from the view.html.php file
<?php
defined('_JEXEC') or die('Restricted access');
class RSFormViewDirectory extends JViewLegacy
{
public function display( $tpl = null ) {
$this->app = JFactory::getApplication();
$this->doc = JFactory::getDocument();
$this->document = &$this->doc;
$this->params = $this->app->getParams('com_rsform');
$this->layout = $this->getLayout();
$this->directory = $this->get('Directory');
$this->tooltipClass = RSFormProHelper::getTooltipClass();
if ($this->layout == 'view') {
$this->doc->addStyleSheet(JHtml::stylesheet('com_rsform/directory.css', array(), true, true));
$this->template = $this->get('template');
$this->canEdit = RSFormProHelper::canEdit($this->params->get('formId'),$this->app->input->getInt('id',0));
$this->id = $this->app->input->getInt('id',0);
// Add custom CSS and JS
if ($this->directory->JS)
$this->doc->addCustomTag($this->directory->JS);
if ($this->directory->CSS)
$this->doc->addCustomTag($this->directory->CSS);
// Add pathway
$this->app->getPathway()->addItem(JText::_('RSFP_SUBM_DIR_VIEW'), '');
} elseif ($this->layout == 'edit') {
if (RSFormProHelper::canEdit($this->params->get('formId'),$this->app->input->getInt('id',0))) {
$this->doc->addStyleSheet(JHtml::stylesheet('com_rsform/directory.css', array(), true, true));
$this->fields = $this->get('EditFields');
} else {
$this->app->redirect(JURI::root());
}
// Add pathway
$this->app->getPathway()->addItem(JText::_('RSFP_SUBM_DIR_EDIT'), '');
} else {
$this->search = $this->get('Search');
$this->items = $this->get('Items');
$this->uploadFields = $this->get('uploadFields');
$this->multipleFields = $this->get('multipleFields');
$this->unescapedFields = array_merge($this->multipleFields, $this->uploadFields);
$this->fields = $this->get('Fields');
$this->headers = RSFormProHelper::getDirectoryStaticHeaders();
$this->hasDetailFields = $this->hasDetailFields();
$this->hasSearchFields = $this->hasSearchFields();
$this->viewableFields = $this->getViewableFields();
$this->pagination = $this->get('Pagination');
$this->filter_search = $this->get('Search');
$this->filter_order = $this->get('ListOrder');
$this->filter_order_Dir = $this->get('ListDirn');
// Add custom CSS and JS
if ($this->directory->JS)
$this->doc->addCustomTag($this->directory->JS);
if ($this->directory->CSS)
$this->doc->addCustomTag($this->directory->CSS);
}
if ($this->params->get('robots')) {
$this->document->setMetadata('robots', $this->params->get('robots'));
}
if ($this->params->get('menu-meta_description')) {
$this->document->setDescription($this->params->get('menu-meta_description'));
}
if ($this->params->get('menu-meta_keywords')) {
$this->document->setMetadata('keywords', $this->params->get('menu-meta_keywords'));
}
$title = $this->params->get('page_title', '');
if (empty($title)) {
$title = JFactory::getConfig()->get('sitename');
}
elseif (JFactory::getConfig()->get('sitename_pagetitles', 0) == 1) {
$title = JText::sprintf('JPAGETITLE', JFactory::getConfig()->get('sitename'), $title);
}
elseif (JFactory::getConfig()->get('sitename_pagetitles', 0) == 2) {
$title = JText::sprintf('JPAGETITLE', $title, JFactory::getConfig()->get('sitename'));
}
$this->document->setTitle($title);
parent::display($tpl);
}
protected function hasDetailFields() {
foreach ($this->fields as $field) {
if ($field->indetails) {
return true;
}
}
}
protected function hasSearchFields() {
foreach ($this->fields as $field) {
if ($field->searchable) {
return true;
}
}
}
protected function getViewableFields() {
$return = array();
foreach ($this->fields as $field) {
if ($field->viewable) {
$return[] = $field;
}
}
return $return;
}
protected function getFilteredName($name) {
return ucfirst(JFilterOutput::stringURLSafe($name));
}
protected function getValue($item, $field) {
if (in_array($field->FieldName, $this->unescapedFields)) {
return $item->{$field->FieldName};
} else {
// Static header?
if ($field->componentId < 0 && isset($this->headers[$field->componentId])) {
$header = $this->headers[$field->componentId];
if ($header == 'DateSubmitted') {
$value = RSFormProHelper::getDate($item->$header);
} else {
$value = $item->$header;
}
} else {
// Dynamic header.
$value = $item->{$field->FieldName};
}
return $this->escape($value);
}
}
public function pdfLink($id) {
$app = JFactory::getApplication();
$has_suffix = JFactory::getConfig()->get('sef') && JFactory::getConfig()->get('sef_suffix');
$pdf_link = JRoute::_('index.php?option=com_rsform&view=directory&layout=view&id='.$id.'&format=pdf');
if ($has_suffix) {
$pdf_link .= strpos($pdf_link, '?') === false ? '?' : '&';
$pdf_link .= 'format=pdf';
}
return $pdf_link;
}
}

PHP Symfony 2 passing class containing sockets between controllers

I am using PHP 5.5.9 and Symfony 2.2.7,
I need to pass an array of class that contains an array of PHP sockets between controllers.
The troubles I get is that I can't pass it through a session that puts a 0 instead of the socket, when I try to pass it through a service that was each time reset the class, then I try to put the array in static but that doesn't work too.
Did anyone have a clue, a track or something to help me?
Thanks for reading at least and have a good day.
Here is the class who ecapsul the sockets:
class Socket {
private $socket;
private $give;
private static $out;
function __construct($host, $port = -1){
$errno = 0;
$errmsg = "";
$this->give = false;
if ($port === -1) {
$this->socket = $host->getFd();
$this->give = true;
}
else {
$this->socket = fsockopen($host, $port, $errno, $errmsg);
echo "connection\n";
}
}
function __destruct() {
if (!$this->give && !$this->socket === false)
fclose($this->socket);
}
function getFd() {
return ($this->socket);
}
function writeSocket($buff, $size) {
if ($this->socket === false)
return (false);
echo "send: " . bin2hex($buff) . "\n";
return (fwrite($this->socket, $buff, $size));
}
function readSocket($size) {
if ($this->socket === false)
return (false);
$out = "";
$out = fgets($this->socket, $size + 1);
if (strlen($out) < $size) {
$tmp = fgets($this->socket, $size - strlen($out) + 1);
if (!($tmp === false))
$out .= $tmp;
}
echo "read: " . bin2hex($out) . "\n";
return ($out);
}
}
Here the class that implement the procol:
class EcoProtocol{
private $socket;
private $isLogged;
private $orga;
private $pass;
private $user;
private $KO;
/**
* Initiate the connexion to the server
* and read the first packet from the server
*/
public function __construct(){
$this->socket = new Socket("91.121.11.33", 4340);
}
public function logIn($new, $user, $pass) {
//using socket here
}
}
And here the class with the array:
class ConnexionsHandler {
private static $socket;
private $maxTime = 120;
function __construct(){
echo "construct";
if (!isset(ConnexionsHandler::$socket))
{
echo "is not set";
ConnexionsHandler::$socket = array();
}
print_r(ConnexionsHandler::$socket);
}
function __destruct(){
echo "destruct";
}
private function cleanConnexion(){
foreach (ConnexionsHandler::$socket as $key => $val) {
if (time() - $val[0] > $this->maxTime){
unset(ConnexionsHandler::$socket[$key]);
}
}
}
public function getConnexion($user){
$this->cleanConnexion();
if (array_key_exists($user, ConnexionsHandler::$socket)){
ConnexionsHandler::$socket[$user][0] = time();
return (ConnexionsHandler::$socket[$user][1]);
}
return (null);
}
public function createConnexion($new, $user, $pass){
$this->cleanConnexion();
$client = new EcoProtocol();
$ret = $client->logIn($new, $user, $pass);
ConnexionsHandler::$socket[$user][0] = time();
ConnexionsHandler::$socket[$user][1] = $client;
return ($ret);
}
}

Opencart Register Account Error

I am currently setting up a website using Opencart. When registering an account on the website I obtain the following:
Warning: Invalid argument supplied for foreach() in
/homepages/2/d493065440/htdocs/sofas/system/library/mail.php on line
22Warning: Cannot modify header information - headers already sent by
(output started at /homepages/2/d493065440/htdocs/sofas/index.php:98)
in /homepages/2/d493065440/htdocs/sofas/system/library/response.php on
line 12
Does anyone know how to avoid this message? The weird thing is the account is still created? I have attached the response.php file. Any help would be much appreciated!
<?php
class Response {
private $headers = array();
private $level = 0;
private $output;
public function addHeader($header) {
$this->headers[] = $header;
}
public function redirect($url, $status = 302) {
header('Location: ' . str_replace(array('&', "\n", "\r"), array('&', '', ''), $url), true, $status);
exit();
}
public function setCompression($level) {
$this->level = $level;
}
public function setOutput($output) {
$this->output = $output;
}
public function getOutput() {
return $this->output;
}
private function compress($data, $level = 0) {
if (isset($_SERVER['HTTP_ACCEPT_ENCODING']) && (strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') !== false)) {
$encoding = 'gzip';
}
if (isset($_SERVER['HTTP_ACCEPT_ENCODING']) && (strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'x-gzip') !== false)) {
$encoding = 'x-gzip';
}
if (!isset($encoding) || ($level < -1 || $level > 9)) {
return $data;
}
if (!extension_loaded('zlib') || ini_get('zlib.output_compression')) {
return $data;
}
if (headers_sent()) {
return $data;
}
if (connection_status()) {
return $data;
}
$this->addHeader('Content-Encoding: ' . $encoding);
return gzencode($data, (int)$level);
}
public function output() {
if ($this->output) {
if ($this->level) {
$output = $this->compress($this->output, $this->level);
} else {
$output = $this->output;
}
if (!headers_sent()) {
foreach ($this->headers as $header) {
header($header, true);
}
}
echo $output;
}
}
}

How to return true/false from a function in php

How can I use the return true/false for another function?
<?php
class Bet {
private $Client;
private $Secret;
private $Server;
public function __construct() {
$this->Client = md5(uniqid(rand(), true));
$this->Secret = md5(uniqid(rand(), true));
$this->Server = md5(uniqid(rand(), true));
}
public function Bet($Type, $Chance) {
if($Type == 'auto') {
$hash = hash('sha512', $this->Client . $this->Secret . $this->Server);
$Result = round(hexdec(substr($hash, 0, 8)) / 42949672.95, 2);
if($Result < $Chance) {
return true;
} else {
return false;
}
}
}
}
?>
Heres what I been trying:
if(isset($_POST['chance'], $_POST['bet'])) {
print_r($Bet->Bet('auto', $_POST['chance']));
if($Bet == true)
{
return "1";
} else {
return "2";
}
}
But I can't see to get inside the if state.
try this
if($Bet)
{
return "1";
} else {
return "2";
}
}
You have to instantiate your class:
$bet = new Bet($type, $chance);
but a constructor cannot return a value like you are doing.
try something like this:
public function betTest() { return what you want; }
[...]
if ($bet->betTest()) { return 1; } else { return 2; }
or use a static method:
public static function betTest() { /.../ }
if (Bet::betTest()) { ... }
Based on your code:
<?php
class Bet {
private $Client;
private $Secret;
private $Server;
private $result;
public function __construct($Type, $Chance) {
$this->Client = md5(uniqid(rand(), true));
$this->Secret = md5(uniqid(rand(), true));
$this->Server = md5(uniqid(rand(), true));
if($Type == 'auto') {
$hash = hash('sha512', $this->Client . $this->Secret . $this->Server);
$Result = round(hexdec(substr($hash, 0, 8)) / 42949672.95, 2);
if($Result < $Chance) {
$this->result = true;
} else {
$this->result = false;
}
}
}
/**
* #return boolean
*/
public function isReturnLessThanChance() { return $this->result; }
}
$bet = new Bet("", "");
if ($bet->isResultLessThanChance()) {
return 1;
else
return 2;
you can try this also.
if($Bet === true) { return "1"; } else { return "2"; }
=== check data type as well as value. then (true !== 1).

php imap - get body and make plain text

I am using the PHP imap function to get emails from a POP3 mailbox and insert the data into a MySQL database.
Here is the PHP code:
$inbox = imap_open($hostname,$username,$password) or die('Cannot connect: ' . imap_last_error());
$emails = imap_search($inbox,'ALL');
if($emails)
{
$output = '';
rsort($emails);
foreach($emails as $email_number)
{
$header=imap_headerinfo($inbox,$email_number);
$from = $header->from[0]->mailbox . "#" . $header->from[0]->host;
$toaddress=$header->toaddress;
$replyto=$header->reply_to[0]->mailbox."#".$header->reply_to[0]->host;
$datetime=date("Y-m-d H:i:s",$header->udate);
$subject=$header->subject;
//remove the " from the $toaddress
$toaddress = str_replace('"','',$toaddress);
echo '<strong>To:</strong> '.$toaddress.'<br>';
echo '<strong>From:</strong> '.$from.'<br>';
echo '<strong>Subject:</strong> '.$subject.'<br>';
//get message body
$message = (imap_fetchbody($inbox,$email_number,1.1));
if($message == '')
{
$message = (imap_fetchbody($inbox,$email_number,1));
}
}
It works fine, however on some emails in the body I get = in between words, or =20 in between words. And other times the emails will just be blank even though they are not blank when sent.
This only happens when coming from certain emails.
How can I get round this and just make the email completely plain text?
This happens because the emails are normally Quoted-printable encoded. The = is a soft line break and =20 is a white space. I think, you could use quoted_printable_decode() on the message so it shows correctly. About the blank emails, I don't know, I would need more details.
Basically:
//get message body
$message = quoted_printable_decode(imap_fetchbody($inbox,$email_number,1.1));
$data = imap_fetchbody($this->imapStream, $Part->uid, $Part->path, FT_UID | FT_PEEK);
if ($Part->format === 'quoted-printable' && $data) {
$data = quoted_printable_decode($data);
}
This is required for mails with
Content-Transfer-Encoding: quoted-printable
But for mails with
Content-Transfer-Encoding: 8bit
simply imap_fetchbody is enough.
Above code was taken from a cake-php component created for fetching mails from mail boxes throgh IMAP.
I made an entire class some years ago, and I'm still using it when I need to get contents from emails. It will help you fetch all email bodies (sometimes you have html and plain text) in a readable format, and get all attached files, just ready to be saved somewhere or sent to a website user.
It is not really optimized so on a big mailbox you may have troubles; but the purpose of this class was to access emails in a readable format to put them on a widget of a website. I let you play with the sample below to get how it works.
ImapReader.class.php Here is the source code.
<?php
class ImapReader
{
private $host;
private $port;
private $user;
private $pass;
private $box;
private $box_list;
private $errors;
private $connected;
private $list;
private $deleted;
const FROM = 0;
const TO = 1;
const REPLY_TO = 2;
const SUBJECT = 3;
const CONTENT = 4;
const ATTACHMENT = 5;
public function __construct($host = null, $port = '143', $user = null, $pass = null)
{
$this->host = $host;
$this->port = $port;
$this->user = $user;
$this->pass = $pass;
$this->box = null;
$this->box_list = null;
$this->errors = array ();
$this->connected = false;
$this->list = null;
$this->deleted = false;
}
public function __destruct()
{
if ($this->isConnected())
{
$this->disconnect();
}
}
public function changeServer($host = null, $port = '143', $user = null, $pass = null)
{
if ($this->isConnected())
{
$this->disconnect();
}
$this->host = $host;
$this->port = $port;
$this->user = $user;
$this->pass = $pass;
$this->box_list = null;
$this->errors = array ();
$this->list = null;
return $this;
}
public function canConnect()
{
return (($this->connected == false) && (is_string($this->host)) && (!empty($this->host))
&& (is_numeric($this->port)) && ($this->port >= 1) && ($this->port <= 65535)
&& (is_string($this->user)) && (!empty($this->user)) && (is_string($this->pass)) && (!empty($this->pass)));
}
public function connect()
{
if ($this->canConnect())
{
$this->box = #imap_open("{{$this->host}:{$this->port}/imap/ssl/novalidate-cert}INBOX", $this->user,
$this->pass);
if ($this->box !== false)
{
$this->_connected();
}
else
{
$this->errors = array_merge($this->errors, imap_errors());
}
}
return $this;
}
public function boxList()
{
if (is_null($this->box_list))
{
$list = imap_getsubscribed($this->box, "{{$this->host}:{$this->port}}", "*");
$this->box_list = array ();
foreach ($list as $box)
{
$this->box_list[] = $box->name;
}
}
return $this->box_list;
}
public function fetchAllHeaders($mbox)
{
if ($this->isConnected())
{
$test = imap_reopen($this->box, "{$mbox}");
if (!$test)
{
return false;
}
$num_msgs = imap_num_msg($this->box);
$this->list = array ();
for ($id = 1; ($id <= $num_msgs); $id++)
{
$this->list[] = $this->_fetchHeader($mbox, $id);
}
return true;
}
return false;
}
public function fetchSearchHeaders($mbox, $criteria)
{
if ($this->isConnected())
{
$test = imap_reopen($this->box, "{$mbox}");
if (!$test)
{
return false;
}
$msgs = imap_search($this->box, $criteria);
if ($msgs)
{
foreach ($msgs as $id)
{
$this->list[] = $this->_fetchHeader($mbox, $id);
}
}
return true;
}
return false;
}
public function isConnected()
{
return $this->connected;
}
public function disconnect()
{
if ($this->connected)
{
if ($this->deleted)
{
imap_expunge($this->box);
$this->deleted = false;
}
imap_close($this->box);
$this->connected = false;
$this->box = null;
}
return $this;
}
/**
* Took from khigashi dot oang at gmail dot com at php.net
* with replacement of ereg family functions by preg's ones.
*
* #param string $str
* #return string
*/
private function _fix($str)
{
if (preg_match("/=\?.{0,}\?[Bb]\?/", $str))
{
$str = preg_split("/=\?.{0,}\?[Bb]\?/", $str);
while (list($key, $value) = each($str))
{
if (preg_match("/\?=/", $value))
{
$arrTemp = preg_split("/\?=/", $value);
$arrTemp[0] = base64_decode($arrTemp[0]);
$str[$key] = join("", $arrTemp);
}
}
$str = join("", $str);
}
if (preg_match("/=\?.{0,}\?Q\?/", $str))
{
$str = quoted_printable_decode($str);
$str = preg_replace("/=\?.{0,}\?[Qq]\?/", "", $str);
$str = preg_replace("/\?=/", "", $str);
}
return trim($str);
}
private function _connected()
{
$this->connected = true;
return $this;
}
public function getErrors()
{
$errors = $this->errors;
$this->errors = array ();
return $errors;
}
public function count()
{
if (is_null($this->list))
{
return 0;
}
return count($this->list);
}
public function get($nbr = null)
{
if (is_null($nbr))
{
return $this->list;
}
if ((is_array($this->list)) && (isset($this->list[$nbr])))
{
return $this->list[$nbr];
}
return null;
}
public function fetch($nbr = null)
{
return $this->_callById('_fetch', $nbr);
}
private function _fetchHeader($mbox, $id)
{
$header = imap_header($this->box, $id);
if (!is_object($header))
{
return;
}
$mail = new stdClass();
$mail->id = $id;
$mail->mbox = $mbox;
$mail->timestamp = (isset($header->udate)) ? ($header->udate) : ('');
$mail->date = date("d/m/Y H:i:s", (isset($header->udate)) ? ($header->udate) : (''));
$mail->from = $this->_fix(isset($header->fromaddress) ? ($header->fromaddress) : (''));
$mail->to = $this->_fix(isset($header->toaddress) ? ($header->toaddress) : (''));
$mail->reply_to = $this->_fix(isset($header->reply_toaddress) ? ($header->reply_toaddress) : (''));
$mail->subject = $this->_fix(isset($header->subject) ? ($header->subject) : (''));
$mail->content = array ();
$mail->attachments = array ();
$mail->deleted = false;
return $mail;
}
private function _fetch($mail)
{
$test = imap_reopen($this->box, "{$mail->mbox}");
if (!$test)
{
return $mail;
}
$structure = imap_fetchstructure($this->box, $mail->id);
if ((!isset($structure->parts)) || (!is_array($structure->parts)))
{
$body = imap_body($this->box, $mail->id);
$content = new stdClass();
$content->type = 'content';
$content->mime = $this->_fetchType($structure);
$content->charset = $this->_fetchParameter($structure->parameters, 'charset');
$content->data = $this->_decode($body, $structure->type);
$content->size = strlen($content->data);
$mail->content[] = $content;
return $mail;
}
else
{
$parts = $this->_fetchPartsStructureRoot($mail, $structure);
foreach ($parts as $part)
{
$content = new stdClass();
$content->type = null;
$content->data = null;
$content->mime = $this->_fetchType($part->data);
if ((isset($part->data->disposition))
&& ((strcmp('attachment', $part->data->disposition) == 0)
|| (strcmp('inline', $part->data->disposition) == 0)))
{
$content->type = $part->data->disposition;
$content->name = null;
if (isset($part->data->dparameters))
{
$content->name = $this->_fetchParameter($part->data->dparameters, 'filename');
}
if (is_null($content->name))
{
if (isset($part->data->parameters))
{
$content->name = $this->_fetchParameter($part->data->parameters, 'name');
}
}
$mail->attachments[] = $content;
}
else if ($part->data->type == 0)
{
$content->type = 'content';
$content->charset = null;
if (isset($part->data->parameters))
{
$content->charset = $this->_fetchParameter($part->data->parameters, 'charset');
}
$mail->content[] = $content;
}
$body = imap_fetchbody($this->box, $mail->id, $part->no);
if (isset($part->data->encoding))
{
$content->data = $this->_decode($body, $part->data->encoding);
}
else
{
$content->data = $body;
}
$content->size = strlen($content->data);
}
}
return $mail;
}
private function _fetchPartsStructureRoot($mail, $structure)
{
$parts = array ();
if ((isset($structure->parts)) && (is_array($structure->parts)) && (count($structure->parts) > 0))
{
foreach ($structure->parts as $key => $data)
{
$this->_fetchPartsStructure($mail, $data, ($key + 1), $parts);
}
}
return $parts;
}
private function _fetchPartsStructure($mail, $structure, $prefix, &$parts)
{
if ((isset($structure->parts)) && (is_array($structure->parts)) && (count($structure->parts) > 0))
{
foreach ($structure->parts as $key => $data)
{
$this->_fetchPartsStructure($mail, $data, $prefix . "." . ($key + 1), $parts);
}
}
$part = new stdClass;
$part->no = $prefix;
$part->data = $structure;
$parts[] = $part;
}
private function _fetchParameter($parameters, $key)
{
foreach ($parameters as $parameter)
{
if (strcmp($key, $parameter->attribute) == 0)
{
return $parameter->value;
}
}
return null;
}
private function _fetchType($structure)
{
$primary_mime_type = array ("TEXT", "MULTIPART", "MESSAGE", "APPLICATION", "AUDIO", "IMAGE", "VIDEO", "OTHER");
if ((isset($structure->subtype)) && ($structure->subtype) && (isset($structure->type)))
{
return $primary_mime_type[(int) $structure->type] . '/' . $structure->subtype;
}
return "TEXT/PLAIN";
}
private function _decode($message, $coding)
{
switch ($coding)
{
case 2:
$message = imap_binary($message);
break;
case 3:
$message = imap_base64($message);
break;
case 4:
$message = imap_qprint($message);
break;
case 5:
break;
default:
break;
}
return $message;
}
private function _callById($method, $data)
{
$callback = array ($this, $method);
// data is null
if (is_null($data))
{
$result = array ();
foreach ($this->list as $mail)
{
$result[] = $this->_callById($method, $mail);
}
return $result;
}
// data is an array
if (is_array($data))
{
$result = array ();
foreach ($data as $elem)
{
$result[] = $this->_callById($method, $elem);
}
return $result;
}
// data is an object
if ((is_object($data)) && ($data instanceof stdClass) && (isset($data->id)))
{
return call_user_func($callback, $data);
}
// data is numeric
if (($this->isConnected()) && (is_array($this->list)) && (is_numeric($data)))
{
foreach ($this->list as $mail)
{
if ($mail->id == $data)
{
return call_user_func($callback, $mail);
}
}
}
return null;
}
public function delete($nbr)
{
$this->_callById('_delete', $nbr);
return;
}
private function _delete($mail)
{
if ($mail->deleted == false)
{
$test = imap_reopen($this->box, "{$mail->mbox}");
if ($test)
{
$this->deleted = true;
imap_delete($this->box, $mail->id);
$mail->deleted = true;
}
}
}
public function searchBy($pattern, $type)
{
$result = array ();
if (is_array($this->list))
{
foreach ($this->list as $mail)
{
$match = false;
switch ($type)
{
case self::FROM:
$match = $this->_match($mail->from, $pattern);
break;
case self::TO:
$match = $this->_match($mail->to, $pattern);
break;
case self::REPLY_TO:
$match = $this->_match($mail->reply_to, $pattern);
break;
case self::SUBJECT:
$match = $this->_match($mail->subject, $pattern);
break;
case self::CONTENT:
foreach ($mail->content as $content)
{
$match = $this->_match($content->data, $pattern);
if ($match)
{
break;
}
}
break;
case self::ATTACHMENT:
foreach ($mail->attachments as $attachment)
{
$match = $this->_match($attachment->name, $pattern);
if ($match)
{
break;
}
}
break;
}
if ($match)
{
$result[] = $mail;
}
}
}
return $result;
}
private function _nmatch($string, $pattern, $a, $b)
{
if ((!isset($string[$a])) && (!isset($pattern[$b])))
{
return 1;
}
if ((isset($pattern[$b])) && ($pattern[$b] == '*'))
{
if (isset($string[$a]))
{
return ($this->_nmatch($string, $pattern, ($a + 1), $b) + $this->_nmatch($string, $pattern, $a, ($b + 1)));
}
else
{
return ($this->_nmatch($string, $pattern, $a, ($b + 1)));
}
}
if ((isset($string[$a])) && (isset($pattern[$b])) && ($pattern[$b] == '?'))
{
return ($this->_nmatch($string, $pattern, ($a + 1), ($b + 1)));
}
if ((isset($string[$a])) && (isset($pattern[$b])) && ($pattern[$b] == '\\'))
{
if ((isset($pattern[($b + 1)])) && ($string[$a] == $pattern[($b + 1)]))
{
return ($this->_nmatch($string, $pattern, ($a + 1), ($b + 2)));
}
}
if ((isset($string[$a])) && (isset($pattern[$b])) && ($string[$a] == $pattern[$b]))
{
return ($this->_nmatch($string, $pattern, ($a + 1), ($b + 1)));
}
return 0;
}
private function _match($string, $pattern)
{
return $this->_nmatch($string, $pattern, 0, 0);
}
}
ImapReader.demo.php Here is the usage sample
<?php
require_once("ImapReader.class.php");
$box = new ImapReader('example.com', '143', 'somebody#example.com', 'xxxxxxxxxxxx');
$box
->connect()
->fetchAllHeaders()
;
echo $box->count() . " emails in mailbox\n";
for ($i = 0; ($i < $box->count()); $i++)
{
$msg = $box->get($i);
echo "Reception date : {$msg->date}\n";
echo "From : {$msg->from}\n";
echo "To : {$msg->to}\n";
echo "Reply to : {$msg->from}\n";
echo "Subject : {$msg->subject}\n";
$msg = $box->fetch($msg);
echo "Number of readable contents : " . count($msg->content) . "\n";
foreach ($msg->content as $key => $content)
{
echo "\tContent " . ($key + 1) . " :\n";
echo "\t\tContent type : {$content->mime}\n";
echo "\t\tContent charset : {$content->charset}\n";
echo "\t\tContent size : {$content->size}\n";
}
echo "Number of attachments : " . count($msg->attachments) . "\n";
foreach ($msg->attachments as $key => $attachment)
{
echo "\tAttachment " . ($key + 1) . " :\n";
echo "\t\tAttachment type : {$attachment->type}\n";
echo "\t\tContent type : {$attachment->mime}\n";
echo "\t\tFile name : {$attachment->name}\n";
echo "\t\tFile size : {$attachment->size}\n";
}
echo "\n";
}
echo "Searching '*Bob*' ...\n";
$results = $box->searchBy('*Bob*', ImapReader::FROM);
foreach ($results as $result)
{
echo "\tMatched: {$result->from} - {$result->date} - {$result->subject}\n";
}
Enjoy
Regarding the blank emails, check the encoding of the mail.
If it is a binary encoded mail then you will get blank mails when you try to insert them into a mysql text field.
Try shifting every mail to UTF-8 and then insert it
iconv(mb_detect_encoding($mail_content, mb_detect_order(), true), "UTF-8", $mail_content);
function getmsg($mbox,$mid) {
// input $mbox = IMAP stream, $mid = message id
// output all the following:
global $charset,$htmlmsg,$plainmsg,$attachments;
$htmlmsg = $plainmsg = $charset = '';
$attachments = array();
// HEADER
$h = imap_header($mbox,$mid);
// add code here to get date, from, to, cc, subject...
// BODY
$s = imap_fetchstructure($mbox,$mid);
if (!$s->parts) // simple
getpart($mbox,$mid,$s,0); // pass 0 as part-number
else { // multipart: cycle through each part
foreach ($s->parts as $partno0=>$p)
getpart($mbox,$mid,$p,$partno0+1);
}
}
function getpart($mbox,$mid,$p,$partno) {
// $partno = '1', '2', '2.1', '2.1.3', etc for multipart, 0 if simple
global $htmlmsg,$plainmsg,$charset,$attachments;
// DECODE DATA
$data = ($partno)?
imap_fetchbody($mbox,$mid,$partno): // multipart
imap_body($mbox,$mid); // simple
// Any part may be encoded, even plain text messages, so check everything.
if ($p->encoding==4)
$data = quoted_printable_decode($data);
elseif ($p->encoding==3)
$data = base64_decode($data);
// PARAMETERS
// get all parameters, like charset, filenames of attachments, etc.
$params = array();
if ($p->parameters)
foreach ($p->parameters as $x)
$params[strtolower($x->attribute)] = $x->value;
if ($p->dparameters)
foreach ($p->dparameters as $x)
$params[strtolower($x->attribute)] = $x->value;
// ATTACHMENT
// Any part with a filename is an attachment,
// so an attached text file (type 0) is not mistaken as the message.
if ($params['filename'] || $params['name']) {
// filename may be given as 'Filename' or 'Name' or both
$filename = ($params['filename'])? $params['filename'] : $params['name'];
// filename may be encoded, so see imap_mime_header_decode()
$attachments[$filename] = $data; // this is a problem if two files have same name
}
// TEXT
if ($p->type==0 && $data) {
// Messages may be split in different parts because of inline attachments,
// so append parts together with blank row.
if (strtolower($p->subtype)=='plain')
$plainmsg. = trim($data) ."\n\n";
else
$htmlmsg. = $data ."<br><br>";
$charset = $params['charset']; // assume all parts are same charset
}
// EMBEDDED MESSAGE
// Many bounce notifications embed the original message as type 2,
// but AOL uses type 1 (multipart), which is not handled here.
// There are no PHP functions to parse embedded messages,
// so this just appends the raw source to the main message.
elseif ($p->type==2 && $data) {
$plainmsg. = $data."\n\n";
}
// SUBPART RECURSION
if ($p->parts) {
foreach ($p->parts as $partno0=>$p2)
getpart($mbox,$mid,$p2,$partno.'.'.($partno0+1)); // 1.2, 1.2.1, etc.
}
}
Reference (First user contributed note): http://php.net/manual/en/function.imap-fetchstructure.php
I tried all this answers, but neither one worked for me. Then I hit first user contributed note on this PHP page:
http://php.net/manual/en/function.imap-fetchstructure.php
and this works for all my cases. Quite old answer btw.

Categories