Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Problem with Forward Plugin #5432

Merged
merged 5 commits into from

3 participants

@Lansoweb

Hi!

I'm playing with apigility and trying to use it with one of my project. But when i try to login in the system i receive the error:

Fatal error: Cannot use object of type ZF\ContentNegotiation\AcceptListener as array in xxx/vendor/zendframework/zendframework/library/Zend/Mvc/Controller/Plugin/Forward.php on line 179

the error occurs inside detachProblemListeners.

If i comment the attacing listener inside the onBootstrap (zfcampus/zf-content-negotiation/src/ZF/ContentNegotiation/Module.php:122) i can login but the api stops working (as expected).

Maybe Forward.php should check if the callback is in fact an array on line 179 (ZF2 2.2.5)? Something like:

if (!is_array($currentCallback) || !isset($currentCallback[0])) {

Thanks,
Leandro Silva

weierophinney added some commits
@weierophinney weierophinney [#5432] Test if callback is an array prior to accessing as array
- Callbacks can be strings, objects (functors), or closures, too.
- Allow testing against functor callbacks
b91c76f
@weierophinney weierophinney [#5432] Added test
- Finally determined a way to add a test for this.
e5fd6bf
@weierophinney weierophinney [#5432] CS fixes
- Trailing whitespace
9c5ba9b
@weierophinney

I've added code that does the following:

  • Tests if we have either an object or an array callback, returning early if not.
  • Allows testing either an object or array callback against the blacklist (as the former likely should be tested).

The test added did indeed display an error before the fix, and now does not.

library/Zend/Mvc/Controller/Plugin/Forward.php
@@ -176,11 +176,22 @@ protected function detachProblemListeners(SharedEvents $sharedEvents)
$events = $sharedEvents->getListeners($id, $eventName);
foreach ($events as $currentEvent) {
$currentCallback = $currentEvent->getCallback();
- if (!isset($currentCallback[0])) {
+
+ // Testing against object callbacks
@Maks3w Collaborator
Maks3w added a note

What do you think about rewrite this part with this?

if (is_array($currentCallback)) {
    $currentCallback = array_shift($currentCallback);
}

if (!is_object($currentCallback) {
    continue;
}
@weierophinney Owner

Sounds good! Implementing now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@Maks3w Maks3w was assigned
@Maks3w Maks3w merged commit 2c20e80 into from
@ThaDafinser ThaDafinser referenced this pull request from a commit in ThaDafinser/zf2
@weierophinney weierophinney [#5432] Test if callback is an array prior to accessing as array
- Callbacks can be strings, objects (functors), or closures, too.
- Allow testing against functor callbacks
5ff3367
@ThaDafinser ThaDafinser referenced this pull request from a commit in ThaDafinser/zf2
@weierophinney weierophinney [#5432] Added test
- Finally determined a way to add a test for this.
50f27f3
@ThaDafinser ThaDafinser referenced this pull request from a commit in ThaDafinser/zf2
@weierophinney weierophinney [#5432] CS fixes
- Trailing whitespace
71fe9f4
@ThaDafinser ThaDafinser referenced this pull request from a commit in ThaDafinser/zf2
@weierophinney weierophinney [#5432] Incorporate feedback
- Simplify logic when introspecting callback
b98c816
@ThaDafinser ThaDafinser referenced this pull request from a commit in ThaDafinser/zf2
@weierophinney weierophinney [#5432] Use array_shift instead of specific index access
- per @Maks3w
24a1e91
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Nov 11, 2013
  1. @weierophinney

    [#5432] Test if callback is an array prior to accessing as array

    weierophinney authored
    - Callbacks can be strings, objects (functors), or closures, too.
    - Allow testing against functor callbacks
  2. @weierophinney

    [#5432] Added test

    weierophinney authored
    - Finally determined a way to add a test for this.
  3. @weierophinney

    [#5432] CS fixes

    weierophinney authored
    - Trailing whitespace
Commits on Nov 12, 2013
  1. @weierophinney

    [#5432] Incorporate feedback

    weierophinney authored
    - Simplify logic when introspecting callback
  2. @weierophinney
This page is out of date. Refresh to see the latest.
View
12 library/Zend/Mvc/Controller/Plugin/Forward.php
@@ -176,11 +176,19 @@ protected function detachProblemListeners(SharedEvents $sharedEvents)
$events = $sharedEvents->getListeners($id, $eventName);
foreach ($events as $currentEvent) {
$currentCallback = $currentEvent->getCallback();
- if (!isset($currentCallback[0])) {
+
+ // If we have an array, grab the object
+ if (is_array($currentCallback)) {
+ $currentCallback = array_shift($currentCallback);
+ }
+
+ // This routine is only valid for object callbacks
+ if (!is_object($currentCallback)) {
continue;
}
+
foreach ($classArray as $class) {
- if (is_a($currentCallback[0], $class)) {
+ if (is_a($currentCallback, $class)) {
$sharedEvents->detach($id, $currentEvent);
$results[$id][$eventName][] = $currentEvent;
}
View
24 tests/ZendTest/Mvc/Controller/Plugin/ForwardTest.php
@@ -19,6 +19,7 @@
use Zend\Mvc\Controller\Plugin\Forward as ForwardPlugin;
use Zend\Mvc\MvcEvent;
use Zend\Mvc\Router\RouteMatch;
+use Zend\Stdlib\CallbackHandler;
use ZendTest\Mvc\Controller\TestAsset\ForwardController;
use ZendTest\Mvc\Controller\TestAsset\SampleController;
use ZendTest\Mvc\Controller\TestAsset\UneventfulController;
@@ -128,6 +129,29 @@ public function testPluginDispatchsRequestedControllerWhenFound()
$this->assertEquals(array('content' => 'ZendTest\Mvc\Controller\TestAsset\ForwardController::testAction'), $result);
}
+ /**
+ * @group 5432
+ */
+ public function testNonArrayListenerDoesNotRaiseErrorWhenPluginDispatchsRequestedController()
+ {
+ $services = $this->plugins->getServiceLocator();
+ $events = $services->get('EventManager');
+ $sharedEvents = $this->getMock('Zend\EventManager\SharedEventManagerInterface');
+ $sharedEvents->expects($this->any())->method('getListeners')->will($this->returnValue(array(
+ new CallbackHandler(function ($e) {})
+ )));
+ $events = $this->getMock('Zend\EventManager\EventManagerInterface');
+ $events->expects($this->any())->method('getSharedManager')->will($this->returnValue($sharedEvents));
+ $application = $this->getMock('Zend\Mvc\ApplicationInterface');
+ $application->expects($this->any())->method('getEventManager')->will($this->returnValue($events));
+ $event = $this->controller->getEvent();
+ $event->setApplication($application);
+
+ $result = $this->plugin->dispatch('forward');
+ $this->assertInternalType('array', $result);
+ $this->assertEquals(array('content' => 'ZendTest\Mvc\Controller\TestAsset\ForwardController::testAction'), $result);
+ }
+
public function testDispatchWillSeedRouteMatchWithPassedParameters()
{
$result = $this->plugin->dispatch('forward', array(
Something went wrong with that request. Please try again.