Passed
Push — master ( 26e0e4...4a85b9 )
by Peter
10:37
created

AbstractElement::createElement()   F

Complexity

Conditions 26
Paths 4097

Size

Total Lines 79
Code Lines 46

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 46
dl 0
loc 79
rs 0
c 0
b 0
f 0
cc 26
nc 4097
nop 2

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/**
4
 * The MIT License
5
 *
6
 * Copyright 2016 Julien Fastré <[email protected]>.
7
 *
8
 * Permission is hereby granted, free of charge, to any person obtaining a copy
9
 * of this software and associated documentation files (the "Software"), to deal
10
 * in the Software without restriction, including without limitation the rights
11
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12
 * copies of the Software, and to permit persons to whom the Software is
13
 * furnished to do so, subject to the following conditions:
14
 *
15
 * The above copyright notice and this permission notice shall be included in
16
 * all copies or substantial portions of the Software.
17
 *
18
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
 * FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE
21
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24
 * THE SOFTWARE.
25
 */
26
27
namespace i3Soft\CDA\Elements;
28
29
use i3Soft\CDA\ClinicalDocument as CDA;
30
use i3Soft\CDA\DataType\Boolean\Boolean;
31
use i3Soft\CDA\Interfaces\ClassCodeInterface;
32
use i3Soft\CDA\Interfaces\ContextConductionIndInterface;
33
use i3Soft\CDA\Interfaces\ContextControlCodeInterface;
34
use i3Soft\CDA\Interfaces\DeterminerCodeInterface;
35
use i3Soft\CDA\Interfaces\ElementInterface;
36
use i3Soft\CDA\Interfaces\InversionIndInterface;
37
use i3Soft\CDA\Interfaces\MediaTypeInterface;
38
use i3Soft\CDA\Interfaces\MoodCodeInterface;
39
use i3Soft\CDA\Interfaces\NegationInterface;
40
use i3Soft\CDA\Interfaces\NullFlavourInterface;
41
use i3Soft\CDA\Interfaces\TypeCodeInterface;
42
use i3Soft\CDA\Interfaces\UseAttributeInterface;
43
use i3Soft\CDA\Interfaces\XSITypeInterface;
44
use i3Soft\CDA\RIM\Act\Observation;
45
use i3Soft\CDA\RIM\Act\SubstanceAdministration;
46
use i3Soft\CDA\RIM\Act\Supply;
47
use i3Soft\CDA\RIM\Entity\AssignedPerson;
48
use i3Soft\CDA\RIM\Entity\SpecimenPlayingEntity;
49
use i3Soft\CDA\RIM\Extensions\ExtParticipantRole;
50
use i3Soft\CDA\RIM\Participation\Consumable;
51
use i3Soft\CDA\RIM\Participation\Performer;
52
use i3Soft\CDA\RIM\Role\ManufacturedProduct;
53
use i3Soft\CDA\RIM\Role\SpecimenRole;
54
use i3Soft\CDA\Traits\NullFlavourTrait;
55
use i3Soft\CDA\Traits\RealmCodesTrait;
56
use i3Soft\CDA\Traits\TemplateIdsTrait;
57
use i3Soft\CDA\Traits\TypeIdTrait;
58
59
/**
60
 * @author Julien Fastré <[email protected]>
61
 */
62
abstract class AbstractElement implements ElementInterface, NullFlavourInterface
63
{
64
    use NullFlavourTrait;
65
    use RealmCodesTrait;
66
    use TypeIdTrait;
67
    use TemplateIdsTrait;
68
69
    /**
70
     * @var array
71
     */
72
    protected $attributes = array();
73
74
    /**
75
     * this is a total hack to add non-commonly used attributes.
76
     * don't use it lazy bones!
77
     *
78
     * @param $attribute
79
     * @param $value
80
     *
81
     * @return AbstractElement
82
     * @deprecated
83
     */
84
    public function addAttribute($attribute, $value): self
85
    {
86
        $this->attributes[$attribute] = $value;
87
        return $this;
88
    }
89
90
    /**
91
     * @return TargetSiteCode
92
     */
93
    public function returnTargetSiteCode(): TargetSiteCode
94
    {
95
        if ($this instanceof TargetSiteCode) {
96
            return $this;
97
        }
98
        throw new \RuntimeException('The method must be an instance of TargetSiteCode');
99
    }
100
101
    /**
102
     * @return Observation
103
     */
104
    public function returnObservation(): Observation
105
    {
106
        if ($this instanceof Observation) {
107
            return $this;
108
        }
109
        throw new \RuntimeException('The method must be an instance of Observation');
110
    }
111
112
    /**
113
     * @return SubstanceAdministration
114
     */
115
    public function returnSubstanceAdministration(): SubstanceAdministration
116
    {
117
        if ($this instanceof SubstanceAdministration) {
118
            return $this;
119
        }
120
        throw new \RuntimeException('The method must be an instance of SubstanceAdministration');
121
    }
122
123
    /**
124
     * @return SpecimenRole
125
     */
126
    public function returnSpecimenRole(): SpecimenRole
127
    {
128
        if ($this instanceof SpecimenRole) {
129
            return $this;
130
        }
131
        throw new \RuntimeException('The method must be an instance of SpecimenRole');
132
    }
133
134
    /**
135
     * @return ManufacturedProduct
136
     */
137
    public function returnManufacturedProduct(): ManufacturedProduct
138
    {
139
        if ($this instanceof ManufacturedProduct) {
140
            return $this;
141
        }
142
        throw new \RuntimeException('The method must be an instance of ManufacturedProduct');
143
    }
144
145
    /**
146
     * @return SpecimenPlayingEntity
147
     */
148
    public function returnSpecimenPlayingEntity(): SpecimenPlayingEntity
149
    {
150
        if ($this instanceof SpecimenPlayingEntity) {
151
            return $this;
152
        }
153
        throw new \RuntimeException('The method must be an instance of SpecimenPlayingEntity');
154
    }
155
156
    /**
157
     * @return Consumable
158
     */
159
    public function returnConsumable(): Consumable
160
    {
161
        if ($this instanceof Consumable) {
162
            return $this;
163
        }
164
        throw new \RuntimeException('The method must be an instance of Consumable');
165
    }
166
167
    /**
168
     * @return Performer
169
     */
170
    public function returnPerformer(): Performer
171
    {
172
        if ($this instanceof Performer) {
173
            return $this;
174
        }
175
        throw new \RuntimeException('The method must be an instance of Performer');
176
    }
177
178
    /**
179
     * @return AssignedPerson
180
     */
181
    public function returnAssignedPerson(): AssignedPerson
182
    {
183
        if ($this instanceof AssignedPerson) {
184
            return $this;
185
        }
186
        throw new \RuntimeException('The method must be an instance of AssignedPerson');
187
    }
188
189
    /**
190
     * @return ExtParticipantRole
191
     */
192
    public function returnExtParticipantRole(): ExtParticipantRole
193
    {
194
        if ($this instanceof ExtParticipantRole) {
195
            return $this;
196
        }
197
        throw new \RuntimeException('The method must be an instance of ExtParticipantRole');
198
    }
199
200
    /**
201
     * @return Supply
202
     */
203
    public function returnSupply(): Supply
204
    {
205
        if ($this instanceof Supply) {
206
            return $this;
207
        }
208
        throw new \RuntimeException('The method must be an instance of Supply');
209
    }
210
211
    /**
212
     * @param \DOMDocument $doc
213
     * @param array        $properties
214
     *
215
     * @return \DOMElement
216
     */
217
    protected function createElement(\DOMDocument $doc, array $properties = array()): \DOMElement
218
    {
219
        /* @var $el \DOMElement */
220
        $el = $doc->createElement(CDA::NS_CDA . $this->getElementTag());
221
        if ($this->hasNullFlavour()) {
222
            $el->setAttribute(CDA::NS_CDA . 'nullFlavor', $this->getNullFlavour());
223
            return $el;
224
        }
225
226
        // tag can have class code or type code, but not both.
227
        // can have a class code and a mood code, but not type code and mood code
228
        /** @noinspection PhpUndefinedMethodInspection */
229
        if ($this instanceof ClassCodeInterface
230
            && $this->hasClassCode()) {
0 ignored issues
show
Bug introduced by
The method hasClassCode() does not exist on i3Soft\CDA\Interfaces\ClassCodeInterface. Since it exists in all sub-types, consider adding an abstract or default implementation to i3Soft\CDA\Interfaces\ClassCodeInterface. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

230
            && $this->/** @scrutinizer ignore-call */ hasClassCode()) {
Loading history...
Bug introduced by
The method hasClassCode() does not exist on i3Soft\CDA\Elements\AbstractElement. It seems like you code against a sub-type of i3Soft\CDA\Elements\AbstractElement such as i3Soft\CDA\RIM\Act\Encounter or i3Soft\CDA\RIM\Extensions\ExtEntitlement or i3Soft\CDA\Elements\AuthoringDevice or i3Soft\CDA\RIM\Act\ObservationMedia or i3Soft\CDA\RIM\Role\IntendedRecipient or i3Soft\CDA\RIM\Entity\Entity or i3Soft\CDA\RIM\Act\Organizer or i3Soft\CDA\RIM\Entity\RepresentedOrganization or i3Soft\CDA\Elements\Procedure or i3Soft\CDA\RIM\Extensions\ExtControlAct or i3Soft\CDA\RIM\Entity\AssignedEntity or i3Soft\CDA\RIM\Act\ObservationRange or i3Soft\CDA\RIM\Act\Supply or i3Soft\CDA\RIM\Entity\PlayingEntity or i3Soft\CDA\RIM\Entity\Device or i3Soft\CDA\RIM\Act\Consent or i3Soft\CDA\RIM\Role\Role or i3Soft\CDA\RIM\Entity\AssociatedEntity or i3Soft\CDA\RIM\Extensions\SubstitutionPermission or i3Soft\CDA\RIM\Act\Act or i3Soft\CDA\RIM\Act\ServiceEvent or i3Soft\CDA\RIM\Act\EncompassingEncounter or i3Soft\CDA\RIM\Extensions\ExtAsSpecimenInContainer or i3Soft\CDA\Component\SingleComponent\Section or i3Soft\CDA\RIM\Act\Criterion or i3Soft\CDA\Component\XMLBodyComponent. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

230
            && $this->/** @scrutinizer ignore-call */ hasClassCode()) {
Loading history...
231
            $el->setAttribute(CDA::NS_CDA . 'classCode', $this->getClassCode());
232
            /** @noinspection PhpUndefinedMethodInspection */
233
            if ($this instanceof MoodCodeInterface
234
                && $this->hasMoodCode()) {
0 ignored issues
show
Bug introduced by
The method hasMoodCode() does not exist on i3Soft\CDA\Elements\AbstractElement. It seems like you code against a sub-type of i3Soft\CDA\Elements\AbstractElement such as i3Soft\CDA\RIM\Act\Encounter or i3Soft\CDA\RIM\Extensions\ExtEntitlement or i3Soft\CDA\RIM\Act\ObservationMedia or i3Soft\CDA\RIM\Act\Organizer or i3Soft\CDA\Elements\Procedure or i3Soft\CDA\RIM\Extensions\ExtControlAct or i3Soft\CDA\RIM\Act\ObservationRange or i3Soft\CDA\RIM\Act\Supply or i3Soft\CDA\RIM\Act\Consent or i3Soft\CDA\RIM\Extensions\SubstitutionPermission or i3Soft\CDA\RIM\Act\Act or i3Soft\CDA\RIM\Act\ServiceEvent or i3Soft\CDA\RIM\Act\EncompassingEncounter or i3Soft\CDA\Component\SingleComponent\Section or i3Soft\CDA\RIM\Act\Criterion or i3Soft\CDA\Component\XMLBodyComponent. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

234
                && $this->/** @scrutinizer ignore-call */ hasMoodCode()) {
Loading history...
Bug introduced by
The method hasMoodCode() does not exist on i3Soft\CDA\Interfaces\MoodCodeInterface. Since it exists in all sub-types, consider adding an abstract or default implementation to i3Soft\CDA\Interfaces\MoodCodeInterface. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

234
                && $this->/** @scrutinizer ignore-call */ hasMoodCode()) {
Loading history...
Bug introduced by
The method hasMoodCode() does not exist on i3Soft\CDA\Interfaces\ClassCodeInterface. It seems like you code against a sub-type of i3Soft\CDA\Interfaces\ClassCodeInterface such as i3Soft\CDA\RIM\Act\Encounter or i3Soft\CDA\RIM\Act\Criterion or i3Soft\CDA\RIM\Extensions\ExtEntitlement or i3Soft\CDA\RIM\Act\ObservationMedia or i3Soft\CDA\Component\XMLBodyComponent or i3Soft\CDA\RIM\Act\Organizer or i3Soft\CDA\Elements\Procedure or i3Soft\CDA\RIM\Extensions\ExtControlAct or i3Soft\CDA\RIM\Act\ObservationRange or i3Soft\CDA\RIM\Act\Supply or i3Soft\CDA\ClinicalDocument or i3Soft\CDA\RIM\Act\Consent or i3Soft\CDA\RIM\Extensions\SubstitutionPermission or i3Soft\CDA\RIM\Act\Act or i3Soft\CDA\RIM\Act\ServiceEvent or i3Soft\CDA\RIM\Act\EncompassingEncounter or i3Soft\CDA\Component\SingleComponent\Section. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

234
                && $this->/** @scrutinizer ignore-call */ hasMoodCode()) {
Loading history...
235
                $el->setAttribute(CDA::NS_CDA . 'moodCode', $this->getMoodCode());
236
            }
237
        } /** @noinspection PhpUndefinedMethodInspection */
238
        elseif ($this instanceof TypeCodeInterface && $this->hasTypeCode()) {
0 ignored issues
show
Bug introduced by
The method hasTypeCode() does not exist on i3Soft\CDA\Interfaces\TypeCodeInterface. Since it exists in all sub-types, consider adding an abstract or default implementation to i3Soft\CDA\Interfaces\TypeCodeInterface. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

238
        elseif ($this instanceof TypeCodeInterface && $this->/** @scrutinizer ignore-call */ hasTypeCode()) {
Loading history...
Bug introduced by
The method hasTypeCode() does not exist on i3Soft\CDA\Elements\AbstractElement. Did you maybe mean hasTypeId()? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

238
        elseif ($this instanceof TypeCodeInterface && $this->/** @scrutinizer ignore-call */ hasTypeCode()) {

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
239
            $el->setAttribute(CDA::NS_CDA . 'typeCode', $this->getTypeCode());
240
        }
241
242
        if ($this instanceof DeterminerCodeInterface
243
            && false === empty($this->getDeterminerCode())) {
244
            $el->setAttribute(CDA::NS_CDA . 'determinerCode', $this->getDeterminerCode());
245
        }
246
247
        if ($this instanceof MediaTypeInterface && $this->getMediaType()) {
248
            $el->setAttribute(CDA::NS_CDA . 'mediaType', $this->getMediaType());
249
        }
250
251
        if ($this instanceof InversionIndInterface
252
            && $this->hasInversionInd()) {
253
            $negationInd = new Boolean('inversionInd', $this->getInversionInd());
254
            $negationInd->setValueToElement($el, $doc);
255
        }
256
257
        if ($this instanceof ContextConductionIndInterface
258
            && $this->hasContextConductionInd()) {
259
            $negationInd = new Boolean('contextConductionInd', $this->getContextConductionInd());
260
            $negationInd->setValueToElement($el, $doc);
261
        }
262
263
        if ($this instanceof NegationInterface
264
            && $this->hasNegationInd()) {
265
            $negationInd = new Boolean('negationInd', $this->getNegationInd());
266
            $negationInd->setValueToElement($el, $doc);
267
        }
268
        if ($this instanceof UseAttributeInterface
269
            && false === empty($this->getUseAttribute())) {
270
            $el->setAttribute(CDA::NS_CDA . 'use', $this->getUseAttribute());
271
        }
272
273
        if ($this instanceof ContextControlCodeInterface
274
            && false === empty($this->getContextControlCode())) {
275
276
            $el->setAttribute(CDA::NS_CDA . 'contextControlCode', $this->getContextControlCode());
277
        }
278
        if ($this instanceof XSITypeInterface
279
            && false === empty($this->getXSIType())) {
280
            $el->setAttribute(CDA::NS_CDA . 'xsi:type', $this->getXSIType());
281
        }
282
283
        foreach ($properties as $property) {
284
            $this->{$property}->setValueToElement($el, $doc);
285
        }
286
287
        foreach ($this->attributes as $attribute => $value) {
288
            $el->setAttribute($attribute, $value);
289
        }
290
        // attributes have finished, now start adding the elements.
291
        // realm codes are used to store data like the organisation/country etc this tag conforms to.
292
        $this->renderRealmCodes($el, $doc)
293
          ->renderTypeId($el, $doc)
0 ignored issues
show
Bug introduced by
It seems like renderTypeId() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

293
          ->/** @scrutinizer ignore-call */ renderTypeId($el, $doc)
Loading history...
294
          ->renderTemplateIds($el, $doc);
295
        return $el;
296
    }
297
298
    /**
299
     * get the element tag name
300
     *
301
     * @return string
302
     */
303
    abstract protected function getElementTag(): string;
304
305
}
306