Add in unit test of getCoordinates Address action and update TestProvider to be like...
[civicrm-core.git] / CRM / Utils / GeocodeProvider.php
CommitLineData
6d04b727
FG
1<?php
2
3/*
bc77d7c0
TO
4 +--------------------------------------------------------------------+
5 | Copyright CiviCRM LLC. All rights reserved. |
6 | |
7 | This work is published under the GNU AGPLv3 license with some |
8 | permitted exceptions and without any warranty. For full license |
9 | and copyright information, see https://civicrm.org/licensing |
10 +--------------------------------------------------------------------+
6d04b727
FG
11 */
12
13/**
14 *
15 * @package CRM
ca5cec67 16 * @copyright CiviCRM LLC https://civicrm.org/licensing
6d04b727
FG
17 */
18class CRM_Utils_GeocodeProvider {
19
94d2b28e
FG
20 /**
21 * Caches the provider class name. Disables geocoding when set to FALSE.
22 *
23 * @var string|bool
24 */
25 private static $providerClassName;
26
6d04b727
FG
27 /**
28 * Instantiate a geocode object of the system-configured type.
29 *
30 * @return CRM_Utils_Geocode
31 * @throws CRM_Core_Exception
32 */
33 public static function getConfiguredProvider() {
34 $geoCodeClassName = self::getUsableClassName();
35 if ($geoCodeClassName === FALSE) {
36 throw new CRM_Core_Exception('No valid geocoding provider enabled');
37 }
38 return new $geoCodeClassName();
39 }
40
41 /**
42 * Get the name of the geocoding class if enabled.
43 *
44 * This retrieves the geocoding class, checking it can be accessed.
45 * Checks are done to mitigate the possibility it has been configured
46 * and then the file has been removed.
47 *
48 * @return string|bool
49 * Class name if usable, else false.
50 */
51 public static function getUsableClassName() {
94d2b28e
FG
52 if (self::$providerClassName === NULL) {
53 $provider = Civi::settings()->get('geoProvider');
54 if (!class_exists($provider)) {
55 if (class_exists('CRM_Utils_Geocode_' . $provider)) {
56 $provider = 'CRM_Utils_Geocode_' . $provider;
57 }
58 else {
59 if (strlen($provider)) {
60 Civi::log()
61 ->error('Configured geocoder has been removed from the system', ['geocode_class' => $provider]);
62 }
63 $provider = FALSE;
64 }
65 }
66
67 // Ideally geocoding providers would be required to implement an interface
68 // or extend a base class. While we identify and implement a geocoding
69 // abstraction library (rather than continue to roll our own), we settle for
70 // this check.
bab0b1f0 71 if ($provider !== FALSE && !method_exists($provider, 'format')) {
94d2b28e
FG
72 Civi::log()->error('Configured geocoder is invalid, must provide a format method', ['geocode_class' => $provider]);
73 $provider = FALSE;
6d04b727 74 }
6d04b727 75
94d2b28e 76 self::$providerClassName = $provider;
6d04b727
FG
77 }
78
94d2b28e
FG
79 return self::$providerClassName;
80 }
81
82 /**
83 * Disable GeoProvider within a session.
84 *
85 * This disables geocoding by causing getUsableClassName() to bail out.
86 */
87 public static function disableForSession() {
88 self::$providerClassName = FALSE;
89 }
90
91 /**
623a6eb7 92 * Reset geoprovider (after settting has been changed).
94d2b28e
FG
93 */
94 public static function reset() {
95 self::$providerClassName = NULL;
6d04b727
FG
96 }
97
98}