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

$form->isValid() is saving my data

When I use isValid() method to validate a Form linked to an entity of a model, then that entity is saved. Why?

I commented the lines "if (!$user->save()) {}" to chek if it was because of that. But I confirmed that was because of using isValid() method.

¿What am I doing wrong?

  $user = $this->getUser();
  $form = new ProfileForm($user, ['edit' => true]);
  $this->view->form = $form;
  if ($this->request->isPost()) {
        if ($form->isValid($this->request->getPost()) == false) {
            foreach ($form->getMessages() as $message) {
                $this->flashSession->error($message);
            }
        }
        else {
            $user->assign([
                'name' => $this->request->getPost('name', ['striptags','trim']),
                    'email' => $this->request->getPost('email', 'email')
            ]);
            // if (!$user->save()) {
            //  $this->flashSession->error($user->getMessages());
            // } else {
            //  $this->flashSession->success("User updated");
            //  Tag::resetInput();
            // }
        }
    }

Can you show ProfileForm class?



3.9k

Yes, it's so simple:

namespace MyApp\Modules\Admin\Forms;

use Phalcon\Forms\Form;
use Phalcon\Forms\Element\Text;
use Phalcon\Validation\Validator\PresenceOf;
use Phalcon\Validation\Validator\Email;

class ProfileForm extends Form
{

    public function initialize()
    {

        $name = new Text('name',[
            'class'=>'form-control',
            'placeholder' => 'Full name'
        ]);
        $name->addValidators([
            new PresenceOf([
                'message' => 'Full name is required'
            ])
        ]);
        $this->add($name);

        $email = new Text('email', [
            'class'=>'form-control',
            'placeholder' => 'Email'
        ]);
        $email->addValidators([
            new PresenceOf([
                'message' => 'Email is required'
            ]),
            new Email([
                'message' => 'Email is not valid'
            ])
        ]);
        $this->add($email);
    }
}

I noticed that you pass entity and options to ProfileForm constructor, but forgot to declare them ininitialize() method

$form = new ProfileForm($user, ['edit' => true]);

This:

public function initialize()

Need to be changed to:

public function initialize($entity = null, $options = null)


3.9k
edited Nov '19

OK, I've done it like that. But the issue is still there.

This is my Model (User)

<?php
namespace MyApp\Models;

use Phalcon\Mvc\Model\Validator\Email as Email;
use Phalcon\Validation;
use Phalcon\Validation\Validator\Uniqueness;

class User extends \Phalcon\Mvc\Model
{

    /**
     *
     * @var string
     * @Primary
     * @Identity
     * @Column(type="string", length=20, nullable=false)
     */
    public $id;

    /**
     *
     * @var string
     * @Column(type="string", length=100, nullable=false)
     */
    public $email;

    /**
     * Initialize method for model.
     */
    public function initialize()
    {
        $this->hasMany('id', __NAMESPACE__ . '\UserMeta', 'user_id', ['alias' => 'userMeta']]);
    }

    /**
     * Returns table name mapped in the model.
     *
     * @return string
     */
    public function getSource()
    {
        return 'user';
    }

    /**
     * Allows to query a set of records that match the specified conditions
     *
     * @param mixed $parameters
     * @return User[]
     */
    public static function find($parameters = null)
    {
        return parent::find($parameters);
    }

    /**
     * Allows to query the first record that match the specified conditions
     *
     * @param mixed $parameters
     * @return User
     */
    public static function findFirst($parameters = null)
    {
        return parent::findFirst($parameters);
    }

    /**
     * Validate that emails/usernames are unique across users
     */
    public function validation()
    {
        $validator = new Validation();

        $validator->add('email', new Uniqueness([
            "message" => "Este email ya está registrado"
        ]));

        return $this->validate($validator);
    }

    /**
     * Return the metadata value for the key
     *
     * @param $key
     * @return string
     */
    public function getMeta($key)
    {
        if($this->getUserMeta(["key = '" . $key . "'"])->count())
            return $this->getUserMeta(["key = '" . $key . "'"])->getFirst()->value;
        else
            return false;
    }

    /**
     * Set the metadata value for the key
     *
     * @param $key
     * @param $value
     */
    public function setMeta($key, $value)
    {
        $userMeta = new UserMeta();

        // Comprobamos si existe ese Meta con ese Key en la base de datos
        if($current = $userMeta->findFirst(["user_id=$this->id and key='$key'"]))
            // Actuamos sobre el meta que ya existe
            $userMeta->id = $current->id;

        // Si pasamos un valor, lo guardamos
        if(!empty($value)) {
            $userMeta->user_id = $this->id;
            $userMeta->key = $key;
            $userMeta->value = $value;
            if($userMeta->save()===false) {
                foreach ($userMeta->getMessages() as $message) {
                    $this->getDI()
                        ->getFlashSession()
                        ->error($message);
                }
                return false;
            }
            return true;
        }
        // Si no pasamos un valor, borramos el meta
        else {
            if($current) {
                if($userMeta->delete()===false) {
                    foreach ($userMeta->getMessages() as $message) {
                        $this->getDI()
                            ->getFlashSession()
                            ->error($message);
                    }
                    return false;
                }
            }
            return true;
        }
    }

    public function getName() {
        return $this->getMeta("name");
    }
    public function setName($value) {
        $this->setMeta("name", $value);
    }
}

What version of Phalcon do you have?



3.9k

Phalcon 3.2.3

Can you update to latest 3.4.5?



3.9k

I can't. I have MAMP, and the instal processl is not working for me (don't know why) I had to download a pre-installed version of Phalcon 3.4.0 (from https://github.com/majksner/php-phalcon-mamp)

So, again, I've tried with Phalcon 3.4.0 and the problem persists

What do you have inside getUser() method $user = $this->getUser(); ?



3.9k

It's a method inside the ControllerBase:

    public function getUser() {
        $user = User::findFirstById($this->auth->getId());

        if (!$user) {
            $this->flashSession->error(__("User not found"));
            return $this->response->redirect('auth/session/login');
        }

        return $user;
    }

and getId() is from an Auth Library:

    public function getId()
    {
        $identity = $this->session->get('auth-identity');
        return $identity['id'];
    }

So, by submitting the form, DB entry will be updated? In that case, columns like "name" and "email". Am I correct?



3.9k

Yes, you're right. It's an update to an entry to the database

I've installed Phalcon 3.4.5 at last. But the problem persists

edited May '20

This is really amazing. Great information about blog.

I'm trying to add the same code in my web pages. You can see here. But it's not working anymore.

Show mode is damaged. It would not update whilst you flow items like this. You have to transfer to a exceptional mode then returned once more to force it to rerender.