Jump to content

Multi-Language Field required check


Orkun
 Share

Recommended Posts

Hi Guys

My Processwire Installation has 4 Languages installed (German, French, Italian and English). German is the default language.

How can I change the behavior of a required Multi-Language Field, that it checks if one of the lanuages is filled out (and not how it is like now where it only checks, if the default language is filled out)?

Do I need a Hook for this or some js action?

 

Kind Regards

Orkun

Link to comment
Share on other sites

I had to do something similar once. Here's something you might try as a starting point. A hook in site/ready.php :

if ($this->page->template == 'admin') {

    $this->addHookBefore('Pages::saveReady', function(HookEvent $event) {
        $form = $event->object;
        $page = $event->arguments(0);
        $user = wire('user');

        if($page->template == "basic-page"){
            $summary = $page->summary;
            $languages = wire('languages');
            // see wire/core/InputfieldWrapper.php
            $item_error = "<p class='InputfieldError ui-state-error'><i class='fa fa-fw fa-flash'></i><span>{out}</span></p>";
            $js = "<script>$(\"wrap_Inputfield_summary div.InputfieldContent.uk-form-controls.langTabsContainer\").append(\"$item_error\");</script>";

            foreach($languages as $language) {
                if($language->isDefault()) continue;
                $user->language = $language;
                $langName = $language->name;
                if(strlen($summary)<50) {
                    $form->error("Summary in $langName is too short!"); // regular error message at the top
                }
            }
        }
        $event->return = str_replace("</body>", "$js</body>", $event->return); // flash error msg on the field
    });
}

(Adjust template and field name of course)

This will still let the page save, and only display a red error msg on top, not the actual "required field error". I have no idea how PW does that.. I'd have to dig around in the core files, but no time atm... Of course it would also be nicer if the actual error message would be displayed in the user's language (d'oh)...

Link to comment
Share on other sites

18 minutes ago, dragan said:

I had to do something similar once. Here's something you might try as a starting point. A hook in site/ready.php :


if ($this->page->template == 'admin') {

    $this->addHookBefore('Pages::saveReady', function(HookEvent $event) {
        $pages = $event->object;
        $page = $event->arguments(0);
        $user = wire('user');

        if($page->template == "basic-page") {
            $summary = $page->summary;
            $languages = wire('languages');

            foreach($languages as $language) {
                if($language->isDefault()) continue;
                $user->language = $language;
                $langName = $language->name;
                if(strlen($summary)<50) {
                    $this->error("Summary in $langName is too short!");
                }
            }
        }
    });
}

(Adjust template and field name of course)

This will still let the page save, and only display a red error msg on top, not the actual "required field error". I have no idea how PW does that.. I'd have to dig around in the core files, but no time atm... Of course it would also be nicer if the actual error message would be displayed in the user's language (d'oh)...

Thanks @dragan

I had solved this with a hook into the processInput of the corresponding Inputfield. It kinda feels dirty but it does the job.

It checks at first if all languages are empty. If all languages are empty, it gets the old values of the page and gives the data to the incoming post request, so that the old values are still in place.
And also an error message is returned on the field.

$wire->addHookAfter("InputfieldPageTitle::processInput", function(HookEvent $event) {
    if(wire('user')->hasRole("partner")){

        $field = $event->object;
        
        $page = $this->modules->ProcessPageEdit->getPage();

        $allowedTemplates = array(
            "event",
            "partner",
        );

        if(in_array($page->template->name, $allowedTemplates)){

            $errorCounter = 0;
            foreach($this->languages as $lang){
                $lname = $lang->isDefault() ? "" : "__".$lang->id;
                if($this->wire('input')->post("title$lname") == ""){
                    $errorCounter++;
                }
            }

            // If all multi-language Fields are empty
            if($errorCounter == 4) {
				
				// Needs to be done like this for the default language. Somehow id doesn't work inside the foreach loop underneath
                $default = $this->languages->getDefault();
                $oldvalue = $page->getLanguageValue($default, 'title');
                $field->value = $oldvalue;

                // iterate through all languages except default
                foreach($this->languages as $lang){
                    if(!$lang->isDefault()){
                        // Get value which is already in db / on page
                        $oldvalue = $page->getLanguageValue($lang, 'title');

                        // Overwrite incoming post with old data from the db
                        $postvar = "title__{$lang->id}";
                        $this->wire('input')->post->$postvar = $oldvalue;
                    }
                }
                

                // Populate Error to field
                $field->error("You must fill in at least one language");
            }

        }
    }

});


$wire->addHookAfter("InputfieldTextarea::processInput", function(HookEvent $event) {
    if(wire('user')->hasRole("partner")){

        $field = $event->object;
        
        $page = $this->modules->ProcessPageEdit->getPage();

        $allowedTemplates = array(
            "event",
            "partner",
        );

        $allowedFields = array(
            "body",
            "about_us",
            "why_we_join"
        );

        // If field is already required, abort the hook
        if($field->required) return;

        $f = $this->wire('fields')->get($field->name);

        if(in_array($page->template->name, $allowedTemplates) && in_array($field->name, $allowedFields) && $f instanceof Field && $f->type instanceof FieldtypeLanguageInterface){
            
            // Check if field is empty in all languages
            $errorCounter = 0;
            foreach($this->languages as $lang){
                $lname = $lang->isDefault() ? "" : "__".$lang->id;
                if($this->wire('input')->post("{$field->name}$lname") == ""){
                    $errorCounter++;
                }
            }

            // If all multi-language Fields are empty
            if($errorCounter == 4) {

				// Needs to be done like this for the default language. Somehow id doesn't work inside the foreach loop underneath
                $default = $this->languages->getDefault();
                $oldvalue = $page->getLanguageValue($default, $field->name);
                $field->value = $oldvalue;

                // iterate through all languages except default
                foreach($this->languages as $lang){
                    if(!$lang->isDefault()){
                        // Get value which is already in db / on page
                        $oldvalue = $page->getLanguageValue($lang, $field->name);

                        // Overwrite incoming post with old data from the db
                        $postvar = "{$field->name}__{$lang->id}";
                        $this->wire('input')->post->$postvar = $oldvalue;
                    }
                }
                

                // Populate Error to field
                $field->error("You must fill in at least one language");
            }

        }

    }

});

Kind Regards

Orkun

  • Like 1
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...