Create custom form themes for pimcore

From time to time you want to overwrite the default templates for forms in pimcore.
I had some problems to find the information I need as they are spreaded widley.

To get it to work it should look like this:

Filestructure

# src/AppBundle/Resources/config/pimcore/config.yml
form_builder:
form:
templates:
ivoclar_div_layout:
value: 'my_form_div_layout.html.twig'
label: 'Custom form layout'
default: true
{# tempaltes/bundles/FormBuilderBundle/Form/Theme/Macro/my_form_div_layout.html.twig #}
{% macro form_builder_form_head() %}
{% endmacro %}

{% macro form_builder_form_foot() %}
{% endmacro %}

{% macro form_builder_form_message(flash_messages) %}
{% if flash_messages is not empty %}
{% for label, messages in flash_messages %}
{% for message in messages %}
<div class="message message-{{ label }}">
{{ message|raw }}
</div>
{% endfor %}
{% endfor %}
{% endif %}
{% endmacro %}
{# tempaltes/bundles/FormBuilderBundle/Form/Theme/my_form_div_layout.html.twig #}
{% extends "form_div_layout.html.twig" %}

{%- block widget_attributes -%}
id="{{ id }}" name="{{ name }}"
{%- if disabled %} disabled="disabled"{% endif -%}
{%- if required %} required="required"{% endif -%}
{{ block('attributes') }}
{%- endblock widget_attributes -%}

Overwrite field-names with a template

In Pimcore I’m using https://github.com/dachcom-digital/pimcore-formbuilder to create input forms in my project.
I have the problem that the default input names are not the once I need for my task.

Default names
<input .. name="formbuilder_1[task]"
<input .. name="task"

I created a form theme to overwrite it

{# /templates/bundles/FormBuilderBundle/Form/Theme/myform_div_layout.html.twig #}
{% extends "form_div_layout.html.twig" %}

{%- block widget_attributes -%}
    id="{{ id }}" name="{{ name }}"
    {%- if disabled %} disabled="disabled"{% endif -%}
    {%- if required %} required="required"{% endif -%}
    {{ block('attributes') }}
{%- endblock widget_attributes -%}

The default name is {{full_name}}, replaced with {{name}} returns the fieldname I’ve set in the formbuilder form.

Laravel hasManyThrough

There is the useful hasManyThrough in Eloquent in which you can you 3 Tables and define which keys to use to join them.

Laravels example and documentation can be found here .
There is a little detail problem with it, it is all called id and the example wasn’t helping me much.

I have the following tables to handle job applications to jobs
Jobs
– id
– title
– description

Users
– id
– firstname
– lastname

Application
– id
– user_id
– job_id
– application_date

In the jobsmodel I want to get a list of all applicants.
Here is the first version of this

public function applicants(): HasManyThrough
{
    return $this->hasManyThrough(
        'App\Models\User',
        'App\Models\Application',
        'job_id',
        'id',
        'id',
        'id'
    );
}

While testing I received some strange applicants which never applied for the job.

After debugging I found that the last 'id' uses job.id to load the users with user.id. Bug found.
It should really be application.user_id to load the correct users. So a small change to this:

public function applicants(): HasManyThrough
{
    return $this->hasManyThrough(
        'App\Models\User',
        'App\Models\Application',
        'job_id', // (application.job_id)
        'id', // Foreign key on User table (user.id)
        'id', // Local key on job table (job.id)
        'user_id' // Local key on Application table (application.user_id)
    );
}

So changing the last id to user_id fixed that bug.