Exemplo n.º 1
0
 function startup(&$controller)
 {
     $this->c =& $controller;
     if (!$this->runPlugin($controller)) {
         return false;
     }
     // Initialize vars
     $center = array();
     $address = '';
     $lat = 0;
     $lon = 0;
     if (!isset($controller->Config)) {
         $controller->Config = Configure::read('JreviewsSystem.Config');
     }
     $this->jr_lat = Sanitize::getString($controller->Config, 'geomaps.latitude');
     $this->jr_lon = Sanitize::getString($controller->Config, 'geomaps.longitude');
     if ($this->jr_lat == '' || $this->jr_lon == '') {
         return false;
     }
     // Setup vars used in startup and other plugin methods
     $this->google_url = Sanitize::getString($this->c->Config, 'geomaps.google_url', 'http://maps.google.com');
     $this->google_api_key = trim(Sanitize::getString($controller->Config, 'geomaps.google_key'));
     $this->google_api_url = $this->google_url . "/maps?file=api&v=2&async=2&key={$this->google_api_key}&sensor=false";
     $search_method = Sanitize::getString($controller->Config, 'geomaps.search_method', 'address');
     // address/disabled
     $search_address_field = Sanitize::getString($controller->Config, 'geomaps.advsearch_input');
     $default_radius = Sanitize::getString($controller->Config, 'geomaps.radius');
     $this->distance_metric = array('mi' => __t("Miles", true), 'km' => __t("Km", true));
     $this->distance_in = Sanitize::getString($controller->Config, 'geomaps.radius_metric', 'mi');
     $this->jr_address1 = Sanitize::getString($controller->Config, 'geomaps.address1');
     $this->jr_address2 = Sanitize::getString($controller->Config, 'geomaps.address2');
     $this->jr_city = Sanitize::getString($controller->Config, 'geomaps.city');
     $this->jr_state = Sanitize::getString($controller->Config, 'geomaps.state');
     $this->jr_postal_code = Sanitize::getString($controller->Config, 'geomaps.postal_code');
     $this->jr_country = Sanitize::getString($controller->Config, 'geomaps.country');
     $this->country_def = Sanitize::getString($controller->Config, 'geomaps.default_country');
     $this->gid = $controller->_user->gid;
     $this->address_fields = array_filter(array('address1' => $this->jr_address1, 'address2' => $this->jr_address2, 'city' => $this->jr_city, 'state' => $this->jr_state, 'postal_code' => $this->jr_postal_code, 'country' => $this->jr_country));
     $this->geo_fields = array('lat' => $this->jr_lat, 'lon' => $this->jr_lon);
     $this->c->set(array('address_fields' => $this->address_fields, 'geo_fields' => $this->geo_fields));
     /**
      * Address search checks
      */
     if (isset($controller->data['Field']['Listing'])) {
         $address = Sanitize::getString($controller->data['Field']['Listing'], $search_address_field);
     } else {
         $address = Sanitize::getString($controller->params, $search_address_field);
         $lat = Sanitize::getFloat($controller->params, $this->jr_lat);
         $lon = Sanitize::getFloat($controller->params, $this->jr_lon);
     }
     /**
      * Plugin does different things for different controller methods
      */
     switch ($controller->name) {
         case 'com_content':
             $this->published = true;
             $controller->Listing->cacheCallbacks[] = 'plgAfterAfterFind';
             $controller->Listing->fields[] = "`Field`.{$this->jr_lat} AS `Geomaps.lat`";
             $controller->Listing->fields[] = "`Field`.{$this->jr_lon} AS `Geomaps.lon`";
             $controller->Listing->fields[] = "JreviewsCategory.marker_icon AS `Geomaps.icon`";
             break;
         case 'listings':
             switch ($controller->action) {
                 // Load the geomaps js library
                 case 'create':
                     // Submit a new listing
                 // Submit a new listing
                 case 'edit':
                     // Edit a listing
                     $this->published = true;
                     $Html = new HtmlHelper();
                     $Html->app = 'jreviews';
                     $Html->startup();
                     $jsGlobals = 'var GeomapsGoogleApi = "' . $this->google_api_url . '";';
                     $jsGlobals .= 'var jr_lat = "' . $this->jr_lat . '";';
                     $jsGlobals .= 'var jr_lon = "' . $this->jr_lon . '";';
                     $jsGlobals .= 'var jr_country_def = "' . $this->country_def . '";';
                     $jsGlobals .= 'var geoAddressObj = {};';
                     foreach ($this->address_fields as $key => $field) {
                         $jsGlobals .= "geoAddressObj.{$key} = '{$field}';";
                     }
                     cmsFramework::addScript($controller->makeJS($jsGlobals), true);
                     $Html->js('geomaps', true);
                     if ($controller->action == 'edit') {
                         $mapit_field = Sanitize::getString($controller->Config, 'geomaps.mapit_field');
                         if ($mapit_field) {
                             $response = "jQuery(document).ready(function() { \n                                \tvar polylines = false;\n                                \tif (jQuery('#cat_id').val() == 2) {\n                                \t\tpolylines = true;\n                                \t}\n                                    jQuery('#{$mapit_field}').after('<span id=\"gm_geocode\">\n                                        <button type=\"button\" onclick=\"geomaps.mapPopupSimple('+polylines+');\">" . __t("Map it", true) . "</button>&nbsp;\n                                        <button type=\"button\" onclick=\"geomaps.clearLatLng();\">" . __t("Clear LatLng", true) . "</button>\n                                    </span>');\n                                });";
                             cmsFramework::addScript($controller->makeJS($response), true);
                         }
                     }
                     break;
                     // Add geomaps buttons after form is loaded
                 // Add geomaps buttons after form is loaded
                 case '_loadForm':
                     // New listing - Loads submit listing form after category selection
                     $this->published = true;
                     $mapit_field = Sanitize::getString($controller->Config, 'geomaps.mapit_field');
                     if ($mapit_field) {
                         $response = array();
                         // Overrode mapPopupSimple() with mapPopupLines()
                         $response[] = "\n                                \tvar polylines = false;\n                                \tif (jQuery('#cat_id').val() == 2) {\n                                \t\tpolylines = true;\n                                \t}\n                                \tjQuery('#{$mapit_field}').after('<span id=\"gm_geocode\"><button type=\"button\" onclick=\"geomaps.mapPopupSimple('+polylines+');\">" . __t("Map it", true) . "</button>&nbsp;<button type=\"button\" onclick=\"geomaps.clearLatLng();\">" . __t("Clear LatLng", true) . "</button></span>');";
                         $controller->afterAjaxResponse = $response;
                     }
                     break;
                 case '_save':
                     // Checks if
                     $isNew = Sanitize::getInt($controller->data['Listing'], 'id', 0) == 0 ? true : false;
                     if (Sanitize::getInt($controller->Config, 'geomaps.autogeocode_new') && $isNew && isset($controller->data['Field']) && (Sanitize::getFloat($controller->data['Field']['Listing'], $this->jr_lat, null) == null || Sanitize::getFloat($controller->data['Field']['Listing'], $this->jr_lon, null) == null)) {
                         // Build whole address from fields
                         $address = '';
                         foreach ($this->address_fields as $key => $field) {
                             ${$field} = Sanitize::getVar($controller->data['Field']['Listing'], $field, '');
                             if (${$field} != '') {
                                 $address .= ' ' . ${$field};
                             } elseif ($field == 'section') {
                                 $address .= " " . Sanitize::getString($controller->data, 'section');
                             } elseif ($field == 'category') {
                                 $address .= " " . Sanitize::getString($controller->data, 'category');
                             }
                         }
                         if (!Sanitize::getVar($controller->data['Field']['Listing'], $this->jr_country, false) && $this->country_def != '') {
                             $address .= ' ' . $this->country_def;
                         }
                         // Geocode address
                         App::import('Component', 'geocoding');
                         $Geocoding = RegisterClass::getInstance('GeocodingComponent');
                         $Geocoding->Config =& $controller->Config;
                         $response = $Geocoding->geocode($address);
                         if ($response['status'] == 200) {
                             $controller->data['Field']['Listing'][$this->jr_lat] = $response['lat'];
                             $controller->data['__raw']['Field']['Listing'][$this->jr_lat] = $response['lat'];
                             $controller->data['Field']['Listing'][$this->jr_lon] = $response['lon'];
                             $controller->data['__raw']['Field']['Listing'][$this->jr_lon] = $response['lon'];
                         }
                     }
                     break;
             }
             break;
         case 'admin_listings':
             switch ($controller->action) {
                 case 'index':
                 case 'browse':
                     App::import('Helper', 'html');
                     $Html = new HtmlHelper();
                     $Html->app = 'jreviews';
                     $Html->startup();
                     $jsGlobals = 'var GeomapsGoogleApi = "' . $this->google_api_url . '";';
                     $jsGlobals .= 'var jr_lat = "' . $this->jr_lat . '";';
                     $jsGlobals .= 'var jr_lon = "' . $this->jr_lon . '";';
                     $jsGlobals .= 'var jr_country_def = "' . $this->country_def . '";';
                     $jsGlobals .= 'var geoAddressObj = {};';
                     foreach ($this->address_fields as $key => $field) {
                         $jsGlobals .= "geoAddressObj.{$key} = '{$field}';";
                     }
                     cmsFramework::addScript($controller->makeJS($jsGlobals), true);
                     $Html->js('geomaps', true);
                     break;
                 case 'edit':
                     $mapit_field = Sanitize::getString($controller->Config, 'geomaps.mapit_field');
                     if ($mapit_field) {
                         $response = "jQuery('#{$mapit_field}').after('<span id=\"gm_geocode\"><button type=\"button\" onclick=\"geomaps.mapPopupSimple();\">" . __t("Map it", true) . "</button>&nbsp;<button type=\"button\" onclick=\"geomaps.clearLatLng();\">" . __t("Clear LatLng", true) . "</button></span>');";
                         $controller->pluginResponse = $response;
                     }
                     break;
             }
             break;
             // A search was performed, make distance the default ordering and copy the entered address to the search address field
         // A search was performed, make distance the default ordering and copy the entered address to the search address field
         case 'search':
             if ($search_method == 'disabled' || $address == '') {
                 return;
             }
             if ($controller->action == '_process') {
                 $this->published = true;
                 // Enable the callbacks for this controller/method
                 // Make distance the default ordering
                 $controller->Config->list_order_default = 'distance';
                 if ($address != '' && in_array($search_method, array('address'))) {
                     $controller->data['Field']['Listing'][$search_address_field] = $address;
                     // Append default country
                     if ($this->country_def != '') {
                         $address .= ' ' . $this->country_def;
                     }
                     // Geocode address
                     App::import('Component', 'geocoding');
                     $Geocoding = RegisterClass::getInstance('GeocodingComponent');
                     $Geocoding->Config =& $controller->Config;
                     $response = $Geocoding->geocode($address);
                     if ($response['status'] == 200) {
                         $center = $response;
                     }
                     if ($center && !empty($center)) {
                         $controller->data['Field']['Listing'][$this->jr_lat] = $center['lat'];
                         $controller->data['Field']['Listing'][$this->jr_lon] = $center['lon'];
                     }
                 }
             }
             break;
             // Display search results
         // Display search results
         case 'categories':
             $controller->Listing->fields[] = "`Field`.{$this->jr_lat} AS `Geomaps.lat`";
             $controller->Listing->fields[] = "`Field`.{$this->jr_lon} AS `Geomaps.lon`";
             $controller->Listing->fields[] = "JreviewsCategory.marker_icon AS `Geomaps.icon`";
             $this->published = true;
             // Enable the callbacks for this controller/method
             if ($search_method == 'disabled' || $lat == 0 || $lon == 0) {
                 return;
             }
             if ($controller->action == 'search') {
                 $radius = min(Sanitize::getFloat($controller->params, $this->radius_field, $default_radius), $this->max_radius);
                 if ($search_method == 'disabled') {
                     $this->published = false;
                     return;
                 }
                 if ($lat != 0 && $lon != 0) {
                     Configure::write('geomaps.enabled', true);
                     // Used to show the Distance ordering in the jreviews.php helper in JReviews.
                     $center = array('lat' => $lat, 'lon' => $lon);
                     // Send center coordinates to theme
                     $controller->set('GeomapsCenter', $center);
                     $sort = $controller->params['order'] = Sanitize::getString($controller->params, 'order', 'distance');
                     // Clear address and coordinate field from parameters because it shouldn't be used on distance searches. Instead we use lat/lon via custom condition below
                     unset($controller->params[$search_address_field], $controller->params['url'][$search_address_field], $controller->params[$this->jr_lat], $controller->params['url'][$this->jr_lat], $controller->params[$this->jr_lon], $controller->params['url'][$this->jr_lon]);
                     $controller->passedArgs['url'] = preg_replace('/\\/' . $search_address_field . _PARAM_CHAR . '[\\p{L}\\s0-9]+/i', '', $controller->passedArgs['url']);
                     $controller->passedArgs['url'] = preg_replace('/\\/' . $search_address_field . _PARAM_CHAR . '[a-z0-9\\s]+/i', '', $controller->passedArgs['url']);
                     // One above doesn't work well in all cases, but required for non-latin characters in address
                     $controller->passedArgs['url'] = preg_replace('/\\/' . $this->jr_lat . _PARAM_CHAR . '[\\-a-z0-9\\.\\s]+/i', '', $controller->passedArgs['url']);
                     $controller->passedArgs['url'] = preg_replace('/\\/' . $this->jr_lon . _PARAM_CHAR . '[\\-a-z0-9\\.\\s]+/i', '', $controller->passedArgs['url']);
                     // Create a square around the center to limite the number of rows processed in the zip code table
                     // http://www.free-zipcodes.com/
                     // http://www.mysqlconf.com/mysql2008/public/schedule/detail/347
                     $degreeDistance = $this->distance_in == 'mi' ? 69.172 : 40076 / 360;
                     $lat_range = $radius / $degreeDistance;
                     $lon_range = $radius / abs(cos($center['lat'] * pi() / 180) * $degreeDistance);
                     $min_lat = $center['lat'] - $lat_range;
                     $max_lat = $center['lat'] + $lat_range;
                     $min_lon = $center['lon'] - $lon_range;
                     $max_lon = $center['lon'] + $lon_range;
                     $squareArea = "`Field`.{$this->jr_lat} BETWEEN {$min_lat} AND {$max_lat} AND `Field`.{$this->jr_lon} BETWEEN {$min_lon} AND {$max_lon}";
                     // calculate the distance between two sets of longitude/latitude coordinates
                     // From http://www.mysqlconf.com/mysql2008/public/schedule/detail/347
                     if ($this->distance_in == 'km') {
                         $controller->Listing->fields['distance'] = "6371 * 2 * ASIN(SQRT(  POWER(SIN(({$center['lat']} - {$this->jr_lat}) * pi()/180 / 2), 2) +  \n                                    COS({$center['lat']} * pi()/180) *  COS({$this->jr_lat} * pi()/180) *  POWER(SIN(({$center['lon']} -{$this->jr_lon}) * pi()/180 / 2), 2)  )) AS `Geomaps.distance`";
                     }
                     if ($this->distance_in == 'mi') {
                         $controller->Listing->fields['distance'] = "3956 * 2 * ASIN(SQRT(  POWER(SIN(({$center['lat']} - {$this->jr_lat}) * pi()/180 / 2), 2) +  \n                                    COS({$center['lat']} * pi()/180) *  COS({$this->jr_lat} * pi()/180) *  POWER(SIN(({$center['lon']} -{$this->jr_lon}) * pi()/180 / 2), 2)  )) AS `Geomaps.distance`";
                     }
                     $controller->Listing->conditions[] = $squareArea;
                     if ($sort == 'distance') {
                         $controller->Listing->order[] = '`Geomaps.distance` ASC';
                     }
                     // Makes sure that only listings within given radius are shown because square limit might include further points
                     //                        $controller->Listing->having[] = '`Geomaps.distance` <= ' . (int) $radius;
                     // Override search theme suffix
                     $theme_suffix = Sanitize::getString($controller->Config, 'geomaps.search_suffix');
                     if ($theme_suffix != '') {
                         $controller->viewSuffix = $theme_suffix;
                     }
                 }
             }
             break;
     }
 }