0

I'm trying to implement the GeocodableBehavior on a Symfony 1.4 (with Propel 1.6) project i'm working on, but until now it's a complete failure. I've tried to search if other people but I didn't found anything, like if I was the only one having troubles with this.

So, maybe I'm missing something very very easy, but following the instructions given on the GeocodableBehavior leads to nothing but errors, and I can't figure out where's the problem.

I followed instructions for the GeocodableBehavior (here -> http://www.propelorm.org/cookbook/geocodable-behavior.html)

This seems to work as i'm getting the latitude/longitude columns created on my model. Until then, it works fine.

Where things get a little more complicated is when trying to save an object with the GeocodableBehavior, there's problems with the Geocoder class.

(Documentation here -> https://github.com/willdurand/Geocoder)

My class is Point, referring to a geolocated point, an address. When creating a Point using sf admin generator, the behavior which is supposed to use some fields (street, postal_code, country, etc) to query the GoogleMaps api, just fails to use the Geocoder class.

Fatal error: Class 'Geocoder\Geocoder' not found in /var/www/vhosts/www._________.local/lib/model/om/BasePoint.php on line 3717

I put the Geocoder class in a lib/vendor/geocoder folder, I tried to use the autoload.yml file to load it, but nothing changes...

autoload:
  geocoder:
    name:       geocoder
    path:       %SF_LIB_DIR%/vendor/geocoder
    recursive:  on

There's something i'm missing in how to load those classes in my sf project, and i can't find what. Geocoder package has an autoload.php file but i didn't manage to "load" it successfully...

Thanks in advance.

evanesis
  • 260
  • 1
  • 9

3 Answers3

4

I know it's kinda giving up on the autoloader, but you could establish a register function in /config/ProjectConfiguration.class.php. The only downside is that you will need to add a call to the function before any block that uses Geocoder.

class ProjectConfiguration extends sfProjectConfiguration
{
    static protected $geocoderLoaded = false;

    static public function registerGeocoder()
    {
        if (self::$geocoderLoaded) {
            return;
        }

        require_once sfConfig::get('sf_lib_dir') . '/vendor/geocoder/autoload.php';

        self::$geocoderLoaded = true;
    }
    ...
}

Then just execute ProjectConfiguration::registerGeocoder(); anywhere you'd need the class. It's more annoying than getting the autoloader to work, but it's at least dependable.

  • I agree with that solution. I know it's used with symfony 1.x, without any problems btw. – William Durand Apr 06 '12 at 16:27
  • Thanks for the answer, it's weird not to use the autoloader for this, but does the job, so i'll stick with this solution (which works). – evanesis Apr 11 '12 at 07:49
1

Did you check your autoload cache to see it there is something related to Geocoder?

  • /cache/[apps_name]/dev/config/config_autoload.yml.php
  • /cache/project_autoload.cache

Maybe, manually add the autoload in the /config/ProjectConfiguration.class.php:

class ProjectConfiguration extends sfProjectConfiguration
{
  public function setup()
  {
    require_once sfConfig::get('sf_lib_dir').'/vendor/geocoder/src/autoload.php';
j0k
  • 22,600
  • 28
  • 79
  • 90
  • I didn't check the cache at first, just gave a look at it now, and there's a bunch of references for the Geocoder class (in both of them) , with correct paths... Concerning the manual adding in Configurations files I had already tried this (just forgot to mention it, sorry), and it gives me this : `Fatal error: Cannot use object of type Closure as array in /var/www/symfony/1.4/lib/autoload/sfAutoloadAgain.class.php on line 72` – evanesis Apr 04 '12 at 09:33
1

Using the built-in autoloader should be a working option, but you can also combine symfony's autoloader with a "PSR-0 enabled" one. Basically, this boils down to the following implementation:

public function setup()
{
  // plugin stuff here

  // register the new autoloader
  spl_autoload_register(array($this, 'autoloadNamespace'));
}

public function autoloadNamespace($className)
{
  $className = ltrim($className, '\\');
  $fileName = ''; 
  $namespace = ''; 
  if ($lastNsPos = strripos($className, '\\'))
  {   
    $namespace = substr($className, 0, $lastNsPos);
    $className = substr($className, $lastNsPos + 1); 
    $fileName = str_replace('\\', DIRECTORY_SEPARATOR, $namespace) . DIRECTORY_SEPARATOR;
  }   

  // make sure that the path to Geocoder is correct
  foreach(array(
    sfConfig::get('sf_lib_dir').'/vendor/Geocoder/src' . DIRECTORY_SEPARATOR . $fileName . $className . '.php', 
    ) as $fileName)
  {   
    if (file_exists($fileName))
    {   
      require $fileName;
      return true;
    }   
  }   
  return false;
}

With this additional autoloader, your application should be able to use Geocoder.

K-Phoen
  • 1,260
  • 9
  • 18