Exemplo n.º 1
0
 /**
  * Loads add/update location form
  *
  * @return	void
  */
 protected function add()
 {
     if (!\IPS\Member::loggedIn()->member_id) {
         \IPS\Output::i()->error('no_permission', '2MM3/1', 403, '');
     }
     /* Get the members location, if it exists */
     $existing = \IPS\membermap\Map::i()->getMarkerByMember(\IPS\Member::loggedIn()->member_id, FALSE);
     $groupId = \IPS\membermap\Map::i()->getMemberGroupId();
     /* Check permissions */
     if ($existing) {
         if (!$existing->canEdit()) {
             \IPS\Output::i()->error('membermap_error_cantEdit', '2MM3/2', 403, '');
         }
     } else {
         if (!\IPS\membermap\Markers\Groups::load($groupId)->can('add')) {
             \IPS\Output::i()->error('membermap_error_cantAdd', '2MM3/3', 403, '');
         }
     }
     /* HTML5 GeoLocation form */
     $geoLocForm = new \IPS\Helpers\Form('membermap_form_geoLocation', NULL, NULL, array('id' => 'membermap_form_geoLocation'));
     $geoLocForm->class = 'ipsForm_vertical ipsType_center';
     $geoLocForm->addHeader('membermap_current_location');
     $geoLocForm->addHtml('<li class="ipsType_center"><i class="fa fa-fw fa-4x fa-location-arrow"></i></li>');
     $geoLocForm->addHtml('<li class="ipsType_center">' . \IPS\Member::loggedIn()->language()->addToStack('membermap_geolocation_desc') . '</li>');
     $geoLocForm->addButton('membermap_current_location', 'button', NULL, 'ipsButton ipsButton_primary', array('id' => 'membermap_currentLocation'));
     $form = new \IPS\Helpers\Form('membermap_form_location', NULL, NULL, array('id' => 'membermap_form_location'));
     $form->class = 'ipsForm_vertical ipsType_center';
     $form->addHeader('membermap_form_location');
     $form->add(new \IPS\Helpers\Form\Text('membermap_location', '', FALSE, array('placeholder' => \IPS\Member::loggedIn()->language()->addToStack('membermap_form_placeholder')), NULL, NULL, NULL, 'membermap_location'));
     $form->addButton('save', 'submit', NULL, 'ipsPos_center ipsButton ipsButton_primary', array('id' => 'membermap_locationSubmit'));
     $form->hiddenValues['lat'] = \IPS\Request::i()->lat;
     $form->hiddenValues['lng'] = \IPS\Request::i()->lng;
     if ($values = $form->values()) {
         try {
             /* Create marker */
             if ($existing instanceof \IPS\membermap\Markers\Markers) {
                 $marker = $existing;
                 $marker->updated = time();
             } else {
                 $marker = \IPS\membermap\Markers\Markers::createItem(\IPS\Member::loggedIn(), \IPS\Request::i()->ipAddress(), new \IPS\DateTime(), \IPS\membermap\Markers\Groups::load($groupId));
                 $marker->member_id = \IPS\Member::loggedIn()->member_id;
             }
             if (isset($values['membermap_location']) and !empty($values['membermap_location'])) {
                 $marker->location = $values['membermap_location'];
             }
             $marker->name = \IPS\Member::loggedIn()->name;
             $marker->lat = $values['lat'];
             $marker->lon = $values['lng'];
             $marker->save();
             /* Add to search index */
             \IPS\Content\Search\Index::i()->index($marker);
             /* Content approval is requred, redirect the member to the marker page, where this is made clear */
             if ($marker->hidden()) {
                 \IPS\Output::i()->redirect($marker->url());
             } else {
                 \IPS\Output::i()->redirect(\IPS\Http\Url::internal('app=membermap&module=membermap&controller=showmap&dropBrowserCache=1&goHome=1', 'front', 'membermap'));
             }
             return;
         } catch (\Exception $e) {
             $form->error = \IPS\Member::loggedIn()->language()->addToStack('membermap_' . $e->getMessage());
             \IPS\Output::i()->output = \IPS\Theme::i()->getTemplate('map')->addLocation($geoLocForm, $form);
             return;
         }
     }
     \IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack(!$existing ? 'membermap_button_addLocation' : 'membermap_button_editLocation');
     \IPS\Output::i()->output = \IPS\Theme::i()->getTemplate('map')->addLocation($geoLocForm, $form);
 }
Exemplo n.º 2
0
 /**
  * Member account has been updated
  *
  * @param	$member		\IPS\Member	Member updating profile
  * @param	$changes	array		The changes
  * @return	void
  */
 public function onProfileUpdate($member, $changes)
 {
     /* An endless loop is formed when \Item::createItem() is saving \Member, which then fire this membersync, which then calls \Item::createItem, and so on, and so on */
     static $wereDoneHere = false;
     if ($wereDoneHere) {
         return;
     }
     $wereDoneHere = true;
     if (isset($changes['name'])) {
         $existingMarker = \IPS\membermap\Map::i()->getMarkerByMember($member->member_id, FALSE, FALSE);
         if ($existingMarker instanceof \IPS\membermap\Markers\Markers) {
             $existingMarker->name = $member->name;
             $existingMarker->updated = time();
             $existingMarker->save();
         }
     }
     if (count($changes) and \IPS\Settings::i()->membermap_monitorLocationField and !$member->members_bitoptions['bw_is_spammer']) {
         if (\IPS\Settings::i()->membermap_monitorLocationField_groupPerm === '*' or \IPS\Member::loggedIn()->inGroup(explode(',', \IPS\Settings::i()->membermap_monitorLocationField_groupPerm))) {
             if (isset($changes['field_' . \IPS\Settings::i()->membermap_profileLocationField]) and !empty($changes['field_' . \IPS\Settings::i()->membermap_profileLocationField])) {
                 try {
                     $lat = $lng = $location = NULL;
                     $fieldValue = $changes['field_' . \IPS\Settings::i()->membermap_profileLocationField];
                     /* If it's an array, it might be from an address field, which already have the lat/lng data */
                     if (is_array(json_decode($fieldValue, TRUE))) {
                         $addressData = json_decode($fieldValue, TRUE);
                         if (is_float($addressData['lat']) and is_float($addressData['long'])) {
                             $lat = floatval($addressData['lat']);
                             $lng = floatval($addressData['long']);
                         }
                         $addressData['addressLines'][] = $addressData['city'];
                         if (count($addressData['addressLines'])) {
                             $location = implode(', ', $addressData['addressLines']);
                         }
                     } else {
                         /* Remove HTML, newlines, tab, etc, etc */
                         $fieldValue = preg_replace("/[\\x00-\\x20]|\\xc2|\\xa0+/", ' ', strip_tags($fieldValue));
                         $fieldValue = trim(preg_replace("/\\s\\s+/", ' ', $fieldValue));
                         /* To my understanding we're not allowed to use \IPS\Geolocation, as that uses Google API, and we're not showing the info on a Google Map. */
                         $nominatim = \IPS\membermap\Map::i()->getLatLng($fieldValue);
                         if (is_array($nominatim) and count($nominatim)) {
                             $lat = $nominatim['lat'];
                             $lng = $nominatim['lng'];
                             $location = $nominatim['location'];
                         }
                     }
                     if ($lat and $lng) {
                         $existingMarker = \IPS\membermap\Map::i()->getMarkerByMember($member->member_id, FALSE);
                         if ($existingMarker instanceof \IPS\membermap\Markers\Markers) {
                             $marker = $existingMarker;
                             $marker->updated = time();
                         } else {
                             $groupId = \IPS\membermap\Map::i()->getMemberGroupId();
                             $marker = \IPS\membermap\Markers\Markers::createItem($member, \IPS\Request::i()->ipAddress(), new \IPS\DateTime(), \IPS\membermap\Markers\Groups::load($groupId));
                         }
                         $marker->name = $member->name;
                         $marker->lat = $lat;
                         $marker->lon = $lng;
                         $marker->location = $location ?: $fieldValue;
                         /* Save and add to search index */
                         $marker->save();
                         \IPS\Content\Search\Index::i()->index($marker);
                     }
                 } catch (\Exception $e) {
                     /* Something went wrong. Such as the input field being an editor */
                     \IPS\Log::log($e, 'membermap');
                     return false;
                 }
             }
         }
     }
 }
Exemplo n.º 3
0
 /**
  * Execute
  *
  * If ran successfully, should return anything worth logging. Only log something
  * worth mentioning (don't log "task ran successfully"). Return NULL (actual NULL, not '' or 0) to not log (which will be most cases).
  * If an error occurs which means the task could not finish running, throw an \IPS\Task\Exception - do not log an error as a normal log.
  * Tasks should execute within the time of a normal HTTP request.
  *
  * @return	mixed	Message to log or NULL
  * @throws	\IPS\Task\Exception
  */
 public function execute()
 {
     if (!\IPS\Settings::i()->membermap_syncLocationField or !\IPS\Settings::i()->membermap_monitorLocationField or !\IPS\Settings::i()->membermap_profileLocationField) {
         $this->enabled = FALSE;
         $this->save();
         return;
     }
     $fieldKey = \IPS\Settings::i()->membermap_profileLocationField;
     $limit = 100;
     $counter = 0;
     $memberMarkerGroupId = \IPS\membermap\Map::i()->getMemberGroupId();
     try {
         $where = array();
         $where[] = array("( pf.field_{$fieldKey} IS NOT NULL OR pf.field_{$fieldKey} != '' )");
         $where[] = array("mm.marker_id IS NULL");
         $where[] = array("m.membermap_location_synced = 0");
         $where[] = array('( ! ' . \IPS\Db::i()->bitwiseWhere(\IPS\Member::$bitOptions['members_bitoptions'], 'bw_is_spammer') . ' )');
         if (\IPS\Settings::i()->membermap_monitorLocationField_groupPerm !== '*') {
             $where[] = \IPS\Db::i()->in('m.member_group_id', explode(',', \IPS\Settings::i()->membermap_monitorLocationField_groupPerm));
         }
         $members = \IPS\Db::i()->select('*', array('core_members', 'm'), $where, 'm.last_activity DESC', array(0, $limit))->join(array('core_pfields_content', 'pf'), 'pf.member_id=m.member_id')->join(array('membermap_markers', 'mm'), 'mm.marker_member_id=m.member_id AND mm.marker_parent_id=' . $memberMarkerGroupId);
         foreach ($members as $member) {
             $lat = $lng = $location = NULL;
             $_member = \IPS\Member::constructFromData($member);
             /* Need to set this to prevent us from looping over the same members with invalid locations over and over again */
             $_member->membermap_location_synced = 1;
             $_member->save();
             $_location = trim($member['field_' . $fieldKey]);
             if (empty($_location)) {
                 continue;
             }
             /* If it's an array, it might be from an address field, which already have the lat/lng data */
             if (is_array(json_decode($_location, TRUE))) {
                 $addressData = json_decode($_location, TRUE);
                 if (is_float($addressData['lat']) and is_float($addressData['long'])) {
                     $lat = floatval($addressData['lat']);
                     $lng = floatval($addressData['long']);
                 }
                 $addressData['addressLines'][] = $addressData['city'];
                 if (count($addressData['addressLines'])) {
                     $location = implode(', ', $addressData['addressLines']);
                 }
             } else {
                 /* Remove HTML, newlines, tab, etc, etc */
                 $_location = preg_replace("/[\\x00-\\x20]|\\xc2|\\xa0+/", ' ', strip_tags($_location));
                 $_location = trim(preg_replace("/\\s\\s+/", ' ', $_location));
                 /* To my understanding we're not allowed to use \IPS\Geolocation, as that uses Google API, and we're not showing the info on a Google Map. */
                 $nominatim = \IPS\membermap\Map::i()->getLatLng($_location);
                 if (is_array($nominatim) and count($nominatim)) {
                     $lat = $nominatim['lat'];
                     $lng = $nominatim['lng'];
                     $location = $nominatim['location'];
                 }
             }
             if ($lat and $lng) {
                 $marker = \IPS\membermap\Markers\Markers::createItem($_member, NULL, new \IPS\DateTime(), \IPS\membermap\Markers\Groups::load($memberMarkerGroupId), FALSE);
                 $marker->name = $_member->name;
                 $marker->lat = $lat;
                 $marker->lon = $lng;
                 $marker->location = $location ?: $_location;
                 $marker->save();
                 /* Add to index */
                 \IPS\Content\Search\Index::i()->index($marker);
                 $counter++;
             }
         }
     } catch (\UnderflowException $e) {
     } catch (\RuntimeException $e) {
         \IPS\Log::log(array($e->getMessage(), $nominatim), 'membermap');
     } catch (\Exception $e) {
         \IPS\Log::log(array($e->getMessage(), $nominatim), 'membermap');
         throw new \IPS\Task\Exception($this, $e->getMessage());
     }
     if ($counter > 0) {
         $foundRows = $members->count();
         return "Synchronised {$counter} out of {$foundRows} member locations";
     } else {
         $this->enabled = FALSE;
         $this->save();
         /* Turn the setting off as well */
         \IPS\Db::i()->update('core_sys_conf_settings', array('conf_value' => 0), array('conf_key=?', 'membermap_syncLocationField'));
         unset(\IPS\Data\Store::i()->settings);
         return;
     }
     return NULL;
 }