Search code examples
phpphp-8

Argument value is not being passed in PHP classes


I have a scenario where I want to create a user using Object Oriented PHP8, I have my users.php page where I have the form and this issue seems to be that I do not think the method from my object form ($objForm) are being passed in correctly to my object validation ($objValidation):

users.php

<?php

use A\B\App\Session;
use A\B\App\Login;
use A\B\App\User;
use A\B\App\Form;
use A\B\App\Validation;

require_once("../../vendor/autoload.php");

$session = new Session();
if(!$session->isLogged()) {
    Login::redirectTo("login");
}



$objForm = new Form();
// passing in the object to validation
$objValidation = new Validation($objForm);
$objUser = new User();

if($objForm->isPost("name")) {

    $objValidation->expected = ["name"];
    $objValidation->required = ["name"];

    $objValidation->special = ["email" => "email"];
    $objValidation->postFormat = ["password" => "password"];

    $email = $objForm->getPost("email");
    $existingUser = $objUser->getUserByEmail($email);
    if($existingUser) {
        $objValidation->addToErrors("user_exists");
    } 

    if($objValidation->isValid()) {
        echo "good";
    } else {
        echo "bad";
    }



}
 
?>

<form action="" method="post">
    
    <p>
        <input type="text" name="name" placeholder="User name" required="">
    </p>
    <?php echo $objValidation->validate('user_exists'); ?>
    <p>
        <input type="email" name="email" placeholder="User email" required="">
    </p>
    <p>
        <input type="password" name="password" placeholder="Password" required="">
    </p>
    <p>
        <input type="submit" name="" value="Add user">
    </p>

</form>

I am simply trying to echo out a yes or no to see if it passes this point so I am not actually calling a method to create a user yet since the code is failing before.

below are my 2 classes:

Form.php

<?php

declare(strict_types = 1);

namespace A\B\App;

class Form
{

    public function isPost(string $field): bool
    {

        if(!empty($field)) {
            if(isset($_POST[$field])) {
                return true;
            }
            return false;
        } else {
            if(!empty($_POST)) {
                return true;
            }
            return false;
        }

    }

    public function getPost(string $field)
    {

        if(!empty($field)) {
            return $this->isPost($field) ? strip_tags($_POST[$field]) : null;
        }

    }

    public function getPostArray(array $field): array
    {

        $out = [];
        if($this->isPost()) {
            foreach($_POST as $key => $value) {
                if(!empty($field)) {
                    if(in_array($key, $expected)) {
                        $out[$key] = strip_tags($value);
                    }
                } else {
                    $out[$key] = strip_tags($value);
                }
            }
        }
        return $out;

    }


}

and here is the validation class:

Validation.php

<?php

declare(strict_types = 1);

namespace A\B\App;

class Validation 
{


    private array $error = [];

    public array $message = ["user_exists" => "This user exists in the Db"];

    public array $expected = [];

    public array $required = [];

    public array $post = [];

    private $objForm;

    public array $test = []; 

    public array $postRemove = [];

    public array $postFormat = [];

    public array $special = []; 

    public function __construct(Form $form)
    {

        $this->objForm = $form;

    }

    public function process()
    {

        if($this->objForm->isPost() && !empty($this->required)) {

            $this->post = $this->objForm->getPostArray($this->expected);
            if(!empty($this->post)) {
                foreach($this->post as $key => $value) {
                    $this->check($key, $value);
                }
            }

        }

    }

    public function check($key, $value)
    {

        if(!empty($this->special) && array_key_exists($key, $this->special)) {
            $this->checkSpecial($key, $value);
        } else {
            if(in_array($key, $this->required) && empty($value)) {
                $this->addToErrors($key);
            }
        }

    }

    public function checkSpecial($key, $value)
    {

        switch($this->special[$key]) {
            case 'email':
            if(!$this->isEmail($value)) {
                $this->addToErrors($key);
            }
            break;
        }

    }

    public function isEmail($email)
    {

        if(!empty($email)) {
            $result = filter_var($email, FILTER_VALIDATE_EMAIL);
            return !$result ? false : true;
        }
        return false;

    }

    public function isValid()
    {

        $this->process();
        if(empty($this->errors) && !empty($this->post)) {
            // remove unwanted fields
            if(!empty($this->postRemove)) {
                foreach($this->postRemove as $value) {
                    unset($this->post[$value]);
                }
            }
            // format required fields
            if(!empty($this->postFormat)) {
                foreach($this->postFormat as $key => $value) {
                    $this->format($key, $value);
                }
            }
            return true;
        }
        return false;

    }

    public function format($key, $value)
    {

        switch($value) {
            case 'password':
            $this->post[$key] = Login::passwordEncrypt($this->post[$key]);
            break;
        }

    }


    public function addToErrors($key)
    {

        $this->errors[] = $key;

    }

    public function validate($key)
    {

        if(!empty($this->errors) && in_array($key, $this->errors)) {
            return $this->wrapWarn($this->message[$key]);
        }

    }

    public function wrapWarn($mess)
    {

        if(!empty($mess)) {
            return "<span class=\"warn\" >{$mess}</span>";
        }

    }

}

I have tested other dummy functions from validations.php and form.php and both work so the issue is definitely between the communication with these 2 classes. The process method is not recognizing or not getting values from the $this->objForm->isPost() call. Here is the error message I get where its telling me no value is being passed in:

Fatal error: Uncaught ArgumentCountError: Too few arguments to function A\B\App\Form::isPost(), 0 passed in /Applications/MAMP/htdocs/project/src/App/Validation.php on line 41 and exactly 1 expected in /Applications/MAMP/htdocs/project/src/App/Form.php:10 Stack trace: #0 /Applications/MAMP/htdocs/project/src/App/Validation.php(41): A\B\App\Form->isPost() #1 /Applications/MAMP/htdocs/project/src/App/Validation.php(94): A\B\App\Validation->process() #2 /Applications/MAMP/htdocs/project/src/Pages/users.php(36): A\B\App\Validation->isValid() #3 {main} thrown in /Applications/MAMP/htdocs/project/src/App/Form.php on line 10

Note: I have not been applying type declarations/hints to everything yet because of being stuck.


Solution

  • In order to not change too much the codebase (change all the references of the method), you should change the signature of the isPost() function in this way:

    public function isPost(string $field = ""): bool