Completed
Push — master ( 22d7bb...dd90a8 )
by Ori
03:00
created

BaseDatapackage   B

Complexity

Total Complexity 36

Size/Duplication

Total Lines 198
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 6

Importance

Changes 0
Metric Value
dl 0
loc 198
rs 8.8
c 0
b 0
f 0
wmc 36
lcom 1
cbo 6

18 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 9 2
A create() 0 12 2
A revalidate() 0 8 2
A handlesDescriptor() 0 4 1
A descriptor() 0 4 1
A resources() 0 9 2
D resource() 0 35 9
A deleteResource() 0 13 4
A saveDescriptor() 0 4 1
A rewind() 0 4 1
A current() 0 4 1
A key() 0 4 1
A next() 0 4 1
A valid() 0 4 1
B save() 0 22 4
A initResource() 0 4 1
A datapackageValidate() 0 4 1
A handlesProfile() 0 4 1
1
<?php
2
3
namespace frictionlessdata\datapackage\Datapackages;
4
5
use frictionlessdata\datapackage\Factory;
6
use frictionlessdata\datapackage\Registry;
7
use frictionlessdata\datapackage\Utils;
8
use frictionlessdata\datapackage\Validators\DatapackageValidator;
9
use frictionlessdata\datapackage\Exceptions\DatapackageValidationFailedException;
10
use Alchemy\Zippy\Zippy;
11
12
abstract class BaseDatapackage implements \Iterator
13
{
14
    /**
15
     * BaseDatapackage constructor.
16
     *
17
     * @param object      $descriptor
18
     * @param null|string $basePath
19
     *
20
     * @throws DatapackageValidationFailedException
21
     */
22
    public function __construct($descriptor, $basePath = null, $skipValidations = false)
23
    {
24
        $this->descriptor = $descriptor;
25
        $this->basePath = $basePath;
26
        $this->skipValidations = $skipValidations;
27
        if (!$this->skipValidations) {
28
            $this->revalidate();
29
        }
30
    }
31
32
    public static function create($name, $resources, $basePath = null)
33
    {
34
        $datapackage = new static((object) [
35
            'name' => $name,
36
            'resources' => [],
37
        ], $basePath, true);
38
        foreach ($resources as $resource) {
39
            $datapackage->addResource($resource);
0 ignored issues
show
Bug introduced by
The method addResource() does not exist on frictionlessdata\datapac...ackages\BaseDatapackage. Did you maybe mean resource()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
40
        }
41
42
        return $datapackage;
43
    }
44
45
    public function revalidate()
46
    {
47
        $this->rewind();
48
        $validationErrors = $this->datapackageValidate();
49
        if (count($validationErrors) > 0) {
50
            throw new DatapackageValidationFailedException($validationErrors);
51
        }
52
    }
53
54
    public static function handlesDescriptor($descriptor)
55
    {
56
        return static::handlesProfile(Registry::getDatapackageValidationProfile($descriptor));
57
    }
58
59
    /**
60
     * returns the descriptor as-is, without adding default values or normalizing.
61
     *
62
     * @return object
63
     */
64
    public function descriptor()
65
    {
66
        return $this->descriptor;
67
    }
68
69
    public function resources()
70
    {
71
        $resources = [];
72
        foreach ($this->descriptor->resources as $resourceDescriptor) {
73
            $resources[$resourceDescriptor->name] = $this->initResource($resourceDescriptor);
74
        }
75
76
        return $resources;
77
    }
78
79
    public function resource($name, $resource = null)
80
    {
81
        if ($resource) {
82
            if (is_a($resource, 'frictionlessdata\\datapackage\\Resources\\BaseResource')) {
83
                $resource = $resource->descriptor();
84
            } else {
85
                $resource = Utils::objectify($resource);
86
            }
87
            $resource->name = $name;
88
            $resourceDescriptors = [];
89
            $gotMatch = false;
90
            foreach ($this->descriptor->resources as $resourceDescriptor) {
91
                if ($resourceDescriptor->name == $resource->name) {
92
                    $resourceDescriptors[] = $resource;
93
                    $gotMatch = true;
94
                } else {
95
                    $resourceDescriptors[] = $resourceDescriptor;
96
                }
97
            }
98
            if (!$gotMatch) {
99
                $resourceDescriptors[] = $resource;
100
            }
101
            $this->descriptor->resources = $resourceDescriptors;
102
            if (!$this->skipValidations) {
103
                $this->revalidate();
104
            }
105
        } else {
106
            foreach ($this->descriptor->resources as $resourceDescriptor) {
107
                if ($resourceDescriptor->name == $name) {
108
                    return $this->initResource($resourceDescriptor);
109
                }
110
            }
111
            throw new \Exception("couldn't find matching resource with name =  '{$name}'");
112
        }
113
    }
114
115
    public function deleteResource($name)
116
    {
117
        $resourceDescriptors = [];
118
        foreach ($this->descriptor->resources as $resourceDescriptor) {
119
            if ($resourceDescriptor->name != $name) {
120
                $resourceDescriptors[] = $resourceDescriptor;
121
            }
122
        }
123
        $this->descriptor->resources = $resourceDescriptors;
124
        if (!$this->skipValidations) {
125
            $this->revalidate();
126
        }
127
    }
128
129
    public function saveDescriptor($filename)
130
    {
131
        return file_put_contents($filename, json_encode($this->descriptor()));
132
    }
133
134
    // standard iterator functions - to iterate over the resources
135
    public function rewind()
136
    {
137
        $this->currentResourcePosition = 0;
138
    }
139
140
    public function current()
141
    {
142
        return $this->initResource($this->descriptor()->resources[$this->currentResourcePosition]);
143
    }
144
145
    public function key()
146
    {
147
        return $this->currentResourcePosition;
148
    }
149
150
    public function next()
151
    {
152
        ++$this->currentResourcePosition;
153
    }
154
155
    public function valid()
156
    {
157
        return isset($this->descriptor()->resources[$this->currentResourcePosition]);
158
    }
159
160
    public function save($zip_filename)
161
    {
162
        $zippy = Zippy::load();
163
        $base = tempnam(sys_get_temp_dir(), 'datapackage-zip-');
164
        $files = [
165
            "datapackage.json" => $base."datapackage.json"
166
        ];
167
        $ri = 0;
168
        foreach ($this as $resource) {
169
            $fileNames = $resource->save($base."resource-".$ri);
170
            foreach ($fileNames as $fileName) {
171
                $relname = str_replace($base."resource-".$ri, "", $fileName);
172
                $files["resource-".$ri.$relname] = $fileName;
173
            }
174
            $ri++;
175
        }
176
        $this->saveDescriptor($files["datapackage.json"]);
177
        $zippy->create($zip_filename, $files);
178
        foreach (array_values($files) as $file) {
179
            unlink($file);
180
        }
181
    }
182
183
    protected $descriptor;
184
    protected $currentResourcePosition = 0;
185
    protected $basePath;
186
    protected $skipValidations = false;
187
188
    /**
189
     * called by the resources iterator for each iteration.
190
     *
191
     * @param object $descriptor
192
     *
193
     * @return \frictionlessdata\datapackage\Resources\BaseResource
194
     */
195
    protected function initResource($descriptor)
196
    {
197
        return Factory::resource($descriptor, $this->basePath, $this->skipValidations);
198
    }
199
200
    protected function datapackageValidate()
201
    {
202
        return DatapackageValidator::validate($this->descriptor(), $this->basePath);
203
    }
204
205
    protected static function handlesProfile($profile)
206
    {
207
        return false;
208
    }
209
}
210