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.

Toniebox und die Cloud

Liebe Eltern: lest die AGB’s solcher Spielzeuge für Kinder

Hier ein Auszug aus den AGB’s der Toniebox

Phoniebox AGB Stand: 06.07.2020 19:39 Uhr

Ich habe hier nicht schlecht geschaut was sie dann alles wissen.

Warum ist das denn so schlimm?

Ganz einfach: alles was ein Kind mit der Box macht, egal was, wird an den Hersteller geschickt. Was ist denn daran so schlimm? Der Hersteller kann aus den Daten alles Mögliche sehen

  • Wann steht das Kind auf
  • Wann geht es ins Bett
  • Gibt es bestimmte Lieder die zur selben Zeit laufen (Gute-Nacht-Lied, Lieblingslied)
  • Welche Titel werden übersprungen
  • Geburtstag (es kommen während des Jahres an einem Tag immer neue Figuren hinzu)
  • Funktioniert die Werbung für Toniefiguren (Eltern kriegen Werbung für die Figuren, bestellen diese dann oder leihen sie aus, das Kind spielt diese dann ab)
  • Stimmung des Kindes könnte anhand der gespielten Lieder abgelesen werden
  • Wie oft spielt das Kind an der Toniebox (könnte Rückschluss geben ob das Kind viel alleine spielt)

Das sind nur einige Punkte die mir einfallen, wass mit den Daten möglich ist. Gleicht man dann noch die Mailadresse des Cloud-Account-Erstellers mit einem Werbenetzwerk ab ergeben sich seehr viele tolle Möglichkeiten euch zum Kauf zu verleiten.

Meine Probleme mit der Cloud

Ihr entscheidet euch für die Toniebox und den Cloudaccount, der “anonym” erstellt werden kann und es müssen ganz wenig Daten angegeben werden. Nun die Toniebox funktioniert nicht ohne Cloud.
Eine neu gekaufte Figur funktioniert nur, wenn die Toniebox Zugang zur Cloud hat um die Daten nachzuladen. Ohne diesen Zugang: keine Musik.
Wer in Gegenden mit schlechtem Internet wohnt oder nur einen LTE-Router hat wird darüber nicht begeistert sein.
Die Box lädt sich die Musik herunter und speichert diese auf der Box selbst zur Verwendung ohne Internet, im Auto oder bei Freunden.
Der interne Speicher ist begrenzt und es werden einfach ältere Lieder überspielt und müssen bei Bedarf neu geladen werden.

Soweit ich es gefunden habe sind nur 8GB interner Speicher verbaut. Wer viele Hörbücher etc hat muss diese unter Umständen nachladen.

Money for nothing

Der Hersteller beschließt plötzlich 5 oder 10 € im Monat für die Clouddienste zu verlagen. Die Kinder sind schon so dran gewöhnt, dass man das als Eltern vmtl zahlen würde oder eine nutzlose Box zu Hause stehen hat die keine neuen Lieder mehr laden kann.

Abschaltung oder Probleme mit der Cloud beim Hersteller

Wo Menschen arbeiten passieren Fehler, das ist normal und auch gut so, daraus kann man lernen. Was passiert wenn die Cloud nichtmehr erreichbar ist aber das Kind Geburtstag hat und viele neue Figuren geschenkt bekommt die zwar auf der Toniebox stehen können aber keine Musik spielen?

Auch schon geschehen: Firmen mit Cloud diensten wurden gekauft und die Dienste abgeschaltet. Was macht ihr dann mit der Toniebox?
Die Toniebox kann leider nicht anders bespielt werden als durch die Cloud.

Fazit

Die Toniebox kommt für mein Kind nicht in Frage und schon gar nicht in mein WLAN.

Mein Phoniebox Build

Es gibt die sehr beliebte Toniebox https://tonies.de/toniebox/ die viele Eltern kennen und auch schätzen. Es ist ein würfelförmiger Musikspieler für Kinder bei dem die Musik mittels Figuren abgespielt werden können. Klopft das Kind auf eine Seite so wird der nächste oder vorherige Titel abgespielt.

Ich hab diese Box bereits bei Freunden gesehen und fand gut gemacht und ein interessantes Konzept. Also hab ich mich mal eingelesen und auch die AGB’s gelesen.

Meine Motivation für den Eigenbau

Ich hab mich ein wenig mit der Toniebox beschäftigt, die AGB’s angeschaut und das Konzept mit der Cloud genauer durchdacht. Mehr Details gibt es im eigenen Artikel dazu.

Alternativen zur Toniebox

Wie bereits erklärt hat mich die Toniebox von der Idee überzeugt, aber das rundherum passt mir einfach nicht.

Welche Möglichkeiten gibt es für einen MP3 Player der für die Kleinsten gut zu bedienen ist, aber für technisch interessiert Eltern nicht zu komplizert zu bauen?

Ich hatte noch einen Raspberry Pi 2 zu Hause und wollte den dafür verwenden. Ich bin dann auf das tolle Projekt von Micz Flor der Phoniebox gestoßen und war gleich begeistert.

Das Projekt ist Open-Source, einfach zu installieren und hat obendrein noch eine Weboberfläche zum Konfigurieren oder Bedienen der Box die in PHP geschrieben ist.

Ich war gleich davon begeistert.

Benötigte Teile

TeilPreis (Gesamt)
RaspiAb 10,83 € Raspi Zero-W
Arcade Buttons11,52 €
Powerbank11,80 €
RFID-Kartenleser3,83 € (War in nem Kit enthalten)
Ein-/Ausschalter2,77 €
Boxen10,25 €
Entstörfilter10,99 €
NFC Karten (10 Stk)5,74 €
Gesamt67,73

Die Arcade Buttons habe ich leider nicht lötfrei anschließen können, es gibt aber auch andere Buttons die Lötfrei verwendet werden können.

Zusammenbauen (Theorie)

Ich bin nach Anleitung auf der Wiki Seite der Phoniebox vorgegangen.

Erster Versuch in der Kiste
  • SD-Karte vorbereiten und Raspbian flashen
  • Raspberry Pi mittels HDMI-Kabel an einen Monitor anschließen (ist einfacher zur Fehlersuche etc)
  • Die Anleitung durchgehen und den Pi mit der Software der Phoniebox installieren
  • Wlan testen und Ip-Adresse fix hinterlegen, ganz wichtig, damit ich nachher wieder drauf verbinden kann falls es mal notwendig ist oder ich neue Musik aufspielen will
  • Musik aufspielen, dafür reichen 2 Lieder
  • Buttons mittels Breadboard testen, ob alles passt und klappt
  • Ich hab mir zuerst eine zu kleine Schachtel ausgesucht, das wäre sich mit den Buttons nie ausgegangen. Also gleich drauf achten, dass die Schactel/Kiste entsprechend groß ist

Ich hab erst alles auf dem Pi Zero eingerichtet und dafür eine USB-Soundkarte verwendet. Leider hatte ich hier Ground Noise und keinen passenden Filter dazu, also bin ich auf den Raspi 2 gewechselt.

Wer die Box nur zusammenbauen will sollte sich an die Anleitung und die entsprechenden Teile-Listen halte. Ich hab es dann mit einigem Ausprobieren hinbekommen. Eine Anleitung folgt noch.

Ich hatte leider keine passenden Kabellängen zu Hause, ich hab einfach ein Stück altes Telefonkabel auseinander genommen, an die Button und die Kabel mit der Buchse gelötet. Funktioniert super, die Kabel sind so lang, dass ich den Deckel ganz bequem aufklappen kann. Löten braucht seine Zeit, vorallem das Vorbereiten. Kabel abisolieren und zusammendrehen, an den Buttons befestigen. All das braucht leider seine Zeit, gelötet ist das nachher um einiges schneller. Egal es macht Spaß 🙂

Damit die Teile in der Box nicht umherfliegen habe ich Klettkabelbinder genommen und einfach mit Alles Kleber in der Box und auf den einzelnen Komponenten fixiert. Somit hält alles wunderbar, aber kann bei Bedarf noch ausgetauscht werden.

Anbringung einzelner teile mit Kklettverschluss

Fazit

Wenn alle Teile da sind ist es ein Wochenendprojekt. Ich glaub, dass ungeübte hier schon eine Weile dran sein werden. Ich habe mich Abends immer mal wieder ein paar Stunden damit beschäftigt und auch erstmal den Prototypen gebastelt und eine Weile liegen lassen.

Mit der Holzkiste kam neuer Schwung ins Projekt, ich hab die Buttons bestellt und mich hingesetzt, um es wirklich fertig zu kriegen und nicht nur als “proof-of-concept” in einer Ecke liegen zu haben.

Ich hab viel gelötet und auch wieder entlötet, Softwareseitig rumprobiert und Ideen für die Kiste im Netz gesucht. Letztlich ists eine einfach Holzkiste die noch verziert wird.

Dank des coolen Projektes von Micz Flors ist der Nachbau recht einfach und für technisch interessierte möglich. Man muss hier kein Profi sein, sollte aber auf jedenfall Spaß am Basteln haben.

Fertige Box
Innenansicht
Buttons unterseite

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.

Dear Linked-In Recruiter

I receive job-offerings on a regular basis. That is really nice you’ve contacted me, but you need to stand out with your texts. And also: I’m not interested.

Most of the time it feels like spam receiving these template letters from people not knowing the industry or not knowing what a programming language is.

Even if the offer might be interesting in the end, I am not interested for some of the following reasons:

  • Wrong or lazy written templates
    • You’re using a template in which the salutation isn’t spelled out (German: Sg. instead of Sehr geehrter Herr …)
    • Any kind of typing errors
    • Leaving your placeholders in your template
    • MfG instead of “Mit freundlichem Gruss”
    • A really long text with no real value or information
  • Tell me more about your “intersting” projects, company culture, top equipment and so on
    • You want to convince me to switch companies with your interesting project might takes more information about the project. I might be heavily into CMS/PIM/DAM systems or backends and you are offering me a position in a company that only does e-commerce frontend work. I don’t want to invest time in such inapt jobs
    • What does the project might have that I’m interested in? Tell me about that in advance.
    • Anything related to company culture should be more than just mentioning it. Does the company have non-work related activities, regular feedbacks, code reviews and their like
    • Equipment is nice to have but I need to feel comfortable with it. You don’t know what type of equipment I like, but on the other hand you keep telling me it is top equipment…
  • Company pays for a moving costs
    • If I already told you that I’m not interested in moving it doesn’t make it more attractive in telling me the company will pay for a move
  • Offering me jobs with wrong programming languages
    • Tells me: you don’t understand your job and you don’t know what I am offering or your client is looking for and therefore wasting my and your clients time
  • Contacting me shortly after job change
    • I’ve changed my job, why should I be interested in joining your clients company? Ever thought about that the change might happened for a reason and I’ve already decided to work for a company

I think this is sort of annoying to get contacted with this kind of letters. I, as an employee trying to get to an interview, need to write a promotion letter, send a whole lot of information about my live, projects, reports and so on.

But you, as a recruiter contacting me, are allowed to just say “hi”? Sorry but I don’t like how this works. Either both of us are allowed to just say “hi” or we both stick to full reports, projects list etc.

Setup Pimcore (my catches)

Create Docker Setup

Explicitly set encoding to utf8mb4 with

    command: ['mysqld', '--character-set-server=utf8mb4', '--collation-server=utf8mb4_unicode_ci']

Create the Project with Composer

COMPOSER_MEMORY_LIMIT=-1 composer create-project pimcore/skeleton my-project

After Docker Setup I was only able to get the installer to work with a file located /app/config/installer.yml

pimcore_install:
parameters:
database_credentials:
user: "%env(DB_USER)%"
password: "%env(DB_PASSWORD)%"
dbname: "%env(DB_NAME)%"
host: "%env(DB_HOST)%"
port: "%env(DB_PORT)%"

Install Pimcore

SSH into php and execute

./vendor/bin/pimcore-install