diff --git a/.circleci/config.yml b/.circleci/config.yml index 9ef8901c2a..608cfb9d36 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -217,6 +217,7 @@ jobs: - run: cp .env /tmp/.env - run: echo "" >> /tmp/.env - run: echo GOOGLE_API_CONSOLE_KEY=$GOOGLE_API_CONSOLE_KEY >> /tmp/.env + - run: echo MAPBOX_TOKEN=$MAPBOX_TOKEN >> /tmp/.env - run: sudo cp /tmp/.env /home/circleci/project/.env # Now run the tests. diff --git a/.env.example b/.env.example index 7aceb782a0..968aee3a86 100644 --- a/.env.example +++ b/.env.example @@ -87,6 +87,7 @@ DISCOURSE_APIKEY=1234 REPAIRDIRECTORY_URL=http://map.restarters.test +MAPBOX_TOKEN=1234 GOOGLE_ANALYTICS_TRACKING_ID=UA-12345678-1 GOOGLE_TAG_MANAGER_ID=GTM-1ABCDEF GOOGLE_API_CONSOLE_KEY=1234 diff --git a/app/Console/Commands/SetPlaceNetworkData.php b/app/Console/Commands/SetPlaceNetworkData.php new file mode 100644 index 0000000000..23194d97d2 --- /dev/null +++ b/app/Console/Commands/SetPlaceNetworkData.php @@ -0,0 +1,80 @@ +argument('networkname'); + + // Find or fail network + $network = Network::where('name', $networkname)->first(); + + if ($network) { + foreach ($network->groups as $group) + { + $this->info('Check group ' . $group->idgroups . ' ' . $group->name); + + if ($group->latitude || $group->longitude) + { + $this->info("...geocode {$group->latitude}, {$group->longitude}"); + $loc = []; + $geocodeResponse = app('geocoder')->reverseQuery(ReverseQuery::fromCoordinates($group->latitude, $group->longitude)->withData('location_type', [ Mapbox::TYPE_PLACE ])->withLocale($network->default_language)); + $addressCollection = $geocodeResponse->get(); + $address = $addressCollection->get(0); + if ($address) { + $loc['place'] = $address->getStreetName(); + } + + if ($loc && $loc['place']) { + $this->info('...found place ' . $loc['place']); + $g = Group::findOrFail($group->idgroups); + $g->network_data = [ + 'place' => $loc['place'], + ]; + $g->save(); + } else { + $this->error($group->id . ' ' . $group->name . " couldn't reverse geocode"); + } + } + } + } + } +} diff --git a/app/Console/Commands/SetPostcodes.php b/app/Console/Commands/SetPostcodes.php deleted file mode 100644 index c3455e5801..0000000000 --- a/app/Console/Commands/SetPostcodes.php +++ /dev/null @@ -1,76 +0,0 @@ -findAll(); - - $geocoder = new Geocoder(); - - foreach ($groups as $group) { - $this->info('Check group '.$group->id.' '.$group->name.' postcode '.$group->postcode); - - if (! $group->postcode) { - if ($group->latitude || $group->longitude) { - $this->info("...no postcode, geocode {$group->latitude}, {$group->longitude}"); - $results = $geocoder->reverseGeocode($group->latitude, $group->longitude); - $found = false; - - if ($results->address_components) { - foreach ($results->address_components as $field) { - if ($field->types && $field->types[0] == 'postal_code') { - $this->info('...found postcode '.$field->long_name); - $found = true; - $g = Group::find($group->id); - $g->postcode = $field->long_name; - $g->save(); - } - } - } - - if (! $found) { - $this->error($group->id.' '.$group->name." couldn't geocode"); - } - } else { - $this->error($group->id.' '.$group->name.' has no lat/lng'); - } - } - } - } -} diff --git a/app/Group.php b/app/Group.php index 696546634e..1815081757 100644 --- a/app/Group.php +++ b/app/Group.php @@ -44,11 +44,17 @@ class Group extends Model implements Auditable 'external_id', 'devices_updated_at', 'timezone', - 'phone' + 'phone', + 'network_data', ]; protected $appends = ['ShareableLink', 'auto_approve']; + protected $casts = [ + // JSON fields in the database should be converted to/from arrays. + 'network_data' => 'array' + ]; + // The distance is not in the groups table; we add it on some queries from the select. private $distance = null; diff --git a/app/Http/Controllers/API/GroupController.php b/app/Http/Controllers/API/GroupController.php index fe300d48b5..c63d3c79ae 100644 --- a/app/Http/Controllers/API/GroupController.php +++ b/app/Http/Controllers/API/GroupController.php @@ -125,7 +125,7 @@ public static function getGroupsByUsersNetworks(Request $request) ], 'created_at' => new \Carbon\Carbon($group->created_at), 'updated_at' => new \Carbon\Carbon($group->max_updated_at_devices_updated_at), - + 'network_data' => $group->network_data ]); foreach ($group->upcomingParties() as $event) { @@ -565,7 +565,12 @@ public function moderateGroupsv2(Request $request) { * description="Image for the group", * property="image", * type="string", format="binary" - * ) + * ), + * @OA\Property( + * description="Network-defined JSON data", + * property="network_data", + * @OA\Schema() + * ), * ) * ) * ), @@ -586,7 +591,7 @@ public function createGroupv2(Request $request) { $user = $this->getUser(); $user->convertToHost(); - list($name, $area, $postcode, $location, $phone, $website, $description, $timezone, $latitude, $longitude, $country) = $this->validateGroupParams( + list($name, $area, $postcode, $location, $phone, $website, $description, $timezone, $latitude, $longitude, $country, $network_data) = $this->validateGroupParams( $request, true ); @@ -604,6 +609,7 @@ public function createGroupv2(Request $request) { 'shareable_code' => Fixometer::generateUniqueShareableCode(\App\Group::class, 'shareable_code'), 'timezone' => $timezone, 'phone' => $phone, + 'network_data' => $network_data, ]; $group = Group::create($data); @@ -696,7 +702,12 @@ public function createGroupv2(Request $request) { * description="Image for the group", * property="image", * type="string", format="binary" - * ) + * ), + * @OA\Property( + * description="Network-defined JSON data", + * property="network_data", + * @OA\Schema() + * ), * ) * ) * ), @@ -716,7 +727,7 @@ public function createGroupv2(Request $request) { public function updateGroupv2(Request $request, $idGroup) { $user = $this->getUser(); - list($name, $area, $postcode, $location, $phone, $website, $description, $timezone, $latitude, $longitude, $country) = $this->validateGroupParams( + list($name, $area, $postcode, $location, $phone, $website, $description, $timezone, $latitude, $longitude, $country, $network_data) = $this->validateGroupParams( $request, false ); @@ -741,6 +752,7 @@ public function updateGroupv2(Request $request, $idGroup) { 'free_text' => $description, 'timezone' => $timezone, 'phone' => $phone, + 'network_data' => $network_data, ]; if ($user->hasRole('Administrator') || $user->hasRole('NetworkCoordinator')) { @@ -857,6 +869,7 @@ private function validateGroupParams(Request $request, $create): array { $website = $request->input('website'); $description = $request->input('description'); $timezone = $request->input('timezone'); + $network_data = $request->input('network_data'); $latitude = null; $longitude = null; @@ -891,7 +904,8 @@ private function validateGroupParams(Request $request, $create): array { $timezone, $latitude, $longitude, - $country + $country, + $network_data, ); } } diff --git a/app/Http/Resources/Group.php b/app/Http/Resources/Group.php index d9c5ca4304..57a0edade7 100644 --- a/app/Http/Resources/Group.php +++ b/app/Http/Resources/Group.php @@ -117,6 +117,11 @@ * example="true" * ), * @OA\Property( + * description="Network-defined JSON data", + * property="network_data", + * @OA\Schema() + * ), + * @OA\Property( * property="stats", * title="stats", * description="An array of statistics about the activity of a group.", @@ -274,6 +279,7 @@ public function toArray($request) 'tags' => new TagCollection($this->group_tags), 'timezone' => $this->timezone, 'approved' => $this->approved ? true : false, + 'network_data' => $this->network_data, 'full' => true ]; diff --git a/app/Http/Resources/Party.php b/app/Http/Resources/Party.php index 86222e7f18..fe7fa6737d 100644 --- a/app/Http/Resources/Party.php +++ b/app/Http/Resources/Party.php @@ -94,6 +94,11 @@ * type="boolean", * ), * @OA\Property( + * description="Network-defined JSON data", + * property="network_data", + * @OA\Schema() + * ), + * @OA\Property( * property="stats", * title="stats", * description="An array of statistics about the activity of an event.", @@ -250,6 +255,7 @@ public function toArray($request) 'stats' => $this->resource->getEventStats(), 'updated_at' => Carbon::parse($this->updated_at)->toIso8601String(), 'approved' => $this->approved ? true : false, + 'network_data' => $this->network_data, 'full' => true, ]; } diff --git a/app/Party.php b/app/Party.php index 74dc260503..88f911250c 100644 --- a/app/Party.php +++ b/app/Party.php @@ -48,7 +48,8 @@ class Party extends Model implements Auditable 'devices_updated_at', 'link', 'timezone', - 'user_id' + 'user_id', + 'network_data', ]; protected $hidden = ['created_at', 'deleted_at', 'frequency', 'group', 'group', 'user_id', 'wordpress_post_id', 'cancelled', 'devices_updated_at']; @@ -58,6 +59,11 @@ class Party extends Model implements Auditable // Append data to Model protected $appends = ['participants', 'ShareableLink', 'event_date_local', 'start_local', 'end_local']; + protected $casts = [ + // JSON fields in the database should be converted to/from arrays. + 'network_data' => 'array' + ]; + //Getters public function findAllSearchable() { diff --git a/composer.json b/composer.json index 5719306303..6c1e7c6f91 100644 --- a/composer.json +++ b/composer.json @@ -19,6 +19,7 @@ "doctrine/dbal": "^2.13", "egulias/email-validator": "^3.0.0", "filp/whoops": "^2.14", + "geocoder-php/mapbox-provider": "^1.4", "guzzlehttp/guzzle": "^7.2", "hieu-le/wordpress-xmlrpc-client": "~2.0", "intervention/image": "^2.7", @@ -41,6 +42,7 @@ "symfony/http-client": "^6.2", "symfony/http-foundation": "^6.0", "symfony/mailgun-mailer": "^6.2", + "toin0u/geocoder-laravel": "^4.6", "twbs/bootstrap": "4.1.0", "wouternl/laravel-drip": "^1.2.4" }, diff --git a/composer.lock b/composer.lock index da26c5b554..3843654a41 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "4f8a9f097d45d20082d16e928ca792cb", + "content-hash": "c759fbce0aa9f769eddd2feb2df5db6d", "packages": [ { "name": "addwiki/mediawiki-api", @@ -1746,6 +1746,308 @@ ], "time": "2022-02-20T15:07:15+00:00" }, + { + "name": "geocoder-php/chain-provider", + "version": "4.5.0", + "source": { + "type": "git", + "url": "https://github.com/geocoder-php/chain-provider.git", + "reference": "ebcae03b9cc6f8dd1ebebf48f8105103e28b9152" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/geocoder-php/chain-provider/zipball/ebcae03b9cc6f8dd1ebebf48f8105103e28b9152", + "reference": "ebcae03b9cc6f8dd1ebebf48f8105103e28b9152", + "shasum": "" + }, + "require": { + "php": "^7.4 || ^8.0", + "psr/log": "^1.0|^2.0|^3.0", + "willdurand/geocoder": "^4.0" + }, + "provide": { + "geocoder-php/provider-implementation": "1.0" + }, + "require-dev": { + "nyholm/nsa": "^1.1", + "php-http/curl-client": "^2.2", + "php-http/message": "^1.0", + "phpunit/phpunit": "^9.5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "psr-4": { + "Geocoder\\Provider\\Chain\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "William Durand", + "email": "william.durand1@gmail.com" + } + ], + "description": "Geocoder chain adapter", + "homepage": "http://geocoder-php.org/Geocoder/", + "support": { + "source": "https://github.com/geocoder-php/chain-provider/tree/4.5.0" + }, + "time": "2022-07-30T12:09:30+00:00" + }, + { + "name": "geocoder-php/common-http", + "version": "4.5.0", + "source": { + "type": "git", + "url": "https://github.com/geocoder-php/php-common-http.git", + "reference": "4ee2cee60d21631e2a09c196bf6b9fd296bca728" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/geocoder-php/php-common-http/zipball/4ee2cee60d21631e2a09c196bf6b9fd296bca728", + "reference": "4ee2cee60d21631e2a09c196bf6b9fd296bca728", + "shasum": "" + }, + "require": { + "php": "^7.4 || ^8.0", + "php-http/client-implementation": "^1.0", + "php-http/discovery": "^1.6", + "php-http/httplug": "^1.0 || ^2.0", + "php-http/message-factory": "^1.0.2", + "psr/http-message": "^1.0", + "psr/http-message-implementation": "^1.0", + "willdurand/geocoder": "^4.0" + }, + "require-dev": { + "nyholm/psr7": "^1.0", + "php-http/message": "^1.0", + "php-http/mock-client": "^1.0", + "phpunit/phpunit": "^9.5", + "symfony/stopwatch": "~2.5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "psr-4": { + "Geocoder\\Http\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com" + } + ], + "description": "Common files for HTTP based Geocoders", + "homepage": "http://geocoder-php.org", + "keywords": [ + "http geocoder" + ], + "support": { + "source": "https://github.com/geocoder-php/php-common-http/tree/4.5.0" + }, + "time": "2022-07-30T12:09:30+00:00" + }, + { + "name": "geocoder-php/geo-plugin-provider", + "version": "4.3.0", + "source": { + "type": "git", + "url": "https://github.com/geocoder-php/geo-plugin-provider.git", + "reference": "fcb8fd60bb6324be305a90deae59497b928ccbd3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/geocoder-php/geo-plugin-provider/zipball/fcb8fd60bb6324be305a90deae59497b928ccbd3", + "reference": "fcb8fd60bb6324be305a90deae59497b928ccbd3", + "shasum": "" + }, + "require": { + "geocoder-php/common-http": "^4.0", + "igorw/get-in": "^1.0", + "php": "^7.4 || ^8.0", + "willdurand/geocoder": "^4.0" + }, + "provide": { + "geocoder-php/provider-implementation": "1.0" + }, + "require-dev": { + "geocoder-php/provider-integration-tests": "^1.0", + "php-http/curl-client": "^2.2", + "php-http/message": "^1.0", + "phpunit/phpunit": "^9.5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "psr-4": { + "Geocoder\\Provider\\GeoPlugin\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "William Durand", + "email": "william.durand1@gmail.com" + } + ], + "description": "Geocoder GeoPlugin adapter", + "homepage": "http://geocoder-php.org/Geocoder/", + "support": { + "source": "https://github.com/geocoder-php/geo-plugin-provider/tree/4.3.0" + }, + "time": "2022-07-30T10:48:32+00:00" + }, + { + "name": "geocoder-php/google-maps-provider", + "version": "4.7.0", + "source": { + "type": "git", + "url": "https://github.com/geocoder-php/google-maps-provider.git", + "reference": "378cd4dd26cba5a004f2a4738e8988e646af3274" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/geocoder-php/google-maps-provider/zipball/378cd4dd26cba5a004f2a4738e8988e646af3274", + "reference": "378cd4dd26cba5a004f2a4738e8988e646af3274", + "shasum": "" + }, + "require": { + "geocoder-php/common-http": "^4.0", + "php": "^7.4 || ^8.0", + "willdurand/geocoder": "^4.0" + }, + "provide": { + "geocoder-php/provider-implementation": "1.0" + }, + "require-dev": { + "geocoder-php/provider-integration-tests": "^1.0", + "php-http/curl-client": "^2.2", + "php-http/message": "^1.0", + "phpunit/phpunit": "^9.5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "psr-4": { + "Geocoder\\Provider\\GoogleMaps\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "William Durand", + "email": "william.durand1@gmail.com" + } + ], + "description": "Geocoder GoogleMaps adapter", + "homepage": "http://geocoder-php.org/Geocoder/", + "support": { + "source": "https://github.com/geocoder-php/google-maps-provider/tree/4.7.0" + }, + "time": "2022-07-30T12:09:30+00:00" + }, + { + "name": "geocoder-php/mapbox-provider", + "version": "1.4.0", + "source": { + "type": "git", + "url": "https://github.com/geocoder-php/mapbox-provider.git", + "reference": "95287b1c4724de32a1552bdaa27e53d7a9490fe8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/geocoder-php/mapbox-provider/zipball/95287b1c4724de32a1552bdaa27e53d7a9490fe8", + "reference": "95287b1c4724de32a1552bdaa27e53d7a9490fe8", + "shasum": "" + }, + "require": { + "geocoder-php/common-http": "^4.0", + "php": "^7.4 || ^8.0", + "willdurand/geocoder": "^4.0" + }, + "provide": { + "geocoder-php/provider-implementation": "1.0" + }, + "require-dev": { + "geocoder-php/provider-integration-tests": "^1.0", + "php-http/curl-client": "^2.2", + "php-http/message": "^1.0", + "phpunit/phpunit": "^9.5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "psr-4": { + "Geocoder\\Provider\\Mapbox\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fede Isas", + "email": "federicoisas@gmail.com" + } + ], + "description": "Geocoder Mapbox adapter", + "homepage": "http://geocoder-php.org/Geocoder/", + "support": { + "source": "https://github.com/geocoder-php/mapbox-provider/tree/1.4.0" + }, + "time": "2022-07-30T12:09:30+00:00" + }, { "name": "graham-campbell/result-type", "version": "v1.1.0", @@ -2254,6 +2556,55 @@ }, "time": "2021-07-21T13:50:14+00:00" }, + { + "name": "igorw/get-in", + "version": "v1.0.3", + "source": { + "type": "git", + "url": "https://github.com/igorw/get-in.git", + "reference": "170ded831f49abc6a6061f655aba9bdbcf7b8111" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/igorw/get-in/zipball/170ded831f49abc6a6061f655aba9bdbcf7b8111", + "reference": "170ded831f49abc6a6061f655aba9bdbcf7b8111", + "shasum": "" + }, + "require": { + "php": ">=5.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "files": [ + "src/get_in.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Igor Wiedler", + "email": "igor@wiedler.ch" + } + ], + "description": "Functions for for hash map (assoc array) traversal.", + "keywords": [ + "assoc-array", + "hash-map" + ], + "support": { + "issues": "https://github.com/igorw/get-in/issues", + "source": "https://github.com/igorw/get-in/tree/v1.0.3" + }, + "time": "2014-12-15T23:03:51+00:00" + }, { "name": "intervention/image", "version": "2.7.2", @@ -4550,6 +4901,75 @@ }, "time": "2022-09-29T09:59:43+00:00" }, + { + "name": "php-http/curl-client", + "version": "2.2.1", + "source": { + "type": "git", + "url": "https://github.com/php-http/curl-client.git", + "reference": "2ed4245a817d859dd0c1d51c7078cdb343cf5233" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-http/curl-client/zipball/2ed4245a817d859dd0c1d51c7078cdb343cf5233", + "reference": "2ed4245a817d859dd0c1d51c7078cdb343cf5233", + "shasum": "" + }, + "require": { + "ext-curl": "*", + "php": "^7.1 || ^8.0", + "php-http/discovery": "^1.6", + "php-http/httplug": "^2.0", + "php-http/message": "^1.2", + "psr/http-client": "^1.0", + "psr/http-factory": "^1.0", + "symfony/options-resolver": "^3.4 || ^4.0 || ^5.0 || ^6.0" + }, + "provide": { + "php-http/async-client-implementation": "1.0", + "php-http/client-implementation": "1.0", + "psr/http-client-implementation": "1.0" + }, + "require-dev": { + "guzzlehttp/psr7": "^1.0", + "laminas/laminas-diactoros": "^2.0", + "php-http/client-integration-tests": "^3.0", + "phpunit/phpunit": "^7.5 || ^9.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.x-dev" + } + }, + "autoload": { + "psr-4": { + "Http\\Client\\Curl\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Михаил Красильников", + "email": "m.krasilnikov@yandex.ru" + } + ], + "description": "PSR-18 and HTTPlug Async client with cURL", + "homepage": "http://php-http.org", + "keywords": [ + "curl", + "http", + "psr-18" + ], + "support": { + "issues": "https://github.com/php-http/curl-client/issues", + "source": "https://github.com/php-http/curl-client/tree/2.2.1" + }, + "time": "2021-12-10T18:02:07+00:00" + }, { "name": "php-http/discovery", "version": "1.14.3", @@ -8981,6 +9401,89 @@ }, "time": "2023-01-03T09:29:04+00:00" }, + { + "name": "toin0u/geocoder-laravel", + "version": "4.6.0", + "source": { + "type": "git", + "url": "https://github.com/geocoder-php/GeocoderLaravel.git", + "reference": "bdbb274ecd9fb32f0937237607456cb0d64a2ebb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/geocoder-php/GeocoderLaravel/zipball/bdbb274ecd9fb32f0937237607456cb0d64a2ebb", + "reference": "bdbb274ecd9fb32f0937237607456cb0d64a2ebb", + "shasum": "" + }, + "require": { + "geocoder-php/chain-provider": "^4.0", + "geocoder-php/geo-plugin-provider": "^4.0", + "geocoder-php/google-maps-provider": "^4.0", + "guzzlehttp/psr7": "*", + "http-interop/http-factory-guzzle": "^1.0", + "illuminate/cache": "^5.0|^6.0|^7.0|^8.0|^9.0|^10.0", + "illuminate/support": "^5.0|^6.0|^7.0|^8.0|^9.0|^10.0", + "php": "^8.0", + "php-http/curl-client": "*", + "willdurand/geocoder": "^4.0" + }, + "require-dev": { + "doctrine/dbal": "*", + "geocoder-php/bing-maps-provider": "^4.0", + "geocoder-php/geoip2-provider": "^4.0", + "geocoder-php/maxmind-binary-provider": "^4.0", + "laravel/legacy-factories": "^1.0", + "orchestra/testbench": "^7.0|^8.0", + "orchestra/testbench-browser-kit": "^7.0", + "orchestra/testbench-dusk": "^7.0", + "php-coveralls/php-coveralls": "*", + "phpunit/phpunit": "8.5|^9.0", + "sebastian/phpcpd": "^5.0|^6.0" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Geocoder\\Laravel\\Providers\\GeocoderService" + ] + } + }, + "autoload": { + "psr-4": { + "Geocoder\\Laravel\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike Bronner", + "email": "hello@genealabs.com", + "homepage": "https://genealabs.com", + "role": "Developer, Maintainer" + }, + { + "name": "Antoine Corcy", + "email": "contact@sbin.dk", + "homepage": "http://sbin.dk", + "role": "Original Creator" + } + ], + "description": "Geocoder Service Provider for Laravel", + "homepage": "http://geocoder-php.org/", + "keywords": [ + "geocoder", + "geocoding", + "laravel" + ], + "support": { + "issues": "https://github.com/geocoder-php/GeocoderLaravel/issues", + "source": "https://github.com/geocoder-php/GeocoderLaravel/tree/4.6.0" + }, + "time": "2023-02-16T17:34:31+00:00" + }, { "name": "twbs/bootstrap", "version": "v4.1.0", @@ -9252,6 +9755,68 @@ }, "time": "2022-06-03T18:03:27+00:00" }, + { + "name": "willdurand/geocoder", + "version": "4.6.0", + "source": { + "type": "git", + "url": "https://github.com/geocoder-php/php-common.git", + "reference": "be3d9ed0fddf8c698ee079d8a07ae9520b4a49a1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/geocoder-php/php-common/zipball/be3d9ed0fddf8c698ee079d8a07ae9520b4a49a1", + "reference": "be3d9ed0fddf8c698ee079d8a07ae9520b4a49a1", + "shasum": "" + }, + "require": { + "php": "^7.4 || ^8.0" + }, + "require-dev": { + "nyholm/nsa": "^1.1", + "phpunit/phpunit": "^9.5", + "symfony/stopwatch": "~2.5" + }, + "suggest": { + "symfony/stopwatch": "If you want to use the TimedGeocoder" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.1-dev" + } + }, + "autoload": { + "psr-4": { + "Geocoder\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "William Durand", + "email": "william.durand1@gmail.com" + } + ], + "description": "Common files for PHP Geocoder", + "homepage": "http://geocoder-php.org", + "keywords": [ + "abstraction", + "geocoder", + "geocoding", + "geoip" + ], + "support": { + "source": "https://github.com/geocoder-php/php-common/tree/4.6.0" + }, + "time": "2022-07-30T11:09:43+00:00" + }, { "name": "wouternl/laravel-drip", "version": "1.2.4", diff --git a/config/geocoder.php b/config/geocoder.php new file mode 100644 index 0000000000..2e65da6ba4 --- /dev/null +++ b/config/geocoder.php @@ -0,0 +1,109 @@ + [ + + /* + |----------------------------------------------------------------------- + | Cache Store + |----------------------------------------------------------------------- + | + | Specify the cache store to use for caching. The value "null" will use + | the default cache store specified in /config/cache.php file. + | + | Default: null + | + */ + + 'store' => null, + + /* + |----------------------------------------------------------------------- + | Cache Duration + |----------------------------------------------------------------------- + | + | Specify the cache duration in seconds. The default approximates a + | "forever" cache, but there are certain issues with Laravel's forever + | caching methods that prevent us from using them in this project. + | + | Default: 9999999 (integer) + | + */ + + 'duration' => 9999999, + ], + + /* + |--------------------------------------------------------------------------- + | Providers + |--------------------------------------------------------------------------- + | + | Here you may specify any number of providers that should be used to + | perform geocaching operations. The `chain` provider is special, + | in that it can contain multiple providers that will be run in + | the sequence listed, should the previous provider fail. By + | default the first provider listed will be used, but you + | can explicitly call subsequently listed providers by + | alias: `app('geocoder')->using('google_maps')`. + | + | Please consult the official Geocoder documentation for more info. + | https://github.com/geocoder-php/Geocoder#providers + | + */ + 'providers' => [ + Chain::class => [ + Mapbox::class => [ + env('MAPBOX_TOKEN'), + ], + GeoPlugin::class => [], + ], + ], + + /* + |--------------------------------------------------------------------------- + | Adapter + |--------------------------------------------------------------------------- + | + | You can specify which PSR-7-compliant HTTP adapter you would like to use. + | There are multiple options at your disposal: CURL, Guzzle, and others. + | + | Please consult the official Geocoder documentation for more info. + | https://github.com/geocoder-php/Geocoder#usage + | + | Default: Client::class (FQCN for CURL adapter) + | + */ + 'adapter' => Client::class, + + /* + |--------------------------------------------------------------------------- + | Reader + |--------------------------------------------------------------------------- + | + | You can specify a reader for specific providers, like GeoIp2, which + | connect to a local file-database. The reader should be set to an + | instance of the required reader class or an array containing the reader + | class and arguments. + | + | Please consult the official Geocoder documentation for more info. + | https://github.com/geocoder-php/geoip2-provider + | + | Default: null + | + | Example: + | 'reader' => [ + | WebService::class => [ + | env('MAXMIND_USER_ID'), + | env('MAXMIND_LICENSE_KEY') + | ], + | ], + | + */ + 'reader' => null, + +]; diff --git a/database/migrations/2023_04_19_153453_network_data.php b/database/migrations/2023_04_19_153453_network_data.php new file mode 100644 index 0000000000..3a7c7db8fc --- /dev/null +++ b/database/migrations/2023_04_19_153453_network_data.php @@ -0,0 +1,40 @@ +json('network_data')->nullable(); + }); + Schema::table('events', function (Blueprint $table) { + $table->json('network_data')->nullable(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('groups', function (Blueprint $table) { + $table->dropColumn('network_data'); + }); + Schema::table('events', function (Blueprint $table) { + $table->dropColumn('network_data'); + }); + } +}; diff --git a/tests/Feature/Groups/APIv2GroupTest.php b/tests/Feature/Groups/APIv2GroupTest.php index a044df4673..ec86bd8def 100644 --- a/tests/Feature/Groups/APIv2GroupTest.php +++ b/tests/Feature/Groups/APIv2GroupTest.php @@ -59,6 +59,9 @@ public function testGetGroup($approve) { $this->assertEquals('London', $location['location']); $this->assertEquals('United Kingdom', $location['country']); + // Check the network data has been created as expected. + $this->assertEquals('dummy', $json['data']['network_data']['dummy']); + // Test group moderation. $response = $this->get("/api/v2/moderate/groups?api_token=1234"); $response->assertSuccessful(); diff --git a/tests/Feature/Groups/GroupCreateTest.php b/tests/Feature/Groups/GroupCreateTest.php index b890262cb9..369cad7eb0 100644 --- a/tests/Feature/Groups/GroupCreateTest.php +++ b/tests/Feature/Groups/GroupCreateTest.php @@ -37,6 +37,7 @@ public function testCreate() self::assertEquals(1, count($ret)); self::assertEquals($idgroups, $ret[0]['idgroups']); self::assertEquals($group->name, $ret[0]['name']); + self::assertEquals('dummy', $ret[0]['network_data']['dummy']); } public function testCreateGroupAsRestarter() { diff --git a/tests/Feature/Groups/GroupEditTest.php b/tests/Feature/Groups/GroupEditTest.php index e6a6f75147..9196c8773c 100644 --- a/tests/Feature/Groups/GroupEditTest.php +++ b/tests/Feature/Groups/GroupEditTest.php @@ -40,12 +40,21 @@ public function group_tags_retained_after_edited_by_host() 'name' => 'Test', 'website' => 'https://therestartproject.org', 'free_text' => 'HQ', + 'network_data' => [ + 'no_dummy' => 'no_dummy' + ] ]); $response->assertSuccessful(); + $group->refresh(); $this->assertEquals(1, count($group->group_tags)); $this->assertEquals($tag->tag_name, $group->group_tags[0]->tag_name); + + // Network data should have changed. + $this->assertEquals($group->network_data, [ + 'no_dummy' => 'no_dummy' + ]); } public function testEditGroupAsRestarter() { diff --git a/tests/TestCase.php b/tests/TestCase.php index ffd20953be..5104847cb1 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -170,7 +170,10 @@ public function createGroup($name = 'Test Group', $website = 'https://therestart 'website' => $website, 'location' => $location, 'description' => $text, - 'timezone' => 'Europe/London' + 'timezone' => 'Europe/London', + 'network_data' => [ + 'dummy' => 'dummy', + ] ]); if ($assert) { diff --git a/tests/Unit/t/GeocoderTest.php b/tests/Unit/t/GeocoderTest.php new file mode 100644 index 0000000000..b2a96e3d8c --- /dev/null +++ b/tests/Unit/t/GeocoderTest.php @@ -0,0 +1,16 @@ +geocode('6 Canterbury Crescent, London SW9 7QD'); + $this->assertEquals(51.4643585, $ret['latitude']); + $this->assertEquals(-0.1135401, $ret['longitude']); + $this->assertEquals('United Kingdom', $ret['country']); + } +}