Forms manager mentioned in docs but no info on how to use

I have just read a section in the docs about 'Phalcon\Forms\Manager' which seems to suggest that you can create forms that can be called universally. However, there is no mention of how to use it in the docs! Such as, what file to put the forms in, and where the file should be stored - is it a class or a view file? Could someone explain it to me please.



11.0k
edited May '14

Yes I read that. It doesn't explain a whole heap! I am looking through vokuro to see if it's implemented there as the docs suggest, and it kind of is, but it seems to be implemented in a way that differs a great deal from the docs... which just confuses matters.

I have created a class for the login form in userLoginForm.php. I have registered a namespace for my forms directory in Common\Forms. Now the docs say...

$di['forms'] = function() {
return new Phalcon\Forms\Manager();
};

It doesn't say, but I'm guessing that could go in the bootstrap? Then...

$this->forms->set('login', new LoginForm());

No idea where I use that - maybe in the controller?. And then...

echo $this->forms->get('login')->render();

Again not too clear where this goes - perhaps in the view file?

Some explaination would be very appriciated! :)

Hi there,

I'm using Form Manager like in Vokuro app.

I have a forms directory (namespace App\Forms) in application dir where I store all forms used in application. I have no registered service. I create instance of form in controller and set as view variable:

namespace App\Controllers;
use App\Forms\RegisterForm;

class RegisterController extends ControllerBase
{

    public function indexAction()
    {
        $form = new RegisterForm();
        if ($this->request->isPost()) {
            if ($form->isValid($this->request->getPost())) {
                try {
                    $user = $this->auth->check($this->request->getPost());
                    if ($user) {
                        $this->flashSession->success(_('You have been logged'));
                    } else {
                        $this->flashSession->error(_('Incorrect login information'));
                    }
                } catch(\Exception $e) {
                    $this->flashSession->error(_($e->getMessage()));
                    return $this->response->redirect('/login');
                }
            } else {
                foreach ($form->getMessages() as $msg) {
                    $this->flashSession->error(_($msg->getMessage()));
                    break; // return only first error
                }
            }
            return $this->response->redirect('/');
        }
        $this->view->form = $form;
    }

}

Form Class example:

<?php

namespace App\Forms;

use Phalcon\Forms\Element\Text,
    Phalcon\Forms\Element\Password,
    Phalcon\Forms\Element\Submit,
    Phalcon\Forms\Element\Check,
    Phalcon\Forms\Element\Hidden,
    Phalcon\Validation\Validator\PresenceOf,
    Phalcon\Validation\Validator\Email,
    Phalcon\Validation\Validator\Identical;

/**
 * Class RegisterForm
 * @package App\Forms
 */
class RegisterForm extends BaseForm
{
    public function initialize()
    {
        $email = new Text('email');
        $email->setLabel(_('Email'));
        $email->addValidators(array(
            new PresenceOf(array(
                'message' => _('Email is required')
            )),
            new Email(array(
                'message' => _('Email is incorrect')
            ))
        ));

        $this->add($email);


        // Password
        $password = new Password('password');
        $password->setLabel(_('Password'));
        $password->addValidator(
            new PresenceOf(array(
                'message' => _('Password is required')
            ))
        );

        $this->add($password);

        // CSRF
        $csrf = new Hidden('csrf');
        $csrf->addValidator(
            new Identical(array(
                'value' => $this->security->getSessionToken(),
                'message' => _('CSRF validation failed')
            ))
        );

        $this->add($csrf);

        $this->add(new Submit('submit', array(
            'value' => _('Register')
        )));
    }
}

View template:

    {{ form('/login') }}
        <div class="popup-header">
            <a href="{{ url('/register') }}" class="pull-left"><i class="icon-user-plus"></i></a>
            <span class="text-semibold">{{ _('Login') }}</span>
            <div class="pull-right">
                <span style="display: block; width: 40px; height: 40px;"></span>
            </div>
        </div>
        <div class="well">
            <div class="form-group has-feedback">
                <label>{{ form.getLabel('email') }}</label>
                <input type="text" name="email" class="form-control" placeholder="{{ _('Email') }}">
                <i class="icon-users form-control-feedback"></i>
            </div>

            <div class="form-group has-feedback">
                <label>{{ form.getLabel('password') }}</label>
                <input type="password" name="password" class="form-control" placeholder="{{ _('Password') }}">
                <i class="icon-lock form-control-feedback"></i>
            </div>

            <div class="row form-actions">
                <div class="col-xs-6">
                </div>

                <div class="col-xs-6">
                    <button type="submit" class="btn btn-warning pull-right"><i class="icon-menu2"></i> {{ _('Sign in') }}</button>
                </div>
            </div>
        </div>
    {{ endform() }}

Attention:

form("/login") is default alias for \Phalcon\Tag::form (http://docs.phalconphp.com/en/latest/api/Phalcon%5Tag.html).

form.render("email") is call for RegisterForm::render("email"). form is a view variable name in this case.



11.0k

Hi Marcin, Thanks for your reply. I follow that, and appriciate the "heads up" on the reserved names, and will probably use that method, but I'm trying to get my head around the method as stated in the docs which is very different to Vokuro method (which doesn't follow the docs at all). I'm trying to learn Phalcon while I port a project, and if I keep reading stuff in the docs that glosses over a method without explaining it, and then view examples that don't correlate to the method in the docs, it makes things very confusing :) Can you explain the documented method please?

I prepared simple application which uses Forms Manager. You should create app/cache directory with chmod 777 to work. Link: https://github.com/czepol/phalcon-forms-manager-example



11.0k

Hi Marcin, Thanks a lot for taking the time to demonstrate this. I finaly got it working! I had to do it slightly differently as I'm using multi modules and namespaces. I also used a loop to generate the form elements.

$form = $this->forms->get('loginForm');
foreach($form as $fm){
    echo $fm->render();
}

If you wrote the docs, things would be much more clear ;-)



5.4k
edited May '14

Yes, I never worked with the Forms Manager, but it just looks like a simple store.

Some things in the docs are a bit briefly described, but I guess if you've already gained a bit of experience with Phalcon, have grasped some concepts, how the DI functions, etc, some things in the docs will be/get more clear to you.

Nowadays you can have a look at the 2.0 Zephir code, which is not too hard to follow: https://github.com/phalcon/cphalcon/blob/2.0.0/phalcon/forms/manager.zep

(But please note that it might be incomplete: https://github.com/phalcon/cphalcon/wiki/Progress-2.0 )