Skip to content

Commit f887669

Browse files
committed
Bump to v1.4.5
1 parent 0e4bdbb commit f887669

File tree

8 files changed

+99
-21
lines changed

8 files changed

+99
-21
lines changed

CHANGELOG.md

100644100755
+23
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,29 @@ Updates should follow the [Keep a CHANGELOG](http://keepachangelog.com/) princip
1414
### Affected Classes
1515
- NaN
1616

17+
## [1.4.5] - 2019-01-23
18+
### Fixed
19+
- .csv attachement is not processed
20+
- mail part structure property comparison changed to lowercase
21+
- Replace helper functions for Laravel 6.0 #4 (@koenhoeijmakers)
22+
- Date handling in Folder::appendMessage() fixed
23+
- Carbon Exception Parse Data
24+
- Convert sender name from non-utf8 to uf8 (@hwilok)
25+
- Convert encoding of personal data struct
26+
27+
### Added
28+
- Path prefix option added to Client::getFolder() method
29+
- Attachment size handling added
30+
- Find messages by custom search criteria
31+
32+
### Affected Classes
33+
- [Query::class](src/Query/WhereQuery.php)
34+
- [Mask::class](src/Support/Masks/Mask.php)
35+
- [Attachment::class](src/Attachment.php)
36+
- [Client::class](src/Client.php)
37+
- [Folder::class](src/Folder.php)
38+
- [Message::class](src/Message.php)
39+
1740
## [1.4.2.1] - 2019-07-03
1841
### Fixed
1942
- Error in Attachment::__construct #3

README.md

100644100755
+15-3
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ Detailed [config/imap.php](src/config/imap.php) configuration:
115115
## Usage
116116
#### Basic usage example
117117
This is a basic example, which will echo out all Mails within all imap folders
118-
and will move every message into INBOX.read. Please be aware that this should not ben
118+
and will move every message into INBOX.read. Please be aware that this should not be
119119
tested in real live but it gives an impression on how things work.
120120

121121
``` php
@@ -178,6 +178,8 @@ For an easier access please take a look at the new config option `imap.options.d
178178
method takes three options: the required (string) $folder_name and two optional variables. An integer $attributes which
179179
seems to be sometimes 32 or 64 (I honestly have no clue what this number does, so feel free to enlighten me and anyone
180180
else) and a delimiter which if it isn't set will use the default option configured inside the [config/imap.php](src/config/imap.php) file.
181+
> If you are using Exchange you might want to set all parameter and the last `$prefix_address` to `false` e.g. `$oClient->getFolder('name', 32, null, false)` #234
182+
181183
``` php
182184
/** @var \Webklex\PHPIMAP\Client $oClient */
183185

@@ -244,6 +246,10 @@ $aMessage = $oFolder->query()
244246
$aMessage = $oFolder->query()->notText('hello world')->get();
245247
$aMessage = $oFolder->query()->not_text('hello world')->get();
246248
$aMessage = $oFolder->query()->not()->text('hello world')->get();
249+
250+
//Get all messages by custom search criteria
251+
/** @var \Webklex\PHPIMAP\Support\MessageCollection $aMessage */
252+
$aMessage = $oFolder->query()->where(["CUSTOM_FOOBAR" => "fooBar"]])->get();
247253
```
248254

249255
Available search aliases for a better code reading:
@@ -298,7 +304,7 @@ Limiting the request emails:
298304
``` php
299305
/** @var \Webklex\PHPIMAP\Folder $oFolder */
300306

301-
//Get all messages for page 2 since march 15 2018 where each apge contains 10 messages
307+
//Get all messages for page 2 since march 15 2018 where each page contains 10 messages
302308
/** @var \Webklex\PHPIMAP\Support\MessageCollection $aMessage */
303309
$aMessage = $oFolder->query()->since('15.03.2018')->limit(10, 2)->get();
304310
```
@@ -564,7 +570,7 @@ if you're just wishing a feature ;)
564570
| checkConnection | | | Determine if connection was established and connect if not. |
565571
| connect | int $attempts | | Connect to server. |
566572
| disconnect | | | Disconnect from server. |
567-
| getFolder | string $folder_name, int $attributes = 32, int or null $delimiter | Folder | Get a Folder instance by name |
573+
| getFolder | string $folder_name, int $attributes = 32, int or null $delimiter, bool $prefix_address | Folder | Get a Folder instance by name |
568574
| getFolders | bool $hierarchical, string or null $parent_folder | FolderCollection | Get folders list. If hierarchical order is set to true, it will make a tree of folders, otherwise it will return flat array. |
569575
| openFolder | string or Folder $folder, integer $attempts | | Open a given folder. |
570576
| createFolder | string $name | boolean | Create a new folder. |
@@ -712,7 +718,11 @@ if you're just wishing a feature ;)
712718
| getContent | | string or null | Get attachment content |
713719
| getMimeType | | string or null | Get attachment mime type |
714720
| getExtension | | string or null | Get a guessed attachment extension |
721+
| getId | | string or null | Get attachment id |
715722
| getName | | string or null | Get attachment name |
723+
| getPartNumber | | int or null | Get attachment part number |
724+
| getContent | | string or null | Get attachment content |
725+
| setSize | | int or null | Get attachment size |
716726
| getType | | string or null | Get attachment type |
717727
| getDisposition | | string or null | Get attachment disposition |
718728
| getContentType | | string or null | Get attachment content type |
@@ -785,6 +795,8 @@ Extends [Illuminate\Support\Collection::class](https://laravel.com/api/5.4/Illum
785795
| DateTime::__construct(): Failed to parse time string (...) | Please report any new invalid timestamps to [#45](https://github.com/Webklex/php-imap/issues/45) |
786796
| imap_open(): Couldn't open (...) Please log in your web browser: (...) | In order to use IMAP on some services (such as Gmail) you need to enable it first. [Google help page]( https://support.google.com/mail/answer/7126229?hl=en) |
787797
| imap_headerinfo(): Bad message number | This happens if no Message number is available. Please make sure Message::parseHeader() has run before |
798+
| imap_fetchheader(): Bad message number | Try to change the `message_key` [#243](https://github.com/Webklex/laravel-imap/issues/243)
799+
788800

789801
## Milestones & upcoming features
790802
* Wiki!!

src/Attachment.php

100644100755
+11-2
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
namespace Webklex\PHPIMAP;
1414

15+
use Illuminate\Support\Str;
1516
use Illuminate\Support\Facades\File;
1617
use Symfony\Component\HttpFoundation\File\MimeType\ExtensionGuesser;
1718
use Webklex\PHPIMAP\Exceptions\MaskNotFoundException;
@@ -24,6 +25,7 @@
2425
* @package Webklex\PHPIMAP
2526
*
2627
* @property integer part_number
28+
* @property integer size
2729
* @property string content
2830
* @property string type
2931
* @property string content_type
@@ -42,6 +44,8 @@
4244
* @method string setContentType(string $content_type)
4345
* @method string getId()
4446
* @method string setId(string $id)
47+
* @method string getSize()
48+
* @method string setSize(integer $size)
4549
* @method string getName()
4650
* @method string getDisposition()
4751
* @method string setDisposition(string $disposition)
@@ -68,6 +72,7 @@ class Attachment {
6872
'name' => null,
6973
'disposition' => null,
7074
'img_src' => null,
75+
'size' => null,
7176
];
7277

7378
/**
@@ -111,15 +116,15 @@ public function __construct(Message $oMessage, $structure, $part_number = 1) {
111116
*/
112117
public function __call($method, $arguments) {
113118
if(strtolower(substr($method, 0, 3)) === 'get') {
114-
$name = snake_case(substr($method, 3));
119+
$name = Str::snake(substr($method, 3));
115120

116121
if(isset($this->attributes[$name])) {
117122
return $this->attributes[$name];
118123
}
119124

120125
return null;
121126
}elseif (strtolower(substr($method, 0, 3)) === 'set') {
122-
$name = snake_case(substr($method, 3));
127+
$name = Str::snake(substr($method, 3));
123128

124129
$this->attributes[$name] = array_pop($arguments);
125130

@@ -205,6 +210,10 @@ protected function fetch() {
205210
$this->id = str_replace(['<', '>'], '', $this->structure->id);
206211
}
207212

213+
if (property_exists($this->structure, 'bytes')) {
214+
$this->size = $this->structure->bytes;
215+
}
216+
208217
if (property_exists($this->structure, 'dparameters')) {
209218
foreach ($this->structure->dparameters as $parameter) {
210219
if (strtolower($parameter->attribute) == "filename") {

src/Client.php

100644100755
+5-2
Original file line numberDiff line numberDiff line change
@@ -325,15 +325,18 @@ public function disconnect() {
325325
* @param string $folder_name
326326
* @param int $attributes
327327
* @param null|string $delimiter
328+
* @param boolean $prefix_address
328329
*
329330
* @return Folder
330331
*/
331-
public function getFolder($folder_name, $attributes = 32, $delimiter = null) {
332+
public function getFolder($folder_name, $attributes = 32, $delimiter = null, $prefix_address = true) {
332333

333334
$delimiter = $delimiter === null ? ClientManager::get('imap.options.delimiter', '/') : $delimiter;
334335

336+
$folder_name = $prefix_address ? $this->getAddress().$folder_name : $folder_name;
337+
335338
$oFolder = new Folder($this, (object) [
336-
'name' => $this->getAddress().$folder_name,
339+
'name' => $folder_name,
337340
'attributes' => $attributes,
338341
'delimiter' => $delimiter
339342
]);

src/Folder.php

100644100755
+15-1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
namespace Webklex\PHPIMAP;
1414

15+
use Carbon\Carbon;
1516
use Webklex\PHPIMAP\Exceptions\GetMessagesFailedException;
1617
use Webklex\PHPIMAP\Exceptions\MessageSearchValidationException;
1718
use Webklex\PHPIMAP\Query\WhereQuery;
@@ -426,7 +427,20 @@ public function getStatus($options) {
426427
* @throws Exceptions\ConnectionFailedException
427428
*/
428429
public function appendMessage($message, $options = null, $internal_date = null) {
429-
return imap_append($this->client->getConnection(), $this->path, $message, $options, $internal_date);
430+
/**
431+
* Check if $internal_date is parsed. If it is null it should not be set. Otherwise the message can't be stored.
432+
* If this parameter is set, it will set the INTERNALDATE on the appended message. The parameter should be a
433+
* date string that conforms to the rfc2060 specifications for a date_time value or be a Carbon object.
434+
*/
435+
436+
if ($internal_date != null) {
437+
if ($internal_date instanceof Carbon){
438+
$internal_date = $internal_date->format('d-M-Y H:i:s O');
439+
}
440+
return imap_append($this->client->getConnection(), $this->path, $message, $options, $internal_date);
441+
}
442+
443+
return imap_append($this->client->getConnection(), $this->path, $message, $options);
430444
}
431445

432446
/**

src/Message.php

100644100755
+22-10
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
use Webklex\PHPIMAP\Support\AttachmentCollection;
2020
use Webklex\PHPIMAP\Support\FlagCollection;
2121
use Webklex\PHPIMAP\Support\Masks\MessageMask;
22+
use Illuminate\Support\Str;
2223

2324
/**
2425
* Class Message
@@ -239,14 +240,14 @@ public function __construct($uid, $msglist, Client $client, $fetch_options = nul
239240
*/
240241
public function __call($method, $arguments) {
241242
if(strtolower(substr($method, 0, 3)) === 'get') {
242-
$name = snake_case(substr($method, 3));
243+
$name = Str::snake(substr($method, 3));
243244

244245
if(in_array($name, array_keys($this->attributes))) {
245246
return $this->attributes[$name];
246247
}
247248

248249
}elseif (strtolower(substr($method, 0, 3)) === 'set') {
249-
$name = snake_case(substr($method, 3));
250+
$name = Str::snake(substr($method, 3));
250251

251252
if(in_array($name, array_keys($this->attributes))) {
252253
$this->attributes[$name] = array_pop($arguments);
@@ -499,6 +500,7 @@ private function parseDate($header) {
499500
case preg_match('/([A-Z]{2,3}\,\ [0-9]{1,2}\ [A-Z]{2,3}\ [0-9]{4}\ [0-9]{1,2}\:[0-9]{1,2}\:[0-9]{1,2}\ UT)+$/i', $date) > 0:
500501
$date .= 'C';
501502
break;
503+
case preg_match('/([A-Z]{2,3}\,\ [0-9]{1,2}\ [A-Z]{2,3}\ [0-9]{4}\ [0-9]{1,2}\:[0-9]{1,2}\:[0-9]{1,2}\ \+[0-9]{2,4}\ \(\+[0-9]{1,2}\))+$/i', $date) > 0:
502504
case preg_match('/([A-Z]{2,3}[\,|\ \,]\ [0-9]{1,2}\ [A-Z]{2,3}\ [0-9]{4}\ [0-9]{1,2}\:[0-9]{1,2}\:[0-9]{1,2}.*)+$/i', $date) > 0:
503505
case preg_match('/([A-Z]{2,3}\,\ [0-9]{1,2}\ [A-Z]{2,3}\ [0-9]{4}\ [0-9]{1,2}\:[0-9]{1,2}\:[0-9]{1,2}\ [\-|\+][0-9]{4}\ \(.*)\)+$/i', $date) > 0:
504506
case preg_match('/([A-Z]{2,3}\, \ [0-9]{1,2}\ [A-Z]{2,3}\ [0-9]{4}\ [0-9]{1,2}\:[0-9]{1,2}\:[0-9]{1,2}\ [\-|\+][0-9]{4}\ \(.*)\)+$/i', $date) > 0:
@@ -601,12 +603,18 @@ private function parseAddresses($list) {
601603
if (!property_exists($address, 'personal')) {
602604
$address->personal = false;
603605
}
606+
if (!property_exists($address, 'personal')) {
607+
$address->personal = false;
608+
} else {
609+
$personalParts = imap_mime_header_decode($address->personal);
604610

605-
$personalParts = imap_mime_header_decode($address->personal);
606-
607-
$address->personal = '';
608-
foreach ($personalParts as $p) {
609-
$address->personal .= $p->text;
611+
if(is_array($personalParts)) {
612+
$address->personal = '';
613+
foreach ($personalParts as $p) {
614+
$encoding = $this->getEncoding($p->text);
615+
$address->personal .= $this->convertEncoding($p->text, $encoding);
616+
}
617+
}
610618
}
611619

612620
$address->mail = ($address->mailbox && $address->host) ? $address->mailbox.'@'.$address->host : false;
@@ -663,10 +671,10 @@ private function fetchStructure($structure, $partNumber = null) {
663671

664672
if ($structure->type == IMAP::MESSAGE_TYPE_TEXT &&
665673
($structure->ifdisposition == 0 ||
666-
($structure->ifdisposition == 1 && !isset($structure->parts) && $partNumber != null)
674+
(empty($structure->disposition) || strtolower($structure->disposition) != 'attachment')
667675
)
668676
) {
669-
if ($structure->subtype == "PLAIN") {
677+
if (strtolower($structure->subtype) == "plain" || strtolower($structure->subtype) == "csv") {
670678
if (!$partNumber) {
671679
$partNumber = 1;
672680
}
@@ -699,7 +707,7 @@ private function fetchStructure($structure, $partNumber = null) {
699707

700708
$this->fetchAttachment($structure, $partNumber);
701709

702-
} elseif ($structure->subtype == "HTML") {
710+
} elseif (strtolower($structure->subtype) == "html") {
703711
if (!$partNumber) {
704712
$partNumber = 1;
705713
}
@@ -717,6 +725,10 @@ private function fetchStructure($structure, $partNumber = null) {
717725
$body->content = $content;
718726

719727
$this->bodies['html'] = $body;
728+
} elseif ($structure->ifdisposition == 1 && strtolower($structure->disposition) == 'attachment') {
729+
if ($this->getFetchAttachmentOption() === true) {
730+
$this->fetchAttachment($structure, $partNumber);
731+
}
720732
}
721733
} elseif ($structure->type == IMAP::MESSAGE_TYPE_MULTIPART) {
722734
foreach ($structure->parts as $index => $subStruct) {

src/Query/WhereQuery.php

100644100755
+5-1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
namespace Webklex\PHPIMAP\Query;
1414

15+
use Illuminate\Support\Str;
1516
use Webklex\PHPIMAP\Exceptions\InvalidWhereQueryCriteriaException;
1617
use Webklex\PHPIMAP\Exceptions\MethodNotFoundException;
1718
use Webklex\PHPIMAP\Exceptions\MessageSearchValidationException;
@@ -72,7 +73,7 @@ class WhereQuery extends Query {
7273
public function __call($name, $arguments) {
7374
$that = $this;
7475

75-
$name = camel_case($name);
76+
$name = Str::camel($name);
7677

7778
if(strtolower(substr($name, 0, 3)) === 'not') {
7879
$that = $that->whereNot();
@@ -97,6 +98,9 @@ public function __call($name, $arguments) {
9798
protected function validate_criteria($criteria) {
9899
$criteria = strtoupper($criteria);
99100

101+
if (substr($criteria, 0, 6) === "CUSTOM") {
102+
return substr($criteria, 6);
103+
}
100104
if(in_array($criteria, $this->available_criteria) === false) {
101105
throw new InvalidWhereQueryCriteriaException();
102106
}

src/Support/Masks/Mask.php

100644100755
+3-2
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
namespace Webklex\PHPIMAP\Support\Masks;
1414

15+
use Illuminate\Support\Str;
1516
use Webklex\PHPIMAP\Exceptions\MethodNotFoundException;
1617

1718
/**
@@ -60,14 +61,14 @@ protected function boot(){}
6061
*/
6162
public function __call($method, $arguments) {
6263
if(strtolower(substr($method, 0, 3)) === 'get') {
63-
$name = snake_case(substr($method, 3));
64+
$name = Str::snake(substr($method, 3));
6465

6566
if(isset($this->attributes[$name])) {
6667
return $this->attributes[$name];
6768
}
6869

6970
}elseif (strtolower(substr($method, 0, 3)) === 'set') {
70-
$name = snake_case(substr($method, 3));
71+
$name = Str::snake(substr($method, 3));
7172

7273
if(isset($this->attributes[$name])) {
7374
$this->attributes[$name] = array_pop($arguments);

0 commit comments

Comments
 (0)