added php download of membershipments
This commit is contained in:
2
vendor/webklex/php-imap/.github/FUNDING.yml
vendored
Normal file
2
vendor/webklex/php-imap/.github/FUNDING.yml
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
ko_fi: webklex
|
||||
custom: ['https://www.buymeacoffee.com/webklex']
|
||||
32
vendor/webklex/php-imap/.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
32
vendor/webklex/php-imap/.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Create a report to help us improve
|
||||
|
||||
---
|
||||
|
||||
**Describe the bug**
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
**Used config**
|
||||
Please provide the used config, if you are not using the package default config.
|
||||
|
||||
**Code to Reproduce**
|
||||
The troubling code section which produces the reported bug.
|
||||
```php
|
||||
echo "Bug";
|
||||
```
|
||||
|
||||
**Expected behavior**
|
||||
A clear and concise description of what you expected to happen.
|
||||
|
||||
**Screenshots**
|
||||
If applicable, add screenshots to help explain your problem.
|
||||
|
||||
**Desktop / Server (please complete the following information):**
|
||||
- OS: [e.g. Debian 10]
|
||||
- PHP: [e.g. 5.5.9]
|
||||
- Version [e.g. v2.3.1]
|
||||
- Provider [e.g. Gmail, Outlook, Dovecot]
|
||||
|
||||
**Additional context**
|
||||
Add any other context about the problem here.
|
||||
17
vendor/webklex/php-imap/.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
17
vendor/webklex/php-imap/.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for this project
|
||||
|
||||
---
|
||||
|
||||
**Is your feature request related to a problem? Please describe.**
|
||||
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||
|
||||
**Describe the solution you'd like**
|
||||
A clear and concise description of what you want to happen.
|
||||
|
||||
**Describe alternatives you've considered**
|
||||
A clear and concise description of any alternative solutions or features you've considered.
|
||||
|
||||
**Additional context**
|
||||
Add any other context or screenshots about the feature request here.
|
||||
12
vendor/webklex/php-imap/.github/ISSUE_TEMPLATE/general-help-request.md
vendored
Normal file
12
vendor/webklex/php-imap/.github/ISSUE_TEMPLATE/general-help-request.md
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
---
|
||||
name: General help request
|
||||
about: Feel free to ask about any project related stuff
|
||||
|
||||
---
|
||||
|
||||
Please be aware that these issues will be closed if inactive for more then 14 days.
|
||||
|
||||
Also make sure to use https://github.com/Webklex/php-imap/issues/new?template=bug_report.md if you want to report a bug
|
||||
or https://github.com/Webklex/php-imap/issues/new?template=feature_request.md if you want to suggest a feature.
|
||||
|
||||
Still here? Well clean this out and go ahead :)
|
||||
4
vendor/webklex/php-imap/.gitignore
vendored
Normal file
4
vendor/webklex/php-imap/.gitignore
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
vendor
|
||||
composer.lock
|
||||
.idea
|
||||
/build/
|
||||
34
vendor/webklex/php-imap/.travis.yml
vendored
Normal file
34
vendor/webklex/php-imap/.travis.yml
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
language: php
|
||||
|
||||
os: linux
|
||||
dist: xenial
|
||||
|
||||
php:
|
||||
- 5.6
|
||||
- 7.0
|
||||
- 7.1
|
||||
- 7.2
|
||||
- 7.3
|
||||
- 7.4
|
||||
- hhvm
|
||||
|
||||
jobs:
|
||||
fast_finish: true
|
||||
allow_failures:
|
||||
- php: 7.3
|
||||
- php: 7.4
|
||||
- php: hhvm
|
||||
|
||||
before_install:
|
||||
- COMPOSER_MEMORY_LIMIT=-1 composer install --prefer-source --no-interaction --dev
|
||||
|
||||
install:
|
||||
- COMPOSER_MEMORY_LIMIT=-1 composer install --no-interaction
|
||||
|
||||
script:
|
||||
- ./vendor/bin/phpunit
|
||||
|
||||
notifications:
|
||||
email:
|
||||
on_success: always
|
||||
on_failure: always
|
||||
739
vendor/webklex/php-imap/CHANGELOG.md
vendored
Executable file
739
vendor/webklex/php-imap/CHANGELOG.md
vendored
Executable file
@@ -0,0 +1,739 @@
|
||||
# Changelog
|
||||
|
||||
All notable changes to `webklex/php-imap` will be documented in this file.
|
||||
|
||||
Updates should follow the [Keep a CHANGELOG](http://keepachangelog.com/) principles.
|
||||
|
||||
## [UNRELEASED]
|
||||
### Fixed
|
||||
- NaN
|
||||
|
||||
### Added
|
||||
- NaN
|
||||
|
||||
### Breaking changes
|
||||
- NaN
|
||||
|
||||
|
||||
## [4.1.2] - 2022-12-14
|
||||
### Fixed
|
||||
- Attachment ID can return an empty value #318
|
||||
- Additional message date format added #345 (thanks @amorebietakoUdala)
|
||||
|
||||
|
||||
## [4.1.1] - 2022-11-16
|
||||
### Fixed
|
||||
- Fix for extension recognition #325 (thanks @pwoszczyk)
|
||||
- Missing null check added #327 (thanks @spanjeta)
|
||||
- Leading white-space in response causes an infinite loop #321 (thanks @thin-k-design)
|
||||
- Fix error when creating folders with special chars #319 (thanks @thin-k-design)
|
||||
- `Client::getFoldersWithStatus()` recursive loading fixed #312 (thanks @szymekjanaczek)
|
||||
- Fix Folder name encoding error in `Folder::appendMessage()` #306 #307 (thanks @rskrzypczak)
|
||||
|
||||
|
||||
## [4.1.0] - 2022-10-18
|
||||
### Fixed
|
||||
- Fix assumedNextTaggedLine bug #288 (thanks @Blear)
|
||||
- Fix empty response error for blank lines #274 (thanks @bierpub)
|
||||
- Fix empty body #233 (thanks @latypoff)
|
||||
- Fix imap_reopen folder argument #234 (thanks @latypoff)
|
||||
|
||||
### Added
|
||||
- Added possibility of loading a Folder status #298 (thanks @szymekjanaczek)
|
||||
|
||||
|
||||
## [4.0.2] - 2022-08-26
|
||||
### Fixed
|
||||
- RFC 822 3.1.1. long header fields regular expression fixed #268 #269 (thanks @hbraehne)
|
||||
|
||||
|
||||
## [4.0.1] - 2022-08-25
|
||||
### Fixed
|
||||
- Type casting added to several ImapProtocol return values #261
|
||||
- Remove IMAP::OP_READONLY flag from imap_reopen if POP3 or NNTP protocol is selected #135 (thanks @xianzhe18)
|
||||
- Several statements optimized and redundant checks removed
|
||||
- Check if the Protocol supports the fetch method if extensions are present
|
||||
- Detect `NONEXISTENT` errors while selecting or examining a folder #266
|
||||
- Missing type cast added to `PaginatedCollection::paginate` #267 (thanks @rogerb87)
|
||||
- Fix multiline header unfolding #250 (thanks @sulgie-eitea)
|
||||
- Fix problem with illegal offset error #226 (thanks @szymekjanaczek)
|
||||
- Typos fixed
|
||||
|
||||
### Affected Classes
|
||||
- [Query::class](src/Query/Query.php)
|
||||
- [ImapProtocol::class](src/Connection/Protocols/ImapProtocol.php)
|
||||
- [LegacyProtocol::class](src/Connection/Protocols/LegacyProtocol.php)
|
||||
- [PaginatedCollection::class](src/Support/PaginatedCollection.php)
|
||||
|
||||
|
||||
## [4.0.0] - 2022-08-19
|
||||
### Fixed
|
||||
- PHP dependency updated to support php v8.0 #212 #214 (thanks @freescout-helpdesk)
|
||||
- Method return and argument types added
|
||||
- Imap `DONE` method refactored
|
||||
- UID cache loop fixed
|
||||
- `HasEvent::getEvent` return value set to mixed to allow multiple event types
|
||||
- Protocol line reader changed to `fread` (stream_context timeout issue fixed)
|
||||
- Issue setting the client timeout fixed
|
||||
- IMAP Connection debugging improved
|
||||
- `Folder::idle()` method reworked and several issues fixed #170 #229 #237 #249 #258
|
||||
- Datetime conversion rules extended #189 #173
|
||||
|
||||
### Affected Classes
|
||||
- [Client::class](src/Client.php)
|
||||
- [Folder::class](src/Folder.php)
|
||||
- [ImapProtocol::class](src/Connection/Protocols/ImapProtocol.php)
|
||||
- [HasEvents::class](src/Traits/HasEvents.php)
|
||||
|
||||
### Breaking changes
|
||||
- No longer supports php >=5.5.9 but instead requires at least php v7.0.0.
|
||||
- `HasEvent::getEvent` returns a mixed result. Either an `Event` or a class string representing the event class.
|
||||
- The error message, if the connection fails to read the next line, is now `empty response` instead of `failed to read - connection closed?`.
|
||||
- The `$auto_reconnect` used with `Folder::indle()` is deprecated and doesn't serve any purpose anymore.
|
||||
|
||||
|
||||
## [3.2.0] - 2022-03-07
|
||||
### Fixed
|
||||
- Fix attribute serialization #179 (thanks @netpok)
|
||||
- Use real tls instead of starttls #180 (thanks @netpok)
|
||||
- Allow to fully overwrite default config arrays #194 (thanks @laurent-rizer)
|
||||
- Query::chunked does not loop over the last chunk #196 (thanks @laurent-rizer)
|
||||
- Fix isAttachment that did not properly take in consideration dispositions options #195 (thanks @laurent-rizer)
|
||||
- Extend date parsing error message #173
|
||||
- Fixed 'Where' method replaces the content with uppercase #148
|
||||
- Don't surround numeric search values with quotes
|
||||
- Context added to `InvalidWhereQueryCriteriaException`
|
||||
- Redundant `stream_set_timeout()` removed
|
||||
|
||||
### Added
|
||||
- UID Cache added #204 (thanks @HelloSebastian)
|
||||
- Query::class extended with `getByUidLower`, `getByUidLowerOrEqual` , `getByUidGreaterOrEqual` , `getByUidGreater` to fetch certain ranges of uids #201 (thanks @HelloSebastian)
|
||||
- Check if IDLE is supported if `Folder::idle()` is called #199 (thanks @HelloSebastian)
|
||||
- Fallback date support added. The config option `options.fallback_date` is used as fallback date is it is set. Otherwise, an exception will be thrown #198
|
||||
- UID filter support added
|
||||
- Make boundary regex configurable #169 #150 #126 #121 #111 #152 #108 (thanks @EthraZa)
|
||||
- IMAP ID support added #174
|
||||
- Enable debug mode via config
|
||||
- Custom UID alternative support added
|
||||
- Fetch additional extensions using `Folder::query(["FEATURE_NAME"])`
|
||||
- Optionally move a message during "deletion" instead of just "flagging" it #106 (thanks @EthraZa)
|
||||
- `WhereQuery::where()` accepts now a wide range of criteria / values. #104
|
||||
|
||||
### Affected Classes
|
||||
- [Part::class](src/Part.php)
|
||||
- [Query::class](src/Query/Query.php)
|
||||
- [Client::class](src/Client.php)
|
||||
- [Header::class](src/Header.php)
|
||||
- [Protocol::class](src/Connection/Protocols/Protocol.php)
|
||||
- [ClientManager::class](src/ClientManager.php)
|
||||
|
||||
### Breaking changes
|
||||
- If you are using the legacy protocol to search, the results no longer return false if the search criteria could not be interpreted but instead return an empty array. This will ensure it is compatible to the rest of this library and no longer result in a potential type confusion.
|
||||
- `Folder::idle` will throw an `Webklex\PHPIMAP\Exceptions\NotSupportedCapabilityException` exception if IMAP isn't supported by the mail server
|
||||
- All protocol methods which had a `boolean` `$uid` option no longer support a boolean value. Use `IMAP::ST_UID` or `IMAP::NIL` instead. If you want to use an alternative to `UID` just use the string instead.
|
||||
- Default config option `options.sequence` changed from `IMAP::ST_MSGN` to `IMAP::ST_UID`.
|
||||
- `Folder::query()` no longer accepts a charset string. It has been replaced by an extension array, which provides the ability to automatically fetch additional features.
|
||||
|
||||
|
||||
## [3.1.0-alpha] - 2022-02-03
|
||||
### Fixed
|
||||
- Fix attribute serialization #179 (thanks @netpok)
|
||||
- Use real tls instead of starttls #180 (thanks @netpok)
|
||||
- Allow to fully overwrite default config arrays #194 (thanks @laurent-rizer)
|
||||
- Query::chunked does not loop over the last chunk #196 (thanks @laurent-rizer)
|
||||
- Fix isAttachment that did not properly take in consideration dispositions options #195 (thanks @laurent-rizer)
|
||||
|
||||
### Affected Classes
|
||||
- [Header::class](src/Header.php)
|
||||
- [Protocol::class](src/Connection/Protocols/Protocol.php)
|
||||
- [Query::class](src/Query/Query.php)
|
||||
- [Part::class](src/Part.php)
|
||||
- [ClientManager::class](src/ClientManager.php)
|
||||
|
||||
## [3.0.0-alpha] - 2021-11-04
|
||||
### Fixed
|
||||
- Extend date parsing error message #173
|
||||
- Fixed 'Where' method replaces the content with uppercase #148
|
||||
- Don't surround numeric search values with quotes
|
||||
- Context added to `InvalidWhereQueryCriteriaException`
|
||||
- Redundant `stream_set_timeout()` removed
|
||||
|
||||
### Added
|
||||
- Make boundary regex configurable #169 #150 #126 #121 #111 #152 #108 (thanks @EthraZa)
|
||||
- IMAP ID support added #174
|
||||
- Enable debug mode via config
|
||||
- Custom UID alternative support added
|
||||
- Fetch additional extensions using `Folder::query(["FEATURE_NAME"])`
|
||||
- Optionally move a message during "deletion" instead of just "flagging" it #106 (thanks @EthraZa)
|
||||
- `WhereQuery::where()` accepts now a wide range of criteria / values. #104
|
||||
|
||||
### Affected Classes
|
||||
- [Header::class](src/Header.php)
|
||||
- [Protocol::class](src/Connection/Protocols/Protocol.php)
|
||||
- [Query::class](src/Query/Query.php)
|
||||
- [WhereQuery::class](src/Query/WhereQuery.php)
|
||||
- [Message::class](src/Message.php)
|
||||
|
||||
### Breaking changes
|
||||
- All protocol methods which had a `boolean` `$uid` option no longer support a boolean. Use `IMAP::ST_UID` or `IMAP::NIL` instead. If you want to use an alternative to `UID` just use the string instead.
|
||||
- Default config option `options.sequence` changed from `IMAP::ST_MSGN` to `IMAP::ST_UID`.
|
||||
- `Folder::query()` no longer accepts a charset string. It has been replaced by an extension array, which provides the ability to automatically fetch additional features.
|
||||
|
||||
## [2.7.2] - 2021-09-27
|
||||
### Fixed
|
||||
- Fixed problem with skipping last line of the response. #166 (thanks @szymekjanaczek)
|
||||
|
||||
## [2.7.1] - 2021-09-08
|
||||
### Added
|
||||
- Added `UID` as available search criteria #161 (thanks @szymekjanaczek)
|
||||
|
||||
## [2.7.0] - 2021-09-04
|
||||
### Fixed
|
||||
- Fixes handling of long header lines which are seperated by `\r\n\t` (thanks @Oliver-Holz)
|
||||
- Fixes to line parsing with multiple addresses (thanks @Oliver-Holz)
|
||||
|
||||
### Added
|
||||
- Expose message folder path #154 (thanks @Magiczne)
|
||||
- Adds mailparse_rfc822_parse_addresses integration (thanks @Oliver-Holz)
|
||||
- Added moveManyMessages method (thanks @Magiczne)
|
||||
- Added copyManyMessages method (thanks @Magiczne)
|
||||
|
||||
### Affected Classes
|
||||
- [Header::class](src/Header.php)
|
||||
- [Message::class](src/Message.php)
|
||||
|
||||
## [2.6.0] - 2021-08-20
|
||||
### Fixed
|
||||
- POP3 fixes #151 (thanks @Korko)
|
||||
|
||||
### Added
|
||||
- Added imap 4 handling. #146 (thanks @szymekjanaczek)
|
||||
- Added laravel's conditionable methods. #147 (thanks @szymekjanaczek)
|
||||
|
||||
### Affected Classes
|
||||
- [Query::class](src/Query/Query.php)
|
||||
- [Client::class](src/Client.php)
|
||||
|
||||
## [2.5.1] - 2021-06-19
|
||||
### Fixed
|
||||
- Fix setting default mask from config #133 (thanks @shacky)
|
||||
- Chunked fetch fails in case of less available mails than page size #114
|
||||
- Protocol::createStream() exception information fixed #137
|
||||
- Legacy methods (headers, content, flags) fixed #125
|
||||
- Legacy connection cycle fixed #124 (thanks @zssarkany)
|
||||
|
||||
### Added
|
||||
- Disable rfc822 header parsing via config option #115
|
||||
|
||||
## [2.5.0] - 2021-02-01
|
||||
### Fixed
|
||||
- Attachment saving filename fixed
|
||||
- Unnecessary parameter removed from `Client::getTimeout()`
|
||||
- Missing encryption variable added - could have caused problems with unencrypted communications
|
||||
- Prefer attachment filename attribute over name attribute #82
|
||||
- Missing connection settings added to `Folder:idle()` auto mode #89
|
||||
- Message move / copy expect a folder path #79
|
||||
- `Client::getFolder()` updated to circumvent special edge cases #79
|
||||
- Missing connection status checks added to various methods
|
||||
- Unused default attribute `message_no` removed from `Message::class`
|
||||
|
||||
### Added
|
||||
- Dynamic Attribute access support added (e.g `$message->from[0]`)
|
||||
- Message not found exception added #93
|
||||
- Chunked fetching support added `Query::chunked()`. Just in case you can't fetch all messages at once
|
||||
- "Soft fail" support added
|
||||
- Count method added to `Attribute:class`
|
||||
- Convert an Attribute instance into a Carbon date object #95
|
||||
|
||||
### Affected Classes
|
||||
- [Attachment::class](src/Attachment.php)
|
||||
- [Attribute::class](src/Attribute.php)
|
||||
- [Query::class](src/Query/Query.php)
|
||||
- [Message::class](src/Message.php)
|
||||
- [Client::class](src/Client.php)
|
||||
- [Folder::class](src/Folder.php)
|
||||
|
||||
### Breaking changes
|
||||
- A new exception can occur if a message can't be fetched (`\Webklex\PHPIMAP\Exceptions\MessageNotFoundException::class`)
|
||||
- `Message::move()` and `Message::copy()` no longer accept folder names as folder path
|
||||
- A `Message::class` instance might no longer have a `message_no` attribute
|
||||
|
||||
## [2.4.4] - 2021-01-22
|
||||
### Fixed
|
||||
- Boundary detection simplified #90
|
||||
- Prevent potential body overwriting #90
|
||||
- CSV files are no longer regarded as plain body
|
||||
- Boundary detection overhauled to support "related" and "alternative" multipart messages #90 #91
|
||||
|
||||
### Affected Classes
|
||||
- [Structure::class](src/Structure.php)
|
||||
- [Message::class](src/Message.php)
|
||||
- [Header::class](src/Header.php)
|
||||
- [Part::class](src/Part.php)
|
||||
|
||||
## [2.4.3] - 2021-01-21
|
||||
### Fixed
|
||||
- Attachment detection updated #82 #90
|
||||
- Timeout handling improved
|
||||
- Additional utf-8 checks added to prevent decoding of unencoded values #76
|
||||
|
||||
### Added
|
||||
- Auto reconnect option added to `Folder::idle()` #89
|
||||
|
||||
### Affected Classes
|
||||
- [Folder::class](src/Folder.php)
|
||||
- [Part::class](src/Part.php)
|
||||
- [Client::class](src/Client.php)
|
||||
- [Header::class](src/Header.php)
|
||||
|
||||
## [2.4.2] - 2021-01-09
|
||||
### Fixed
|
||||
- Attachment::save() return error 'A facade root has not been set' #87
|
||||
- Unused dependencies removed
|
||||
- Fix PHP 8 error that changes null back in to an empty string. #88 (thanks @mennovanhout)
|
||||
- Fix regex to be case insensitive #88 (thanks @mennovanhout)
|
||||
|
||||
### Affected Classes
|
||||
- [Attachment::class](src/Attachment.php)
|
||||
- [Address::class](src/Address.php)
|
||||
- [Attribute::class](src/Attribute.php)
|
||||
- [Structure::class](src/Structure.php)
|
||||
|
||||
## [2.4.1] - 2021-01-06
|
||||
### Fixed
|
||||
- Debug line position fixed
|
||||
- Handle incomplete address to string conversion #83
|
||||
- Configured message key gets overwritten by the first fetched message #84
|
||||
|
||||
### Affected Classes
|
||||
- [Address::class](src/Address.php)
|
||||
- [Query::class](src/Query/Query.php)
|
||||
|
||||
## [2.4.0] - 2021-01-03
|
||||
### Fixed
|
||||
- Get partial overview when `IMAP::ST_UID` is set #74
|
||||
- Unnecessary "'" removed from address names
|
||||
- Folder referral typo fixed
|
||||
- Legacy protocol fixed
|
||||
- Treat message collection keys always as strings
|
||||
|
||||
### Added
|
||||
- Configurable supported default flags added
|
||||
- Message attribute class added to unify value handling
|
||||
- Address class added and integrated
|
||||
- Alias `Message::attachments()` for `Message::getAttachments()` added
|
||||
- Alias `Message::addFlag()` for `Message::setFlag()` added
|
||||
- Alias `Message::removeFlag()` for `Message::unsetFlag()` added
|
||||
- Alias `Message::flags()` for `Message::getFlags()` added
|
||||
- New Exception `MessageFlagException::class` added
|
||||
- New method `Message::setSequenceId($id)` added
|
||||
- Optional Header attributizion option added
|
||||
|
||||
### Affected Classes
|
||||
- [Folder::class](src/Folder.php)
|
||||
- [Header::class](src/Header.php)
|
||||
- [Message::class](src/Message.php)
|
||||
- [Address::class](src/Address.php)
|
||||
- [Query::class](src/Query/Query.php)
|
||||
- [Attribute::class](src/Attribute.php)
|
||||
|
||||
### Breaking changes
|
||||
- Stringified message headers are now separated by ", " instead of " ".
|
||||
- All message header values such as subject, message_id, from, to, etc now consists of an `Àttribute::class` instance (should behave the same way as before, but might cause some problem in certain edge cases)
|
||||
- The formal address object "from", "to", etc now consists of an `Address::class` instance (should behave the same way as before, but might cause some problem in certain edge cases)
|
||||
- When fetching or manipulating message flags a `MessageFlagException::class` exception can be thrown if a runtime error occurs
|
||||
- Learn more about the new `Attribute` class here: [www.php-imap.com/api/attribute](https://www.php-imap.com/api/attribute)
|
||||
- Learn more about the new `Address` class here: [www.php-imap.com/api/address](https://www.php-imap.com/api/address)
|
||||
- Folder attribute "referal" is now called "referral"
|
||||
|
||||
## [2.3.1] - 2020-12-30
|
||||
### Fixed
|
||||
- Missing RFC attributes added
|
||||
- Set the message sequence when idling
|
||||
- Missing UID commands added #64
|
||||
|
||||
### Added
|
||||
- Get a message by its message number
|
||||
- Get a message by its uid #72 #66 #63
|
||||
|
||||
### Affected Classes
|
||||
- [Message::class](src/Message.php)
|
||||
- [Folder::class](src/Folder.php)
|
||||
- [Query::class](src/Query/Query.php)
|
||||
|
||||
## [2.3.0] - 2020-12-21
|
||||
### Fixed
|
||||
- Cert validation issue fixed
|
||||
- Allow boundaries ending with a space or semicolon (thanks [@smartilabs](https://github.com/smartilabs))
|
||||
- Ignore IMAP DONE command response #57
|
||||
- Default `options.fetch` set to `IMAP::FT_PEEK`
|
||||
- Address parsing fixed #60
|
||||
- Alternative rfc822 header parsing fixed #60
|
||||
- Parse more than one Received: header #61
|
||||
- Fetch folder overview fixed
|
||||
- `Message::getTextBody()` fallback value fixed
|
||||
|
||||
### Added
|
||||
- Proxy support added
|
||||
- Flexible disposition support added #58
|
||||
- New `options.message_key` option `uid` added
|
||||
- Protocol UID support added
|
||||
- Flexible sequence type support added
|
||||
|
||||
### Affected Classes
|
||||
- [Structure::class](src/Structure.php)
|
||||
- [Query::class](src/Query/Query.php)
|
||||
- [Client::class](src/Client.php)
|
||||
- [Header::class](src/Header.php)
|
||||
- [Folder::class](src/Folder.php)
|
||||
- [Part::class](src/Part.php)
|
||||
|
||||
### Breaking changes
|
||||
- Depending on your configuration, your certificates actually get checked. Which can cause an aborted connection if the certificate can not be validated.
|
||||
- Messages don't get flagged as read unless you are using your own custom config.
|
||||
- All `Header::class` attribute keys are now in a snake_format and no longer minus-separated.
|
||||
- `Message::getTextBody()` no longer returns false if no text body is present. `null` is returned instead.
|
||||
|
||||
## [2.2.5] - 2020-12-11
|
||||
### Fixed
|
||||
- Missing array decoder method added #51 (thanks [@lutchin](https://github.com/lutchin))
|
||||
- Additional checks added to prevent message from getting marked as seen #33
|
||||
- Boundary parsing improved #39 #36 (thanks [@AntonioDiPassio-AppSys](https://github.com/AntonioDiPassio-AppSys))
|
||||
- Idle operation updated #44
|
||||
|
||||
### Added
|
||||
- Force a folder to be opened
|
||||
|
||||
### Affected Classes
|
||||
- [Header::class](src/Header.php)
|
||||
- [Folder::class](src/Folder.php)
|
||||
- [Query::class](src/Query/Query.php)
|
||||
- [Message::class](src/Message.php)
|
||||
- [Structure::class](src/Structure.php)
|
||||
|
||||
## [2.2.4] - 2020-12-08
|
||||
### Fixed
|
||||
- Search performance increased by fetching all headers, bodies and flags at once #42
|
||||
- Legacy protocol support updated
|
||||
- Fix Query pagination. (#52 [@mikemiller891](https://github.com/mikemiller891))
|
||||
|
||||
### Added
|
||||
- Missing message setter methods added
|
||||
- `Folder::overview()` method added to fetch all headers of all messages in the current folder
|
||||
|
||||
### Affected Classes
|
||||
- [Message::class](src/Message.php)
|
||||
- [Folder::class](src/Folder.php)
|
||||
- [Query::class](src/Query/Query.php)
|
||||
- [PaginatedCollection::class](src/Support/PaginatedCollection.php)
|
||||
|
||||
## [2.2.3] - 2020-11-02
|
||||
### Fixed
|
||||
- Text/Html body fetched as attachment if subtype is null #34
|
||||
- Potential header overwriting through header extensions #35
|
||||
- Prevent empty attachments #37
|
||||
|
||||
### Added
|
||||
- Set fetch order during query #41 [@Max13](https://github.com/Max13)
|
||||
|
||||
### Affected Classes
|
||||
- [Message::class](src/Message.php)
|
||||
- [Part::class](src/Part.php)
|
||||
- [Header::class](src/Header.php)
|
||||
- [Query::class](src/Query/Query.php)
|
||||
|
||||
|
||||
## [2.2.2] - 2020-10-20
|
||||
### Fixed
|
||||
- IMAP::FT_PEEK removing "Seen" flag issue fixed #33
|
||||
|
||||
### Affected Classes
|
||||
- [Message::class](src/Message.php)
|
||||
|
||||
## [2.2.1] - 2020-10-19
|
||||
### Fixed
|
||||
- Header decoding problem fixed #31
|
||||
|
||||
### Added
|
||||
- Search for messages by message-Id
|
||||
- Search for messages by In-Reply-To
|
||||
- Message threading added `Message::thread()`
|
||||
- Default folder locations added
|
||||
|
||||
### Affected Classes
|
||||
- [Query::class](src/Query/Query.php)
|
||||
- [Message::class](src/Message.php)
|
||||
- [Header::class](src/Header.php)
|
||||
|
||||
|
||||
## [2.2.0] - 2020-10-16
|
||||
### Fixed
|
||||
- Prevent text bodies from being fetched as attachment #27
|
||||
- Missing variable check added to prevent exception while parsing an address [webklex/laravel-imap #356](https://github.com/Webklex/laravel-imap/issues/356)
|
||||
- Missing variable check added to prevent exception while parsing a part subtype #27
|
||||
- Missing variable check added to prevent exception while parsing a part content-type [webklex/laravel-imap #356](https://github.com/Webklex/laravel-imap/issues/356)
|
||||
- Mixed message header attribute `in_reply_to` "unified" to be always an array #26
|
||||
- Potential message moving / copying problem fixed #29
|
||||
- Move messages by using `Protocol::moveMessage()` instead of `Protocol::copyMessage()` and `Message::delete()` #29
|
||||
|
||||
### Added
|
||||
- `Protocol::moveMessage()` method added #29
|
||||
|
||||
### Affected Classes
|
||||
- [Message::class](src/Message.php)
|
||||
- [Header::class](src/Header.php)
|
||||
- [Part::class](src/Part.php)
|
||||
|
||||
### Breaking changes
|
||||
- Text bodies might no longer get fetched as attachment
|
||||
- `Message::$in_reply_to` type changed from mixed to array
|
||||
|
||||
## [2.1.13] - 2020-10-13
|
||||
### Fixed
|
||||
- Boundary detection problem fixed (#28 [@DasTobbel](https://github.com/DasTobbel))
|
||||
- Content-Type detection problem fixed (#28 [@DasTobbel](https://github.com/DasTobbel))
|
||||
|
||||
### Affected Classes
|
||||
- [Structure::class](src/Structure.php)
|
||||
|
||||
## [2.1.12] - 2020-10-13
|
||||
### Fixed
|
||||
- If content disposition is multiline, implode the array to a simple string (#25 [@DasTobbel](https://github.com/DasTobbel))
|
||||
|
||||
### Affected Classes
|
||||
- [Part::class](src/Part.php)
|
||||
|
||||
## [2.1.11] - 2020-10-13
|
||||
### Fixed
|
||||
- Potential problematic prefixed white-spaces removed from header attributes
|
||||
|
||||
### Added
|
||||
- Expended `Client::getFolder($name, $deleimiter = null)` to accept either a folder name or path ([@DasTobbel](https://github.com/DasTobbel))
|
||||
- Special MS-Exchange header decoding support added
|
||||
|
||||
### Affected Classes
|
||||
- [Client::class](src/Client.php)
|
||||
- [Header::class](src/Header.php)
|
||||
|
||||
## [2.1.10] - 2020-10-09
|
||||
### Added
|
||||
- `ClientManager::make()` method added to support undefined accounts
|
||||
|
||||
### Affected Classes
|
||||
- [ClientManager::class](src/ClientManager.php)
|
||||
|
||||
## [2.1.9] - 2020-10-08
|
||||
### Fixed
|
||||
- Fix inline attachments and embedded images (#22 [@dwalczyk](https://github.com/dwalczyk))
|
||||
|
||||
### Added
|
||||
- Alternative attachment names support added (#20 [@oneFoldSoftware](https://github.com/oneFoldSoftware))
|
||||
- Fetch message content without leaving a "Seen" flag behind
|
||||
|
||||
### Affected Classes
|
||||
- [Attachment::class](src/Attachment.php)
|
||||
- [Message::class](src/Message.php)
|
||||
- [Part::class](src/Part.php)
|
||||
- [Query::class](src/Query/Query.php)
|
||||
|
||||
## [2.1.8] - 2020-10-08
|
||||
### Fixed
|
||||
- Possible error during address decoding fixed (#16 [@Slauta](https://github.com/Slauta))
|
||||
- Flag event dispatching fixed #15
|
||||
|
||||
### Added
|
||||
- Support multiple boundaries (#17, #19 [@dwalczyk](https://github.com/dwalczyk))
|
||||
|
||||
### Affected Classes
|
||||
- [Structure::class](src/Structure.php)
|
||||
|
||||
## [2.1.7] - 2020-10-03
|
||||
### Fixed
|
||||
- Fixed `Query::paginate()` (#13 #14 by [@Max13](https://github.com/Max13))
|
||||
|
||||
### Affected Classes
|
||||
- [Query::class](src/Query/Query.php)
|
||||
|
||||
## [2.1.6] - 2020-10-02
|
||||
### Fixed
|
||||
- `Message::getAttributes()` hasn't returned all parameters
|
||||
|
||||
### Affected Classes
|
||||
- [Message::class](src/Message.php)
|
||||
|
||||
### Added
|
||||
- Part number added to attachment
|
||||
- `Client::getFolderByPath()` added (#12 by [@Max13](https://github.com/Max13))
|
||||
- `Client::getFolderByName()` added (#12 by [@Max13](https://github.com/Max13))
|
||||
- Throws exceptions if the authentication fails (#11 by [@Max13](https://github.com/Max13))
|
||||
|
||||
### Affected Classes
|
||||
- [Client::class](src/Client.php)
|
||||
|
||||
## [2.1.5] - 2020-09-30
|
||||
### Fixed
|
||||
- Wrong message content property reference fixed (#10)
|
||||
|
||||
## [2.1.4] - 2020-09-30
|
||||
### Fixed
|
||||
- Fix header extension values
|
||||
- Part header detection method changed (#10)
|
||||
|
||||
### Affected Classes
|
||||
- [Header::class](src/Header.php)
|
||||
- [Part::class](src/Part.php)
|
||||
|
||||
## [2.1.3] - 2020-09-29
|
||||
### Fixed
|
||||
- Possible decoding problem fixed
|
||||
- `Str::class` dependency removed from `Header::class`
|
||||
|
||||
### Affected Classes
|
||||
- [Header::class](src/Header.php)
|
||||
|
||||
## [2.1.2] - 2020-09-28
|
||||
### Fixed
|
||||
- Dependency problem in `Attachement::getExtension()` fixed (#9)
|
||||
|
||||
### Affected Classes
|
||||
- [Attachment::class](src/Attachment.php)
|
||||
|
||||
## [2.1.1] - 2020-09-23
|
||||
### Fixed
|
||||
- Missing default config parameter added
|
||||
|
||||
### Added
|
||||
- Default account config fallback added
|
||||
|
||||
### Affected Classes
|
||||
- [Client::class](src/Client.php)
|
||||
|
||||
## [2.1.0] - 2020-09-22
|
||||
### Fixed
|
||||
- Quota handling fixed
|
||||
|
||||
### Added
|
||||
- Event system and callbacks added
|
||||
|
||||
### Affected Classes
|
||||
- [Client::class](src/Client.php)
|
||||
- [Folder::class](src/Folder.php)
|
||||
- [Message::class](src/Message.php)
|
||||
|
||||
## [2.0.1] - 2020-09-20
|
||||
### Fixed
|
||||
- Carbon dependency fixed
|
||||
|
||||
## [2.0.0] - 2020-09-20
|
||||
### Fixed
|
||||
- Missing pagination item records fixed
|
||||
|
||||
### Added
|
||||
- php-imap module replaced by direct socket communication
|
||||
- Legacy support added
|
||||
- IDLE support added
|
||||
- oAuth support added
|
||||
- Charset detection method updated
|
||||
- Decoding fallback charsets added
|
||||
|
||||
### Affected Classes
|
||||
- All
|
||||
|
||||
## [1.4.5] - 2019-01-23
|
||||
### Fixed
|
||||
- .csv attachement is not processed
|
||||
- mail part structure property comparison changed to lowercase
|
||||
- Replace helper functions for Laravel 6.0 #4 (@koenhoeijmakers)
|
||||
- Date handling in Folder::appendMessage() fixed
|
||||
- Carbon Exception Parse Data
|
||||
- Convert sender name from non-utf8 to uf8 (@hwilok)
|
||||
- Convert encoding of personal data struct
|
||||
|
||||
### Added
|
||||
- Path prefix option added to Client::getFolder() method
|
||||
- Attachment size handling added
|
||||
- Find messages by custom search criteria
|
||||
|
||||
### Affected Classes
|
||||
- [Query::class](src/Query/WhereQuery.php)
|
||||
- [Mask::class](src/Support/Masks/Mask.php)
|
||||
- [Attachment::class](src/Attachment.php)
|
||||
- [Client::class](src/Client.php)
|
||||
- [Folder::class](src/Folder.php)
|
||||
- [Message::class](src/Message.php)
|
||||
|
||||
## [1.4.2.1] - 2019-07-03
|
||||
### Fixed
|
||||
- Error in Attachment::__construct #3
|
||||
- Examples added
|
||||
|
||||
## [1.4.2] - 2019-07-02
|
||||
### Fixed
|
||||
- Pagination count total bug #213
|
||||
- Changed internal message move and copy methods #210
|
||||
- Query::since() query returning empty response #215
|
||||
- Carbon Exception Parse Data #45
|
||||
- Reading a blank body (text / html) but only from this sender #203
|
||||
- Problem with Message::moveToFolder() and multiple moves #31
|
||||
- Problem with encoding conversion #203
|
||||
- Message null value attribute problem fixed
|
||||
- Client connection path handling changed to be handled inside the calling method #31
|
||||
- iconv(): error suppressor for //IGNORE added #184
|
||||
- Typo Folder attribute fullName changed to full_name
|
||||
- Query scope error fixed #153
|
||||
- Replace embedded image with URL #151
|
||||
- Fix sender name in non-latin emails sent from Gmail (#155)
|
||||
- Fix broken non-latin characters in body in ASCII (us-ascii) charset #156
|
||||
- Message::getMessageId() returns wrong value #197
|
||||
- Message date validation extended #45 #192
|
||||
- Removed "-i" from "iso-8859-8-i" in Message::parseBody #146
|
||||
|
||||
### Added
|
||||
- Message::getFolder() method
|
||||
- Create a fast count method for queries #216
|
||||
- STARTTLS encryption alias added
|
||||
- Mailbox fetching exception added #201
|
||||
- Message::moveToFolder() fetches new Message::class afterwards #31
|
||||
- Message structure accessor added #182
|
||||
- Shadow Imap const class added #188
|
||||
- Connectable "NOT" queries added
|
||||
- Additional where methods added
|
||||
- Message attribute handling changed
|
||||
- Attachment attribute handling changed
|
||||
- Message flag handling updated
|
||||
- Message::getHTMLBody($callback) extended
|
||||
- Masks added (take look at the examples for more information on masks)
|
||||
- More examples added
|
||||
- Query::paginate() method added
|
||||
- Imap client timeout can be modified and read #186
|
||||
- Decoder config options added #175
|
||||
- Message search criteria "NOT" added #181
|
||||
- Invalid message date exception added
|
||||
- Blade examples
|
||||
|
||||
### Breaking changes
|
||||
- Message::moveToFolder() returns either a Message::class instance or null and not a boolean
|
||||
- Folder::fullName is now Folder::full_name
|
||||
- Attachment::image_src might no longer work as expected - use Attachment::getImageSrc() instead
|
||||
|
||||
### Affected Classes
|
||||
- [Folder::class](src/Folder.php)
|
||||
- [Client::class](src/Client.php)
|
||||
- [Message::class](src/Message.php)
|
||||
- [Attachment::class](src/Attachment.php)
|
||||
- [Query::class](src/Query/Query.php)
|
||||
- [WhereQuery::class](src/Query/WhereQuery.php)
|
||||
|
||||
## 0.0.3 - 2018-12-02
|
||||
### Fixed
|
||||
- Folder delimiter check added #137
|
||||
- Config setting not getting loaded
|
||||
- Date parsing updated
|
||||
|
||||
### Affected Classes
|
||||
- [Folder::class](src/IMAP/Client.php)
|
||||
- [Folder::class](src/IMAP/Message.php)
|
||||
|
||||
## 0.0.1 - 2018-08-13
|
||||
### Added
|
||||
- new php-imap package (fork from [webklex/laravel-imap](https://github.com/Webklex/laravel-imap))
|
||||
46
vendor/webklex/php-imap/CODE_OF_CONDUCT.md
vendored
Normal file
46
vendor/webklex/php-imap/CODE_OF_CONDUCT.md
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
# Contributor Covenant Code of Conduct
|
||||
|
||||
## Our Pledge
|
||||
|
||||
In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
|
||||
|
||||
## Our Standards
|
||||
|
||||
Examples of behavior that contributes to creating a positive environment include:
|
||||
|
||||
* Using welcoming and inclusive language
|
||||
* Being respectful of differing viewpoints and experiences
|
||||
* Gracefully accepting constructive criticism
|
||||
* Focusing on what is best for the community
|
||||
* Showing empathy towards other community members
|
||||
|
||||
Examples of unacceptable behavior by participants include:
|
||||
|
||||
* The use of sexualized language or imagery and unwelcome sexual attention or advances
|
||||
* Trolling, insulting/derogatory comments, and personal or political attacks
|
||||
* Public or private harassment
|
||||
* Publishing others' private information, such as a physical or electronic address, without explicit permission
|
||||
* Other conduct which could reasonably be considered inappropriate in a professional setting
|
||||
|
||||
## Our Responsibilities
|
||||
|
||||
Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
|
||||
|
||||
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
|
||||
|
||||
## Scope
|
||||
|
||||
This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
|
||||
|
||||
## Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at github@webklex.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
|
||||
|
||||
Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
|
||||
|
||||
## Attribution
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
|
||||
|
||||
[homepage]: http://contributor-covenant.org
|
||||
[version]: http://contributor-covenant.org/version/1/4/
|
||||
21
vendor/webklex/php-imap/LICENSE
vendored
Normal file
21
vendor/webklex/php-imap/LICENSE
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2016 Webklex
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
21
vendor/webklex/php-imap/LICENSE.md
vendored
Normal file
21
vendor/webklex/php-imap/LICENSE.md
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
# The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2016 Malte Goldenbaum <info@webklex.com>
|
||||
|
||||
> Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
> of this software and associated documentation files (the "Software"), to deal
|
||||
> in the Software without restriction, including without limitation the rights
|
||||
> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
> copies of the Software, and to permit persons to whom the Software is
|
||||
> furnished to do so, subject to the following conditions:
|
||||
>
|
||||
> The above copyright notice and this permission notice shall be included in
|
||||
> all copies or substantial portions of the Software.
|
||||
>
|
||||
> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
> THE SOFTWARE.
|
||||
167
vendor/webklex/php-imap/README.md
vendored
Executable file
167
vendor/webklex/php-imap/README.md
vendored
Executable file
@@ -0,0 +1,167 @@
|
||||
|
||||
# IMAP Library for PHP
|
||||
|
||||
[![Latest release on Packagist][ico-release]][link-packagist]
|
||||
[![Latest prerelease on Packagist][ico-prerelease]][link-packagist]
|
||||
[![Software License][ico-license]][link-license]
|
||||
[![Build Status][ico-travis]][link-scrutinizer]
|
||||
[![Total Downloads][ico-downloads]][link-downloads]
|
||||
[![Hits][ico-hits]][link-hits]
|
||||
[![Discord][ico-discord]][link-discord]
|
||||
[![Snyk][ico-snyk]][link-snyk]
|
||||
|
||||
|
||||
## Description
|
||||
PHP-IMAP is a wrapper for common IMAP communication without the need to have the php-imap module installed / enabled.
|
||||
The protocol is completely integrated and therefore supports IMAP IDLE operation and the "new" oAuth authentication
|
||||
process as well.
|
||||
You can enable the `php-imap` module in order to handle edge cases, improve message decoding quality and is required if
|
||||
you want to use legacy protocols such as pop3.
|
||||
|
||||
Official documentation: [php-imap.com](https://www.php-imap.com/)
|
||||
|
||||
Laravel wrapper: [webklex/laravel-imap](https://github.com/Webklex/laravel-imap)
|
||||
|
||||
Discord: [discord.gg/rd4cN9h6][link-discord]
|
||||
|
||||
## Table of Contents
|
||||
- [Documentations](#documentations)
|
||||
- [Basic usage example](#basic-usage-example)
|
||||
- [Known issues](#known-issues)
|
||||
- [Support](#support)
|
||||
- [Features & pull requests](#features--pull-requests)
|
||||
- [Security](#security)
|
||||
- [Credits](#credits)
|
||||
- [License](#license)
|
||||
|
||||
|
||||
## Documentations
|
||||
- Legacy (< v2.0.0): [legacy documentation](https://github.com/Webklex/php-imap/tree/1.4.5)
|
||||
- Core documentation: [php-imap.com](https://www.php-imap.com/)
|
||||
|
||||
|
||||
## Basic usage example
|
||||
This is a basic example, which will echo out all Mails within all imap folders
|
||||
and will move every message into INBOX.read. Please be aware that this should not be
|
||||
tested in real life and is only meant to gives an impression on how things work.
|
||||
|
||||
```php
|
||||
use Webklex\PHPIMAP\ClientManager;
|
||||
|
||||
$cm = new ClientManager('path/to/config/imap.php');
|
||||
|
||||
/** @var \Webklex\PHPIMAP\Client $client */
|
||||
$client = $cm->account('account_identifier');
|
||||
|
||||
//Connect to the IMAP Server
|
||||
$client->connect();
|
||||
|
||||
//Get all Mailboxes
|
||||
/** @var \Webklex\PHPIMAP\Support\FolderCollection $folders */
|
||||
$folders = $client->getFolders();
|
||||
|
||||
//Loop through every Mailbox
|
||||
/** @var \Webklex\PHPIMAP\Folder $folder */
|
||||
foreach($folders as $folder){
|
||||
|
||||
//Get all Messages of the current Mailbox $folder
|
||||
/** @var \Webklex\PHPIMAP\Support\MessageCollection $messages */
|
||||
$messages = $folder->messages()->all()->get();
|
||||
|
||||
/** @var \Webklex\PHPIMAP\Message $message */
|
||||
foreach($messages as $message){
|
||||
echo $message->getSubject().'<br />';
|
||||
echo 'Attachments: '.$message->getAttachments()->count().'<br />';
|
||||
echo $message->getHTMLBody();
|
||||
|
||||
//Move the current Message to 'INBOX.read'
|
||||
if($message->move('INBOX.read') == true){
|
||||
echo 'Message has been moved';
|
||||
}else{
|
||||
echo 'Message could not be moved';
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### Known issues
|
||||
| Error | Solution |
|
||||
| ------------------------------------------------------------------------- | ---------------------------------------------------------- |
|
||||
| Kerberos error: No credentials cache file found (try running kinit) (...) | Uncomment "DISABLE_AUTHENTICATOR" inside your config and use the `legacy-imap` protocol |
|
||||
|
||||
|
||||
## Support
|
||||
If you encounter any problems or if you find a bug, please don't hesitate to create a new [issue](https://github.com/Webklex/php-imap/issues).
|
||||
However please be aware that it might take some time to get an answer.
|
||||
Off topic, rude or abusive issues will be deleted without any notice.
|
||||
|
||||
If you need **commercial** support, feel free to send me a mail at github@webklex.com.
|
||||
|
||||
|
||||
##### A little notice
|
||||
If you write source code in your issue, please consider to format it correctly. This makes it so much nicer to read
|
||||
and people are more likely to comment and help :)
|
||||
|
||||
```php
|
||||
|
||||
echo 'your php code...';
|
||||
|
||||
```
|
||||
|
||||
will turn into:
|
||||
```php
|
||||
echo 'your php code...';
|
||||
```
|
||||
|
||||
|
||||
## Features & pull requests
|
||||
Everyone can contribute to this project. Every pull request will be considered but it can also happen to be declined.
|
||||
To prevent unnecessary work, please consider to create a [feature issue](https://github.com/Webklex/php-imap/issues/new?template=feature_request.md)
|
||||
first, if you're planning to do bigger changes. Of course, you can also create a new [feature issue](https://github.com/Webklex/php-imap/issues/new?template=feature_request.md)
|
||||
if you're just wishing a feature ;)
|
||||
|
||||
|
||||
## Change log
|
||||
Please see [CHANGELOG][link-changelog] for more information what has changed recently.
|
||||
|
||||
|
||||
## Security
|
||||
If you discover any security related issues, please email github@webklex.com instead of using the issue tracker.
|
||||
|
||||
|
||||
## Credits
|
||||
- [Webklex][link-author]
|
||||
- [All Contributors][link-contributors]
|
||||
|
||||
|
||||
## License
|
||||
The MIT License (MIT). Please see [License File][link-license] for more information.
|
||||
|
||||
|
||||
[ico-release]: https://img.shields.io/packagist/v/Webklex/php-imap.svg?style=flat-square&label=version
|
||||
[ico-prerelease]: https://img.shields.io/github/v/release/webklex/php-imap?include_prereleases&style=flat-square&label=pre-release
|
||||
[ico-license]: https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat-square
|
||||
[ico-travis]: https://img.shields.io/travis/Webklex/php-imap/master.svg?style=flat-square
|
||||
[ico-scrutinizer]: https://img.shields.io/scrutinizer/coverage/g/Webklex/php-imap.svg?style=flat-square
|
||||
[ico-code-quality]: https://img.shields.io/scrutinizer/g/Webklex/php-imap.svg?style=flat-square
|
||||
[ico-downloads]: https://img.shields.io/packagist/dt/Webklex/php-imap.svg?style=flat-square
|
||||
[ico-build]: https://img.shields.io/scrutinizer/build/g/Webklex/php-imap/master?style=flat-square
|
||||
[ico-quality]: https://img.shields.io/scrutinizer/quality/g/Webklex/php-imap/master?style=flat-square
|
||||
[ico-hits]: https://hits.webklex.com/svg/webklex/php-imap
|
||||
[ico-snyk]: https://snyk-widget.herokuapp.com/badge/composer/webklex/php-imap/badge.svg
|
||||
[ico-discord]: https://img.shields.io/static/v1?label=discord&message=open&color=5865f2&style=flat-square
|
||||
|
||||
[link-packagist]: https://packagist.org/packages/Webklex/php-imap
|
||||
[link-travis]: https://travis-ci.org/Webklex/php-imap
|
||||
[link-scrutinizer]: https://scrutinizer-ci.com/g/Webklex/php-imap/code-structure
|
||||
[link-code-quality]: https://scrutinizer-ci.com/g/Webklex/php-imap
|
||||
[link-downloads]: https://packagist.org/packages/Webklex/php-imap
|
||||
[link-author]: https://github.com/webklex
|
||||
[link-contributors]: https://github.com/Webklex/php-imap/graphs/contributors
|
||||
[link-license]: https://github.com/Webklex/php-imap/blob/master/LICENSE
|
||||
[link-changelog]: https://github.com/Webklex/php-imap/blob/master/CHANGELOG.md
|
||||
[link-jetbrains]: https://www.jetbrains.com
|
||||
[link-hits]: https://hits.webklex.com
|
||||
[link-snyk]: https://snyk.io/vuln/composer:webklex%2Fphp-imap
|
||||
[link-discord]: https://discord.gg/rd4cN9h6
|
||||
1
vendor/webklex/php-imap/_config.yml
vendored
Normal file
1
vendor/webklex/php-imap/_config.yml
vendored
Normal file
@@ -0,0 +1 @@
|
||||
theme: jekyll-theme-cayman
|
||||
58
vendor/webklex/php-imap/composer.json
vendored
Normal file
58
vendor/webklex/php-imap/composer.json
vendored
Normal file
@@ -0,0 +1,58 @@
|
||||
{
|
||||
"name": "webklex/php-imap",
|
||||
"type": "library",
|
||||
"description": "PHP IMAP client",
|
||||
"keywords": [
|
||||
"webklex",
|
||||
"imap",
|
||||
"pop3",
|
||||
"php-imap",
|
||||
"mail"
|
||||
],
|
||||
"homepage": "https://github.com/webklex/php-imap",
|
||||
"license": "MIT",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Malte Goldenbaum",
|
||||
"email": "github@webklex.com",
|
||||
"role": "Developer"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": ">=7.0.0",
|
||||
"ext-openssl": "*",
|
||||
"ext-json": "*",
|
||||
"ext-mbstring": "*",
|
||||
"ext-iconv": "*",
|
||||
"ext-fileinfo": "*",
|
||||
"nesbot/carbon": ">=1.0",
|
||||
"symfony/http-foundation": ">=2.8.0",
|
||||
"illuminate/pagination": ">=5.0.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "~4.0"
|
||||
},
|
||||
"suggest": {
|
||||
"symfony/mime": "Recomended for better extension support"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Webklex\\PHPIMAP\\": "src"
|
||||
}
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"Tests\\": "tests"
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"test": "phpunit"
|
||||
},
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.0-dev"
|
||||
}
|
||||
},
|
||||
"minimum-stability": "dev",
|
||||
"prefer-stable": true
|
||||
}
|
||||
56
vendor/webklex/php-imap/examples/custom_attachment_mask.php
vendored
Normal file
56
vendor/webklex/php-imap/examples/custom_attachment_mask.php
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
/*
|
||||
* File: custom_message_mask.php
|
||||
* Category: Example
|
||||
* Author: M.Goldenbaum
|
||||
* Created: 14.03.19 18:47
|
||||
* Updated: -
|
||||
*
|
||||
* Description:
|
||||
* -
|
||||
*/
|
||||
|
||||
class CustomAttachmentMask extends \Webklex\PHPIMAP\Support\Masks\AttachmentMask {
|
||||
|
||||
/**
|
||||
* New custom method which can be called through a mask
|
||||
* @return string
|
||||
*/
|
||||
public function token(){
|
||||
return implode('-', [$this->id, $this->getMessage()->getUid(), $this->name]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom attachment saving method
|
||||
* @return bool
|
||||
*/
|
||||
public function custom_save() {
|
||||
$path = "foo".DIRECTORY_SEPARATOR."bar".DIRECTORY_SEPARATOR;
|
||||
$filename = $this->token();
|
||||
|
||||
return file_put_contents($path.$filename, $this->getContent()) !== false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/** @var \Webklex\PHPIMAP\Client $client */
|
||||
$cm = new \Webklex\PHPIMAP\ClientManager('path/to/config/imap.php');
|
||||
$client = $cm->account('default');
|
||||
$client->connect();
|
||||
$client->setDefaultAttachmentMask(CustomAttachmentMask::class);
|
||||
|
||||
/** @var \Webklex\PHPIMAP\Folder $folder */
|
||||
$folder = $client->getFolder('INBOX');
|
||||
|
||||
/** @var \Webklex\PHPIMAP\Message $message */
|
||||
$message = $folder->query()->limit(1)->get()->first();
|
||||
|
||||
/** @var \Webklex\PHPIMAP\Attachment $attachment */
|
||||
$attachment = $message->getAttachments()->first();
|
||||
|
||||
/** @var CustomAttachmentMask $masked_attachment */
|
||||
$masked_attachment = $attachment->mask();
|
||||
|
||||
echo 'Token for uid ['.$masked_attachment->getMessage()->getUid().']: '.$masked_attachment->token();
|
||||
|
||||
$masked_attachment->custom_save();
|
||||
50
vendor/webklex/php-imap/examples/custom_message_mask.php
vendored
Normal file
50
vendor/webklex/php-imap/examples/custom_message_mask.php
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
/*
|
||||
* File: custom_message_mask.php
|
||||
* Category: Example
|
||||
* Author: M.Goldenbaum
|
||||
* Created: 14.03.19 18:47
|
||||
* Updated: -
|
||||
*
|
||||
* Description:
|
||||
* -
|
||||
*/
|
||||
|
||||
class CustomMessageMask extends \Webklex\PHPIMAP\Support\Masks\MessageMask {
|
||||
|
||||
/**
|
||||
* New custom method which can be called through a mask
|
||||
* @return string
|
||||
*/
|
||||
public function token(){
|
||||
return implode('-', [$this->message_id, $this->uid, $this->message_no]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get number of message attachments
|
||||
* @return integer
|
||||
*/
|
||||
public function getAttachmentCount() {
|
||||
return $this->getAttachments()->count();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/** @var \Webklex\PHPIMAP\Client $client */
|
||||
$cm = new \Webklex\PHPIMAP\ClientManager('path/to/config/imap.php');
|
||||
$client = $cm->account('default');
|
||||
$client->connect();
|
||||
|
||||
/** @var \Webklex\PHPIMAP\Folder $folder */
|
||||
$folder = $client->getFolder('INBOX');
|
||||
|
||||
/** @var \Webklex\PHPIMAP\Message $message */
|
||||
$message = $folder->query()->limit(1)->get()->first();
|
||||
|
||||
/** @var CustomMessageMask $masked_message */
|
||||
$masked_message = $message->mask(CustomMessageMask::class);
|
||||
|
||||
echo 'Token for uid ['.$masked_message->uid.']: '.$masked_message->token().' @atms:'.$masked_message->getAttachmentCount();
|
||||
|
||||
$masked_message->setFlag('seen');
|
||||
|
||||
42
vendor/webklex/php-imap/examples/folder_structure.blade.php
vendored
Normal file
42
vendor/webklex/php-imap/examples/folder_structure.blade.php
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
/*
|
||||
* File: folder_structure.blade.php
|
||||
* Category: View
|
||||
* Author: M.Goldenbaum
|
||||
* Created: 15.09.18 19:53
|
||||
* Updated: -
|
||||
*
|
||||
* Description:
|
||||
* -
|
||||
*/
|
||||
|
||||
/**
|
||||
* @var \Webklex\PHPIMAP\Support\FolderCollection $paginator
|
||||
* @var \Webklex\PHPIMAP\Folder $folder
|
||||
*/
|
||||
|
||||
?>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Folder</th>
|
||||
<th>Unread messages</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php if($paginator->count() > 0): ?>
|
||||
<?php foreach($paginator as $folder): ?>
|
||||
<tr>
|
||||
<td><?php echo $folder->name; ?></td>
|
||||
<td><?php echo $folder->search()->unseen()->setFetchBody(false)->count(); ?></td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
<?php else: ?>
|
||||
<tr>
|
||||
<td colspan="4">No folders found</td>
|
||||
</tr>
|
||||
<?php endif; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<?php echo $paginator->links(); ?>
|
||||
46
vendor/webklex/php-imap/examples/message_table.blade.php
vendored
Normal file
46
vendor/webklex/php-imap/examples/message_table.blade.php
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
/*
|
||||
* File: message_table.blade.php
|
||||
* Category: View
|
||||
* Author: M.Goldenbaum
|
||||
* Created: 15.09.18 19:53
|
||||
* Updated: -
|
||||
*
|
||||
* Description:
|
||||
* -
|
||||
*/
|
||||
|
||||
/**
|
||||
* @var \Webklex\PHPIMAP\Support\FolderCollection $paginator
|
||||
* @var \Webklex\PHPIMAP\Message $message
|
||||
*/
|
||||
|
||||
?>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>UID</th>
|
||||
<th>Subject</th>
|
||||
<th>From</th>
|
||||
<th>Attachments</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php if($paginator->count() > 0): ?>
|
||||
<?php foreach($paginator as $message): ?>
|
||||
<tr>
|
||||
<td><?php echo $message->getUid(); ?></td>
|
||||
<td><?php echo $message->getSubject(); ?></td>
|
||||
<td><?php echo $message->getFrom()[0]->mail; ?></td>
|
||||
<td><?php echo $message->getAttachments()->count() > 0 ? 'yes' : 'no'; ?></td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
<?php else: ?>
|
||||
<tr>
|
||||
<td colspan="4">No messages found</td>
|
||||
</tr>
|
||||
<?php endif; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<?php echo $paginator->links(); ?>
|
||||
32
vendor/webklex/php-imap/phpunit.xml
vendored
Normal file
32
vendor/webklex/php-imap/phpunit.xml
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<phpunit bootstrap="vendor/autoload.php"
|
||||
backupGlobals="false"
|
||||
backupStaticAttributes="false"
|
||||
colors="true"
|
||||
verbose="true"
|
||||
convertErrorsToExceptions="true"
|
||||
convertNoticesToExceptions="true"
|
||||
convertWarningsToExceptions="true"
|
||||
processIsolation="false"
|
||||
stopOnFailure="false">
|
||||
<testsuites>
|
||||
<testsuite name="PHP-IMAP Test Suite">
|
||||
<directory>tests</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
<filter>
|
||||
<whitelist>
|
||||
<directory suffix=".php">src/</directory>
|
||||
</whitelist>
|
||||
</filter>
|
||||
<logging>
|
||||
<log type="tap" target="build/report.tap"/>
|
||||
<log type="junit" target="build/report.junit.xml"/>
|
||||
<log type="coverage-html" target="build/coverage"/>
|
||||
<log type="coverage-text" target="build/coverage.txt"/>
|
||||
<log type="coverage-clover" target="build/logs/clover.xml"/>
|
||||
</logging>
|
||||
<php>
|
||||
<env name="APP_ENV" value="testing"/>
|
||||
</php>
|
||||
</phpunit>
|
||||
90
vendor/webklex/php-imap/src/Address.php
vendored
Normal file
90
vendor/webklex/php-imap/src/Address.php
vendored
Normal file
@@ -0,0 +1,90 @@
|
||||
<?php
|
||||
/*
|
||||
* File: Address.php
|
||||
* Category: -
|
||||
* Author: M. Goldenbaum
|
||||
* Created: 01.01.21 21:17
|
||||
* Updated: -
|
||||
*
|
||||
* Description:
|
||||
* -
|
||||
*/
|
||||
|
||||
namespace Webklex\PHPIMAP;
|
||||
|
||||
/**
|
||||
* Class Address
|
||||
*
|
||||
* @package Webklex\PHPIMAP
|
||||
*/
|
||||
class Address {
|
||||
|
||||
/**
|
||||
* Address attributes
|
||||
* @var string $personal
|
||||
* @var string $mailbox
|
||||
* @var string $host
|
||||
* @var string $mail
|
||||
* @var string $full
|
||||
*/
|
||||
public $personal = "";
|
||||
public $mailbox = "";
|
||||
public $host = "";
|
||||
public $mail = "";
|
||||
public $full = "";
|
||||
|
||||
/**
|
||||
* Address constructor.
|
||||
* @param object $object
|
||||
*/
|
||||
public function __construct($object) {
|
||||
if (property_exists($object, "personal")){ $this->personal = $object->personal; }
|
||||
if (property_exists($object, "mailbox")){ $this->mailbox = $object->mailbox; }
|
||||
if (property_exists($object, "host")){ $this->host = $object->host; }
|
||||
if (property_exists($object, "mail")){ $this->mail = $object->mail; }
|
||||
if (property_exists($object, "full")){ $this->full = $object->full; }
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the stringified address
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __toString() {
|
||||
return $this->full ?: "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the serialized address
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function __serialize(){
|
||||
return [
|
||||
"personal" => $this->personal,
|
||||
"mailbox" => $this->mailbox,
|
||||
"host" => $this->host,
|
||||
"mail" => $this->mail,
|
||||
"full" => $this->full,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert instance to array
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function toArray(): array {
|
||||
return $this->__serialize();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the stringified attribute
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function toString(): string {
|
||||
return $this->__toString();
|
||||
}
|
||||
}
|
||||
353
vendor/webklex/php-imap/src/Attachment.php
vendored
Executable file
353
vendor/webklex/php-imap/src/Attachment.php
vendored
Executable file
@@ -0,0 +1,353 @@
|
||||
<?php
|
||||
/*
|
||||
* File: Attachment.php
|
||||
* Category: -
|
||||
* Author: M. Goldenbaum
|
||||
* Created: 16.03.18 19:37
|
||||
* Updated: -
|
||||
*
|
||||
* Description:
|
||||
* -
|
||||
*/
|
||||
|
||||
namespace Webklex\PHPIMAP;
|
||||
|
||||
use Illuminate\Support\Str;
|
||||
use Webklex\PHPIMAP\Exceptions\MaskNotFoundException;
|
||||
use Webklex\PHPIMAP\Exceptions\MethodNotFoundException;
|
||||
use Webklex\PHPIMAP\Support\Masks\AttachmentMask;
|
||||
|
||||
/**
|
||||
* Class Attachment
|
||||
*
|
||||
* @package Webklex\PHPIMAP
|
||||
*
|
||||
* @property integer part_number
|
||||
* @property integer size
|
||||
* @property string content
|
||||
* @property string type
|
||||
* @property string content_type
|
||||
* @property string id
|
||||
* @property string name
|
||||
* @property string disposition
|
||||
* @property string img_src
|
||||
*
|
||||
* @method integer getPartNumber()
|
||||
* @method integer setPartNumber(integer $part_number)
|
||||
* @method string getContent()
|
||||
* @method string setContent(string $content)
|
||||
* @method string getType()
|
||||
* @method string setType(string $type)
|
||||
* @method string getContentType()
|
||||
* @method string setContentType(string $content_type)
|
||||
* @method string getId()
|
||||
* @method string setId(string $id)
|
||||
* @method string getSize()
|
||||
* @method string setSize(integer $size)
|
||||
* @method string getName()
|
||||
* @method string getDisposition()
|
||||
* @method string setDisposition(string $disposition)
|
||||
* @method string setImgSrc(string $img_src)
|
||||
*/
|
||||
class Attachment {
|
||||
|
||||
/**
|
||||
* @var Message $oMessage
|
||||
*/
|
||||
protected $oMessage;
|
||||
|
||||
/**
|
||||
* Used config
|
||||
*
|
||||
* @var array $config
|
||||
*/
|
||||
protected $config = [];
|
||||
|
||||
/** @var Part $part */
|
||||
protected $part;
|
||||
|
||||
/**
|
||||
* Attribute holder
|
||||
*
|
||||
* @var array $attributes
|
||||
*/
|
||||
protected $attributes = [
|
||||
'content' => null,
|
||||
'type' => null,
|
||||
'part_number' => 0,
|
||||
'content_type' => null,
|
||||
'id' => null,
|
||||
'name' => null,
|
||||
'disposition' => null,
|
||||
'img_src' => null,
|
||||
'size' => null,
|
||||
];
|
||||
|
||||
/**
|
||||
* Default mask
|
||||
*
|
||||
* @var string $mask
|
||||
*/
|
||||
protected $mask = AttachmentMask::class;
|
||||
|
||||
/**
|
||||
* Attachment constructor.
|
||||
* @param Message $oMessage
|
||||
* @param Part $part
|
||||
*/
|
||||
public function __construct(Message $oMessage, Part $part) {
|
||||
$this->config = ClientManager::get('options');
|
||||
|
||||
$this->oMessage = $oMessage;
|
||||
$this->part = $part;
|
||||
$this->part_number = $part->part_number;
|
||||
|
||||
$default_mask = $this->oMessage->getClient()->getDefaultAttachmentMask();
|
||||
if($default_mask != null) {
|
||||
$this->mask = $default_mask;
|
||||
}
|
||||
|
||||
$this->findType();
|
||||
$this->fetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* Call dynamic attribute setter and getter methods
|
||||
* @param string $method
|
||||
* @param array $arguments
|
||||
*
|
||||
* @return mixed
|
||||
* @throws MethodNotFoundException
|
||||
*/
|
||||
public function __call(string $method, array $arguments) {
|
||||
if(strtolower(substr($method, 0, 3)) === 'get') {
|
||||
$name = Str::snake(substr($method, 3));
|
||||
|
||||
if(isset($this->attributes[$name])) {
|
||||
return $this->attributes[$name];
|
||||
}
|
||||
|
||||
return null;
|
||||
}elseif (strtolower(substr($method, 0, 3)) === 'set') {
|
||||
$name = Str::snake(substr($method, 3));
|
||||
|
||||
$this->attributes[$name] = array_pop($arguments);
|
||||
|
||||
return $this->attributes[$name];
|
||||
}
|
||||
|
||||
throw new MethodNotFoundException("Method ".self::class.'::'.$method.'() is not supported');
|
||||
}
|
||||
|
||||
/**
|
||||
* Magic setter
|
||||
* @param $name
|
||||
* @param $value
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function __set($name, $value) {
|
||||
$this->attributes[$name] = $value;
|
||||
|
||||
return $this->attributes[$name];
|
||||
}
|
||||
|
||||
/**
|
||||
* magic getter
|
||||
* @param $name
|
||||
*
|
||||
* @return mixed|null
|
||||
*/
|
||||
public function __get($name) {
|
||||
if(isset($this->attributes[$name])) {
|
||||
return $this->attributes[$name];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine the structure type
|
||||
*/
|
||||
protected function findType() {
|
||||
switch ($this->part->type) {
|
||||
case IMAP::ATTACHMENT_TYPE_MESSAGE:
|
||||
$this->type = 'message';
|
||||
break;
|
||||
case IMAP::ATTACHMENT_TYPE_APPLICATION:
|
||||
$this->type = 'application';
|
||||
break;
|
||||
case IMAP::ATTACHMENT_TYPE_AUDIO:
|
||||
$this->type = 'audio';
|
||||
break;
|
||||
case IMAP::ATTACHMENT_TYPE_IMAGE:
|
||||
$this->type = 'image';
|
||||
break;
|
||||
case IMAP::ATTACHMENT_TYPE_VIDEO:
|
||||
$this->type = 'video';
|
||||
break;
|
||||
case IMAP::ATTACHMENT_TYPE_MODEL:
|
||||
$this->type = 'model';
|
||||
break;
|
||||
case IMAP::ATTACHMENT_TYPE_TEXT:
|
||||
$this->type = 'text';
|
||||
break;
|
||||
case IMAP::ATTACHMENT_TYPE_MULTIPART:
|
||||
$this->type = 'multipart';
|
||||
break;
|
||||
default:
|
||||
$this->type = 'other';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch the given attachment
|
||||
*/
|
||||
protected function fetch() {
|
||||
|
||||
$content = $this->part->content;
|
||||
|
||||
$this->content_type = $this->part->content_type;
|
||||
$this->content = $this->oMessage->decodeString($content, $this->part->encoding);
|
||||
|
||||
if (($id = $this->part->id) !== null) {
|
||||
$this->id = str_replace(['<', '>'], '', $id);
|
||||
}else{
|
||||
$this->id = hash("sha256", (string)microtime(true));
|
||||
}
|
||||
|
||||
$this->size = $this->part->bytes;
|
||||
$this->disposition = $this->part->disposition;
|
||||
|
||||
if (($filename = $this->part->filename) !== null) {
|
||||
$this->setName($filename);
|
||||
} elseif (($name = $this->part->name) !== null) {
|
||||
$this->setName($name);
|
||||
}else {
|
||||
$this->setName("undefined");
|
||||
}
|
||||
|
||||
if (IMAP::ATTACHMENT_TYPE_MESSAGE == $this->part->type) {
|
||||
if ($this->part->ifdescription) {
|
||||
$this->setName($this->part->description);
|
||||
} else {
|
||||
$this->setName($this->part->subtype);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Save the attachment content to your filesystem
|
||||
* @param string $path
|
||||
* @param string|null $filename
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function save(string $path, $filename = null): bool {
|
||||
$filename = $filename ?: $this->getName();
|
||||
|
||||
return file_put_contents($path.$filename, $this->getContent()) !== false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the attachment name and try to decode it
|
||||
* @param $name
|
||||
*/
|
||||
public function setName($name) {
|
||||
$decoder = $this->config['decoder']['attachment'];
|
||||
if ($name !== null) {
|
||||
if($decoder === 'utf-8' && extension_loaded('imap')) {
|
||||
$this->name = \imap_utf8($name);
|
||||
}else{
|
||||
$this->name = mb_decode_mimeheader($name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the attachment mime type
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getMimeType(){
|
||||
return (new \finfo())->buffer($this->getContent(), FILEINFO_MIME_TYPE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to guess the attachment file extension
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getExtension(){
|
||||
$guesser = "\Symfony\Component\Mime\MimeTypes";
|
||||
if (class_exists($guesser) !== false) {
|
||||
/** @var Symfony\Component\Mime\MimeTypes $guesser */
|
||||
$extensions = $guesser::getDefault()->getExtensions($this->getMimeType());
|
||||
return $extensions[0] ?? null;
|
||||
}
|
||||
|
||||
$deprecated_guesser = "\Symfony\Component\HttpFoundation\File\MimeType\ExtensionGuesser";
|
||||
if (class_exists($deprecated_guesser) !== false){
|
||||
/** @var \Symfony\Component\HttpFoundation\File\MimeType\ExtensionGuesser $deprecated_guesser */
|
||||
return $deprecated_guesser::getInstance()->guess($this->getMimeType());
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all attributes
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getAttributes(): array {
|
||||
return $this->attributes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Message
|
||||
*/
|
||||
public function getMessage(): Message {
|
||||
return $this->oMessage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the default mask
|
||||
* @param $mask
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setMask($mask): Attachment {
|
||||
if(class_exists($mask)){
|
||||
$this->mask = $mask;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the used default mask
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getMask(): string {
|
||||
return $this->mask;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a masked instance by providing a mask name
|
||||
* @param string|null $mask
|
||||
*
|
||||
* @return mixed
|
||||
* @throws MaskNotFoundException
|
||||
*/
|
||||
public function mask($mask = null){
|
||||
$mask = $mask !== null ? $mask : $this->mask;
|
||||
if(class_exists($mask)){
|
||||
return new $mask($this);
|
||||
}
|
||||
|
||||
throw new MaskNotFoundException("Unknown mask provided: ".$mask);
|
||||
}
|
||||
}
|
||||
262
vendor/webklex/php-imap/src/Attribute.php
vendored
Normal file
262
vendor/webklex/php-imap/src/Attribute.php
vendored
Normal file
@@ -0,0 +1,262 @@
|
||||
<?php
|
||||
/*
|
||||
* File: Attribute.php
|
||||
* Category: -
|
||||
* Author: M. Goldenbaum
|
||||
* Created: 01.01.21 20:17
|
||||
* Updated: -
|
||||
*
|
||||
* Description:
|
||||
* -
|
||||
*/
|
||||
|
||||
namespace Webklex\PHPIMAP;
|
||||
|
||||
use ArrayAccess;
|
||||
use Carbon\Carbon;
|
||||
use ReturnTypeWillChange;
|
||||
|
||||
/**
|
||||
* Class Attribute
|
||||
*
|
||||
* @package Webklex\PHPIMAP
|
||||
*/
|
||||
class Attribute implements ArrayAccess {
|
||||
|
||||
/** @var string $name */
|
||||
protected $name;
|
||||
|
||||
/**
|
||||
* Value holder
|
||||
*
|
||||
* @var array $values
|
||||
*/
|
||||
protected $values = [];
|
||||
|
||||
/**
|
||||
* Attribute constructor.
|
||||
* @param string $name
|
||||
* @param array|mixed $value
|
||||
*/
|
||||
public function __construct(string $name, $value = null) {
|
||||
$this->setName($name);
|
||||
$this->add($value);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the stringified attribute
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __toString() {
|
||||
return implode(", ", $this->values);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the stringified attribute
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function toString(): string {
|
||||
return $this->__toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert instance to array
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function toArray(): array {
|
||||
return $this->values;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert first value to a date object
|
||||
*
|
||||
* @return Carbon
|
||||
*/
|
||||
public function toDate(): Carbon {
|
||||
$date = $this->first();
|
||||
if ($date instanceof Carbon) return $date;
|
||||
|
||||
return Carbon::parse($date);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if a value exists at an offset.
|
||||
*
|
||||
* @param mixed $offset
|
||||
* @return bool
|
||||
*/
|
||||
public function offsetExists($offset): bool {
|
||||
return array_key_exists($offset, $this->values);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a value at a given offset.
|
||||
*
|
||||
* @param mixed $offset
|
||||
* @return mixed
|
||||
*/
|
||||
#[ReturnTypeWillChange]
|
||||
public function offsetGet($offset) {
|
||||
return $this->values[$offset];
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value at a given offset.
|
||||
*
|
||||
* @param mixed $offset
|
||||
* @param mixed $value
|
||||
* @return void
|
||||
*/
|
||||
#[ReturnTypeWillChange]
|
||||
public function offsetSet($offset, $value) {
|
||||
if (is_null($offset)) {
|
||||
$this->values[] = $value;
|
||||
} else {
|
||||
$this->values[$offset] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unset the value at a given offset.
|
||||
*
|
||||
* @param string $offset
|
||||
* @return void
|
||||
*/
|
||||
#[ReturnTypeWillChange]
|
||||
public function offsetUnset($offset) {
|
||||
unset($this->values[$offset]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add one or more values to the attribute
|
||||
* @param array|mixed $value
|
||||
* @param boolean $strict
|
||||
*
|
||||
* @return Attribute
|
||||
*/
|
||||
public function add($value, bool $strict = false): Attribute {
|
||||
if (is_array($value)) {
|
||||
return $this->merge($value, $strict);
|
||||
}elseif ($value !== null) {
|
||||
$this->attach($value, $strict);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Merge a given array of values with the current values array
|
||||
* @param array $values
|
||||
* @param boolean $strict
|
||||
*
|
||||
* @return Attribute
|
||||
*/
|
||||
public function merge(array $values, bool $strict = false): Attribute {
|
||||
foreach ($values as $value) {
|
||||
$this->attach($value, $strict);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the attribute contains the given value
|
||||
* @param mixed $value
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function contains($value): bool {
|
||||
return in_array($value, $this->values, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Attach a given value to the current value array
|
||||
* @param $value
|
||||
* @param bool $strict
|
||||
*/
|
||||
public function attach($value, bool $strict = false) {
|
||||
if ($strict === true) {
|
||||
if ($this->contains($value) === false) {
|
||||
$this->values[] = $value;
|
||||
}
|
||||
}else{
|
||||
$this->values[] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the attribute name
|
||||
* @param $name
|
||||
*
|
||||
* @return Attribute
|
||||
*/
|
||||
public function setName($name): Attribute {
|
||||
$this->name = $name;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the attribute name
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getName(): string {
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all values
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get(): array {
|
||||
return $this->values;
|
||||
}
|
||||
|
||||
/**
|
||||
* Alias method for self::get()
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function all(): array {
|
||||
return $this->get();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the first value if possible
|
||||
*
|
||||
* @return mixed|null
|
||||
*/
|
||||
public function first(){
|
||||
if ($this->offsetExists(0)) {
|
||||
return $this->values[0];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the last value if possible
|
||||
*
|
||||
* @return mixed|null
|
||||
*/
|
||||
public function last(){
|
||||
if (($cnt = $this->count()) > 0) {
|
||||
return $this->values[$cnt - 1];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the number of values
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function count(): int {
|
||||
return count($this->values);
|
||||
}
|
||||
}
|
||||
746
vendor/webklex/php-imap/src/Client.php
vendored
Executable file
746
vendor/webklex/php-imap/src/Client.php
vendored
Executable file
@@ -0,0 +1,746 @@
|
||||
<?php
|
||||
/*
|
||||
* File: Client.php
|
||||
* Category: -
|
||||
* Author: M. Goldenbaum
|
||||
* Created: 19.01.17 22:21
|
||||
* Updated: -
|
||||
*
|
||||
* Description:
|
||||
* -
|
||||
*/
|
||||
|
||||
namespace Webklex\PHPIMAP;
|
||||
|
||||
use ErrorException;
|
||||
use Webklex\PHPIMAP\Connection\Protocols\ImapProtocol;
|
||||
use Webklex\PHPIMAP\Connection\Protocols\LegacyProtocol;
|
||||
use Webklex\PHPIMAP\Connection\Protocols\Protocol;
|
||||
use Webklex\PHPIMAP\Connection\Protocols\ProtocolInterface;
|
||||
use Webklex\PHPIMAP\Exceptions\AuthFailedException;
|
||||
use Webklex\PHPIMAP\Exceptions\ConnectionFailedException;
|
||||
use Webklex\PHPIMAP\Exceptions\FolderFetchingException;
|
||||
use Webklex\PHPIMAP\Exceptions\MaskNotFoundException;
|
||||
use Webklex\PHPIMAP\Exceptions\ProtocolNotSupportedException;
|
||||
use Webklex\PHPIMAP\Support\FolderCollection;
|
||||
use Webklex\PHPIMAP\Support\Masks\AttachmentMask;
|
||||
use Webklex\PHPIMAP\Support\Masks\MessageMask;
|
||||
use Webklex\PHPIMAP\Traits\HasEvents;
|
||||
|
||||
/**
|
||||
* Class Client
|
||||
*
|
||||
* @package Webklex\PHPIMAP
|
||||
*/
|
||||
class Client {
|
||||
use HasEvents;
|
||||
|
||||
/**
|
||||
* Connection resource
|
||||
*
|
||||
* @var boolean|Protocol|ProtocolInterface
|
||||
*/
|
||||
public $connection = false;
|
||||
|
||||
/**
|
||||
* Server hostname.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $host;
|
||||
|
||||
/**
|
||||
* Server port.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $port;
|
||||
|
||||
/**
|
||||
* Service protocol.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $protocol;
|
||||
|
||||
/**
|
||||
* Server encryption.
|
||||
* Supported: none, ssl, tls, starttls or notls.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $encryption;
|
||||
|
||||
/**
|
||||
* If server has to validate cert.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public $validate_cert = true;
|
||||
|
||||
/**
|
||||
* Proxy settings
|
||||
* @var array
|
||||
*/
|
||||
protected $proxy = [
|
||||
'socket' => null,
|
||||
'request_fulluri' => false,
|
||||
'username' => null,
|
||||
'password' => null,
|
||||
];
|
||||
|
||||
/**
|
||||
* Connection timeout
|
||||
* @var int $timeout
|
||||
*/
|
||||
public $timeout;
|
||||
|
||||
/**
|
||||
* Account username/
|
||||
*
|
||||
* @var mixed
|
||||
*/
|
||||
public $username;
|
||||
|
||||
/**
|
||||
* Account password.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $password;
|
||||
|
||||
/**
|
||||
* Additional data fetched from the server.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $extensions;
|
||||
|
||||
/**
|
||||
* Account authentication method.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $authentication;
|
||||
|
||||
/**
|
||||
* Active folder path.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $active_folder = null;
|
||||
|
||||
/**
|
||||
* Default message mask
|
||||
*
|
||||
* @var string $default_message_mask
|
||||
*/
|
||||
protected $default_message_mask = MessageMask::class;
|
||||
|
||||
/**
|
||||
* Default attachment mask
|
||||
*
|
||||
* @var string $default_attachment_mask
|
||||
*/
|
||||
protected $default_attachment_mask = AttachmentMask::class;
|
||||
|
||||
/**
|
||||
* Used default account values
|
||||
*
|
||||
* @var array $default_account_config
|
||||
*/
|
||||
protected $default_account_config = [
|
||||
'host' => 'localhost',
|
||||
'port' => 993,
|
||||
'protocol' => 'imap',
|
||||
'encryption' => 'ssl',
|
||||
'validate_cert' => true,
|
||||
'username' => '',
|
||||
'password' => '',
|
||||
'authentication' => null,
|
||||
"extensions" => [],
|
||||
'proxy' => [
|
||||
'socket' => null,
|
||||
'request_fulluri' => false,
|
||||
'username' => null,
|
||||
'password' => null,
|
||||
],
|
||||
"timeout" => 30
|
||||
];
|
||||
|
||||
/**
|
||||
* Client constructor.
|
||||
* @param array $config
|
||||
*
|
||||
* @throws MaskNotFoundException
|
||||
*/
|
||||
public function __construct(array $config = []) {
|
||||
$this->setConfig($config);
|
||||
$this->setMaskFromConfig($config);
|
||||
$this->setEventsFromConfig($config);
|
||||
}
|
||||
|
||||
/**
|
||||
* Client destructor
|
||||
*/
|
||||
public function __destruct() {
|
||||
$this->disconnect();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the Client configuration
|
||||
* @param array $config
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function setConfig(array $config): Client {
|
||||
$default_account = ClientManager::get('default');
|
||||
$default_config = ClientManager::get("accounts.$default_account");
|
||||
|
||||
foreach ($this->default_account_config as $key => $value) {
|
||||
$this->setAccountConfig($key, $config, $default_config);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a specific account config
|
||||
* @param string $key
|
||||
* @param array $config
|
||||
* @param array $default_config
|
||||
*/
|
||||
private function setAccountConfig(string $key, array $config, array $default_config){
|
||||
$value = $this->default_account_config[$key];
|
||||
if(isset($config[$key])) {
|
||||
$value = $config[$key];
|
||||
}elseif(isset($default_config[$key])) {
|
||||
$value = $default_config[$key];
|
||||
}
|
||||
$this->$key = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Look for a possible events in any available config
|
||||
* @param $config
|
||||
*/
|
||||
protected function setEventsFromConfig($config) {
|
||||
$this->events = ClientManager::get("events");
|
||||
if(isset($config['events'])){
|
||||
foreach($config['events'] as $section => $events) {
|
||||
$this->events[$section] = array_merge($this->events[$section], $events);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Look for a possible mask in any available config
|
||||
* @param $config
|
||||
*
|
||||
* @throws MaskNotFoundException
|
||||
*/
|
||||
protected function setMaskFromConfig($config) {
|
||||
$default_config = ClientManager::get("masks");
|
||||
|
||||
if(isset($config['masks'])){
|
||||
if(isset($config['masks']['message'])) {
|
||||
if(class_exists($config['masks']['message'])) {
|
||||
$this->default_message_mask = $config['masks']['message'];
|
||||
}else{
|
||||
throw new MaskNotFoundException("Unknown mask provided: ".$config['masks']['message']);
|
||||
}
|
||||
}else{
|
||||
if(class_exists($default_config['message'])) {
|
||||
$this->default_message_mask = $default_config['message'];
|
||||
}else{
|
||||
throw new MaskNotFoundException("Unknown mask provided: ".$default_config['message']);
|
||||
}
|
||||
}
|
||||
if(isset($config['masks']['attachment'])) {
|
||||
if(class_exists($config['masks']['attachment'])) {
|
||||
$this->default_attachment_mask = $config['masks']['attachment'];
|
||||
}else{
|
||||
throw new MaskNotFoundException("Unknown mask provided: ".$config['masks']['attachment']);
|
||||
}
|
||||
}else{
|
||||
if(class_exists($default_config['attachment'])) {
|
||||
$this->default_attachment_mask = $default_config['attachment'];
|
||||
}else{
|
||||
throw new MaskNotFoundException("Unknown mask provided: ".$default_config['attachment']);
|
||||
}
|
||||
}
|
||||
}else{
|
||||
if(class_exists($default_config['message'])) {
|
||||
$this->default_message_mask = $default_config['message'];
|
||||
}else{
|
||||
throw new MaskNotFoundException("Unknown mask provided: ".$default_config['message']);
|
||||
}
|
||||
|
||||
if(class_exists($default_config['attachment'])) {
|
||||
$this->default_attachment_mask = $default_config['attachment'];
|
||||
}else{
|
||||
throw new MaskNotFoundException("Unknown mask provided: ".$default_config['attachment']);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current imap resource
|
||||
*
|
||||
* @return bool|Protocol|ProtocolInterface
|
||||
* @throws ConnectionFailedException
|
||||
*/
|
||||
public function getConnection() {
|
||||
$this->checkConnection();
|
||||
return $this->connection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if connection was established.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isConnected(): bool {
|
||||
return $this->connection && $this->connection->connected();
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if connection was established and connect if not.
|
||||
*
|
||||
* @throws ConnectionFailedException
|
||||
*/
|
||||
public function checkConnection() {
|
||||
if (!$this->isConnected()) {
|
||||
$this->connect();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Force the connection to reconnect
|
||||
*
|
||||
* @throws ConnectionFailedException
|
||||
*/
|
||||
public function reconnect() {
|
||||
if ($this->isConnected()) {
|
||||
$this->disconnect();
|
||||
}
|
||||
$this->connect();
|
||||
}
|
||||
|
||||
/**
|
||||
* Connect to server.
|
||||
*
|
||||
* @return $this
|
||||
* @throws ConnectionFailedException
|
||||
*/
|
||||
public function connect(): Client {
|
||||
$this->disconnect();
|
||||
$protocol = strtolower($this->protocol);
|
||||
|
||||
if (in_array($protocol, ['imap', 'imap4', 'imap4rev1'])) {
|
||||
$this->connection = new ImapProtocol($this->validate_cert, $this->encryption);
|
||||
$this->connection->setConnectionTimeout($this->timeout);
|
||||
$this->connection->setProxy($this->proxy);
|
||||
}else{
|
||||
if (extension_loaded('imap') === false) {
|
||||
throw new ConnectionFailedException("connection setup failed", 0, new ProtocolNotSupportedException($protocol." is an unsupported protocol"));
|
||||
}
|
||||
$this->connection = new LegacyProtocol($this->validate_cert, $this->encryption);
|
||||
if (strpos($protocol, "legacy-") === 0) {
|
||||
$protocol = substr($protocol, 7);
|
||||
}
|
||||
$this->connection->setProtocol($protocol);
|
||||
}
|
||||
|
||||
if (ClientManager::get('options.debug')) {
|
||||
$this->connection->enableDebug();
|
||||
}
|
||||
|
||||
if (!ClientManager::get('options.uid_cache')) {
|
||||
$this->connection->disableUidCache();
|
||||
}
|
||||
|
||||
try {
|
||||
$this->connection->connect($this->host, $this->port);
|
||||
} catch (ErrorException $e) {
|
||||
throw new ConnectionFailedException("connection setup failed", 0, $e);
|
||||
} catch (Exceptions\RuntimeException $e) {
|
||||
throw new ConnectionFailedException("connection setup failed", 0, $e);
|
||||
}
|
||||
$this->authenticate();
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Authenticate the current session
|
||||
*
|
||||
* @throws ConnectionFailedException
|
||||
*/
|
||||
protected function authenticate() {
|
||||
try {
|
||||
if ($this->authentication == "oauth") {
|
||||
if (!$this->connection->authenticate($this->username, $this->password)) {
|
||||
throw new AuthFailedException();
|
||||
}
|
||||
} elseif (!$this->connection->login($this->username, $this->password)) {
|
||||
throw new AuthFailedException();
|
||||
}
|
||||
} catch (AuthFailedException $e) {
|
||||
throw new ConnectionFailedException("connection setup failed", 0, $e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Disconnect from server.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function disconnect(): Client {
|
||||
if ($this->isConnected() && $this->connection !== false) {
|
||||
$this->connection->logout();
|
||||
}
|
||||
$this->active_folder = null;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a folder instance by a folder name
|
||||
* @param string $folder_name
|
||||
* @param string|bool|null $delimiter
|
||||
*
|
||||
* @return Folder|null
|
||||
* @throws ConnectionFailedException
|
||||
* @throws FolderFetchingException
|
||||
* @throws Exceptions\RuntimeException
|
||||
*/
|
||||
public function getFolder(string $folder_name, $delimiter = null) {
|
||||
if ($delimiter !== false && $delimiter !== null) {
|
||||
return $this->getFolderByPath($folder_name);
|
||||
}
|
||||
|
||||
// Set delimiter to false to force selection via getFolderByName (maybe useful for uncommon folder names)
|
||||
$delimiter = is_null($delimiter) ? ClientManager::get('options.delimiter', "/") : $delimiter;
|
||||
if (strpos($folder_name, (string)$delimiter) !== false) {
|
||||
return $this->getFolderByPath($folder_name);
|
||||
}
|
||||
|
||||
return $this->getFolderByName($folder_name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a folder instance by a folder name
|
||||
* @param $folder_name
|
||||
*
|
||||
* @return Folder|null
|
||||
* @throws ConnectionFailedException
|
||||
* @throws FolderFetchingException
|
||||
* @throws Exceptions\RuntimeException
|
||||
*/
|
||||
public function getFolderByName($folder_name) {
|
||||
return $this->getFolders(false)->where("name", $folder_name)->first();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a folder instance by a folder path
|
||||
* @param $folder_path
|
||||
*
|
||||
* @return Folder|null
|
||||
* @throws ConnectionFailedException
|
||||
* @throws FolderFetchingException
|
||||
* @throws Exceptions\RuntimeException
|
||||
*/
|
||||
public function getFolderByPath($folder_path) {
|
||||
return $this->getFolders(false)->where("path", $folder_path)->first();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get folders list.
|
||||
* If hierarchical order is set to true, it will make a tree of folders, otherwise it will return flat array.
|
||||
*
|
||||
* @param boolean $hierarchical
|
||||
* @param string|null $parent_folder
|
||||
*
|
||||
* @return FolderCollection
|
||||
* @throws ConnectionFailedException
|
||||
* @throws FolderFetchingException
|
||||
* @throws Exceptions\RuntimeException
|
||||
*/
|
||||
public function getFolders(bool $hierarchical = true, string $parent_folder = null): FolderCollection {
|
||||
$this->checkConnection();
|
||||
$folders = FolderCollection::make([]);
|
||||
|
||||
$pattern = $parent_folder.($hierarchical ? '%' : '*');
|
||||
$items = $this->connection->folders('', $pattern);
|
||||
|
||||
if(is_array($items)){
|
||||
foreach ($items as $folder_name => $item) {
|
||||
$folder = new Folder($this, $folder_name, $item["delimiter"], $item["flags"]);
|
||||
|
||||
if ($hierarchical && $folder->hasChildren()) {
|
||||
$pattern = $folder->full_name.$folder->delimiter.'%';
|
||||
|
||||
$children = $this->getFolders(true, $pattern);
|
||||
$folder->setChildren($children);
|
||||
}
|
||||
|
||||
$folders->push($folder);
|
||||
}
|
||||
|
||||
return $folders;
|
||||
}else{
|
||||
throw new FolderFetchingException("failed to fetch any folders");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get folders list.
|
||||
* If hierarchical order is set to true, it will make a tree of folders, otherwise it will return flat array.
|
||||
*
|
||||
* @param boolean $hierarchical
|
||||
* @param string|null $parent_folder
|
||||
*
|
||||
* @return FolderCollection
|
||||
* @throws ConnectionFailedException
|
||||
* @throws FolderFetchingException
|
||||
* @throws Exceptions\RuntimeException
|
||||
*/
|
||||
public function getFoldersWithStatus(bool $hierarchical = true, string $parent_folder = null): FolderCollection {
|
||||
$this->checkConnection();
|
||||
$folders = FolderCollection::make([]);
|
||||
|
||||
$pattern = $parent_folder.($hierarchical ? '%' : '*');
|
||||
$items = $this->connection->folders('', $pattern);
|
||||
|
||||
if(is_array($items)){
|
||||
foreach ($items as $folder_name => $item) {
|
||||
$folder = new Folder($this, $folder_name, $item["delimiter"], $item["flags"]);
|
||||
|
||||
if ($hierarchical && $folder->hasChildren()) {
|
||||
$pattern = $folder->full_name.$folder->delimiter.'%';
|
||||
|
||||
$children = $this->getFoldersWithStatus(true, $pattern);
|
||||
$folder->setChildren($children);
|
||||
}
|
||||
|
||||
$folder->loadStatus();
|
||||
$folders->push($folder);
|
||||
}
|
||||
|
||||
return $folders;
|
||||
}else{
|
||||
throw new FolderFetchingException("failed to fetch any folders");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Open a given folder.
|
||||
* @param string $folder_path
|
||||
* @param boolean $force_select
|
||||
*
|
||||
* @return array|bool
|
||||
* @throws ConnectionFailedException
|
||||
* @throws Exceptions\RuntimeException
|
||||
*/
|
||||
public function openFolder(string $folder_path, bool $force_select = false) {
|
||||
if ($this->active_folder == $folder_path && $this->isConnected() && $force_select === false) {
|
||||
return true;
|
||||
}
|
||||
$this->checkConnection();
|
||||
$this->active_folder = $folder_path;
|
||||
return $this->connection->selectFolder($folder_path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new Folder
|
||||
* @param string $folder
|
||||
* @param boolean $expunge
|
||||
*
|
||||
* @return Folder
|
||||
* @throws ConnectionFailedException
|
||||
* @throws FolderFetchingException
|
||||
* @throws Exceptions\EventNotFoundException
|
||||
* @throws Exceptions\RuntimeException
|
||||
*/
|
||||
public function createFolder(string $folder, bool $expunge = true): Folder {
|
||||
$this->checkConnection();
|
||||
$status = $this->connection->createFolder($folder);
|
||||
|
||||
if($expunge) $this->expunge();
|
||||
|
||||
$folder = $this->getFolderByPath($folder);
|
||||
if($status && $folder) {
|
||||
$event = $this->getEvent("folder", "new");
|
||||
$event::dispatch($folder);
|
||||
}
|
||||
|
||||
return $folder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check a given folder
|
||||
* @param $folder
|
||||
*
|
||||
* @return array|bool
|
||||
* @throws ConnectionFailedException
|
||||
* @throws Exceptions\RuntimeException
|
||||
*/
|
||||
public function checkFolder($folder) {
|
||||
$this->checkConnection();
|
||||
return $this->connection->examineFolder($folder);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current active folder
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getFolderPath(){
|
||||
return $this->active_folder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Exchange identification information
|
||||
* Ref.: https://datatracker.ietf.org/doc/html/rfc2971
|
||||
*
|
||||
* @param array|null $ids
|
||||
* @return array|bool|void|null
|
||||
*
|
||||
* @throws ConnectionFailedException
|
||||
* @throws Exceptions\RuntimeException
|
||||
*/
|
||||
public function Id(array $ids = null) {
|
||||
$this->checkConnection();
|
||||
return $this->connection->ID($ids);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the quota level settings, and usage statics per mailbox
|
||||
*
|
||||
* @return array
|
||||
* @throws ConnectionFailedException
|
||||
* @throws Exceptions\RuntimeException
|
||||
*/
|
||||
public function getQuota(): array {
|
||||
$this->checkConnection();
|
||||
return $this->connection->getQuota($this->username);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the quota settings per user
|
||||
* @param string $quota_root
|
||||
*
|
||||
* @return array
|
||||
* @throws ConnectionFailedException
|
||||
*/
|
||||
public function getQuotaRoot(string $quota_root = 'INBOX'): array {
|
||||
$this->checkConnection();
|
||||
return $this->connection->getQuotaRoot($quota_root);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete all messages marked for deletion
|
||||
*
|
||||
* @return bool
|
||||
* @throws ConnectionFailedException
|
||||
* @throws Exceptions\RuntimeException
|
||||
*/
|
||||
public function expunge(): bool {
|
||||
$this->checkConnection();
|
||||
return $this->connection->expunge();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the connection timeout
|
||||
* @param integer $timeout
|
||||
*
|
||||
* @return Protocol
|
||||
* @throws ConnectionFailedException
|
||||
*/
|
||||
public function setTimeout(int $timeout): Protocol {
|
||||
$this->timeout = $timeout;
|
||||
if ($this->isConnected()) {
|
||||
$this->connection->setConnectionTimeout($timeout);
|
||||
$this->reconnect();
|
||||
}
|
||||
return $this->connection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the connection timeout
|
||||
*
|
||||
* @return int
|
||||
* @throws ConnectionFailedException
|
||||
*/
|
||||
public function getTimeout(): int {
|
||||
$this->checkConnection();
|
||||
return $this->connection->getConnectionTimeout();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the default message mask
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getDefaultMessageMask(): string {
|
||||
return $this->default_message_mask;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the default events for a given section
|
||||
* @param $section
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getDefaultEvents($section): array {
|
||||
if (isset($this->events[$section])) {
|
||||
return is_array($this->events[$section]) ? $this->events[$section] : [];
|
||||
}
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the default message mask
|
||||
* @param string $mask
|
||||
*
|
||||
* @return $this
|
||||
* @throws MaskNotFoundException
|
||||
*/
|
||||
public function setDefaultMessageMask(string $mask): Client {
|
||||
if(class_exists($mask)) {
|
||||
$this->default_message_mask = $mask;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
throw new MaskNotFoundException("Unknown mask provided: ".$mask);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the default attachment mask
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getDefaultAttachmentMask(): string {
|
||||
return $this->default_attachment_mask;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the default attachment mask
|
||||
* @param string $mask
|
||||
*
|
||||
* @return $this
|
||||
* @throws MaskNotFoundException
|
||||
*/
|
||||
public function setDefaultAttachmentMask(string $mask): Client {
|
||||
if(class_exists($mask)) {
|
||||
$this->default_attachment_mask = $mask;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
throw new MaskNotFoundException("Unknown mask provided: ".$mask);
|
||||
}
|
||||
}
|
||||
276
vendor/webklex/php-imap/src/ClientManager.php
vendored
Normal file
276
vendor/webklex/php-imap/src/ClientManager.php
vendored
Normal file
@@ -0,0 +1,276 @@
|
||||
<?php
|
||||
/*
|
||||
* File: ClientManager.php
|
||||
* Category: -
|
||||
* Author: M. Goldenbaum
|
||||
* Created: 19.01.17 22:21
|
||||
* Updated: -
|
||||
*
|
||||
* Description:
|
||||
* -
|
||||
*/
|
||||
|
||||
namespace Webklex\PHPIMAP;
|
||||
|
||||
/**
|
||||
* Class ClientManager
|
||||
*
|
||||
* @package Webklex\IMAP
|
||||
*
|
||||
* @mixin Client
|
||||
*/
|
||||
class ClientManager {
|
||||
|
||||
/**
|
||||
* All library config
|
||||
*
|
||||
* @var array $config
|
||||
*/
|
||||
public static $config = [];
|
||||
|
||||
/**
|
||||
* @var array $accounts
|
||||
*/
|
||||
protected $accounts = [];
|
||||
|
||||
/**
|
||||
* ClientManager constructor.
|
||||
* @param array|string $config
|
||||
*/
|
||||
public function __construct($config = []) {
|
||||
$this->setConfig($config);
|
||||
}
|
||||
|
||||
/**
|
||||
* Dynamically pass calls to the default account.
|
||||
* @param string $method
|
||||
* @param array $parameters
|
||||
*
|
||||
* @return mixed
|
||||
* @throws Exceptions\MaskNotFoundException
|
||||
*/
|
||||
public function __call(string $method, array $parameters) {
|
||||
$callable = [$this->account(), $method];
|
||||
|
||||
return call_user_func_array($callable, $parameters);
|
||||
}
|
||||
|
||||
/**
|
||||
* Safely create a new client instance which is not listed in accounts
|
||||
* @param array $config
|
||||
*
|
||||
* @return Client
|
||||
* @throws Exceptions\MaskNotFoundException
|
||||
*/
|
||||
public function make(array $config): Client {
|
||||
return new Client($config);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a dotted config parameter
|
||||
* @param string $key
|
||||
* @param null $default
|
||||
*
|
||||
* @return mixed|null
|
||||
*/
|
||||
public static function get(string $key, $default = null) {
|
||||
$parts = explode('.', $key);
|
||||
$value = null;
|
||||
foreach($parts as $part) {
|
||||
if($value === null) {
|
||||
if(isset(self::$config[$part])) {
|
||||
$value = self::$config[$part];
|
||||
}else{
|
||||
break;
|
||||
}
|
||||
}else{
|
||||
if(isset($value[$part])) {
|
||||
$value = $value[$part];
|
||||
}else{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $value === null ? $default : $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve a account instance.
|
||||
* @param string|null $name
|
||||
*
|
||||
* @return Client
|
||||
* @throws Exceptions\MaskNotFoundException
|
||||
*/
|
||||
public function account(string $name = null): Client {
|
||||
$name = $name ?: $this->getDefaultAccount();
|
||||
|
||||
// If the connection has not been resolved we will resolve it now as all
|
||||
// the connections are resolved when they are actually needed, so we do
|
||||
// not make any unnecessary connection to the various queue end-points.
|
||||
if (!isset($this->accounts[$name])) {
|
||||
$this->accounts[$name] = $this->resolve($name);
|
||||
}
|
||||
|
||||
return $this->accounts[$name];
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve an account.
|
||||
* @param string $name
|
||||
*
|
||||
* @return Client
|
||||
* @throws Exceptions\MaskNotFoundException
|
||||
*/
|
||||
protected function resolve(string $name): Client {
|
||||
$config = $this->getClientConfig($name);
|
||||
|
||||
return new Client($config);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the account configuration.
|
||||
* @param string|null $name
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function getClientConfig($name): array {
|
||||
if ($name === null || $name === 'null') {
|
||||
return ['driver' => 'null'];
|
||||
}
|
||||
|
||||
return is_array(self::$config["accounts"][$name]) ? self::$config["accounts"][$name] : [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the name of the default account.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getDefaultAccount(): string {
|
||||
return self::$config['default'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the name of the default account.
|
||||
* @param string $name
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setDefaultAccount(string $name) {
|
||||
self::$config['default'] = $name;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Merge the vendor settings with the local config
|
||||
*
|
||||
* The default account identifier will be used as default for any missing account parameters.
|
||||
* If however the default account is missing a parameter the package default account parameter will be used.
|
||||
* This can be disabled by setting imap.default in your config file to 'false'
|
||||
*
|
||||
* @param array|string $config
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setConfig($config): ClientManager {
|
||||
|
||||
if(is_array($config) === false) {
|
||||
$config = require $config;
|
||||
}
|
||||
|
||||
$config_key = 'imap';
|
||||
$path = __DIR__.'/config/'.$config_key.'.php';
|
||||
|
||||
$vendor_config = require $path;
|
||||
$config = $this->array_merge_recursive_distinct($vendor_config, $config);
|
||||
|
||||
if(is_array($config)){
|
||||
if(isset($config['default'])){
|
||||
if(isset($config['accounts']) && $config['default']){
|
||||
|
||||
$default_config = $vendor_config['accounts']['default'];
|
||||
if(isset($config['accounts'][$config['default']])){
|
||||
$default_config = array_merge($default_config, $config['accounts'][$config['default']]);
|
||||
}
|
||||
|
||||
if(is_array($config['accounts'])){
|
||||
foreach($config['accounts'] as $account_key => $account){
|
||||
$config['accounts'][$account_key] = array_merge($default_config, $account);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self::$config = $config;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Marge arrays recursively and distinct
|
||||
*
|
||||
* Merges any number of arrays / parameters recursively, replacing
|
||||
* entries with string keys with values from latter arrays.
|
||||
* If the entry or the next value to be assigned is an array, then it
|
||||
* automatically treats both arguments as an array.
|
||||
* Numeric entries are appended, not replaced, but only if they are
|
||||
* unique
|
||||
*
|
||||
* @return array|mixed
|
||||
*
|
||||
* @link http://www.php.net/manual/en/function.array-merge-recursive.php#96201
|
||||
* @author Mark Roduner <mark.roduner@gmail.com>
|
||||
*/
|
||||
private function array_merge_recursive_distinct() {
|
||||
|
||||
$arrays = func_get_args();
|
||||
$base = array_shift($arrays);
|
||||
|
||||
// From https://stackoverflow.com/a/173479
|
||||
$isAssoc = function(array $arr) {
|
||||
if (array() === $arr) return false;
|
||||
return array_keys($arr) !== range(0, count($arr) - 1);
|
||||
};
|
||||
|
||||
if(!is_array($base)) $base = empty($base) ? array() : array($base);
|
||||
|
||||
foreach($arrays as $append) {
|
||||
|
||||
if(!is_array($append)) $append = array($append);
|
||||
|
||||
foreach($append as $key => $value) {
|
||||
|
||||
if(!array_key_exists($key, $base) and !is_numeric($key)) {
|
||||
$base[$key] = $value;
|
||||
continue;
|
||||
}
|
||||
|
||||
if(
|
||||
(
|
||||
is_array($value)
|
||||
&& $isAssoc($value)
|
||||
)
|
||||
|| (
|
||||
is_array($base[$key])
|
||||
&& $isAssoc($base[$key])
|
||||
)
|
||||
) {
|
||||
// If the arrays are not associates we don't want to array_merge_recursive_distinct
|
||||
// else merging $baseConfig['dispositions'] = ['attachment', 'inline'] with $customConfig['dispositions'] = ['attachment']
|
||||
// results in $resultConfig['dispositions'] = ['attachment', 'inline']
|
||||
$base[$key] = $this->array_merge_recursive_distinct($base[$key], $value);
|
||||
} else if(is_numeric($key)) {
|
||||
if(!in_array($value, $base)) $base[] = $value;
|
||||
} else {
|
||||
$base[$key] = $value;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return $base;
|
||||
}
|
||||
}
|
||||
1160
vendor/webklex/php-imap/src/Connection/Protocols/ImapProtocol.php
vendored
Normal file
1160
vendor/webklex/php-imap/src/Connection/Protocols/ImapProtocol.php
vendored
Normal file
File diff suppressed because it is too large
Load Diff
643
vendor/webklex/php-imap/src/Connection/Protocols/LegacyProtocol.php
vendored
Normal file
643
vendor/webklex/php-imap/src/Connection/Protocols/LegacyProtocol.php
vendored
Normal file
@@ -0,0 +1,643 @@
|
||||
<?php
|
||||
/*
|
||||
* File: LegacyProtocol.php
|
||||
* Category: Protocol
|
||||
* Author: M.Goldenbaum
|
||||
* Created: 16.09.20 18:27
|
||||
* Updated: -
|
||||
*
|
||||
* Description:
|
||||
* -
|
||||
*/
|
||||
|
||||
namespace Webklex\PHPIMAP\Connection\Protocols;
|
||||
|
||||
use Webklex\PHPIMAP\ClientManager;
|
||||
use Webklex\PHPIMAP\Exceptions\AuthFailedException;
|
||||
use Webklex\PHPIMAP\Exceptions\MethodNotSupportedException;
|
||||
use Webklex\PHPIMAP\Exceptions\RuntimeException;
|
||||
use Webklex\PHPIMAP\IMAP;
|
||||
|
||||
/**
|
||||
* Class LegacyProtocol
|
||||
*
|
||||
* @package Webklex\PHPIMAP\Connection\Protocols
|
||||
*/
|
||||
class LegacyProtocol extends Protocol {
|
||||
|
||||
protected $protocol = "imap";
|
||||
protected $host = null;
|
||||
protected $port = null;
|
||||
protected $encryption = null;
|
||||
|
||||
/**
|
||||
* Imap constructor.
|
||||
* @param bool $cert_validation set to false to skip SSL certificate validation
|
||||
* @param mixed $encryption Connection encryption method
|
||||
*/
|
||||
public function __construct(bool $cert_validation = true, $encryption = false) {
|
||||
$this->setCertValidation($cert_validation);
|
||||
$this->encryption = $encryption;
|
||||
}
|
||||
|
||||
/**
|
||||
* Public destructor
|
||||
*/
|
||||
public function __destruct() {
|
||||
$this->logout();
|
||||
}
|
||||
|
||||
/**
|
||||
* Save the information for a nw connection
|
||||
* @param string $host
|
||||
* @param null $port
|
||||
*/
|
||||
public function connect(string $host, $port = null) {
|
||||
if ($this->encryption) {
|
||||
$encryption = strtolower($this->encryption);
|
||||
if ($encryption == "ssl") {
|
||||
$port = $port === null ? 993 : $port;
|
||||
}
|
||||
}
|
||||
$port = $port === null ? 143 : $port;
|
||||
$this->host = $host;
|
||||
$this->port = $port;
|
||||
}
|
||||
|
||||
/**
|
||||
* Login to a new session.
|
||||
* @param string $user username
|
||||
* @param string $password password
|
||||
*
|
||||
* @return bool
|
||||
* @throws AuthFailedException
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function login(string $user, string $password): bool {
|
||||
try {
|
||||
$this->stream = \imap_open(
|
||||
$this->getAddress(),
|
||||
$user,
|
||||
$password,
|
||||
0,
|
||||
$attempts = 3,
|
||||
ClientManager::get('options.open')
|
||||
);
|
||||
} catch (\ErrorException $e) {
|
||||
$errors = \imap_errors();
|
||||
$message = $e->getMessage().'. '.implode("; ", (is_array($errors) ? $errors : array()));
|
||||
throw new AuthFailedException($message);
|
||||
}
|
||||
|
||||
if(!$this->stream) {
|
||||
$errors = \imap_errors();
|
||||
$message = implode("; ", (is_array($errors) ? $errors : array()));
|
||||
throw new AuthFailedException($message);
|
||||
}
|
||||
|
||||
$errors = \imap_errors();
|
||||
if(is_array($errors)) {
|
||||
$status = $this->examineFolder();
|
||||
if($status['exists'] !== 0) {
|
||||
$message = implode("; ", (is_array($errors) ? $errors : array()));
|
||||
throw new RuntimeException($message);
|
||||
}
|
||||
}
|
||||
|
||||
return $this->stream !== false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Authenticate your current session.
|
||||
* @param string $user username
|
||||
* @param string $token access token
|
||||
*
|
||||
* @return bool|resource
|
||||
* @throws AuthFailedException|RuntimeException
|
||||
*/
|
||||
public function authenticate(string $user, string $token): bool {
|
||||
return $this->login($user, $token);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get full address of mailbox.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getAddress(): string {
|
||||
$address = "{".$this->host.":".$this->port."/".$this->protocol;
|
||||
if (!$this->cert_validation) {
|
||||
$address .= '/novalidate-cert';
|
||||
}
|
||||
if (in_array($this->encryption,['tls', 'notls', 'ssl'])) {
|
||||
$address .= '/'.$this->encryption;
|
||||
} elseif ($this->encryption === "starttls") {
|
||||
$address .= '/tls';
|
||||
}
|
||||
|
||||
$address .= '}';
|
||||
|
||||
return $address;
|
||||
}
|
||||
|
||||
/**
|
||||
* Logout of the current session
|
||||
*
|
||||
* @return bool success
|
||||
*/
|
||||
public function logout(): bool {
|
||||
if ($this->stream) {
|
||||
$result = \imap_close($this->stream, IMAP::CL_EXPUNGE);
|
||||
$this->stream = false;
|
||||
$this->uid_cache = null;
|
||||
return $result;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the current session is connected
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function connected(): bool {
|
||||
return boolval($this->stream);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an array of available capabilities
|
||||
*
|
||||
* @throws MethodNotSupportedException
|
||||
*/
|
||||
public function getCapabilities(): array {
|
||||
throw new MethodNotSupportedException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the current folder
|
||||
* @param string $folder change to this folder
|
||||
*
|
||||
* @return bool|array see examineOrselect()
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function selectFolder(string $folder = 'INBOX') {
|
||||
$flags = IMAP::OP_READONLY;
|
||||
if (in_array($this->protocol, ["pop3", "nntp"])) {
|
||||
$flags = IMAP::NIL;
|
||||
}
|
||||
if ($this->stream === false) {
|
||||
throw new RuntimeException("failed to reopen stream.");
|
||||
}
|
||||
|
||||
\imap_reopen($this->stream, $this->getAddress().$folder, $flags, 3);
|
||||
$this->uid_cache = null;
|
||||
return $this->examineFolder($folder);
|
||||
}
|
||||
|
||||
/**
|
||||
* Examine a given folder
|
||||
* @param string $folder examine this folder
|
||||
*
|
||||
* @return bool|array
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function examineFolder(string $folder = 'INBOX') {
|
||||
if (strpos($folder, ".") === 0) {
|
||||
throw new RuntimeException("Segmentation fault prevented. Folders starts with an illegal char '.'.");
|
||||
}
|
||||
$folder = $this->getAddress().$folder;
|
||||
$status = \imap_status($this->stream, $folder, IMAP::SA_ALL);
|
||||
return [
|
||||
"flags" => [],
|
||||
"exists" => $status->messages,
|
||||
"recent" => $status->recent,
|
||||
"unseen" => $status->unseen,
|
||||
"uidnext" => $status->uidnext,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch message content
|
||||
* @param array|int $uids
|
||||
* @param string $rfc
|
||||
* @param int $uid set to IMAP::ST_UID if you pass message unique identifiers instead of numbers.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function content($uids, string $rfc = "RFC822", $uid = IMAP::ST_UID): array {
|
||||
$result = [];
|
||||
$uids = is_array($uids) ? $uids : [$uids];
|
||||
foreach ($uids as $id) {
|
||||
$result[$id] = \imap_fetchbody($this->stream, $id, "", $uid ? IMAP::ST_UID : IMAP::NIL);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch message headers
|
||||
* @param array|int $uids
|
||||
* @param string $rfc
|
||||
* @param int $uid set to IMAP::ST_UID if you pass message unique identifiers instead of numbers.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function headers($uids, string $rfc = "RFC822", $uid = IMAP::ST_UID): array {
|
||||
$result = [];
|
||||
$uids = is_array($uids) ? $uids : [$uids];
|
||||
foreach ($uids as $id) {
|
||||
$result[$id] = \imap_fetchheader($this->stream, $id, $uid ? IMAP::ST_UID : IMAP::NIL);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch message flags
|
||||
* @param array|int $uids
|
||||
* @param int $uid set to IMAP::ST_UID if you pass message unique identifiers instead of numbers.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function flags($uids, $uid = IMAP::ST_UID): array {
|
||||
$result = [];
|
||||
$uids = is_array($uids) ? $uids : [$uids];
|
||||
foreach ($uids as $id) {
|
||||
$raw_flags = \imap_fetch_overview($this->stream, $id, $uid ? IMAP::ST_UID : IMAP::NIL);
|
||||
$flags = [];
|
||||
if (is_array($raw_flags) && isset($raw_flags[0])) {
|
||||
$raw_flags = (array) $raw_flags[0];
|
||||
foreach($raw_flags as $flag => $value) {
|
||||
if ($value === 1 && in_array($flag, ["size", "uid", "msgno", "update"]) === false){
|
||||
$flags[] = "\\".ucfirst($flag);
|
||||
}
|
||||
}
|
||||
}
|
||||
$result[$uid] = $flags;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get uid for a given id
|
||||
* @param int|null $id message number
|
||||
*
|
||||
* @return array|string message number for given message or all messages as array
|
||||
*/
|
||||
public function getUid($id = null) {
|
||||
if ($id === null) {
|
||||
if ($this->enable_uid_cache && $this->uid_cache) {
|
||||
return $this->uid_cache;
|
||||
}
|
||||
|
||||
$overview = $this->overview("1:*");
|
||||
$uids = [];
|
||||
foreach($overview as $set){
|
||||
$uids[$set->msgno] = $set->uid;
|
||||
}
|
||||
|
||||
$this->setUidCache($uids);
|
||||
return $uids;
|
||||
}
|
||||
|
||||
return \imap_uid($this->stream, $id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a message number for a uid
|
||||
* @param string $id uid
|
||||
*
|
||||
* @return int message number
|
||||
*/
|
||||
public function getMessageNumber(string $id): int {
|
||||
return \imap_msgno($this->stream, $id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a message overview
|
||||
* @param string $sequence uid sequence
|
||||
* @param int $uid set to IMAP::ST_UID if you pass message unique identifiers instead of numbers.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function overview(string $sequence, $uid = IMAP::ST_UID): array {
|
||||
return \imap_fetch_overview($this->stream, $sequence,$uid ? IMAP::ST_UID : IMAP::NIL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of available folders
|
||||
* @param string $reference mailbox reference for list
|
||||
* @param string $folder mailbox name match with wildcards
|
||||
*
|
||||
* @return array folders that matched $folder as array(name => array('delimiter' => .., 'flags' => ..))
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function folders(string $reference = '', string $folder = '*'): array {
|
||||
$result = [];
|
||||
|
||||
$items = \imap_getmailboxes($this->stream, $this->getAddress(), $reference.$folder);
|
||||
if(is_array($items)){
|
||||
foreach ($items as $item) {
|
||||
$name = $this->decodeFolderName($item->name);
|
||||
$result[$name] = ['delimiter' => $item->delimiter, 'flags' => []];
|
||||
}
|
||||
}else{
|
||||
throw new RuntimeException(\imap_last_error());
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Manage flags
|
||||
* @param array $flags flags to set, add or remove - see $mode
|
||||
* @param int $from message for items or start message if $to !== null
|
||||
* @param int|null $to if null only one message ($from) is fetched, else it's the
|
||||
* last message, INF means last message available
|
||||
* @param string|null $mode '+' to add flags, '-' to remove flags, everything else sets the flags as given
|
||||
* @param bool $silent if false the return values are the new flags for the wanted messages
|
||||
* @param int $uid set to IMAP::ST_UID if you pass message unique identifiers instead of numbers.
|
||||
* @param null $item unused attribute
|
||||
*
|
||||
* @return bool|array new flags if $silent is false, else true or false depending on success
|
||||
*/
|
||||
public function store(array $flags, int $from, $to = null, $mode = null, bool $silent = true, $uid = IMAP::ST_UID, $item = null) {
|
||||
$flag = trim(is_array($flags) ? implode(" ", $flags) : $flags);
|
||||
|
||||
if ($mode == "+"){
|
||||
$status = \imap_setflag_full($this->stream, $from, $flag, $uid ? IMAP::ST_UID : IMAP::NIL);
|
||||
}else{
|
||||
$status = \imap_clearflag_full($this->stream, $from, $flag, $uid ? IMAP::ST_UID : IMAP::NIL);
|
||||
}
|
||||
|
||||
if ($silent === true) {
|
||||
return $status;
|
||||
}
|
||||
|
||||
return $this->flags($from);
|
||||
}
|
||||
|
||||
/**
|
||||
* Append a new message to given folder
|
||||
* @param string $folder name of target folder
|
||||
* @param string $message full message content
|
||||
* @param array|null $flags flags for new message
|
||||
* @param string $date date for new message
|
||||
*
|
||||
* @return bool success
|
||||
*/
|
||||
public function appendMessage(string $folder, string $message, $flags = null, $date = null): bool {
|
||||
if ($date != null) {
|
||||
if ($date instanceof \Carbon\Carbon){
|
||||
$date = $date->format('d-M-Y H:i:s O');
|
||||
}
|
||||
return \imap_append($this->stream, $folder, $message, $flags, $date);
|
||||
}
|
||||
|
||||
return \imap_append($this->stream, $folder, $message, $flags);
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy message set from current folder to other folder
|
||||
* @param string $folder destination folder
|
||||
* @param $from
|
||||
* @param int|null $to if null only one message ($from) is fetched, else it's the
|
||||
* last message, INF means last message available
|
||||
* @param int $uid set to IMAP::ST_UID if you pass message unique identifiers instead of numbers.
|
||||
*
|
||||
* @return bool success
|
||||
*/
|
||||
public function copyMessage(string $folder, $from, $to = null, $uid = IMAP::ST_UID): bool {
|
||||
return \imap_mail_copy($this->stream, $from, $folder, $uid ? IMAP::ST_UID : IMAP::NIL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy multiple messages to the target folder
|
||||
* @param array $messages List of message identifiers
|
||||
* @param string $folder Destination folder
|
||||
* @param int $uid set to IMAP::ST_UID if you pass message unique identifiers instead of numbers.
|
||||
*
|
||||
* @return array|bool Tokens if operation successful, false if an error occurred
|
||||
*/
|
||||
public function copyManyMessages(array $messages, string $folder, $uid = IMAP::ST_UID) {
|
||||
foreach($messages as $msg) {
|
||||
if (!$this->copyMessage($folder, $msg, null, $uid)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return $messages;
|
||||
}
|
||||
|
||||
/**
|
||||
* Move a message set from current folder to another folder
|
||||
* @param string $folder destination folder
|
||||
* @param $from
|
||||
* @param int|null $to if null only one message ($from) is fetched, else it's the
|
||||
* last message, INF means last message available
|
||||
* @param int $uid set to IMAP::ST_UID if you pass message unique identifiers instead of numbers.
|
||||
*
|
||||
* @return bool success
|
||||
*/
|
||||
public function moveMessage(string $folder, $from, $to = null, $uid = IMAP::ST_UID): bool {
|
||||
return \imap_mail_move($this->stream, $from, $folder, $uid ? IMAP::ST_UID : IMAP::NIL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Move multiple messages to the target folder
|
||||
* @param array $messages List of message identifiers
|
||||
* @param string $folder Destination folder
|
||||
* @param int $uid set to IMAP::ST_UID if you pass message unique identifiers instead of numbers.
|
||||
*
|
||||
* @return array|bool Tokens if operation successful, false if an error occurred
|
||||
*/
|
||||
public function moveManyMessages(array $messages, string $folder, $uid = IMAP::ST_UID) {
|
||||
foreach($messages as $msg) {
|
||||
if (!$this->moveMessage($folder, $msg, null, $uid)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return $messages;
|
||||
}
|
||||
|
||||
/**
|
||||
* Exchange identification information
|
||||
* Ref.: https://datatracker.ietf.org/doc/html/rfc2971
|
||||
*
|
||||
* @param null $ids
|
||||
* @return array|bool|void|null
|
||||
*
|
||||
* @throws MethodNotSupportedException
|
||||
*/
|
||||
public function ID($ids = null) {
|
||||
throw new MethodNotSupportedException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new folder (and parent folders if needed)
|
||||
* @param string $folder folder name
|
||||
*
|
||||
* @return bool success
|
||||
*/
|
||||
public function createFolder(string $folder): bool {
|
||||
return \imap_createmailbox($this->stream, $folder);
|
||||
}
|
||||
|
||||
/**
|
||||
* Rename an existing folder
|
||||
* @param string $old old name
|
||||
* @param string $new new name
|
||||
*
|
||||
* @return bool success
|
||||
*/
|
||||
public function renameFolder(string $old, string $new): bool {
|
||||
return \imap_renamemailbox($this->stream, $old, $new);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a folder
|
||||
* @param string $folder folder name
|
||||
*
|
||||
* @return bool success
|
||||
*/
|
||||
public function deleteFolder(string $folder): bool {
|
||||
return \imap_deletemailbox($this->stream, $folder);
|
||||
}
|
||||
|
||||
/**
|
||||
* Subscribe to a folder
|
||||
* @param string $folder folder name
|
||||
*
|
||||
* @throws MethodNotSupportedException
|
||||
*/
|
||||
public function subscribeFolder(string $folder): bool {
|
||||
throw new MethodNotSupportedException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Unsubscribe from a folder
|
||||
* @param string $folder folder name
|
||||
*
|
||||
* @throws MethodNotSupportedException
|
||||
*/
|
||||
public function unsubscribeFolder(string $folder): bool {
|
||||
throw new MethodNotSupportedException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply session saved changes to the server
|
||||
*
|
||||
* @return bool success
|
||||
*/
|
||||
public function expunge(): bool {
|
||||
return \imap_expunge($this->stream);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send noop command
|
||||
*
|
||||
* @throws MethodNotSupportedException
|
||||
*/
|
||||
public function noop(): bool {
|
||||
throw new MethodNotSupportedException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Send idle command
|
||||
*
|
||||
* @throws MethodNotSupportedException
|
||||
*/
|
||||
public function idle() {
|
||||
throw new MethodNotSupportedException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Send done command
|
||||
*
|
||||
* @throws MethodNotSupportedException
|
||||
*/
|
||||
public function done() {
|
||||
throw new MethodNotSupportedException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Search for matching messages
|
||||
* @param array $params
|
||||
* @param int $uid set to IMAP::ST_UID if you pass message unique identifiers instead of numbers.
|
||||
*
|
||||
* @return array message ids
|
||||
*/
|
||||
public function search(array $params, $uid = IMAP::ST_UID): array {
|
||||
$result = \imap_search($this->stream, $params[0], $uid ? IMAP::ST_UID : IMAP::NIL);
|
||||
if ($result === false) {
|
||||
return [];
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable the debug mode
|
||||
*/
|
||||
public function enableDebug(){
|
||||
$this->debug = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable the debug mode
|
||||
*/
|
||||
public function disableDebug(){
|
||||
$this->debug = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode name.
|
||||
* It converts UTF7-IMAP encoding to UTF-8.
|
||||
*
|
||||
* @param $name
|
||||
*
|
||||
* @return array|false|string|string[]|null
|
||||
*/
|
||||
protected function decodeFolderName($name) {
|
||||
preg_match('#\{(.*)\}(.*)#', $name, $preg);
|
||||
return mb_convert_encoding($preg[2], "UTF-8", "UTF7-IMAP");
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getProtocol(): string {
|
||||
return $this->protocol;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the quota level settings, and usage statics per mailbox
|
||||
* @param $username
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getQuota($username): array {
|
||||
return \imap_get_quota($this->stream, 'user.'.$username);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the quota settings per user
|
||||
* @param string $quota_root
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getQuotaRoot(string $quota_root = 'INBOX'): array {
|
||||
return \imap_get_quotaroot($this->stream, $quota_root);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $protocol
|
||||
* @return LegacyProtocol
|
||||
*/
|
||||
public function setProtocol(string $protocol): LegacyProtocol {
|
||||
if (($pos = strpos($protocol, "legacy")) > 0) {
|
||||
$protocol = substr($protocol, 0, ($pos + 2) * -1);
|
||||
}
|
||||
$this->protocol = $protocol;
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
285
vendor/webklex/php-imap/src/Connection/Protocols/Protocol.php
vendored
Normal file
285
vendor/webklex/php-imap/src/Connection/Protocols/Protocol.php
vendored
Normal file
@@ -0,0 +1,285 @@
|
||||
<?php
|
||||
/*
|
||||
* File: ImapProtocol.php
|
||||
* Category: Protocol
|
||||
* Author: M.Goldenbaum
|
||||
* Created: 16.09.20 18:27
|
||||
* Updated: -
|
||||
*
|
||||
* Description:
|
||||
* -
|
||||
*/
|
||||
|
||||
namespace Webklex\PHPIMAP\Connection\Protocols;
|
||||
|
||||
use Webklex\PHPIMAP\Exceptions\ConnectionFailedException;
|
||||
use Webklex\PHPIMAP\IMAP;
|
||||
|
||||
/**
|
||||
* Class Protocol
|
||||
*
|
||||
* @package Webklex\PHPIMAP\Connection\Protocols
|
||||
*/
|
||||
abstract class Protocol implements ProtocolInterface {
|
||||
|
||||
/**
|
||||
* Default connection timeout in seconds
|
||||
*/
|
||||
protected $connection_timeout = 30;
|
||||
|
||||
/**
|
||||
* @var boolean
|
||||
*/
|
||||
protected $debug = false;
|
||||
|
||||
/**
|
||||
* @var boolean
|
||||
*/
|
||||
protected $enable_uid_cache = true;
|
||||
|
||||
/**
|
||||
* @var false|\IMAP\Connection|resource
|
||||
*/
|
||||
public $stream = false;
|
||||
|
||||
/**
|
||||
* Connection encryption method
|
||||
* @var mixed $encryption
|
||||
*/
|
||||
protected $encryption = false;
|
||||
|
||||
/**
|
||||
* Set to false to ignore SSL certificate validation
|
||||
* @var bool
|
||||
*/
|
||||
protected $cert_validation = true;
|
||||
|
||||
/**
|
||||
* Proxy settings
|
||||
* @var array
|
||||
*/
|
||||
protected $proxy = [
|
||||
'socket' => null,
|
||||
'request_fulluri' => false,
|
||||
'username' => null,
|
||||
'password' => null,
|
||||
];
|
||||
|
||||
/**
|
||||
* Cache for uid of active folder.
|
||||
*
|
||||
* @var null|array
|
||||
*/
|
||||
protected $uid_cache = null;
|
||||
|
||||
/**
|
||||
* Get an available cryptographic method
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getCryptoMethod() {
|
||||
// Allow the best TLS version(s) we can
|
||||
$cryptoMethod = STREAM_CRYPTO_METHOD_TLS_CLIENT;
|
||||
|
||||
// PHP 5.6.7 dropped inclusion of TLS 1.1 and 1.2 in STREAM_CRYPTO_METHOD_TLS_CLIENT
|
||||
// so add them back in manually if we can
|
||||
if (defined('STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT')) {
|
||||
$cryptoMethod = STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT;
|
||||
}elseif (defined('STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT')) {
|
||||
$cryptoMethod = STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT;
|
||||
}
|
||||
|
||||
return $cryptoMethod;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable SSL certificate validation
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function enableCertValidation() {
|
||||
$this->cert_validation = true;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable SSL certificate validation
|
||||
* @return $this
|
||||
*/
|
||||
public function disableCertValidation() {
|
||||
$this->cert_validation = false;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set SSL certificate validation
|
||||
* @var int $cert_validation
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setCertValidation($cert_validation) {
|
||||
$this->cert_validation = $cert_validation;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Should we validate SSL certificate?
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function getCertValidation() {
|
||||
return $this->cert_validation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set connection proxy settings
|
||||
* @var array $options
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setProxy($options) {
|
||||
foreach ($this->proxy as $key => $val) {
|
||||
if (isset($options[$key])) {
|
||||
$this->proxy[$key] = $options[$key];
|
||||
}
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current proxy settings
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getProxy() {
|
||||
return $this->proxy;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare socket options
|
||||
* @var string $transport
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function defaultSocketOptions($transport) {
|
||||
$options = [];
|
||||
if ($this->encryption != false) {
|
||||
$options["ssl"] = [
|
||||
'verify_peer_name' => $this->getCertValidation(),
|
||||
'verify_peer' => $this->getCertValidation(),
|
||||
];
|
||||
}
|
||||
|
||||
if ($this->proxy["socket"] != null) {
|
||||
$options[$transport]["proxy"] = $this->proxy["socket"];
|
||||
$options[$transport]["request_fulluri"] = $this->proxy["request_fulluri"];
|
||||
|
||||
if ($this->proxy["username"] != null) {
|
||||
$auth = base64_encode($this->proxy["username"].':'.$this->proxy["password"]);
|
||||
|
||||
$options[$transport]["header"] = [
|
||||
"Proxy-Authorization: Basic $auth"
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
return $options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new resource stream
|
||||
* @param $transport
|
||||
* @param string $host hostname or IP address of IMAP server
|
||||
* @param int $port of IMAP server, default is 143 (993 for ssl)
|
||||
* @param int $timeout timeout in seconds for initiating session
|
||||
*
|
||||
* @return resource|boolean The socket created.
|
||||
* @throws ConnectionFailedException
|
||||
*/
|
||||
protected function createStream($transport, $host, $port, $timeout) {
|
||||
$socket = "$transport://$host:$port";
|
||||
$stream = stream_socket_client($socket, $errno, $errstr, $timeout,
|
||||
STREAM_CLIENT_CONNECT,
|
||||
stream_context_create($this->defaultSocketOptions($transport))
|
||||
);
|
||||
|
||||
if (!$stream) {
|
||||
throw new ConnectionFailedException($errstr, $errno);
|
||||
}
|
||||
|
||||
if (false === stream_set_timeout($stream, $timeout)) {
|
||||
throw new ConnectionFailedException('Failed to set stream timeout');
|
||||
}
|
||||
|
||||
return $stream;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getConnectionTimeout() {
|
||||
return $this->connection_timeout;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $connection_timeout
|
||||
* @return Protocol
|
||||
*/
|
||||
public function setConnectionTimeout($connection_timeout) {
|
||||
if ($connection_timeout !== null) {
|
||||
$this->connection_timeout = $connection_timeout;
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the UID key string
|
||||
* @param int|string $uid
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getUIDKey($uid) {
|
||||
if ($uid == IMAP::ST_UID || $uid == IMAP::FT_UID) {
|
||||
return "UID";
|
||||
}
|
||||
if (strlen($uid) > 0 && !is_numeric($uid)) {
|
||||
return (string)$uid;
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
public function buildUIDCommand($command, $uid) {
|
||||
return trim($this->getUIDKey($uid)." ".$command);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the uid cache of current active folder
|
||||
*
|
||||
* @param array|null $uids
|
||||
*/
|
||||
public function setUidCache($uids) {
|
||||
if (is_null($uids)) {
|
||||
$this->uid_cache = null;
|
||||
return;
|
||||
}
|
||||
|
||||
$messageNumber = 1;
|
||||
|
||||
$uid_cache = [];
|
||||
foreach ($uids as $uid) {
|
||||
$uid_cache[$messageNumber++] = $uid;
|
||||
}
|
||||
|
||||
$this->uid_cache = $uid_cache;
|
||||
}
|
||||
|
||||
public function enableUidCache() {
|
||||
$this->enable_uid_cache = true;
|
||||
}
|
||||
|
||||
public function disableUidCache() {
|
||||
$this->enable_uid_cache = false;
|
||||
}
|
||||
}
|
||||
408
vendor/webklex/php-imap/src/Connection/Protocols/ProtocolInterface.php
vendored
Normal file
408
vendor/webklex/php-imap/src/Connection/Protocols/ProtocolInterface.php
vendored
Normal file
@@ -0,0 +1,408 @@
|
||||
<?php
|
||||
/*
|
||||
* File: ImapProtocol.php
|
||||
* Category: Protocol
|
||||
* Author: M.Goldenbaum
|
||||
* Created: 16.09.20 18:27
|
||||
* Updated: -
|
||||
*
|
||||
* Description:
|
||||
* -
|
||||
*/
|
||||
|
||||
namespace Webklex\PHPIMAP\Connection\Protocols;
|
||||
|
||||
use ErrorException;
|
||||
use Webklex\PHPIMAP\Client;
|
||||
use Webklex\PHPIMAP\Exceptions\AuthFailedException;
|
||||
use Webklex\PHPIMAP\Exceptions\ConnectionFailedException;
|
||||
use Webklex\PHPIMAP\Exceptions\InvalidMessageDateException;
|
||||
use Webklex\PHPIMAP\Exceptions\MessageNotFoundException;
|
||||
use Webklex\PHPIMAP\Exceptions\RuntimeException;
|
||||
use Webklex\PHPIMAP\IMAP;
|
||||
|
||||
/**
|
||||
* Interface ProtocolInterface
|
||||
*
|
||||
* @package Webklex\PHPIMAP\Connection\Protocols
|
||||
*/
|
||||
interface ProtocolInterface {
|
||||
|
||||
/**
|
||||
* Public destructor
|
||||
*/
|
||||
public function __destruct();
|
||||
|
||||
/**
|
||||
* Open a new connection / session
|
||||
* @param string $host hostname or IP address of IMAP server
|
||||
* @param int|null $port of service server
|
||||
*
|
||||
* @throws ErrorException
|
||||
* @throws ConnectionFailedException
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function connect(string $host, $port = null);
|
||||
|
||||
/**
|
||||
* Login to a new session.
|
||||
*
|
||||
* @param string $user username
|
||||
* @param string $password password
|
||||
* @return bool success
|
||||
* @throws AuthFailedException
|
||||
*/
|
||||
public function login(string $user, string $password): bool;
|
||||
|
||||
/**
|
||||
* Authenticate your current session.
|
||||
* @param string $user username
|
||||
* @param string $token access token
|
||||
*
|
||||
* @return bool|mixed
|
||||
* @throws AuthFailedException
|
||||
*/
|
||||
public function authenticate(string $user, string $token);
|
||||
|
||||
/**
|
||||
* Logout of the current server session
|
||||
*
|
||||
* @return bool success
|
||||
*/
|
||||
public function logout(): bool;
|
||||
|
||||
/**
|
||||
* Check if the current session is connected
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function connected(): bool;
|
||||
|
||||
/**
|
||||
* Get an array of available capabilities
|
||||
*
|
||||
* @return array list of capabilities
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function getCapabilities(): array;
|
||||
|
||||
/**
|
||||
* Change the current folder
|
||||
*
|
||||
* @param string $folder change to this folder
|
||||
* @return bool|array see examineOrSelect()
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function selectFolder(string $folder = 'INBOX');
|
||||
|
||||
/**
|
||||
* Examine a given folder
|
||||
*
|
||||
* @param string $folder
|
||||
* @return bool|array
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function examineFolder(string $folder = 'INBOX');
|
||||
|
||||
/**
|
||||
* Fetch message headers
|
||||
* @param array|int $uids
|
||||
* @param string $rfc
|
||||
* @param int|string $uid set to IMAP::ST_UID or any string representing the UID - set to IMAP::ST_MSGN to use
|
||||
* message numbers instead.
|
||||
*
|
||||
* @return array
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function content($uids, string $rfc = "RFC822", $uid = IMAP::ST_UID): array;
|
||||
|
||||
/**
|
||||
* Fetch message headers
|
||||
* @param array|int $uids
|
||||
* @param string $rfc
|
||||
* @param int|string $uid set to IMAP::ST_UID or any string representing the UID - set to IMAP::ST_MSGN to use
|
||||
* message numbers instead.
|
||||
*
|
||||
* @return array
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function headers($uids, string $rfc = "RFC822", $uid = IMAP::ST_UID): array;
|
||||
|
||||
/**
|
||||
* Fetch message flags
|
||||
* @param array|int $uids
|
||||
* @param int|string $uid set to IMAP::ST_UID or any string representing the UID - set to IMAP::ST_MSGN to use
|
||||
* message numbers instead.
|
||||
*
|
||||
* @return array
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function flags($uids, $uid = IMAP::ST_UID): array;
|
||||
|
||||
/**
|
||||
* Get uid for a given id
|
||||
* @param int|null $id message number
|
||||
*
|
||||
* @return array|string message number for given message or all messages as array
|
||||
* @throws MessageNotFoundException
|
||||
*/
|
||||
public function getUid($id = null);
|
||||
|
||||
/**
|
||||
* Get a message number for a uid
|
||||
* @param string $id uid
|
||||
*
|
||||
* @return int message number
|
||||
* @throws MessageNotFoundException
|
||||
*/
|
||||
public function getMessageNumber(string $id): int;
|
||||
|
||||
/**
|
||||
* Get a list of available folders
|
||||
* @param string $reference mailbox reference for list
|
||||
* @param string $folder mailbox / folder name match with wildcards
|
||||
*
|
||||
* @return array mailboxes that matched $folder as array(globalName => array('delim' => .., 'flags' => ..))
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function folders(string $reference = '', string $folder = '*'): array;
|
||||
|
||||
/**
|
||||
* Set message flags
|
||||
* @param array $flags flags to set, add or remove
|
||||
* @param int $from message for items or start message if $to !== null
|
||||
* @param int|null $to if null only one message ($from) is fetched, else it's the
|
||||
* last message, INF means last message available
|
||||
* @param string|null $mode '+' to add flags, '-' to remove flags, everything else sets the flags as given
|
||||
* @param bool $silent if false the return values are the new flags for the wanted messages
|
||||
* @param int|string $uid set to IMAP::ST_UID or any string representing the UID - set to IMAP::ST_MSGN to use
|
||||
* message numbers instead.
|
||||
* @param null|string $item command used to store a flag
|
||||
*
|
||||
* @return bool|array new flags if $silent is false, else true or false depending on success
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function store(array $flags, int $from, $to = null, $mode = null, bool $silent = true, $uid = IMAP::ST_UID, $item = null);
|
||||
|
||||
/**
|
||||
* Append a new message to given folder
|
||||
* @param string $folder name of target folder
|
||||
* @param string $message full message content
|
||||
* @param array|null $flags flags for new message
|
||||
* @param string|null $date date for new message
|
||||
*
|
||||
* @return bool success
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function appendMessage(string $folder, string $message, $flags = null, $date = null): bool;
|
||||
|
||||
/**
|
||||
* Copy message set from current folder to other folder
|
||||
*
|
||||
* @param string $folder destination folder
|
||||
* @param $from
|
||||
* @param int|null $to if null only one message ($from) is fetched, else it's the
|
||||
* last message, INF means last message available
|
||||
* @param int|string $uid set to IMAP::ST_UID or any string representing the UID - set to IMAP::ST_MSGN to use
|
||||
* message numbers instead.
|
||||
*
|
||||
* @return bool success
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function copyMessage(string $folder, $from, $to = null, $uid = IMAP::ST_UID): bool;
|
||||
|
||||
/**
|
||||
* Copy multiple messages to the target folder
|
||||
* @param array<string> $messages List of message identifiers
|
||||
* @param string $folder Destination folder
|
||||
* @param int|string $uid set to IMAP::ST_UID or any string representing the UID - set to IMAP::ST_MSGN to use
|
||||
* message numbers instead.
|
||||
*
|
||||
* @return array|bool Tokens if operation successful, false if an error occurred
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function copyManyMessages(array $messages, string $folder, $uid = IMAP::ST_UID);
|
||||
|
||||
/**
|
||||
* Move a message set from current folder to another folder
|
||||
* @param string $folder destination folder
|
||||
* @param $from
|
||||
* @param int|null $to if null only one message ($from) is fetched, else it's the
|
||||
* last message, INF means last message available
|
||||
* @param int|string $uid set to IMAP::ST_UID or any string representing the UID - set to IMAP::ST_MSGN to use
|
||||
* message numbers instead.
|
||||
*
|
||||
* @return bool success
|
||||
*/
|
||||
public function moveMessage(string $folder, $from, $to = null, $uid = IMAP::ST_UID): bool;
|
||||
|
||||
/**
|
||||
* Move multiple messages to the target folder
|
||||
*
|
||||
* @param array<string> $messages List of message identifiers
|
||||
* @param string $folder Destination folder
|
||||
* @param int|string $uid set to IMAP::ST_UID or any string representing the UID - set to IMAP::ST_MSGN to use
|
||||
* message numbers instead.
|
||||
*
|
||||
* @return array|bool Tokens if operation successful, false if an error occurred
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function moveManyMessages(array $messages, string $folder, $uid = IMAP::ST_UID);
|
||||
|
||||
/**
|
||||
* Exchange identification information
|
||||
* Ref.: https://datatracker.ietf.org/doc/html/rfc2971
|
||||
*
|
||||
* @param null $ids
|
||||
* @return array|bool|void|null
|
||||
*
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function ID($ids = null);
|
||||
|
||||
/**
|
||||
* Create a new folder
|
||||
*
|
||||
* @param string $folder folder name
|
||||
* @return bool success
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function createFolder(string $folder): bool;
|
||||
|
||||
/**
|
||||
* Rename an existing folder
|
||||
*
|
||||
* @param string $old old name
|
||||
* @param string $new new name
|
||||
* @return bool success
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function renameFolder(string $old, string $new): bool;
|
||||
|
||||
/**
|
||||
* Delete a folder
|
||||
*
|
||||
* @param string $folder folder name
|
||||
* @return bool success
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function deleteFolder(string $folder): bool;
|
||||
|
||||
/**
|
||||
* Subscribe to a folder
|
||||
*
|
||||
* @param string $folder folder name
|
||||
* @return bool success
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function subscribeFolder(string $folder): bool;
|
||||
|
||||
/**
|
||||
* Unsubscribe from a folder
|
||||
* @param string $folder folder name
|
||||
*
|
||||
* @return bool success
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function unsubscribeFolder(string $folder): bool;
|
||||
|
||||
/**
|
||||
* Send idle command
|
||||
*
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function idle();
|
||||
|
||||
/**
|
||||
* Send done command
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function done();
|
||||
|
||||
/**
|
||||
* Apply session saved changes to the server
|
||||
*
|
||||
* @return bool success
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function expunge(): bool;
|
||||
|
||||
/**
|
||||
* Retrieve the quota level settings, and usage statics per mailbox
|
||||
* @param $username
|
||||
*
|
||||
* @return array
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function getQuota($username): array;
|
||||
|
||||
/**
|
||||
* Retrieve the quota settings per user
|
||||
*
|
||||
* @param string $quota_root
|
||||
*
|
||||
* @return array
|
||||
* @throws ConnectionFailedException
|
||||
*/
|
||||
public function getQuotaRoot(string $quota_root = 'INBOX'): array;
|
||||
|
||||
/**
|
||||
* Send noop command
|
||||
*
|
||||
* @return bool success
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function noop(): bool;
|
||||
|
||||
/**
|
||||
* Do a search request
|
||||
*
|
||||
* @param array $params
|
||||
* @param int|string $uid set to IMAP::ST_UID or any string representing the UID - set to IMAP::ST_MSGN to use
|
||||
* message numbers instead.
|
||||
*
|
||||
* @return array message ids
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function search(array $params, $uid = IMAP::ST_UID): array;
|
||||
|
||||
/**
|
||||
* Get a message overview
|
||||
* @param string $sequence uid sequence
|
||||
* @param int|string $uid set to IMAP::ST_UID or any string representing the UID - set to IMAP::ST_MSGN to use
|
||||
* message numbers instead.
|
||||
*
|
||||
* @return array
|
||||
* @throws RuntimeException
|
||||
* @throws MessageNotFoundException
|
||||
* @throws InvalidMessageDateException
|
||||
*/
|
||||
public function overview(string $sequence, $uid = IMAP::ST_UID): array;
|
||||
|
||||
/**
|
||||
* Enable the debug mode
|
||||
*/
|
||||
public function enableDebug();
|
||||
|
||||
/**
|
||||
* Disable the debug mode
|
||||
*/
|
||||
public function disableDebug();
|
||||
|
||||
/**
|
||||
* Enable uid caching
|
||||
*/
|
||||
public function enableUidCache();
|
||||
|
||||
/**
|
||||
* Disable uid caching
|
||||
*/
|
||||
public function disableUidCache();
|
||||
|
||||
/**
|
||||
* Set the uid cache of current active folder
|
||||
*
|
||||
* @param array|null $uids
|
||||
*/
|
||||
public function setUidCache($uids);
|
||||
}
|
||||
482
vendor/webklex/php-imap/src/EncodingAliases.php
vendored
Normal file
482
vendor/webklex/php-imap/src/EncodingAliases.php
vendored
Normal file
@@ -0,0 +1,482 @@
|
||||
<?php
|
||||
/*
|
||||
* File: EncodingAliases.php
|
||||
* Category: -
|
||||
* Author: S. Todorov (https://github.com/todorowww)
|
||||
* Created: 23.04.18 14:16
|
||||
* Updated: -
|
||||
*
|
||||
* Description:
|
||||
* Contains email encoding aliases, thta can occur when fetching emails. These sometimes can break icvon()
|
||||
* This file attempts to correct this by using a list of aliases and their mappings to supported iconv() encodings
|
||||
*/
|
||||
|
||||
namespace Webklex\PHPIMAP;
|
||||
|
||||
/**
|
||||
* Class EncodingAliases
|
||||
*
|
||||
* @package Webklex\PHPIMAP
|
||||
*/
|
||||
class EncodingAliases {
|
||||
|
||||
/**
|
||||
* Contains email encoding mappings
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private static $aliases = [
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Email encoding aliases
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Email encoding aliases used to convert to iconv supported charsets
|
||||
|
|
||||
|
|
||||
| This Source Code Form is subject to the terms of the Mozilla Public
|
||||
| License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
| file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
|
||||
| This Original Code has been modified by IBM Corporation.
|
||||
| Modifications made by IBM described herein are
|
||||
| Copyright (c) International Business Machines
|
||||
| Corporation, 1999
|
||||
|
|
||||
| Modifications to Mozilla code or documentation
|
||||
| identified per MPL Section 3.3
|
||||
|
|
||||
| Date Modified by Description of modification
|
||||
| 12/09/1999 IBM Corp. Support for IBM codepages - 850,852,855,857,862,864
|
||||
|
|
||||
| Rule of this file:
|
||||
| 1. key should always be in lower case ascii so we can do case insensitive
|
||||
| comparison in the code faster.
|
||||
| 2. value should be the one used in unicode converter
|
||||
|
|
||||
| 3. If the charset is not used for document charset, but font charset
|
||||
| (e.g. XLFD charset- such as JIS x0201, JIS x0208), don't put here
|
||||
|
|
||||
*/
|
||||
"ascii" => "us-ascii",
|
||||
"us-ascii" => "us-ascii",
|
||||
"ansi_x3.4-1968" => "us-ascii",
|
||||
"646" => "us-ascii",
|
||||
"iso-8859-1" => "ISO-8859-1",
|
||||
"iso-8859-2" => "ISO-8859-2",
|
||||
"iso-8859-3" => "ISO-8859-3",
|
||||
"iso-8859-4" => "ISO-8859-4",
|
||||
"iso-8859-5" => "ISO-8859-5",
|
||||
"iso-8859-6" => "ISO-8859-6",
|
||||
"iso-8859-6-i" => "ISO-8859-6-I",
|
||||
"iso-8859-6-e" => "ISO-8859-6-E",
|
||||
"iso-8859-7" => "ISO-8859-7",
|
||||
"iso-8859-8" => "ISO-8859-8",
|
||||
"iso-8859-8-i" => "ISO-8859-8-I",
|
||||
"iso-8859-8-e" => "ISO-8859-8-E",
|
||||
"iso-8859-9" => "ISO-8859-9",
|
||||
"iso-8859-10" => "ISO-8859-10",
|
||||
"iso-8859-11" => "ISO-8859-11",
|
||||
"iso-8859-13" => "ISO-8859-13",
|
||||
"iso-8859-14" => "ISO-8859-14",
|
||||
"iso-8859-15" => "ISO-8859-15",
|
||||
"iso-8859-16" => "ISO-8859-16",
|
||||
"iso-ir-111" => "ISO-IR-111",
|
||||
"iso-2022-cn" => "ISO-2022-CN",
|
||||
"iso-2022-cn-ext" => "ISO-2022-CN",
|
||||
"iso-2022-kr" => "ISO-2022-KR",
|
||||
"iso-2022-jp" => "ISO-2022-JP",
|
||||
"utf-16be" => "UTF-16BE",
|
||||
"utf-16le" => "UTF-16LE",
|
||||
"utf-16" => "UTF-16",
|
||||
"windows-1250" => "windows-1250",
|
||||
"windows-1251" => "windows-1251",
|
||||
"windows-1252" => "windows-1252",
|
||||
"windows-1253" => "windows-1253",
|
||||
"windows-1254" => "windows-1254",
|
||||
"windows-1255" => "windows-1255",
|
||||
"windows-1256" => "windows-1256",
|
||||
"windows-1257" => "windows-1257",
|
||||
"windows-1258" => "windows-1258",
|
||||
"ibm866" => "IBM866",
|
||||
"ibm850" => "IBM850",
|
||||
"ibm852" => "IBM852",
|
||||
"ibm855" => "IBM855",
|
||||
"ibm857" => "IBM857",
|
||||
"ibm862" => "IBM862",
|
||||
"ibm864" => "IBM864",
|
||||
"utf-8" => "UTF-8",
|
||||
"utf-7" => "UTF-7",
|
||||
"shift_jis" => "Shift_JIS",
|
||||
"big5" => "Big5",
|
||||
"euc-jp" => "EUC-JP",
|
||||
"euc-kr" => "EUC-KR",
|
||||
"gb2312" => "GB2312",
|
||||
"gb18030" => "gb18030",
|
||||
"viscii" => "VISCII",
|
||||
"koi8-r" => "KOI8-R",
|
||||
"koi8_r" => "KOI8-R",
|
||||
"cskoi8r" => "KOI8-R",
|
||||
"koi" => "KOI8-R",
|
||||
"koi8" => "KOI8-R",
|
||||
"koi8-u" => "KOI8-U",
|
||||
"tis-620" => "TIS-620",
|
||||
"t.61-8bit" => "T.61-8bit",
|
||||
"hz-gb-2312" => "HZ-GB-2312",
|
||||
"big5-hkscs" => "Big5-HKSCS",
|
||||
"gbk" => "gbk",
|
||||
"cns11643" => "x-euc-tw",
|
||||
//
|
||||
// Aliases for ISO-8859-1
|
||||
//
|
||||
"latin1" => "ISO-8859-1",
|
||||
"iso_8859-1" => "ISO-8859-1",
|
||||
"iso8859-1" => "ISO-8859-1",
|
||||
"iso8859-2" => "ISO-8859-2",
|
||||
"iso8859-3" => "ISO-8859-3",
|
||||
"iso8859-4" => "ISO-8859-4",
|
||||
"iso8859-5" => "ISO-8859-5",
|
||||
"iso8859-6" => "ISO-8859-6",
|
||||
"iso8859-7" => "ISO-8859-7",
|
||||
"iso8859-8" => "ISO-8859-8",
|
||||
"iso8859-9" => "ISO-8859-9",
|
||||
"iso8859-10" => "ISO-8859-10",
|
||||
"iso8859-11" => "ISO-8859-11",
|
||||
"iso8859-13" => "ISO-8859-13",
|
||||
"iso8859-14" => "ISO-8859-14",
|
||||
"iso8859-15" => "ISO-8859-15",
|
||||
"iso_8859-1:1987" => "ISO-8859-1",
|
||||
"iso-ir-100" => "ISO-8859-1",
|
||||
"l1" => "ISO-8859-1",
|
||||
"ibm819" => "ISO-8859-1",
|
||||
"cp819" => "ISO-8859-1",
|
||||
"csisolatin1" => "ISO-8859-1",
|
||||
//
|
||||
// Aliases for ISO-8859-2
|
||||
//
|
||||
"latin2" => "ISO-8859-2",
|
||||
"iso_8859-2" => "ISO-8859-2",
|
||||
"iso_8859-2:1987" => "ISO-8859-2",
|
||||
"iso-ir-101" => "ISO-8859-2",
|
||||
"l2" => "ISO-8859-2",
|
||||
"csisolatin2" => "ISO-8859-2",
|
||||
//
|
||||
// Aliases for ISO-8859-3
|
||||
//
|
||||
"latin3" => "ISO-8859-3",
|
||||
"iso_8859-3" => "ISO-8859-3",
|
||||
"iso_8859-3:1988" => "ISO-8859-3",
|
||||
"iso-ir-109" => "ISO-8859-3",
|
||||
"l3" => "ISO-8859-3",
|
||||
"csisolatin3" => "ISO-8859-3",
|
||||
//
|
||||
// Aliases for ISO-8859-4
|
||||
//
|
||||
"latin4" => "ISO-8859-4",
|
||||
"iso_8859-4" => "ISO-8859-4",
|
||||
"iso_8859-4:1988" => "ISO-8859-4",
|
||||
"iso-ir-110" => "ISO-8859-4",
|
||||
"l4" => "ISO-8859-4",
|
||||
"csisolatin4" => "ISO-8859-4",
|
||||
//
|
||||
// Aliases for ISO-8859-5
|
||||
//
|
||||
"cyrillic" => "ISO-8859-5",
|
||||
"iso_8859-5" => "ISO-8859-5",
|
||||
"iso_8859-5:1988" => "ISO-8859-5",
|
||||
"iso-ir-144" => "ISO-8859-5",
|
||||
"csisolatincyrillic" => "ISO-8859-5",
|
||||
//
|
||||
// Aliases for ISO-8859-6
|
||||
//
|
||||
"arabic" => "ISO-8859-6",
|
||||
"iso_8859-6" => "ISO-8859-6",
|
||||
"iso_8859-6:1987" => "ISO-8859-6",
|
||||
"iso-ir-127" => "ISO-8859-6",
|
||||
"ecma-114" => "ISO-8859-6",
|
||||
"asmo-708" => "ISO-8859-6",
|
||||
"csisolatinarabic" => "ISO-8859-6",
|
||||
//
|
||||
// Aliases for ISO-8859-6-I
|
||||
//
|
||||
"csiso88596i" => "ISO-8859-6-I",
|
||||
//
|
||||
// Aliases for ISO-8859-6-E",
|
||||
//
|
||||
"csiso88596e" => "ISO-8859-6-E",
|
||||
//
|
||||
// Aliases for ISO-8859-7",
|
||||
//
|
||||
"greek" => "ISO-8859-7",
|
||||
"greek8" => "ISO-8859-7",
|
||||
"sun_eu_greek" => "ISO-8859-7",
|
||||
"iso_8859-7" => "ISO-8859-7",
|
||||
"iso_8859-7:1987" => "ISO-8859-7",
|
||||
"iso-ir-126" => "ISO-8859-7",
|
||||
"elot_928" => "ISO-8859-7",
|
||||
"ecma-118" => "ISO-8859-7",
|
||||
"csisolatingreek" => "ISO-8859-7",
|
||||
//
|
||||
// Aliases for ISO-8859-8",
|
||||
//
|
||||
"hebrew" => "ISO-8859-8",
|
||||
"iso_8859-8" => "ISO-8859-8",
|
||||
"visual" => "ISO-8859-8",
|
||||
"iso_8859-8:1988" => "ISO-8859-8",
|
||||
"iso-ir-138" => "ISO-8859-8",
|
||||
"csisolatinhebrew" => "ISO-8859-8",
|
||||
//
|
||||
// Aliases for ISO-8859-8-I",
|
||||
//
|
||||
"csiso88598i" => "ISO-8859-8-I",
|
||||
"iso-8859-8i" => "ISO-8859-8-I",
|
||||
"logical" => "ISO-8859-8-I",
|
||||
//
|
||||
// Aliases for ISO-8859-8-E",
|
||||
//
|
||||
"csiso88598e" => "ISO-8859-8-E",
|
||||
//
|
||||
// Aliases for ISO-8859-9",
|
||||
//
|
||||
"latin5" => "ISO-8859-9",
|
||||
"iso_8859-9" => "ISO-8859-9",
|
||||
"iso_8859-9:1989" => "ISO-8859-9",
|
||||
"iso-ir-148" => "ISO-8859-9",
|
||||
"l5" => "ISO-8859-9",
|
||||
"csisolatin5" => "ISO-8859-9",
|
||||
//
|
||||
// Aliases for UTF-8",
|
||||
//
|
||||
"unicode-1-1-utf-8" => "UTF-8",
|
||||
// nl_langinfo(CODESET) in HP/UX returns 'utf8' under UTF-8 locales",
|
||||
"utf8" => "UTF-8",
|
||||
//
|
||||
// Aliases for Shift_JIS",
|
||||
//
|
||||
"x-sjis" => "Shift_JIS",
|
||||
"shift-jis" => "Shift_JIS",
|
||||
"ms_kanji" => "Shift_JIS",
|
||||
"csshiftjis" => "Shift_JIS",
|
||||
"windows-31j" => "Shift_JIS",
|
||||
"cp932" => "Shift_JIS",
|
||||
"sjis" => "Shift_JIS",
|
||||
//
|
||||
// Aliases for EUC_JP",
|
||||
//
|
||||
"cseucpkdfmtjapanese" => "EUC-JP",
|
||||
"x-euc-jp" => "EUC-JP",
|
||||
//
|
||||
// Aliases for ISO-2022-JP",
|
||||
//
|
||||
"csiso2022jp" => "ISO-2022-JP",
|
||||
// The following are really not aliases ISO-2022-JP, but sharing the same decoder",
|
||||
"iso-2022-jp-2" => "ISO-2022-JP",
|
||||
"csiso2022jp2" => "ISO-2022-JP",
|
||||
//
|
||||
// Aliases for Big5",
|
||||
//
|
||||
"csbig5" => "Big5",
|
||||
"cn-big5" => "Big5",
|
||||
// x-x-big5 is not really a alias for Big5, add it only for MS FrontPage",
|
||||
"x-x-big5" => "Big5",
|
||||
// Sun Solaris",
|
||||
"zh_tw-big5" => "Big5",
|
||||
//
|
||||
// Aliases for EUC-KR",
|
||||
//
|
||||
"cseuckr" => "EUC-KR",
|
||||
"ks_c_5601-1987" => "EUC-KR",
|
||||
"iso-ir-149" => "EUC-KR",
|
||||
"ks_c_5601-1989" => "EUC-KR",
|
||||
"ksc_5601" => "EUC-KR",
|
||||
"ksc5601" => "EUC-KR",
|
||||
"korean" => "EUC-KR",
|
||||
"csksc56011987" => "EUC-KR",
|
||||
"5601" => "EUC-KR",
|
||||
"windows-949" => "EUC-KR",
|
||||
//
|
||||
// Aliases for GB2312",
|
||||
//
|
||||
// The following are really not aliases GB2312, add them only for MS FrontPage",
|
||||
"gb_2312-80" => "GB2312",
|
||||
"iso-ir-58" => "GB2312",
|
||||
"chinese" => "GB2312",
|
||||
"csiso58gb231280" => "GB2312",
|
||||
"csgb2312" => "GB2312",
|
||||
"zh_cn.euc" => "GB2312",
|
||||
// Sun Solaris",
|
||||
"gb_2312" => "GB2312",
|
||||
//
|
||||
// Aliases for windows-125x ",
|
||||
//
|
||||
"x-cp1250" => "windows-1250",
|
||||
"x-cp1251" => "windows-1251",
|
||||
"x-cp1252" => "windows-1252",
|
||||
"x-cp1253" => "windows-1253",
|
||||
"x-cp1254" => "windows-1254",
|
||||
"x-cp1255" => "windows-1255",
|
||||
"x-cp1256" => "windows-1256",
|
||||
"x-cp1257" => "windows-1257",
|
||||
"x-cp1258" => "windows-1258",
|
||||
//
|
||||
// Aliases for windows-874 ",
|
||||
//
|
||||
"windows-874" => "windows-874",
|
||||
"ibm874" => "windows-874",
|
||||
"dos-874" => "windows-874",
|
||||
//
|
||||
// Aliases for macintosh",
|
||||
//
|
||||
"macintosh" => "macintosh",
|
||||
"x-mac-roman" => "macintosh",
|
||||
"mac" => "macintosh",
|
||||
"csmacintosh" => "macintosh",
|
||||
//
|
||||
// Aliases for IBM866",
|
||||
//
|
||||
"cp866" => "IBM866",
|
||||
"cp-866" => "IBM866",
|
||||
"866" => "IBM866",
|
||||
"csibm866" => "IBM866",
|
||||
//
|
||||
// Aliases for IBM850",
|
||||
//
|
||||
"cp850" => "IBM850",
|
||||
"850" => "IBM850",
|
||||
"csibm850" => "IBM850",
|
||||
//
|
||||
// Aliases for IBM852",
|
||||
//
|
||||
"cp852" => "IBM852",
|
||||
"852" => "IBM852",
|
||||
"csibm852" => "IBM852",
|
||||
//
|
||||
// Aliases for IBM855",
|
||||
//
|
||||
"cp855" => "IBM855",
|
||||
"855" => "IBM855",
|
||||
"csibm855" => "IBM855",
|
||||
//
|
||||
// Aliases for IBM857",
|
||||
//
|
||||
"cp857" => "IBM857",
|
||||
"857" => "IBM857",
|
||||
"csibm857" => "IBM857",
|
||||
//
|
||||
// Aliases for IBM862",
|
||||
//
|
||||
"cp862" => "IBM862",
|
||||
"862" => "IBM862",
|
||||
"csibm862" => "IBM862",
|
||||
//
|
||||
// Aliases for IBM864",
|
||||
//
|
||||
"cp864" => "IBM864",
|
||||
"864" => "IBM864",
|
||||
"csibm864" => "IBM864",
|
||||
"ibm-864" => "IBM864",
|
||||
//
|
||||
// Aliases for T.61-8bit",
|
||||
//
|
||||
"t.61" => "T.61-8bit",
|
||||
"iso-ir-103" => "T.61-8bit",
|
||||
"csiso103t618bit" => "T.61-8bit",
|
||||
//
|
||||
// Aliases for UTF-7",
|
||||
//
|
||||
"x-unicode-2-0-utf-7" => "UTF-7",
|
||||
"unicode-2-0-utf-7" => "UTF-7",
|
||||
"unicode-1-1-utf-7" => "UTF-7",
|
||||
"csunicode11utf7" => "UTF-7",
|
||||
//
|
||||
// Aliases for ISO-10646-UCS-2",
|
||||
//
|
||||
"csunicode" => "UTF-16BE",
|
||||
"csunicode11" => "UTF-16BE",
|
||||
"iso-10646-ucs-basic" => "UTF-16BE",
|
||||
"csunicodeascii" => "UTF-16BE",
|
||||
"iso-10646-unicode-latin1" => "UTF-16BE",
|
||||
"csunicodelatin1" => "UTF-16BE",
|
||||
"iso-10646" => "UTF-16BE",
|
||||
"iso-10646-j-1" => "UTF-16BE",
|
||||
//
|
||||
// Aliases for ISO-8859-10",
|
||||
//
|
||||
"latin6" => "ISO-8859-10",
|
||||
"iso-ir-157" => "ISO-8859-10",
|
||||
"l6" => "ISO-8859-10",
|
||||
// Currently .properties cannot handle : in key",
|
||||
//iso_8859-10:1992" => "ISO-8859-10",
|
||||
"csisolatin6" => "ISO-8859-10",
|
||||
//
|
||||
// Aliases for ISO-8859-15",
|
||||
//
|
||||
"iso_8859-15" => "ISO-8859-15",
|
||||
"csisolatin9" => "ISO-8859-15",
|
||||
"l9" => "ISO-8859-15",
|
||||
//
|
||||
// Aliases for ISO-IR-111",
|
||||
//
|
||||
"ecma-cyrillic" => "ISO-IR-111",
|
||||
"csiso111ecmacyrillic" => "ISO-IR-111",
|
||||
//
|
||||
// Aliases for ISO-2022-KR",
|
||||
//
|
||||
"csiso2022kr" => "ISO-2022-KR",
|
||||
//
|
||||
// Aliases for VISCII",
|
||||
//
|
||||
"csviscii" => "VISCII",
|
||||
//
|
||||
// Aliases for x-euc-tw",
|
||||
//
|
||||
"zh_tw-euc" => "x-euc-tw",
|
||||
//
|
||||
// Following names appears in unix nl_langinfo(CODESET)",
|
||||
// They can be compiled as platform specific if necessary",
|
||||
// DONT put things here if it does not look generic enough (like hp15CN)",
|
||||
//
|
||||
"iso88591" => "ISO-8859-1",
|
||||
"iso88592" => "ISO-8859-2",
|
||||
"iso88593" => "ISO-8859-3",
|
||||
"iso88594" => "ISO-8859-4",
|
||||
"iso88595" => "ISO-8859-5",
|
||||
"iso88596" => "ISO-8859-6",
|
||||
"iso88597" => "ISO-8859-7",
|
||||
"iso88598" => "ISO-8859-8",
|
||||
"iso88599" => "ISO-8859-9",
|
||||
"iso885910" => "ISO-8859-10",
|
||||
"iso885911" => "ISO-8859-11",
|
||||
"iso885912" => "ISO-8859-12",
|
||||
"iso885913" => "ISO-8859-13",
|
||||
"iso885914" => "ISO-8859-14",
|
||||
"iso885915" => "ISO-8859-15",
|
||||
"cp1250" => "windows-1250",
|
||||
"cp1251" => "windows-1251",
|
||||
"cp1252" => "windows-1252",
|
||||
"cp1253" => "windows-1253",
|
||||
"cp1254" => "windows-1254",
|
||||
"cp1255" => "windows-1255",
|
||||
"cp1256" => "windows-1256",
|
||||
"cp1257" => "windows-1257",
|
||||
"cp1258" => "windows-1258",
|
||||
"x-gbk" => "gbk",
|
||||
"windows-936" => "gbk",
|
||||
"ansi-1251" => "windows-1251",
|
||||
];
|
||||
|
||||
/**
|
||||
* Returns proper encoding mapping, if exsists. If it doesn't, return unchanged $encoding
|
||||
* @param string|null $encoding
|
||||
* @param string|null $fallback
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function get($encoding, string $fallback = null): string {
|
||||
if (isset(self::$aliases[strtolower($encoding ?? '')])) {
|
||||
return self::$aliases[strtolower($encoding ?? '')];
|
||||
}
|
||||
return $fallback !== null ? $fallback : $encoding;
|
||||
}
|
||||
|
||||
}
|
||||
28
vendor/webklex/php-imap/src/Events/Event.php
vendored
Normal file
28
vendor/webklex/php-imap/src/Events/Event.php
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
/*
|
||||
* File: Event.php
|
||||
* Category: Event
|
||||
* Author: M. Goldenbaum
|
||||
* Created: 25.11.20 22:21
|
||||
* Updated: -
|
||||
*
|
||||
* Description:
|
||||
* -
|
||||
*/
|
||||
|
||||
namespace Webklex\PHPIMAP\Events;
|
||||
|
||||
/**
|
||||
* Class Event
|
||||
*
|
||||
* @package Webklex\PHPIMAP\Events
|
||||
*/
|
||||
abstract class Event {
|
||||
|
||||
/**
|
||||
* Dispatch the event with the given arguments.
|
||||
*/
|
||||
public static function dispatch(): Event {
|
||||
return new static(func_get_args());
|
||||
}
|
||||
}
|
||||
22
vendor/webklex/php-imap/src/Events/FlagDeletedEvent.php
vendored
Normal file
22
vendor/webklex/php-imap/src/Events/FlagDeletedEvent.php
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
/*
|
||||
* File: FlagDeletedEvent.php
|
||||
* Category: Event
|
||||
* Author: M. Goldenbaum
|
||||
* Created: 25.11.20 22:21
|
||||
* Updated: -
|
||||
*
|
||||
* Description:
|
||||
* -
|
||||
*/
|
||||
|
||||
namespace Webklex\PHPIMAP\Events;
|
||||
|
||||
/**
|
||||
* Class FlagDeletedEvent
|
||||
*
|
||||
* @package Webklex\PHPIMAP\Events
|
||||
*/
|
||||
class FlagDeletedEvent extends FlagNewEvent {
|
||||
|
||||
}
|
||||
39
vendor/webklex/php-imap/src/Events/FlagNewEvent.php
vendored
Normal file
39
vendor/webklex/php-imap/src/Events/FlagNewEvent.php
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
/*
|
||||
* File: FlagNewEvent.php
|
||||
* Category: Event
|
||||
* Author: M. Goldenbaum
|
||||
* Created: 25.11.20 22:21
|
||||
* Updated: -
|
||||
*
|
||||
* Description:
|
||||
* -
|
||||
*/
|
||||
|
||||
namespace Webklex\PHPIMAP\Events;
|
||||
|
||||
use Webklex\PHPIMAP\Message;
|
||||
|
||||
/**
|
||||
* Class FlagNewEvent
|
||||
*
|
||||
* @package Webklex\PHPIMAP\Events
|
||||
*/
|
||||
class FlagNewEvent extends Event {
|
||||
|
||||
/** @var Message $message */
|
||||
public $message;
|
||||
|
||||
/** @var string $flag */
|
||||
public $flag;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
* @var mixed[] $arguments
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($arguments) {
|
||||
$this->message = $arguments[0];
|
||||
$this->flag = $arguments[1];
|
||||
}
|
||||
}
|
||||
22
vendor/webklex/php-imap/src/Events/FolderDeletedEvent.php
vendored
Normal file
22
vendor/webklex/php-imap/src/Events/FolderDeletedEvent.php
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
/*
|
||||
* File: FolderDeletedEvent.php
|
||||
* Category: Event
|
||||
* Author: M. Goldenbaum
|
||||
* Created: 25.11.20 22:21
|
||||
* Updated: -
|
||||
*
|
||||
* Description:
|
||||
* -
|
||||
*/
|
||||
|
||||
namespace Webklex\PHPIMAP\Events;
|
||||
|
||||
/**
|
||||
* Class FolderDeletedEvent
|
||||
*
|
||||
* @package Webklex\PHPIMAP\Events
|
||||
*/
|
||||
class FolderDeletedEvent extends FolderNewEvent {
|
||||
|
||||
}
|
||||
38
vendor/webklex/php-imap/src/Events/FolderMovedEvent.php
vendored
Normal file
38
vendor/webklex/php-imap/src/Events/FolderMovedEvent.php
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
/*
|
||||
* File: FolderMovedEvent.php
|
||||
* Category: Event
|
||||
* Author: M. Goldenbaum
|
||||
* Created: 25.11.20 22:21
|
||||
* Updated: -
|
||||
*
|
||||
* Description:
|
||||
* -
|
||||
*/
|
||||
|
||||
namespace Webklex\PHPIMAP\Events;
|
||||
|
||||
use Webklex\PHPIMAP\Folder;
|
||||
|
||||
/**
|
||||
* Class FolderMovedEvent
|
||||
*
|
||||
* @package Webklex\PHPIMAP\Events
|
||||
*/
|
||||
class FolderMovedEvent extends Event {
|
||||
|
||||
/** @var Folder $old_folder */
|
||||
public $old_folder;
|
||||
/** @var Folder $new_folder */
|
||||
public $new_folder;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
* @var Folder[] $folders
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($folders) {
|
||||
$this->old_folder = $folders[0];
|
||||
$this->new_folder = $folders[1];
|
||||
}
|
||||
}
|
||||
35
vendor/webklex/php-imap/src/Events/FolderNewEvent.php
vendored
Normal file
35
vendor/webklex/php-imap/src/Events/FolderNewEvent.php
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
/*
|
||||
* File: FolderNewEvent.php
|
||||
* Category: Event
|
||||
* Author: M. Goldenbaum
|
||||
* Created: 25.11.20 22:21
|
||||
* Updated: -
|
||||
*
|
||||
* Description:
|
||||
* -
|
||||
*/
|
||||
|
||||
namespace Webklex\PHPIMAP\Events;
|
||||
|
||||
use Webklex\PHPIMAP\Folder;
|
||||
|
||||
/**
|
||||
* Class FolderNewEvent
|
||||
*
|
||||
* @package Webklex\PHPIMAP\Events
|
||||
*/
|
||||
class FolderNewEvent extends Event {
|
||||
|
||||
/** @var Folder $folder */
|
||||
public $folder;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
* @var Folder[] $folders
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($folders) {
|
||||
$this->folder = $folders[0];
|
||||
}
|
||||
}
|
||||
22
vendor/webklex/php-imap/src/Events/MessageCopiedEvent.php
vendored
Normal file
22
vendor/webklex/php-imap/src/Events/MessageCopiedEvent.php
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
/*
|
||||
* File: MessageCopiedEvent.php
|
||||
* Category: Event
|
||||
* Author: M. Goldenbaum
|
||||
* Created: 25.11.20 22:21
|
||||
* Updated: -
|
||||
*
|
||||
* Description:
|
||||
* -
|
||||
*/
|
||||
|
||||
namespace Webklex\PHPIMAP\Events;
|
||||
|
||||
/**
|
||||
* Class MessageCopiedEvent
|
||||
*
|
||||
* @package Webklex\PHPIMAP\Events
|
||||
*/
|
||||
class MessageCopiedEvent extends MessageMovedEvent {
|
||||
|
||||
}
|
||||
22
vendor/webklex/php-imap/src/Events/MessageDeletedEvent.php
vendored
Normal file
22
vendor/webklex/php-imap/src/Events/MessageDeletedEvent.php
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
/*
|
||||
* File: MessageDeletedEvent.php
|
||||
* Category: Event
|
||||
* Author: M. Goldenbaum
|
||||
* Created: 25.11.20 22:21
|
||||
* Updated: -
|
||||
*
|
||||
* Description:
|
||||
* -
|
||||
*/
|
||||
|
||||
namespace Webklex\PHPIMAP\Events;
|
||||
|
||||
/**
|
||||
* Class MessageDeletedEvent
|
||||
*
|
||||
* @package Webklex\PHPIMAP\Events
|
||||
*/
|
||||
class MessageDeletedEvent extends MessageNewEvent {
|
||||
|
||||
}
|
||||
38
vendor/webklex/php-imap/src/Events/MessageMovedEvent.php
vendored
Normal file
38
vendor/webklex/php-imap/src/Events/MessageMovedEvent.php
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
/*
|
||||
* File: MessageMovedEvent.php
|
||||
* Category: Event
|
||||
* Author: M. Goldenbaum
|
||||
* Created: 25.11.20 22:21
|
||||
* Updated: -
|
||||
*
|
||||
* Description:
|
||||
* -
|
||||
*/
|
||||
|
||||
namespace Webklex\PHPIMAP\Events;
|
||||
|
||||
use Webklex\PHPIMAP\Message;
|
||||
|
||||
/**
|
||||
* Class MessageMovedEvent
|
||||
*
|
||||
* @package Webklex\PHPIMAP\Events
|
||||
*/
|
||||
class MessageMovedEvent extends Event {
|
||||
|
||||
/** @var Message $old_message */
|
||||
public $old_message;
|
||||
/** @var Message $new_message */
|
||||
public $new_message;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
* @var Message[] $messages
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($messages) {
|
||||
$this->old_message = $messages[0];
|
||||
$this->new_message = $messages[1];
|
||||
}
|
||||
}
|
||||
35
vendor/webklex/php-imap/src/Events/MessageNewEvent.php
vendored
Normal file
35
vendor/webklex/php-imap/src/Events/MessageNewEvent.php
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
/*
|
||||
* File: MessageNewEvent.php
|
||||
* Category: Event
|
||||
* Author: M. Goldenbaum
|
||||
* Created: 25.11.20 22:21
|
||||
* Updated: -
|
||||
*
|
||||
* Description:
|
||||
* -
|
||||
*/
|
||||
|
||||
namespace Webklex\PHPIMAP\Events;
|
||||
|
||||
use Webklex\PHPIMAP\Message;
|
||||
|
||||
/**
|
||||
* Class MessageNewEvent
|
||||
*
|
||||
* @package Webklex\PHPIMAP\Events
|
||||
*/
|
||||
class MessageNewEvent extends Event {
|
||||
|
||||
/** @var Message $message */
|
||||
public $message;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
* @var Message[] $messages
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($messages) {
|
||||
$this->message = $messages[0];
|
||||
}
|
||||
}
|
||||
22
vendor/webklex/php-imap/src/Events/MessageRestoredEvent.php
vendored
Normal file
22
vendor/webklex/php-imap/src/Events/MessageRestoredEvent.php
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
/*
|
||||
* File: MessageRestoredEvent.php
|
||||
* Category: Event
|
||||
* Author: M. Goldenbaum
|
||||
* Created: 25.11.20 22:21
|
||||
* Updated: -
|
||||
*
|
||||
* Description:
|
||||
* -
|
||||
*/
|
||||
|
||||
namespace Webklex\PHPIMAP\Events;
|
||||
|
||||
/**
|
||||
* Class MessageRestoredEvent
|
||||
*
|
||||
* @package Webklex\PHPIMAP\Events
|
||||
*/
|
||||
class MessageRestoredEvent extends MessageNewEvent {
|
||||
|
||||
}
|
||||
24
vendor/webklex/php-imap/src/Exceptions/AuthFailedException.php
vendored
Normal file
24
vendor/webklex/php-imap/src/Exceptions/AuthFailedException.php
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
/*
|
||||
* File: AuthFailedException.php
|
||||
* Category: Exception
|
||||
* Author: M. Goldenbaum
|
||||
* Created: 19.01.17 22:21
|
||||
* Updated: -
|
||||
*
|
||||
* Description:
|
||||
* -
|
||||
*/
|
||||
|
||||
namespace Webklex\PHPIMAP\Exceptions;
|
||||
|
||||
use \Exception;
|
||||
|
||||
/**
|
||||
* Class AuthFailedException
|
||||
*
|
||||
* @package Webklex\PHPIMAP\Exceptions
|
||||
*/
|
||||
class AuthFailedException extends Exception {
|
||||
|
||||
}
|
||||
24
vendor/webklex/php-imap/src/Exceptions/ConnectionFailedException.php
vendored
Normal file
24
vendor/webklex/php-imap/src/Exceptions/ConnectionFailedException.php
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
/*
|
||||
* File: ConnectionFailedException.php
|
||||
* Category: Exception
|
||||
* Author: M. Goldenbaum
|
||||
* Created: 19.01.17 22:21
|
||||
* Updated: -
|
||||
*
|
||||
* Description:
|
||||
* -
|
||||
*/
|
||||
|
||||
namespace Webklex\PHPIMAP\Exceptions;
|
||||
|
||||
use \Exception;
|
||||
|
||||
/**
|
||||
* Class ConnectionFailedException
|
||||
*
|
||||
* @package Webklex\PHPIMAP\Exceptions
|
||||
*/
|
||||
class ConnectionFailedException extends Exception {
|
||||
|
||||
}
|
||||
24
vendor/webklex/php-imap/src/Exceptions/EventNotFoundException.php
vendored
Normal file
24
vendor/webklex/php-imap/src/Exceptions/EventNotFoundException.php
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
/*
|
||||
* File: EventNotFoundException.php
|
||||
* Category: Exception
|
||||
* Author: M. Goldenbaum
|
||||
* Created: 05.03.18 23:21
|
||||
* Updated: -
|
||||
*
|
||||
* Description:
|
||||
* -
|
||||
*/
|
||||
|
||||
namespace Webklex\PHPIMAP\Exceptions;
|
||||
|
||||
use \Exception;
|
||||
|
||||
/**
|
||||
* Class EventNotFoundException
|
||||
*
|
||||
* @package Webklex\PHPIMAP\Exceptions
|
||||
*/
|
||||
class EventNotFoundException extends Exception {
|
||||
|
||||
}
|
||||
24
vendor/webklex/php-imap/src/Exceptions/FolderFetchingException.php
vendored
Normal file
24
vendor/webklex/php-imap/src/Exceptions/FolderFetchingException.php
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
/*
|
||||
* File: FolderFetchingException.php
|
||||
* Category: Exception
|
||||
* Author: M. Goldenbaum
|
||||
* Created: 05.03.18 23:21
|
||||
* Updated: -
|
||||
*
|
||||
* Description:
|
||||
* -
|
||||
*/
|
||||
|
||||
namespace Webklex\PHPIMAP\Exceptions;
|
||||
|
||||
use \Exception;
|
||||
|
||||
/**
|
||||
* Class FolderFetchingException
|
||||
*
|
||||
* @package Webklex\PHPIMAP\Exceptions
|
||||
*/
|
||||
class FolderFetchingException extends Exception {
|
||||
|
||||
}
|
||||
24
vendor/webklex/php-imap/src/Exceptions/GetMessagesFailedException.php
vendored
Normal file
24
vendor/webklex/php-imap/src/Exceptions/GetMessagesFailedException.php
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
/*
|
||||
* File: GetMessagesFailedException.php
|
||||
* Category: Exception
|
||||
* Author: M. Goldenbaum
|
||||
* Created: 19.01.17 22:21
|
||||
* Updated: -
|
||||
*
|
||||
* Description:
|
||||
* -
|
||||
*/
|
||||
|
||||
namespace Webklex\PHPIMAP\Exceptions;
|
||||
|
||||
use \Exception;
|
||||
|
||||
/**
|
||||
* Class GetMessagesFailedException
|
||||
*
|
||||
* @package Webklex\PHPIMAP\Exceptions
|
||||
*/
|
||||
class GetMessagesFailedException extends Exception {
|
||||
|
||||
}
|
||||
24
vendor/webklex/php-imap/src/Exceptions/InvalidMessageDateException.php
vendored
Normal file
24
vendor/webklex/php-imap/src/Exceptions/InvalidMessageDateException.php
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
/*
|
||||
* File: InvalidMessageDateException.php
|
||||
* Category: Exception
|
||||
* Author: M. Goldenbaum
|
||||
* Created: 10.03.19 04:31
|
||||
* Updated: -
|
||||
*
|
||||
* Description:
|
||||
* -
|
||||
*/
|
||||
|
||||
namespace Webklex\PHPIMAP\Exceptions;
|
||||
|
||||
use \Exception;
|
||||
|
||||
/**
|
||||
* Class InvalidMessageDateException
|
||||
*
|
||||
* @package Webklex\PHPIMAP\Exceptions
|
||||
*/
|
||||
class InvalidMessageDateException extends Exception {
|
||||
|
||||
}
|
||||
24
vendor/webklex/php-imap/src/Exceptions/InvalidWhereQueryCriteriaException.php
vendored
Normal file
24
vendor/webklex/php-imap/src/Exceptions/InvalidWhereQueryCriteriaException.php
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
/*
|
||||
* File: InvalidWhereQueryCriteriaException.php
|
||||
* Category: Exception
|
||||
* Author: M. Goldenbaum
|
||||
* Created: 21.07.18 19:04
|
||||
* Updated: -
|
||||
*
|
||||
* Description:
|
||||
* -
|
||||
*/
|
||||
|
||||
namespace Webklex\PHPIMAP\Exceptions;
|
||||
|
||||
use \Exception;
|
||||
|
||||
/**
|
||||
* Class InvalidWhereQueryCriteriaException
|
||||
*
|
||||
* @package Webklex\PHPIMAP\Exceptions
|
||||
*/
|
||||
class InvalidWhereQueryCriteriaException extends Exception {
|
||||
|
||||
}
|
||||
24
vendor/webklex/php-imap/src/Exceptions/MaskNotFoundException.php
vendored
Normal file
24
vendor/webklex/php-imap/src/Exceptions/MaskNotFoundException.php
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
/*
|
||||
* File: MaskNotFoundException.php
|
||||
* Category: Exception
|
||||
* Author: M. Goldenbaum
|
||||
* Created: 05.03.18 23:21
|
||||
* Updated: -
|
||||
*
|
||||
* Description:
|
||||
* -
|
||||
*/
|
||||
|
||||
namespace Webklex\PHPIMAP\Exceptions;
|
||||
|
||||
use \Exception;
|
||||
|
||||
/**
|
||||
* Class MaskNotFoundException
|
||||
*
|
||||
* @package Webklex\PHPIMAP\Exceptions
|
||||
*/
|
||||
class MaskNotFoundException extends Exception {
|
||||
|
||||
}
|
||||
24
vendor/webklex/php-imap/src/Exceptions/MessageContentFetchingException.php
vendored
Normal file
24
vendor/webklex/php-imap/src/Exceptions/MessageContentFetchingException.php
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
/*
|
||||
* File: MessageContentFetchingException.php
|
||||
* Category: Exception
|
||||
* Author: M. Goldenbaum
|
||||
* Created: 05.03.18 23:21
|
||||
* Updated: -
|
||||
*
|
||||
* Description:
|
||||
* -
|
||||
*/
|
||||
|
||||
namespace Webklex\PHPIMAP\Exceptions;
|
||||
|
||||
use \Exception;
|
||||
|
||||
/**
|
||||
* Class MessageContentFetchingException
|
||||
*
|
||||
* @package Webklex\PHPIMAP\Exceptions
|
||||
*/
|
||||
class MessageContentFetchingException extends Exception {
|
||||
|
||||
}
|
||||
24
vendor/webklex/php-imap/src/Exceptions/MessageFlagException.php
vendored
Normal file
24
vendor/webklex/php-imap/src/Exceptions/MessageFlagException.php
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
/*
|
||||
* File: MessageFlagException.php
|
||||
* Category: Exception
|
||||
* Author: M. Goldenbaum
|
||||
* Created: 02.01.21 02:47
|
||||
* Updated: -
|
||||
*
|
||||
* Description:
|
||||
* -
|
||||
*/
|
||||
|
||||
namespace Webklex\PHPIMAP\Exceptions;
|
||||
|
||||
use \Exception;
|
||||
|
||||
/**
|
||||
* Class MessageFlagException
|
||||
*
|
||||
* @package Webklex\PHPIMAP\Exceptions
|
||||
*/
|
||||
class MessageFlagException extends Exception {
|
||||
|
||||
}
|
||||
24
vendor/webklex/php-imap/src/Exceptions/MessageHeaderFetchingException.php
vendored
Normal file
24
vendor/webklex/php-imap/src/Exceptions/MessageHeaderFetchingException.php
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
/*
|
||||
* File: MessageHeaderFetchingException.php
|
||||
* Category: Exception
|
||||
* Author: M. Goldenbaum
|
||||
* Created: 05.03.18 23:21
|
||||
* Updated: -
|
||||
*
|
||||
* Description:
|
||||
* -
|
||||
*/
|
||||
|
||||
namespace Webklex\PHPIMAP\Exceptions;
|
||||
|
||||
use \Exception;
|
||||
|
||||
/**
|
||||
* Class MessageHeaderFetchingException
|
||||
*
|
||||
* @package Webklex\PHPIMAP\Exceptions
|
||||
*/
|
||||
class MessageHeaderFetchingException extends Exception {
|
||||
|
||||
}
|
||||
24
vendor/webklex/php-imap/src/Exceptions/MessageNotFoundException.php
vendored
Normal file
24
vendor/webklex/php-imap/src/Exceptions/MessageNotFoundException.php
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
/*
|
||||
* File: MessageNotFoundException.php
|
||||
* Category: Exception
|
||||
* Author: M. Goldenbaum
|
||||
* Created: 25.01.21 18:19
|
||||
* Updated: -
|
||||
*
|
||||
* Description:
|
||||
* -
|
||||
*/
|
||||
|
||||
namespace Webklex\PHPIMAP\Exceptions;
|
||||
|
||||
use \Exception;
|
||||
|
||||
/**
|
||||
* Class MessageNotFoundException
|
||||
*
|
||||
* @package Webklex\PHPIMAP\Exceptions
|
||||
*/
|
||||
class MessageNotFoundException extends Exception {
|
||||
|
||||
}
|
||||
24
vendor/webklex/php-imap/src/Exceptions/MessageSearchValidationException.php
vendored
Normal file
24
vendor/webklex/php-imap/src/Exceptions/MessageSearchValidationException.php
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
/*
|
||||
* File: MessageSearchValidationException.php
|
||||
* Category: Exception
|
||||
* Author: M. Goldenbaum
|
||||
* Created: 05.03.18 23:21
|
||||
* Updated: -
|
||||
*
|
||||
* Description:
|
||||
* -
|
||||
*/
|
||||
|
||||
namespace Webklex\PHPIMAP\Exceptions;
|
||||
|
||||
use \Exception;
|
||||
|
||||
/**
|
||||
* Class MessageSearchValidationException
|
||||
*
|
||||
* @package Webklex\PHPIMAP\Exceptions
|
||||
*/
|
||||
class MessageSearchValidationException extends Exception {
|
||||
|
||||
}
|
||||
24
vendor/webklex/php-imap/src/Exceptions/MethodNotFoundException.php
vendored
Normal file
24
vendor/webklex/php-imap/src/Exceptions/MethodNotFoundException.php
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
/*
|
||||
* File: MethodNotFoundException.php
|
||||
* Category: Exception
|
||||
* Author: M. Goldenbaum
|
||||
* Created: 05.03.18 23:21
|
||||
* Updated: -
|
||||
*
|
||||
* Description:
|
||||
* -
|
||||
*/
|
||||
|
||||
namespace Webklex\PHPIMAP\Exceptions;
|
||||
|
||||
use \Exception;
|
||||
|
||||
/**
|
||||
* Class MethodNotFoundException
|
||||
*
|
||||
* @package Webklex\PHPIMAP\Exceptions
|
||||
*/
|
||||
class MethodNotFoundException extends Exception {
|
||||
|
||||
}
|
||||
24
vendor/webklex/php-imap/src/Exceptions/MethodNotSupportedException.php
vendored
Normal file
24
vendor/webklex/php-imap/src/Exceptions/MethodNotSupportedException.php
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
/*
|
||||
* File: MethodNotSupportedException.php
|
||||
* Category: Exception
|
||||
* Author: M. Goldenbaum
|
||||
* Created: 05.03.18 23:21
|
||||
* Updated: -
|
||||
*
|
||||
* Description:
|
||||
* -
|
||||
*/
|
||||
|
||||
namespace Webklex\PHPIMAP\Exceptions;
|
||||
|
||||
use \Exception;
|
||||
|
||||
/**
|
||||
* Class MethodNotSupportedException
|
||||
*
|
||||
* @package Webklex\PHPIMAP\Exceptions
|
||||
*/
|
||||
class MethodNotSupportedException extends Exception {
|
||||
|
||||
}
|
||||
24
vendor/webklex/php-imap/src/Exceptions/NotSupportedCapabilityException.php
vendored
Normal file
24
vendor/webklex/php-imap/src/Exceptions/NotSupportedCapabilityException.php
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
/*
|
||||
* File: RuntimeException.php
|
||||
* Category: Exception
|
||||
* Author: M. Goldenbaum
|
||||
* Created: 19.01.17 22:21
|
||||
* Updated: -
|
||||
*
|
||||
* Description:
|
||||
* -
|
||||
*/
|
||||
|
||||
namespace Webklex\PHPIMAP\Exceptions;
|
||||
|
||||
use \Exception;
|
||||
|
||||
/**
|
||||
* Class NotSupportedCapabilityException
|
||||
*
|
||||
* @package Webklex\PHPIMAP\Exceptions
|
||||
*/
|
||||
class NotSupportedCapabilityException extends Exception {
|
||||
|
||||
}
|
||||
24
vendor/webklex/php-imap/src/Exceptions/ProtocolNotSupportedException.php
vendored
Normal file
24
vendor/webklex/php-imap/src/Exceptions/ProtocolNotSupportedException.php
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
/*
|
||||
* File: ProtocolNotSupportedException.php
|
||||
* Category: Exception
|
||||
* Author: M. Goldenbaum
|
||||
* Created: 19.01.17 22:21
|
||||
* Updated: -
|
||||
*
|
||||
* Description:
|
||||
* -
|
||||
*/
|
||||
|
||||
namespace Webklex\PHPIMAP\Exceptions;
|
||||
|
||||
use \Exception;
|
||||
|
||||
/**
|
||||
* Class ProtocolNotSupportedException
|
||||
*
|
||||
* @package Webklex\PHPIMAP\Exceptions
|
||||
*/
|
||||
class ProtocolNotSupportedException extends Exception {
|
||||
|
||||
}
|
||||
24
vendor/webklex/php-imap/src/Exceptions/RuntimeException.php
vendored
Normal file
24
vendor/webklex/php-imap/src/Exceptions/RuntimeException.php
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
/*
|
||||
* File: RuntimeException.php
|
||||
* Category: Exception
|
||||
* Author: M. Goldenbaum
|
||||
* Created: 19.01.17 22:21
|
||||
* Updated: -
|
||||
*
|
||||
* Description:
|
||||
* -
|
||||
*/
|
||||
|
||||
namespace Webklex\PHPIMAP\Exceptions;
|
||||
|
||||
use \Exception;
|
||||
|
||||
/**
|
||||
* Class RuntimeException
|
||||
*
|
||||
* @package Webklex\PHPIMAP\Exceptions
|
||||
*/
|
||||
class RuntimeException extends Exception {
|
||||
|
||||
}
|
||||
475
vendor/webklex/php-imap/src/Folder.php
vendored
Executable file
475
vendor/webklex/php-imap/src/Folder.php
vendored
Executable file
@@ -0,0 +1,475 @@
|
||||
<?php
|
||||
/*
|
||||
* File: Folder.php
|
||||
* Category: -
|
||||
* Author: M. Goldenbaum
|
||||
* Created: 19.01.17 22:21
|
||||
* Updated: -
|
||||
*
|
||||
* Description:
|
||||
* -
|
||||
*/
|
||||
|
||||
namespace Webklex\PHPIMAP;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Webklex\PHPIMAP\Exceptions\ConnectionFailedException;
|
||||
use Webklex\PHPIMAP\Exceptions\NotSupportedCapabilityException;
|
||||
use Webklex\PHPIMAP\Exceptions\RuntimeException;
|
||||
use Webklex\PHPIMAP\Query\WhereQuery;
|
||||
use Webklex\PHPIMAP\Support\FolderCollection;
|
||||
use Webklex\PHPIMAP\Traits\HasEvents;
|
||||
|
||||
/**
|
||||
* Class Folder
|
||||
*
|
||||
* @package Webklex\PHPIMAP
|
||||
*/
|
||||
class Folder {
|
||||
use HasEvents;
|
||||
|
||||
/**
|
||||
* Client instance
|
||||
*
|
||||
* @var Client
|
||||
*/
|
||||
protected $client;
|
||||
|
||||
/**
|
||||
* Folder full path
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $path;
|
||||
|
||||
/**
|
||||
* Folder name
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $name;
|
||||
|
||||
/**
|
||||
* Folder fullname
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $full_name;
|
||||
|
||||
/**
|
||||
* Children folders
|
||||
*
|
||||
* @var FolderCollection|array
|
||||
*/
|
||||
public $children = [];
|
||||
|
||||
/**
|
||||
* Delimiter for folder
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $delimiter;
|
||||
|
||||
/**
|
||||
* Indicates if folder can't containg any "children".
|
||||
* CreateFolder won't work on this folder.
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
public $no_inferiors;
|
||||
|
||||
/**
|
||||
* Indicates if folder is only container, not a mailbox - you can't open it.
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
public $no_select;
|
||||
|
||||
/**
|
||||
* Indicates if folder is marked. This means that it may contain new messages since the last time it was checked.
|
||||
* Not provided by all IMAP servers.
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
public $marked;
|
||||
|
||||
/**
|
||||
* Indicates if folder containg any "children".
|
||||
* Not provided by all IMAP servers.
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
public $has_children;
|
||||
|
||||
/**
|
||||
* Indicates if folder refers to other.
|
||||
* Not provided by all IMAP servers.
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
public $referral;
|
||||
|
||||
/** @var array */
|
||||
public $status;
|
||||
|
||||
/**
|
||||
* Folder constructor.
|
||||
* @param Client $client
|
||||
* @param string $folder_name
|
||||
* @param string $delimiter
|
||||
* @param string[] $attributes
|
||||
*/
|
||||
public function __construct(Client $client, string $folder_name, string $delimiter, array $attributes) {
|
||||
$this->client = $client;
|
||||
|
||||
$this->events["message"] = $client->getDefaultEvents("message");
|
||||
$this->events["folder"] = $client->getDefaultEvents("folder");
|
||||
|
||||
$this->setDelimiter($delimiter);
|
||||
$this->path = $folder_name;
|
||||
$this->full_name = $this->decodeName($folder_name);
|
||||
$this->name = $this->getSimpleName($this->delimiter, $this->full_name);
|
||||
|
||||
$this->parseAttributes($attributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a new search query instance
|
||||
* @param string[] $extensions
|
||||
*
|
||||
* @return WhereQuery
|
||||
* @throws Exceptions\ConnectionFailedException
|
||||
* @throws Exceptions\RuntimeException
|
||||
*/
|
||||
public function query(array $extensions = []): WhereQuery {
|
||||
$this->getClient()->checkConnection();
|
||||
$this->getClient()->openFolder($this->path);
|
||||
$extensions = count($extensions) > 0 ? $extensions : $this->getClient()->extensions;
|
||||
|
||||
return new WhereQuery($this->getClient(), $extensions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a new search query instance
|
||||
* @param string[] $extensions
|
||||
*
|
||||
* @return WhereQuery
|
||||
* @throws Exceptions\ConnectionFailedException
|
||||
* @throws Exceptions\RuntimeException
|
||||
*/
|
||||
public function search(array $extensions = []): WhereQuery {
|
||||
return $this->query($extensions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a new search query instance
|
||||
* @param string[] $extensions
|
||||
*
|
||||
* @return WhereQuery
|
||||
* @throws Exceptions\ConnectionFailedException
|
||||
* @throws Exceptions\RuntimeException
|
||||
*/
|
||||
public function messages(array $extensions = []): WhereQuery {
|
||||
return $this->query($extensions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if folder has children.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function hasChildren(): bool {
|
||||
return $this->has_children;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set children.
|
||||
* @param FolderCollection|array $children
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function setChildren($children = []): Folder {
|
||||
$this->children = $children;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode name.
|
||||
* It converts UTF7-IMAP encoding to UTF-8.
|
||||
* @param $name
|
||||
*
|
||||
* @return array|false|string|string[]|null
|
||||
*/
|
||||
protected function decodeName($name) {
|
||||
return mb_convert_encoding($name, "UTF-8", "UTF7-IMAP");
|
||||
}
|
||||
|
||||
/**
|
||||
* Get simple name (without parent folders).
|
||||
* @param $delimiter
|
||||
* @param $full_name
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
protected function getSimpleName($delimiter, $full_name) {
|
||||
$arr = explode($delimiter, $full_name);
|
||||
|
||||
return end($arr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse attributes and set it to object properties.
|
||||
* @param $attributes
|
||||
*/
|
||||
protected function parseAttributes($attributes) {
|
||||
$this->no_inferiors = in_array('\NoInferiors', $attributes);
|
||||
$this->no_select = in_array('\NoSelect', $attributes);
|
||||
$this->marked = in_array('\Marked', $attributes);
|
||||
$this->referral = in_array('\Referral', $attributes);
|
||||
$this->has_children = in_array('\HasChildren', $attributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Move or rename the current folder
|
||||
* @param string $new_name
|
||||
* @param boolean $expunge
|
||||
*
|
||||
* @return bool
|
||||
* @throws ConnectionFailedException
|
||||
* @throws Exceptions\EventNotFoundException
|
||||
* @throws Exceptions\FolderFetchingException
|
||||
* @throws Exceptions\RuntimeException
|
||||
*/
|
||||
public function move(string $new_name, bool $expunge = true): bool {
|
||||
$this->client->checkConnection();
|
||||
$status = $this->client->getConnection()->renameFolder($this->full_name, $new_name);
|
||||
if($expunge) $this->client->expunge();
|
||||
|
||||
$folder = $this->client->getFolder($new_name);
|
||||
$event = $this->getEvent("folder", "moved");
|
||||
$event::dispatch($this, $folder);
|
||||
|
||||
return $status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a message overview
|
||||
* @param string|null $sequence uid sequence
|
||||
*
|
||||
* @return array
|
||||
* @throws ConnectionFailedException
|
||||
* @throws Exceptions\InvalidMessageDateException
|
||||
* @throws Exceptions\MessageNotFoundException
|
||||
* @throws Exceptions\RuntimeException
|
||||
*/
|
||||
public function overview(string $sequence = null): array {
|
||||
$this->client->openFolder($this->path);
|
||||
$sequence = $sequence === null ? "1:*" : $sequence;
|
||||
$uid = ClientManager::get('options.sequence', IMAP::ST_MSGN) == IMAP::ST_UID;
|
||||
return $this->client->getConnection()->overview($sequence, $uid);
|
||||
}
|
||||
|
||||
/**
|
||||
* Append a string message to the current mailbox
|
||||
* @param string $message
|
||||
* @param array|null $options
|
||||
* @param string|null|Carbon $internal_date
|
||||
*
|
||||
* @return bool
|
||||
* @throws Exceptions\ConnectionFailedException
|
||||
* @throws Exceptions\RuntimeException
|
||||
*/
|
||||
public function appendMessage(string $message, array $options = null, $internal_date = null): bool {
|
||||
/**
|
||||
* Check if $internal_date is parsed. If it is null it should not be set. Otherwise, the message can't be stored.
|
||||
* If this parameter is set, it will set the INTERNALDATE on the appended message. The parameter should be a
|
||||
* date string that conforms to the rfc2060 specifications for a date_time value or be a Carbon object.
|
||||
*/
|
||||
|
||||
if ($internal_date instanceof Carbon){
|
||||
$internal_date = $internal_date->format('d-M-Y H:i:s O');
|
||||
}
|
||||
|
||||
return $this->client->getConnection()->appendMessage($this->path, $message, $options, $internal_date);
|
||||
}
|
||||
|
||||
/**
|
||||
* Rename the current folder
|
||||
* @param string $new_name
|
||||
* @param boolean $expunge
|
||||
*
|
||||
* @return bool
|
||||
* @throws ConnectionFailedException
|
||||
* @throws Exceptions\EventNotFoundException
|
||||
* @throws Exceptions\FolderFetchingException
|
||||
* @throws Exceptions\RuntimeException
|
||||
*/
|
||||
public function rename(string $new_name, bool $expunge = true): bool {
|
||||
return $this->move($new_name, $expunge);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the current folder
|
||||
* @param boolean $expunge
|
||||
*
|
||||
* @return bool
|
||||
* @throws Exceptions\ConnectionFailedException
|
||||
* @throws Exceptions\RuntimeException
|
||||
* @throws Exceptions\EventNotFoundException
|
||||
*/
|
||||
public function delete(bool $expunge = true): bool {
|
||||
$status = $this->client->getConnection()->deleteFolder($this->path);
|
||||
if($expunge) $this->client->expunge();
|
||||
|
||||
$event = $this->getEvent("folder", "deleted");
|
||||
$event::dispatch($this);
|
||||
|
||||
return $status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Subscribe the current folder
|
||||
*
|
||||
* @return bool
|
||||
* @throws Exceptions\ConnectionFailedException
|
||||
* @throws Exceptions\RuntimeException
|
||||
*/
|
||||
public function subscribe(): bool {
|
||||
$this->client->openFolder($this->path);
|
||||
return $this->client->getConnection()->subscribeFolder($this->path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unsubscribe the current folder
|
||||
*
|
||||
* @return bool
|
||||
* @throws Exceptions\ConnectionFailedException
|
||||
* @throws Exceptions\RuntimeException
|
||||
*/
|
||||
public function unsubscribe(): bool {
|
||||
$this->client->openFolder($this->path);
|
||||
return $this->client->getConnection()->unsubscribeFolder($this->path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Idle the current connection
|
||||
* @param callable $callback
|
||||
* @param integer $timeout max 1740 seconds - recommended by rfc2177 §3. Should not be lower than the servers "* OK Still here" message interval
|
||||
* @param boolean $auto_reconnect try to reconnect on connection close (@deprecated is no longer required)
|
||||
*
|
||||
* @throws ConnectionFailedException
|
||||
* @throws Exceptions\InvalidMessageDateException
|
||||
* @throws Exceptions\MessageContentFetchingException
|
||||
* @throws Exceptions\MessageHeaderFetchingException
|
||||
* @throws Exceptions\RuntimeException
|
||||
* @throws Exceptions\EventNotFoundException
|
||||
* @throws Exceptions\MessageFlagException
|
||||
* @throws Exceptions\MessageNotFoundException
|
||||
* @throws Exceptions\NotSupportedCapabilityException
|
||||
*/
|
||||
public function idle(callable $callback, int $timeout = 300, bool $auto_reconnect = false) {
|
||||
$this->client->setTimeout($timeout);
|
||||
if (!in_array("IDLE", $this->client->getConnection()->getCapabilities())) {
|
||||
throw new NotSupportedCapabilityException("IMAP server does not support IDLE");
|
||||
}
|
||||
$this->client->openFolder($this->path, true);
|
||||
$connection = $this->client->getConnection();
|
||||
$connection->idle();
|
||||
|
||||
$sequence = ClientManager::get('options.sequence', IMAP::ST_MSGN);
|
||||
|
||||
while (true) {
|
||||
try {
|
||||
// This polymorphic call is fine - Protocol::idle() will throw an exception beforehand
|
||||
$line = $connection->nextLine();
|
||||
|
||||
if (($pos = strpos($line, "EXISTS")) !== false) {
|
||||
$connection->done();
|
||||
$msgn = (int) substr($line, 2, $pos -2);
|
||||
|
||||
$this->client->openFolder($this->path, true);
|
||||
$message = $this->query()->getMessageByMsgn($msgn);
|
||||
$message->setSequence($sequence);
|
||||
$callback($message);
|
||||
|
||||
$event = $this->getEvent("message", "new");
|
||||
$event::dispatch($message);
|
||||
$connection->idle();
|
||||
} elseif (strpos($line, "OK") === false) {
|
||||
$connection->done();
|
||||
$connection->idle();
|
||||
}
|
||||
}catch (Exceptions\RuntimeException $e) {
|
||||
if(strpos($e->getMessage(), "empty response") >= 0 && $connection->connected()) {
|
||||
$connection->done();
|
||||
$connection->idle();
|
||||
continue;
|
||||
}
|
||||
if(strpos($e->getMessage(), "connection closed") === false) {
|
||||
throw $e;
|
||||
}
|
||||
|
||||
$this->client->reconnect();
|
||||
$this->client->openFolder($this->path, true);
|
||||
|
||||
$connection = $this->client->getConnection();
|
||||
$connection->idle();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get folder status information
|
||||
*
|
||||
* @return array
|
||||
* @throws Exceptions\ConnectionFailedException
|
||||
* @throws Exceptions\RuntimeException
|
||||
*/
|
||||
public function getStatus(): array {
|
||||
return $this->examine();
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws RuntimeException
|
||||
* @throws ConnectionFailedException
|
||||
*/
|
||||
public function loadStatus(): Folder
|
||||
{
|
||||
$this->status = $this->getStatus();
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Examine the current folder
|
||||
*
|
||||
* @return array
|
||||
* @throws Exceptions\ConnectionFailedException
|
||||
* @throws Exceptions\RuntimeException
|
||||
*/
|
||||
public function examine(): array {
|
||||
$result = $this->client->getConnection()->examineFolder($this->path);
|
||||
return is_array($result) ? $result : [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current Client instance
|
||||
*
|
||||
* @return Client
|
||||
*/
|
||||
public function getClient(): Client {
|
||||
return $this->client;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the delimiter
|
||||
* @param $delimiter
|
||||
*/
|
||||
public function setDelimiter($delimiter){
|
||||
if(in_array($delimiter, [null, '', ' ', false]) === true) {
|
||||
$delimiter = ClientManager::get('options.delimiter', '/');
|
||||
}
|
||||
|
||||
$this->delimiter = $delimiter;
|
||||
}
|
||||
}
|
||||
756
vendor/webklex/php-imap/src/Header.php
vendored
Normal file
756
vendor/webklex/php-imap/src/Header.php
vendored
Normal file
@@ -0,0 +1,756 @@
|
||||
<?php
|
||||
/*
|
||||
* File: Header.php
|
||||
* Category: -
|
||||
* Author: M.Goldenbaum
|
||||
* Created: 17.09.20 20:38
|
||||
* Updated: -
|
||||
*
|
||||
* Description:
|
||||
* -
|
||||
*/
|
||||
|
||||
namespace Webklex\PHPIMAP;
|
||||
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Webklex\PHPIMAP\Exceptions\InvalidMessageDateException;
|
||||
use Webklex\PHPIMAP\Exceptions\MethodNotFoundException;
|
||||
|
||||
/**
|
||||
* Class Header
|
||||
*
|
||||
* @package Webklex\PHPIMAP
|
||||
*/
|
||||
class Header {
|
||||
|
||||
/**
|
||||
* Raw header
|
||||
*
|
||||
* @var string $raw
|
||||
*/
|
||||
public $raw = "";
|
||||
|
||||
/**
|
||||
* Attribute holder
|
||||
*
|
||||
* @var Attribute[]|array $attributes
|
||||
*/
|
||||
protected $attributes = [];
|
||||
|
||||
/**
|
||||
* Config holder
|
||||
*
|
||||
* @var array $config
|
||||
*/
|
||||
protected $config = [];
|
||||
|
||||
/**
|
||||
* Fallback Encoding
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $fallback_encoding = 'UTF-8';
|
||||
|
||||
/**
|
||||
* Convert parsed values to attributes
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $attributize = false;
|
||||
|
||||
/**
|
||||
* Header constructor.
|
||||
* @param string $raw_header
|
||||
* @param boolean $attributize
|
||||
*
|
||||
* @throws InvalidMessageDateException
|
||||
*/
|
||||
public function __construct(string $raw_header, bool $attributize = true) {
|
||||
$this->raw = $raw_header;
|
||||
$this->config = ClientManager::get('options');
|
||||
$this->attributize = $attributize;
|
||||
$this->parse();
|
||||
}
|
||||
|
||||
/**
|
||||
* Call dynamic attribute setter and getter methods
|
||||
* @param string $method
|
||||
* @param array $arguments
|
||||
*
|
||||
* @return Attribute|mixed
|
||||
* @throws MethodNotFoundException
|
||||
*/
|
||||
public function __call(string $method, array $arguments) {
|
||||
if (strtolower(substr($method, 0, 3)) === 'get') {
|
||||
$name = preg_replace('/(.)(?=[A-Z])/u', '$1_', substr(strtolower($method), 3));
|
||||
|
||||
if (in_array($name, array_keys($this->attributes))) {
|
||||
return $this->attributes[$name];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
throw new MethodNotFoundException("Method " . self::class . '::' . $method . '() is not supported');
|
||||
}
|
||||
|
||||
/**
|
||||
* Magic getter
|
||||
* @param $name
|
||||
*
|
||||
* @return Attribute|null
|
||||
*/
|
||||
public function __get($name) {
|
||||
return $this->get($name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a specific header attribute
|
||||
* @param $name
|
||||
*
|
||||
* @return Attribute|mixed
|
||||
*/
|
||||
public function get($name) {
|
||||
if (isset($this->attributes[$name])) {
|
||||
return $this->attributes[$name];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a specific attribute
|
||||
* @param string $name
|
||||
* @param array|mixed $value
|
||||
* @param boolean $strict
|
||||
*
|
||||
* @return Attribute
|
||||
*/
|
||||
public function set(string $name, $value, bool $strict = false) {
|
||||
if (isset($this->attributes[$name]) && $strict === false) {
|
||||
if ($this->attributize) {
|
||||
$this->attributes[$name]->add($value, true);
|
||||
} else {
|
||||
if (isset($this->attributes[$name])) {
|
||||
if (!is_array($this->attributes[$name])) {
|
||||
$this->attributes[$name] = [$this->attributes[$name], $value];
|
||||
} else {
|
||||
$this->attributes[$name][] = $value;
|
||||
}
|
||||
} else {
|
||||
$this->attributes[$name] = $value;
|
||||
}
|
||||
}
|
||||
} elseif (!$this->attributize) {
|
||||
$this->attributes[$name] = $value;
|
||||
} else {
|
||||
$this->attributes[$name] = new Attribute($name, $value);
|
||||
}
|
||||
|
||||
return $this->attributes[$name];
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform a regex match all on the raw header and return the first result
|
||||
* @param $pattern
|
||||
*
|
||||
* @return mixed|null
|
||||
*/
|
||||
public function find($pattern) {
|
||||
if (preg_match_all($pattern, $this->raw, $matches)) {
|
||||
if (isset($matches[1])) {
|
||||
if (count($matches[1]) > 0) {
|
||||
return $matches[1][0];
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to find a boundary if possible
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getBoundary() {
|
||||
$regex = $this->config["boundary"] ?? "/boundary=(.*?(?=;)|(.*))/i";
|
||||
$boundary = $this->find($regex);
|
||||
|
||||
if ($boundary === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $this->clearBoundaryString($boundary);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove all unwanted chars from a given boundary
|
||||
* @param string $str
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function clearBoundaryString(string $str): string {
|
||||
return str_replace(['"', '\r', '\n', "\n", "\r", ";", "\s"], "", $str);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the raw headers
|
||||
*
|
||||
* @throws InvalidMessageDateException
|
||||
*/
|
||||
protected function parse() {
|
||||
$header = $this->rfc822_parse_headers($this->raw);
|
||||
$this->extractAddresses($header);
|
||||
|
||||
if (property_exists($header, 'subject')) {
|
||||
$sub = $this->decode($header->subject);
|
||||
$this->set("subject", $sub);
|
||||
}
|
||||
if (property_exists($header, 'references')) {
|
||||
$this->set("references", $this->decode($header->references));
|
||||
}
|
||||
if (property_exists($header, 'message_id')) {
|
||||
$this->set("message_id", str_replace(['<', '>'], '', $header->message_id));
|
||||
}
|
||||
|
||||
$this->parseDate($header);
|
||||
foreach ($header as $key => $value) {
|
||||
$key = trim(rtrim(strtolower($key)));
|
||||
if (!isset($this->attributes[$key])) {
|
||||
$this->set($key, $value);
|
||||
}
|
||||
}
|
||||
|
||||
$this->extractHeaderExtensions();
|
||||
$this->findPriority();
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse mail headers from a string
|
||||
* @link https://php.net/manual/en/function.imap-rfc822-parse-headers.php
|
||||
* @param $raw_headers
|
||||
*
|
||||
* @return object
|
||||
*/
|
||||
public function rfc822_parse_headers($raw_headers) {
|
||||
$headers = [];
|
||||
$imap_headers = [];
|
||||
if (extension_loaded('imap') && $this->config["rfc822"]) {
|
||||
$raw_imap_headers = (array)\imap_rfc822_parse_headers($this->raw);
|
||||
foreach ($raw_imap_headers as $key => $values) {
|
||||
$key = str_replace("-", "_", $key);
|
||||
$imap_headers[$key] = $values;
|
||||
}
|
||||
}
|
||||
$lines = explode("\r\n", preg_replace("/\r\n\s/", ' ', $raw_headers));
|
||||
$prev_header = null;
|
||||
foreach ($lines as $line) {
|
||||
if (substr($line, 0, 1) === "\n") {
|
||||
$line = substr($line, 1);
|
||||
}
|
||||
|
||||
if (substr($line, 0, 1) === "\t") {
|
||||
$line = substr($line, 1);
|
||||
$line = trim(rtrim($line));
|
||||
if ($prev_header !== null) {
|
||||
$headers[$prev_header][] = $line;
|
||||
}
|
||||
} elseif (substr($line, 0, 1) === " ") {
|
||||
$line = substr($line, 1);
|
||||
$line = trim(rtrim($line));
|
||||
if ($prev_header !== null) {
|
||||
if (!isset($headers[$prev_header])) {
|
||||
$headers[$prev_header] = "";
|
||||
}
|
||||
if (is_array($headers[$prev_header])) {
|
||||
$headers[$prev_header][] = $line;
|
||||
} else {
|
||||
$headers[$prev_header] .= $line;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (($pos = strpos($line, ":")) > 0) {
|
||||
$key = trim(rtrim(strtolower(substr($line, 0, $pos))));
|
||||
$key = str_replace("-", "_", $key);
|
||||
|
||||
$value = trim(rtrim(substr($line, $pos + 1)));
|
||||
if (isset($headers[$key])) {
|
||||
$headers[$key][] = $value;
|
||||
} else {
|
||||
$headers[$key] = [$value];
|
||||
}
|
||||
$prev_header = $key;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($headers as $key => $values) {
|
||||
if (isset($imap_headers[$key])) continue;
|
||||
$value = null;
|
||||
switch ($key) {
|
||||
case 'from':
|
||||
case 'to':
|
||||
case 'cc':
|
||||
case 'bcc':
|
||||
case 'reply_to':
|
||||
case 'sender':
|
||||
$value = $this->decodeAddresses($values);
|
||||
$headers[$key . "address"] = implode(", ", $values);
|
||||
break;
|
||||
case 'subject':
|
||||
$value = implode(" ", $values);
|
||||
break;
|
||||
default:
|
||||
if (is_array($values)) {
|
||||
foreach ($values as $k => $v) {
|
||||
if ($v == "") {
|
||||
unset($values[$k]);
|
||||
}
|
||||
}
|
||||
$available_values = count($values);
|
||||
if ($available_values === 1) {
|
||||
$value = array_pop($values);
|
||||
} elseif ($available_values === 2) {
|
||||
$value = implode(" ", $values);
|
||||
} elseif ($available_values > 2) {
|
||||
$value = array_values($values);
|
||||
} else {
|
||||
$value = "";
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
$headers[$key] = $value;
|
||||
}
|
||||
|
||||
return (object)array_merge($headers, $imap_headers);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode MIME header elements
|
||||
* @link https://php.net/manual/en/function.imap-mime-header-decode.php
|
||||
* @param string $text The MIME text
|
||||
*
|
||||
* @return array The decoded elements are returned in an array of objects, where each
|
||||
* object has two properties, charset and text.
|
||||
*/
|
||||
public function mime_header_decode(string $text): array {
|
||||
if (extension_loaded('imap')) {
|
||||
$result = \imap_mime_header_decode($text);
|
||||
return is_array($result) ? $result : [];
|
||||
}
|
||||
$charset = $this->getEncoding($text);
|
||||
return [(object)[
|
||||
"charset" => $charset,
|
||||
"text" => $this->convertEncoding($text, $charset)
|
||||
]];
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a given pair of strings has been decoded
|
||||
* @param $encoded
|
||||
* @param $decoded
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function notDecoded($encoded, $decoded): bool {
|
||||
return 0 === strpos($decoded, '=?')
|
||||
&& strlen($decoded) - 2 === strpos($decoded, '?=')
|
||||
&& false !== strpos($encoded, $decoded);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the encoding
|
||||
* @param $str
|
||||
* @param string $from
|
||||
* @param string $to
|
||||
*
|
||||
* @return mixed|string
|
||||
*/
|
||||
public function convertEncoding($str, $from = "ISO-8859-2", $to = "UTF-8") {
|
||||
|
||||
$from = EncodingAliases::get($from, $this->fallback_encoding);
|
||||
$to = EncodingAliases::get($to, $this->fallback_encoding);
|
||||
|
||||
if ($from === $to) {
|
||||
return $str;
|
||||
}
|
||||
|
||||
// We don't need to do convertEncoding() if charset is ASCII (us-ascii):
|
||||
// ASCII is a subset of UTF-8, so all ASCII files are already UTF-8 encoded
|
||||
// https://stackoverflow.com/a/11303410
|
||||
//
|
||||
// us-ascii is the same as ASCII:
|
||||
// ASCII is the traditional name for the encoding system; the Internet Assigned Numbers Authority (IANA)
|
||||
// prefers the updated name US-ASCII, which clarifies that this system was developed in the US and
|
||||
// based on the typographical symbols predominantly in use there.
|
||||
// https://en.wikipedia.org/wiki/ASCII
|
||||
//
|
||||
// convertEncoding() function basically means convertToUtf8(), so when we convert ASCII string into UTF-8 it gets broken.
|
||||
if (strtolower($from) == 'us-ascii' && $to == 'UTF-8') {
|
||||
return $str;
|
||||
}
|
||||
|
||||
try {
|
||||
if (function_exists('iconv') && $from != 'UTF-7' && $to != 'UTF-7') {
|
||||
return iconv($from, $to, $str);
|
||||
} else {
|
||||
if (!$from) {
|
||||
return mb_convert_encoding($str, $to);
|
||||
}
|
||||
return mb_convert_encoding($str, $to, $from);
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
if (strstr($from, '-')) {
|
||||
$from = str_replace('-', '', $from);
|
||||
return $this->convertEncoding($str, $from, $to);
|
||||
} else {
|
||||
return $str;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the encoding of a given abject
|
||||
* @param object|string $structure
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getEncoding($structure): string {
|
||||
if (property_exists($structure, 'parameters')) {
|
||||
foreach ($structure->parameters as $parameter) {
|
||||
if (strtolower($parameter->attribute) == "charset") {
|
||||
return EncodingAliases::get($parameter->value, $this->fallback_encoding);
|
||||
}
|
||||
}
|
||||
} elseif (property_exists($structure, 'charset')) {
|
||||
return EncodingAliases::get($structure->charset, $this->fallback_encoding);
|
||||
} elseif (is_string($structure) === true) {
|
||||
$result = mb_detect_encoding($structure);
|
||||
return $result === false ? $this->fallback_encoding : $result;
|
||||
}
|
||||
|
||||
return $this->fallback_encoding;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if a given value is utf-8 encoded
|
||||
* @param $value
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function is_uft8($value): bool {
|
||||
return strpos(strtolower($value), '=?utf-8?') === 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to decode a specific header
|
||||
* @param mixed $value
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function decode($value) {
|
||||
// Check if the input contains any encoding
|
||||
if (!preg_match('/=\?([^?]+)\?([QB])\?([^?]+)\?=/i', $value)) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
preg_match_all('/=\?([^?]+)\?([QB])\?([^?]+)\?=/i', $value, $matches, PREG_SET_ORDER);
|
||||
|
||||
$decoded = '';
|
||||
foreach ($matches as $match) {
|
||||
$encoding = $match[1];
|
||||
$type = $match[2];
|
||||
$encoded_string = $match[3];
|
||||
|
||||
// Decode based on encoding type
|
||||
if (strtolower($type) == 'q') {
|
||||
$decoded_part = quoted_printable_decode($encoded_string);
|
||||
} elseif (strtolower($type) == 'b') {
|
||||
$decoded_part = base64_decode($encoded_string);
|
||||
}
|
||||
|
||||
if (strtolower($encoding) != 'utf-8') {
|
||||
$decoded_part = iconv($encoding, 'UTF-8', $decoded_part);
|
||||
}
|
||||
|
||||
$decoded .= str_replace('_', ' ', $decoded_part);
|
||||
}
|
||||
|
||||
return $decoded;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode a given array
|
||||
* @param array $values
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function decodeArray(array $values): array {
|
||||
foreach ($values as $key => $value) {
|
||||
$values[$key] = $this->decode($value);
|
||||
}
|
||||
return $values;
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to extract the priority from a given raw header string
|
||||
*/
|
||||
private function findPriority() {
|
||||
if (($priority = $this->get("x_priority")) === null) return;
|
||||
switch ((int)"$priority") {
|
||||
case IMAP::MESSAGE_PRIORITY_HIGHEST;
|
||||
$priority = IMAP::MESSAGE_PRIORITY_HIGHEST;
|
||||
break;
|
||||
case IMAP::MESSAGE_PRIORITY_HIGH;
|
||||
$priority = IMAP::MESSAGE_PRIORITY_HIGH;
|
||||
break;
|
||||
case IMAP::MESSAGE_PRIORITY_NORMAL;
|
||||
$priority = IMAP::MESSAGE_PRIORITY_NORMAL;
|
||||
break;
|
||||
case IMAP::MESSAGE_PRIORITY_LOW;
|
||||
$priority = IMAP::MESSAGE_PRIORITY_LOW;
|
||||
break;
|
||||
case IMAP::MESSAGE_PRIORITY_LOWEST;
|
||||
$priority = IMAP::MESSAGE_PRIORITY_LOWEST;
|
||||
break;
|
||||
default:
|
||||
$priority = IMAP::MESSAGE_PRIORITY_UNKNOWN;
|
||||
break;
|
||||
}
|
||||
|
||||
$this->set("priority", $priority);
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract a given part as address array from a given header
|
||||
* @param $values
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function decodeAddresses($values): array {
|
||||
$addresses = [];
|
||||
|
||||
if (extension_loaded('mailparse') && $this->config["rfc822"]) {
|
||||
foreach ($values as $address) {
|
||||
foreach (\mailparse_rfc822_parse_addresses($address) as $parsed_address) {
|
||||
if (isset($parsed_address['address'])) {
|
||||
$mail_address = explode('@', $parsed_address['address']);
|
||||
if (count($mail_address) == 2) {
|
||||
$addresses[] = (object)[
|
||||
"personal" => $parsed_address['display'] ?? '',
|
||||
"mailbox" => $mail_address[0],
|
||||
"host" => $mail_address[1],
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $addresses;
|
||||
}
|
||||
|
||||
foreach ($values as $address) {
|
||||
foreach (preg_split('/, (?=(?:[^"]*"[^"]*")*[^"]*$)/', $address) as $split_address) {
|
||||
$split_address = trim(rtrim($split_address));
|
||||
|
||||
if (strpos($split_address, ",") == strlen($split_address) - 1) {
|
||||
$split_address = substr($split_address, 0, -1);
|
||||
}
|
||||
if (preg_match(
|
||||
'/^(?:(?P<name>.+)\s)?(?(name)<|<?)(?P<email>[^\s]+?)(?(name)>|>?)$/',
|
||||
$split_address,
|
||||
$matches
|
||||
)) {
|
||||
$name = trim(rtrim($matches["name"]));
|
||||
$email = trim(rtrim($matches["email"]));
|
||||
list($mailbox, $host) = array_pad(explode("@", $email), 2, null);
|
||||
$addresses[] = (object)[
|
||||
"personal" => $name,
|
||||
"mailbox" => $mailbox,
|
||||
"host" => $host,
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $addresses;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract a given part as address array from a given header
|
||||
* @param object $header
|
||||
*/
|
||||
private function extractAddresses($header) {
|
||||
foreach (['from', 'to', 'cc', 'bcc', 'reply_to', 'sender'] as $key) {
|
||||
if (property_exists($header, $key)) {
|
||||
$this->set($key, $this->parseAddresses($header->$key));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse Addresses
|
||||
* @param $list
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function parseAddresses($list): array {
|
||||
$addresses = [];
|
||||
|
||||
if (is_array($list) === false) {
|
||||
return $addresses;
|
||||
}
|
||||
|
||||
foreach ($list as $item) {
|
||||
$address = (object)$item;
|
||||
|
||||
if (!property_exists($address, 'mailbox')) {
|
||||
$address->mailbox = false;
|
||||
}
|
||||
if (!property_exists($address, 'host')) {
|
||||
$address->host = false;
|
||||
}
|
||||
if (!property_exists($address, 'personal')) {
|
||||
$address->personal = false;
|
||||
} else {
|
||||
$personalParts = $this->mime_header_decode($address->personal);
|
||||
|
||||
if (is_array($personalParts)) {
|
||||
$address->personal = '';
|
||||
foreach ($personalParts as $p) {
|
||||
$address->personal .= $this->convertEncoding($p->text, $this->getEncoding($p));
|
||||
}
|
||||
}
|
||||
|
||||
if (strpos($address->personal, "'") === 0) {
|
||||
$address->personal = str_replace("'", "", $address->personal);
|
||||
}
|
||||
}
|
||||
|
||||
$address->mail = ($address->mailbox && $address->host) ? $address->mailbox . '@' . $address->host : false;
|
||||
$address->full = ($address->personal) ? $address->personal . ' <' . $address->mail . '>' : $address->mail;
|
||||
|
||||
$addresses[] = new Address($address);
|
||||
}
|
||||
|
||||
return $addresses;
|
||||
}
|
||||
|
||||
/**
|
||||
* Search and extract potential header extensions
|
||||
*/
|
||||
private function extractHeaderExtensions() {
|
||||
foreach ($this->attributes as $key => $value) {
|
||||
if (is_array($value)) {
|
||||
$value = implode(", ", $value);
|
||||
} else {
|
||||
$value = (string)$value;
|
||||
}
|
||||
// Only parse strings and don't parse any attributes like the user-agent
|
||||
if (($key == "user_agent") === false) {
|
||||
if (($pos = strpos($value, ";")) !== false) {
|
||||
$original = substr($value, 0, $pos);
|
||||
$this->set($key, trim(rtrim($original)), true);
|
||||
|
||||
// Get all potential extensions
|
||||
$extensions = explode(";", substr($value, $pos + 1));
|
||||
foreach ($extensions as $extension) {
|
||||
if (($pos = strpos($extension, "=")) !== false) {
|
||||
$key = substr($extension, 0, $pos);
|
||||
$key = trim(rtrim(strtolower($key)));
|
||||
|
||||
if (isset($this->attributes[$key]) === false) {
|
||||
$value = substr($extension, $pos + 1);
|
||||
$value = str_replace('"', "", $value);
|
||||
$value = trim(rtrim($value));
|
||||
|
||||
$this->set($key, $value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Exception handling for invalid dates
|
||||
*
|
||||
* Currently known invalid formats:
|
||||
* ^ Datetime ^ Problem ^ Cause
|
||||
* | Mon, 20 Nov 2017 20:31:31 +0800 (GMT+8:00) | Double timezone specification | A Windows feature
|
||||
* | Thu, 8 Nov 2018 08:54:58 -0200 (-02) |
|
||||
* | | and invalid timezone (max 6 char) |
|
||||
* | 04 Jan 2018 10:12:47 UT | Missing letter "C" | Unknown
|
||||
* | Thu, 31 May 2018 18:15:00 +0800 (added by) | Non-standard details added by the | Unknown
|
||||
* | | mail server |
|
||||
* | Sat, 31 Aug 2013 20:08:23 +0580 | Invalid timezone | PHPMailer bug https://sourceforge.net/p/phpmailer/mailman/message/6132703/
|
||||
*
|
||||
* Please report any new invalid timestamps to [#45](https://github.com/Webklex/php-imap/issues)
|
||||
*
|
||||
* @param object $header
|
||||
*
|
||||
* @throws InvalidMessageDateException
|
||||
*/
|
||||
private function parseDate($header) {
|
||||
|
||||
if (property_exists($header, 'date')) {
|
||||
$date = $header->date;
|
||||
|
||||
if (preg_match('/\+0580/', $date)) {
|
||||
$date = str_replace('+0580', '+0530', $date);
|
||||
}
|
||||
|
||||
$date = trim(rtrim($date));
|
||||
try {
|
||||
if(strpos($date, ' ') !== false){
|
||||
$date = str_replace(' ', ' ', $date);
|
||||
}
|
||||
$parsed_date = Carbon::parse($date);
|
||||
} catch (\Exception $e) {
|
||||
switch (true) {
|
||||
case preg_match('/([0-9]{4}\.[0-9]{1,2}\.[0-9]{1,2}\-[0-9]{1,2}\.[0-9]{1,2}.[0-9]{1,2})+$/i', $date) > 0:
|
||||
$date = Carbon::createFromFormat("Y.m.d-H.i.s", $date);
|
||||
break;
|
||||
case preg_match('/([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:
|
||||
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:
|
||||
$date .= 'C';
|
||||
break;
|
||||
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:
|
||||
$date = str_replace(',', '', $date);
|
||||
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:
|
||||
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:
|
||||
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:
|
||||
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:
|
||||
case preg_match('/([0-9]{1,2}\ [A-Z]{2,3}\ [0-9]{2,4}\ [0-9]{2}\:[0-9]{2}\:[0-9]{2}\ [A-Z]{2}\ \-[0-9]{2}\:[0-9]{2}\ \([A-Z]{2,3}\ \-[0-9]{2}:[0-9]{2}\))+$/i', $date) > 0:
|
||||
$array = explode('(', $date);
|
||||
$array = array_reverse($array);
|
||||
$date = trim(array_pop($array));
|
||||
break;
|
||||
}
|
||||
try {
|
||||
$parsed_date = Carbon::parse($date);
|
||||
} catch (\Exception $_e) {
|
||||
if (!isset($this->config["fallback_date"])) {
|
||||
throw new InvalidMessageDateException("Invalid message date. ID:" . $this->get("message_id") . " Date:" . $header->date . "/" . $date, 1100, $e);
|
||||
} else {
|
||||
$parsed_date = Carbon::parse($this->config["fallback_date"]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->set("date", $parsed_date);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all available attributes
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getAttributes(): array {
|
||||
return $this->attributes;
|
||||
}
|
||||
|
||||
}
|
||||
375
vendor/webklex/php-imap/src/IMAP.php
vendored
Normal file
375
vendor/webklex/php-imap/src/IMAP.php
vendored
Normal file
@@ -0,0 +1,375 @@
|
||||
<?php
|
||||
/*
|
||||
* File: IMAP.php
|
||||
* Category: -
|
||||
* Author: M.Goldenbaum
|
||||
* Created: 14.03.19 18:22
|
||||
* Updated: -
|
||||
*
|
||||
* Description:
|
||||
* -
|
||||
*/
|
||||
|
||||
namespace Webklex\PHPIMAP;
|
||||
|
||||
/**
|
||||
* Class IMAP
|
||||
*
|
||||
* Independent imap const holder
|
||||
*/
|
||||
class IMAP {
|
||||
|
||||
/**
|
||||
* Message const
|
||||
*
|
||||
* @const integer TYPE_TEXT
|
||||
* @const integer TYPE_MULTIPART
|
||||
*
|
||||
* @const integer ENC_7BIT
|
||||
* @const integer ENC_8BIT
|
||||
* @const integer ENC_BINARY
|
||||
* @const integer ENC_BASE64
|
||||
* @const integer ENC_QUOTED_PRINTABLE
|
||||
* @const integer ENC_OTHER
|
||||
*/
|
||||
const MESSAGE_TYPE_TEXT = 0;
|
||||
const MESSAGE_TYPE_MULTIPART = 1;
|
||||
|
||||
const MESSAGE_ENC_7BIT = 0;
|
||||
const MESSAGE_ENC_8BIT = 1;
|
||||
const MESSAGE_ENC_BINARY = 2;
|
||||
const MESSAGE_ENC_BASE64 = 3;
|
||||
const MESSAGE_ENC_QUOTED_PRINTABLE = 4;
|
||||
const MESSAGE_ENC_OTHER = 5;
|
||||
|
||||
const MESSAGE_PRIORITY_UNKNOWN = 0;
|
||||
const MESSAGE_PRIORITY_HIGHEST = 1;
|
||||
const MESSAGE_PRIORITY_HIGH = 2;
|
||||
const MESSAGE_PRIORITY_NORMAL = 3;
|
||||
const MESSAGE_PRIORITY_LOW = 4;
|
||||
const MESSAGE_PRIORITY_LOWEST = 5;
|
||||
|
||||
/**
|
||||
* Attachment const
|
||||
*
|
||||
* @const integer TYPE_TEXT
|
||||
* @const integer TYPE_MULTIPART
|
||||
* @const integer TYPE_MESSAGE
|
||||
* @const integer TYPE_APPLICATION
|
||||
* @const integer TYPE_AUDIO
|
||||
* @const integer TYPE_IMAGE
|
||||
* @const integer TYPE_VIDEO
|
||||
* @const integer TYPE_MODEL
|
||||
* @const integer TYPE_OTHER
|
||||
*/
|
||||
const ATTACHMENT_TYPE_TEXT = 0;
|
||||
const ATTACHMENT_TYPE_MULTIPART = 1;
|
||||
const ATTACHMENT_TYPE_MESSAGE = 2;
|
||||
const ATTACHMENT_TYPE_APPLICATION = 3;
|
||||
const ATTACHMENT_TYPE_AUDIO = 4;
|
||||
const ATTACHMENT_TYPE_IMAGE = 5;
|
||||
const ATTACHMENT_TYPE_VIDEO = 6;
|
||||
const ATTACHMENT_TYPE_MODEL = 7;
|
||||
const ATTACHMENT_TYPE_OTHER = 8;
|
||||
|
||||
/**
|
||||
* Client const
|
||||
*
|
||||
* @const integer CLIENT_OPENTIMEOUT
|
||||
* @const integer CLIENT_READTIMEOUT
|
||||
* @const integer CLIENT_WRITETIMEOUT
|
||||
* @const integer CLIENT_CLOSETIMEOUT
|
||||
*/
|
||||
const CLIENT_OPENTIMEOUT = 1;
|
||||
const CLIENT_READTIMEOUT = 2;
|
||||
const CLIENT_WRITETIMEOUT = 3;
|
||||
const CLIENT_CLOSETIMEOUT = 4;
|
||||
|
||||
/**
|
||||
* Generic imap const
|
||||
*
|
||||
* @const integer NIL
|
||||
* @const integer IMAP_OPENTIMEOUT
|
||||
* @const integer IMAP_READTIMEOUT
|
||||
* @const integer IMAP_WRITETIMEOUT
|
||||
* @const integer IMAP_CLOSETIMEOUT
|
||||
* @const integer OP_DEBUG
|
||||
* @const integer OP_READONLY
|
||||
* @const integer OP_ANONYMOUS
|
||||
* @const integer OP_SHORTCACHE
|
||||
* @const integer OP_SILENT
|
||||
* @const integer OP_PROTOTYPE
|
||||
* @const integer OP_HALFOPEN
|
||||
* @const integer OP_EXPUNGE
|
||||
* @const integer OP_SECURE
|
||||
* @const integer CL_EXPUNGE
|
||||
* @const integer FT_UID
|
||||
* @const integer FT_PEEK
|
||||
* @const integer FT_NOT
|
||||
* @const integer FT_INTERNAL
|
||||
* @const integer FT_PREFETCHTEXT
|
||||
* @const integer ST_UID
|
||||
* @const integer ST_SILENT
|
||||
* @const integer ST_SET
|
||||
* @const integer CP_UID
|
||||
* @const integer CP_MOVE
|
||||
* @const integer SE_UID
|
||||
* @const integer SE_FREE
|
||||
* @const integer SE_NOPREFETCH
|
||||
* @const integer SO_FREE
|
||||
* @const integer SO_NOSERVER
|
||||
* @const integer SA_MESSAGES
|
||||
* @const integer SA_RECENT
|
||||
* @const integer SA_UNSEEN
|
||||
* @const integer SA_UIDNEXT
|
||||
* @const integer SA_UIDVALIDITY
|
||||
* @const integer SA_ALL
|
||||
* @const integer LATT_NOINFERIORS
|
||||
* @const integer LATT_NOSELECT
|
||||
* @const integer LATT_MARKED
|
||||
* @const integer LATT_UNMARKED
|
||||
* @const integer LATT_REFERRAL
|
||||
* @const integer LATT_HASCHILDREN
|
||||
* @const integer LATT_HASNOCHILDREN
|
||||
* @const integer SORTDATE
|
||||
* @const integer SORTARRIVAL
|
||||
* @const integer SORTFROM
|
||||
* @const integer SORTSUBJECT
|
||||
* @const integer SORTTO
|
||||
* @const integer SORTCC
|
||||
* @const integer SORTSIZE
|
||||
* @const integer TYPETEXT
|
||||
* @const integer TYPEMULTIPART
|
||||
* @const integer TYPEMESSAGE
|
||||
* @const integer TYPEAPPLICATION
|
||||
* @const integer TYPEAUDIO
|
||||
* @const integer TYPEIMAGE
|
||||
* @const integer TYPEVIDEO
|
||||
* @const integer TYPEMODEL
|
||||
* @const integer TYPEOTHER
|
||||
* @const integer ENC7BIT
|
||||
* @const integer ENC8BIT
|
||||
* @const integer ENCBINARY
|
||||
* @const integer ENCBASE64
|
||||
* @const integer ENCQUOTEDPRINTABLE
|
||||
* @const integer ENCOTHER
|
||||
* @const integer IMAP_GC_ELT
|
||||
* @const integer IMAP_GC_ENV
|
||||
* @const integer IMAP_GC_TEXTS
|
||||
*/
|
||||
|
||||
const NIL = 0;
|
||||
const IMAP_OPENTIMEOUT = 1;
|
||||
const IMAP_READTIMEOUT = 2;
|
||||
const IMAP_WRITETIMEOUT = 3;
|
||||
const IMAP_CLOSETIMEOUT = 4;
|
||||
const OP_DEBUG = 1;
|
||||
|
||||
/**
|
||||
* Open mailbox read-only
|
||||
* @link http://php.net/manual/en/imap.constants.php
|
||||
*/
|
||||
const OP_READONLY = 2;
|
||||
|
||||
/**
|
||||
* Don't use or update a .newsrc for news
|
||||
* (NNTP only)
|
||||
* @link http://php.net/manual/en/imap.constants.php
|
||||
*/
|
||||
const OP_ANONYMOUS = 4;
|
||||
const OP_SHORTCACHE = 8;
|
||||
const OP_SILENT = 16;
|
||||
const OP_PROTOTYPE = 32;
|
||||
|
||||
/**
|
||||
* For IMAP and NNTP
|
||||
* names, open a connection but don't open a mailbox.
|
||||
* @link http://php.net/manual/en/imap.constants.php
|
||||
*/
|
||||
const OP_HALFOPEN = 64;
|
||||
const OP_EXPUNGE = 128;
|
||||
const OP_SECURE = 256;
|
||||
|
||||
/**
|
||||
* silently expunge the mailbox before closing when
|
||||
* calling <b>imap_close</b>
|
||||
* @link http://php.net/manual/en/imap.constants.php
|
||||
*/
|
||||
const CL_EXPUNGE = 32768;
|
||||
|
||||
/**
|
||||
* The parameter is a UID
|
||||
* @link http://php.net/manual/en/imap.constants.php
|
||||
*/
|
||||
const FT_UID = 1;
|
||||
|
||||
/**
|
||||
* Do not set the \Seen flag if not already set
|
||||
* @link http://php.net/manual/en/imap.constants.php
|
||||
*/
|
||||
const FT_PEEK = 2;
|
||||
const FT_NOT = 4;
|
||||
|
||||
/**
|
||||
* The return string is in internal format, will not canonicalize to CRLF.
|
||||
* @link http://php.net/manual/en/imap.constants.php
|
||||
*/
|
||||
const FT_INTERNAL = 8;
|
||||
const FT_PREFETCHTEXT = 32;
|
||||
|
||||
/**
|
||||
* The sequence argument contains UIDs instead of sequence numbers
|
||||
* @link http://php.net/manual/en/imap.constants.php
|
||||
*/
|
||||
const ST_UID = 1;
|
||||
const ST_SILENT = 2;
|
||||
const ST_MSGN = 3;
|
||||
const ST_SET = 4;
|
||||
|
||||
/**
|
||||
* the sequence numbers contain UIDS
|
||||
* @link http://php.net/manual/en/imap.constants.php
|
||||
*/
|
||||
const CP_UID = 1;
|
||||
|
||||
/**
|
||||
* Delete the messages from the current mailbox after copying
|
||||
* with <b>imap_mail_copy</b>
|
||||
* @link http://php.net/manual/en/imap.constants.php
|
||||
*/
|
||||
const CP_MOVE = 2;
|
||||
|
||||
/**
|
||||
* Return UIDs instead of sequence numbers
|
||||
* @link http://php.net/manual/en/imap.constants.php
|
||||
*/
|
||||
const SE_UID = 1;
|
||||
const SE_FREE = 2;
|
||||
|
||||
/**
|
||||
* Don't prefetch searched messages
|
||||
* @link http://php.net/manual/en/imap.constants.php
|
||||
*/
|
||||
const SE_NOPREFETCH = 4;
|
||||
const SO_FREE = 8;
|
||||
const SO_NOSERVER = 16;
|
||||
const SA_MESSAGES = 1;
|
||||
const SA_RECENT = 2;
|
||||
const SA_UNSEEN = 4;
|
||||
const SA_UIDNEXT = 8;
|
||||
const SA_UIDVALIDITY = 16;
|
||||
const SA_ALL = 31;
|
||||
|
||||
/**
|
||||
* This mailbox has no "children" (there are no
|
||||
* mailboxes below this one).
|
||||
* @link http://php.net/manual/en/imap.constants.php
|
||||
*/
|
||||
const LATT_NOINFERIORS = 1;
|
||||
|
||||
/**
|
||||
* This is only a container, not a mailbox - you
|
||||
* cannot open it.
|
||||
* @link http://php.net/manual/en/imap.constants.php
|
||||
*/
|
||||
const LATT_NOSELECT = 2;
|
||||
|
||||
/**
|
||||
* This mailbox is marked. Only used by UW-IMAPD.
|
||||
* @link http://php.net/manual/en/imap.constants.php
|
||||
*/
|
||||
const LATT_MARKED = 4;
|
||||
|
||||
/**
|
||||
* This mailbox is not marked. Only used by
|
||||
* UW-IMAPD.
|
||||
* @link http://php.net/manual/en/imap.constants.php
|
||||
*/
|
||||
const LATT_UNMARKED = 8;
|
||||
const LATT_REFERRAL = 16;
|
||||
const LATT_HASCHILDREN = 32;
|
||||
const LATT_HASNOCHILDREN = 64;
|
||||
|
||||
/**
|
||||
* Sort criteria for <b>imap_sort</b>:
|
||||
* message Date
|
||||
* @link http://php.net/manual/en/imap.constants.php
|
||||
*/
|
||||
const SORTDATE = 0;
|
||||
|
||||
/**
|
||||
* Sort criteria for <b>imap_sort</b>:
|
||||
* arrival date
|
||||
* @link http://php.net/manual/en/imap.constants.php
|
||||
*/
|
||||
const SORTARRIVAL = 1;
|
||||
|
||||
/**
|
||||
* Sort criteria for <b>imap_sort</b>:
|
||||
* mailbox in first From address
|
||||
* @link http://php.net/manual/en/imap.constants.php
|
||||
*/
|
||||
const SORTFROM = 2;
|
||||
|
||||
/**
|
||||
* Sort criteria for <b>imap_sort</b>:
|
||||
* message subject
|
||||
* @link http://php.net/manual/en/imap.constants.php
|
||||
*/
|
||||
const SORTSUBJECT = 3;
|
||||
|
||||
/**
|
||||
* Sort criteria for <b>imap_sort</b>:
|
||||
* mailbox in first To address
|
||||
* @link http://php.net/manual/en/imap.constants.php
|
||||
*/
|
||||
const SORTTO = 4;
|
||||
|
||||
/**
|
||||
* Sort criteria for <b>imap_sort</b>:
|
||||
* mailbox in first cc address
|
||||
* @link http://php.net/manual/en/imap.constants.php
|
||||
*/
|
||||
const SORTCC = 5;
|
||||
|
||||
/**
|
||||
* Sort criteria for <b>imap_sort</b>:
|
||||
* size of message in octets
|
||||
* @link http://php.net/manual/en/imap.constants.php
|
||||
*/
|
||||
const SORTSIZE = 6;
|
||||
const TYPETEXT = 0;
|
||||
const TYPEMULTIPART = 1;
|
||||
const TYPEMESSAGE = 2;
|
||||
const TYPEAPPLICATION = 3;
|
||||
const TYPEAUDIO = 4;
|
||||
const TYPEIMAGE = 5;
|
||||
const TYPEVIDEO = 6;
|
||||
const TYPEMODEL = 7;
|
||||
const TYPEOTHER = 8;
|
||||
const ENC7BIT = 0;
|
||||
const ENC8BIT = 1;
|
||||
const ENCBINARY = 2;
|
||||
const ENCBASE64 = 3;
|
||||
const ENCQUOTEDPRINTABLE = 4;
|
||||
const ENCOTHER = 5;
|
||||
|
||||
/**
|
||||
* Garbage collector, clear message cache elements.
|
||||
* @link http://php.net/manual/en/imap.constants.php
|
||||
*/
|
||||
const IMAP_GC_ELT = 1;
|
||||
|
||||
/**
|
||||
* Garbage collector, clear envelopes and bodies.
|
||||
* @link http://php.net/manual/en/imap.constants.php
|
||||
*/
|
||||
const IMAP_GC_ENV = 2;
|
||||
|
||||
/**
|
||||
* Garbage collector, clear texts.
|
||||
* @link http://php.net/manual/en/imap.constants.php
|
||||
*/
|
||||
const IMAP_GC_TEXTS = 4;
|
||||
|
||||
}
|
||||
1432
vendor/webklex/php-imap/src/Message.php
vendored
Executable file
1432
vendor/webklex/php-imap/src/Message.php
vendored
Executable file
File diff suppressed because it is too large
Load Diff
312
vendor/webklex/php-imap/src/Part.php
vendored
Normal file
312
vendor/webklex/php-imap/src/Part.php
vendored
Normal file
@@ -0,0 +1,312 @@
|
||||
<?php
|
||||
/*
|
||||
* File: Part.php
|
||||
* Category: -
|
||||
* Author: M.Goldenbaum
|
||||
* Created: 17.09.20 20:38
|
||||
* Updated: -
|
||||
*
|
||||
* Description:
|
||||
* -
|
||||
*/
|
||||
|
||||
namespace Webklex\PHPIMAP;
|
||||
|
||||
|
||||
use Webklex\PHPIMAP\Exceptions\InvalidMessageDateException;
|
||||
|
||||
/**
|
||||
* Class Part
|
||||
*
|
||||
* @package Webklex\PHPIMAP
|
||||
*/
|
||||
class Part {
|
||||
|
||||
/**
|
||||
* Raw part
|
||||
*
|
||||
* @var string $raw
|
||||
*/
|
||||
public $raw = "";
|
||||
|
||||
/**
|
||||
* Part type
|
||||
*
|
||||
* @var int $type
|
||||
*/
|
||||
public $type = IMAP::MESSAGE_TYPE_TEXT;
|
||||
|
||||
/**
|
||||
* Part content
|
||||
*
|
||||
* @var string $content
|
||||
*/
|
||||
public $content = "";
|
||||
|
||||
/**
|
||||
* Part subtype
|
||||
*
|
||||
* @var string $subtype
|
||||
*/
|
||||
public $subtype = null;
|
||||
|
||||
/**
|
||||
* Part charset - if available
|
||||
*
|
||||
* @var string $charset
|
||||
*/
|
||||
public $charset = "utf-8";
|
||||
|
||||
/**
|
||||
* Part encoding method
|
||||
*
|
||||
* @var int $encoding
|
||||
*/
|
||||
public $encoding = IMAP::MESSAGE_ENC_OTHER;
|
||||
|
||||
/**
|
||||
* Alias to check if the part is an attachment
|
||||
*
|
||||
* @var boolean $ifdisposition
|
||||
*/
|
||||
public $ifdisposition = false;
|
||||
|
||||
/**
|
||||
* Indicates if the part is an attachment
|
||||
*
|
||||
* @var string $disposition
|
||||
*/
|
||||
public $disposition = null;
|
||||
|
||||
/**
|
||||
* Alias to check if the part has a description
|
||||
*
|
||||
* @var boolean $ifdescription
|
||||
*/
|
||||
public $ifdescription = false;
|
||||
|
||||
/**
|
||||
* Part description if available
|
||||
*
|
||||
* @var string $description
|
||||
*/
|
||||
public $description = null;
|
||||
|
||||
/**
|
||||
* Part filename if available
|
||||
*
|
||||
* @var string $filename
|
||||
*/
|
||||
public $filename = null;
|
||||
|
||||
/**
|
||||
* Part name if available
|
||||
*
|
||||
* @var string $name
|
||||
*/
|
||||
public $name = null;
|
||||
|
||||
/**
|
||||
* Part id if available
|
||||
*
|
||||
* @var string $id
|
||||
*/
|
||||
public $id = null;
|
||||
|
||||
/**
|
||||
* The part number of the current part
|
||||
*
|
||||
* @var integer $part_number
|
||||
*/
|
||||
public $part_number = 0;
|
||||
|
||||
/**
|
||||
* Part length in bytes
|
||||
*
|
||||
* @var integer $bytes
|
||||
*/
|
||||
public $bytes = null;
|
||||
|
||||
/**
|
||||
* Part content type
|
||||
*
|
||||
* @var string|null $content_type
|
||||
*/
|
||||
public $content_type = null;
|
||||
|
||||
/**
|
||||
* @var Header $header
|
||||
*/
|
||||
private $header = null;
|
||||
|
||||
/**
|
||||
* Part constructor.
|
||||
* @param $raw_part
|
||||
* @param Header|null $header
|
||||
* @param integer $part_number
|
||||
*
|
||||
* @throws InvalidMessageDateException
|
||||
*/
|
||||
public function __construct($raw_part, Header $header = null, int $part_number = 0) {
|
||||
$this->raw = $raw_part;
|
||||
$this->header = $header;
|
||||
$this->part_number = $part_number;
|
||||
$this->parse();
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the raw parts
|
||||
*
|
||||
* @throws InvalidMessageDateException
|
||||
*/
|
||||
protected function parse(){
|
||||
if ($this->header === null) {
|
||||
$body = $this->findHeaders();
|
||||
}else{
|
||||
$body = $this->raw;
|
||||
}
|
||||
|
||||
$this->parseDisposition();
|
||||
$this->parseDescription();
|
||||
$this->parseEncoding();
|
||||
|
||||
$this->charset = $this->header->get("charset");
|
||||
$this->name = $this->header->get("name");
|
||||
$this->filename = $this->header->get("filename");
|
||||
|
||||
if(!empty($this->header->get("id"))) {
|
||||
$this->id = $this->header->get("id");
|
||||
} else if(!empty($this->header->get("x_attachment_id"))){
|
||||
$this->id = $this->header->get("x_attachment_id");
|
||||
} else if(!empty($this->header->get("content_id"))){
|
||||
$this->id = strtr($this->header->get("content_id"), [
|
||||
'<' => '',
|
||||
'>' => ''
|
||||
]);
|
||||
}
|
||||
|
||||
$content_types = $this->header->get("content_type");
|
||||
if(!empty($content_types)){
|
||||
$this->subtype = $this->parseSubtype($content_types);
|
||||
$content_type = $content_types;
|
||||
if (is_array($content_types)) {
|
||||
$content_type = $content_types[0];
|
||||
}
|
||||
$parts = explode(';', $content_type);
|
||||
$this->content_type = trim($parts[0]);
|
||||
}
|
||||
|
||||
|
||||
$this->content = trim(rtrim($body));
|
||||
$this->bytes = strlen($this->content);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find all available headers and return the leftover body segment
|
||||
*
|
||||
* @return string
|
||||
* @throws InvalidMessageDateException
|
||||
*/
|
||||
private function findHeaders(): string {
|
||||
$body = $this->raw;
|
||||
while (($pos = strpos($body, "\r\n")) > 0) {
|
||||
$body = substr($body, $pos + 2);
|
||||
}
|
||||
$headers = substr($this->raw, 0, strlen($body) * -1);
|
||||
$body = substr($body, 0, -2);
|
||||
|
||||
$this->header = new Header($headers);
|
||||
|
||||
return $body;
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to parse the subtype if any is present
|
||||
* @param $content_type
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function parseSubtype($content_type){
|
||||
if (is_array($content_type)) {
|
||||
foreach ($content_type as $part){
|
||||
if ((strpos($part, "/")) !== false){
|
||||
return $this->parseSubtype($part);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
if (($pos = strpos($content_type, "/")) !== false){
|
||||
return substr($content_type, $pos + 1);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to parse the disposition if any is present
|
||||
*/
|
||||
private function parseDisposition(){
|
||||
$content_disposition = $this->header->get("content_disposition");
|
||||
if($content_disposition !== null) {
|
||||
$this->ifdisposition = true;
|
||||
$this->disposition = (is_array($content_disposition)) ? implode(' ', $content_disposition) : $content_disposition;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to parse the description if any is present
|
||||
*/
|
||||
private function parseDescription(){
|
||||
$content_description = $this->header->get("content_description");
|
||||
if($content_description !== null) {
|
||||
$this->ifdescription = true;
|
||||
$this->description = $content_description;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to parse the encoding if any is present
|
||||
*/
|
||||
private function parseEncoding(){
|
||||
$encoding = $this->header->get("content_transfer_encoding");
|
||||
if($encoding !== null) {
|
||||
switch (strtolower($encoding)) {
|
||||
case "quoted-printable":
|
||||
$this->encoding = IMAP::MESSAGE_ENC_QUOTED_PRINTABLE;
|
||||
break;
|
||||
case "base64":
|
||||
$this->encoding = IMAP::MESSAGE_ENC_BASE64;
|
||||
break;
|
||||
case "7bit":
|
||||
$this->encoding = IMAP::MESSAGE_ENC_7BIT;
|
||||
break;
|
||||
case "8bit":
|
||||
$this->encoding = IMAP::MESSAGE_ENC_8BIT;
|
||||
break;
|
||||
case "binary":
|
||||
$this->encoding = IMAP::MESSAGE_ENC_BINARY;
|
||||
break;
|
||||
default:
|
||||
$this->encoding = IMAP::MESSAGE_ENC_OTHER;
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the current part represents an attachment
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isAttachment(): bool {
|
||||
$valid_disposition = in_array(strtolower($this->disposition ?? ''), ClientManager::get('options.dispositions'));
|
||||
|
||||
if ($this->type == IMAP::MESSAGE_TYPE_TEXT && ($this->ifdisposition == 0 || empty($this->disposition) || !$valid_disposition)) {
|
||||
if (($this->subtype == null || in_array((strtolower($this->subtype)), ["plain", "html"])) && $this->filename == null && $this->name == null) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
979
vendor/webklex/php-imap/src/Query/Query.php
vendored
Normal file
979
vendor/webklex/php-imap/src/Query/Query.php
vendored
Normal file
@@ -0,0 +1,979 @@
|
||||
<?php
|
||||
/*
|
||||
* File: Query.php
|
||||
* Category: -
|
||||
* Author: M. Goldenbaum
|
||||
* Created: 21.07.18 18:54
|
||||
* Updated: -
|
||||
*
|
||||
* Description:
|
||||
* -
|
||||
*/
|
||||
|
||||
namespace Webklex\PHPIMAP\Query;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Exception;
|
||||
use Illuminate\Pagination\LengthAwarePaginator;
|
||||
use Illuminate\Support\Collection;
|
||||
use ReflectionException;
|
||||
use Webklex\PHPIMAP\Client;
|
||||
use Webklex\PHPIMAP\ClientManager;
|
||||
use Webklex\PHPIMAP\Exceptions\ConnectionFailedException;
|
||||
use Webklex\PHPIMAP\Exceptions\EventNotFoundException;
|
||||
use Webklex\PHPIMAP\Exceptions\GetMessagesFailedException;
|
||||
use Webklex\PHPIMAP\Exceptions\InvalidMessageDateException;
|
||||
use Webklex\PHPIMAP\Exceptions\MessageContentFetchingException;
|
||||
use Webklex\PHPIMAP\Exceptions\MessageFlagException;
|
||||
use Webklex\PHPIMAP\Exceptions\MessageHeaderFetchingException;
|
||||
use Webklex\PHPIMAP\Exceptions\MessageNotFoundException;
|
||||
use Webklex\PHPIMAP\Exceptions\MessageSearchValidationException;
|
||||
use Webklex\PHPIMAP\Exceptions\RuntimeException;
|
||||
use Webklex\PHPIMAP\IMAP;
|
||||
use Webklex\PHPIMAP\Message;
|
||||
use Webklex\PHPIMAP\Support\MessageCollection;
|
||||
|
||||
/**
|
||||
* Class Query
|
||||
*
|
||||
* @package Webklex\PHPIMAP\Query
|
||||
*/
|
||||
class Query {
|
||||
|
||||
/** @var Collection $query */
|
||||
protected $query;
|
||||
|
||||
/** @var string $raw_query */
|
||||
protected $raw_query;
|
||||
|
||||
/** @var string[] $extensions */
|
||||
protected $extensions;
|
||||
|
||||
/** @var Client $client */
|
||||
protected $client;
|
||||
|
||||
/** @var int $limit */
|
||||
protected $limit = null;
|
||||
|
||||
/** @var int $page */
|
||||
protected $page = 1;
|
||||
|
||||
/** @var int $fetch_options */
|
||||
protected $fetch_options = null;
|
||||
|
||||
/** @var int $fetch_body */
|
||||
protected $fetch_body = true;
|
||||
|
||||
/** @var int $fetch_flags */
|
||||
protected $fetch_flags = true;
|
||||
|
||||
/** @var int|string $sequence */
|
||||
protected $sequence = IMAP::NIL;
|
||||
|
||||
/** @var string $fetch_order */
|
||||
protected $fetch_order;
|
||||
|
||||
/** @var string $date_format */
|
||||
protected $date_format;
|
||||
|
||||
/** @var bool $soft_fail */
|
||||
protected $soft_fail = false;
|
||||
|
||||
/** @var array $errors */
|
||||
protected $errors = [];
|
||||
|
||||
/**
|
||||
* Query constructor.
|
||||
* @param Client $client
|
||||
* @param string[] $extensions
|
||||
*/
|
||||
public function __construct(Client $client, array $extensions = []) {
|
||||
$this->setClient($client);
|
||||
|
||||
$this->sequence = ClientManager::get('options.sequence', IMAP::ST_MSGN);
|
||||
if (ClientManager::get('options.fetch') === IMAP::FT_PEEK) $this->leaveUnread();
|
||||
|
||||
if (ClientManager::get('options.fetch_order') === 'desc') {
|
||||
$this->fetch_order = 'desc';
|
||||
} else {
|
||||
$this->fetch_order = 'asc';
|
||||
}
|
||||
|
||||
$this->date_format = ClientManager::get('date_format', 'd M y');
|
||||
$this->soft_fail = ClientManager::get('options.soft_fail', false);
|
||||
|
||||
$this->setExtensions($extensions);
|
||||
$this->query = new Collection();
|
||||
$this->boot();
|
||||
}
|
||||
|
||||
/**
|
||||
* Instance boot method for additional functionality
|
||||
*/
|
||||
protected function boot() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a given value
|
||||
* @param mixed $value
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function parse_value($value): string {
|
||||
if ($value instanceof Carbon) {
|
||||
$value = $value->format($this->date_format);
|
||||
}
|
||||
|
||||
return (string)$value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a given date is a valid carbon object and if not try to convert it
|
||||
* @param string|Carbon $date
|
||||
*
|
||||
* @return Carbon
|
||||
* @throws MessageSearchValidationException
|
||||
*/
|
||||
protected function parse_date($date): Carbon {
|
||||
if ($date instanceof Carbon) return $date;
|
||||
|
||||
try {
|
||||
$date = Carbon::parse($date);
|
||||
} catch (Exception $e) {
|
||||
throw new MessageSearchValidationException();
|
||||
}
|
||||
|
||||
return $date;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the raw IMAP search query
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function generate_query(): string {
|
||||
$query = '';
|
||||
$this->query->each(function($statement) use (&$query) {
|
||||
if (count($statement) == 1) {
|
||||
$query .= $statement[0];
|
||||
} else {
|
||||
if ($statement[1] === null) {
|
||||
$query .= $statement[0];
|
||||
} else {
|
||||
if (is_numeric($statement[1])) {
|
||||
$query .= $statement[0] . ' ' . $statement[1];
|
||||
} else {
|
||||
$query .= $statement[0] . ' "' . $statement[1] . '"';
|
||||
}
|
||||
}
|
||||
}
|
||||
$query .= ' ';
|
||||
|
||||
});
|
||||
|
||||
$this->raw_query = trim($query);
|
||||
|
||||
return $this->raw_query;
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform an imap search request
|
||||
*
|
||||
* @return Collection
|
||||
* @throws GetMessagesFailedException
|
||||
*/
|
||||
protected function search(): Collection {
|
||||
$this->generate_query();
|
||||
|
||||
try {
|
||||
$available_messages = $this->client->getConnection()->search([$this->getRawQuery()], $this->sequence);
|
||||
return new Collection($available_messages);
|
||||
} catch (RuntimeException $e) {
|
||||
throw new GetMessagesFailedException("failed to fetch messages", 0, $e);
|
||||
} catch (ConnectionFailedException $e) {
|
||||
throw new GetMessagesFailedException("failed to fetch messages", 0, $e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Count all available messages matching the current search criteria
|
||||
*
|
||||
* @return int
|
||||
* @throws GetMessagesFailedException
|
||||
*/
|
||||
public function count(): int {
|
||||
return $this->search()->count();
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch a given id collection
|
||||
* @param Collection $available_messages
|
||||
*
|
||||
* @return array
|
||||
* @throws ConnectionFailedException
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
protected function fetch(Collection $available_messages): array {
|
||||
if ($this->fetch_order === 'desc') {
|
||||
$available_messages = $available_messages->reverse();
|
||||
}
|
||||
|
||||
$uids = $available_messages->forPage($this->page, $this->limit)->toArray();
|
||||
$extensions = $this->getExtensions();
|
||||
if (empty($extensions) === false && method_exists($this->client->getConnection(), "fetch")) {
|
||||
$extensions = $this->client->getConnection()->fetch($extensions, $uids, null, $this->sequence);
|
||||
}
|
||||
$flags = $this->client->getConnection()->flags($uids, $this->sequence);
|
||||
$headers = $this->client->getConnection()->headers($uids, "RFC822", $this->sequence);
|
||||
|
||||
$contents = [];
|
||||
if ($this->getFetchBody()) {
|
||||
$contents = $this->client->getConnection()->content($uids, "RFC822", $this->sequence);
|
||||
}
|
||||
|
||||
return [
|
||||
"uids" => $uids,
|
||||
"flags" => $flags,
|
||||
"headers" => $headers,
|
||||
"contents" => $contents,
|
||||
"extensions" => $extensions,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Make a new message from given raw components
|
||||
* @param integer $uid
|
||||
* @param integer $msglist
|
||||
* @param string $header
|
||||
* @param string $content
|
||||
* @param array $flags
|
||||
*
|
||||
* @return Message|null
|
||||
* @throws ConnectionFailedException
|
||||
* @throws EventNotFoundException
|
||||
* @throws GetMessagesFailedException
|
||||
* @throws ReflectionException
|
||||
*/
|
||||
protected function make(int $uid, int $msglist, string $header, string $content, array $flags) {
|
||||
try {
|
||||
return Message::make($uid, $msglist, $this->getClient(), $header, $content, $flags, $this->getFetchOptions(), $this->sequence);
|
||||
} catch (MessageNotFoundException $e) {
|
||||
$this->setError($uid, $e);
|
||||
} catch (RuntimeException $e) {
|
||||
$this->setError($uid, $e);
|
||||
} catch (MessageFlagException $e) {
|
||||
$this->setError($uid, $e);
|
||||
} catch (InvalidMessageDateException $e) {
|
||||
$this->setError($uid, $e);
|
||||
} catch (MessageContentFetchingException $e) {
|
||||
$this->setError($uid, $e);
|
||||
}
|
||||
|
||||
$this->handleException($uid);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the message key for a given message
|
||||
* @param string $message_key
|
||||
* @param integer $msglist
|
||||
* @param Message $message
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getMessageKey(string $message_key, int $msglist, Message $message): string {
|
||||
switch ($message_key) {
|
||||
case 'number':
|
||||
$key = $message->getMessageNo();
|
||||
break;
|
||||
case 'list':
|
||||
$key = $msglist;
|
||||
break;
|
||||
case 'uid':
|
||||
$key = $message->getUid();
|
||||
break;
|
||||
default:
|
||||
$key = $message->getMessageId();
|
||||
break;
|
||||
}
|
||||
return (string)$key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Curates a given collection aof messages
|
||||
* @param Collection $available_messages
|
||||
*
|
||||
* @return MessageCollection
|
||||
* @throws GetMessagesFailedException
|
||||
*/
|
||||
public function curate_messages(Collection $available_messages): MessageCollection {
|
||||
try {
|
||||
if ($available_messages->count() > 0) {
|
||||
return $this->populate($available_messages);
|
||||
}
|
||||
return MessageCollection::make([]);
|
||||
} catch (Exception $e) {
|
||||
throw new GetMessagesFailedException($e->getMessage(), 0, $e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Populate a given id collection and receive a fully fetched message collection
|
||||
* @param Collection $available_messages
|
||||
*
|
||||
* @return MessageCollection
|
||||
* @throws ConnectionFailedException
|
||||
* @throws EventNotFoundException
|
||||
* @throws GetMessagesFailedException
|
||||
* @throws ReflectionException
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
protected function populate(Collection $available_messages): MessageCollection {
|
||||
$messages = MessageCollection::make([]);
|
||||
|
||||
$messages->total($available_messages->count());
|
||||
|
||||
$message_key = ClientManager::get('options.message_key');
|
||||
|
||||
$raw_messages = $this->fetch($available_messages);
|
||||
|
||||
$msglist = 0;
|
||||
foreach ($raw_messages["headers"] as $uid => $header) {
|
||||
$content = $raw_messages["contents"][$uid] ?? "";
|
||||
$flag = $raw_messages["flags"][$uid] ?? [];
|
||||
$extensions = $raw_messages["extensions"][$uid] ?? [];
|
||||
|
||||
$message = $this->make($uid, $msglist, $header, $content, $flag);
|
||||
foreach($extensions as $key => $extension) {
|
||||
$message->getHeader()->set($key, $extension);
|
||||
}
|
||||
if ($message !== null) {
|
||||
$key = $this->getMessageKey($message_key, $msglist, $message);
|
||||
$messages->put("$key", $message);
|
||||
}
|
||||
$msglist++;
|
||||
}
|
||||
|
||||
return $messages;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch the current query and return all found messages
|
||||
*
|
||||
* @return MessageCollection
|
||||
* @throws GetMessagesFailedException
|
||||
*/
|
||||
public function get(): MessageCollection {
|
||||
return $this->curate_messages($this->search());
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch the current query as chunked requests
|
||||
* @param callable $callback
|
||||
* @param int $chunk_size
|
||||
* @param int $start_chunk
|
||||
*
|
||||
* @throws ConnectionFailedException
|
||||
* @throws EventNotFoundException
|
||||
* @throws GetMessagesFailedException
|
||||
* @throws ReflectionException
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function chunked(callable $callback, int $chunk_size = 10, int $start_chunk = 1) {
|
||||
$available_messages = $this->search();
|
||||
if (($available_messages_count = $available_messages->count()) > 0) {
|
||||
$old_limit = $this->limit;
|
||||
$old_page = $this->page;
|
||||
|
||||
$this->limit = $chunk_size;
|
||||
$this->page = $start_chunk;
|
||||
$handled_messages_count = 0;
|
||||
do {
|
||||
$messages = $this->populate($available_messages);
|
||||
$handled_messages_count += $messages->count();
|
||||
$callback($messages, $this->page);
|
||||
$this->page++;
|
||||
} while ($handled_messages_count < $available_messages_count);
|
||||
$this->limit = $old_limit;
|
||||
$this->page = $old_page;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Paginate the current query
|
||||
* @param int $per_page Results you which to receive per page
|
||||
* @param int|null $page The current page you are on (e.g. 0, 1, 2, ...) use `null` to enable auto mode
|
||||
* @param string $page_name The page name / uri parameter used for the generated links and the auto mode
|
||||
*
|
||||
* @return LengthAwarePaginator
|
||||
* @throws GetMessagesFailedException
|
||||
*/
|
||||
public function paginate(int $per_page = 5, $page = null, string $page_name = 'imap_page'): LengthAwarePaginator {
|
||||
if (
|
||||
$page === null
|
||||
&& isset($_GET[$page_name])
|
||||
&& $_GET[$page_name] > 0
|
||||
) {
|
||||
$this->page = intval($_GET[$page_name]);
|
||||
} elseif ($page > 0) {
|
||||
$this->page = $page;
|
||||
}
|
||||
|
||||
$this->limit = $per_page;
|
||||
|
||||
return $this->get()->paginate($per_page, $this->page, $page_name, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a new Message instance
|
||||
* @param int $uid
|
||||
* @param int|null $msglist
|
||||
* @param int|string|null $sequence
|
||||
*
|
||||
* @return Message
|
||||
* @throws ConnectionFailedException
|
||||
* @throws RuntimeException
|
||||
* @throws InvalidMessageDateException
|
||||
* @throws MessageContentFetchingException
|
||||
* @throws MessageHeaderFetchingException
|
||||
* @throws EventNotFoundException
|
||||
* @throws MessageFlagException
|
||||
* @throws MessageNotFoundException
|
||||
*/
|
||||
public function getMessage(int $uid, $msglist = null, $sequence = null): Message {
|
||||
return new Message($uid, $msglist, $this->getClient(), $this->getFetchOptions(), $this->getFetchBody(), $this->getFetchFlags(), $sequence ? $sequence : $this->sequence);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a message by its message number
|
||||
* @param $msgn
|
||||
* @param int|null $msglist
|
||||
*
|
||||
* @return Message
|
||||
* @throws ConnectionFailedException
|
||||
* @throws InvalidMessageDateException
|
||||
* @throws MessageContentFetchingException
|
||||
* @throws MessageHeaderFetchingException
|
||||
* @throws RuntimeException
|
||||
* @throws EventNotFoundException
|
||||
* @throws MessageFlagException
|
||||
* @throws MessageNotFoundException
|
||||
*/
|
||||
public function getMessageByMsgn($msgn, $msglist = null): Message {
|
||||
return $this->getMessage($msgn, $msglist, IMAP::ST_MSGN);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a message by its uid
|
||||
* @param $uid
|
||||
*
|
||||
* @return Message
|
||||
* @throws ConnectionFailedException
|
||||
* @throws InvalidMessageDateException
|
||||
* @throws MessageContentFetchingException
|
||||
* @throws MessageHeaderFetchingException
|
||||
* @throws RuntimeException
|
||||
* @throws EventNotFoundException
|
||||
* @throws MessageFlagException
|
||||
* @throws MessageNotFoundException
|
||||
*/
|
||||
public function getMessageByUid($uid): Message {
|
||||
return $this->getMessage($uid, null, IMAP::ST_UID);
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter all available uids by a given closure and get a curated list of messages
|
||||
* @param callable $closure
|
||||
*
|
||||
* @return MessageCollection
|
||||
* @throws ConnectionFailedException
|
||||
* @throws GetMessagesFailedException
|
||||
* @throws MessageNotFoundException
|
||||
*/
|
||||
public function filter(callable $closure): MessageCollection {
|
||||
$connection = $this->getClient()->getConnection();
|
||||
|
||||
$uids = $connection->getUid();
|
||||
$available_messages = new Collection();
|
||||
if (is_array($uids)) {
|
||||
foreach ($uids as $id){
|
||||
if ($closure($id)) {
|
||||
$available_messages->push($id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $this->curate_messages($available_messages);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all messages with an uid greater or equal to a given UID
|
||||
* @param int $uid
|
||||
*
|
||||
* @return MessageCollection
|
||||
* @throws ConnectionFailedException
|
||||
* @throws GetMessagesFailedException
|
||||
* @throws MessageNotFoundException
|
||||
*/
|
||||
public function getByUidGreaterOrEqual(int $uid): MessageCollection {
|
||||
return $this->filter(function($id) use($uid){
|
||||
return $id >= $uid;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all messages with an uid greater than a given UID
|
||||
* @param int $uid
|
||||
*
|
||||
* @return MessageCollection
|
||||
* @throws ConnectionFailedException
|
||||
* @throws GetMessagesFailedException
|
||||
* @throws MessageNotFoundException
|
||||
*/
|
||||
public function getByUidGreater(int $uid): MessageCollection {
|
||||
return $this->filter(function($id) use($uid){
|
||||
return $id > $uid;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all messages with an uid lower than a given UID
|
||||
* @param int $uid
|
||||
*
|
||||
* @return MessageCollection
|
||||
* @throws ConnectionFailedException
|
||||
* @throws GetMessagesFailedException
|
||||
* @throws MessageNotFoundException
|
||||
*/
|
||||
public function getByUidLower(int $uid): MessageCollection {
|
||||
return $this->filter(function($id) use($uid){
|
||||
return $id < $uid;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all messages with an uid lower or equal to a given UID
|
||||
* @param int $uid
|
||||
*
|
||||
* @return MessageCollection
|
||||
* @throws ConnectionFailedException
|
||||
* @throws GetMessagesFailedException
|
||||
* @throws MessageNotFoundException
|
||||
*/
|
||||
public function getByUidLowerOrEqual(int $uid): MessageCollection {
|
||||
return $this->filter(function($id) use($uid){
|
||||
return $id <= $uid;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all messages with an uid greater than a given UID
|
||||
* @param int $uid
|
||||
*
|
||||
* @return MessageCollection
|
||||
* @throws ConnectionFailedException
|
||||
* @throws GetMessagesFailedException
|
||||
* @throws MessageNotFoundException
|
||||
*/
|
||||
public function getByUidLowerThan(int $uid): MessageCollection {
|
||||
return $this->filter(function($id) use($uid){
|
||||
return $id < $uid;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Don't mark messages as read when fetching
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function leaveUnread(): Query {
|
||||
$this->setFetchOptions(IMAP::FT_PEEK);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark all messages as read when fetching
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function markAsRead(): Query {
|
||||
$this->setFetchOptions(IMAP::FT_UID);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the sequence type
|
||||
* @param int $sequence
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setSequence(int $sequence): Query {
|
||||
$this->sequence = $sequence;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the sequence type
|
||||
*
|
||||
* @return int|string
|
||||
*/
|
||||
public function getSequence() {
|
||||
return $this->sequence;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Client
|
||||
* @throws ConnectionFailedException
|
||||
*/
|
||||
public function getClient(): Client {
|
||||
$this->client->checkConnection();
|
||||
return $this->client;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the limit and page for the current query
|
||||
* @param int $limit
|
||||
* @param int $page
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function limit(int $limit, int $page = 1): Query {
|
||||
if ($page >= 1) $this->page = $page;
|
||||
$this->limit = $limit;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Collection
|
||||
*/
|
||||
public function getQuery(): Collection {
|
||||
return $this->query;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $query
|
||||
* @return Query
|
||||
*/
|
||||
public function setQuery(array $query): Query {
|
||||
$this->query = new Collection($query);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getRawQuery(): string {
|
||||
return $this->raw_query;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $raw_query
|
||||
* @return Query
|
||||
*/
|
||||
public function setRawQuery(string $raw_query): Query {
|
||||
$this->raw_query = $raw_query;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
public function getExtensions(): array {
|
||||
return $this->extensions;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string[] $extensions
|
||||
* @return Query
|
||||
*/
|
||||
public function setExtensions(array $extensions): Query {
|
||||
$this->extensions = $extensions;
|
||||
if (count($this->extensions) > 0) {
|
||||
if (in_array("UID", $this->extensions) === false) {
|
||||
$this->extensions[] = "UID";
|
||||
}
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Client $client
|
||||
* @return Query
|
||||
*/
|
||||
public function setClient(Client $client): Query {
|
||||
$this->client = $client;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the set fetch limit
|
||||
* @return int
|
||||
*/
|
||||
public function getLimit() {
|
||||
return $this->limit;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $limit
|
||||
* @return Query
|
||||
*/
|
||||
public function setLimit(int $limit): Query {
|
||||
$this->limit = $limit <= 0 ? null : $limit;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getPage(): int {
|
||||
return $this->page;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $page
|
||||
* @return Query
|
||||
*/
|
||||
public function setPage(int $page): Query {
|
||||
$this->page = $page;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $fetch_options
|
||||
* @return Query
|
||||
*/
|
||||
public function setFetchOptions(int $fetch_options): Query {
|
||||
$this->fetch_options = $fetch_options;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $fetch_options
|
||||
* @return Query
|
||||
*/
|
||||
public function fetchOptions(int $fetch_options): Query {
|
||||
return $this->setFetchOptions($fetch_options);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getFetchOptions() {
|
||||
return $this->fetch_options;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return boolean
|
||||
*/
|
||||
public function getFetchBody() {
|
||||
return $this->fetch_body;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param boolean $fetch_body
|
||||
* @return Query
|
||||
*/
|
||||
public function setFetchBody(bool $fetch_body): Query {
|
||||
$this->fetch_body = $fetch_body;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param boolean $fetch_body
|
||||
* @return Query
|
||||
*/
|
||||
public function fetchBody(bool $fetch_body): Query {
|
||||
return $this->setFetchBody($fetch_body);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getFetchFlags() {
|
||||
return $this->fetch_flags;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $fetch_flags
|
||||
* @return Query
|
||||
*/
|
||||
public function setFetchFlags(int $fetch_flags): Query {
|
||||
$this->fetch_flags = $fetch_flags;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $fetch_order
|
||||
* @return Query
|
||||
*/
|
||||
public function setFetchOrder(string $fetch_order): Query {
|
||||
$fetch_order = strtolower($fetch_order);
|
||||
|
||||
if (in_array($fetch_order, ['asc', 'desc'])) {
|
||||
$this->fetch_order = $fetch_order;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $fetch_order
|
||||
* @return Query
|
||||
*/
|
||||
public function fetchOrder(string $fetch_order): Query {
|
||||
return $this->setFetchOrder($fetch_order);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getFetchOrder(): string {
|
||||
return $this->fetch_order;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Query
|
||||
*/
|
||||
public function setFetchOrderAsc(): Query {
|
||||
return $this->setFetchOrder('asc');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Query
|
||||
*/
|
||||
public function fetchOrderAsc(): Query {
|
||||
return $this->setFetchOrderAsc();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Query
|
||||
*/
|
||||
public function setFetchOrderDesc(): Query {
|
||||
return $this->setFetchOrder('desc');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Query
|
||||
*/
|
||||
public function fetchOrderDesc(): Query {
|
||||
return $this->setFetchOrderDesc();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Query
|
||||
* @var boolean $state
|
||||
*
|
||||
*/
|
||||
public function softFail(bool $state = true): Query {
|
||||
return $this->setSoftFail($state);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Query
|
||||
* @var boolean $state
|
||||
*
|
||||
*/
|
||||
public function setSoftFail(bool $state = true): Query {
|
||||
$this->soft_fail = $state;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return boolean
|
||||
*/
|
||||
public function getSoftFail(): bool {
|
||||
return $this->soft_fail;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the exception for a given uid
|
||||
* @param integer $uid
|
||||
*
|
||||
* @throws GetMessagesFailedException
|
||||
*/
|
||||
protected function handleException(int $uid) {
|
||||
if ($this->soft_fail === false && $this->hasError($uid)) {
|
||||
$error = $this->getError($uid);
|
||||
throw new GetMessagesFailedException($error->getMessage(), 0, $error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new error to the error holder
|
||||
* @param integer $uid
|
||||
* @param Exception $error
|
||||
*/
|
||||
protected function setError(int $uid, Exception $error) {
|
||||
$this->errors[$uid] = $error;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if there are any errors / exceptions present
|
||||
* @return boolean
|
||||
* @var integer|null $uid
|
||||
*
|
||||
*/
|
||||
public function hasErrors($uid = null): bool {
|
||||
if ($uid !== null) {
|
||||
return $this->hasError($uid);
|
||||
}
|
||||
return count($this->errors) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if there is an error / exception present
|
||||
* @return boolean
|
||||
* @var integer $uid
|
||||
*
|
||||
*/
|
||||
public function hasError(int $uid): bool {
|
||||
return isset($this->errors[$uid]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all available errors / exceptions
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function errors(): array {
|
||||
return $this->getErrors();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all available errors / exceptions
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getErrors(): array {
|
||||
return $this->errors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a specific error / exception
|
||||
* @return Exception|null
|
||||
* @var integer $uid
|
||||
*
|
||||
*/
|
||||
public function error(int $uid) {
|
||||
return $this->getError($uid);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a specific error / exception
|
||||
* @return Exception|null
|
||||
* @var integer $uid
|
||||
*
|
||||
*/
|
||||
public function getError(int $uid) {
|
||||
if ($this->hasError($uid)) {
|
||||
return $this->errors[$uid];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
546
vendor/webklex/php-imap/src/Query/WhereQuery.php
vendored
Executable file
546
vendor/webklex/php-imap/src/Query/WhereQuery.php
vendored
Executable file
@@ -0,0 +1,546 @@
|
||||
<?php
|
||||
/*
|
||||
* File: Query.php
|
||||
* Category: -
|
||||
* Author: M. Goldenbaum
|
||||
* Created: 21.07.18 18:54
|
||||
* Updated: -
|
||||
*
|
||||
* Description:
|
||||
* -
|
||||
*/
|
||||
|
||||
namespace Webklex\PHPIMAP\Query;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Support\Str;
|
||||
use Webklex\PHPIMAP\Exceptions\InvalidWhereQueryCriteriaException;
|
||||
use Webklex\PHPIMAP\Exceptions\MethodNotFoundException;
|
||||
use Webklex\PHPIMAP\Exceptions\MessageSearchValidationException;
|
||||
|
||||
/**
|
||||
* Class WhereQuery
|
||||
*
|
||||
* @package Webklex\PHPIMAP\Query
|
||||
*
|
||||
* @method WhereQuery all()
|
||||
* @method WhereQuery answered()
|
||||
* @method WhereQuery deleted()
|
||||
* @method WhereQuery new()
|
||||
* @method WhereQuery old()
|
||||
* @method WhereQuery recent()
|
||||
* @method WhereQuery seen()
|
||||
* @method WhereQuery unanswered()
|
||||
* @method WhereQuery undeleted()
|
||||
* @method WhereQuery unflagged()
|
||||
* @method WhereQuery unseen()
|
||||
* @method WhereQuery not()
|
||||
* @method WhereQuery unkeyword($value)
|
||||
* @method WhereQuery to($value)
|
||||
* @method WhereQuery text($value)
|
||||
* @method WhereQuery subject($value)
|
||||
* @method WhereQuery since($date)
|
||||
* @method WhereQuery on($date)
|
||||
* @method WhereQuery keyword($value)
|
||||
* @method WhereQuery from($value)
|
||||
* @method WhereQuery flagged()
|
||||
* @method WhereQuery cc($value)
|
||||
* @method WhereQuery body($value)
|
||||
* @method WhereQuery before($date)
|
||||
* @method WhereQuery bcc($value)
|
||||
* @method WhereQuery inReplyTo($value)
|
||||
* @method WhereQuery messageId($value)
|
||||
*
|
||||
* @mixin Query
|
||||
*/
|
||||
class WhereQuery extends Query {
|
||||
|
||||
/**
|
||||
* @var array $available_criteria
|
||||
*/
|
||||
protected $available_criteria = [
|
||||
'OR', 'AND',
|
||||
'ALL', 'ANSWERED', 'BCC', 'BEFORE', 'BODY', 'CC', 'DELETED', 'FLAGGED', 'FROM', 'KEYWORD',
|
||||
'NEW', 'NOT', 'OLD', 'ON', 'RECENT', 'SEEN', 'SINCE', 'SUBJECT', 'TEXT', 'TO',
|
||||
'UNANSWERED', 'UNDELETED', 'UNFLAGGED', 'UNKEYWORD', 'UNSEEN', 'UID'
|
||||
];
|
||||
|
||||
/**
|
||||
* Magic method in order to allow alias usage of all "where" methods in an optional connection with "NOT"
|
||||
* @param string $name
|
||||
* @param array|null $arguments
|
||||
*
|
||||
* @return mixed
|
||||
* @throws InvalidWhereQueryCriteriaException
|
||||
* @throws MethodNotFoundException
|
||||
*/
|
||||
public function __call(string $name, $arguments) {
|
||||
$that = $this;
|
||||
|
||||
$name = Str::camel($name);
|
||||
|
||||
if (strtolower(substr($name, 0, 3)) === 'not') {
|
||||
$that = $that->whereNot();
|
||||
$name = substr($name, 3);
|
||||
}
|
||||
|
||||
if (strpos(strtolower($name), "where") === false) {
|
||||
$method = 'where' . ucfirst($name);
|
||||
} else {
|
||||
$method = lcfirst($name);
|
||||
}
|
||||
|
||||
if (method_exists($this, $method) === true) {
|
||||
return call_user_func_array([$that, $method], $arguments);
|
||||
}
|
||||
|
||||
throw new MethodNotFoundException("Method " . self::class . '::' . $method . '() is not supported');
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate a given criteria
|
||||
* @param $criteria
|
||||
*
|
||||
* @return string
|
||||
* @throws InvalidWhereQueryCriteriaException
|
||||
*/
|
||||
protected function validate_criteria($criteria): string {
|
||||
$command = strtoupper($criteria);
|
||||
if (substr($command, 0, 7) === "CUSTOM ") {
|
||||
return substr($criteria, 7);
|
||||
}
|
||||
if (in_array($command, $this->available_criteria) === false) {
|
||||
throw new InvalidWhereQueryCriteriaException("Invalid imap search criteria: $command");
|
||||
}
|
||||
|
||||
return $criteria;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register search parameters
|
||||
* @param mixed $criteria
|
||||
* @param null $value
|
||||
*
|
||||
* @return $this
|
||||
* @throws InvalidWhereQueryCriteriaException
|
||||
*
|
||||
* Examples:
|
||||
* $query->from("someone@email.tld")->seen();
|
||||
* $query->whereFrom("someone@email.tld")->whereSeen();
|
||||
* $query->where([["FROM" => "someone@email.tld"], ["SEEN"]]);
|
||||
* $query->where(["FROM" => "someone@email.tld"])->where(["SEEN"]);
|
||||
* $query->where(["FROM" => "someone@email.tld", "SEEN"]);
|
||||
* $query->where("FROM", "someone@email.tld")->where("SEEN");
|
||||
*/
|
||||
public function where($criteria, $value = null): WhereQuery {
|
||||
if (is_array($criteria)) {
|
||||
foreach ($criteria as $key => $value) {
|
||||
if (is_numeric($key)) {
|
||||
$this->where($value);
|
||||
}else{
|
||||
$this->where($key, $value);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$this->push_search_criteria($criteria, $value);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Push a given search criteria and value pair to the search query
|
||||
* @param $criteria string
|
||||
* @param $value mixed
|
||||
*
|
||||
* @throws InvalidWhereQueryCriteriaException
|
||||
*/
|
||||
protected function push_search_criteria(string $criteria, $value){
|
||||
$criteria = $this->validate_criteria($criteria);
|
||||
$value = $this->parse_value($value);
|
||||
|
||||
if ($value === null || $value === '') {
|
||||
$this->query->push([$criteria]);
|
||||
} else {
|
||||
$this->query->push([$criteria, $value]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Closure $closure
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function orWhere(Closure $closure = null): WhereQuery {
|
||||
$this->query->push(['OR']);
|
||||
if ($closure !== null) $closure($this);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Closure $closure
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function andWhere(Closure $closure = null): WhereQuery {
|
||||
$this->query->push(['AND']);
|
||||
if ($closure !== null) $closure($this);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return WhereQuery
|
||||
* @throws InvalidWhereQueryCriteriaException
|
||||
*/
|
||||
public function whereAll(): WhereQuery {
|
||||
return $this->where('ALL');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return WhereQuery
|
||||
* @throws InvalidWhereQueryCriteriaException
|
||||
*/
|
||||
public function whereAnswered(): WhereQuery {
|
||||
return $this->where('ANSWERED');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $value
|
||||
*
|
||||
* @return WhereQuery
|
||||
* @throws InvalidWhereQueryCriteriaException
|
||||
*/
|
||||
public function whereBcc(string $value): WhereQuery {
|
||||
return $this->where('BCC', $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $value
|
||||
* @return WhereQuery
|
||||
* @throws InvalidWhereQueryCriteriaException
|
||||
* @throws MessageSearchValidationException
|
||||
*/
|
||||
public function whereBefore($value): WhereQuery {
|
||||
$date = $this->parse_date($value);
|
||||
return $this->where('BEFORE', $date);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $value
|
||||
*
|
||||
* @return WhereQuery
|
||||
* @throws InvalidWhereQueryCriteriaException
|
||||
*/
|
||||
public function whereBody(string $value): WhereQuery {
|
||||
return $this->where('BODY', $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $value
|
||||
*
|
||||
* @return WhereQuery
|
||||
* @throws InvalidWhereQueryCriteriaException
|
||||
*/
|
||||
public function whereCc(string $value): WhereQuery {
|
||||
return $this->where('CC', $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return WhereQuery
|
||||
* @throws InvalidWhereQueryCriteriaException
|
||||
*/
|
||||
public function whereDeleted(): WhereQuery {
|
||||
return $this->where('DELETED');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $value
|
||||
*
|
||||
* @return WhereQuery
|
||||
* @throws InvalidWhereQueryCriteriaException
|
||||
*/
|
||||
public function whereFlagged(string $value): WhereQuery {
|
||||
return $this->where('FLAGGED', $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $value
|
||||
*
|
||||
* @return WhereQuery
|
||||
* @throws InvalidWhereQueryCriteriaException
|
||||
*/
|
||||
public function whereFrom(string $value): WhereQuery {
|
||||
return $this->where('FROM', $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $value
|
||||
*
|
||||
* @return WhereQuery
|
||||
* @throws InvalidWhereQueryCriteriaException
|
||||
*/
|
||||
public function whereKeyword(string $value): WhereQuery {
|
||||
return $this->where('KEYWORD', $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return WhereQuery
|
||||
* @throws InvalidWhereQueryCriteriaException
|
||||
*/
|
||||
public function whereNew(): WhereQuery {
|
||||
return $this->where('NEW');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return WhereQuery
|
||||
* @throws InvalidWhereQueryCriteriaException
|
||||
*/
|
||||
public function whereNot(): WhereQuery {
|
||||
return $this->where('NOT');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return WhereQuery
|
||||
* @throws InvalidWhereQueryCriteriaException
|
||||
*/
|
||||
public function whereOld(): WhereQuery {
|
||||
return $this->where('OLD');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $value
|
||||
*
|
||||
* @return WhereQuery
|
||||
* @throws MessageSearchValidationException
|
||||
* @throws InvalidWhereQueryCriteriaException
|
||||
*/
|
||||
public function whereOn($value): WhereQuery {
|
||||
$date = $this->parse_date($value);
|
||||
return $this->where('ON', $date);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return WhereQuery
|
||||
* @throws InvalidWhereQueryCriteriaException
|
||||
*/
|
||||
public function whereRecent(): WhereQuery {
|
||||
return $this->where('RECENT');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return WhereQuery
|
||||
* @throws InvalidWhereQueryCriteriaException
|
||||
*/
|
||||
public function whereSeen(): WhereQuery {
|
||||
return $this->where('SEEN');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $value
|
||||
*
|
||||
* @return WhereQuery
|
||||
* @throws MessageSearchValidationException
|
||||
* @throws InvalidWhereQueryCriteriaException
|
||||
*/
|
||||
public function whereSince($value): WhereQuery {
|
||||
$date = $this->parse_date($value);
|
||||
return $this->where('SINCE', $date);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $value
|
||||
*
|
||||
* @return WhereQuery
|
||||
* @throws InvalidWhereQueryCriteriaException
|
||||
*/
|
||||
public function whereSubject(string $value): WhereQuery {
|
||||
return $this->where('SUBJECT', $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $value
|
||||
*
|
||||
* @return WhereQuery
|
||||
* @throws InvalidWhereQueryCriteriaException
|
||||
*/
|
||||
public function whereText(string $value): WhereQuery {
|
||||
return $this->where('TEXT', $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $value
|
||||
*
|
||||
* @return WhereQuery
|
||||
* @throws InvalidWhereQueryCriteriaException
|
||||
*/
|
||||
public function whereTo(string $value): WhereQuery {
|
||||
return $this->where('TO', $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $value
|
||||
*
|
||||
* @return WhereQuery
|
||||
* @throws InvalidWhereQueryCriteriaException
|
||||
*/
|
||||
public function whereUnkeyword(string $value): WhereQuery {
|
||||
return $this->where('UNKEYWORD', $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return WhereQuery
|
||||
* @throws InvalidWhereQueryCriteriaException
|
||||
*/
|
||||
public function whereUnanswered(): WhereQuery {
|
||||
return $this->where('UNANSWERED');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return WhereQuery
|
||||
* @throws InvalidWhereQueryCriteriaException
|
||||
*/
|
||||
public function whereUndeleted(): WhereQuery {
|
||||
return $this->where('UNDELETED');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return WhereQuery
|
||||
* @throws InvalidWhereQueryCriteriaException
|
||||
*/
|
||||
public function whereUnflagged(): WhereQuery {
|
||||
return $this->where('UNFLAGGED');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return WhereQuery
|
||||
* @throws InvalidWhereQueryCriteriaException
|
||||
*/
|
||||
public function whereUnseen(): WhereQuery {
|
||||
return $this->where('UNSEEN');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return WhereQuery
|
||||
* @throws InvalidWhereQueryCriteriaException
|
||||
*/
|
||||
public function whereNoXSpam(): WhereQuery {
|
||||
return $this->where("CUSTOM X-Spam-Flag NO");
|
||||
}
|
||||
|
||||
/**
|
||||
* @return WhereQuery
|
||||
* @throws InvalidWhereQueryCriteriaException
|
||||
*/
|
||||
public function whereIsXSpam(): WhereQuery {
|
||||
return $this->where("CUSTOM X-Spam-Flag YES");
|
||||
}
|
||||
|
||||
/**
|
||||
* Search for a specific header value
|
||||
* @param $header
|
||||
* @param $value
|
||||
*
|
||||
* @return WhereQuery
|
||||
* @throws InvalidWhereQueryCriteriaException
|
||||
*/
|
||||
public function whereHeader($header, $value): WhereQuery {
|
||||
return $this->where("CUSTOM HEADER $header $value");
|
||||
}
|
||||
|
||||
/**
|
||||
* Search for a specific message id
|
||||
* @param $messageId
|
||||
*
|
||||
* @return WhereQuery
|
||||
* @throws InvalidWhereQueryCriteriaException
|
||||
*/
|
||||
public function whereMessageId($messageId): WhereQuery {
|
||||
return $this->whereHeader("Message-ID", $messageId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Search for a specific message id
|
||||
* @param $messageId
|
||||
*
|
||||
* @return WhereQuery
|
||||
* @throws InvalidWhereQueryCriteriaException
|
||||
*/
|
||||
public function whereInReplyTo($messageId): WhereQuery {
|
||||
return $this->whereHeader("In-Reply-To", $messageId);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $country_code
|
||||
*
|
||||
* @return WhereQuery
|
||||
* @throws InvalidWhereQueryCriteriaException
|
||||
*/
|
||||
public function whereLanguage($country_code): WhereQuery {
|
||||
return $this->where("Content-Language $country_code");
|
||||
}
|
||||
|
||||
/**
|
||||
* Get message be it UID.
|
||||
*
|
||||
* @param int|string $uid
|
||||
*
|
||||
* @return WhereQuery
|
||||
* @throws InvalidWhereQueryCriteriaException
|
||||
*/
|
||||
public function whereUid($uid): WhereQuery {
|
||||
return $this->where('UID', $uid);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get messages by their UIDs.
|
||||
*
|
||||
* @param array<int, int> $uids
|
||||
*
|
||||
* @return WhereQuery
|
||||
* @throws InvalidWhereQueryCriteriaException
|
||||
*/
|
||||
public function whereUidIn(array $uids): WhereQuery {
|
||||
$uids = implode(',', $uids);
|
||||
return $this->where('UID', $uids);
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the callback if the given "value" is truthy.
|
||||
* copied from @url https://github.com/laravel/framework/blob/8.x/src/Illuminate/Support/Traits/Conditionable.php
|
||||
*
|
||||
* @param mixed $value
|
||||
* @param callable $callback
|
||||
* @param callable|null $default
|
||||
* @return $this|mixed
|
||||
*/
|
||||
public function when($value, callable $callback, $default = null) {
|
||||
if ($value) {
|
||||
return $callback($this, $value) ?: $this;
|
||||
} elseif ($default) {
|
||||
return $default($this, $value) ?: $this;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the callback if the given "value" is falsy.
|
||||
* copied from @url https://github.com/laravel/framework/blob/8.x/src/Illuminate/Support/Traits/Conditionable.php
|
||||
*
|
||||
* @param mixed $value
|
||||
* @param callable $callback
|
||||
* @param callable|null $default
|
||||
* @return $this|mixed
|
||||
*/
|
||||
public function unless($value, callable $callback, $default = null) {
|
||||
if (!$value) {
|
||||
return $callback($this, $value) ?: $this;
|
||||
} elseif ($default) {
|
||||
return $default($this, $value) ?: $this;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
174
vendor/webklex/php-imap/src/Structure.php
vendored
Normal file
174
vendor/webklex/php-imap/src/Structure.php
vendored
Normal file
@@ -0,0 +1,174 @@
|
||||
<?php
|
||||
/*
|
||||
* File: Structure.php
|
||||
* Category: -
|
||||
* Author: M.Goldenbaum
|
||||
* Created: 17.09.20 20:38
|
||||
* Updated: -
|
||||
*
|
||||
* Description:
|
||||
* -
|
||||
*/
|
||||
|
||||
namespace Webklex\PHPIMAP;
|
||||
|
||||
|
||||
use Webklex\PHPIMAP\Exceptions\InvalidMessageDateException;
|
||||
use Webklex\PHPIMAP\Exceptions\MessageContentFetchingException;
|
||||
|
||||
/**
|
||||
* Class Structure
|
||||
*
|
||||
* @package Webklex\PHPIMAP
|
||||
*/
|
||||
class Structure {
|
||||
|
||||
/**
|
||||
* Raw structure
|
||||
*
|
||||
* @var string $raw
|
||||
*/
|
||||
public $raw = "";
|
||||
|
||||
/**
|
||||
* @var Header $header
|
||||
*/
|
||||
private $header = null;
|
||||
|
||||
/**
|
||||
* Message type (if multipart or not)
|
||||
*
|
||||
* @var int $type
|
||||
*/
|
||||
public $type = IMAP::MESSAGE_TYPE_TEXT;
|
||||
|
||||
/**
|
||||
* All available parts
|
||||
*
|
||||
* @var Part[] $parts
|
||||
*/
|
||||
public $parts = [];
|
||||
|
||||
/**
|
||||
* Config holder
|
||||
*
|
||||
* @var array $config
|
||||
*/
|
||||
protected $config = [];
|
||||
|
||||
/**
|
||||
* Structure constructor.
|
||||
* @param $raw_structure
|
||||
* @param Header $header
|
||||
*
|
||||
* @throws MessageContentFetchingException
|
||||
* @throws InvalidMessageDateException
|
||||
*/
|
||||
public function __construct($raw_structure, Header $header) {
|
||||
$this->raw = $raw_structure;
|
||||
$this->header = $header;
|
||||
$this->config = ClientManager::get('options');
|
||||
$this->parse();
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the given raw structure
|
||||
*
|
||||
* @throws MessageContentFetchingException
|
||||
* @throws InvalidMessageDateException
|
||||
*/
|
||||
protected function parse(){
|
||||
$this->findContentType();
|
||||
$this->parts = $this->find_parts();
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine the message content type
|
||||
*/
|
||||
public function findContentType(){
|
||||
$content_type = $this->header->get("content_type");
|
||||
$content_type = (is_array($content_type)) ? implode(' ', $content_type) : $content_type;
|
||||
if($content_type && stripos($content_type, 'multipart') === 0) {
|
||||
$this->type = IMAP::MESSAGE_TYPE_MULTIPART;
|
||||
}else{
|
||||
$this->type = IMAP::MESSAGE_TYPE_TEXT;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Find all available headers and return the left over body segment
|
||||
* @var string $context
|
||||
* @var integer $part_number
|
||||
*
|
||||
* @return Part[]
|
||||
* @throws InvalidMessageDateException
|
||||
*/
|
||||
private function parsePart(string $context, int $part_number = 0): array {
|
||||
$body = $context;
|
||||
while (($pos = strpos($body, "\r\n")) > 0) {
|
||||
$body = substr($body, $pos + 2);
|
||||
}
|
||||
$headers = substr($context, 0, strlen($body) * -1);
|
||||
$body = substr($body, 0, -2);
|
||||
|
||||
$headers = new Header($headers);
|
||||
if (($boundary = $headers->getBoundary()) !== null) {
|
||||
return $this->detectParts($boundary, $body, $part_number);
|
||||
}
|
||||
return [new Part($body, $headers, $part_number)];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $boundary
|
||||
* @param string $context
|
||||
* @param int $part_number
|
||||
*
|
||||
* @return array
|
||||
* @throws InvalidMessageDateException
|
||||
*/
|
||||
private function detectParts(string $boundary, string $context, int $part_number = 0): array {
|
||||
$base_parts = explode( $boundary, $context);
|
||||
$final_parts = [];
|
||||
foreach($base_parts as $ctx) {
|
||||
$ctx = substr($ctx, 2);
|
||||
if ($ctx !== "--" && $ctx != "") {
|
||||
$parts = $this->parsePart($ctx, $part_number);
|
||||
foreach ($parts as $part) {
|
||||
$final_parts[] = $part;
|
||||
$part_number = $part->part_number;
|
||||
}
|
||||
$part_number++;
|
||||
}
|
||||
}
|
||||
return $final_parts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find all available parts
|
||||
*
|
||||
* @return array
|
||||
* @throws MessageContentFetchingException
|
||||
* @throws InvalidMessageDateException
|
||||
*/
|
||||
public function find_parts(): array {
|
||||
if($this->type === IMAP::MESSAGE_TYPE_MULTIPART) {
|
||||
if (($boundary = $this->header->getBoundary()) === null) {
|
||||
throw new MessageContentFetchingException("no content found", 0);
|
||||
}
|
||||
|
||||
return $this->detectParts($boundary, $this->raw);
|
||||
}
|
||||
|
||||
return [new Part($this->raw, $this->header)];
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to find a boundary if possible
|
||||
*
|
||||
* @return string|null
|
||||
* @Depricated since version 2.4.4
|
||||
*/
|
||||
public function getBoundary(){
|
||||
return $this->header->getBoundary();
|
||||
}
|
||||
}
|
||||
22
vendor/webklex/php-imap/src/Support/AttachmentCollection.php
vendored
Normal file
22
vendor/webklex/php-imap/src/Support/AttachmentCollection.php
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
/*
|
||||
* File: AttachmentCollection.php
|
||||
* Category: Collection
|
||||
* Author: M. Goldenbaum
|
||||
* Created: 16.03.18 03:13
|
||||
* Updated: -
|
||||
*
|
||||
* Description:
|
||||
* -
|
||||
*/
|
||||
|
||||
namespace Webklex\PHPIMAP\Support;
|
||||
|
||||
/**
|
||||
* Class AttachmentCollection
|
||||
*
|
||||
* @package Webklex\PHPIMAP\Support
|
||||
*/
|
||||
class AttachmentCollection extends PaginatedCollection {
|
||||
|
||||
}
|
||||
22
vendor/webklex/php-imap/src/Support/FlagCollection.php
vendored
Normal file
22
vendor/webklex/php-imap/src/Support/FlagCollection.php
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
/*
|
||||
* File: FlagCollection.php
|
||||
* Category: Collection
|
||||
* Author: M. Goldenbaum
|
||||
* Created: 21.07.18 23:10
|
||||
* Updated: -
|
||||
*
|
||||
* Description:
|
||||
* -
|
||||
*/
|
||||
|
||||
namespace Webklex\PHPIMAP\Support;
|
||||
|
||||
/**
|
||||
* Class FlagCollection
|
||||
*
|
||||
* @package Webklex\PHPIMAP\Support
|
||||
*/
|
||||
class FlagCollection extends PaginatedCollection {
|
||||
|
||||
}
|
||||
22
vendor/webklex/php-imap/src/Support/FolderCollection.php
vendored
Normal file
22
vendor/webklex/php-imap/src/Support/FolderCollection.php
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
/*
|
||||
* File: FolderCollection.php
|
||||
* Category: Collection
|
||||
* Author: M. Goldenbaum
|
||||
* Created: 18.03.18 02:21
|
||||
* Updated: -
|
||||
*
|
||||
* Description:
|
||||
* -
|
||||
*/
|
||||
|
||||
namespace Webklex\PHPIMAP\Support;
|
||||
|
||||
/**
|
||||
* Class FolderCollection
|
||||
*
|
||||
* @package Webklex\PHPIMAP\Support
|
||||
*/
|
||||
class FolderCollection extends PaginatedCollection {
|
||||
|
||||
}
|
||||
44
vendor/webklex/php-imap/src/Support/Masks/AttachmentMask.php
vendored
Normal file
44
vendor/webklex/php-imap/src/Support/Masks/AttachmentMask.php
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
/*
|
||||
* File: AttachmentMask.php
|
||||
* Category: Mask
|
||||
* Author: M.Goldenbaum
|
||||
* Created: 14.03.19 20:49
|
||||
* Updated: -
|
||||
*
|
||||
* Description:
|
||||
* -
|
||||
*/
|
||||
|
||||
namespace Webklex\PHPIMAP\Support\Masks;
|
||||
|
||||
use Webklex\PHPIMAP\Attachment;
|
||||
|
||||
/**
|
||||
* Class AttachmentMask
|
||||
*
|
||||
* @package Webklex\PHPIMAP\Support\Masks
|
||||
*/
|
||||
class AttachmentMask extends Mask {
|
||||
|
||||
/** @var Attachment $parent */
|
||||
protected $parent;
|
||||
|
||||
/**
|
||||
* Get the attachment content base64 encoded
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getContentBase64Encoded() {
|
||||
return base64_encode($this->parent->content);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a base64 image src string
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getImageSrc() {
|
||||
return 'data:'.$this->parent->content_type.';base64,'.$this->getContentBase64Encoded();
|
||||
}
|
||||
}
|
||||
137
vendor/webklex/php-imap/src/Support/Masks/Mask.php
vendored
Executable file
137
vendor/webklex/php-imap/src/Support/Masks/Mask.php
vendored
Executable file
@@ -0,0 +1,137 @@
|
||||
<?php
|
||||
/*
|
||||
* File: Mask.php
|
||||
* Category: Mask
|
||||
* Author: M.Goldenbaum
|
||||
* Created: 14.03.19 20:49
|
||||
* Updated: -
|
||||
*
|
||||
* Description:
|
||||
* -
|
||||
*/
|
||||
|
||||
namespace Webklex\PHPIMAP\Support\Masks;
|
||||
|
||||
use Illuminate\Support\Str;
|
||||
use Webklex\PHPIMAP\Exceptions\MethodNotFoundException;
|
||||
|
||||
/**
|
||||
* Class Mask
|
||||
*
|
||||
* @package Webklex\PHPIMAP\Support\Masks
|
||||
*/
|
||||
class Mask {
|
||||
|
||||
/**
|
||||
* Available attributes
|
||||
*
|
||||
* @var array $attributes
|
||||
*/
|
||||
protected $attributes = [];
|
||||
|
||||
/**
|
||||
* Parent instance
|
||||
*
|
||||
* @var object $parent
|
||||
*/
|
||||
protected $parent;
|
||||
|
||||
/**
|
||||
* Mask constructor.
|
||||
* @param $parent
|
||||
*/
|
||||
public function __construct($parent) {
|
||||
$this->parent = $parent;
|
||||
|
||||
if(method_exists($this->parent, 'getAttributes')){
|
||||
$this->attributes = array_merge($this->attributes, $this->parent->getAttributes());
|
||||
}
|
||||
|
||||
$this->boot();
|
||||
}
|
||||
|
||||
/**
|
||||
* Boot method made to be used by any custom mask
|
||||
*/
|
||||
protected function boot(){}
|
||||
|
||||
/**
|
||||
* Call dynamic attribute setter and getter methods and inherit the parent calls
|
||||
* @param string $method
|
||||
* @param array $arguments
|
||||
*
|
||||
* @return mixed
|
||||
* @throws MethodNotFoundException
|
||||
*/
|
||||
public function __call(string $method, array $arguments) {
|
||||
if(strtolower(substr($method, 0, 3)) === 'get') {
|
||||
$name = Str::snake(substr($method, 3));
|
||||
|
||||
if(isset($this->attributes[$name])) {
|
||||
return $this->attributes[$name];
|
||||
}
|
||||
|
||||
}elseif (strtolower(substr($method, 0, 3)) === 'set') {
|
||||
$name = Str::snake(substr($method, 3));
|
||||
|
||||
if(isset($this->attributes[$name])) {
|
||||
$this->attributes[$name] = array_pop($arguments);
|
||||
|
||||
return $this->attributes[$name];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if(method_exists($this->parent, $method) === true){
|
||||
return call_user_func_array([$this->parent, $method], $arguments);
|
||||
}
|
||||
|
||||
throw new MethodNotFoundException("Method ".self::class.'::'.$method.'() is not supported');
|
||||
}
|
||||
|
||||
/**
|
||||
* Magic setter
|
||||
* @param $name
|
||||
* @param $value
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function __set($name, $value) {
|
||||
$this->attributes[$name] = $value;
|
||||
|
||||
return $this->attributes[$name];
|
||||
}
|
||||
|
||||
/**
|
||||
* Magic getter
|
||||
* @param $name
|
||||
*
|
||||
* @return mixed|null
|
||||
*/
|
||||
public function __get($name) {
|
||||
if(isset($this->attributes[$name])) {
|
||||
return $this->attributes[$name];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the parent instance
|
||||
*
|
||||
* @return object
|
||||
*/
|
||||
public function getParent(){
|
||||
return $this->parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all available attributes
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getAttributes(): array {
|
||||
return $this->attributes;
|
||||
}
|
||||
|
||||
}
|
||||
86
vendor/webklex/php-imap/src/Support/Masks/MessageMask.php
vendored
Normal file
86
vendor/webklex/php-imap/src/Support/Masks/MessageMask.php
vendored
Normal file
@@ -0,0 +1,86 @@
|
||||
<?php
|
||||
/*
|
||||
* File: MessageMask.php
|
||||
* Category: Mask
|
||||
* Author: M.Goldenbaum
|
||||
* Created: 14.03.19 20:49
|
||||
* Updated: -
|
||||
*
|
||||
* Description:
|
||||
* -
|
||||
*/
|
||||
|
||||
namespace Webklex\PHPIMAP\Support\Masks;
|
||||
|
||||
use Webklex\PHPIMAP\Attachment;
|
||||
use Webklex\PHPIMAP\Message;
|
||||
|
||||
/**
|
||||
* Class MessageMask
|
||||
*
|
||||
* @package Webklex\PHPIMAP\Support\Masks
|
||||
*/
|
||||
class MessageMask extends Mask {
|
||||
|
||||
/** @var Message $parent */
|
||||
protected $parent;
|
||||
|
||||
/**
|
||||
* Get the message html body
|
||||
*
|
||||
* @return null
|
||||
*/
|
||||
public function getHtmlBody(){
|
||||
$bodies = $this->parent->getBodies();
|
||||
if (!isset($bodies['html'])) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if(is_object($bodies['html']) && property_exists($bodies['html'], 'content')) {
|
||||
return $bodies['html']->content;
|
||||
}
|
||||
return $bodies['html'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Message html body filtered by an optional callback
|
||||
* @param callable|bool $callback
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getCustomHTMLBody($callback = false) {
|
||||
$body = $this->getHtmlBody();
|
||||
if($body === null) return null;
|
||||
|
||||
if ($callback !== false) {
|
||||
$aAttachment = $this->parent->getAttachments();
|
||||
$aAttachment->each(function($oAttachment) use(&$body, $callback) {
|
||||
/** @var Attachment $oAttachment */
|
||||
if(is_callable($callback)) {
|
||||
$body = $callback($body, $oAttachment);
|
||||
}elseif(is_string($callback)) {
|
||||
call_user_func($callback, [$body, $oAttachment]);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return $body;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Message html body with embedded base64 images
|
||||
* the resulting $body.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getHTMLBodyWithEmbeddedBase64Images() {
|
||||
return $this->getCustomHTMLBody(function($body, $oAttachment){
|
||||
/** @var Attachment $oAttachment */
|
||||
if ($oAttachment->id) {
|
||||
$body = str_replace('cid:'.$oAttachment->id, 'data:'.$oAttachment->getContentType().';base64, '.base64_encode($oAttachment->getContent()), $body);
|
||||
}
|
||||
|
||||
return $body;
|
||||
});
|
||||
}
|
||||
}
|
||||
22
vendor/webklex/php-imap/src/Support/MessageCollection.php
vendored
Normal file
22
vendor/webklex/php-imap/src/Support/MessageCollection.php
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
/*
|
||||
* File: MessageCollection.php
|
||||
* Category: Collection
|
||||
* Author: M. Goldenbaum
|
||||
* Created: 16.03.18 03:13
|
||||
* Updated: -
|
||||
*
|
||||
* Description:
|
||||
* -
|
||||
*/
|
||||
|
||||
namespace Webklex\PHPIMAP\Support;
|
||||
|
||||
/**
|
||||
* Class MessageCollection
|
||||
*
|
||||
* @package Webklex\PHPIMAP\Support
|
||||
*/
|
||||
class MessageCollection extends PaginatedCollection {
|
||||
|
||||
}
|
||||
82
vendor/webklex/php-imap/src/Support/PaginatedCollection.php
vendored
Normal file
82
vendor/webklex/php-imap/src/Support/PaginatedCollection.php
vendored
Normal file
@@ -0,0 +1,82 @@
|
||||
<?php
|
||||
/*
|
||||
* File: PaginatedCollection.php
|
||||
* Category: Collection
|
||||
* Author: M. Goldenbaum
|
||||
* Created: 16.03.18 03:13
|
||||
* Updated: -
|
||||
*
|
||||
* Description:
|
||||
* -
|
||||
*/
|
||||
|
||||
namespace Webklex\PHPIMAP\Support;
|
||||
|
||||
use Illuminate\Pagination\LengthAwarePaginator;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Pagination\Paginator;
|
||||
|
||||
/**
|
||||
* Class PaginatedCollection
|
||||
*
|
||||
* @package Webklex\PHPIMAP\Support
|
||||
*/
|
||||
class PaginatedCollection extends Collection {
|
||||
|
||||
/**
|
||||
* Number of total entries
|
||||
*
|
||||
* @var int $total
|
||||
*/
|
||||
protected $total;
|
||||
|
||||
/**
|
||||
* Paginate the current collection.
|
||||
* @param int $per_page
|
||||
* @param int|null $page
|
||||
* @param string $page_name
|
||||
* @param boolean $prepaginated
|
||||
*
|
||||
* @return LengthAwarePaginator
|
||||
*/
|
||||
public function paginate(int $per_page = 15, $page = null, string $page_name = 'page', bool $prepaginated = false): LengthAwarePaginator {
|
||||
$page = $page ?: Paginator::resolveCurrentPage($page_name);
|
||||
|
||||
$total = $this->total ?: $this->count();
|
||||
|
||||
$results = !$prepaginated && $total ? $this->forPage($page, $per_page)->toArray() : $this->all();
|
||||
|
||||
return $this->paginator($results, $total, $per_page, $page, [
|
||||
'path' => Paginator::resolveCurrentPath(),
|
||||
'pageName' => $page_name,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new length-aware paginator instance.
|
||||
* @param array $items
|
||||
* @param int $total
|
||||
* @param int $per_page
|
||||
* @param int|null $current_page
|
||||
* @param array $options
|
||||
*
|
||||
* @return LengthAwarePaginator
|
||||
*/
|
||||
protected function paginator(array $items, int $total, int $per_page, $current_page, array $options): LengthAwarePaginator {
|
||||
return new LengthAwarePaginator($items, $total, $per_page, $current_page, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get and set the total amount
|
||||
* @param null $total
|
||||
*
|
||||
* @return int|null
|
||||
*/
|
||||
public function total($total = null) {
|
||||
if($total === null) {
|
||||
return $this->total;
|
||||
}
|
||||
|
||||
return $this->total = $total;
|
||||
}
|
||||
}
|
||||
77
vendor/webklex/php-imap/src/Traits/HasEvents.php
vendored
Normal file
77
vendor/webklex/php-imap/src/Traits/HasEvents.php
vendored
Normal file
@@ -0,0 +1,77 @@
|
||||
<?php
|
||||
/*
|
||||
* File: HasEvents.php
|
||||
* Category: -
|
||||
* Author: M.Goldenbaum
|
||||
* Created: 21.09.20 22:46
|
||||
* Updated: -
|
||||
*
|
||||
* Description:
|
||||
* -
|
||||
*/
|
||||
|
||||
namespace Webklex\PHPIMAP\Traits;
|
||||
|
||||
|
||||
use Webklex\PHPIMAP\Events\Event;
|
||||
use Webklex\PHPIMAP\Exceptions\EventNotFoundException;
|
||||
|
||||
/**
|
||||
* Trait HasEvents
|
||||
*
|
||||
* @package Webklex\PHPIMAP\Traits
|
||||
*/
|
||||
trait HasEvents {
|
||||
|
||||
/**
|
||||
* Event holder
|
||||
*
|
||||
* @var array $events
|
||||
*/
|
||||
protected $events = [];
|
||||
|
||||
/**
|
||||
* Set a specific event
|
||||
* @param $section
|
||||
* @param $event
|
||||
* @param $class
|
||||
*/
|
||||
public function setEvent($section, $event, $class) {
|
||||
if (isset($this->events[$section])) {
|
||||
$this->events[$section][$event] = $class;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set all events
|
||||
* @param $events
|
||||
*/
|
||||
public function setEvents($events) {
|
||||
$this->events = $events;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a specific event callback
|
||||
* @param $section
|
||||
* @param $event
|
||||
*
|
||||
* @return Event|string
|
||||
* @throws EventNotFoundException
|
||||
*/
|
||||
public function getEvent($section, $event) {
|
||||
if (isset($this->events[$section])) {
|
||||
return $this->events[$section][$event];
|
||||
}
|
||||
throw new EventNotFoundException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all events
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getEvents(): array {
|
||||
return $this->events;
|
||||
}
|
||||
|
||||
}
|
||||
226
vendor/webklex/php-imap/src/config/imap.php
vendored
Normal file
226
vendor/webklex/php-imap/src/config/imap.php
vendored
Normal file
@@ -0,0 +1,226 @@
|
||||
<?php
|
||||
/*
|
||||
* File: imap.php
|
||||
* Category: config
|
||||
* Author: M. Goldenbaum
|
||||
* Created: 24.09.16 22:36
|
||||
* Updated: -
|
||||
*
|
||||
* Description:
|
||||
* -
|
||||
*/
|
||||
|
||||
return [
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Default date format
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| The default date format is used to convert any given Carbon::class object into a valid date string.
|
||||
| These are currently known working formats: "d-M-Y", "d-M-y", "d M y"
|
||||
|
|
||||
*/
|
||||
'date_format' => 'd-M-Y',
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Default account
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| The default account identifier. It will be used as default for any missing account parameters.
|
||||
| If however the default account is missing a parameter the package default will be used.
|
||||
| Set to 'false' [boolean] to disable this functionality.
|
||||
|
|
||||
*/
|
||||
'default' => 'default',
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Available accounts
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Please list all IMAP accounts which you are planning to use within the
|
||||
| array below.
|
||||
|
|
||||
*/
|
||||
'accounts' => [
|
||||
|
||||
'default' => [// account identifier
|
||||
'host' => 'localhost',
|
||||
'port' => 993,
|
||||
'protocol' => 'imap', //might also use imap, [pop3 or nntp (untested)]
|
||||
'encryption' => 'ssl', // Supported: false, 'ssl', 'tls'
|
||||
'validate_cert' => true,
|
||||
'username' => 'root@example.com',
|
||||
'password' => '',
|
||||
'authentication' => null,
|
||||
'proxy' => [
|
||||
'socket' => null,
|
||||
'request_fulluri' => false,
|
||||
'username' => null,
|
||||
'password' => null,
|
||||
],
|
||||
"timeout" => 30,
|
||||
"extensions" => []
|
||||
],
|
||||
|
||||
/*
|
||||
'gmail' => [ // account identifier
|
||||
'host' => 'imap.gmail.com',
|
||||
'port' => 993,
|
||||
'encryption' => 'ssl',
|
||||
'validate_cert' => true,
|
||||
'username' => 'example@gmail.com',
|
||||
'password' => 'PASSWORD',
|
||||
'authentication' => 'oauth',
|
||||
],
|
||||
|
||||
'another' => [ // account identifier
|
||||
'host' => '',
|
||||
'port' => 993,
|
||||
'encryption' => false,
|
||||
'validate_cert' => true,
|
||||
'username' => '',
|
||||
'password' => '',
|
||||
'authentication' => null,
|
||||
]
|
||||
*/
|
||||
],
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Available IMAP options
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Available php imap config parameters are listed below
|
||||
| -Delimiter (optional):
|
||||
| This option is only used when calling $oClient->
|
||||
| You can use any supported char such as ".", "/", (...)
|
||||
| -Fetch option:
|
||||
| IMAP::FT_UID - Message marked as read by fetching the body message
|
||||
| IMAP::FT_PEEK - Fetch the message without setting the "seen" flag
|
||||
| -Fetch sequence id:
|
||||
| IMAP::ST_UID - Fetch message components using the message uid
|
||||
| IMAP::ST_MSGN - Fetch message components using the message number
|
||||
| -Body download option
|
||||
| Default TRUE
|
||||
| -Flag download option
|
||||
| Default TRUE
|
||||
| -Soft fail
|
||||
| Default FALSE - Set to TRUE if you want to ignore certain exception while fetching bulk messages
|
||||
| -RFC822
|
||||
| Default TRUE - Set to FALSE to prevent the usage of \imap_rfc822_parse_headers().
|
||||
| See https://github.com/Webklex/php-imap/issues/115 for more information.
|
||||
| -Debug enable to trace communication traffic
|
||||
| -UID cache enable the UID cache
|
||||
| -Fallback date is used if the given message date could not be parsed
|
||||
| -Boundary regex used to detect message boundaries. If you are having problems with empty messages, missing
|
||||
| attachments or anything like this. Be advised that it likes to break which causes new problems..
|
||||
| -Message key identifier option
|
||||
| You can choose between the following:
|
||||
| 'id' - Use the MessageID as array key (default, might cause hickups with yahoo mail)
|
||||
| 'number' - Use the message number as array key (isn't always unique and can cause some interesting behavior)
|
||||
| 'list' - Use the message list number as array key (incrementing integer (does not always start at 0 or 1)
|
||||
| 'uid' - Use the message uid as array key (isn't always unique and can cause some interesting behavior)
|
||||
| -Fetch order
|
||||
| 'asc' - Order all messages ascending (probably results in oldest first)
|
||||
| 'desc' - Order all messages descending (probably results in newest first)
|
||||
| -Disposition types potentially considered an attachment
|
||||
| Default ['attachment', 'inline']
|
||||
| -Common folders
|
||||
| Default folder locations and paths assumed if none is provided
|
||||
| -Open IMAP options:
|
||||
| DISABLE_AUTHENTICATOR - Disable authentication properties.
|
||||
| Use 'GSSAPI' if you encounter the following
|
||||
| error: "Kerberos error: No credentials cache
|
||||
| file found (try running kinit) (...)"
|
||||
| or ['GSSAPI','PLAIN'] if you are using outlook mail
|
||||
| -Decoder options (currently only the message subject and attachment name decoder can be set)
|
||||
| 'utf-8' - Uses imap_utf8($string) to decode a string
|
||||
| 'mimeheader' - Uses mb_decode_mimeheader($string) to decode a string
|
||||
|
|
||||
*/
|
||||
'options' => [
|
||||
'delimiter' => '/',
|
||||
'fetch' => \Webklex\PHPIMAP\IMAP::FT_PEEK,
|
||||
'sequence' => \Webklex\PHPIMAP\IMAP::ST_UID,
|
||||
'fetch_body' => true,
|
||||
'fetch_flags' => true,
|
||||
'soft_fail' => false,
|
||||
'rfc822' => true,
|
||||
'debug' => false,
|
||||
'uid_cache' => true,
|
||||
// 'fallback_date' => "01.01.1970 00:00:00",
|
||||
'boundary' => '/boundary=(.*?(?=;)|(.*))/i',
|
||||
'message_key' => 'list',
|
||||
'fetch_order' => 'asc',
|
||||
'dispositions' => ['attachment', 'inline'],
|
||||
'common_folders' => [
|
||||
"root" => "INBOX",
|
||||
"junk" => "INBOX/Junk",
|
||||
"draft" => "INBOX/Drafts",
|
||||
"sent" => "INBOX/Sent",
|
||||
"trash" => "INBOX/Trash",
|
||||
],
|
||||
'decoder' => [
|
||||
'message' => 'utf-8', // mimeheader
|
||||
'attachment' => 'utf-8' // mimeheader
|
||||
],
|
||||
'open' => [
|
||||
// 'DISABLE_AUTHENTICATOR' => 'GSSAPI'
|
||||
]
|
||||
],
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Available flags
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| List all available / supported flags. Set to null to accept all given flags.
|
||||
*/
|
||||
'flags' => ['recent', 'flagged', 'answered', 'deleted', 'seen', 'draft'],
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Available events
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
*/
|
||||
'events' => [
|
||||
"message" => [
|
||||
'new' => \Webklex\PHPIMAP\Events\MessageNewEvent::class,
|
||||
'moved' => \Webklex\PHPIMAP\Events\MessageMovedEvent::class,
|
||||
'copied' => \Webklex\PHPIMAP\Events\MessageCopiedEvent::class,
|
||||
'deleted' => \Webklex\PHPIMAP\Events\MessageDeletedEvent::class,
|
||||
'restored' => \Webklex\PHPIMAP\Events\MessageRestoredEvent::class,
|
||||
],
|
||||
"folder" => [
|
||||
'new' => \Webklex\PHPIMAP\Events\FolderNewEvent::class,
|
||||
'moved' => \Webklex\PHPIMAP\Events\FolderMovedEvent::class,
|
||||
'deleted' => \Webklex\PHPIMAP\Events\FolderDeletedEvent::class,
|
||||
],
|
||||
"flag" => [
|
||||
'new' => \Webklex\PHPIMAP\Events\FlagNewEvent::class,
|
||||
'deleted' => \Webklex\PHPIMAP\Events\FlagDeletedEvent::class,
|
||||
],
|
||||
],
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Available masking options
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| By using your own custom masks you can implement your own methods for
|
||||
| a better and faster access and less code to write.
|
||||
|
|
||||
| Checkout the two examples custom_attachment_mask and custom_message_mask
|
||||
| for a quick start.
|
||||
|
|
||||
| The provided masks below are used as the default masks.
|
||||
*/
|
||||
'masks' => [
|
||||
'message' => \Webklex\PHPIMAP\Support\Masks\MessageMask::class,
|
||||
'attachment' => \Webklex\PHPIMAP\Support\Masks\AttachmentMask::class
|
||||
]
|
||||
];
|
||||
26
vendor/webklex/php-imap/tests/InitialTest.php
vendored
Normal file
26
vendor/webklex/php-imap/tests/InitialTest.php
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
/*
|
||||
* File: InitialTest.php
|
||||
* Category: test
|
||||
* Author: M.Goldenbaum
|
||||
* Created: 02.01.21 04:42
|
||||
* Updated: -
|
||||
*
|
||||
* Description:
|
||||
* -
|
||||
*/
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use \Webklex\PHPIMAP\ClientManager;
|
||||
|
||||
class InitialTest extends TestCase {
|
||||
protected $cm;
|
||||
|
||||
public function setUp() {
|
||||
$this->cm = new ClientManager();
|
||||
}
|
||||
|
||||
public function testConfigDefaultAccount() {
|
||||
$this->assertEquals("default", ClientManager::get("default"));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user