@miiikkeyyyy I wouldn’t do any geocoding in a controller, as if the geocoding service takes a long time to load, is down etc, then you’re putting that on the user. Instead, I do it in a queued job, which can keep re-trying if geocoding isn’t successful for whatever reason.
In the past, I’ve had an interface that mandates two methods:
interface Geocodable
{
public function getAddressString();
public function setCoordinates($latitude, $longitude);
}
I then apply this to whatever model I want to be “geocodable”:
class Venue extends Model implements Geocodable
{
public function getAddressString()
{
return sprintf('%s, %s', $this->hometown, $this->country);
}
public function setCoordinates($latitude, $longitude)
{
return $this->update(compact('latitude', 'longitude'));
}
}
Then when a model is created, I’ll dispatch a job:
class VenueController extends Controller
{
public function store(Request $request)
{
$venue = Venue::create($request->all());
$this->dispatch(new GeocodeAddress($venue));
// Set flash message and redirect
}
}
The job itself looks like this:
class GeocodeAddress extends Job implements SelfHandling, ShouldQueue
{
use InteractsWithQueue, SerializesModels;
public $model;
public function __construct(Geocodable $model)
{
$this->model = $model;
}
public function handle()
{
$result = Geocoder::geocode($this->model->getAddressString());
$this->model->setCoordinates($result->getLatitude(), $result->getLongitude());
}
}
As you can see, the Geocodable contract makes sure the methods are available in the job class.
You also probably want to use the https://github.com/geocoder-php/GeocoderLaravel package for actually geocoding address strings.