AddressFactory   A
last analyzed

Complexity

Total Complexity 8

Size/Duplication

Total Lines 66
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 2

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 8
lcom 1
cbo 2
dl 0
loc 66
ccs 23
cts 23
cp 1
rs 10
c 0
b 0
f 0

3 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 2
A __invoke() 0 5 1
A apply() 0 27 5
1
<?php
2
namespace Germania\Addresses;
3
4
5
/**
6
 * Creates AddressInterface instances from an associative array.
7
 *
8
 * Example:
9
 *
10
 *     <?php
11
 *     $factory = (new AddressFactory)([
12
 *       'street1'  => 'Street name 1',
13
 *       'street2'  => null,
14
 *       'zip'      => 'DG2JQ',
15
 *       'location' => 'Dumfries',
16
 *       'country'  => 'Scotland'
17
 *     ]);
18
 *
19
 */
20
class AddressFactory
21
{
22
    public $php_address_class;
23
24
    public $default_data = array(
25
        'type'     => null,
26
        'street1'  => null,
27
        'street2'  => null,
28
        'zip'      => null,
29
        'location' => null,
30
        'country'  => null,
31
    );
32
33
    /**
34
     * @param string|null $address_class
35
     */
36 10
    public function __construct(string $address_class = null)
37
    {
38 10
        $this->php_address_class = $address_class ?: Address::class ;
39 10
    }
40
41
42
    /**
43
     * @param  array  $address_data
44
     * @return AddressInterface
45
     */
46 6
    public function __invoke(array $address_data = array()) : AddressInterface
47
    {
48 6
        $address = new $this->php_address_class;
49 6
        return $this->apply($address, $address_data);
50
    }
51
52
53
    /**
54
     * @param  AddressProviderInterface $address_provider
55
     * @param  array|null               $address_data
56
     * @return AddressProviderInterface
57
     */
58 12
    public function apply(AddressProviderInterface $address_provider, array $address_data = null): AddressProviderInterface
59
    {
60 12
        $address = $address_provider->getAddress();
61
62 12
        if (!$address):
63 4
            $address = new $this->php_address_class;
64 4
            if ($address_provider instanceOf AddressAwareInterface):
65 2
                $address_provider->setAddress($address);
66
            else:
67 2
                $address_provider->address = $address;
0 ignored issues
show
Bug introduced by
Accessing address on the interface Germania\Addresses\AddressProviderInterface suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
68
            endif;
69
        endif;
70
71 12
        $raw = array_merge($this->default_data, $address_data ?: array());
72
73 12
        $address->setStreet1(  $raw['street1'])
74 12
                ->setStreet2(  $raw['street2'])
75 12
                ->setZip(      $raw['zip'])
76 12
                ->setLocation( $raw['location'])
77 12
                ->setCountry(  $raw['country'])
78 12
                ->setType(     $raw['type']);
79
80 12
        foreach($address_data as $field => $value)                     
0 ignored issues
show
Bug introduced by
The expression $address_data of type null|array is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
81 10
            $address->{$field} = $value;
82
83 12
        return $address_provider;
84
    }
85
}
86