We have moved our forum to GitHub Discussions. For questions about Phalcon v3/v4/v5 you can visit here and for Phalcon v6 here.

MVC Model Binder default return type

Hi,

is there a way to tell the model binder / dispatcher to inject a default return value in case no model is found. Otherwise it returns false and only null is allowed as default in PHP.

Did I missed something in the docs ?

Thanks in advance

401

you can change it very simple

<?php

use \Exception;
use Phalcon\Mvc\Model;
use Phalcon\Mvc\Dispatcher as MvcDispatcher;
use Phalcon\Events\Event;
use Phalcon\Events\Manager as EventsManager;
use \ReflectionMethod;

$di->set(
    'dispatcher',
    function () {
        // Create an EventsManager
        $eventsManager = new EventsManager();

        $eventsManager->attach(
            'dispatch:beforeDispatchLoop',
            function (Event $event, $dispatcher) {
                // Possible controller class name
                $controllerName = $dispatcher->getControllerClass();

                // Possible method name
                $actionName = $dispatcher->getActiveMethod();

                try {
                    // Get the reflection for the method to be executed
                    $reflection = new ReflectionMethod($controllerName, $actionName);

                    $parameters = $reflection->getParameters();

                    // Check parameters
                    foreach ($parameters as $parameter) {
                        // Get the expected model name
                        $className = $parameter->getClass()->name;

                        // Check if the parameter expects a model instance
                        if (is_subclass_of($className, Model::class)) {
                            $model = $className::findFirstById($dispatcher->getParams()[0]) ?: null; // <<< HERE YOU HAVE TO CHANGE

                            // OTHER EXAMPLE If the parameter is a slug you would do something like this
                            if (!is_numeric($dispatcher->getParams()[0])) {
                                $model = $className::findFirstBySlug($dispatcher->getParams()[0]) ?: null;
                            }

                            // Override the parameters by the model instance
                            $dispatcher->setParams([$model]);
                        }
                    }
                } catch (Exception $e) {
                    // An exception has occurred, maybe the class or action does not exist?
                }
            }
        );

        $dispatcher = new MvcDispatcher();

        $dispatcher->setEventsManager($eventsManager);

        return $dispatcher;
    }
);

I've wrote 2 examples into the above code

Good luck

That's actually a good catch with this, i guess we should check if it's false and return null.

For now you can just extend Binder class and override findBoundModel method to return null.

HI buddy, does the above code with the loop works well for you? While I tried showing ";" error. Can you help me out please?

Regards, SixTad