Routing - change url during submission

Hello i am new to CakePhp routes. I have the following url at index
/controller/action/
when do submit a search it change to /controller/action?parm1=value1
when visit page 2 it change to /controller/action/page:2?parm1=value1

When i try to do another search i get error message

Not Found

The requested address ‘/controller/action/page:2?url=controller%2Faction%2Fpage%3A2&param1=value1’ was not found on this server.

how do i resolve this error please.

Page 2 should not result in

/controller/action/page:2?parm1=value1

but instead in

/controller/action/?parm1=value1&page=2

Thats the default behavior of CakePHPs paginator.

What kind of search form are you using?

I can highly recommend you build your search logic and forms via GitHub - FriendsOfCake/search: CakePHP: Easy model searching

You are correct, here is my controller logic

$controller->paginate = array(
‘limit’ => 15,
‘conditions’ => $conditions
);

    $results = $controller->Paginate('model');     
    return $results;

How do i make it look this way
/controller/action/?parm1=value1&page=2

I am using default route

can anyone help me to change

/controller/action/page:2?parm1=value1
to
/controller/action/?parm1=value1&page=2

Again: Your current behavior of having

/controller/action/page:2?parm1=value1

instead of

/controller/action/?parm1=value1&page=2

is NOT CakePHP’s default behavior. See CakePHP 4 Tutorial 2022 - Going through the Code (Part 4) - YouTube

You must have some custom code which changes CakePHP’s default paginator behavior.

Without telling us what custom code/config you have we can’t help you with how to fix that.

How about we start with the basics:

  • Which CakePHP version are you using?
  • What does your index method (or whatever you using to paginate a query) look like?
  • How do you output the table including the paginator links in your template?

I use CakePHP 2.8 version
below is my index and private method

public function index()
{
	$this->_loadModels(array('Users'));
	$this->Users->recursive = 1;

   //Pagination Settings
	$this->_initPaginator($conditions);
    
    //Search Vairables -> (array) of usersFound and (boolean) error notFound
	$usersFound = array();
	$notFound = false;

	if ((count($conditions) > 1) || count($conditions['OR'])) {

		try {
		    $usersFound = $this->Paginator->paginate('Users');
		} catch (Exception $e) {

			//May be the requested page is out of range
			$notFound = true;

		}//[End] try-catch

	}//[End] if
	$paginationData = $this->request->params['paging']['Users'];

    $this->set(compact('usersFound', 'notFound', 'paginationData'));

}

protected function _initPaginator($conditions = array())
{
	$this->Paginator->settings = array('limit' => 10, 'conditions' => $conditions);

	$this->Paginator->settings['page'] = !empty($this->request->query['page']) ? 
	                                       (int) $this->request->query['page'] : 1;

}

Paginator template:

<div class="paging">
    <ul class="pagination">
    <li><span><?php echo $this->Paginator->counter(array('format' => __('PAGE {:page} of {:pages}'))); ?></span></li>

    <?php if ($this->Paginator->hasNext): ?>
    <li><?php echo $this->Paginator->prev('<i class="fa fa-angle-left"></i>', array('escape' => false, 'tag' => false, 'class' => 'pagination-link'), null, array('class' => 'disabled')); ?></li>
    <?php endif; ?>

    <?php echo $this->Paginator->numbers(array('separator' => '', 'escape' => false, 'tag' => 'li', 'class' => 'pagination-link', 'currentClass' => 'active', 'currentTag' => 'span')); ?>

    <?php if ($this->Paginator->hasNext): ?>
    <li><?php echo $this->Paginator->next('<i class="fa fa-angle-right"></i>', array('escape' => false, 'tag' => false, 'class' => 'pagination-link'), null, array('class' => 'disabled')); ?></li>
    <?php endif; ?>

    </ul>
</div>

Well… I expected you were on a somewhat recent CakePHP Version but 2.8 is not what I expected.

In CakePHP 2 the Paginator links indeed looked like what you are showing us as you can see here:

I am just not used to those Links because I started with CakePHP 3.5 in 2017

BUT you can adjust that behavior via adding a bit of configuration as you can see here:
https://book.cakephp.org/2/en/core-libraries/components/pagination.html#pagination-with-get-parameters

So try to add

$this->Paginator->settings['paramType'] = 'querystring';

To your _initPaginator method and try again

Thanks for your choice to help. I have been trying to upgrade the code to the latest but it is a long standing, large project.

If you do not mind, I may have to contact you for support once we start the upgrading process next month. You can share your contact please if interested to help

Thanks

Sorry, but I am not available as a upgrade service.
I only like to help other developers understand how CakePHP works.

So if you need a CakePHP upgrade service I would rather recommend you get in touch with CakeDC

However, this is working fine now when you submit the search and move through the pages. I got the error when i try to resubmit another search which i expect a new clean query to be submitted rather it did not get the address bar clean but send back the /controller/action/page:2?parm1=value1 link to my index controller.

How can i submit a clean query without the “page:2”

I am also just looking through the documentation but my guess is that you will need this as well

So try adding

$this->Paginator->options(array(
  'convertKeys' => array('page')
));

in your template before you output the paginator as well.

Hi
Thanks for your support so far. I have started the upgrading of the project. I run into route errors now.

My route.php looks this way

return static function (RouteBuilder $routes) {
$routes->setRouteClass(DashedRoute::class);

$routes->scope('/', function (RouteBuilder $builder) {
   
    $builder->connect('/', ['controller' => 'Index', 'action' => 'index', 'index']);

    $builder->connect('/login', ['controller' => 'Login', 'action' => 'index']);

    $builder->connect('/pages/*', 'Pages::display');

    $builder->fallbacks(DashedRoute::class);
});


/**
 * Route to membership management controls
 */

$routes->prefix('membership', function ($routes) {
    $routes->connect('/', ['controller' => 'Members', 'action' => 'index']);
    $routes->setExtensions(['json']);
    $routes->fallbacks(DashedRoute::class);
});

$routes->prefix('accountsetup', function ($routes) {
    $routes->connect('/', ['controller' => 'Index', 'action' => 'index']);
    $routes->setExtensions(['json']);
    $routes->fallbacks(DashedRoute::class);
});


/**
 * RESTful
 */

$routes->scope('/api', function (RouteBuilder $routes) {
    $routes->resources('Accountsetup', function (RouteBuilder $routes) {
        $routes->resources('Comments', ['prefix' => 'Articles']);
    });
});

$routes->scope('/items/ajaxFetchItemOrders', function ($routes) {
    // $routes->extensions(['json', 'xml']);
    $routes->connect(
        '/:productid',
        ['controller' => 'Items', 'action' => 'ajaxFetchItemOrders'],
        [
            'pass' => ['productid']
        ]
    );
});

    $builder->fallbacks();
});

};

What am i missing here.

Are you calling a UrlHelper method with a URL array including 'controller' => 'members' instead of 'controller' => 'Members'?

[Zuluru] Thanks a lots. Your suggestion saved me a lots of days.