• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

grueneschweiz / mailchimpservice / 16296819851

15 Jul 2025 02:57PM UTC coverage: 70.196% (-1.4%) from 71.551%
16296819851

push

github

web-flow
Merge pull request #85 from grueneschweiz/ignore_mailchimp_new_subscription

Allow admins to disable Notifications for direct Subscriptions in Mailchimp

3 of 9 new or added lines in 2 files covered. (33.33%)

11 existing lines in 2 files now uncovered.

822 of 1171 relevant lines covered (70.2%)

11.29 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

86.21
/app/Synchronizer/Config.php
1
<?php
2

3

4
namespace App\Synchronizer;
5

6

7
use App\Exceptions\ConfigException;
8
use App\Synchronizer\Mapper\FieldMapFacade;
9
use Symfony\Component\Yaml\Exception\ParseException;
10
use Symfony\Component\Yaml\Yaml;
11

12
class Config
13
{
14
    private const CRM_ID_KEY = 'id';
15
    
16
    private $fields;
17
    private $auth;
18
    private $dataOwner;
19
    private $mailchimp;
20
    private $errors;
21
    private $crmEmailKey;
22
    private $webling;
23
    
24
    /**
25
     * Config constructor.
26
     *
27
     * @param string $configFileName file name of the config file
28
     *
29
     * @throws ConfigException
30
     */
31
    public function __construct(string $configFileName)
32
    {
33
        $this->loadConfig($configFileName);
47✔
34
    }
35
    
36
    /**
37
     * Read the config file and populate object
38
     *
39
     * @param string $configFileName file name of the config file
40
     *
41
     * @throws ConfigException
42
     */
43
    private function loadConfig(string $configFileName)
44
    {
45
        $configFileName = ltrim($configFileName, './');
47✔
46
        $configFolderPath = rtrim(config('app.config_base_path'), '/');
47✔
47
        $configFilePath = base_path($configFolderPath . '/' . $configFileName);
47✔
48
        
49
        if (!file_exists($configFilePath)) {
47✔
50
            throw new ConfigException('The config file was not found.');
×
51
        }
52
        
53
        try {
54
            $config = Yaml::parseFile($configFilePath);
47✔
55
        } catch (ParseException $e) {
×
56
            throw new ConfigException("YAML parse error: {$e->getMessage()}");
×
57
        }
58
        
59
        // prevalidate config
60
        if ($config['auth']) {
47✔
61
            $this->auth = $config['auth'];
47✔
62
        } else {
63
            throw new ConfigException("Missing 'auth' section.");
×
64
        }
65
        
66
        if ($config['dataOwner']) {
47✔
67
            $this->dataOwner = $config['dataOwner'];
47✔
68
        } else {
69
            throw new ConfigException("Missing 'dataOwner' section.");
×
70
        }
71
        
72
        if ($config['mailchimp']) {
47✔
73
            $this->mailchimp = $config['mailchimp'];
47✔
74
        } else {
75
            throw new ConfigException("Missing 'mailchimp' section.");
×
76
        }
77
    
78
        if ($config['fields']) {
47✔
79
            $this->fields = $config['fields'];
47✔
80
        } else {
81
            throw new ConfigException("Missing 'fields' section.");
×
82
        }
83
    
84
        if (isset($config['webling'])) {
47✔
85
            $this->webling = $config['webling'];
47✔
86
        }
87
    }
88
    
89
    public static function getCrmIdKey()
90
    {
91
        return self::CRM_ID_KEY;
23✔
92
    }
93
    
94
    /**
95
     * Return array with crm credentials
96
     *
97
     * @return array {clientId: string, clientSecret: string, url: string}
98
     *
99
     * @throws ConfigException
100
     */
101
    public function getCrmCredentials(): array
102
    {
103
        if (empty($this->auth['crm'])
4✔
104
            || empty($this->auth['crm']['clientId'])
4✔
105
            || empty($this->auth['crm']['clientSecret'])
2✔
106
            || empty($this->auth['crm']['url'])
4✔
107
        ) {
108
            throw new ConfigException("Missing CRM credentials.");
2✔
109
        }
110
        
111
        return $this->auth['crm'];
2✔
112
    }
113
    
114
    /**
115
     * Return array with mailchimp credentials
116
     *
117
     * @return array {apikey: string, url: string}
118
     *
119
     * @throws ConfigException
120
     */
121
    public function getMailchimpCredentials(): array
122
    {
123
        if (empty($this->auth['mailchimp'])
4✔
124
            || empty($this->auth['mailchimp']['apikey'])
4✔
125
        ) {
126
            throw new ConfigException("Missing Mailchimp credentials.");
2✔
127
        }
128
        
129
        return $this->auth['mailchimp'];
2✔
130
    }
131
    
132
    /**
133
     * Return array with name and email of data owner
134
     *
135
     * @return array {email: string, name: string,}
136
     *
137
     * @throws ConfigException
138
     */
139
    public function getDataOwner(): array
140
    {
141
        if (empty($this->dataOwner)
5✔
142
            || empty($this->dataOwner['email'])
5✔
143
            || empty($this->dataOwner['name'])
5✔
144
        ) {
145
            throw new ConfigException("Missing data owner details.");
2✔
146
        }
147
        
148
        return $this->dataOwner;
3✔
149
    }
150
    
151
    /**
152
     * Return bool that indicates if all records should be synced even if they dont have
153
     * relevant subscriptions
154
     *
155
     * @return bool
156
     */
157
    public function getSyncAll(): bool
158
    {
159
        if (array_key_exists('syncAll', $this->mailchimp)) {
30✔
160
            return filter_var($this->mailchimp['syncAll'], FILTER_VALIDATE_BOOLEAN);
30✔
161
        }
162
        
163
        return false;
×
164
    }
165

166
    /**
167
     * Return bool that indicates if subscriptions through mailchimp should be ignored
168
     *
169
     * @return bool
170
     */
171
    public function getIgnoreSubscribeThroughMailchimp(): bool
172
    {
173
        if (array_key_exists('ignoreSubscribeThroughMailchimp', $this->mailchimp)) {
2✔
174
            return filter_var($this->mailchimp['ignoreSubscribeThroughMailchimp'], FILTER_VALIDATE_BOOLEAN);
2✔
175
        }
176

NEW
177
        return false;
×
178
    }
179
    
180
    /**
181
     * Return the default list id in Mailchimp
182
     *
183
     * @return string the list id
184
     *
185
     * @throws ConfigException
186
     */
187
    public function getMailchimpListId(): string
188
    {
189
        if (empty($this->mailchimp['listId'])) {
34✔
190
            throw new ConfigException("Missing mailchimp list id.");
2✔
191
        }
192

193
        return $this->mailchimp['listId'];
32✔
194
    }
195

196
    /**
197
     * Return the tag that should be added to new subscribers
198
     *
199
     * @return string
200
     */
201
    public function getNewTag(): string
202
    {
203
        if (empty($this->mailchimp['newtag'])) {
1✔
204
            return 'new';
1✔
205
        }
206

207
        return $this->mailchimp['newtag'];
×
208
    }
209

210
    /**
211
     * The mailchimp merge field key that corresponds to the crm's id
212
     *
213
     * @return string
214
     * @throws ConfigException
215
     */
216
    public function getMailchimpKeyOfCrmId(): string
217
    {
218
        foreach ($this->getFieldMaps() as $map) {
26✔
219
            if (self::CRM_ID_KEY === $map->getCrmKey()) {
26✔
220
                $keys = array_keys($map->getMailchimpDataArray());
24✔
221
                
222
                return reset($keys);
24✔
223
            }
224
        }
225
        
226
        throw new ConfigException('Missing "' . self::CRM_ID_KEY . '" field.');
2✔
227
    }
228
    
229
    /**
230
     * Return array with the field maps
231
     *
232
     * @return FieldMapFacade[]
233
     *
234
     * @throws ConfigException
235
     */
236
    public function getFieldMaps(): array
237
    {
238
        if (!is_array($this->fields)) {
41✔
239
            throw new ConfigException("Fields configuration must be an array.");
×
240
        }
241
        
242
        $fields = [];
41✔
243
        foreach ($this->fields as $config) {
41✔
244
            $fields[] = new FieldMapFacade($config);
41✔
245
        }
246
        
247
        return $fields;
41✔
248
    }
249
    
250
    /**
251
     * Return the field key in the crm that corresponds to the email field
252
     *
253
     * @return string
254
     * @throws ConfigException
255
     */
256
    public function getCrmEmailKey(): string
257
    {
258
        if ($this->crmEmailKey) {
19✔
259
            return $this->crmEmailKey;
18✔
260
        }
261
        
262
        foreach ($this->getFieldMaps() as $map) {
19✔
263
            if ($map->isEmail()) {
19✔
264
                $this->crmEmailKey = $map->getCrmKey();
19✔
265
        
266
                return $this->crmEmailKey;
19✔
267
            }
268
        }
269
    
270
        throw new ConfigException('Missing email field.');
×
271
    }
272
    
273
    /**
274
     * Return array of the Webling group ids of the prioritized groups
275
     *
276
     * @return int[]
277
     */
278
    public function getPrioritizedGroups(): array
279
    {
280
        return $this->webling['prioritizedGroups'] ?? [];
5✔
281
    }
282
    
283
    /**
284
     * Return the validation errors of this config
285
     *
286
     * @return array
287
     */
288
    public function getErrors(): array
289
    {
290
        if (is_null($this->errors)) {
1✔
291
            $this->isValid();
1✔
292
        }
293
        
294
        return $this->errors;
1✔
295
    }
296
    
297
    /**
298
     * Return true, if the given config is valid
299
     *
300
     * @return bool
301
     */
302
    public function isValid(): bool
303
    {
304
        $methods = [
3✔
305
            'getCrmCredentials',
3✔
306
            'getDataOwner',
3✔
307
            'getFieldMaps',
3✔
308
            'getMailchimpCredentials',
3✔
309
            'getMailchimpKeyOfCrmId',
3✔
310
            'getMailchimpListId'
3✔
311
        ];
3✔
312
        
313
        $this->errors = [];
3✔
314
        foreach ($methods as $method) {
3✔
315
            // we throw errors and catch them, because one can also change the config
316
            // while the endpoint is already established, so the validation is not
317
            // necessarily executed.
318
            try {
319
                $this->$method();
3✔
320
            } catch (ConfigException $e) {
2✔
321
                $this->errors[] = $e->getMessage();
2✔
322
            }
323
        }
324
        
325
        return empty($this->errors);
3✔
326
    }
327
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc