CRM-14370 - Backport container and classloader (from doctrine => master)
authorTim Otten <totten@civicrm.org>
Sun, 6 Apr 2014 04:10:55 +0000 (21:10 -0700)
committerTim Otten <totten@civicrm.org>
Sun, 6 Apr 2014 04:10:55 +0000 (21:10 -0700)
CRM/Core/ClassLoader.php
Civi/Core/Container.php [new file with mode: 0644]

index e1b03d17ff8dd5fa1c2f82e0c9890e892515f622..b2f1c0afd3ee87be70af7c0121c114df779a2f13 100644 (file)
@@ -70,6 +70,9 @@ class CRM_Core_ClassLoader {
     if ($this->_registered) {
       return;
     }
+    $civicrm_base_path = dirname(dirname(__DIR__));
+
+    require_once dirname(dirname(__DIR__)) . '/packages/vendor/autoload.php';
 
     // we do this to prevent a autoloader errors with joomla / 3rd party packages
     // use absolute path since we dont know the content of include_path as yet
@@ -81,7 +84,7 @@ class CRM_Core_ClassLoader {
     // the files might not exists, in which case we skip loading the file
     // if you change the below, please test on Joomla and also PCP pages
     $includeHTMLPurifier = TRUE;
-    $htmlPurifierPath = dirname(__FILE__) . '/../../packages/IDS/vendors/htmlpurifier/HTMLPurifier/Bootstrap.php';
+    $htmlPurifierPath = "$civicrm_base_path/packages/IDS/vendors/htmlpurifier/HTMLPurifier/Bootstrap.php";
     if (
       class_exists('HTMLPurifier_Bootstrap') ||
       !file_exists($htmlPurifierPath)
@@ -92,22 +95,23 @@ class CRM_Core_ClassLoader {
       require_once $htmlPurifierPath;
     }
 
-    if (version_compare(PHP_VERSION, '5.3.0') >= 0) {
-      spl_autoload_register(array($this, 'loadClass'), TRUE, $prepend);
-      if ($includeHTMLPurifier) {
-        spl_autoload_register(array('HTMLPurifier_Bootstrap', 'autoload'), TRUE, $prepend);
-      }
-    }
-    else {
-      // http://www.php.net/manual/de/function.spl-autoload-register.php#107362
-      // "when specifying the third parameter (prepend), the function will fail badly in PHP 5.2"
-      spl_autoload_register(array($this, 'loadClass'), TRUE);
-      if ($includeHTMLPurifier) {
-        spl_autoload_register(array('HTMLPurifier_Bootstrap', 'autoload'), TRUE);
-      }
+    // TODO Remove this autoloader. For civicrm-core and civicrm-packages, the composer autoloader works fine.
+    // Extensions rely on include_path-based autoloading
+    spl_autoload_register(array($this, 'loadClass'), TRUE, $prepend);
+    if ($includeHTMLPurifier) {
+      spl_autoload_register(array('HTMLPurifier_Bootstrap', 'autoload'), TRUE, $prepend);
     }
 
     $this->_registered = TRUE;
+    $packages_path = implode(DIRECTORY_SEPARATOR, array($civicrm_base_path, 'packages'));
+    $include_paths = array(
+      '.',
+      $civicrm_base_path,
+      $packages_path
+    );
+    $include_paths = implode(PATH_SEPARATOR, $include_paths);
+    set_include_path($include_paths . PATH_SEPARATOR . get_include_path());
+    require_once "$civicrm_base_path/packages/vendor/autoload.php";
   }
 
   function loadClass($class) {
@@ -127,4 +131,3 @@ class CRM_Core_ClassLoader {
     }
   }
 }
-
diff --git a/Civi/Core/Container.php b/Civi/Core/Container.php
new file mode 100644 (file)
index 0000000..a53af70
--- /dev/null
@@ -0,0 +1,77 @@
+<?php
+namespace Civi\Core;
+use Doctrine\Common\Annotations\AnnotationReader;
+use Doctrine\Common\Annotations\AnnotationRegistry;
+use Doctrine\Common\Annotations\FileCacheReader;
+use Doctrine\Common\Cache\FilesystemCache;
+use Doctrine\ORM\EntityManager;
+use Doctrine\ORM\Mapping\Driver\AnnotationDriver;
+use Doctrine\ORM\Tools\Setup;
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\DependencyInjection\Definition;
+use Symfony\Component\DependencyInjection\Reference;
+
+// TODO use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
+
+class Container {
+
+  const SELF = 'civi_container_factory';
+
+  /**
+   * @var ContainerBuilder
+   */
+  private static $singleton;
+
+  /**
+   * @return \Symfony\Component\DependencyInjection\TaggedContainerInterface
+   */
+  public static function singleton() {
+    if (self::$singleton === NULL) {
+      $c = new self();
+      self::$singleton = $c->createContainer();
+    }
+    return self::$singleton;
+  }
+
+  /**
+   * @var ContainerBuilder
+   */
+  public function createContainer() {
+    $civicrm_base_path = dirname(dirname(__DIR__));
+    $container = new ContainerBuilder();
+    $container->setParameter('civicrm_base_path', $civicrm_base_path);
+    $container->set(self::SELF, $this);
+
+// TODO Move configuration to an external file; define caching structure
+//    if (empty($configDirectories)) {
+//      throw new \Exception(__CLASS__ . ': Missing required properties (civicrmRoot, configDirectories)');
+//    }
+//    $locator = new FileLocator($configDirectories);
+//    $loaderResolver = new LoaderResolver(array(
+//      new YamlFileLoader($container, $locator)
+//    ));
+//    $delegatingLoader = new DelegatingLoader($loaderResolver);
+//    foreach (array('services.yml') as $file) {
+//      $yamlUserFiles = $locator->locate($file, NULL, FALSE);
+//      foreach ($yamlUserFiles as $file) {
+//        $delegatingLoader->load($file);
+//      }
+//    }
+
+    $container->setDefinition('dispatcher', new Definition(
+      '\Symfony\Component\EventDispatcher\EventDispatcher',
+      array()
+    ))
+      ->setFactoryService(self::SELF)->setFactoryMethod('createEventDispatcher');
+
+    return $container;
+  }
+
+  /**
+   * @return \Symfony\Component\EventDispatcher\EventDispatcher
+   */
+  public function createEventDispatcher() {
+    $dispatcher = new \Symfony\Component\EventDispatcher\EventDispatcher();
+    return $dispatcher;
+  }
+}