CodeIgniter Forums

Full Version: {field} placeholder does not get replaced with field name in a custom error message
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
I have a trouble with the {field} placeholder in a custom validation rule error message. What am I missing?

I have created a custom validation rule and put it into the app/Libraries/MyRules.php file:

PHP Code:
<?php 

namespace App\Libraries;

class 
MyRules
{
    public function 
no_links(string $stringstring &$error null): bool
    
{
        
$str preg_replace('/ /',''$string);
        
$error 'Field {field} should not contain links.';
        if (
strpos($str,'http')) { return false; }
        elseif (
strpos($str,'www')) { return false; }
        elseif (
strpos($str,'ftp')) { return false; }
        else {return 
true;}
    }


Then I added this custom rules library to the list where validation class looks for rules - in app/Config/Validation.php:

PHP Code:
<?php namespace Config;

class 
Validation
{
    public 
$ruleSets = [
        \
CodeIgniter\Validation\Rules::class,
        \
CodeIgniter\Validation\FormatRules::class,
        \
CodeIgniter\Validation\FileRules::class,
        \
CodeIgniter\Validation\CreditCardRules::class,
        \
App\Libraries\MyRules::class, // HERE
    
]; 

The rule, when added to validation rules set like this:

PHP Code:
            $validation->setRules([
                
'name' => ['label' => '„Your name“''rules' => 'required|min_length[3]|max_length[100]'],
                
'email' => ['label' => '„Email“''rules' => 'required|valid_email'],
                
'message' => ['label' => '„Message“''rules' => 'required|no_links|min_length[10]|max_length[2000]'],
            ]); 


in the controller and invoked, seems to work, the error message is displayed, but the {field} placeholder is not replaced with the field name „Message“ (while it does get replaced in case of all other error messages, even for the same field). What is the problem here?

Would be grateful for any suggestions.
I think your |no_links| should probably be invoked like this: |no_links[message]|
Hi Gary, why do you think so? It matches nothing in the manual - the parenthesis contains something to evaluate the field content against, or the name of another field/database column with the data to use for evaluation, not the error message. I already have the message displayed, only the {field} placeholder does not work...
I think doing it that way forces all the fields to be pushed into an array, so that in your custom function (now defined like this: function no_links(string $string, string $fields = NULL, array $data = NULL, string &$error = NULL) gets this array ($data), that has all the field names in it, from which you can extract {field} and insert it into the $error string your function is returning.

I stand under possible correction, but as far as I'm aware, the returned string is not processed any further, and pretty much gets displayed as is (with {field}).
(04-17-2020, 07:23 AM)Gary Wrote: [ -> ]I think your |no_links| should probably be invoked like this:  |no_links[message]|

(04-17-2020, 09:24 AM)Gary Wrote: [ -> ]I think doing it that way forces all the fields to be pushed into an array, so that in your custom function (now defined like this:  function no_links(string $string, string $fields = NULL, array $data = NULL, string &$error = NULL) gets this array ($data), that has all the field names in it, from which you can extract {field} and insert it into the $error string your function is returning.

I stand under possible correction, but as far as I'm aware, the returned string is not processed any further, and pretty much gets displayed as is (with {field}).

Tried it but it does not seem to work; whatever I write in parentheses does not show up as an error message. But if I simplify the validation function thus:
PHP Code:
    public function no_links(string $string null): bool
    
{
        
$str preg_replace('/ /',''$string);
        
//$error = 'Lauke {field} negali būti nuorodų.';
        
if (strpos($str,'http')) { return false; }
        elseif (
strpos($str,'www')) { return false; }
        elseif (
strpos($str,'ftp')) { return false; }
        else {return 
true;}
    } 

and then append to my language validation file the error message key-value pair (file app/Language/lt/Validation.php):
PHP Code:
'no_links'             => 'Lauke {field} negali būti nuorodų.'

the function begins to work as expected. Only I do not want to modify the default language files to add new strings for my own rules...
Good going.

What's wrong with modifying the language files... they are in the app directory = for user modification. It's only mods to things in the system directory that's frowned upon.
(04-17-2020, 03:12 PM)Gary Wrote: [ -> ]Good going. 

What's wrong with modifying the language files... they are in the app directory = for user modification.  It's only mods to things in the system directory that's frowned upon.

Well, if I get updated language files later and forget to update them with my own strings, I would end up with missing strings... So I would still like to keep the strings in a file that I create myself, not download from somewhere. But yeh, I am being too picky.
Hi there...

After hours of try and error I found a solution for this problem. In my solution I use my code to show how it works fine:

The "MyRules" file (part):
PHP Code:
public function myinvaliddate($str)
    {
        switch(session()->get('locale')){
            case "en":
                $format "Y-m-d H:i";
                break;
            case "de":
                $format "d.m.Y H:i";
                break;
        }
        $d = \DateTime::createFromFormat($format$str);
        return $d && $d->format($format) == $str;
    


The Model (part with rules & messages):
PHP Code:
protected $validationRules = [
        'title'             => 'trim|required|min_length[5]|max_length[190]',
        'category'          => 'required',
        'description'       => 'trim|required|min_length[10]',
        'starts_at'         => [
            'label' => 'Homegames.form.event_start',
            'rules' =>'required|format_date|myinvaliddate|dateinpast',
            'errors' => [
                'required' => 'Homegames.validation.description_required',
                'format_date' => 'Homegames.validation.format_date',
                'dateinpast' => 'Homegames.validation.date_in_past',
            ],
        ],
        'ends_at'           => [
            'label' => 'Homegames.form.event_end',
            'rules' => 'required|format_date|myinvaliddate|dateinpast',
            'errors' => [
                'required' => 'Homegames.validation.description_required',
                'format_date' => 'Homegames.validation.format_date',
                'dateinpast' => 'Homegames.validation.date_in_past',
                'myinvaliddate' => 'Homegames.validation.myinvaliddate',
            ],
        ],
    ]; 


The Language-File (part):
PHP Code:
'validation' => [
        'description_required' => 'Das {field} - Formularfeld ist erforderlich',
        'date_in_past' => 'Das {field} - Formularfeld darf nicht in der Vergangenheit sein',
        'end_before_start' => 'Das Enddatum darf nicht früher als das Startdatum sein',
        'wrong_format' => 'Das {field} - Datum muss von folgendem Format sein: dd.mm.JJJJ ST:MI',
        'myinvaliddate' => 'Das {field} enthält ein ungültiges Datum'
    ], 


I hope my approach will help you with your project.

Greetings,

Kighlander