PHP IMAP extract mail attachment in gmail - php

I am trying to extract the attachment of an email, its structure is as follows:
stdClass Object ( [type] => 3 [encoding] => 3 [ifsubtype] => 1 [subtype] => PDF [ifdescription] => 1 [description] => 3002024147 [ifid] => 0 [bytes] => 90256 [ifdisposition] => 0 [ifdparameters] => 0 [ifparameters] => 1 [parameters] => Array ( [0] => stdClass Object ( [attribute] => NAME [value] => 3002024147.pdf ) ) )
I have tried in the following way:
foreach($emails as $email_number) {
/* get information specific to this email */
$overview = imap_fetch_overview($inbox,$email_number,0);
/* get mail message */
$message = imap_fetchbody($inbox,$email_number,2);
/* get mail structure */
$structure = imap_fetchstructure($inbox, $email_number);
$attachments = array();
/* if any attachments found... */
if(isset($structure->parts) && count($structure->parts)) {
for($i = 0; $i < count($structure->parts); $i++)
{
$attachments[$i] = array(
'is_attachment' => false,
'filename' => '',
'name' => '',
'attachment' => ''
);
if($structure->parts[$i]->ifdparameters)
{
foreach($structure->parts[$i]->dparameters as $object)
{
if(strtolower($object->attribute) == 'filename')
{
$attachments[$i]['is_attachment'] = true;
$attachments[$i]['filename'] = $object->value;
}
}
}
if($structure->parts[$i]->ifparameters)
{
foreach($structure->parts[$i]->parameters as $object)
{
if(strtolower($object->attribute) == 'name')
{
$attachments[$i]['is_attachment'] = true;
$attachments[$i]['name'] = $object->value;
}
}
}
if($attachments[$i]['is_attachment'])
{
$attachments[$i]['attachment'] = imap_fetchbody($inbox, $email_number, $i+1);
/* 4 = QUOTED-PRINTABLE encoding */
if($structure->parts[$i]->encoding == 3)
{
$attachments[$i]['attachment'] = base64_decode($attachments[$i]['attachment']);
}
/* 3 = BASE64 encoding */
elseif($structure->parts[$i]->encoding == 4)
{
$attachments[$i]['attachment'] = quoted_printable_decode($attachments[$i]['attachment']);
}
}
}
}
/* iterate through each attachment and save it */
foreach($attachments as $attachment)
{
if($attachment['is_attachment'] == 1)
{
$filename = $attachment['name'];
if(empty($filename)) $filename = $attachment['filename'];
if(empty($filename)) $filename = time() . ".dat";
$fp = fopen($email_number . "-" . $filename, "w+");
fwrite($fp, $attachment['attachment']);
fclose($fp);
}
}
}
I manage to extract the email attachment that I send from Apple Mail and others, but the ones I receive with the previous structure do not.
What I can do?

Related

How to set the index value as 0 for the array in php?

I am working on my php to fetch the data to store them in an array. I have got a problem with the index value in the array, because the index value will start with 1 then it will count it up to 2, 3, 4...etc which it should start with 0 then 1, 2 3...etc, because I am using $i = 0; to start with zero as default.
Here is what I use that the index value start with 1:
if(isset($structure->parts) && count($structure->parts)) {
for($i = 0; $i < count($structure->parts); $i++) {
if (($structure->parts[$i]->ifdisposition) && ($structure->parts[$i]->disposition == 'attachment')) {
foreach($structure->parts[$i]->parameters as $object) {
if(strtolower($object->attribute) == 'name') {
$attachments[$i]['is_attachment'] = true;
$attachments[$i]['name'] = $object->value;
$attachments[$i]['attachment'] = '';
}
}
}
}
I have tried to change from $i++ to $i and I tried to put $i++ in the for loop, but it didn't work.
Output:
Array ( [1] => Array ( [is_attachment] => 1 [name] => 2019-01-23 (1).rar [attachment] => ) [2] => Array ( [is_attachment] => 1 [name] => email.zip [attachment] => ) )
It should be:
Array ( [0] => Array ( [is_attachment] => 1 [name] => 2019-01-23 (1).rar [attachment] => ) [1] => Array ( [is_attachment] => 1 [name] => email.zip [attachment] => ) )
Here is the full code:
<?php
require_once "Mail.php";
require_once('Mail/IMAPv2.php');
$username = 'username';
$password = 'password';
$mailserver = '{imap.domain.com:993/imap/ssl/novalidate-cert}INBOX';
$mailbox = imap_open($mailserver, $username, $password) or die("Can't connect: " . imap_last_error());
$key = "key";
$email_number = openssl_decrypt(hex2bin('477'),'AES-128-CBC', $key);
$attach_id = $_GET['attid'];
/* get information specific to this email */
$overview = imap_fetch_overview($mailbox, $email_number, 0);
$message = imap_fetchbody($mailbox, $email_number, 2);
/* get mail structure */
$structure = imap_fetchstructure($mailbox, $email_number);
$attachments = array();
$attachment_number = 0;
if(isset($structure->parts) && count($structure->parts)) {
for($i = 0; $i < count($structure->parts); $i++) {
if (($structure->parts[$i]->ifdisposition) && ($structure->parts[$i]->disposition == 'attachment')) {
foreach($structure->parts[$i]->parameters as $object) {
if(strtolower($object->attribute) == 'name') {
$attachments[$i]['is_attachment'] = true;
$attachments[$i]['name'] = $object->value;
$attachments[$i]['attachment'] = '';
}
}
}
}
?>
I am unable to find out why the index value have always start with 1 when it should have start with zero then 1, 2, 3 as it get counting up the value each time.
Can you please show me an example how I can start the index value with 0 as a default then count it up to 1, then 2, 3, 4, 5...etc when I am using $i++?
Thank you.
It's because $structure->parts[0] does not match $structure->parts[$i]->disposition == 'attachment' in all cases.
Only create a new item in your array when one is correct and dont use the loop counter use a simpe $arr[] contruct to create the next occurance
$attachments = array();
if(isset($structure->parts) && count($structure->parts)) {
foreach ($structure->parts as $part) {
if (($part->ifdisposition) && ($part->disposition == 'attachment')) {
foreach($part->parameters as $obj) {
if(strtolower($obj->attribute) == 'name') {
$t['is_attachment'] = true;
$t['name'] = $obj->value;
$t['attachment'] = '';
$attachments[] = $t
}
}
}
}
}
Try this
foreach($structure->parts[$i]->parameters as $object) {
if(strtolower($object->attribute) == 'name') {
$attachment['is_attachment'] = true;
$attachment['name'] = $object->value;
$attachment['attachment'] = '';
$attachments[]=$attachment;
}
}
If you want to know why indexes of array start with 1 and not 0, show us definition of array.
But you can also loop array with unknown keys with for loop by getting array keys with PHP array_keys function
$this->arr = [1 => 'one', 2 => 'two', 3 => 'three'];
$keys = array_keys($this->arr);
for($i = 0; $i < count($keys); $i++) {
$value = $this->arr[$keys[$i]];
echo 'val: ' .$value.'<br>';
}
Or you can wrap two foreaches into another
foreach($structure->parts as $key => $part){
$part->ifdisposition = true;
$part->disposition = 'attachment';
if (($part->ifdisposition) && ($part->disposition == 'attachment')) {
foreach($part->parameters as $object) {
if(strtolower($object->attribute) == 'name') {
$attachments[$key]['is_attachment'] = true;
$attachments[$key]['name'] = $object->value;
$attachments[$key]['attachment'] = '';
}
}
}
}
Another option is to remap keys of array, using array_map but you array will be altered, so if you need the original array, you can cache it into another variable.
Here:
$attachments[$i]['is_attachment'] = true;
$attachments[$i]['name'] = $object->value;
$attachments[$i]['attachment'] = '';
You are setting the key to $i, so the first element in $structure->parts to match the criteria is the second element in the loop. To set the $attachments array starting at zero, you simply need to let PHP create the keys itself:
$attachments[] = ['is_attachment' => true, 'name' => $object->value, 'attachment' => ''];

Unable to get multiple notifications on same device with different device tokens

I have to implement notification functionality in my project which is made in CodeIgniter.
Scenario is like, I have two apps in my device i.e. driver and passenger app. I have created a function in a controller file and trying to send notifications to both the apps. But I am getting the notification on only one driver app.
Below is my controller function. Please suggest me where I am committing mistake -
public function tripNotStartedCron() {
try {
$allTripsdata = $this->trip->getAllTripsCron();
echo "<pre>";print_r($allTripsdata);
$allCancelTripsdata = $this->trip->getAllTripsCron(1);
print_r($allCancelTripsdata);
// Send notification for trip notification after 30 min
foreach ($allTripsdata as $tripsData) {
/* Time calculation */
$buggyTimeZones = array('19800' => 'Asia/Calcutta');
if (array_key_exists($tripsData['timezone'], $buggyTimeZones)) {
$pickUpLocationTimeZone = $buggyTimeZones[$tripsData['timezone']];
} else {
$pickUpLocationTimeZone = timezone_name_from_abbr('', $tripsData['timezone'], 0);
}
$date = new DateTime('NOW', new DateTimeZone($pickUpLocationTimeZone));
$tripsData['pickupdatetime'] = date('Y-m-d H:i:s', strtotime($tripsData['pickupdatetime'] . ' +' . CONFIRMED_CANCELLED_TRIP . ' minutes'));
$tripDateTime = new DateTime($tripsData['pickupdatetime'], new DateTimeZone($pickUpLocationTimeZone));
/* End time calculation */
$driverId = $tripsData['fkdriverid'];
$rideId = $tripsData['rideid'];
$asap = $tripsData['is_pickup_as_soon'];
$tripStatusId = TRIP_STATUS_DRIVERCONFIRMED;
//$message = 'You have a trip that was scheduled to start more than ' . CONFIRMED_CANCELLED_TRIP . ' minutes ago, if you do not start it within ' . DRIVER_TRIP_CANCELLED_SECOND_WARING . ' minutes it will be automatically cancelled.';
$message = 'You have a trip that was scheduled to start more than 1 hour ago, if you do not start it within ' . DRIVER_TRIP_CANCELLED_SECOND_WARING . ' minutes it will be automatically cancelled.';
//echo date($date->format('U'))."----------".date($tripDateTime->format('U'));
if ($date->format('U') > $tripDateTime->format('U')) {
if ($driverId > 0) {
/* * ** Send push notificaion on ios *** */
$iosDeviceDetailArr = $this->profile->getIosNotificationStatus($driverId, DRIVER_ROLE, IOS);
$tripCompleteDetail = $this->trip->getOrderDetailForARide($rideId);
$driverDetails = $this->profile->getDriverDetails($driverId);
$driverBUserId = $driverDetails[0]->id ? $driverDetails[0]->id : 0;
$driverCurrentUserId = $driverId;
$driverCurrentRoleId = DRIVER_ROLE;
$additionalDetail = array();
if (!empty($driverBUserId)) {
$additionalDetail = array('bUserId' => $driverBUserId, 'currentUserId' => $driverCurrentUserId, 'currentRoleId' => $driverCurrentRoleId);
}
/* store notification detail in db start */
$dataDictionary = array(
'alert' => $message,
'ondemand' => $asap,
'ridedetail' => $tripCompleteDetail,
'rideid' => $rideId,
'type' => "trip_cancel_reminder",
'userdetail' => $additionalDetail
);
$dataToSave = array(
'buserid' => $additionalDetail['bUserId'],
'currentuserid' => $additionalDetail['currentUserId'],
'currentroleid' => $additionalDetail['currentRoleId'],
'datadictionary' => json_encode($dataDictionary),
'rideid' => $rideId,
'notificationlabel' => 'Trip Scheduling Alert',
'createddate' => date('Y-m-d H:i:s'),
'modifydate' => date('Y-m-d H:i:s')
);
$notificationId = $this->common->saveDetails(TBL_PUSH_NOTIFICATIONS, $dataToSave);
if ($notificationId) {
updateNotificationStatus(array('currentuserid' => $additionalDetail['currentUserId'], 'rideid' => $rideId, 'notificationid !=' => $notificationId), 'trip_cancel_reminder');
}
$tripCompleteDetail[0]['notificationId'] = (isset($notificationId) && $notificationId) ? $notificationId : 0;
/* store notification detail in db start */
$res = member_notification_ios($iosDeviceDetailArr, $message, $rideId, $asap, $tripCompleteDetail, $additionalDetail, 'trip_cancel_reminder');
/* * ** Send push notificaion on antroid device *** */
$androidDeviceDetailArr = $this->profile->getIosNotificationStatus($driverId, DRIVER_ROLE, ANTROID);
if (is_array($androidDeviceDetailArr) && count($androidDeviceDetailArr) > 0)
foreach ($androidDeviceDetailArr as $deviceDetail) {
/* * ** Code for send push notification *** */
$deviceToken = isset($deviceDetail['devicetoken']) ? $deviceDetail['devicetoken'] : '';
$deviceToken = get_device_token($deviceToken);
if (isset($deviceToken) && !empty($deviceToken))
$androidRes = member_notification_antroid($deviceDetail['devicetoken'], $message, $rideId, $asap, $tripCompleteDetail, $additionalDetail, 'trip_cancel_reminder');
}
/* Update notification status in TBL_TRIPS_ASSIGNEDDRIVER table */
$data = array('notificationflag' => 1);
$condition = array('fkdriverid' => $driverId, 'rideid' => $rideId, 'tripstatusid' => $tripStatusId);
$updateResult = $this->common->saveDetails(TBL_TRIPS_ASSIGNEDDRIVER, $data, $condition);
/* * ** End of code for push notification *** */
}
}
}
// Send notification for trip cancelation after 35 min
foreach ($allCancelTripsdata as $canceltripsData) {
/* Time calculation */
$buggyTimeZones = array('19800' => 'Asia/Calcutta');
if (array_key_exists($canceltripsData['timezone'], $buggyTimeZones)) {
$pickUpLocationTimeZone = $buggyTimeZones[$canceltripsData['timezone']];
} else {
$pickUpLocationTimeZone = timezone_name_from_abbr('', $canceltripsData['timezone'], 0);
}
$date = new DateTime('NOW', new DateTimeZone($pickUpLocationTimeZone));
$canceltripsData['pickupdatetime'] = date('Y-m-d H:i:s', strtotime($canceltripsData['pickupdatetime'] . ' +' . CONFIRMED_CANCELLED_TRIP_FINAL . ' minutes'));
$tripDateTime = new DateTime($canceltripsData['pickupdatetime'], new DateTimeZone($pickUpLocationTimeZone));
$driverId = $canceltripsData['fkdriverid'];
$rideId = $canceltripsData['rideid'];
$asap = $canceltripsData['is_pickup_as_soon'];
$tripStatusId = TRIP_STATUS_DRIVERCONFIRMED;
//$message = 'Your trip has been cancelled because it was never started.';
$messagePassenger = 'Your trip has been cancelled because the driver did not show up to the location.';
$messageDriver = 'Your trip has been cancelled because you did not show up to the location.';
if ($date->format('U') > $tripDateTime->format('U')) {
if ($driverId > 0) {
/** ** Send push notificaion on ios *** */
$tripCompleteDetail = $this->trip->getOrderDetailForARide($rideId);
$iosDeviceDetailArrDriver = $this->profile->getIosNotificationStatus($driverId, DRIVER_ROLE, IOS);
//echo "<pre>";print_r($iosDeviceDetailArr);die(' ll');
$driverDetails = $this->profile->getDriverDetails($driverId);
$driverBUserId = $driverDetails[0]->id ? $driverDetails[0]->id : 0;
$driverCurrentUserId = $driverId;
$driverCurrentRoleId = DRIVER_ROLE;
$additionalDetailDriver = array();
$additionalDetailPassenger = array();
if (!empty($driverBUserId)) {
$additionalDetailDriver = array('bUserId' => $driverBUserId, 'currentUserId' => $driverCurrentUserId, 'currentRoleId' => $driverCurrentRoleId);
}
/* store notification detail in db start */
$dataDictionaryDriver = array(
'alert' => $messageDriver,
'ondemand' => $asap,
'ridedetail' => $tripCompleteDetail,
'rideid' => $rideId,
'type' => "trip_cancel_notification_driver",
'userdetail' => $additionalDetailDriver
);
$dataToSaveDriver = array(
'buserid' => $additionalDetailDriver['bUserId'],
'currentuserid' => $additionalDetailDriver['currentUserId'],
'currentroleid' => $additionalDetailDriver['currentRoleId'],
'datadictionary' => json_encode($dataDictionaryDriver),
'rideid' => $rideId,
'notificationlabel' => 'Trip Cancelled',
'forlisting' => 0,
'createddate' => date('Y-m-d H:i:s'),
'modifydate' => date('Y-m-d H:i:s')
);
$notificationIdDriver = $this->common->saveDetails(TBL_PUSH_NOTIFICATIONS, $dataToSaveDriver);
if ($notificationIdDriver) {
updateNotificationStatus(array('currentuserid' => $additionalDetailDriver['currentUserId'], 'rideid' => $rideId, 'notificationid !=' => $notificationIdDriver), 'trip_cancel_notification_driver');
}
$tripCompleteDetail[0]['notificationId'] = (isset($notificationIdDriver) && $notificationIdDriver) ? $notificationIdDriver : 0;
/* store notification detail in db start */
$res = member_notification_ios($iosDeviceDetailArrDriver, $messageDriver, $rideId, $asap, $tripCompleteDetail, $additionalDetailDriver, 'trip_cancel_notification_driver');
$androidDeviceDetailArrDriver = $this->profile->getIosNotificationStatus($driverId, DRIVER_ROLE, ANTROID);
if (is_array($androidDeviceDetailArrDriver) && count($androidDeviceDetailArrDriver) > 0) {
foreach ($androidDeviceDetailArrDriver as $deviceDetail) {
/* * ** Code for send push notification *** */
$deviceToken = isset($deviceDetail['devicetoken']) ? $deviceDetail['devicetoken'] : '';
$deviceToken = get_device_token($deviceToken);
if (isset($deviceToken) && !empty($deviceToken))
$androidRes = member_notification_antroid($deviceDetail['devicetoken'], $messageDriver, $rideId, $asap, $tripCompleteDetail, $additionalDetailDriver, 'trip_cancel_notification_driver');
}
}
/*********************************************************/
$iosDeviceDetailArrPassenger = $this->profile->getIosNotificationStatus($tripCompleteDetail[0]['currentuserid'], USER_ROLE, IOS);
$userRecord = $this->common->getData(TBL_USE_AS, array('use_driverfy_as' => $tripCompleteDetail[0]['currentuserid']), 'array', 'userid', 'rows');
if (!empty($userRecord)) {
$additionalDetailPassenger = array('bUserId' => $userRecord[0]['userid'], 'currentUserId' => $tripCompleteDetail[0]['currentuserid'], 'currentRoleId' => USER_ROLE);
}
$dataDictionaryPassenger = array(
'alert' => $messagePassenger,
'ondemand' => $asap,
'ridedetail' => $tripCompleteDetail,
'rideid' => $rideId,
'type' => "trip_cancel_notification_passenger",
'userdetail' => $additionalDetailPassenger
);
$dataToSavePassenger = array(
'buserid' => $additionalDetailPassenger['bUserId'],
'currentuserid' => $additionalDetailPassenger['currentUserId'],
'currentroleid' => $additionalDetailPassenger['currentRoleId'],
'datadictionary' => json_encode($dataDictionaryPassenger),
'rideid' => $rideId,
'notificationlabel' => 'Trip Cancelled',
'forlisting' => 0,
'createddate' => date('Y-m-d H:i:s'),
'modifydate' => date('Y-m-d H:i:s')
);
$notificationIdPassenger = $this->common->saveDetails(TBL_PUSH_NOTIFICATIONS, $dataToSavePassenger);
if ($notificationIdPassenger) {
updateNotificationStatus(array('currentuserid' => $additionalDetailPassenger['currentUserId'], 'rideid' => $rideId, 'notificationid !=' => $notificationIdPassenger), 'trip_cancel_notification_passenger');
}
$tripCompleteDetail[0]['notificationId'] = (isset($notificationIdPassenger) && $notificationIdPassenger) ? $notificationIdPassenger : 0;
/* store notification detail in db start */
$res = member_notification_ios($iosDeviceDetailArrPassenger, $messagePassenger, $rideId, $asap, $tripCompleteDetail, $additionalDetailPassenger, 'trip_cancel_notification_passenger', '', USER_ROLE);
die("tt");
/** ** Send push notificaion on antroid device *** */
$androidDeviceDetailArrPassenger = $this->profile->getIosNotificationStatus($tripCompleteDetail[0]['currentuserid'], USER_ROLE, ANTROID);
if (is_array($androidDeviceDetailArrPassenger) && count($androidDeviceDetailArrPassenger) > 0) {
foreach ($androidDeviceDetailArrPassenger as $deviceDetail) {
/* * ** Code for send push notification *** */
$deviceToken = isset($deviceDetail['devicetoken']) ? $deviceDetail['devicetoken'] : '';
$deviceToken = get_device_token($deviceToken);
if (isset($deviceToken) && !empty($deviceToken))
$androidRes = member_notification_antroid($deviceDetail['devicetoken'], $messagePassenger, $rideId, $asap, $tripCompleteDetail, $additionalDetailPassenger, 'trip_cancel_notification_passenger');
}
}
/* * ** End Send push notificaion on antroid device *** */
/* Update notification status in TBL_TRIPS_ASSIGNEDDRIVER table */
$cancelData = array('tripstatusid' => TRIP_STATUS_CANCEL_RUN);
$conditionCancel = array('fkdriverid' => $driverId, 'rideid' => $rideId, 'tripstatusid' => $tripStatusId);
$updateResult = $this->common->saveDetails(TBL_TRIPS_ASSIGNEDDRIVER, $cancelData, $conditionCancel);
/* * ** End of code for push notification *** */
/* Code for void authorized amount of cancel trip */
$orderResultedData = $this->common->getData(TBL_RS_ORDER, array('bookingid' => $canceltripsData['bookingid']), 'array', 'orderid');
//echo 'orderId=>'.$orderResultedData['orderid']; echo "<br/>";
$tripAuthorizationDetails = $this->common->getRowDetails(TBL_RS_ORDER_AUTHORIZATION, array('orderid' => $orderResultedData['orderid'], 'authorization_status' => 'hold', 'is_edit_charge' => 0, 'is_cancel_charge' => 0), '', 1);
//print_r($tripAuthorizationDetails);
if (count($tripAuthorizationDetails) > 0) {
foreach ($tripAuthorizationDetails as $key => $value) {
$brainTreeAuthorizationId = base64_decode($value['braintree_authorization_id']);
$orderAuthorizationId = $value['id'];
/* Here we will void all amount and maintain records in tables for future */
$this->load->library("braintreelib");
$rsltVoidSucc = $this->braintreelib->voidTransactionCustomer($brainTreeAuthorizationId);
if ($rsltVoidSucc->success) {
/* Insert records in escrow details table */
$tableName = TBL_ORDER_ESCROW_DETAIL;
$condition = array();
$dataToSave = array(
'escrow_status' => VOID_ALL_AMOUNT,
'order_id' => $orderResultedData['orderid'],
'final_trip_amount' => 0,
'created_date' => date('Y-m-d H:i:s'),
'braintree_escrow_id' => $brainTreeAuthorizationId,
'order_authorization_id' => $orderAuthorizationId
);
$insertData = $this->common->saveDetails($tableName, $dataToSave, $condition);
if ($insertData) {
$updateData = $this->common->saveDetails(TBL_RS_ORDER_AUTHORIZATION, array('authorization_status' => 'amount_void'), array('id' => $value['id']));
} else {
$this->data['status'] = faLSE;
$this->data['data'] = '';
$this->data['errorMessages'] = 'Your trip is cancel, but amount is not refund. Please contact to admin.';
}
/* End */
} else {
$errorFound = '';
foreach ($rsltVoidSucc->errors->deepAll() as $error) {
echo $errorFound = $error->message;
}
die();
}
}
}
/* End code for void authorized amount of cancel trip */
}
}
}
} catch (Exception $e) {
echo $e->getMessage() . "<br>" . $e->getFile() . "<br>" . $e->getLine();
}
}

PHP IMAP failed to get attachment if its filename contains asterisks

I'm using IMAP to do some data entry by reading a mailbox. The code works perfectly for almost all emails except for one instance where the attachment's filename contains asterisk (*) character, in such case the code can't grab the file (or more exactly, the PDF attachment is not readable)
The code that I write to fetch email content (including getting PDF attachment) is:
public function fetchBody ($message_num) {
if ($this->imap) {
$body = '';
$body_type = 'text';
$attachments = array();
$structure = imap_fetchstructure($this->imap, $message_num);
//pr($structure);
if (!$structure) {
return false;
} else {
if ($structure->type == 0) {
if (strtolower($structure->subtype) == 'html') {
$body_type = 'html';
}
$body = $this->decodeBody(imap_body($this->imap, $message_num), $structure->encoding, FT_PEEK);
} elseif ($structure->type == 1) {
// Grab the text portion of a multipart email
if (count($structure->parts)) {
foreach ($structure->parts as $i => $part) {
if (strtolower($part->subtype) == 'alternative') {
if (count($part->parts)) {
foreach ($part->parts as $j => $subpart) {
if (strtolower($subpart->subtype) == 'plain' || strtolower($subpart->subtype) == 'text') {
$body = $this->decodeBody(imap_fetchbody($this->imap, $message_num, ($i + 1) . '.' . ($j + 1), FT_PEEK), $subpart->encoding);
}
}
}
} elseif (strtolower($part->subtype) == 'related') {
if (count($part->parts)) {
foreach ($part->parts as $j => $subpart) {
if ( isset($subpart->parts) && count($subpart->parts)) {
foreach ($subpart->parts as $k => $subsubpart) {
if (strtolower($subsubpart->subtype) == 'plain' || strtolower($subsubpart->subtype) == 'text') {
$body = $this->decodeBody(imap_fetchbody($this->imap, $message_num, ($i + 1) . '.' . ($j + 1) . '.' . ($k + 1), FT_PEEK), $subsubpart->encoding);
}
}
}
}
}
} elseif (strtolower($part->subtype) == 'plain' || strtolower($part->subtype) == 'text') {
$body = $this->decodeBody(imap_fetchbody($this->imap, $message_num, $i + 1, FT_PEEK), $structure->encoding);
} else {
CakeLog::write('debug', print_r($part, true));
if (($part->type >= 2 && $part->type <= 7) && (!isset($part->parts))) {
$attachments[] = $this->processAttachment($part, $i);
}elseif (strtolower($part->subtype) == 'mixed' || (count($part->parts) && $part->subtype == 'RFC822')) {
if (count($part->parts)) {
foreach ($part->parts as $j => $subpart) {
if (strtolower($subpart->subtype) == 'plain' || strtolower($subpart->subtype) == 'text') {
$body = $this->decodeBody(imap_fetchbody($this->imap, $message_num, ($i + 1) . '.' . ($j + 1) . '.' . ($k + 1), FT_PEEK), $mixedsubpart->encoding);
}else{
if ($subpart->type >= 2 && $subpart->type <= 7) {
$attachments[] = $this->processAttachment($subpart, $i);
}
}
}
}
}
}
}
}
}
}
$data['body'] = $this->cleanUp($body, $structure);
$data['body_type'] = $body_type;
$data['attachments'] = $attachments;
return $data;
} else {
return false;
}
}
Also, this is the debug output when the code detects attachment's filename contains asterisk characters:
2016-02-19 17:13:46 Debug: stdClass Object
(
[type] => 2
[encoding] => 0
[ifsubtype] => 1
[subtype] => RFC822
[ifdescription] => 0
[ifid] => 0
[lines] => 343
[bytes] => 25561
[ifdisposition] => 0
[ifdparameters] => 0
[ifparameters] => 0
[parameters] => stdClass Object
(
)
[parts] => Array
(
[0] => stdClass Object
(
[type] => 3
[encoding] => 3
[ifsubtype] => 1
[subtype] => PDF
[ifdescription] => 1
[description] => *MEA - Invoice No. 91135811 *
[ifid] => 0
[bytes] => 23602
[ifdisposition] => 0
[ifdparameters] => 0
[ifparameters] => 1
[parameters] => Array
(
[0] => stdClass Object
(
[attribute] => name
[value] => *MEA - Invoice No. 91135811 *.pdf
)
)
)
)
)
I can still save all the information (title, filename, etc) to the database though, only the file when saved to the server is unreadable for some reason (see attached photo)
Has anybody come across this situation before?

How can I get and display imap emails with attachments and display

I'm trying to grab an email and display the body of the email as well as links to download any attachments. I've had success with other emails without attachments but with this, I can't even find the body.
My questions:
Where is the body? How do I get it in readable format?
If I were to link to an attachment, what kind of code would I have to use to display the attachment?
Thanks in advance!
--
expected email body:
This s the second test with attachments
expected email attachment:
code:
$mbox = imap_open($mailbox_path, $username, $password);
$msgs = imap_sort($mbox, SORTDATE, 1, SE_UID);
$msguid = array_shift($msgs);
$email['msgno'] = imap_msgno($mbox, $msguid);
$email['body'] = imap_fetchbody($mbox, $email['msgno'], 2);
$email['printable_body'] = quoted_printable_decode($email['body']);
$email['attachments'] = getAttachments($mbox, $email['msgno']);
print_r($email);
function getAttachments($connection, $message_number) {
$structure = imap_fetchstructure($connection, $message_number);
$attachments = array();
if(isset($structure->parts) && count($structure->parts)) {
for($i = 0; $i < count($structure->parts); $i++) {
$attachments[$i] = array(
'is_attachment' => false,
'filename' => '',
'name' => '',
'attachment' => ''
);
if($structure->parts[$i]->ifdparameters) {
foreach($structure->parts[$i]->dparameters as $object) {
if(strtolower($object->attribute) == 'filename') {
$attachments[$i]['is_attachment'] = true;
$attachments[$i]['filename'] = $object->value;
}
}
}
if($structure->parts[$i]->ifparameters) {
foreach($structure->parts[$i]->parameters as $object) {
if(strtolower($object->attribute) == 'name') {
$attachments[$i]['is_attachment'] = true;
$attachments[$i]['name'] = $object->value;
}
}
}
if($attachments[$i]['is_attachment']) {
$attachments[$i]['attachment'] = imap_fetchbody($connection, $message_number, $i+1);
if($structure->parts[$i]->encoding == 3) { // 3 = BASE64
$attachments[$i]['attachment'] = base64_decode($attachments[$i]['attachment']);
}
elseif($structure->parts[$i]->encoding == 4) { // 4 = QUOTED-PRINTABLE
$attachments[$i]['attachment'] = quoted_printable_decode($attachments[$i]['attachment']);
}
}
}
}
return $attachments;
}
output:
Array
(
[msgno] => 1
[body] => bWFnZVJlYWR5ccllPAAAA09JREFUeNqUVG1MTmEYfr7PKzYjZvODZlr+hFlo813GD5+LTKtNs6aX
Rn4oP9iyUsNGXsQP6x0ipBGaz5makfrHMMvMCIWZFHo7H89xnRct9BZnu899nvu57+u57o/nUPIf
z7Rl6cKyzHir21xh22YsTJQL+VgZvnKljNeNNRWE/SvYzFVZDMExQgi/UIpK5TsIoMOQEbAt5Xh5
fqI/kLnpfk5c4jF5o7UeTqlcyxl/KIQdbDh/vGva8gwCZp9ANINSOhJ+rf0yhNNkSDZkNOd8IUjE
MM4rPTBvv6nmJJFSdUkpHTEQwwWZmyRYzXNd9zmW7QBNxneVS9z2Xj4UPsO8s7HXGSbRF9jidVu4
o3UCnDKQ8j7K6EpXa/NacH9giT+fwO6l98VxnJFYZLsueXQtWHrai2URUo1GinMgzUKKYYyxGUj1
7A8GdDDUasg47MfDHsc5u/8rtk9AdGwWnKegLHWcCz+k7srRvW0rNm6nsM+HTIBI2FOhaxnjL37F
/lXDVZsLOOqSirRqwDQWNQvh+0qYHaOjOOVJzGVVXsNgb9WaVl04UkIiMkTQbJzayQVvhE7EmNxA
yq/SthQqrCdBNMrQCb0I9ooLZSXfesf/Bpi5bXecUioXssdn+CZCO5D66kBRSEk11VDGGmWoWthy
pJL3zgUKn/xJqCflDUUHpGmZaTj1GaPUROcSkVJTcGdeZ07xQdLdbSajFJ+wr6AlQm71VX/RqxGT
FSXjAVKGoGivi/guD+9xAbYkjhD3EGqXAsAzkOY+J8R75ZcGJeYuD04vtXYuomujYd6K+j1gjL7F
vGVgv4wzFoVDZjjaKQ5sXf85IkMpxVCh3aFwfmra1lec0wKWJzBf6Zi7BLC6aTD2zquMdvVVy6Id
kW5YGHCQzzcEgdq7YtuyUl1o767W/xRSeuoy+xYKlWhHd4Bp7a7cNDcSYLjLhlKmz1BikM+IOlx9
/e9ThRgDn1jDUMd3+NOc/n4o4ifgRyH4e8FFEurUBtMHz155vYGg8xNMy9qM5THbsR8P9N/s+TmU
X7o9VklZgEY4UoijuNDtaMZ0NGClbdt3Qt1mIDtlvjUQYM/YgF0LwPYJ3FWwzaOUoA+0jVikgnD3
7r+Aec93AQYAtxlOu/e3wtgAAAAASUVORK5CYII=
[printable_body] => iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJ
bWFnZVJlYWR5ccllPAAAA09JREFUeNqUVG1MTmEYfr7PKzYjZvODZlr+hFlo813GD5+LTKtNs6aX
Rn4oP9iyUsNGXsQP6x0ipBGaz5makfrHMMvMCIWZFHo7H89xnRct9BZnu899nvu57+u57o/nUPIf
z7Rl6cKyzHir21xh22YsTJQL+VgZvnKljNeNNRWE/SvYzFVZDMExQgi/UIpK5TsIoMOQEbAt5Xh5
fqI/kLnpfk5c4jF5o7UeTqlcyxl/KIQdbDh/vGva8gwCZp9ANINSOhJ+rf0yhNNkSDZkNOd8IUjE
MM4rPTBvv6nmJJFSdUkpHTEQwwWZmyRYzXNd9zmW7QBNxneVS9z2Xj4UPsO8s7HXGSbRF9jidVu4
o3UCnDKQ8j7K6EpXa/NacH9giT+fwO6l98VxnJFYZLsueXQtWHrai2URUo1GinMgzUKKYYyxGUj1
7A8GdDDUasg47MfDHsc5u/8rtk9AdGwWnKegLHWcCz+k7srRvW0rNm6nsM+HTIBI2FOhaxnjL37F
/lXDVZsLOOqSirRqwDQWNQvh+0qYHaOjOOVJzGVVXsNgb9WaVl04UkIiMkTQbJzayQVvhE7EmNxA
yq/SthQqrCdBNMrQCb0I9ooLZSXfesf/Bpi5bXecUioXssdn+CZCO5D66kBRSEk11VDGGmWoWthy
pJL3zgUKn/xJqCflDUUHpGmZaTj1GaPUROcSkVJTcGdeZ07xQdLdbSajFJ+wr6AlQm71VX/RqxGT
FSXjAVKGoGivi/guD+9xAbYkjhD3EGqXAsAzkOY+J8R75ZcGJeYuD04vtXYuomujYd6K+j1gjL7F
vGVgv4wzFoVDZjjaKQ5sXf85IkMpxVCh3aFwfmra1lec0wKWJzBf6Zi7BLC6aTD2zquMdvVVy6Id
kW5YGHCQzzcEgdq7YtuyUl1o767W/xRSeuoy+xYKlWhHd4Bp7a7cNDcSYLjLhlKmz1BikM+IOlx9
/e9ThRgDn1jDUMd3+NOc/n4o4ifgRyH4e8FFEurUBtMHz155vYGg8xNMy9qM5THbsR8P9N/s+TmU
X7o9VklZgEY4UoijuNDtaMZ0NGClbdt3Qt1mIDtlvjUQYM/YgF0LwPYJ3FWwzaOUoA+0jVikgnD3
7r+Aec93AQYAtxlOu/e3wtgAAAAASUVORK5CYII
[attachments] => Array
(
[0] => Array
(
[is_attachment] =>
[filename] =>
[name] =>
[attachment] =>
)
[1] => Array
(
[is_attachment] => 1
[filename] => attachment.png
[name] => attachment.png
[attachment] => ‰PNG
IHDR‰
tEXtSoftwareAdobe ImageReadyqÉe<OIDATxÚ”TmLNa~¾Ï+6#fóƒfZþ„Yhó]ÆŸ‹L«M³¦—F~(?زRÃF^Äë"¤šÏ™š‘úÇ0ËÌ…™z;Ïq-ôg»Ï}žû¹ïë¹îçPòÏ´eé²Ìx«Û\aÛf,L”ùX¾r¥Œ×5„ý+ØÌUYÁ1B¿PŠJå; ð-åxy~¢?¹é~N\â1y£µN©\Ë(„l8¼kÚòfŸ#4ƒR:~­ý2„ÓdH6d4ç|!HÄ0Î+=0o¿©æ$‘RuI)1Ù›$XÍs]÷9–íMÆw•KÜö^>>ü³±×&ÑØâu[¸£uœ2ò>ÊèJWkóZp`‰?ŸÀî¥÷Åqœ‘Xd».yt-XzÚ‹eRFŠs ÍBŠaŒ±Hõìt0ÔjÈ8ìÇÃÇ9»ÿ+¶O#tlœ§ ,uœ?¤îÊѽm+6n§°Ï‡L€HØS¡kã/~ÅþUÃU›8ê’Š´jÀ45áûJ˜££8åIÌeU^Ã`oÕšV]8RB"2DÐlœÚÉo„NĘÜ#ʯҶ*¬'A4ÊÐ ½öŠe%ßzÇÿ˜¹mwœR*²Çgø&B;úê#QHI5ÕPÆe¨ZØr¤’÷Î
ŸüI¨'å
E¤i™i8õ£ÔDç‘RSpg^gNñAÒÝm&£Ÿ°¯ %BnõUÑ«“%ãR† h¯‹ø.ïq¶$Ž÷j—À3æ>'Ä{å—%æ.N/µv.¢k£aÞŠú=`Œ¾Å¼e`¿Œ3…Cf8Ú)l]ÿ9"C)ÅP¡Ý¡p~jÚÖWœÓ–'0_阻°ºi0öΫŒvõUË¢‘nXpÏ7Ú»bÛ²R]hï®ÖÿRzê2û
•hGw€ií®Ü47`¸Ë†R¦ÏPbψ:\}ýïS…ŸXÃPÇwøÓœþ~(â'àG!ø{ÁEêÔÓÏ^y½ óLËÚŒå1Û±ôßìù9”_º=VIY€F8Rˆ£¸ÐíhÆt4`¥mÛwBÝf ;e¾5`ÏØ€]Àö ÜU°Í£” ´X¤‚p÷î¿€yÏw·N»÷·ÂØIEND®B`‚
)
)
)

PHP Read Specific Value from API Response

I have this bit of code:
<?php
#
# Sample Socket I/O to CGMiner API
#
function getsock($addr, $port)
{
$socket = null;
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
if ($socket === false || $socket === null)
{
$error = socket_strerror(socket_last_error());
$msg = "socket create(TCP) failed";
echo "ERR: $msg '$error'\n";
return null;
}
$res = socket_connect($socket, $addr, $port);
if ($res === false)
{
$error = socket_strerror(socket_last_error());
$msg = "socket connect($addr,$port) failed";
echo "ERR: $msg '$error'\n";
socket_close($socket);
return null;
}
return $socket;
}
#
# Slow ...
function readsockline($socket)
{
$line = '';
while (true)
{
$byte = socket_read($socket, 1);
if ($byte === false || $byte === '')
break;
if ($byte === "\0")
break;
$line .= $byte;
}
return $line;
}
#
function request($cmd)
{
$socket = getsock('127.0.0.1', 4028);
if ($socket != null)
{
socket_write($socket, $cmd, strlen($cmd));
$line = readsockline($socket);
socket_close($socket);
if (strlen($line) == 0)
{
echo "WARN: '$cmd' returned nothing\n";
return $line;
}
print "$cmd returned '$line'\n";
if (substr($line,0,1) == '{')
return json_decode($line, true);
$data = array();
$objs = explode('|', $line);
foreach ($objs as $obj)
{
if (strlen($obj) > 0)
{
$items = explode(',', $obj);
$item = $items[0];
$id = explode('=', $items[0], 2);
if (count($id) == 1 or !ctype_digit($id[1]))
$name = $id[0];
else
$name = $id[0].$id[1];
if (strlen($name) == 0)
$name = 'null';
if (isset($data[$name]))
{
$num = 1;
while (isset($data[$name.$num]))
$num++;
$name .= $num;
}
$counter = 0;
foreach ($items as $item)
{
$id = explode('=', $item, 2);
if (count($id) == 2)
$data[$name][$id[0]] = $id[1];
else
$data[$name][$counter] = $id[0];
$counter++;
}
}
}
return $data;
}
return null;
}
#
if (isset($argv) and count($argv) > 1)
$r = request($argv[1]);
else
$r = request('summary');
#
echo print_r($r, true)."\n";
#
?>
Which outputs this information:
summary returned 'STATUS=S,When=1399108671,Code=11,Msg=Summary,Description=cgminer 4.3.0hf|SUMMARY,Elapsed=531,MHS av=453052.33,MHS 5s=537024.44,MHS 1m=458922.01,MHS 5m=375184.88,MHS 15m=201623.38,Found Blocks=0,Getworks=16,Accepted=518,Rejected=12,Hardware Errors=271,Utility=58.54,Discarded=276,Stale=0,Get Failures=0,Local Work=65806,Remote Failures=0,Network Blocks=1,Total MH=240524241.0000,Work Utility=5589.33,Difficulty Accepted=49008.00000000,Difficulty Rejected=448.00000000,Difficulty Stale=0.00000000,Best Share=93465,Device Hardware%=0.5450,Device Rejected%=0.9059,Pool Rejected%=0.9059,Pool Stale%=0.0000,Last getwork=1399108671|'
Array
(
[STATUS] => Array
(
[STATUS] => S
[When] => 1399108671
[Code] => 11
[Msg] => Summary
[Description] => cgminer 4.3.0
)
[SUMMARY] => Array
(
[0] => SUMMARY
[Elapsed] => 531
[MHS av] => 453052.33
[MHS 5s] => 537024.44
[MHS 1m] => 458922.01
[MHS 5m] => 375184.88
[MHS 15m] => 201623.38
[Found Blocks] => 0
[Getworks] => 16
[Accepted] => 518
[Rejected] => 12
[Hardware Errors] => 271
[Utility] => 58.54
[Discarded] => 276
[Stale] => 0
[Get Failures] => 0
[Local Work] => 65806
[Remote Failures] => 0
[Network Blocks] => 1
[Total MH] => 240524241.0000
[Work Utility] => 5589.33
[Difficulty Accepted] => 49008.00000000
[Difficulty Rejected] => 448.00000000
[Difficulty Stale] => 0.00000000
[Best Share] => 93465
[Device Hardware%] => 0.5450
[Device Rejected%] => 0.9059
[Pool Rejected%] => 0.9059
[Pool Stale%] => 0.0000
[Last getwork] => 1399108671
)
)
How can I get a specific value? For example, how can I output only '[MHS 15m]'
if $res is the variable containing the array you can get the value as
echo $res['SUMMARY']['MHS 15m'];

Categories