Completed
Push — master ( 0c3e92...3c3b41 )
by Ori
01:47
created

src/Datapackages/BaseDatapackage.php (1 issue)

Labels
Severity

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

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
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