Trying to add a custom module to the mapping module.

I added the custom module to Admin :: Google Map Settings :: Valid Geocode Modules/Valid Geocode Tables

Once saved, the drop down option to select the modules “Address Type” appeared, “primary address” showed up and I selected that.

It doesn’t seem to geocode the addresses even though I have a primary_address_street, primary_address_city, etc in the database.

Also I would like to be able to go to the modules listing page, multi select many records and bulk action “Map” them.

Anyone know what Im doing wrong? Or if I need to add some code somewhere?

Ok, so the geocoding part first, digging through the code for jjwg_Maps module

controller.php under the action_geocode_addresses method

I added the following debug code around line 203:



$display_result = $this->bean->getGeocodeAddressesResult($this->display_object->table_name);
            var_dump($display_result);
            var_dump($this->display_object->table_name);
            echo '<br /><br />';

it produced the following output:



object(mysqli_result)#47 (5) { ["current_field"]=> int(0) ["field_count"]=> int(41) ["lengths"]=> NULL ["num_rows"]=> int(0) ["type"]=> int(0) } string(8) "accounts"

object(mysqli_result)#53 (5) { ["current_field"]=> int(0) ["field_count"]=> int(47) ["lengths"]=> NULL ["num_rows"]=> int(0) ["type"]=> int(0) } string(8) "contacts"

object(mysqli_result)#56 (5) { ["current_field"]=> int(0) ["field_count"]=> int(59) ["lengths"]=> NULL ["num_rows"]=> int(0) ["type"]=> int(0) } string(5) "leads"

object(mysqli_result)#60 (5) { ["current_field"]=> int(0) ["field_count"]=> int(25) ["lengths"]=> NULL ["num_rows"]=> int(0) ["type"]=> int(0) } string(13) "opportunities"

object(mysqli_result)#59 (5) { ["current_field"]=> int(0) ["field_count"]=> int(23) ["lengths"]=> NULL ["num_rows"]=> int(0) ["type"]=> int(0) } string(5) "cases"

object(mysqli_result)#65 (5) { ["current_field"]=> int(0) ["field_count"]=> int(19) ["lengths"]=> NULL ["num_rows"]=> int(0) ["type"]=> int(0) } string(7) "project"

object(mysqli_result)#62 (5) { ["current_field"]=> int(0) ["field_count"]=> int(41) ["lengths"]=> NULL ["num_rows"]=> int(0) ["type"]=> int(0) } string(8) "meetings"

object(mysqli_result)#66 (5) { ["current_field"]=> int(0) ["field_count"]=> int(45) ["lengths"]=> NULL ["num_rows"]=> int(0) ["type"]=> int(0) } string(9) "prospects"

bool(false) string(13) "comp_mycustommodule"

so for some reason when I am calling the getGeocodeAddressesResult method on the bean object I am returning false… looking into that now as I try and find that method in the code.

ok so in the getGeocodeAddressesResult method the $query in built like so:



$where_conds = "(" .
                "(" . $table_name . "_cstm.jjwg_maps_lat_c = 0 AND " .
                "" . $table_name . "_cstm.jjwg_maps_lng_c = 0)" .
                " OR " .
                "(" . $table_name . "_cstm.jjwg_maps_lat_c IS NULL AND " .
                "" . $table_name . "_cstm.jjwg_maps_lng_c IS NULL)" .
                ")" .
                " AND " .
                "(" . $table_name . "_cstm.jjwg_maps_geocode_status_c = '' OR " .
                "" . $table_name . "_cstm.jjwg_maps_geocode_status_c IS NULL)";

$query = "SELECT " . $table_name . ".*, " . $table_name . "_cstm.* FROM " . $table_name .
                " LEFT JOIN " . $table_name . "_cstm " .
                " ON " . $table_name . ".id = " . $table_name . "_cstm.id_c " .
                " WHERE " . $table_name . ".deleted = 0 AND " . $where_conds;

It expects my custom module to have an extra _cstm table in the database, possibly suppose to be created by the jjwg_maps module already, but I have not added additional fields to the database since deployment from the module builder. and there is no comp_mycustommodule_cstm table in the database yet with the required jjwg_maps fields.

Is there something that should be creating those for me or do I need to manually set those up?

Ok, so I made the extra fields and table comp_mycustommodule_cstm and the query is working fine…

But it seems I need to extend module/jjwg_Maps/controller.php to override the defineMapsAddressCustom method

I did so with custom/module/jjwg_Maps/controller.php with the following code:



<?php
if (!defined('sugarEntry') || !sugarEntry)
    die('Not A Valid Entry Point');

// modules/jjwg_Maps/controller.php
require_once('modules/jjwg_Maps/controller.php');

class Customjjwg_MapsController extends jjwg_MapsController {

  function Customjjwg_MapsController() {
    parent::jjwg_MapsController();
  }

  /**
   * Custom Override for Defining Maps Address
   *
   * @param $aInfo        address info array(address, status, lat, lng)
   * @param $object_name  signular object name
   * @param $display      fetched row array
   */
  function defineMapsAddressCustom($aInfo, $object_name, $display) {
die('Does my method get called?');
      if($object_name == 'comp_MyCustomModule')
      {
          $address = $this->defineMapsFormattedAddress($display, $this->settings['geocode_modules_to_address_type']['comp_MyCustomModule']);
          $aInfo = 'insert code here';
      }
      return $aInfo;
  }
}


However my method is not being called for some reason… any idea why?

Try changing this line

modules/jjwg_Maps/jjwg_Maps_Router.php:15:  require_once('modules/jjwg_Maps/controller.php');

to this

require_once(get_custom_file_if_exists('modules/jjwg_Maps/controller.php'));

If that works, we can put it in the main code. You see, not everything in SuiteCRM is using the “custom” folder mechanism. I have a bunch of PR waiting that fix things like this (for example https://github.com/salesagility/SuiteCRM/pull/3891/files )

Changed the code in jjwg_Maps_Router to the below code, still doesn’t call my custom controller action, I have the custom code in the default controller now and it works, but that makes upgrades very hard as you can imagine.


<?php
if(!defined('sugarEntry') || !sugarEntry) die('Not A Valid Entry Point');

require_once('include/utils.php');
require_once('include/export_utils.php');

/*
 * The entry point is registered by
 * custom/include/MVC/Controller/entry_point_registry.php
 */

if (!empty($_REQUEST['cron'])) {

  require_once('modules/jjwg_Maps/jjwg_Maps.php');
  require_once(get_custom_file_if_exists('modules/jjwg_Maps/controller.php'));
  /*
   * This script can be used as an entry point for a cron
   * job to run the address geocoding on a regular basis.
   * index.php?module=jjwg_Maps&entryPoint=jjwg_Maps&cron=1&limit=2500
   */
  $controller = new jjwg_MapsController();
  $controller->action_geocode_addresses();

  exit;

} else {

  /*
   * This script is also used to pass selected records from
   * a module list view to the Maps Module (jjwg_Maps).
   *
   * Multiple records are posted thru 'uid' (comma separated) or
   * 'current_post' (see export_utils.php)
   *
   * A Javascript post method is required here as the
   * parameters are sometimes too long for a get method
   *
   * Search Types
   * 1.) Default - All Records - Map
   *     Uses 'current_post' parameter to define search
   * 2.) Default - Checked Records or This Page - Map
   *     Uses 'uid'(s) parameter to define search
   * 3.) Parameter Search - Select All - Map
   *     Uses 'current_post'
   * 4.) Parameter Search - Checked Records - Map
   *     Uses 'uid'(s) parameter to define search
   */
  //echo 'Test:<pre>'."\n";
  //foreach (array_keys($_REQUEST) as $key) {
  //  echo 'Name: '.htmlspecialchars($key).'  Value: '.htmlspecialchars($_REQUEST[$key])."\n";
  //}

  // Redirect parameters to view/action using Javascript form post.
  echo '<html><head></head><body>';
  echo '<form name="redirect" action="index.php" method="POST">'."\n";
  echo '<input type="hidden" name="module" value="jjwg_Maps">'."\n";
  echo '<input type="hidden" name="action" value="map_display">'."\n";
  foreach (array_keys($_REQUEST) as $key) {
    if (!in_array($key, array('action','module','entryPoint','display_module', 'quick_address'))) {
      echo '<input type="hidden" name="'.htmlspecialchars($key).'" value="'.htmlspecialchars($_REQUEST[$key]).'">'."\n";
    }
  }
  echo '<input type="hidden" name="display_module" value="'.htmlspecialchars($_REQUEST['display_module']).'">'."\n";
  echo '</form>'."\n";
  echo '<script language="javascript" type="text/javascript">document.redirect.submit();</script>'."\n";
  echo '</body></html>';

  exit;
}

I’d like to understand why the custom controller isn’t getting called.

Maybe you could force a FATAL error inside the controller. and get PHP to give you a full call stack, so we could see where it’s being included from.

Is there any news about this ? Got exactly the same issue (a custom module cant be geocoded).

My SuiteCRM install is already customized a lot, so I dont really want to add thing to my “to-do-list-after-update” …