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`‚
)
)
)
Related
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' => ''];
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?
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?
In my lottery project I have 5 tickets, in which you select numbers and buy. The thing is, you can only buy the tickets if you buy them in order... For example:
Ticket 1 Ticket 2 Ticket 3 Ticket 4 Ticket 5
If you add numbers to the ticket 1 and then the others it works... If you skip the ticket 1 and add numbers to the other ones, when you try to buy you get this error:
ContextErrorException: Notice: Undefined offset: 0 in C:\wamp\www\Digidis\front\src\MediaparkLt\UserBundle\Service\MoneyManager.php line 313
The full stack:
array('cartProduct' => array('title' => 'EUROMILLONES', 'price' => '2.35', 'product' => '2', 'ticket_id' => '1433921783_19792', 'numbers' => '8,13,14,17,37', 'stars' => '4,7', 'betslip' => '{"duration":"1","subscription":"false","jsPrice":"235","type":"simple","numbers1":"0,0,0,0,0","numbers2":"8,13,14,17,37","numbers3":"0,0,0,0,0","numbers4":"0,0,0,0,0","numbers5":"0,0,0,0,0","stars1":"0,0","stars2":"4,7","stars3":"0,0","stars4":"0,0","stars5":"0,0","dayOfWeek":"3"}', 'is_syndicate' => false, 'draw' => object(DateTime)), 'product' => object(Product), 'user' => object(User), 'reference' => null, 'paymentResult' => 'Authorised', 'bets' => object(stdClass), 'individualBets' => array(), 'tickets' => array(array('numbers' => '8,13,14,17,37', 'stars' => '4,7')), 'k' => '0', 't' => array('numbers' => '0,0,0,0,0', 'stars' => '0,0'), 'is_ticket_filled' => false, 'week_id' => array(array('ticketId' => '7005')), 'g' => '0', 'lastId' => '7005', 'purchase' => object(Purchase), 'price' => '2.35', 'bet' => object(Bet), 'euromillonesBet' => object(EuromillonesBet), 'drawDate' => array(object(DrawDate)), 'j' => '0')) in C:\wamp\www\Digidis\front\src\MediaparkLt\UserBundle\Service\MoneyManager.php line 313
As you can see first it gets the ticket 1, which is empty(or 0) and thats why it causes the error... How can I make it so that it skips the empty tickets?
Here is the controller where the error occurs:
$bets = json_decode($cartProduct['betslip']);
$individualBets = array();
$tickets = array(
array('numbers' => $bets->numbers1, 'stars' => $bets->stars1),
array('numbers' => $bets->numbers2, 'stars' => $bets->stars2),
array('numbers' => $bets->numbers3, 'stars' => $bets->stars3),
array('numbers' => $bets->numbers4, 'stars' => $bets->stars4),
array('numbers' => $bets->numbers5, 'stars' => $bets->stars5)
);
if ($bets->type === 'simple') {
foreach ($tickets as $k => $t) {
$is_ticket_filled = ((int) str_replace(',', '', $t['numbers'])) > 0;
if (!$is_ticket_filled) {
unset($tickets[$k]);
}
}
} else if ($bets->type === 'multiple') {
$tickets = array(array('numbers' => $bets->numbers1, 'stars' => $bets->stars1));
}
$week_id = null;
for ($k = 0; $k < (count($tickets)); $k++) {
for ($g = 0; $g < $bets->duration; $g++) {
if (!isset($week_id[$g])) {
$week_id[$g] = $this->entityManager->getRepository('MediaparkLtLotteryBundle:Bet')->getLastTicketId();
if ($week_id[$g]) {
$week_id[$g]['ticketId'] ++;
} else {
$week_id[$g]['ticketId'] = 0;
}
}
$lastId = $week_id[$g]['ticketId'];
$purchase = new Purchase();
$purchase->setUser($user);
$purchase->setDrawDate($cartProduct['draw']);
$purchase->setProduct($product);
$purchase->setReference($reference);
$price = $cartProduct['price'];
$bet = new Bet();
if ('eurojackpot' == $product->getAlias()) {
$euromillonesBet = new EurojackpotBet();
} else {
$euromillonesBet = new EuromillonesBet();
}
$drawDate = $this->entityManager->getRepository('MediaparkLtLotteryBundle:DrawDate')->findByDrawDate($cartProduct['draw']);
if (!$drawDate)
die('no draw date found ' . $cartProduct['draw']->format('Y-m-d H:i:s'));
$bet->setDrawDate($drawDate[0]);
$bet->setTicketId($lastId);
if (strtoupper($paymentResult) === 'AUTHORISED') {
$bet->setStatus(BetStatus::AUTHORISED);
} else {
$bet->setStatus(BetStatus::FAILED);
}
$bet->setWinnings(0);
$euromillonesBet->setBet($bet);
/// LINE 313 ABOVE!!!!!!!
$numbers = $this->getNumbersArray($tickets[$k]['numbers']);
$j = 0;
foreach ($numbers as $number) {
$j++;
$name = 'setN' . $j;
$euromillonesBet->$name($number);
}
$numbers = $this->getNumbersArray($tickets[$k]['stars']);
$euromillonesBet->setS1($numbers[0]);
$euromillonesBet->setS2($numbers[1]);
$euromillonesBet->setAmountOfStars(Bet::NUMBER_OF_STARS);
$purchase->addBet($bet);
$purchase->setPricePaid($price);
if (strtoupper($paymentResult) === 'AUTHORISED') {
$purchase->setStatus(PaymentStatus::AUTHORISED);
} else {
$purchase->setStatus(PaymentStatus::FAILED);
}
if ($bets->subscription === "true") {
$contract = new PurchaseContract();
$contract->setAccumulatedWinnings(0);
$contract->setCancellationDate(null);
$contract->setFirstDrawDate($purchase->getDrawDate());
$contract->setLastRenewedDate($purchase->getDrawDate());
$contract->setNextRenewalFirstDrawDate($purchase->getDrawDate());
// $contract->setPurchase($purchase);
$contract->setStatusPurchaseContract(1);
$contract->setWeeks(1);
$purchase->setPurchaseContract($contract);
$this->entityManager->persist($contract);
}
if ($g == 0)
$individualBets[] = $euromillonesBet;
$this->entityManager->persist($bet);
$this->entityManager->persist($euromillonesBet);
$this->entityManager->persist($purchase);
$this->entityManager->flush();
}
}
return $individualBets;
}
From what I see the bet type in your object is set to "type":"simple" and numbers1":"0,0,0,0,0"
$is_ticket_filled = ((int) str_replace(',', '', $t['numbers'])) > 0;
//(int) 00000 = 0
if (!$is_ticket_filled) {
unset($tickets[$k]);
}
Is causing the issue since unset does not reset the array indexes.
http://ideone.com/5q74Wv
Then later you iterate using for($k=0; $k < count($tickets); $k++)
You should instead rebase the array after using unset($tickets[$k])
if ($bets->type === 'simple') {
//...
$tickets = array_values($tickets);
}
or check the existence of the ticket when iterating over indexes
$ticketCount = count($tickets);
for ($k=0; $k < $ticketCount; $k++) {
if (false === isset($tickets[$k]) {
continue;
}
//...
}
or easier still, iterate over the existing tickets array using foreach instead of for.
foreach ($tickets as $k => $ticket) {
//...
}
Then change $tickets[$k] with just $ticket since $k is not used anywhere else.
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'];