From 451437ed6adb65b5181184339bac9095632ab10d Mon Sep 17 00:00:00 2001 From: Jonny Barnes Date: Sun, 28 May 2017 22:45:14 +0100 Subject: [PATCH] Allow simple merging of places --- .../Controllers/Admin/PlacesController.php | 51 +++++++++++++++++++ app/Place.php | 38 ++++++-------- resources/views/admin/places/edit.blade.php | 2 + .../views/admin/places/merge/edit.blade.php | 47 +++++++++++++++++ .../views/admin/places/merge/index.blade.php | 14 +++++ routes/web.php | 3 ++ 6 files changed, 132 insertions(+), 23 deletions(-) create mode 100644 resources/views/admin/places/merge/edit.blade.php create mode 100644 resources/views/admin/places/merge/index.blade.php diff --git a/app/Http/Controllers/Admin/PlacesController.php b/app/Http/Controllers/Admin/PlacesController.php index 2e655c42..47aed5f4 100644 --- a/app/Http/Controllers/Admin/PlacesController.php +++ b/app/Http/Controllers/Admin/PlacesController.php @@ -95,4 +95,55 @@ class PlacesController extends Controller return redirect('/admin/places'); } + + /** + * List the places we can merge with the current place. + * + * @param string Place id + * @return Illuminate\View\Factory view + */ + public function mergeIndex($placeId) + { + $first = Place::find($placeId); + $results = Place::near(new Point($first->latitude, $first->longitude))->get(); + $places = []; + foreach ($results as $place) { + if ($place->slug !== $first->slug) { + $places[] = $place; + } + } + + return view('admin.places.merge.index', compact('first', 'places')); + } + + public function mergeEdit($place1_id, $place2_id) + { + $place1 = Place::find($place1_id); + $place2 = Place::find($place2_id); + + return view('admin.places.merge.edit', compact('place1', 'place2')); + } + + public function mergeStore(Request $request) + { + $place1 = Place::find($request->input('place1')); + $place2 = Place::find($request->input('place2')); + + if ($request->input('delete') === '1') { + foreach ($place1->notes as $note) { + $note->place()->dissociate(); + $note->place()->associate($place2->id); + } + $place1->delete(); + } + if ($request->input('delete') === '2') { + foreach ($place2->notes as $note) { + $note->place()->dissociate(); + $note->place()->associate($place1->id); + } + $place2->delete(); + } + + return redirect('/admin/places'); + } } diff --git a/app/Place.php b/app/Place.php index 42ece165..75634337 100644 --- a/app/Place.php +++ b/app/Place.php @@ -4,6 +4,8 @@ namespace App; use DB; use Illuminate\Database\Eloquent\Model; +use Illuminate\Database\Eloquent\Builder; +use Phaza\LaravelPostgis\Geometries\Point; use MartinBean\Database\Eloquent\Sluggable; use Phaza\LaravelPostgis\Eloquent\PostgisTrait; @@ -45,33 +47,23 @@ class Place extends Model } /** - * Get all places within a specified distance. + * Select places near a given location. * - * @param float latitude - * @param float longitude - * @param int maximum distance - * @todo Check this shit. + * @param \Illuminate\Database\Eloquent\Builder $query + * @param Point $point + * @param int Distance + * @return \Illuminate\Database\Eloquent\Builder */ - public static function near(float $lat, float $lng, int $distance) + public function scopeNear(Builder $query, Point $point, $distance = 100) { - $point = $lng . ' ' . $lat; - $distace = $distance ?? 1000; - $places = DB::select(DB::raw("select - name, - slug, - ST_AsText(location) AS location, - ST_Distance( - ST_GeogFromText('SRID=4326;POINT($point)'), - location - ) AS distance - from places - where ST_DWithin( - ST_GeogFromText('SRID=4326;POINT($point)'), - location, - $distance - ) ORDER BY distance")); + $field = DB::raw( + sprintf("ST_Distance(%s.location, ST_GeogFromText('%s'))", + $this->getTable(), + $point->toWKT() + ) + ); - return $places; + return $query->where($field, '<=', $distance)->orderBy($field); } /* diff --git a/resources/views/admin/places/edit.blade.php b/resources/views/admin/places/edit.blade.php index 3efae944..4c492593 100644 --- a/resources/views/admin/places/edit.blade.php +++ b/resources/views/admin/places/edit.blade.php @@ -119,6 +119,8 @@ Edit Place « Admin CP

+ +

Merge with another place?

@stop @section('scripts') diff --git a/resources/views/admin/places/merge/edit.blade.php b/resources/views/admin/places/merge/edit.blade.php new file mode 100644 index 00000000..2a9fb14a --- /dev/null +++ b/resources/views/admin/places/merge/edit.blade.php @@ -0,0 +1,47 @@ +@extends('master') + +@section('title') +Merge Places « Admin CP +@stop + +@section('content') +

Merge places

+

When a place is deleted, it is removed from the database, and all the notes associated with it, will be re-associated with the other place.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {{ csrf_field() }} + + + + + + +
Place 1Place 2
Name{{ $place1->name }}{{ $place2->name }}
Description{{ $place1->description }}{{ $place2->description }}
location{{ $place1->latitude }}, {{ $place1->longitude }}{{ $place2->latitude }}, {{ $place2->longitude }}
Foursquare{{ $place1->foursquare }}{{ $place2->foursquare }}
+@stop diff --git a/resources/views/admin/places/merge/index.blade.php b/resources/views/admin/places/merge/index.blade.php new file mode 100644 index 00000000..e9b3120c --- /dev/null +++ b/resources/views/admin/places/merge/index.blade.php @@ -0,0 +1,14 @@ +@extends('master') + +@section('title') +Merge Places « Admin CP +@stop + +@section('content') +

We shall be merging {{ $first->name }}. It’s location is Point({{ $first->location }}).

+ +@stop diff --git a/routes/web.php b/routes/web.php index fe462895..d006be26 100644 --- a/routes/web.php +++ b/routes/web.php @@ -80,6 +80,9 @@ Route::group(['domain' => config('url.longurl')], function () { Route::post('/', 'PlacesController@store'); Route::get('/{id}/edit', 'PlacesController@edit'); Route::put('/{id}', 'PlacesController@update'); + Route::get('/{id}/merge', 'PlacesController@mergeIndex'); + Route::get('/{place1_id}/merge/{place2_id}', 'PlacesController@mergeEdit'); + Route::post('/merge', 'PlacesController@mergeStore'); Route::delete('/{id}', 'PlacesController@destroy'); }); });