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

Call to a member function getLabel() on a non-object

Hello,

I have the following files:

  • views/register.phtml view for a registration page
  • forms/RegisterForm.php for the registration form on the registration page
  • controllers/SessionController.php with a RegisterAction()
  • models/Users.php model for database interaction.

The Users.php model contains a Uniqueness Validator for username and email, so users can't add duplicate records. Everything is working perfectly fine, the form is displayed correctly, labels are displayed, when someone submits the registration form, the record gets added to the database, however, when i try to add a record that already exists, it gives me "Fatal error: Call to a member function getLabel() on a non-object in C:\wamp\www\test.local\app\views\session\register.phtml on line 11" instead of getting an error message from the Uniqueness validator in the model. The same thing happens with everything else, everytime an interaction with the database fails (e.g. adding/removing/querying), it breaks the form and gives me "Fatal error: Call to a member function getLabel() on a non-object".

I'm not really sure where to start from here, does anyone know what i might be doing wrong?



2.0k

Hello, I think registerAction() works not correct. Please, show a code of the method.



3.8k
edited Nov '15

Here's my code:

registerAction() in controllers/SessionController.php

public function registerAction() {
        $form = new RegisterForm();

        if ($this->request->isPost()) {
            if ($this->security->checkToken()) {
                if ($form->isValid($_POST)) {

                        $user = new Users;
                        $user->username =   $this->request->getPost('username');
                        $user->email =      $this->request->getPost('email');
                        $user->password =   $this->security->hash($this->request->getPost('password'));
                        $user->created_at = time();

                        $user->create();

                }
                else
                {       
                    echo $form->getMessages()[0];
                }
            }
        }
        $this->view->form = $form;
}

models/User.php Model:

use Phalcon\Mvc\Model\Validator\Uniqueness;

class Users extends Phalcon\Mvc\Model
{

    public function validation()
    {

        $this->validate(new Uniqueness(array(
            'field' => 'email',
            "message" => "Value of field 'email' is already present in another record"
        )));

        $this->validate(new Uniqueness(array(
            'field' => 'username',
            "message" => "Value of field 'username' is already present in another record"

        )));

        if ($this->validationHasFailed() == true) {
            return false;
        }
    }

    public function initialize() {

        $this->skipAttributesOnCreate(array('status'));
    }
}

views/session/register.phtml

<?=$this->getContent();?>

<?php use Phalcon\Tag; ?>

<h1 class="main_heading">Create a new Account!</h1>

<div class="form">
    <form action="register" method="post">
        <p>
            <label for="username"><?=$form->getLabel('username');?></label>
            <?=$form->render('username');?>
        </p>
        <p>
            <label for="email"><?=$form->getLabel('email');?></label>
            <?=$form->render('email');?>
        </p>
        <p>
            <label for="email"><?=$form->getLabel('password');?></label>
            <?=$form->render('password');?>
        </p>
        <p>
            <input type="submit" value="Register" name="submit">
        </p>
        <input type="hidden" name="<?php echo $this->security->getTokenKey() ?>" value="<?php echo $this->security->getToken() ?>"/>
    </form>
</div>

forms/RegisterForm.php

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

class RegisterForm extends Form
{

    public function initialize()
    {

        /**
         *  Validate Username
         */

        $username = new Text('username', array(
            'placeholder' => 'Username'
        ));

        $username->setLabel('Username');

        $username->addValidators(array(
            new PresenceOf(array(
                'message' => 'Please enter a username.'
            )),
            new Regex(array(
                'pattern' => '/^[A-Za-z][A-Za-z0-9]*(?:_[A-Za-z0-9]+)*$/',
                'message' => 'Only letters, numbers and underscores allowed in the username'
            )),
            new StringLength(array(
              'max' => 16,
              'min' => 4,
              'messageMaximum' => 'Username too long. Max. 16 characters allowed.',
              'messageMinimum' => 'The username is too short. Please enter at least 4 characters.'
        ))
        ));

        $this->add($username);

        /**
         *  Validate E-Mail Address
         */

        $email = new Text('email', array(
            'placeholder' => 'Email'
        ));
        $email->setLabel('E-Mail');

        $email->addValidators(array(
            new PresenceOf(array(
                'message' => 'Please enter an email address.'
            )),
            new Email(array(
                'message' => 'Please enter a valid email address.'
            ))
        ));

        $this->add($email);

        /**
         *  Validate Password
         */

        $password = new Text('password', array(
            'placeholder' => 'Password'
        ));

        $password->setLabel('Password');

        $password->addValidators(array(
            new PresenceOf(array(
                'message' => 'You did not enter a password.'
            )),
            new StringLength(array(
              'max' => 40,
              'min' => 4,
              'messageMaximum' => 'The password must be max 40 characters.',
              'messageMinimum' => 'The password must be at least 4 characters.'
        ))
        ));

        $this->add($password);

    }
}


2.0k

Try to add Uniquiness validator in the form.


use Phalcon\Validation\Validator\Uniqueness;

...

new Uniqueness(array(
      'field' => 'email',
      'model' => Users::class,
      'message' => $email->getLabel() . ' is not unique.'
));

...

new Uniqueness(array(
      'field' => 'username',
      'model' => Users::class,
      'message' => $username->getLabel() . ' is not unique.'
));

Display form errors in the template

<?=$this->getContent();?>

<?php use Phalcon\Tag; ?>

<h1 class="main_heading">Create a new Account!</h1>

<div class="form">
    <form action="register" method="post">
        <p>
            <label for="username"><?=$form->getLabel('username');?></label>
            <?=$form->render('username');?>
            <?php if ($form->hasMessagesFor('username')): ?>
                <?=$form->getMessagesFor('username')[0];?>
            <?php endif; ?>
        </p>
        <p>
            <label for="email"><?=$form->getLabel('email');?></label>
            <?=$form->render('email');?>
            <?php if ($form->hasMessagesFor('email')): ?>
                <?=$form->getMessagesFor('email')[0];?>
            <?php endif; ?>
        </p>
        <p>
            <label for="email"><?=$form->getLabel('password');?></label>
            <?=$form->render('password');?>
            <?php if ($form->hasMessagesFor('password')): ?>
                <?=$form->getMessagesFor('password')[0];?>
            <?php endif; ?>
        </p>
        <p>
            <input type="submit" value="Register" name="submit">
        </p>
        <input type="hidden" name="<?php echo $this->security->getTokenKey() ?>" value="<?php echo $this->security->getToken() ?>"/>
    </form>
</div>
public function registerAction() {
        $form = new RegisterForm();

        if ($this->request->isPost()) {
            if ($this->security->checkToken()) {
                if ($form->isValid($_POST)) {

                        $user = new Users;
                        $user->username =    $this->request->getPost('username');
                        $user->email =       $this->request->getPost('email');
                        $user->password =    $this->security->hash($this->request->getPost('password'));
                        $user->created_at =  time();

                        $user->create();

                }
                else
                {     
                    //echo $form->getMessages()[0]; 
                }
            }
        }

        $this->view->form = $form;
}
use Phalcon\Mvc\Model\Validator\Uniqueness;

class Users extends Phalcon\Mvc\Model
{

    public function validation()
    {

        $this->validate(new Uniqueness(array(
            'field' => 'email',
            "message" => "Value of field 'email' is already present in another record"
        )));

        $this->validate(new Uniqueness(array(
            'field' => 'username',
            "message" => "Value of field 'username' is already present in another record"

        )));

        // I think the problem is there
        /*if ($this->validationHasFailed() == true) {
            return false;
        }*/

        return $this->validationHasFailed() != true;
    }

    public function initialize() {

        $this->skipAttributesOnCreate(array('status'));
    }
}


3.8k
edited Nov '15

Tried everything of that. I'm always getting

Fatal error: Call to a member function getLabel() on a non-object in C:\wamp\www\test.local\app\views\session\register.phtml on line 11

if there is a duplicate or other error with the db



2.0k
edited Nov '15

Try to use $this->form in the template.

<label for="username"><?=$this->form->getLabel('username');?></label>
<?=$this->form->render('username');?>
<?php if ($this->form->hasMessagesFor('username')): ?>
<?=$this->form->getMessagesFor('username')[0];?>
<?php endif; ?>

and so on



3.8k

Using $this->form breaks the page completely, and i'm getting "Call to a member function getLabel() on a non-object" without submitting the form already

Try to skip or comment $this->form->getLabel('username');

<label for="username">Username</label>
<?=$this->form->render('username');?>
<?php if ($this->form->hasMessagesFor('username')): ?>
<?=$this->form->getMessagesFor('username')[0];?>
<?php endif; ?>

What is error said now?



3.8k
edited Nov '15

When i remove all the $form-> variables from the register view and add a record that already exists, it just reloads the page, the error messages from the registerAction() are not triggered, but they should, this only happens if the record already exists in the database or if database connection fails, im not really sure where to go from here.

It is the $user->create(); in registerAction that is causing this, everytime this fails, it breaks the whole action and nothing is executed and it breaks the form on register view saying "Fatal error: Call to a member function getLabel() on a non-object in C:\wamp\www\test.local\app\views\session\register.phtml on line 11"

Here is my registerAction again with some comments

    public function signupAction() {
        $form = new RegisterForm();

        if ($this->request->isPost()) {
            if ($this->security->checkToken()) {
                if ($form->isValid($_POST)) {

                        $user = new Users;
                        $user->username =   $this->request->getPost('username');
                        $user->email =      $this->request->getPost('email');
                        $user->password =   $this->security->hash($this->request->getPost('password'));
                        $user->created_at = time();

                        if ($user->create()) {
                            echo 'success';
                        }

                        echo 'dead'; // not executed if $user->create() fails, but it should

                }
                else
                {
                    echo $form->getMessages()[0];
                }
            }
        }
        $this->view->form = $form;  // not executed if $user->create() fails (= breaks registration form)
    }