Completed
Push — release-2.x ( 370844...c278f6 )
by A.
05:18
created

updateAllowedSecondFactorList()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 17
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 0
loc 17
rs 9.4285
cc 3
eloc 9
nc 2
nop 1
1
<?php
2
3
/**
4
 * Copyright 2016 SURFnet B.V.
5
 *
6
 * Licensed under the Apache License, Version 2.0 (the "License");
7
 * you may not use this file except in compliance with the License.
8
 * You may obtain a copy of the License at
9
 *
10
 *     http://www.apache.org/licenses/LICENSE-2.0
11
 *
12
 * Unless required by applicable law or agreed to in writing, software
13
 * distributed under the License is distributed on an "AS IS" BASIS,
14
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
 * See the License for the specific language governing permissions and
16
 * limitations under the License.
17
 */
18
19
namespace Surfnet\Stepup\Configuration;
20
21
use Broadway\EventSourcing\EventSourcedAggregateRoot;
22
use Surfnet\Stepup\Configuration\Api\InstitutionConfiguration as InstitutionConfigurationInterface;
23
use Surfnet\Stepup\Configuration\Entity\RaLocation;
24
use Surfnet\Stepup\Configuration\Event\AllowedSecondFactorListUpdatedEvent;
25
use Surfnet\Stepup\Configuration\Event\InstitutionConfigurationRemovedEvent;
26
use Surfnet\Stepup\Configuration\Event\NewInstitutionConfigurationCreatedEvent;
27
use Surfnet\Stepup\Configuration\Event\RaLocationAddedEvent;
28
use Surfnet\Stepup\Configuration\Event\RaLocationContactInformationChangedEvent;
29
use Surfnet\Stepup\Configuration\Event\RaLocationRelocatedEvent;
30
use Surfnet\Stepup\Configuration\Event\RaLocationRemovedEvent;
31
use Surfnet\Stepup\Configuration\Event\RaLocationRenamedEvent;
32
use Surfnet\Stepup\Configuration\Event\ShowRaaContactInformationOptionChangedEvent;
33
use Surfnet\Stepup\Configuration\Event\UseRaLocationsOptionChangedEvent;
34
use Surfnet\Stepup\Configuration\Value\AllowedSecondFactorList;
35
use Surfnet\Stepup\Configuration\Value\ContactInformation;
36
use Surfnet\Stepup\Configuration\Value\Institution;
37
use Surfnet\Stepup\Configuration\Value\InstitutionConfigurationId;
38
use Surfnet\Stepup\Configuration\Value\Location;
39
use Surfnet\Stepup\Configuration\Value\RaLocationId;
40
use Surfnet\Stepup\Configuration\Value\RaLocationList;
41
use Surfnet\Stepup\Configuration\Value\RaLocationName;
42
use Surfnet\Stepup\Configuration\Value\ShowRaaContactInformationOption;
43
use Surfnet\Stepup\Configuration\Value\UseRaLocationsOption;
44
use Surfnet\Stepup\Exception\DomainException;
45
46
/**
47
 * @SuppressWarnings(PHPMD.CouplingBetweenObjects) Events and value objects
48
 * @SuppressWarnings(PHPMD.TooManyPublicMethods) AggregateRoot
49
 */
50
class InstitutionConfiguration extends EventSourcedAggregateRoot implements InstitutionConfigurationInterface
51
{
52
    /**
53
     * @var InstitutionConfigurationId
54
     */
55
    private $institutionConfigurationId;
56
57
    /**
58
     * @var Institution
59
     */
60
    private $institution;
61
62
    /**
63
     * @var RaLocationList
64
     */
65
    private $raLocations;
66
67
    /**
68
     * @var UseRaLocationsOption
69
     */
70
    private $useRaLocationsOption;
71
72
    /**
73
     * @var ShowRaaContactInformationOption
74
     */
75
    private $showRaaContactInformationOption;
76
77
    /**
78
     * @var AllowedSecondFactorList
79
     */
80
    private $allowedSecondFactorList;
81
82
    /**
83
     * @var boolean
84
     */
85
    private $isMarkedAsDestroyed;
86
87
    /**
88
     * @param InstitutionConfigurationId $institutionConfigurationId
89
     * @param Institution $institution
90
     * @return InstitutionConfiguration
91
     */
92
    public static function create(InstitutionConfigurationId $institutionConfigurationId, Institution $institution)
93
    {
94
        $institutionConfiguration = new self;
95
        $institutionConfiguration->apply(
96
            new NewInstitutionConfigurationCreatedEvent(
97
                $institutionConfigurationId,
98
                $institution,
99
                UseRaLocationsOption::getDefault(),
100
                ShowRaaContactInformationOption::getDefault()
101
            )
102
        );
103
        $institutionConfiguration->apply(new AllowedSecondFactorListUpdatedEvent(
104
            $institutionConfigurationId,
105
            $institution,
106
            AllowedSecondFactorList::blank()
107
        ));
108
109
        return $institutionConfiguration;
110
    }
111
112
    /**
113
     * @return InstitutionConfiguration
114
     */
115
    public function rebuild()
116
    {
117
        // We can only rebuild a destroyed InstitutionConfiguration, all other cases are not valid
118
        if ($this->isMarkedAsDestroyed !== true) {
119
            throw new DomainException('Cannot rebuild InstitutionConfiguration as it has not been destroyed');
120
        }
121
122
        $this->apply(
123
            new NewInstitutionConfigurationCreatedEvent(
124
                $this->institutionConfigurationId,
125
                $this->institution,
126
                UseRaLocationsOption::getDefault(),
127
                ShowRaaContactInformationOption::getDefault()
128
            )
129
        );
130
        $this->apply(new AllowedSecondFactorListUpdatedEvent(
131
            $this->institutionConfigurationId,
132
            $this->institution,
133
            AllowedSecondFactorList::blank()
134
        ));
135
136
        return $this;
137
    }
138
139
    final public function __construct()
140
    {
141
    }
142
143
    public function configureUseRaLocationsOption(UseRaLocationsOption $useRaLocationsOption)
144
    {
145
        if ($this->useRaLocationsOption->equals($useRaLocationsOption)) {
146
            return;
147
        }
148
149
        $this->apply(
150
            new UseRaLocationsOptionChangedEvent(
151
                $this->institutionConfigurationId,
152
                $this->institution,
153
                $useRaLocationsOption
154
            )
155
        );
156
    }
157
158
    public function configureShowRaaContactInformationOption(ShowRaaContactInformationOption $showRaaContactInformationOption)
0 ignored issues
show
Comprehensibility Naming introduced by
The variable name $showRaaContactInformationOption exceeds the maximum configured length of 30.

Very long variable names usually make code harder to read. It is therefore recommended not to make variable names too verbose.

Loading history...
Coding Style introduced by
This line exceeds maximum limit of 120 characters; contains 126 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
159
    {
160
        if ($this->showRaaContactInformationOption->equals($showRaaContactInformationOption)) {
161
            return;
162
        }
163
164
        $this->apply(
165
            new ShowRaaContactInformationOptionChangedEvent(
166
                $this->institutionConfigurationId,
167
                $this->institution,
168
                $showRaaContactInformationOption
169
            )
170
        );
171
    }
172
173
    public function updateAllowedSecondFactorList(AllowedSecondFactorList $allowedSecondFactorList)
174
    {
175
        // AllowedSecondFactorList can be null for InstitutionConfigurations for which this functionality did not exist
176
        if ($this->allowedSecondFactorList !== null
177
            && $this->allowedSecondFactorList->equals($allowedSecondFactorList)
178
        ) {
179
            return;
180
        }
181
182
        $this->apply(
183
            new AllowedSecondFactorListUpdatedEvent(
184
                $this->institutionConfigurationId,
185
                $this->institution,
186
                $allowedSecondFactorList
187
            )
188
        );
189
    }
190
191
    /**
192
     * @param RaLocationId $raLocationId
193
     * @param RaLocationName $raLocationName
194
     * @param Location $location
195
     * @param ContactInformation $contactInformation
196
     */
197
    public function addRaLocation(
198
        RaLocationId $raLocationId,
199
        RaLocationName $raLocationName,
200
        Location $location,
201
        ContactInformation $contactInformation
202
    ) {
203 View Code Duplication
        if ($this->raLocations->containsWithId($raLocationId)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
204
            throw new DomainException(sprintf(
205
                'Cannot add RaLocation with RaLocationId "%s" to RaLocations of InstitutionConfiguration "%s":'
206
                . ' it is already present',
207
                $raLocationId,
208
                $this->getAggregateRootId()
209
            ));
210
        }
211
212
        $this->apply(new RaLocationAddedEvent(
213
            $this->institutionConfigurationId,
214
            $this->institution,
215
            $raLocationId,
216
            $raLocationName,
217
            $location,
218
            $contactInformation
219
        ));
220
    }
221
222
    /**
223
     * @param RaLocationId $raLocationId
224
     * @param RaLocationName $raLocationName
225
     * @param Location $location
226
     * @param ContactInformation $contactInformation
227
     */
228
    public function changeRaLocation(
229
        RaLocationId $raLocationId,
230
        RaLocationName $raLocationName,
231
        Location $location,
232
        ContactInformation $contactInformation
233
    ) {
234 View Code Duplication
        if (!$this->raLocations->containsWithId($raLocationId)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
235
            throw new DomainException(sprintf(
236
                'Cannot change RaLocation with RaLocationId "%s" in RaLocations of InstitutionConfiguration "%s":'
237
                . ' it is not present',
238
                $raLocationId,
239
                $this->getAggregateRootId()
240
            ));
241
        }
242
243
        $raLocation = $this->raLocations->getById($raLocationId);
244
245
        if (!$raLocation->getName()->equals($raLocationName)) {
246
            $this->apply(
247
                new RaLocationRenamedEvent($this->institutionConfigurationId, $raLocationId, $raLocationName)
248
            );
249
        }
250
        if (!$raLocation->getLocation()->equals($location)) {
251
            $this->apply(
252
                new RaLocationRelocatedEvent($this->institutionConfigurationId, $raLocationId, $location)
253
            );
254
        }
255
        if (!$raLocation->getContactInformation()->equals($contactInformation)) {
256
            $this->apply(
257
                new RaLocationContactInformationChangedEvent(
258
                    $this->institutionConfigurationId,
259
                    $raLocationId,
260
                    $contactInformation
261
                )
262
            );
263
        }
264
    }
265
266
    /**
267
     * @param RaLocationId $raLocationId
268
     */
269
    public function removeRaLocation(RaLocationId $raLocationId)
270
    {
271 View Code Duplication
        if (!$this->raLocations->containsWithId($raLocationId)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
272
            throw new DomainException(sprintf(
273
                'Cannot remove RaLocation with RaLocationId "%s" in RaLocations of InstitutionConfiguration "%s":'
274
                . ' it is not present',
275
                $raLocationId,
276
                $this->getAggregateRootId()
277
            ));
278
        }
279
280
        $this->apply(new RaLocationRemovedEvent($this->institutionConfigurationId, $raLocationId));
281
    }
282
283
    /**
284
     * @return void
285
     */
286
    public function destroy()
287
    {
288
        $this->apply(new InstitutionConfigurationRemovedEvent($this->institutionConfigurationId, $this->institution));
289
    }
290
291
    public function getAggregateRootId()
292
    {
293
        return $this->institutionConfigurationId;
294
    }
295
296
    protected function applyNewInstitutionConfigurationCreatedEvent(NewInstitutionConfigurationCreatedEvent $event)
297
    {
298
        $this->institutionConfigurationId      = $event->institutionConfigurationId;
299
        $this->institution                     = $event->institution;
300
        $this->useRaLocationsOption            = $event->useRaLocationsOption;
301
        $this->showRaaContactInformationOption = $event->showRaaContactInformationOption;
302
        $this->raLocations                     = new RaLocationList([]);
303
        $this->isMarkedAsDestroyed             = false;
304
    }
305
306
    protected function applyUseRaLocationsOptionChangedEvent(UseRaLocationsOptionChangedEvent $event)
307
    {
308
        $this->useRaLocationsOption = $event->useRaLocationsOption;
309
    }
310
311
    protected function applyShowRaaContactInformationOptionChangedEvent(
312
        ShowRaaContactInformationOptionChangedEvent $event
313
    ) {
314
        $this->showRaaContactInformationOption = $event->showRaaContactInformationOption;
315
    }
316
317
    protected function applyAllowedSecondFactorListUpdatedEvent(AllowedSecondFactorListUpdatedEvent $event)
318
    {
319
        $this->allowedSecondFactorList = $event->allowedSecondFactorList;
320
    }
321
322
    protected function applyRaLocationAddedEvent(RaLocationAddedEvent $event)
323
    {
324
        $this->raLocations->add(
325
            RaLocation::create(
326
                $event->raLocationId,
327
                $event->raLocationName,
328
                $event->location,
329
                $event->contactInformation
330
            )
331
        );
332
    }
333
334
    protected function applyRaLocationRenamedEvent(RaLocationRenamedEvent $event)
335
    {
336
        $raLocation = $this->raLocations->getById($event->raLocationId);
337
        $raLocation->rename($event->raLocationName);
338
    }
339
340
    protected function applyRaLocationRelocatedEvent(RaLocationRelocatedEvent $event)
341
    {
342
        $raLocation = $this->raLocations->getById($event->raLocationId);
343
        $raLocation->relocate($event->location);
344
    }
345
346
    protected function applyRaLocationContactInformationChangedEvent(RaLocationContactInformationChangedEvent $event)
347
    {
348
        $raLocation = $this->raLocations->getById($event->raLocationId);
349
        $raLocation->changeContactInformation($event->contactInformation);
350
    }
351
352
    protected function applyRaLocationRemovedEvent(RaLocationRemovedEvent $event)
353
    {
354
        $this->raLocations->removeWithId($event->raLocationId);
355
    }
356
357
    /**
358
     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
359
     * @param InstitutionConfigurationRemovedEvent $event
360
     */
361
    protected function applyInstitutionConfigurationRemovedEvent(InstitutionConfigurationRemovedEvent $event)
0 ignored issues
show
Unused Code introduced by
The parameter $event is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
362
    {
363
        // reset all configuration to defaults. This way, should it be rebuild, it seems like it is new again
364
        $this->raLocations                     = new RaLocationList([]);
365
        $this->useRaLocationsOption            = UseRaLocationsOption::getDefault();
366
        $this->showRaaContactInformationOption = ShowRaaContactInformationOption::getDefault();
367
        $this->allowedSecondFactorList         = AllowedSecondFactorList::blank();
368
369
        $this->isMarkedAsDestroyed             = true;
370
    }
371
}
372