Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

ENHANCEMENT Added $exclusive flag to SS_ClassLoader->pushManifest() t…

…o allow for multiple manifests co-existing (useful for tests which rely on core classes but also want to test their own manifests)
  • Loading branch information...
commit 0a0be63ee2ade7797d54f403aeef915d7e73ad36 1 parent a3e74bb
Ingo Schommer chillu authored
38 core/manifest/ClassLoader.php
View
@@ -14,7 +14,7 @@ class SS_ClassLoader {
private static $instance;
/**
- * @var SS_ClassManifest[]
+ * @var array Map of 'instance' (SS_ClassManifest) and other options.
*/
protected $manifests = array();
@@ -32,7 +32,7 @@ public static function instance() {
* @return SS_ClassManifest
*/
public function getManifest() {
- return $this->manifests[count($this->manifests) - 1];
+ return $this->manifests[count($this->manifests) - 1]['instance'];
}
/**
@@ -47,16 +47,23 @@ public function hasManifest() {
* also include any module configuration files at the same time.
*
* @param SS_ClassManifest $manifest
+ * @param Boolean Marks the manifest as exclusive. If set to FALSE, will
+ * look for classes in earlier manifests as well.
*/
- public function pushManifest(SS_ClassManifest $manifest) {
- $this->manifests[] = $manifest;
+ public function pushManifest(SS_ClassManifest $manifest, $exclusive = true) {
+ $this->manifests[] = array('exclusive' => $exclusive, 'instance' => $manifest);
+
+ foreach ($manifest->getConfigs() as $config) {
+ require_once $config;
+ }
}
/**
* @return SS_ClassManifest
*/
public function popManifest() {
- return array_pop($this->manifests);
+ $manifest = array_pop($this->manifests);
+ return $manifest['instance'];
}
public function registerAutoloader() {
@@ -68,11 +75,28 @@ public function registerAutoloader() {
* manifest.
*
* @param string $class
+ * @return String
*/
public function loadClass($class) {
- if ($path = $this->getManifest()->getItemPath($class)) {
+ if ($path = $this->getItemPath($class)) {
require_once $path;
}
+ return $path;
+ }
+
+ /**
+ * Returns the path for a class or interface in the currently active manifest,
+ * or any previous ones if later manifests aren't set to "exclusive".
+ *
+ * @return String
+ */
+ public function getItemPath($class) {
+ foreach(array_reverse($this->manifests) as $manifest) {
+ $manifestInst = $manifest['instance'];
+ if ($path = $manifestInst->getItemPath($class)) return $path;
+ if($manifest['exclusive']) break;
+ }
+ return false;
}
/**
@@ -82,7 +106,7 @@ public function loadClass($class) {
* @return bool
*/
public function classExists($class) {
- return class_exists($class, false) || $this->getManifest()->getItemPath($class);
+ return class_exists($class, false) || $this->getItemPath($class);
}
}
71 tests/core/manifest/ClassLoaderTest.php
View
@@ -0,0 +1,71 @@
+<?php
+/**
+ * Tests for the {@link SS_ClassManifest} class.
+ *
+ * @package sapphire
+ * @subpackage tests
+ */
+class ClassLoaderTest extends SapphireTest {
+
+ protected $base;
+ protected $manifest;
+
+ function setUp() {
+ parent::setUp();
+
+ $this->baseManifest1 = dirname(__FILE__) . '/fixtures/classmanifest';
+ $this->baseManifest2 = dirname(__FILE__) . '/fixtures/classmanifest_other';
+ $this->testManifest1 = new SS_ClassManifest($this->baseManifest1, false, true, false);
+ $this->testManifest2 = new SS_ClassManifest($this->baseManifest2, false, true, false);
+ }
+
+ function testExclusive() {
+ $loader = new SS_ClassLoader();
+
+ $loader->pushManifest($this->testManifest1);
+ $this->assertTrue((bool)$loader->getItemPath('ClassA'));
+ $this->assertFalse((bool)$loader->getItemPath('OtherClassA'));
+
+ $loader->pushManifest($this->testManifest2);
+ $this->assertFalse((bool)$loader->getItemPath('ClassA'));
+ $this->assertTrue((bool)$loader->getItemPath('OtherClassA'));
+
+ $loader->popManifest();
+ $loader->pushManifest($this->testManifest2, false);
+ $this->assertTrue((bool)$loader->getItemPath('ClassA'));
+ $this->assertTrue((bool)$loader->getItemPath('OtherClassA'));
+ }
+
+ function testGetItemPath() {
+ $ds = DIRECTORY_SEPARATOR;
+ $loader = new SS_ClassLoader();
+
+ $loader->pushManifest($this->testManifest1);
+ $this->assertEquals(
+ $this->baseManifest1 . $ds . 'module' . $ds . 'classes' . $ds . 'ClassA.php',
+ $loader->getItemPath('ClassA')
+ );
+ $this->assertEquals(
+ false,
+ $loader->getItemPath('UnknownClass')
+ );
+ $this->assertEquals(
+ false,
+ $loader->getItemPath('OtherClassA')
+ );
+
+ $loader->pushManifest($this->testManifest2);
+ $this->assertEquals(
+ false,
+ $loader->getItemPath('ClassA')
+ );
+ $this->assertEquals(
+ false,
+ $loader->getItemPath('UnknownClass')
+ );
+ $this->assertEquals(
+ $this->baseManifest2 . $ds . 'module' . $ds . 'classes' . $ds . 'OtherClassA.php',
+ $loader->getItemPath('OtherClassA')
+ );
+ }
+}
0  tests/core/manifest/fixtures/classmanifest_other/module/_config.php
View
No changes.
5 tests/core/manifest/fixtures/classmanifest_other/module/classes/OtherClassA.php
View
@@ -0,0 +1,5 @@
+<?php
+/**
+ * @ignore
+ */
+class OtherClassA { }
Please sign in to comment.
Something went wrong with that request. Please try again.