Skip to content

Commit

Permalink
Merge pull request #16694 from twistersfury/hotfix/controller-named-p…
Browse files Browse the repository at this point in the history
…arams

Resolving Issue With Named Parameters and Dispatcher
  • Loading branch information
niden authored Feb 7, 2025
2 parents ca9be48 + 8bee72a commit 4d1b750
Show file tree
Hide file tree
Showing 3 changed files with 187 additions and 4 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG-5.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
- Changed `Phalcon\Filter\Validation\Validator\Email` to allow UTF8 in local part. [#16637](https://github.com/phalcon/cphalcon/issues/16637)

### Added

- Added `dispatch:beforeCallAction` and `dispatch:afterCallAction` to last-minute modifications to handler and method (mostly for debugging).

### Fixed

Expand All @@ -17,6 +17,7 @@
- Fixed `Phalcon\Filter\Validation\Validator\File\MimeType::validate` to close the handle when using `finfo` [#16647](https://github.com/phalcon/cphalcon/issues/16647)
- Fixed `Phalcon\Mvc\Model\Manager::getRelationRecords` to explicitly set the `referencedModel` in the conditions along with the `referencedFields` [#16655](https://github.com/phalcon/cphalcon/pull/16655)
- Fixed `Phalcon\Image\Adapters\AbstractAdapter::watermark` to correctly calculate the Y offset [#16658](https://github.com/phalcon/cphalcon/issues/16658)
- Fixed `Phalcon\Dispatcher\AbstractDispatcher` when calling action methods that do not define parameters to prevent `Unknown named parameter` error.

### Removed

Expand Down
49 changes: 46 additions & 3 deletions phalcon/Dispatcher/AbstractDispatcher.zep
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ use Phalcon\Events\ManagerInterface;
use Phalcon\Filter\FilterInterface;
use Phalcon\Mvc\Model\Binder;
use Phalcon\Mvc\Model\BinderInterface;
use Phalcon\Support\Collection;

/**
* This is the base class for Phalcon\Mvc\Dispatcher and Phalcon\Cli\Dispatcher.
Expand Down Expand Up @@ -154,10 +155,52 @@ abstract class AbstractDispatcher extends AbstractInjectionAware implements Disp

public function callActionMethod(handler, string actionMethod, array! params = [])
{
return call_user_func_array(
[handler, actionMethod],
params
var result, observer, altHandler, altAction, altParams;

let altHandler = handler;
let altAction = actionMethod;
let altParams = params;

if this->eventsManager !== null && this->eventsManager instanceof ManagerInterface {
let observer = <Collection> this->getDi()->get(
"Phalcon\Support\Collection",
[[
"handler": handler,
"action": actionMethod,
"params": params
]]
);

this->eventsManager->fire(
"dispatch:beforeCallAction",
this,
observer
);

let altHandler = observer->get("handler");
let altAction = observer->get("action");
let altParams = observer->get("params", [], "array");
}

let result = call_user_func_array(
[
altHandler,
altAction
],
array_values(altParams)
);

if this->eventsManager !== null && this->eventsManager instanceof ManagerInterface {
let observer["result"] = result;

this->eventsManager->fire(
"dispatch:afterCallAction",
this,
observer
);
}

return result;
}

/**
Expand Down
139 changes: 139 additions & 0 deletions tests/unit/Dispatcher/CallActionMethodCest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
<?php

/**
* This file is part of the Phalcon Framework.
*
* (c) Phalcon Team <team@phalcon.io>
*
* For the full copyright and license information, please view the LICENSE.txt
* file that was distributed with this source code.
*/

declare(strict_types=1);

namespace Phalcon\Tests\Unit\Dispatcher;

use Phalcon\Di\Di;
use Phalcon\Events\Event;
use Phalcon\Events\Manager;
use Phalcon\Mvc\Dispatcher;
use Phalcon\Support\Collection;
use UnitTester;

class CallActionMethodCest
{
private bool $wasCalled = false;
private bool $altCalled = false;
private string $paramCalled = '';

public function _before(UnitTester $I)
{
$this->wasCalled = false;
$this->altCalled = false;
$this->paramCalled = '';
}

/**
* Tests Phalcon\Dispatcher :: callActionMethod()
*
* @author Phalcon Team <team@phalcon.io>
* @since 2025-01-06
*/
public function dispatcherCallActionMethod(UnitTester $I)
{
$I->wantToTest('Dispatcher - callActionMethod()');

$dispatcher = new Dispatcher();

$dispatcher->callActionMethod(
$this,
'_wasCalled'
);

$I->assertTrue($this->wasCalled);
$I->assertFalse($this->altCalled);
}

/**
* Tests Phalcon\Dispatcher :: callActionMethod()
*
* @author Phalcon Team <team@phalcon.io>
* @since 2025-01-06
*/
public function dispatcherCallActionMethodWithParams(UnitTester $I)
{
$I->wantToTest('Dispatcher - callActionMethod() - Params');

$dispatcher = new Dispatcher();

$dispatcher->callActionMethod(
$this,
'_paramCalled',
[
'something' => 'else'
]
);

$I->assertFalse($this->wasCalled);
$I->assertFalse($this->altCalled);
$I->assertEquals('else', $this->paramCalled);

$dispatcher->callActionMethod(
$this,
'_paramCalled',
[
'something'
]
);

$I->assertFalse($this->wasCalled);
$I->assertFalse($this->altCalled);
$I->assertEquals('something', $this->paramCalled);
}

/**
* Tests Phalcon\Dispatcher :: callActionMethod() Events
*
* @author Phalcon Team <team@phalcon.io>
* @since 2025-01-06
*/
public function dispatcherCallActionMethodWithEvents(UnitTester $I)
{
$I->wantToTest('Dispatcher - callActionMethod() - Events');

$eventsManager = new Manager();
$eventsManager->attach(
'dispatch:beforeCallAction',
function (Event $event, Dispatcher $dispatcher, Collection $observer) {
$observer->action = "_altCalled";
}
);

$dispatcher = new Dispatcher();
$dispatcher->setEventsManager($eventsManager);
$dispatcher->setDi(new Di());

$dispatcher->callActionMethod(
$this,
'_wasCalled'
);

$I->assertTrue($this->altCalled);
$I->assertFalse($this->wasCalled);
}

public function _wasCalled(): void
{
$this->wasCalled = true;
}

public function _altCalled(): void
{
$this->altCalled = true;
}

public function _paramCalled(string $param): void
{
$this->paramCalled = $param;
}
}

0 comments on commit 4d1b750

Please sign in to comment.