commit 48d33c301151399f8368731c9208f4472ebd8ac2 Author: Maximilian Ruta Date: Tue Jun 25 14:38:56 2019 +0200 First commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1bd0a44 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +/vendor/ +/composer.lock +/tests/green-directory \ No newline at end of file diff --git a/.phpunit.result.cache b/.phpunit.result.cache new file mode 100644 index 0000000..b306b03 --- /dev/null +++ b/.phpunit.result.cache @@ -0,0 +1 @@ +C:37:"PHPUnit\Runner\DefaultTestResultCache":831:{a:2:{s:7:"defects";a:5:{s:69:"Netzbegruenung\GreenDirectory\Models\Tests\PartyTest::testDeserialize";i:5;s:74:"Netzbegruenung\GreenDirectory\Models\Tests\SerializerTest::testDeserialize";i:4;s:67:"Netzbegruenung\GreenDirectory\Tests\SerializerTest::testDeserialize";i:5;s:55:"Netzbegruenung\GreenDirectory\Tests\ReaderTest::testAll";i:5;s:59:"Netzbegruenung\GreenDirectory\Tests\RepositoryTest::testAll";i:4;}s:5:"times";a:5:{s:69:"Netzbegruenung\GreenDirectory\Models\Tests\PartyTest::testDeserialize";d:0.009;s:74:"Netzbegruenung\GreenDirectory\Models\Tests\SerializerTest::testDeserialize";d:0.01;s:67:"Netzbegruenung\GreenDirectory\Tests\SerializerTest::testDeserialize";d:0.042;s:55:"Netzbegruenung\GreenDirectory\Tests\ReaderTest::testAll";d:0.919;s:59:"Netzbegruenung\GreenDirectory\Tests\RepositoryTest::testAll";d:0.898;}}} \ No newline at end of file diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..6d990b7 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,10 @@ +language: php +php: + - '7.0' + - '7.1' + - '7.2' + - nightly + +install: + - travis_retry composer update --no-interaction --no-suggest + - cd tests; git clone git@github.com:netzbegruenung/green-directory.git \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..760505a --- /dev/null +++ b/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2019 NETZBEGRÜNUNG – Verein für grüne Netzkultur e.V. + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/bootstrap.php b/bootstrap.php new file mode 100644 index 0000000..1ee3d32 --- /dev/null +++ b/bootstrap.php @@ -0,0 +1,5 @@ + + + + + ./tests + + + \ No newline at end of file diff --git a/serializer/Email.yml b/serializer/Email.yml new file mode 100644 index 0000000..2255507 --- /dev/null +++ b/serializer/Email.yml @@ -0,0 +1,4 @@ +Netzbegruenung\GreenDirectory\Model\Email: + properties: + address: + type: string diff --git a/serializer/ExternalRef.yml b/serializer/ExternalRef.yml new file mode 100644 index 0000000..35dba01 --- /dev/null +++ b/serializer/ExternalRef.yml @@ -0,0 +1,6 @@ +Netzbegruenung\GreenDirectory\Model\ExternalRef: + properties: + type: + type: string + key: + type: string diff --git a/serializer/Party.yml b/serializer/Party.yml new file mode 100644 index 0000000..0e0e9d4 --- /dev/null +++ b/serializer/Party.yml @@ -0,0 +1,10 @@ +Netzbegruenung\GreenDirectory\Model\Party: + properties: + country: + type: string + level: + type: string + urls: + type: array + emails: + type: array diff --git a/serializer/Person.yml b/serializer/Person.yml new file mode 100644 index 0000000..bc6568f --- /dev/null +++ b/serializer/Person.yml @@ -0,0 +1,24 @@ +Netzbegruenung\GreenDirectory\Model\Person: + properties: + name: + type: string + givenName: + type: string + familyName: + type: string + level: + type: string + country: + type: string + state: + type: string + district: + type: string + city: + type: string + region: + type: string + urls: + type: array + emails: + type: array diff --git a/serializer/RegionalChapter.yml b/serializer/RegionalChapter.yml new file mode 100644 index 0000000..d9944b0 --- /dev/null +++ b/serializer/RegionalChapter.yml @@ -0,0 +1,22 @@ +Netzbegruenung\GreenDirectory\Model\RegionalChapter: + properties: + name: + type: string + level: + type: string + country: + type: string + state: + type: string + district: + type: string + city: + type: string + region: + type: string + urls: + type: array + emails: + type: array + externalRefs: + type: array diff --git a/serializer/Url.yml b/serializer/Url.yml new file mode 100644 index 0000000..9df9855 --- /dev/null +++ b/serializer/Url.yml @@ -0,0 +1,6 @@ +Netzbegruenung\GreenDirectory\Model\Url: + properties: + type: + type: string + url: + type: string diff --git a/serializer/YouthOrganization.yml b/serializer/YouthOrganization.yml new file mode 100644 index 0000000..e743fd3 --- /dev/null +++ b/serializer/YouthOrganization.yml @@ -0,0 +1,18 @@ +Netzbegruenung\GreenDirectory\Model\YouthOrganization: + properties: + level: + type: string + country: + type: string + state: + type: string + district: + type: string + city: + type: string + region: + type: string + urls: + type: array + emails: + type: array diff --git a/src/IndexInterface.php b/src/IndexInterface.php new file mode 100644 index 0000000..e444b3c --- /dev/null +++ b/src/IndexInterface.php @@ -0,0 +1,12 @@ +address = $address; + } + + /** + * @return string + */ + public function getAddress(): string + { + return $this->address; + } +} \ No newline at end of file diff --git a/src/Model/ExternalRef.php b/src/Model/ExternalRef.php new file mode 100644 index 0000000..bde81f0 --- /dev/null +++ b/src/Model/ExternalRef.php @@ -0,0 +1,33 @@ +type; + } + + /** + * @return string + */ + public function getKey(): string + { + return $this->key; + } +} \ No newline at end of file diff --git a/src/Model/ExternalRef/Type.php b/src/Model/ExternalRef/Type.php new file mode 100644 index 0000000..6e51508 --- /dev/null +++ b/src/Model/ExternalRef/Type.php @@ -0,0 +1,8 @@ +country = $country; + $this->level = $level; + $this->urls = $urls; + $this->emails = $emails; + } + + public function getType() : string + { + return 'PARTY'; + } + + /** + * @return string + */ + public function getCountry(): string + { + return $this->country; + } + + /** + * @return string + */ + public function getLevel(): string + { + return $this->level; + } + + /** + * @return Url[] + */ + public function getUrls(): array + { + return $this->urls; + } + + /** + * @return Email[] + */ + public function getEmails(): array + { + return $this->emails; + } +} \ No newline at end of file diff --git a/src/Model/Person.php b/src/Model/Person.php new file mode 100644 index 0000000..61249b4 --- /dev/null +++ b/src/Model/Person.php @@ -0,0 +1,181 @@ +name = $name; + $this->givenName = $givenName; + $this->familyName = $familyName; + $this->level = $level; + $this->country = $country; + $this->state = $state; + $this->district = $district; + $this->city = $city; + $this->region = $region; + $this->urls = $urls; + $this->emails = $emails; + } + + public function getType() : string + { + return 'PERSON'; + } + + /** + * @return string + */ + public function getName(): string + { + return $this->name; + } + + /** + * @return string|null + */ + public function getGivenName(): ?string + { + return $this->givenName; + } + + /** + * @return string|null + */ + public function getFamilyName(): ?string + { + return $this->familyName; + } + + /** + * @return string|null + */ + public function getLevel(): ?string + { + return $this->level; + } + + /** + * @return string|null + */ + public function getCountry(): ?string + { + return $this->country; + } + + /** + * @return string|null + */ + public function getState(): ?string + { + return $this->state; + } + + /** + * @return string|null + */ + public function getDistrict(): ?string + { + return $this->district; + } + + /** + * @return string|null + */ + public function getCity(): ?string + { + return $this->city; + } + + /** + * @return string|null + */ + public function getRegion(): ?string + { + return $this->region; + } + + /** + * @return Url[] + */ + public function getUrls(): array + { + return $this->urls; + } + + /** + * @return Email[] + */ + public function getEmails(): array + { + return $this->emails; + } +} \ No newline at end of file diff --git a/src/Model/RegionalChapter.php b/src/Model/RegionalChapter.php new file mode 100644 index 0000000..410b695 --- /dev/null +++ b/src/Model/RegionalChapter.php @@ -0,0 +1,166 @@ +name = $name; + $this->level = $level; + $this->country = $country; + $this->state = $state; + $this->district = $district; + $this->city = $city; + $this->region = $region; + $this->urls = $urls; + $this->emails = $emails; + $this->externalRefs = $externalRefs; + } + + public function getType() : string + { + return 'REGIONAL_CHAPTER'; + } + + /** + * @return string + */ + public function getName(): ?string + { + return $this->name; + } + + /** + * @return string|null + */ + public function getLevel(): ?string + { + return $this->level; + } + + /** + * @return string + */ + public function getCountry(): string + { + return $this->country; + } + + /** + * @return string|null + */ + public function getState(): ?string + { + return $this->state; + } + + /** + * @return string|null + */ + public function getDistrict(): ?string + { + return $this->district; + } + + /** + * @return string|null + */ + public function getCity(): ?string + { + return $this->city; + } + + /** + * @return string|null + */ + public function getRegion(): ?string + { + return $this->region; + } + + /** + * @return Url[] + */ + public function getUrls(): array + { + return $this->urls; + } + + /** + * @return Email[] + */ + public function getEmails(): array + { + return $this->emails; + } + + /** + * @return ExternalRef[] + */ + public function getExternalRefs(): array + { + return $this->externalRefs; + } +} diff --git a/src/Model/Url.php b/src/Model/Url.php new file mode 100644 index 0000000..b9c0f71 --- /dev/null +++ b/src/Model/Url.php @@ -0,0 +1,38 @@ +type = $type; + $this->url = $url; + } + + /** + * @return string + */ + public function getType(): string + { + return $this->type; + } + + /** + * @return string + */ + public function getUrl(): string + { + return $this->url; + } +} diff --git a/src/Model/Url/Type.php b/src/Model/Url/Type.php new file mode 100644 index 0000000..0840756 --- /dev/null +++ b/src/Model/Url/Type.php @@ -0,0 +1,16 @@ +level = $level; + $this->country = $country; + $this->state = $state; + $this->district = $district; + $this->city = $city; + $this->region = $region; + $this->urls = $urls; + $this->emails = $emails; + } + + public function getType() : string + { + return 'YOUTH_ORGANIZATION'; + } + + /** + * @return string|null + */ + public function getLevel(): ?string + { + return $this->level; + } + + /** + * @return string|null + */ + public function getCountry(): ?string + { + return $this->country; + } + + /** + * @return string|null + */ + public function getState(): ?string + { + return $this->state; + } + + /** + * @return string|null + */ + public function getDistrict(): ?string + { + return $this->district; + } + + /** + * @return string|null + */ + public function getCity(): ?string + { + return $this->city; + } + + /** + * @return string|null + */ + public function getRegion(): ?string + { + return $this->region; + } + + /** + * @return Url[] + */ + public function getUrls(): array + { + return $this->urls; + } + + /** + * @return Email[] + */ + public function getEmails(): array + { + return $this->emails; + } +} \ No newline at end of file diff --git a/src/Reader.php b/src/Reader.php new file mode 100644 index 0000000..6bc8fa0 --- /dev/null +++ b/src/Reader.php @@ -0,0 +1,56 @@ +directory = $directory; + + if ($serializer === null) { + $serializer = SerializerFactory::create(); + } + + $this->serializer = $serializer; + $this->indizes = $indizes; + } + + private function findFiles() : iterable + { + $iterator = new \RecursiveDirectoryIterator($this->directory); + + /** @var \SplFileInfo $item */ + foreach (new \RecursiveIteratorIterator($iterator) as $item) { + if (in_array($item->getExtension(), ['yaml', 'yml'])) { + yield $item->getPathname(); + } + } + + yield from []; + } + + public function all() : iterable + { + foreach ($this->findFiles() as $file) { + foreach ($this->serializer->deserializeFile($file) as $item) { + yield $item; + } + } + + yield from []; + } +} diff --git a/src/Repository.php b/src/Repository.php new file mode 100644 index 0000000..7553099 --- /dev/null +++ b/src/Repository.php @@ -0,0 +1,56 @@ +reader = $reader; + } + + protected static function getSherpaId(ItemInterface $item) : ?string + { + if ($item instanceof ExternalRefAwareInterface) { + foreach ($item->getExternalRefs() as $ref) { + if ($ref->getType() == Type::SHERPA) { + return $ref->getKey(); + } + } + } + + return null; + } + + protected function index() + { + if ($this->index === null) { + $this->index = []; + foreach ($this->reader->all() as $item) { + $ref = self::getSherpaId($item); + if ($ref !== null) { + $this->index[$ref] = $item; + } + } + } + } + + public function findBySherpaId(string $id) : ?ItemInterface + { + $this->index(); + + if (isset($this->index[$id])) { + return $this->index[$id]; + } + + return null; + } +} diff --git a/src/Serializer.php b/src/Serializer.php new file mode 100644 index 0000000..81f33df --- /dev/null +++ b/src/Serializer.php @@ -0,0 +1,80 @@ +serializer = $serializer; + } + + /** + * @param string $file + * @return ItemInterface[] + * @throws UnknownTypeException + */ + public function deserializeFile(string $file) : iterable + { + return $this->deserializeArray(yaml_parse_file($file, -1)); + } + + /** + * @param string $data + * @return ItemInterface[] + * @throws UnknownTypeException + */ + public function deserialize(string $data) : iterable + { + return $this->deserializeArray(yaml_parse($data, -1)); + } + + /** + * @param array[] $documents + * @return ItemInterface[] + * @throws UnknownTypeException + */ + public function deserializeArray(array $documents) : iterable + { + foreach ($documents as $document) { + $class = null; + switch ($document['type']) { + case 'PARTY': + $class = Party::class; + break; + case 'PERSON': + $class = Person::class; + break; + case 'REGIONAL_CHAPTER': + $class = RegionalChapter::class; + break; + case 'YOUTH_ORGANIZATION': + $class = YouthOrganization::class; + break; + } + + if ($class === null) { + continue; + } + + unset($document['type']); + + yield $this->serializer->deserialize( + json_encode($document), + $class, + 'json' + ); + } + + yield from []; + } +} \ No newline at end of file diff --git a/src/SerializerFactory.php b/src/SerializerFactory.php new file mode 100644 index 0000000..2636dbc --- /dev/null +++ b/src/SerializerFactory.php @@ -0,0 +1,17 @@ +setMetadataDirs([ + NETZBEGRUENUNG_GREEN_DIRECTORY_MODELS_SERIALIZER_PREFIX => + NETZBEGRUENUNG_GREEN_DIRECTORY_MODELS_SERIALIZER_METADATA + ]) + ->build()); + } +} \ No newline at end of file diff --git a/src/UnknownTypeException.php b/src/UnknownTypeException.php new file mode 100644 index 0000000..d562907 --- /dev/null +++ b/src/UnknownTypeException.php @@ -0,0 +1,8 @@ +reader = new Reader(__DIR__ . '/green-directory/data'); + } + + public function testAll() + { + $items = iterator_to_array($this->reader->all()); + $this->assertGreaterThan(1, count($items)); + } +} diff --git a/tests/RepositoryTest.php b/tests/RepositoryTest.php new file mode 100644 index 0000000..c72418a --- /dev/null +++ b/tests/RepositoryTest.php @@ -0,0 +1,29 @@ +repository = new Repository(new Reader(__DIR__ . '/green-directory/data')); + } + + public function testAll() + { + /** @var RegionalChapter $ov */ + $ov = $this->repository->findBySherpaId('11002609'); + $this->assertInstanceOf(RegionalChapter::class, $ov); + $this->assertEquals('Köln-Kalk', $ov->getCity()); + } +} diff --git a/tests/SerializerTest.php b/tests/SerializerTest.php new file mode 100644 index 0000000..1426caa --- /dev/null +++ b/tests/SerializerTest.php @@ -0,0 +1,32 @@ +serializer = SerializerFactory::create(); + } + + public function testDeserialize() + { + $items = iterator_to_array($this->serializer->deserializeFile( + __DIR__ . '/green-directory/data/countries/de/nw/data.yaml' + )); + + foreach ($items as $item) { + $this->assertInstanceOf(ItemInterface::class, $item); + } + } +}