Better encapsulation of plugins config + method to list implementations (needed for...
authorYves Chedemois
Mon, 5 Dec 2011 21:04:01 +0000 (13:04 -0800)
committerYves Chedemois
Mon, 5 Dec 2011 21:57:54 +0000 (13:57 -0800)
core/includes/Drupal/Configuration/Configuration.php
core/includes/Drupal/Configuration/ConfigurationService.php [new file with mode: 0644]
core/includes/Drupal/Plugin/FactoryInterface.php
core/includes/Drupal/Plugin/Mapper.php
core/includes/Drupal/Plugin/MapperInterface.php
core/includes/Drupal/Plugin/Multiconfig.php
core/includes/bootstrap.inc
test.php

index e14a1c3..ed147c7 100755 (executable)
@@ -5,39 +5,11 @@ namespace Drupal\Configuration;
 class Configuration {
   protected $id;
 
-  public function __construct($id) {
+  public function __construct($id, $data) {
     $this->id = $id;
 
-    $data = array();
-    if ($id == 'plugin.core.cache') {
-      $data = array(
-                'factory' => '\Drupal\Plugin\Core\Cache',
-                'title' => 'Cache',
-                'description' => 'A core cache plugin utility mechanism.',
-              );
-    }
-    if ($id == 'plugin.core.block') {
-      $data = array(
-                'factory' => '\Drupal\Plugin\Multiconfig',
-                'title' => 'Block',
-                'description' => 'Block plugin mechanism.',
-                'class_param' => 'block_class',
-                'children' => TRUE,
-              );
-    }
-    if ($id == 'plugin.core.block.test') {
-      $data = array(
-                'title' => 'Test Block PLugin',
-                'description' => 'A test block plugins.',
-                'block_class' => '\Drupal\Plugin\Core\Testblock',
-              );
-    }
     foreach ($data as $key => $value) {
       $this->$key = $value;
     }
   }
-
-  public function save() {
-    // TODO: Implement
-  }
 }
diff --git a/core/includes/Drupal/Configuration/ConfigurationService.php b/core/includes/Drupal/Configuration/ConfigurationService.php
new file mode 100644 (file)
index 0000000..3702866
--- /dev/null
@@ -0,0 +1,82 @@
+<?php
+
+/**
+ * @file
+ * Stub placeholder for the Configuration system.
+ */
+
+namespace Drupal\Configuration;
+
+class ConfigurationService {
+
+  static protected function stubConfigData() {
+    $data = array(
+      'plugin.core.cache' => array(
+        'factory' => '\Drupal\Plugin\Core\Cache',
+         'title' => 'Cache',
+         'description' => 'A core cache plugin utility mechanism.',
+      ),
+      'plugin.core.block' => array(
+        'factory' => '\Drupal\Plugin\Multiconfig',
+        'title' => 'Block',
+        'description' => 'Block plugin mechanism.',
+        'class_param' => 'block_class',
+        'children' => TRUE,
+      ),
+      'plugin.core.block.test' => array(
+        'title' => 'Test Block PLugin',
+        'description' => 'A test block plugin.',
+        'block_class' => '\Drupal\Plugin\Core\Testblock',
+      ),
+      'plugin.core.block.test2' => array(
+        'title' => 'Test Block PLugin 2',
+        'description' => 'Another test block plugin.',
+        'block_class' => '\Drupal\Plugin\Core\Testblock',
+      ),
+    );
+
+    return $data;
+  }
+
+  public function getConfiguration($key) {
+    $data = self::stubConfigData();
+
+    if (isset($data[$key])) {
+      return new Configuration($key, $data[$key]);
+    }
+  }
+
+  public function getConfigurationsNamesByPrefix($prefix) {
+    $data = self::stubConfigData();
+
+    $prefix = preg_quote($prefix);
+    $names = array();
+    foreach ($data as $key => $value) {
+      $matches = array();
+      if (preg_match("/^$prefix\.([^\.]*)$/", $key, $matches)) {
+        $names[] = $matches[1];
+      }
+    }
+
+    return $names;
+  }
+
+  /**
+   * @todo Probably not the right class for those Plugin-specific helpers.
+   */
+  public function getPluginTypeConfiguration($scope, $type) {
+    return $this->getConfiguration("plugin.$scope.$type");
+  }
+
+  public function getPluginImplementations($scope, $type) {
+    return $this->getConfigurationsNamesByPrefix("plugin.$scope.$type");
+  }
+
+  public function getPluginImplementationConfiguration($scope, $type, $implementation) {
+    return $this->getConfiguration("plugin.$scope.$type.$implementation");
+  }
+
+  public function save() {
+    // TODO: Implement
+  }
+}
index 56e6563..ff37f65 100644 (file)
@@ -7,6 +7,7 @@
 namespace Drupal\Plugin;
 use Drupal\Context\Context;
 use Drupal\Configuration\Configuration;
+use Drupal\Configuration\ConfigurationService;
 
 /**
  * Plugin factory interface.
@@ -26,8 +27,10 @@ interface FactoryInterface {
    *   The requested plugin type.
    * @param Configuration $type_configuration
    *   A configuration object containing information about the plugin type.
+   * @param ConfigurationService $config
+   *   The configuration service.
    */
-  public function __construct($scope, $type, Configuration $type_configuration);
+  public function __construct($scope, $type, Configuration $type_configuration, ConfigurationService $config);
 
   /**
    * Responsible for returning a preconfigured instance of a plugin.
index 6579426..27d38d7 100644 (file)
@@ -7,6 +7,7 @@
 namespace Drupal\Plugin;
 use Drupal\Context\Context;
 use Drupal\Configuration\Configuration;
+use Drupal\Configuration\ConfigurationService;
 use Closure;
 
 /**
@@ -16,14 +17,12 @@ use Closure;
  * instances.
  */
 class Mapper implements MapperInterface {
-
+  
+  protected $config;
   protected $factories = array();
 
-  /**
-   * Implements MapperInterface::getConfiguration().
-   */
-  public function getConfiguration($scope, $type) {
-    return config('plugin.' . $scope . '.' . $type);
+  function __construct(ConfigurationService $config) {
+    $this->config = $config;
   }
 
   /**
@@ -31,7 +30,7 @@ class Mapper implements MapperInterface {
    */
   public function getFactoryClass($scope, $type, Configuration $configuration = NULL) {
     if (empty($configuration)) {
-      $configuration = $this->getConfiguration($scope, $type);
+      $configuration = $this->config->getPluginTypeConfiguration($scope, $type);
     }
     if (!isset($configuration->factory)) {
       throw new MapperException("Factory class not found in configuration.");
@@ -45,13 +44,13 @@ class Mapper implements MapperInterface {
    */
   public function getFactory($scope, $type) {
     if (!isset($this->factories[$scope][$type])) {
-      $configuration = $this->getConfiguration($scope, $type);
+      $configuration = $this->config->getPluginTypeConfiguration($scope, $type);
       $factory_class = $this->getFactoryClass($scope, $type, $configuration);
       if (!class_exists($factory_class)) {
         throw new MapperException("New factory class was not successfully created.");
       }
 
-      $this->factories[$scope][$type] = new $factory_class($scope, $type, $configuration);
+      $this->factories[$scope][$type] = new $factory_class($scope, $type, $configuration, $this->config);
       if (!in_array('Drupal\\Plugin\\FactoryInterface', class_implements($this->factories[$scope][$type]))) {
         throw new MapperException("Unable to load a valid factory.");
       }
index 68e6f53..267dc03 100644 (file)
@@ -18,21 +18,14 @@ use Closure;
 interface MapperInterface {
 
   /**
-   * Gets a configuration object for the requested plugin type.
-   *
-   * @param string $scope
-   *   Provides a scoped namespace for the plugin type being requested. This
-   *   allows for providers to create identically named plugin types without
-   *   needing to worry about panels and views caching plugins being delivered
-   *   for core cache plugin requests.
-   *
-   * @param string $type
-   *   The plugin type for the requested scope.
-   *
-   * @return string
-   *   The factory class name.
+   * Constructs a Plugin mapper.
+   * 
+   * @param $config
+   *   The configuration service.
    */
-  public function getConfiguration($scope, $type);
+  function __construct(ConfigurationService $config) {
+    $this->config = $config;
+  }
 
   /**
    * Gets a string representation of the factory class for use in the requested
index c179600..228ded6 100644 (file)
@@ -7,6 +7,7 @@
 namespace Drupal\Plugin;
 use Drupal\Context\Context;
 use Drupal\Configuration\Configuration;
+use Drupal\Configuration\ConfigurationService;
 use Drupal\Plugin\PluginException;
 
 /**
@@ -20,14 +21,16 @@ class Multiconfig implements FactoryInterface {
   protected $scope;
   protected $type;
   protected $type_configuration;
+  protected $config;
 
   /**
    * Implements FactoryInterface::__construct().
    */
-  public function __construct($scope, $type, Configuration $type_configuration) {
+  public function __construct($scope, $type, Configuration $type_configuration, ConfigurationService $config) {
     $this->scope = $scope;
     $this->type = $type;
     $this->type_configuration = $type_configuration;
+    $this->config = $config;
   }
 
   /**
@@ -44,7 +47,7 @@ class Multiconfig implements FactoryInterface {
    *    configuration object.
    */
   public function getConfiguration($options) {
-    $config = config('plugin.' . $this->scope . '.' . $this->type . '.' . $options['config']);
+    $config = $this->config->getPluginImplementationConfiguration($this->scope, $this->type, $options['config']);
 
     if (!isset($this->type_configuration->class_param)) {
       throw new PluginException("The plugin type class parameter is not specified.");
@@ -64,7 +67,7 @@ class Multiconfig implements FactoryInterface {
   }
 
   /**
-   * Implements MulticonfigInterface::getInstance().
+   * Implements FactoryInterface::getInstance().
    */
   public function getInstance($options, Context $context) {
     list($plugin_class, $config) = $this->getConfiguration($options);
index f6c3cad..264adfa 100644 (file)
@@ -487,16 +487,21 @@ function timer_stop($name) {
   return $timers[$name];
 }
 
-function config($id) {
-  return new \Drupal\Configuration\Configuration($id);
+function config($class = 'Drupal\\Configuration\\ConfigurationService') {
+  static $config;
+  if (empty($config)) {
+    $config = new $class();
+  }
+  return $config;
 }
 
 function mapper($class = '\\Drupal\\Plugin\\Mapper') {
   static $mapper;
   if (empty($mapper)) {
-    $mapper = new $class();
+    $config = config();
+    $mapper = new $class($config);
     if ($class != 'Drupal\\Plugin\\MapperInterface' && !in_array('Drupal\\Plugin\\MapperInterface', class_implements($mapper))) {
-      throw new MapperException("Mapper class not an implementation of Drupal\\Plugin\\MapperInterface.");
+      throw new Drupal\Plugin\MapperException("Mapper class not an implementation of Drupal\\Plugin\\MapperInterface.");
     }
   }
   return $mapper;
index 5d4807e..508a9e4 100755 (executable)
--- a/test.php
+++ b/test.php
@@ -5,6 +5,12 @@ define('DRUPAL_ROOT', getcwd());
 require_once DRUPAL_ROOT . '/core/includes/bootstrap.inc';
 drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);
 
-$mapper = new \Drupal\Plugin\Mapper();
+
+$config = config();
+print '<pre>' . var_export($config->getPluginTypeConfiguration('core', 'block'), TRUE) . '</pre>';
+print '<pre>' . var_export($config->getPluginImplementations('core', 'block'), TRUE) . '</pre>';
+print '<pre>' . var_export($config->getPluginImplementationConfiguration('core', 'block', 'test'), TRUE) . '</pre>';
+
+$mapper = mapper();
 $factory_class = $mapper->getFactoryClass('core', 'cache');
 print '<pre>' . var_export($factory_class, TRUE) . '</pre>';