Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merging custom config array with default config in ClientManager #193

Closed
laurent-rizer opened this issue Jan 28, 2022 · 3 comments · Fixed by #194 or rizer-io/php-imap#3
Closed

Merging custom config array with default config in ClientManager #193

laurent-rizer opened this issue Jan 28, 2022 · 3 comments · Fixed by #194 or rizer-io/php-imap#3
Labels
bug Something isn't working

Comments

@laurent-rizer
Copy link
Contributor

Describe the bug
When merging a custom config array with the default config array, it is not possible to "remove" one of the value from the default config.
ie.
Default config is ['dispositions' => ['attachment', 'inline']]
My local config is ['dispositions' => ['attachment']]
The config stored in ClientManager::$config is ['dispositions' => ['attachment', 'inline']] when I expect it to be ['dispositions' => ['attachment']]

Used config

$customConfig = [
            'date_format' => 'd-M-Y',
            'default' => 'default',
            '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' => '[email protected]',
                    'password' => '',
                    'authentication' => null,
                    'proxy' => [
                        'socket' => null,
                        'request_fulluri' => false,
                        'username' => null,
                        'password' => null,
                    ],
                    'timeout' => 30,
                    'extensions' => [],
                ],
            ],
            'options' => [
                'delimiter' => '/',
                'fetch' => \Webklex\PHPIMAP\IMAP::FT_PEEK,
                'sequence' => \Webklex\PHPIMAP\IMAP::ST_UID,
                'fetch_body' => false,
                'fetch_flags' => false,
                'soft_fail' => false,
                'rfc822' => true,
                'debug' => false,
                'boundary' => '/boundary=(.*?(?=;)|(.*))/i',
                'message_key' => 'id',
                'fetch_order' => 'asc',
                'dispositions' => ['attachment'],
                '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'
                ],
            ],
            'flags' => ['recent', 'flagged', 'answered', 'deleted', 'seen', 'draft'],
            '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,
                ],
            ],
            'masks' => [
                'message' => \Webklex\PHPIMAP\Support\Masks\MessageMask::class,
                'attachment' => \Webklex\PHPIMAP\Support\Masks\AttachmentMask::class,
            ],
        ];

Code to Reproduce

$clientManager = (new ClientManager($customConfig)); // $customConfig defined above
// var_dump($clientManager::$config);
var_dump($clientManager::$config['options']['dispositions']); 
/*
array(2) {
  [0]=>
  string(10) "attachment"
  [1]=>
  string(6) "inline"
}
*/

Expected behavior
It should be possible to fully overwrite the default values of config array

$clientManager = (new ClientManager($customConfig)); // $customConfig defined above
// var_dump($clientManager::$config);
var_dump($clientManager::$config['options']['dispositions']); 
/*
array(2) {
  [0]=>
  string(10) "attachment"
}
*/

Proposed resolution

diff --git a/src/ClientManager.php b/src/ClientManager.php
index 3daf9f8..d2da699 100644
--- a/src/ClientManager.php
+++ b/src/ClientManager.php
@@ -232,6 +232,12 @@ class ClientManager {
         $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) {
@@ -241,12 +247,24 @@ class ClientManager {
             foreach($append as $key => $value) {
 
                 if(!array_key_exists($key, $base) and !is_numeric($key)) {
-                    $base[$key] = $append[$key];
+                    $base[$key] = $value;
                     continue;
                 }
 
-                if(is_array($value) or is_array($base[$key])) {
-                    $base[$key] = $this->array_merge_recursive_distinct($base[$key], $append[$key]);
+                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 {
@laurent-rizer
Copy link
Contributor Author

I did create a PR to resolve this: #194

@laurent-rizer
Copy link
Contributor Author

Issue has been closed due to merging on my fork's master, I didn't expect that

@laurent-rizer laurent-rizer reopened this Jan 28, 2022
@Webklex Webklex added the bug Something isn't working label Feb 3, 2022
@Webklex
Copy link
Owner

Webklex commented Feb 3, 2022

Hi @laurent-rizer ,
many thanks for your pull requests and your well written reports.

I highly appreciate it!

Best regards,

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
2 participants