<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Refactoring on markob.de</title><link>https://markob.de/thema/refactoring/</link><description>Recent content in Refactoring on markob.de</description><generator>Hugo</generator><language>de-DE</language><lastBuildDate>Mon, 17 Aug 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://markob.de/thema/refactoring/index.xml" rel="self" type="application/rss+xml"/><item><title>Zweimal `square()` - Teil 1</title><link>https://markob.de/limesurvey/zweimal-square-teil-1/</link><pubDate>Mon, 17 Aug 2026 00:00:00 +0000</pubDate><guid>https://markob.de/limesurvey/zweimal-square-teil-1/</guid><description>&lt;p&gt;Manchmal beginnt Code-Archäologie nicht mit einem spektakulären Fund. Manchmal beginnt sie mit einem SQL-Injection-Fix – und einer Funktion, die eine Zahl quadriert.&lt;/p&gt;
&lt;p&gt;Am 12. August 2026 wurde im LimeSurvey-Repository Pull Request &lt;a href="https://github.com/LimeSurvey/LimeSurvey/pull/5225"&gt;#5225&lt;/a&gt; eröffnet. Der Titel: &amp;ldquo;Fixed issue #20648: [security] SQL injection in statistics&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;Das Problem war ernst. In der Statistikfunktion konnten manipulierte Filterparameter dazu führen, dass vom Request stammende Feldnamen ungeprüft in SQL-Abfragen gelangten. Der Fix führte deshalb eine Allowlist ein: Nur Spalten, die tatsächlich im Schema der jeweiligen Response-Tabelle existieren, dürfen noch als Feldnamen verwendet werden&lt;sup id="fnref:1"&gt;&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref"&gt;1&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;</description></item><item><title>Naming ist wichtig</title><link>https://markob.de/limesurvey/naming-ist-wichtig/</link><pubDate>Sat, 15 Aug 2026 00:00:00 +0000</pubDate><guid>https://markob.de/limesurvey/naming-ist-wichtig/</guid><description>&lt;p&gt;Manchmal reicht ein einzelner Feldname, um zu zeigen, wie viel Architektur eigentlich in einer Namensentscheidung steckt. Ein aktueller Pull Request im LimeSurvey-Kernrepository liefert dafür ein besonders klares Beispiel.&lt;/p&gt;
&lt;h2 id="der-fall"&gt;Der Fall&lt;/h2&gt;
&lt;p&gt;Am 14. August 2026 wurde im LimeSurvey-Repository der Pull Request &lt;a href="https://github.com/LimeSurvey/LimeSurvey/pull/5236"&gt;#5236&lt;/a&gt; eingereicht: ein neues Feature, das Surveys um einen zusätzlichen, sprachunabhängigen Titel erweitert – gedacht als interne Bezeichnung zur Identifikation im Administrationsbereich, unabhängig vom öffentlich sichtbaren, lokalisierten Umfragetitel.&lt;/p&gt;
&lt;p&gt;Technisch ist das ein sinnvolles Feature. Der bestehende Titel einer Survey (&lt;code&gt;survey_languagesettings.surveyls_title&lt;/code&gt;) ist an eine Sprache gebunden und für interne Zwecke – etwa das Wiederfinden einer Umfrage in einer langen Liste – oft ungeeignet. Ein zweites, sprachneutrales Feld schließt eine echte Lücke.&lt;/p&gt;</description></item><item><title>SurveyIndex + SurveyRuntimeHelper – Anatomie eines God Flow</title><link>https://markob.de/limesurvey/god-flow/</link><pubDate>Wed, 06 May 2026 00:00:00 +0000</pubDate><guid>https://markob.de/limesurvey/god-flow/</guid><description>&lt;p&gt;Wenn zu viel Verantwortung nicht in einer Klasse steckt, sondern in einem Ablauf&lt;/p&gt;
&lt;p&gt;In den letzten Artikeln dieser Serie haben wir zwei bekannte Antipattern betrachtet: &lt;a href="https://markob.de/create-field-map-die-god-function"&gt;&lt;code&gt;createFieldMap()&lt;/code&gt;&lt;/a&gt; als Beispiel einer Funktion, die zu viele Verantwortlichkeiten in sich vereint, und &lt;a href="https://markob.de/limemailer-anatomie-einer-god-class"&gt;&lt;code&gt;LimeMailer&lt;/code&gt;&lt;/a&gt; als Beispiel einer Klasse, die zu viel weiß, zu viel hält und zu viel tut. Beide Diagnosen folgten derselben Logik: Zu viel Verantwortung an einer Stelle.&lt;/p&gt;
&lt;p&gt;Diesmal geht es um etwas anderes. Nicht eine Funktion. Nicht eine Klasse. Sondern einen Ablauf.&lt;/p&gt;</description></item><item><title>Refactoring – was kostet es, was kostet es nicht?</title><link>https://markob.de/limesurvey/refactoring-kosten/</link><pubDate>Thu, 30 Apr 2026 00:00:00 +0000</pubDate><guid>https://markob.de/limesurvey/refactoring-kosten/</guid><description>&lt;p&gt;Im &lt;a href="https://markob.de/create-field-map-die-god-function"&gt;Artikel über &lt;code&gt;createFieldMap()&lt;/code&gt;&lt;/a&gt; haben wir gesehen was eine GodFunction ist, wie sie entsteht, und wie ein Weg heraus aussehen könnte: ein sauberes Composer Package, vollständige QA-Kette, 100% Testbarkeit.&lt;/p&gt;
&lt;p&gt;Der Plan ist klar. Die Frage die danach kommt, ist schwieriger:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Was kostet das? Und was kostet es, es nicht zu tun?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Das ist keine technische Frage mehr. Das ist eine unternehmerische. Und sie landet früher oder später auf dem Tisch des CTOs oder Lead Developers – meistens dann wenn das Budget knapp ist und die Roadmap voll.&lt;/p&gt;</description></item><item><title>createFieldMap() – die God Function</title><link>https://markob.de/limesurvey/create-field-map-die-god-function/</link><pubDate>Sun, 26 Apr 2026 00:00:00 +0000</pubDate><guid>https://markob.de/limesurvey/create-field-map-die-god-function/</guid><description>&lt;p&gt;&lt;a href="https://markob.de/limesurvey/helper-funktionen"&gt;Im Artikel über die Helper-Funktionen&lt;/a&gt; haben wir &lt;code&gt;common_helper.php&lt;/code&gt; als Ganzes betrachtet – 130+ globale Funktionen, über 11.000 Aufrufe im Code, ein Relikt aus der prozeduralen Ära. &lt;a href="https://markob.de/limemailer-anatomie-einer-god-class"&gt;In einem anderen Artikel&lt;/a&gt; haben wir &lt;code&gt;LimeMailer&lt;/code&gt; als GodClass analysiert: eine Klasse die zu viel weiß, zu viel tut, und deshalb praktisch nicht testbar ist.&lt;/p&gt;
&lt;p&gt;Heute schauen wir auf etwas das noch subtiler ist: eine &lt;strong&gt;GodFunction&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Keine Klasse. Eine einzelne Funktion. Mit über 600 Zeilen Code.&lt;/p&gt;</description></item><item><title>LimeSurvey und die Helper-Funktionen</title><link>https://markob.de/limesurvey/helper-funktionen/</link><pubDate>Sun, 29 Mar 2026 00:00:00 +0000</pubDate><guid>https://markob.de/limesurvey/helper-funktionen/</guid><description>&lt;p&gt;Wer LimeSurvey als Plugin-Entwickler nutzt oder in der Codebasis arbeitet, begegnet früher oder später diesem Muster:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-php" data-lang="php"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;Yii&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;loadHelper&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;common&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;Yii&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;loadHelper&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;surveytranslator&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;Yii&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;loadHelper&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;replacements&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Dahinter steckt ein einfacher Mechanismus: &lt;code&gt;loadHelper('common')&lt;/code&gt; lädt die Datei &lt;code&gt;application/helpers/common_helper.php&lt;/code&gt; und macht ihre Funktionen im globalen Scope verfügbar. Dasselbe Muster findet sich auch bei &lt;code&gt;loadLibrary()&lt;/code&gt;, das auf &lt;code&gt;application/libraries/&lt;/code&gt; zeigt:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-php" data-lang="php"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;loadHelper&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$helper&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;Yii&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="na"&gt;import&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;application.helpers.&amp;#39;&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="nv"&gt;$helper&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;_helper&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;loadLibrary&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$library&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;Yii&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="na"&gt;import&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;application.libraries.&amp;#39;&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="nv"&gt;$library&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Der konzeptuelle Unterschied zwischen Helper und Library ist dabei in der LimeSurvey-Codebasis kaum greifbar – beide Mechanismen lösen dasselbe Problem auf dieselbe Art. Das war in einer Zeit sinnvoll, als PHP noch kein Autoloading kannte und Funktionen manuell eingebunden werden mussten. PHP 5.1 war 2005. Composer erschien 2012.&lt;/p&gt;</description></item><item><title>LimeMailer - Anatomie einer God Class</title><link>https://markob.de/limesurvey/limemailer-anatomie-einer-god-class/</link><pubDate>Sun, 22 Mar 2026 00:00:00 +0000</pubDate><guid>https://markob.de/limesurvey/limemailer-anatomie-einer-god-class/</guid><description>&lt;p&gt;&lt;a href="https://github.com/LimeSurvey/LimeSurvey/blob/master/application/core/LimeMailer.php"&gt;LimeMailer&lt;/a&gt; ist die zentrale E-Mail-Komponente von LimeSurvey. Sie erbt von PHPMailer, der weit verbreiteten PHP-Mailer-Bibliothek, und erweitert diese um LimeSurvey-spezifische Logik: Umfrage-Templates, Token-Ersetzungen, Anhänge nach E-Mail-Typ, Plugin-Events und vieles mehr.&lt;/p&gt;
&lt;p&gt;Dieser Artikel betrachtet die Klasse nicht als Fehler ihrer Entwickler. Wer in einem laufenden Open-Source-Projekt unter Zeitdruck Features liefert, trifft Entscheidungen, die im Moment vernünftig sind. Technische Schulden entstehen nicht durch Unwissenheit, sondern durch die Realität von Softwareentwicklung. Was hier analysiert wird, ist das Muster – nicht die Person dahinter.&lt;/p&gt;</description></item><item><title>LimeSurvey und die Hungarian Notation</title><link>https://markob.de/limesurvey/hungarian-notation/</link><pubDate>Sun, 15 Mar 2026 00:00:00 +0000</pubDate><guid>https://markob.de/limesurvey/hungarian-notation/</guid><description>&lt;p&gt;Wer schon einmal einen Blick in den Quellcode von LimeSurvey geworfen hat, dem begegnet unweigerlich Folgendes:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-php" data-lang="php"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;$iSurveyId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;$sLanguage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;de&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;$oSurvey&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Survey&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;findByPk&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$iSurveyId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;$aQuestions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$oSurvey&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;getQuestions&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;$bActive&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Das Präfix verrät den Typ: &lt;code&gt;i&lt;/code&gt; für Integer, &lt;code&gt;s&lt;/code&gt; für String, &lt;code&gt;o&lt;/code&gt; für Object, &lt;code&gt;a&lt;/code&gt; für Array, &lt;code&gt;b&lt;/code&gt; für Boolean. Diese Konvention nennt sich Hungarian Notation – und sie stammt aus einer Zeit, in der PHP noch keinerlei Typisierung kannte. LimeSurvey existiert seit über 20 Jahren, und manche dieser Muster sind genauso alt.&lt;/p&gt;</description></item><item><title>Der Rewrite-Reflex</title><link>https://markob.de/limesurvey/rewrite-reflex/</link><pubDate>Sun, 08 Mar 2026 00:00:00 +0000</pubDate><guid>https://markob.de/limesurvey/rewrite-reflex/</guid><description>&lt;p&gt;Wer zum ersten Mal in eine gewachsene Codebasis eintaucht – unbekannte Strukturen, kryptische Bezeichner, Abhängigkeiten, die sich wie ein Geflecht durch das System ziehen – kennt den Impuls: &lt;strong&gt;neu schreiben.&lt;/strong&gt; Sauber. Modern. Diesmal richtig.&lt;/p&gt;
&lt;p&gt;Dieser Reflex ist verständlich. Er ist menschlich. Und er ist einer der teuersten Fehler, den ein Entwicklungsteam machen kann.&lt;/p&gt;
&lt;h2 id="was-ist-legacy-code-überhaupt"&gt;Was ist Legacy-Code überhaupt?&lt;/h2&gt;
&lt;p&gt;Bevor man über Rewrite oder Modernisierung spricht, lohnt sich ein Blick auf die Frage: &lt;strong&gt;Was ist Legacy-Code?&lt;/strong&gt;&lt;/p&gt;</description></item></channel></rss>