Jump to content
Orkun

Multi-Language Field required check

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

Share this post


Link to post
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)...

Share this post


Link to post
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

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...