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

Controller not registering a variable

I am experiencing something probably very stupid and I hope easily solveable.

Here is the code: https://pastebin.com/KsCynBis

When I edit an object, and when I write a description shorter than 300 characters on purpose, after I try to save it , I get error like this :

Warning: Missing argument 1 for ObjectsController::editAction()

I am probably sending the $id variable in a wrong way, but which is right? Thanks in advance :)



17.0k

I have solved it by removing if (!$request->isPost()) { , but if someone could explain me the logics behind it i would be grateful :)



19.2k
Accepted
answer

solved it by removing if (!$request->isPost()) {

Well, that's because there was no closing curlybracket) It looks to me that you are using INVO app as your base. Your problem Warning: Missing argument 1 for ObjectsController::editAction() was caused by that method of ControllerBase class, from INVO app (I guess):

protected function forward($uri)
{
    $uriParts = explode('/', $uri);
    return $this->dispatcher->forward(
        array(
            'controller' => $uriParts[0], 
            'action' => $uriParts[1]
        )
    );
}

In your code you tried to pass $id param to editAction and, as you can see from above, it never got there...

return $this->forward("objects/edit/".$id);

I fixed a couple of things for you, give it a try ;)

public function editAction($id)
{
    if ($this->request->isGet()) {
        $id = $this->filter->sanitize($id, 'int');

        /** You can pass id directly to findFirst($id) or use magic method like findFirstById($id) */
        $object = Objects::findFirst($id);

        if (!$object) {
            $this->flash->error('Object was not found!');

            return $this->forward('objects/index');
        }
        /** You don't need those second Var, as you can get it from $object->id in view. */
        $this->view->setVar('object', $object);
    }
}

public function saveAction()
{
    if (!$this->request->isPost()) {

        return $this->forward('objects/index');
    }

    $id = $this->request->getPost('id', 'int');
    $object = Objects::findFirst($id);

    if (!$object) {
        $this->flash->error('Object does not exist!');

        return $this->forward('objects/index');
    }

    $description = $this->request->getPost('description', 'striptags');

    if (strlen($description) < 300) {
        $this->flash->error('<b>Too short description!</b> Must be longer than 300 characters.');

        /** From now on it should run as expected, though I'll better use $this->response->redirect() */
        return $this->dispatcher->forward(array(
            'action' => 'edit',
            'params' => array($id)
        ));
    }
}


17.0k

Thank you for your explaination. I did not understood the first part about base controller very best. How come it works then when I use this in volt ?

<td width="12%"><?php echo Tag::linkTo(array("location/edit/".$location->id, '<i class="icon-pencil"></i> Edit', "class" => "btn")) ?></td>



19.2k
protected function forward($uri)
{
    $uriParts = explode('/', $uri);
    return $this->dispatcher->forward(
        array(
            'controller' => $uriParts[0], 
            'action' => $uriParts[1]
        )
    );
}

That method from ControllerBase class you are using, is a "userspace" method, not "Phalcon original". It reads $uri, explodes it by / and passes to dispatcher only first two elements of that $uri (for example, objects/edit), as controller($uriParts[0]) and action($uriParts[1]) respectively. So there's no difference between that: objects/edit or objects/edit/someparam or objects/edit/someparam/andanotherparam - all it passes to $this->dispatcher->forward() is

'controller' => 'objects',
'action'      => 'edit'

But if you use that $this->dispatcher->forward() "Phalcon original" method, you have the flexibility to control what to pass and where:

$this->dispatcher->forward(array(
    'namespace' => 'somenamespace',
    'controller'    => 'somecontroller',
    'action'         => 'someaction',
    'params'       => array(1, 2, 3)
));

For more information about dispatcher, read this article from docs.

And about Tag::linkTo() - all it do is just generating links in Phalcon application. For more information read-the-docs.