Skip to content

Commit 4f6b660

Browse files
authored
Merge pull request #661 from hhaccessibility/issue-460
Issue 460
2 parents c184643 + 93aa8b8 commit 4f6b660

15 files changed

Lines changed: 353 additions & 121 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@
22
/importers/**/*.class
33
/importers/**/raw_html/*.html
44
/importers/**/raw_xml/*.xml
5+
.DS_Store

app/app/Http/Controllers/LocationManagementController.php

Lines changed: 131 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
use App\Location;
44
use App\BaseUser;
55
use App\User;
6+
use App\Role;
67
use App\Libraries\Gis;
78
use App\Libraries\StringMatcher;
89
use App\Libraries\StringMatcherRepository;
@@ -89,12 +90,37 @@ private function getLocationGroupForLocationName($location_name)
8990
return $matched_group;
9091
}
9192

92-
private function getLocationAddViewData()
93+
private function getLocationAddViewData($location_id = '')
9394
{
9495
$user = BaseUser::getDbUser();
9596
$location_groups = DB::table('location_group')->orderBy('name')->get();
9697
$location_tags = DB::table('location_tag')->orderBy('name')->get();
97-
$location = new Location();
98+
if (!empty($location_id)) {
99+
$location=location::find($location_id);
100+
$location_tag_location_ids = DB::table('location_location_tag')
101+
->where('location_id', '=', $location_id)
102+
->get(array('location_tag_id'))->toArray();
103+
104+
$array_location_ids = array_map(function ($item) {
105+
return (array)$item;
106+
}, $location_tag_location_ids);
107+
108+
foreach ($array_location_ids as $array_location_id) {
109+
$location_location_tag_ids[] = $array_location_id['location_tag_id'];
110+
}
111+
112+
if (!isset($location_location_tag_ids)|| $location_location_tag_ids === null) {
113+
$location_location_tag_ids = [];
114+
}
115+
foreach ($location_tags as $location_tag) {
116+
$location_tag->is_selected = in_array($location_tag->id, $location_location_tag_ids);
117+
}
118+
} else {
119+
$location = new Location();
120+
foreach ($location_tags as $location_tag) {
121+
$location_tag->is_selected = false;
122+
}
123+
}
98124
$location->latitude = $user->latitude;
99125
$location->longitude = $user->longitude;
100126
if ($location->latitude === null) {
@@ -103,9 +129,6 @@ private function getLocationAddViewData()
103129
if ($location->longitude === null) {
104130
$location->longitude = BaseUser::getLongitude();
105131
}
106-
foreach ($location_tags as $location_tag) {
107-
$location_tag->is_selected = false;
108-
}
109132
return [
110133
'location' => $location,
111134
'location_groups' => $location_groups,
@@ -121,9 +144,9 @@ public function addNewLocation()
121144
$view_data['locations'] = json_encode(
122145
$this->getLocationsNear($view_data['location']->longitude, $view_data['location']->latitude)
123146
);
124-
return view('pages.location_management.add_new_location', $view_data);
147+
return view('pages.location_management.add_or_edit_location', $view_data);
125148
}
126-
149+
127150
private static function isDuplicateLocation($location)
128151
{
129152
$maxRadius = 50; // 50 meters
@@ -137,6 +160,16 @@ private static function isDuplicateLocation($location)
137160
return count($locations) !== 0;
138161
}
139162

163+
public function editLocation($location_id)
164+
{
165+
$view_data = $this->getLocationAddViewData($location_id);
166+
$view_data['location'] = DB::table('location')->where("id", '=', trim($location_id))->first();
167+
$view_data['action'] = 'edit';
168+
$view_data['locations'] = json_encode($this->
169+
getLocationsNear($view_data['location']->longitude, $view_data['location']->latitude));
170+
return view('pages.location_management.add_or_edit_location', $view_data);
171+
}
172+
140173
public function addNewLocationSave(Request $request)
141174
{
142175
$user = BaseUser::getDbUser();
@@ -195,7 +228,7 @@ public function addNewLocationSave(Request $request)
195228
}
196229
if ($custom_validation_failed) {
197230
$view_data['errors'] = $validator->errors();
198-
return view('pages.location_management.add_new_location', $view_data);
231+
return view('pages.location_management.add_or_edit_location', $view_data);
199232
}
200233

201234
$location->creator_user_id = $user->id;
@@ -205,20 +238,28 @@ public function addNewLocationSave(Request $request)
205238
// Delete records from child tables.
206239
DB::transaction(function () use ($location, $view_data) {
207240
$location->save();
208-
foreach ($view_data['location_tags'] as $location_tag) {
209-
if ($location_tag->is_selected) {
210-
DB::table('location_location_tag')->insert(
211-
['location_id' => $location->id,
212-
'location_tag_id' => $location_tag->id,
213-
'id' => Uuid::generate(4)->string]
214-
);
215-
}
216-
}
241+
$this->saveLocationLocationTag($location, $view_data);
217242
});
218243

219244
return view('pages.location_management.location_created', $view_data);
220245
}
221246

247+
public function saveLocationLocationTag($location, $view_data, $action = '')
248+
{
249+
if (!empty($action) && $action == 'edit') {
250+
DB::table('location_location_tag')->where('location_id', '=', $location->id)->delete();
251+
}
252+
foreach ($view_data['location_tags'] as $location_tag) {
253+
if ($location_tag->is_selected) {
254+
DB::table('location_location_tag')->insert(
255+
['location_id' => $location->id,
256+
'location_tag_id' => $location_tag->id,
257+
'id' => Uuid::generate(4)->string]
258+
);
259+
}
260+
}
261+
}
262+
222263
public function showCurrentUserLocations()
223264
{
224265
$user = BaseUser::getDbUser();
@@ -250,13 +291,84 @@ public function showCurrentUserLocations()
250291
foreach ($locations as $location) {
251292
$location->is_safe_to_delete = in_array($location->id, $location_ids);
252293
}
253-
254294
$view_data = [
255295
'locations' => $locations
256296
];
297+
257298
return view('pages.location_management.locations_added_by_me', $view_data);
258299
}
259300

301+
public function editLocationSave(Request $request)
302+
{
303+
$user = BaseUser::getDbUser();
304+
// perform some validation.
305+
$validation_rules = array(
306+
'location_id' => 'required|string',
307+
'name' => 'required|between:2,255','phone_number' => 'max:50',
308+
'address' => 'max:255|required',
309+
'external_web_url' => 'max:255|url',
310+
'location_tags' => 'array',
311+
'location_tags.*' => 'int|required'
312+
// Every array element is an integer.
313+
);
314+
$validator = Validator::make(Input::all(), $validation_rules);
315+
$fields = ['name','address', 'phone_number',
316+
'external_web_url', 'location_group_id'];
317+
$input_edit_id = Input::get('location_id');
318+
$view_data = $this->getLocationAddViewData($input_edit_id);
319+
foreach ($fields as $fieldName) {
320+
if (Input::has($fieldName)) {
321+
$view_data['location']->{$fieldName} = Input::get($fieldName);
322+
} else {
323+
$view_data['location']->{$fieldName} = '';
324+
}
325+
}
326+
$location_group_id = Input::get('location_group_id');
327+
if (!is_numeric($location_group_id)) {
328+
$location_group_id = null; // convert things like '-' to null.
329+
} else {
330+
$location_group_id = intval($location_group_id);
331+
}
332+
$location = $view_data['location'];
333+
if (!$user->hasRole(Role::INTERNAL) && $user->id !== $location->creator_user_id) {
334+
throw new AuthenticationException('You are not authorized to edit this location');
335+
}
336+
$location->location_group_id = $location_group_id;
337+
$custom_validation_failed = false;
338+
$selected_location_tag_ids = Input::get('location_tags');
339+
if ($selected_location_tag_ids === null) {
340+
$selected_location_tag_ids = [];
341+
}
342+
343+
foreach ($view_data['location_tags'] as $location_tag) {
344+
$location_tag->is_selected = in_array($location_tag->id, $selected_location_tag_ids);
345+
}
346+
if (!$validator->fails()) {
347+
if ($location->phone_number !== '' && preg_match_all("/[0-9]/", $location->phone_number) < 9) {
348+
$validator->errors()->add('phone_number', 'At least 9 digits needed in phone number');
349+
$custom_validation_failed = true;
350+
} elseif (strlen(trim($location->address)) < 5) {
351+
$validator->errors()->add('address', 'Address must be at least 5 characters long');
352+
$custom_validation_failed = true;
353+
}
354+
} else {
355+
$custom_validation_failed = true;
356+
}
357+
if ($custom_validation_failed) {
358+
$view_data['errors'] = $validator->errors();
359+
return view('pages.location_management.add_or_edit_location', $view_data);
360+
}
361+
362+
// Send the information to the database in a single transaction.
363+
// Delete records from child tables.
364+
DB::transaction(function () use ($location, $view_data) {
365+
$location->save();
366+
$this->saveLocationLocationTag($location, $view_data, 'edit');
367+
});
368+
369+
return Redirect('/location/report/' . $location->id);
370+
}
371+
260372
public function deleteMyLocation(string $location_id)
261373
{
262374
$user = BaseUser::getDbUser();
@@ -283,7 +395,7 @@ public function deleteMyLocation(string $location_id)
283395
DB::table('location_location_tag')->where('location_id', '=', $location->id)->delete();
284396
DB::table('location')->where('id', '=', $location->id)->delete();
285397
});
286-
return Redirect('/locations-added-by-me');
398+
return Redirect('/location/management/add');
287399
}
288400

289401
public function show(string $location_id)

app/database/seeds/data/faq_item.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
{"id": 3, "question": "Who owns the map data?", "answer_html": "<p>The map data on AccessLocator is open and public. <a href=\"/contact\">Contact us</a> with a request if you want to get a lot of our data.</p>"},
55
{"id": 4, "question": "Who is behind AccessLocator?", "answer_html": "<p>AccessLocator was entirely created from volunteer effort and funding from <a href=\"http://www.jmccentre.ca/\">JMCC</a>.</p>"},
66
{"id": 5, "question": "Why can't I find some places on AccessLocator?", "answer_html": "<p>You can add locations if you can't find it. Windsor has the most complete set of locations for now but we're always growing thanks to people like you who sign up and share what you know about locations in your area.</p>"},
7-
{"id": 6, "question": "How do I rate a location?", "answer_html": "<ol><li><a href=\"/signin\">Sign in</a>.</li><li>Find the location. Start your search from the <a href=\"/\">home page</a>.</li><li>Click one of the locations to open a page on <a href=\"/location-report/00000000-0000-0000-0000-000000000040\">the location</a>.</li><li>Click one of <a href=\"/location-rating/00000000-0000-0000-0000-000000000040/6\">the question categories</a>.</li><li>Answer questions by clicking buttons.</li></ol>."},
7+
{"id": 6, "question": "How do I rate a location?", "answer_html": "<ol><li><a href=\"/signin\">Sign in</a>.</li><li>Find the location. Start your search from the <a href=\"/\">home page</a>.</li><li>Click one of the locations to open a page on <a href=\"/location/report/00000000-0000-0000-0000-000000000040\">the location</a>.</li><li>Click one of <a href=\"/location/rating/00000000-0000-0000-0000-000000000040/6\">the question categories</a>.</li><li>Answer questions by clicking buttons.</li></ol>."},
88
{"id": 7, "question": "How do I register with AccessLocator?", "answer_html": "<p>You can register on <a href=\"/signup\">our sign up page</a>. You can sign up using <a href=\"/socialauth/auth/Facebook\">facebook</a>, <a href=\"/socialauth/auth/Google\">google</a>, or by entering your information there.</p>"},
99
{"id": 8, "question": "I'm planning a trip. How can AccessLocator help?", "answer_html": "<p>Get informed about where you're traveling and plan carefully. Search for locations on <a href=\"/\">AccessLocator</a> where you plan to travel. More tips on travelling with disabilities can be found at <a target=\"_empty\" href=\"https://www.ricksteves.com/travel-tips/trip-planning/travelers-with-disabilities\">ricksteves.com</a>.</p>"},
1010
{"id": 9, "question": "How can I upload photos of a location?", "answer_html": "<p>The location photos feature is under development but not ready yet.</p>"}

app/public/js/add_location.js

Lines changed: 0 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
var user_input_marker;
2-
var map;
3-
41
function initMap() {
52
// initial map location
63
var initPoint = {lat: parseFloat($('#latitude').val()), lng: parseFloat($('#longitude').val()) };
@@ -40,43 +37,6 @@ function initMap() {
4037
updateNearbyLocationMarkers();
4138
}
4239

43-
function sanitizeExternalWebURL() {
44-
var field_id = 'external_web_url';
45-
var $element = $('#' + field_id);
46-
singleSpaceAndTrim(field_id)();
47-
var val = $element.val();
48-
if ( val !== '' ) {
49-
var index = val.indexOf(':/');
50-
// Fix missing extra slash in protocol.
51-
// For example, 'http:/www.google.com' instead of 'http://www.google.com'.
52-
if ( index < 8 && val.indexOf('://') !== index ) {
53-
val = val.substring(0, index) + '://' + val.substring(index + 2);
54-
}
55-
var protocol = val.split('://');
56-
// If no protocol specified, use http.
57-
if ( protocol.length === 1 ) {
58-
val = 'http://' + val;
59-
}
60-
else {
61-
protocol = protocol[0].toLowerCase();
62-
// Use one of the HTTP protocols instead of anything else like ftp.
63-
if ( ['http', 'https'].indexOf(protocol) === -1 ) {
64-
protocol = 'http';
65-
}
66-
val = protocol + '://' + val.substring(val.indexOf('://') + 3);
67-
}
68-
// Replace with sanitized value.
69-
$element.val(val);
70-
}
71-
}
72-
73-
function singleSpaceAndTrim(field_id) {
74-
return function() {
75-
var $element = $('#' + field_id);
76-
$element.val($element.val().trim().replace(/\s+/g, ' '));
77-
};
78-
}
79-
8040
function setHiddenValue(param_name, value) {
8141
$('#' + param_name).val(value);
8242
}
@@ -152,45 +112,6 @@ function setLocationPosition(new_position) {
152112
addLocationsNear(new_position.lng(), new_position.lat());
153113
}
154114

155-
function getNameElement() {
156-
return $('#name');
157-
}
158-
159-
function getName() {
160-
return getNameElement().val();
161-
}
162-
163-
function processName(new_name) {
164-
// Avoid route match problems from having slashes in the name.
165-
new_name = new_name.replace(/[\/\\]/g, ' ');
166-
var api_route = '/location-suggestions-for-name/';
167-
$.ajax({
168-
'method': 'GET',
169-
'url': api_route + new_name,
170-
'success': function(response) {
171-
// update the location tags.
172-
var selected_a_location_tag = false;
173-
$('#location_tags option:not(#location-tag-i-do-not-know)').each(function() {
174-
var $this = $(this);
175-
$this.prop('selected', response.location_tags[$this.val()].is_matched);
176-
selected_a_location_tag = true;
177-
});
178-
if( selected_a_location_tag ) {
179-
$('#location-tag-i-do-not-know').prop('selected', false);
180-
}
181-
182-
// update the location group.
183-
if( response.location_group === null ) {
184-
response.location_group = '-';
185-
}
186-
$('#location_group_id').val(response.location_group);
187-
},
188-
'error': function() {
189-
console.error('Failed to get respone from ' + api_route);
190-
}
191-
});
192-
}
193-
194115
function getAddress() {
195116
return $('#address').val();
196117
}

0 commit comments

Comments
 (0)