RegionService   A
last analyzed

Complexity

Total Complexity 10

Size/Duplication

Total Lines 79
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 5

Importance

Changes 0
Metric Value
wmc 10
lcom 1
cbo 5
dl 0
loc 79
rs 10
c 0
b 0
f 0

5 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
A getProvinces() 0 4 1
A findByIdCard() 0 9 2
A filter() 0 15 3
A traverseTree() 0 11 3
1
<?php
2
/*
3
 * This file is part of the Slince/China package.
4
 *
5
 * (c) Slince <[email protected]>
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
11
namespace China\Region;
12
13
use China\Common\ResourceFile;
14
use China\IDCard\IDCard;
15
use China\Region\Location\AddressInterface;
16
use Doctrine\Common\Collections\Collection;
17
18
class RegionService implements RegionServiceInterface
19
{
20
    use AddressFinderTrait;
21
    /**
22
     * @var AddressInterface
23
     */
24
    protected $regions;
25
26
    /**
27
     * 根据code做索引.
28
     *
29
     * @var AddressInterface[]|Collection
30
     */
31
    protected $flattenRegions;
32
33
    public function __construct(ResourceFile $resourceFile)
34
    {
35
        $this->regions = new RegionLoader($resourceFile);
0 ignored issues
show
Documentation Bug introduced by
It seems like new \China\Region\RegionLoader($resourceFile) of type object<China\Region\RegionLoader> is incompatible with the declared type object<China\Region\Location\AddressInterface> of property $regions.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
36
        $this->flattenRegions = new RegionCollection();
37
    }
38
39
    /**
40
     * {@inheritdoc}
41
     */
42
    public function getProvinces()
43
    {
44
        return $this->regions->first()->getChildren();
0 ignored issues
show
Bug introduced by
The method first() does not seem to exist on object<China\Region\Location\AddressInterface>.

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...
45
    }
46
47
    /**
48
     * {@inheritdoc}
49
     */
50
    public function findByIdCard($idCard)
51
    {
52
        if (is_string($idCard)) {
53
            $idCard = new IDCard($idCard);
54
        }
55
        $areaCode = substr($idCard, 0, 6);
56
57
        return $this->findByCode($areaCode);
58
    }
59
60
    /**
61
     * {@inheritdoc}
62
     */
63
    public function filter(\Closure $callback)
64
    {
65
        if (!$this->flattenRegions->isEmpty()) {
66
            return $this->flattenRegions->filter($callback);
67
        }
68
        // 没有遍历过则自行遍历
69
        $addresses = [];
70
        $this->traverseTree($this->regions->first(), function(AddressInterface $address) use ($callback, &$addresses){
0 ignored issues
show
Bug introduced by
The method first() does not seem to exist on object<China\Region\Location\AddressInterface>.

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...
71
            if ($callback($address) === true) {
72
                $addresses[] = $address;
73
            }
74
        });
75
76
        return new RegionCollection($addresses);
77
    }
78
79
    /**
80
     * 遍历地区树.
81
     *
82
     * @param AddressInterface $address
83
     * @param \Closure         $callback
84
     */
85
    protected function traverseTree(AddressInterface $address, \Closure $callback)
86
    {
87
        $callback($address);
88
        //将树形结构扁平化
89
        $this->flattenRegions->add($address);
90
        if ($address->getChildren()) {
91
            foreach ($address->getChildren() as $child) {
92
                $this->traverseTree($child, $callback);
93
            }
94
        }
95
    }
96
}