Browse files

Merge pull request #366 from jails/master

Adding a way to replace any library's file
  • Loading branch information...
2 parents e9d7480 + 47a9c64 commit ab8f628ffa0a7d8baf8447a199d41ed51ef613a2 @nateabele nateabele committed Mar 7, 2012
Showing with 118 additions and 2 deletions.
  1. +52 −1 core/Libraries.php
  2. +66 −1 tests/cases/core/LibrariesTest.php
View
53 core/Libraries.php
@@ -157,6 +157,16 @@ class Libraries {
protected static $_cachedPaths = array();
/**
+ * Holds associations between fully-namespaced class names and file's paths mapped
+ * with `lithium\core\Libraries::map()`.
+ *
+ * @var array
+ * @see lithium\core\Libraries::map()
+ * @see lithium\core\Libraries::unmap()
+ */
+ protected static $_map = array();
+
+ /**
* Accessor method for the class path templates which `Libraries` uses to look up and load
* classes. Using this method, you can define your own types of classes, or modify the default
* organization of built-in class types.
@@ -475,6 +485,44 @@ public static function load($class, $require = false) {
}
/**
+ * Associtates fully-namespaced class names to their corresponding paths on
+ * the file system.
+ *
+ * Once a class is associtated to a path using `lithium\core\Libraries::map()`
+ * the PSR-0 loader or custom class loader setted using the `transform` or `loader`
+ * option of `lithium\core\Libraries::add()` are ignored and the associtated path
+ * is used instead.
+ *
+ * @param array $classes An array of fully-namespaced class names (as keys) and
+ * their correponding file's paths (as values).
+ *
+ * @return void
+ */
+ public static function map(array $classes) {
+ foreach ($classes as $key => $value) {
+ unset(static::$_cachedPaths[$key]);
+ }
+ static::$_map = array_merge(static::$_map, $classes);
+ }
+
+ /**
+ * Unmap fully-namespaced class names mapped using `lithium\core\Libraries::map()`.
+ *
+ * @param mixed $classes An array of fully-namespaced class names or
+ * a string with a fully-namespaced class name.
+ *
+ * @see lithium\core\Libraries::map()
+ */
+ public static function unmap($classes) {
+ if (!is_array($classes)) {
+ $classes = array($classes);
+ }
+ foreach ($classes as $value) {
+ unset(static::$_map[$value]);
+ }
+ }
+
+ /**
* Get the corresponding physical file path for a class or namespace name.
*
* @param string $class The class name to locate the physical file for. If `$options['dirs']` is
@@ -495,6 +543,9 @@ public static function path($class, array $options = array()) {
if (isset(static::$_cachedPaths[$class]) && !$options['dirs']) {
return static::$_cachedPaths[$class];
}
+ if (isset(static::$_map[$class]) && !$options['dirs']) {
+ return static::$_map[$class];
+ }
foreach (static::$_configurations as $name => $config) {
$params = $options + $config;
$suffix = $params['suffix'];
@@ -1004,4 +1055,4 @@ protected static function _params($type, $name = "*") {
}
}
-?>
+?>
View
67 tests/cases/core/LibrariesTest.php
@@ -628,6 +628,71 @@ public function index() {
$this->_cleanUp();
}
+
+ /**
+ * Tests that `Libraries::map()` and `Libraries::unmap()`
+ *
+ */
+ public function testMapUnmap() {
+ $testApp = Libraries::get(true, 'resources') . '/tmp/tests/test_app';
+ mkdir($testApp, 0777, true);
+ Libraries::add('test_app', array('path' => $testApp));
+
+ mkdir($testApp. '/lib', 0777);
+ mkdir($testApp. '/_patch', 0777);
+
+ file_put_contents($testApp . '/lib/LibTest.php',
+ "<?php namespace test_app\\lib;\n
+ class LibTest{ public function testMe() {
+ return 'core class';
+ }}"
+ );
+
+ file_put_contents($testApp . '/_patch/PatchedLibTest.php',
+ "<?php namespace test_app\\lib;\n
+ class LibTest{ public function testMe() {
+ return 'patched class';
+ }}"
+ );
+
+ $expected = $result = Libraries::realPath($testApp . '/lib/LibTest.php');
+ $result = Libraries::path('test_app\\lib\\LibTest');
+
+ $this->assertEqual($expected, $result);
+
+ Libraries::map(array(
+ 'test_app\\lib\\LibTest' => $testApp . '/_patch/PatchedLibTest.php'
+ ));
+
+ $expected = $result = Libraries::realPath($testApp . '/_patch/PatchedLibTest.php');
+ $result = Libraries::path('test_app\\lib\\LibTest');
+
+ Libraries::unmap(array('test_app\\lib\\LibTest'));
+
+ $expected = $result = Libraries::realPath($testApp . '/lib/LibTest.php');
+ $result = Libraries::path('test_app\\lib\\LibTest');
+
+ $this->assertEqual($expected, $result);
+
+ Libraries::map(array(
+ 'test_app\\lib\\LibTest' => $testApp . '/_patch/PatchedLibTest.php'
+ ));
+ Libraries::unmap('test_app\\lib\\LibTest');
+
+ $expected = $result = Libraries::realPath($testApp . '/lib/LibTest.php');
+ $result = Libraries::path('test_app\\lib\\LibTest');
+
+ Libraries::map(array(
+ 'test_app\\lib\\LibTest' => $testApp . '/_patch/PatchedLibTest.php'
+ ));
+
+ $object = new \test_app\lib\LibTest();
+
+ $result = $object->testMe();
+ $this->assertEqual('patched class', $result);
+
+ $this->_cleanUp();
+ }
}
-?>
+?>

0 comments on commit ab8f628

Please sign in to comment.