Skip to content
This repository
Browse code

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 authored November 27, 2011
38  core/manifest/ClassLoader.php
@@ -14,7 +14,7 @@ class SS_ClassLoader {
14 14
 	private static $instance;
15 15
 
16 16
 	/**
17  
-	 * @var SS_ClassManifest[]
  17
+	 * @var array Map of 'instance' (SS_ClassManifest) and other options.
18 18
 	 */
19 19
 	protected $manifests = array();
20 20
 
@@ -32,7 +32,7 @@ public static function instance() {
32 32
 	 * @return SS_ClassManifest
33 33
 	 */
34 34
 	public function getManifest() {
35  
-		return $this->manifests[count($this->manifests) - 1];
  35
+		return $this->manifests[count($this->manifests) - 1]['instance'];
36 36
 	}
37 37
 	
38 38
 	/**
@@ -47,16 +47,23 @@ public function hasManifest() {
47 47
 	 * also include any module configuration files at the same time.
48 48
 	 *
49 49
 	 * @param SS_ClassManifest $manifest
  50
+	 * @param Boolean Marks the manifest as exclusive. If set to FALSE, will
  51
+	 * look for classes in earlier manifests as well.
50 52
 	 */
51  
-	public function pushManifest(SS_ClassManifest $manifest) {
52  
-		$this->manifests[] = $manifest;
  53
+	public function pushManifest(SS_ClassManifest $manifest, $exclusive = true) {
  54
+		$this->manifests[] = array('exclusive' => $exclusive, 'instance' => $manifest);
  55
+
  56
+		foreach ($manifest->getConfigs() as $config) {
  57
+			require_once $config;
  58
+		}
53 59
 	}
54 60
 
55 61
 	/**
56 62
 	 * @return SS_ClassManifest
57 63
 	 */
58 64
 	public function popManifest() {
59  
-		return array_pop($this->manifests);
  65
+		$manifest = array_pop($this->manifests);
  66
+		return $manifest['instance'];
60 67
 	}
61 68
 
62 69
 	public function registerAutoloader() {
@@ -68,11 +75,28 @@ public function registerAutoloader() {
68 75
 	 * manifest.
69 76
 	 *
70 77
 	 * @param string $class
  78
+	 * @return String
71 79
 	 */
72 80
 	public function loadClass($class) {
73  
-		if ($path = $this->getManifest()->getItemPath($class)) {
  81
+		if ($path = $this->getItemPath($class)) {
74 82
 			require_once $path;
75 83
 		}
  84
+		return $path;
  85
+	}
  86
+	
  87
+	/**
  88
+	 * Returns the path for a class or interface in the currently active manifest,
  89
+	 * or any previous ones if later manifests aren't set to "exclusive".
  90
+	 * 
  91
+	 * @return String
  92
+	 */
  93
+	public function getItemPath($class) {
  94
+		foreach(array_reverse($this->manifests) as $manifest) {
  95
+			$manifestInst = $manifest['instance'];
  96
+			if ($path = $manifestInst->getItemPath($class)) return $path;
  97
+			if($manifest['exclusive']) break;
  98
+		}
  99
+		return false;
76 100
 	}
77 101
 
78 102
 	/**
@@ -82,7 +106,7 @@ public function loadClass($class) {
82 106
 	 * @return bool
83 107
 	 */
84 108
 	public function classExists($class) {
85  
-		return class_exists($class, false) || $this->getManifest()->getItemPath($class);
  109
+		return class_exists($class, false) || $this->getItemPath($class);
86 110
 	}
87 111
 
88 112
 }
71  tests/core/manifest/ClassLoaderTest.php
... ...
@@ -0,0 +1,71 @@
  1
+<?php
  2
+/**
  3
+ * Tests for the {@link SS_ClassManifest} class.
  4
+ *
  5
+ * @package    sapphire
  6
+ * @subpackage tests
  7
+ */
  8
+class ClassLoaderTest extends SapphireTest {
  9
+
  10
+	protected $base;
  11
+	protected $manifest;
  12
+	
  13
+	function setUp() {
  14
+		parent::setUp();
  15
+		
  16
+		$this->baseManifest1 = dirname(__FILE__) . '/fixtures/classmanifest';
  17
+		$this->baseManifest2 = dirname(__FILE__) . '/fixtures/classmanifest_other';
  18
+		$this->testManifest1 = new SS_ClassManifest($this->baseManifest1, false, true, false);
  19
+		$this->testManifest2 = new SS_ClassManifest($this->baseManifest2, false, true, false);
  20
+	}
  21
+
  22
+	function testExclusive() {
  23
+		$loader = new SS_ClassLoader();
  24
+		
  25
+		$loader->pushManifest($this->testManifest1);
  26
+		$this->assertTrue((bool)$loader->getItemPath('ClassA'));
  27
+		$this->assertFalse((bool)$loader->getItemPath('OtherClassA'));
  28
+		
  29
+		$loader->pushManifest($this->testManifest2);
  30
+		$this->assertFalse((bool)$loader->getItemPath('ClassA'));
  31
+		$this->assertTrue((bool)$loader->getItemPath('OtherClassA'));
  32
+		
  33
+		$loader->popManifest();
  34
+		$loader->pushManifest($this->testManifest2, false);
  35
+		$this->assertTrue((bool)$loader->getItemPath('ClassA'));
  36
+		$this->assertTrue((bool)$loader->getItemPath('OtherClassA'));
  37
+	}
  38
+
  39
+	function testGetItemPath() {
  40
+		$ds = DIRECTORY_SEPARATOR;
  41
+		$loader = new SS_ClassLoader();
  42
+		
  43
+		$loader->pushManifest($this->testManifest1);
  44
+		$this->assertEquals(
  45
+			$this->baseManifest1 . $ds . 'module' . $ds . 'classes' . $ds . 'ClassA.php',
  46
+			$loader->getItemPath('ClassA')
  47
+		);
  48
+		$this->assertEquals(
  49
+			false,
  50
+			$loader->getItemPath('UnknownClass')
  51
+		);
  52
+		$this->assertEquals(
  53
+			false,
  54
+			$loader->getItemPath('OtherClassA')
  55
+		);
  56
+		
  57
+		$loader->pushManifest($this->testManifest2);
  58
+		$this->assertEquals(
  59
+			false,
  60
+			$loader->getItemPath('ClassA')
  61
+		);
  62
+		$this->assertEquals(
  63
+			false,
  64
+			$loader->getItemPath('UnknownClass')
  65
+		);
  66
+		$this->assertEquals(
  67
+			$this->baseManifest2 . $ds . 'module' . $ds . 'classes' . $ds . 'OtherClassA.php',
  68
+			$loader->getItemPath('OtherClassA')
  69
+		);
  70
+	}
  71
+}
0  tests/core/manifest/fixtures/classmanifest_other/module/_config.php
No changes.
5  tests/core/manifest/fixtures/classmanifest_other/module/classes/OtherClassA.php
... ...
@@ -0,0 +1,5 @@
  1
+<?php
  2
+/**
  3
+ * @ignore
  4
+ */
  5
+class OtherClassA {  }

0 notes on commit 0a0be63

Please sign in to comment.
Something went wrong with that request. Please try again.