Browse Source

Merge pull request #5004 from cakephp/issue-4967

Fix addContextProvider()
José Lorenzo Rodríguez 11 years ago
parent
commit
1017a75ceb
2 changed files with 54 additions and 11 deletions
  1. 15 9
      src/View/Helper/FormHelper.php
  2. 39 2
      tests/TestCase/View/Helper/FormHelperTest.php

+ 15 - 9
src/View/Helper/FormHelper.php

@@ -161,7 +161,7 @@ class FormHelper extends Helper {
  * @var array
  * @see addContextProvider
  */
-	protected $_contextProviders;
+	protected $_contextProviders = [];
 
 /**
  * The action attribute value of the last created form.
@@ -211,12 +211,6 @@ class FormHelper extends Helper {
  * @return void
  */
 	protected function _addDefaultContextProviders() {
-		$this->addContextProvider('array', function ($request, $data) {
-			if (is_array($data['entity']) && isset($data['entity']['schema'])) {
-				return new ArrayContext($request, $data['entity']);
-			}
-		});
-
 		$this->addContextProvider('orm', function ($request, $data) {
 			if (is_array($data['entity']) || $data['entity'] instanceof Traversable) {
 				$pass = (new Collection($data['entity']))->first() !== null;
@@ -231,6 +225,12 @@ class FormHelper extends Helper {
 				return new EntityContext($request, $data);
 			}
 		});
+
+		$this->addContextProvider('array', function ($request, $data) {
+			if (is_array($data['entity']) && isset($data['entity']['schema'])) {
+				return new ArrayContext($request, $data['entity']);
+			}
+		});
 	}
 
 /**
@@ -2256,7 +2256,12 @@ class FormHelper extends Helper {
  * @return void
  */
 	public function addContextProvider($type, callable $check) {
-		$this->_contextProviders[$type] = $check;
+		foreach ($this->_contextProviders as $i => $provider) {
+			if ($provider['type'] === $type) {
+				unset($this->_contextProviders[$i]);
+			}
+		}
+		array_unshift($this->_contextProviders, ['type' => $type, 'callable' => $check]);
 	}
 
 /**
@@ -2290,7 +2295,8 @@ class FormHelper extends Helper {
 		}
 		$data += ['entity' => null];
 
-		foreach ($this->_contextProviders as $key => $check) {
+		foreach ($this->_contextProviders as $provider) {
+			$check = $provider['callable'];
 			$context = $check($this->request, $data);
 			if ($context) {
 				break;

+ 39 - 2
tests/TestCase/View/Helper/FormHelperTest.php

@@ -241,12 +241,49 @@ class FormHelperTest extends TestCase {
  */
 	public function testAddContextProvider() {
 		$context = 'My data';
-		$this->Form->addContextProvider('test', function ($request, $data) use ($context) {
+		$stub = $this->getMock('Cake\View\Form\ContextInterface');
+		$this->Form->addContextProvider('test', function ($request, $data) use ($context, $stub) {
 			$this->assertInstanceOf('Cake\Network\Request', $request);
 			$this->assertEquals($context, $data['entity']);
-			return $this->getMock('Cake\View\Form\ContextInterface');
+			return $stub;
 		});
 		$this->Form->create($context);
+		$result = $this->Form->context();
+		$this->assertSame($stub, $result);
+	}
+
+/**
+ * Test replacing a context class.
+ *
+ * @return void
+ */
+	public function testAddContextProviderReplace() {
+		$entity = new Article();
+		$stub = $this->getMock('Cake\View\Form\ContextInterface');
+		$this->Form->addContextProvider('orm', function ($request, $data) use ($stub) {
+			return $stub;
+		});
+		$this->Form->create($entity);
+		$result = $this->Form->context();
+		$this->assertSame($stub, $result);
+	}
+
+/**
+ * Test overriding a context class.
+ *
+ * @return void
+ */
+	public function testAddContextProviderAdd() {
+		$entity = new Article();
+		$stub = $this->getMock('Cake\View\Form\ContextInterface');
+		$this->Form->addContextProvider('newshiny', function ($request, $data) use ($stub) {
+			if ($data['entity'] instanceof Entity) {
+				return $stub;
+			}
+		});
+		$this->Form->create($entity);
+		$result = $this->Form->context();
+		$this->assertSame($stub, $result);
 	}
 
 /**