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

Dispatcher getParam default value

Hi,

I'm trying to make pagination for a listing, and I'm having problems setting default value for $page with getParam method from dispatcher. The URL is like this : (https://www.example.com/category/subcategory/{page_number_here}) This is how I get page param from dispatcher

$page = $this->dispatcher->getParam('page', 'int', 1);

the problem is that when I put letters only (or nothing at all) for page it doesn't set $page with 1 as I expect it to do, it sets it with an empty string. Am I doing something wrong, is there something that I got it wrong on how it should work?

Thanks.

edited Aug '15

Why you just not use routeparams ? You can access them like:

use Phalcon\Mvc\Router\Group;

class Routes extends Group
{
    public function initialize()
    {
$this->addGet('/{id:[0-9]+$}', array('action' => 'index', 'controller' => 'test'));
    }
}

then mount this group in router :

$di->get('router')->mount(new Routes());

and finally in controller:

public function indexAction($id) // $id is our id from URL
{

}

Thanks for reply, I don't have issue working around this, I want to know why it's not working as it should, since I have the 3rd param as default value in getParam method, I want to know why it's not set. What are the conditions so that param (page) to get the default value.

edited Aug '15

Use the routing example (category/subcategory/{id:[0-9]+$}) provided by @Jurigag and if the paramater is not an integer, it will not even be routed to the action at all. (You can still use getParam(id))

According to the source of Phalcon, the default value will only be returned if there is no such key in the params... You could file a bug report on github.

public function getParam(param, filters = null, defaultValue = null)
    {
        var params, filter, paramValue, dependencyInjector;

        let params = this->_params;
        if !fetch paramValue, params[param] {
            return defaultValue;
        }

        if filters === null {
            return paramValue;
        }

        let dependencyInjector = this->_dependencyInjector;
        if typeof dependencyInjector != "object" {
            this->{"_throwDispatchException"}("A dependency injection object is required to access the 'filter' service", self::EXCEPTION_NO_DI);
        }
        let filter = <FilterInterface> dependencyInjector->getShared("filter");
        return filter->sanitize(paramValue, filters);
    }

Thanks for the info, I will try it, first thing in the morning when I get to work. Regarding bug report, I'll file one, but maybe this was the intended use of the default value, even though I find it strange to work like that.

edited Aug '15

Yeah... You got a point, sanitize != validate :D It should probably be a NFR, because it does makes sense to have the default value returned if the length of the sanitized field is 0

https://github.com/phalcon/cphalcon/issues/10866

Hi, I'm back again with some more code samples regarding the routes that I want to achieve, I left the routes at the end of the project so I could focus more important things. Now I'm struggling to get pagination working properly.

here are some routes:

This works fine, the only problem is that if there's no page number in url (/mac/browsers/) the default page is 3.

    // route for category with pagination
    $this->add('/(windows|mac|mobile)/([a-zA-Z0-9\-]+)/?[0-9+]?/?',
        array(
            'module' => 'category',
            'namespace' => 'Category\controllers',
            'controller' => 'Category',
            'action'     => 'index',
            'os'        => 1,
            'category' => 2,
            'page' => 3
        )
    );

This also works fine, and fixes the problem with the above one, but it's conflicting with subcategory routes.

    $this->add('/(windows|mac|mobile)/([a-zA-Z0-9\-]+)/?{page}?/?',
        array(
            'module' => 'category',
            'namespace' => 'Category\controllers',
            'controller' => 'Category',
            'action'     => 'index',
            'os'        => 1,
            'category' => 2,
            'page' => 3
        )
    )->convert('page', function($page) {
        if (!is_int($page))
            return 1;
        else
            return $page;
    });

This route is working ok if the category route is using [0-9+] regex to get the page param, or page number is present in URL.

    // subcategory with pagination -  default tab
    $this->add('/(windows|mac|mobile)/([a-zA-Z0-9_-]+)/([a-zA-Z0-9_-]+)/?{page}?/?',
        array(
            'module' => 'subcategory',
            'namespace' => 'Subcategory\controllers',
            'controller' => 'Subcategory',
            'os' => 1,
            'subcategory' => 3,
            'category' => 2,
            'action' => 'index',
            'page' => 4
        )
    )->convert('page', function($page) {
          if (!is_int($page)) return 1;
    });

The problem that I have is that if I use {page} instead of regex [0-9+] in category route, the app follows the category route and sets page = 1, so I'm not able to use that, therefore getting into the other issue caused by default value of page param which is the param index number from the URL, in my case 3. I think this could be avoided if the parser would return null instead of param index.

I hope this makes sense :)