0

I try to log if user type wrong url parameter for a route with

'constraints' => array('personalnumber' => '[0-9]*')

$error  = $e->getError();

if ($error == Application::ERROR_ROUTER_NO_MATCH) {
    $url = $e->getRequest()->getUriString();
    $sm->get('Zend\Log\RouteLogger')->warn('Url could not match to routing: ' . $url);
}

Can I get a specific error like: Value for Parameter "id" must type integer?

Ankh
  • 5,478
  • 3
  • 36
  • 40
stefen
  • 39
  • 6

1 Answers1

0

That won't be so easy. You would have to build your own functionality to find out the exact details on why the route didn't match.

Route matching is checked using the RouteInterface::match method from the corresponding class. For example for segment routes this method can be found in the Zend\Router\Http\Segment class on line 359-404.

If there is no match, the class returns null/void. Details on why the route didn't match is not part of the response, so you would have to do such in depth analysis yourself and write your own custom error response.


Such a solution could be to do manually validate the person number (for example by isolating it from the request url) when the dispatch error event is triggered and return your own custom response before the default 404 response.

<?php

namespace Application;

use Zend\Http\Response;
use Zend\Mvc\MvcEvent;
use Zend\Router\Http\RouteMatch;

class Module{

    public function onBootstrap(MvcEvent $event)
    {    
        $eventManager = $event->getApplication()->getEventManager();
        $eventManager->attach(MvcEvent::EVENT_DISPATCH_ERROR, array($this, 'validatePersonNumber'), 1000);
    }


    public function validatePersonNumber(MvcEvent $event)
    {
        if ($event->getError() !== Application::ERROR_ROUTER_NO_MATCH) {
            // Not a 404 error
            return;
        }

        $request = $event->getRequest();
         $controller = $event->getController();
        if($controller !== 'Application\Expected\ControllerName'){
            // not a controller for person number route
            return;
        }
        $url = $request->getRequestUri();
        $personNumber = ''; //...manually isolate the person number from the request...

        /** @var Response $response */
        $response = $event->getResponse();
        $response->setStatusCode(404);
        $viewModel = $event->getViewModel();
        $viewModel->setTemplate('error/404');
        $event->setViewModel($viewModel);
        $event->stopPropagation(true);

        if (strlen($personNumber) !== 12) {
            $viewModel->setVariable('message', 'A person number should have 12 characters');
        }
        if(...additional check...){
            $viewModel->setVariable('message', 'Some other message');
        }
    }
}

To make things prettier you could consider moving all this into a Listener class (instead of polluting your module.php file) and you could also consider the 404 code here. Most likely there is a more suitable status code for such validation response.

Note: This is not a completely finished example, it needs more work!

Wilt
  • 41,477
  • 12
  • 152
  • 203
  • Nice idear, but $event->getController()); is null. – stefen Mar 17 '17 at 14:17
  • Thank you :) This is not soo importent if its not supported but I have another problem with ZF2, may you can help me: http://stackoverflow.com/questions/42859322/zend-2-sqlsrv-prepareparams-not-setted – stefen Mar 17 '17 at 15:45