Small ORM forms

From small iceberg
Revision as of 11:33, 29 October 2021 by Seb (talk | contribs) (→‎Repository)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

What is Small ORM forms ?[edit]

Small ORM forms is a package to help data validation and model update.

It's not a html generator and priority is done to work for api applications.

Repository[edit]

The source code is available on GitHub : https://github.com/sebk69/small-orm-forms

The core package of Small ORM is required : https://github.com/sebk69/small-orm-core

Creating a simple form[edit]

Here is a login form class :

namespace Sebk\SmallSwoftAuth\Service\Form;

use Sebk\SmallOrmForms\Form\AbstractForm;
use Sebk\SmallOrmForms\Form\Field;

class LoginForm extends AbstractForm
{
    public function __construct($account, $password)
    {
        $this->addField('account', null, $account, null, Field::MANDATORY);
        $this->addField('password', null, $password, null, Field::MANDATORY);
    }
}

All forms must extends AbstractForm class.

Here we initialize form in constructor, and the new form will have two fields :

  • The account
  • The password

Form validation[edit]

To validate the form, just call the validate method :

            // Check input
            $form = new LoginForm('my-user', 'my-password');
            $messages = $form->validate();
            if (count($messages) > 0) {
                // Validation failed
                return ['success' => false, "messages' => $messages];
            }
            return ['success' => true];

In this example, the validation will check : - The values are string compatible (a int type is compatible with a string for example) - The fields are not empty (null or empty string) because we have specified in LoginForm constructor that the fields are mandatory

If password is an empty string, they will be a message 'The password field is mandatory'.

FormModel class[edit]

Create a form from DAO[edit]

It's good but, it's a lot of code for a little validation. But now, come the FormModel class.

This class allow you to generate a form automatically from a DAO :


use Sebk\SmallOrmForms\Form\FormModel;

/**
 * @Controller("address")
 */
class FormController
{
    use DaoFactory;

    protected function createForm(): FormModel
    {
        return (new FormModel())
            ->buildFromDao($this->daoFactory->get("CommandeBundle", "Address"))
        ;
    }
}

Here the form is created directly from DAO data : fields, types...

Add mandatory fields[edit]

Only the mandatory are not managed. Here is an example to set madatory fields :

/**
 * @Controller("address")
 */
class FormController
{
    use DaoFactory;

    protected function createForm(): FormModel
    {
        return (new FormModel())
            ->buildFromDao($this->daoFactory->get("CommandeBundle", "Address"))
            ->setFieldMandatory("idClient")
            ->setFieldMandatory("firstName")
            ->setFieldMandatory("lastName")
            ->setFieldMandatory("address")
            ->setFieldMandatory("zipCode")
            ->setFieldMandatory("city")
            ->setFieldMandatory("country")
        ;
    }
}

Consequences on form validation[edit]

The the validation of form will do two things :

  • Validate format and mandatory of fields
  • Call the validator of the Model ($model->getValidator()->validate())

Inject data in form[edit]

You can now inject directly array of data to fill form :

        // Form validation
        $form = $this->createForm()
            ->fillFromArray(json_decode($request->getParsedBody(), true))
        ;
        $messages = $form->validate();

Inject a model in form[edit]

You can also inject a model in the form :

       /** @var Address $model */
       $model = $this->daoFactory->get("OrderBundle", "Address")->findOneBy(["id" => $id]);
       
        // Form validation
        $form = $this->createForm()
            ->fillFromModel($model)
        ;
        $messages = $form->validate();

The final process for an update for example will be to load model in the form, and then load xhr data to update it :

        /** @var Address $model */
        $model = $this->daoFactory->get("OrderBundle", "Address")->findOneBy(["id" => $id]);
        
        $data = json_decode($request->getParsedBody(), true);
        if (isset($data["id"])) {
            unset($data["id"]);
        }

        // Form validation
        $form = $this->createForm()
            ->fillFromModel($model)
            ->fillFromArray($data)
        ;
        $messages = $form->validate();

Generate model from form[edit]

Now the last thing to achieve the update process is to persist data. Just get model with 'fillModel' method and call 'persist' method :

        $model = $form->fillModel();
        $model->persist();