Merge pull request #18286 from sunilpawar/ui_30
[civicrm-core.git] / CRM / Contact / Form / Task / Map.php
1 <?php
2 /*
3 +--------------------------------------------------------------------+
4 | Copyright CiviCRM LLC. All rights reserved. |
5 | |
6 | This work is published under the GNU AGPLv3 license with some |
7 | permitted exceptions and without any warranty. For full license |
8 | and copyright information, see https://civicrm.org/licensing |
9 +--------------------------------------------------------------------+
10 */
11
12 /**
13 *
14 * @package CRM
15 * @copyright CiviCRM LLC https://civicrm.org/licensing
16 */
17
18 /**
19 * This class provides the functionality to map
20 * the address for group of
21 * contacts.
22 */
23 class CRM_Contact_Form_Task_Map extends CRM_Contact_Form_Task {
24
25 /**
26 * Are we operating in "single mode", i.e. mapping address to one
27 * specific contact?
28 *
29 * @var bool
30 */
31 protected $_single = FALSE;
32
33 /**
34 * Build all the data structures needed to build the form.
35 */
36 public function preProcess() {
37 $cid = CRM_Utils_Request::retrieve('cid', 'Positive',
38 $this, FALSE
39 );
40 $lid = CRM_Utils_Request::retrieve('lid', 'Positive',
41 $this, FALSE
42 );
43 $eid = CRM_Utils_Request::retrieve('eid', 'Positive',
44 $this, FALSE
45 );
46 $profileGID = CRM_Utils_Request::retrieve('profileGID', 'Integer',
47 $this, FALSE
48 );
49 $this->assign('profileGID', $profileGID);
50 $context = CRM_Utils_Request::retrieve('context', 'Alphanumeric', $this);
51
52 $type = 'Contact';
53 if ($cid) {
54 $ids = [$cid];
55 $this->_single = TRUE;
56 if ($profileGID) {
57 // this does a check and ensures that the user has permission on this profile
58 // CRM-11766
59 $profileIDs = CRM_Profile_Page_Listings::getProfileContact($profileGID);
60 if (!in_array($cid, $profileIDs)) {
61 CRM_Core_Error::statusBounce(ts('Contact not found when building list of contacts in the profile'));
62 }
63 }
64 elseif ($context) {
65 $qfKey = CRM_Utils_Request::retrieve('key', 'String', $this);
66 $urlParams = 'force=1';
67 if (CRM_Utils_Rule::qfKey($qfKey)) {
68 $urlParams .= "&qfKey=$qfKey";
69 }
70 $session = CRM_Core_Session::singleton();
71 $urlString = "civicrm/contact/search/$context";
72 if ($context == 'search') {
73 $urlString = 'civicrm/contact/search';
74 }
75 $url = CRM_Utils_System::url($urlString, $urlParams);
76 $session->replaceUserContext($url);
77 }
78 }
79 elseif ($eid) {
80 $ids = $eid;
81 $type = 'Event';
82 }
83 else {
84 if ($profileGID) {
85 $ids = CRM_Profile_Page_Listings::getProfileContact($profileGID);
86 }
87 else {
88 parent::preProcess();
89 $ids = $this->_contactIds;
90 }
91 }
92 self::createMapXML($ids, $lid, $this, TRUE, $type);
93 $this->assign('single', $this->_single);
94 }
95
96 /**
97 * Build the form object.
98 */
99 public function buildQuickForm() {
100 $this->addButtons([
101 [
102 'type' => 'done',
103 'name' => ts('Done'),
104 'isDefault' => TRUE,
105 ],
106 ]);
107 }
108
109 /**
110 * Process the form after the input has been submitted and validated.
111 */
112 public function postProcess() {
113 }
114
115 /**
116 * Assign smarty variables to the template that will be used by google api to plot the contacts.
117 *
118 * @param array $ids
119 * @param int $locationId
120 * Location_id.
121 * @param CRM_Core_Page $page
122 * @param bool $addBreadCrumb
123 * @param string $type
124 */
125 public static function createMapXML($ids, $locationId, &$page, $addBreadCrumb, $type = 'Contact') {
126 $config = CRM_Core_Config::singleton();
127
128 CRM_Utils_System::setTitle(ts('Map Location(s)'));
129 $page->assign('query', 'CiviCRM Search Query');
130 $page->assign('mapProvider', $config->mapProvider);
131 $page->assign('mapKey', urlencode($config->mapAPIKey));
132 if ($type == 'Contact') {
133 $imageUrlOnly = FALSE;
134
135 // google needs image url, CRM-6564
136 if ($config->mapProvider == 'Google' || $config->mapProvider == 'OpenStreetMaps') {
137 $imageUrlOnly = TRUE;
138 }
139 $locations = CRM_Contact_BAO_Contact_Location::getMapInfo($ids, $locationId, $imageUrlOnly);
140 }
141 else {
142 $locations = CRM_Event_BAO_Event::getMapInfo($ids);
143 }
144
145 if (empty($locations)) {
146 CRM_Core_Error::statusBounce(ts('This address does not contain latitude/longitude information and cannot be mapped.'));
147 }
148
149 if (empty($config->mapProvider)) {
150 CRM_Core_Error::statusBounce(ts('You need to configure a Mapping Provider before using this feature (Administer > System Settings > Mapping and Geocoding).'));
151 }
152 if ($addBreadCrumb) {
153 $session = CRM_Core_Session::singleton();
154 $redirect = $session->readUserContext();
155 if ($type == 'Contact') {
156 $bcTitle = ts('Contact');
157 }
158 else {
159 $bcTitle = ts('Event Info');
160 $action = CRM_Utils_Request::retrieve('action', 'String',
161 $page, FALSE
162 );
163 if ($action) {
164 $args = 'reset=1&action=preview&id=';
165 }
166 else {
167 $args = 'reset=1&id=';
168 }
169 $session->pushUserContext(CRM_Utils_System::url('civicrm/event/info', "{$args}{$ids}"));
170 }
171 CRM_Utils_System::appendBreadCrumb($bcTitle, $redirect);
172 }
173
174 $page->assign_by_ref('locations', $locations);
175
176 // only issue a javascript warning if we know we will not
177 // mess the poor user with too many warnings
178 if (count($locations) <= 3) {
179 $page->assign('geoCodeWarn', TRUE);
180 }
181 else {
182 $page->assign('geoCodeWarn', FALSE);
183 }
184
185 $sumLat = $sumLng = 0;
186 $maxLat = $maxLng = -400;
187 $minLat = $minLng = 400;
188 foreach ($locations as $location) {
189 $sumLat += $location['lat'];
190 $sumLng += $location['lng'];
191
192 if ($location['lat'] > $maxLat) {
193 $maxLat = $location['lat'];
194 }
195 if ($location['lat'] < $minLat) {
196 $minLat = $location['lat'];
197 }
198
199 if ($location['lng'] > $maxLng) {
200 $maxLng = $location['lng'];
201 }
202 if ($location['lng'] < $minLng) {
203 $minLng = $location['lng'];
204 }
205 }
206
207 $center = [
208 'lat' => (float ) $sumLat / count($locations),
209 'lng' => (float ) $sumLng / count($locations),
210 ];
211 $span = [
212 'lat' => (float ) ($maxLat - $minLat),
213 'lng' => (float ) ($maxLng - $minLng),
214 ];
215 $page->assign_by_ref('center', $center);
216 $page->assign_by_ref('span', $span);
217 }
218
219 }