<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.9.0">Jekyll</generator><link href="/programming-laws/feed.xml" rel="self" type="application/atom+xml" /><link href="/programming-laws/" rel="alternate" type="text/html" /><updated>2024-11-26T10:07:17+00:00</updated><id>/programming-laws/feed.xml</id><title type="html">Martinus Devs - zbierka zákonov</title><subtitle>Zbierka pravidiel, ktoré sa programátorom v Martinuse osvedčilo používať.</subtitle><entry><title type="html"># 11 - V ORM v query builder treba vždy k názvu stĺpca pridať aj názov tabuľky</title><link href="/programming-laws/tech%20%3E%20php%20%3E%20cakephp/11-orm-query-builder-mandatory-table-name.html" rel="alternate" type="text/html" title="# 11 - V ORM v query builder treba vždy k názvu stĺpca pridať aj názov tabuľky" /><published>2020-06-24T14:16:00+00:00</published><updated>2020-06-24T14:16:00+00:00</updated><id>/programming-laws/tech%20%3E%20php%20%3E%20cakephp/11-orm-query-builder-mandatory-table-name</id><content type="html" xml:base="/programming-laws/tech%20%3E%20php%20%3E%20cakephp/11-orm-query-builder-mandatory-table-name.html">&lt;p&gt;V CakePHP ORM v query builder treba vždy k názvu stĺpca pridať aj názov (alebo alias) tabuľky. Aby neskôr zbytočne nevznikali kolizie v názvoch stĺpcoch.&lt;/p&gt;

&lt;h1 id=&quot;prečo-je-to-dôležité&quot;&gt;Prečo je to dôležité?&lt;/h1&gt;

&lt;p&gt;Ak chceme neskôr pridať nejakým spôsobom do query &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;contain&lt;/code&gt; (&lt;em&gt;join&lt;/em&gt; na inú tabuľku), tak treba ku stĺpcom manuálne dopĺňať názov tabuľky.&lt;/p&gt;

&lt;p&gt;Ešte horšie je to v prípade, že sa &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;contain&lt;/code&gt; pridá hromadne na veľa miest. Napríklad ak sa pridá do &lt;em&gt;finder-a&lt;/em&gt;, ktorý je použitý na viac miestach. Alebo cez &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;beforeFind&lt;/code&gt; – tak to napríklad robí &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;TranslateBehavior&lt;/code&gt;. Pri bežných stĺpcoch (napr. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;id&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;created&lt;/code&gt; alebo &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;modified&lt;/code&gt;), ktoré má veľa tabuliek, potom databáza nevie, ktorú tabuľku má použiť.&lt;/p&gt;</content><author><name></name></author><category term="Tech &gt; PHP &gt; CakePHP" /><summary type="html">V CakePHP ORM v query builder treba vždy k názvu stĺpca pridať aj názov (alebo alias) tabuľky. Aby neskôr zbytočne nevznikali kolizie v názvoch stĺpcoch.</summary></entry><entry><title type="html"># 01 - Dodržiavať CakePHP Coding Standards</title><link href="/programming-laws/tech%20%3E%20php/1-coding-standards-cakephp.html" rel="alternate" type="text/html" title="# 01 - Dodržiavať CakePHP Coding Standards" /><published>2020-02-17T13:15:50+00:00</published><updated>2020-02-17T13:15:50+00:00</updated><id>/programming-laws/tech%20%3E%20php/1-coding-standards-cakephp</id><content type="html" xml:base="/programming-laws/tech%20%3E%20php/1-coding-standards-cakephp.html">&lt;p&gt;V PHP kóde dodržiavame &lt;a href=&quot;https://book.cakephp.org/4/en/contributing/cakephp-coding-conventions.html&quot;&gt;CakePHP Coding Standards&lt;/a&gt;. Všetky budúce zmeny budeme dodržiavať tiež.&lt;/p&gt;</content><author><name></name></author><category term="Tech &gt; PHP" /><summary type="html">V PHP kóde dodržiavame CakePHP Coding Standards. Všetky budúce zmeny budeme dodržiavať tiež.</summary></entry><entry><title type="html"># 10 - Každý argument funkcie akceptuje iba hodnoty jedného typu</title><link href="/programming-laws/tech/10-arguments-single-type.html" rel="alternate" type="text/html" title="# 10 - Každý argument funkcie akceptuje iba hodnoty jedného typu" /><published>2020-02-17T13:15:50+00:00</published><updated>2020-02-17T13:15:50+00:00</updated><id>/programming-laws/tech/10-arguments-single-type</id><content type="html" xml:base="/programming-laws/tech/10-arguments-single-type.html">&lt;p&gt;Každý argument funkcie alebo metódy musí mať definovaný iba 1 typ.
Funkcie/metódy teda nesmú pre 1 argument akceptovať hodnoty rôznych dátových typov (2 a viac rôznych dátových typov).&lt;/p&gt;

&lt;p&gt;Zákon umožňuje 1 výnimku – ak akceptovanie viacerých rôznych typov zjednodušuje navrhnuté API. A to iba za podmienky, že autor preukázateľne dokáže, že funckia bude fungovať správne pre všetky možné primitívne typy a objekty. Správne fungovanie môže byť aj exception pre nepodporované typy argumentov. Najlepší spôsob, ako autor preukázateľne dokáže, že funckia bude fungovať, sú testy.&lt;/p&gt;

&lt;h1 id=&quot;php&quot;&gt;PHP&lt;/h1&gt;

&lt;p&gt;V PHP ľahko vynútiteľné cez type hinting, takže podzákon pre PHP: Každý argument PHP funckie/metódy musí mať type hint.&lt;/p&gt;

&lt;p&gt;Akceptovať 1 typ alebo &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;null&lt;/code&gt; (v PHP type hinting s &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;?type&lt;/code&gt;) je povolené.&lt;/p&gt;</content><author><name></name></author><category term="Tech" /><summary type="html">Každý argument funkcie alebo metódy musí mať definovaný iba 1 typ. Funkcie/metódy teda nesmú pre 1 argument akceptovať hodnoty rôznych dátových typov (2 a viac rôznych dátových typov).</summary></entry><entry><title type="html"># 02 - Nepoužívať implicitné typové konverzie</title><link href="/programming-laws/tech%20%3E%20php/2-no-implicit-type-conversions.html" rel="alternate" type="text/html" title="# 02 - Nepoužívať implicitné typové konverzie" /><published>2020-02-17T13:15:50+00:00</published><updated>2020-02-17T13:15:50+00:00</updated><id>/programming-laws/tech%20%3E%20php/2-no-implicit-type-conversions</id><content type="html" xml:base="/programming-laws/tech%20%3E%20php/2-no-implicit-type-conversions.html">&lt;p&gt;Implicitné typové konverzie sú niekedy zvláštne. A aj keď sa objektívne dajú vysvetliť, málokto v nich má prehľad a nikto si na všetky prípady nedáva pozor.&lt;/p&gt;

&lt;p&gt;Jeden príklad za všetky:&lt;/p&gt;
&lt;div class=&quot;language-php highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;var_dump&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;1&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;01&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// 1 == 1 -&amp;gt; true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Síce (subjektívne) zriedkavo, ale niekedy vyústia v zbytočné chyby, ktoré by sme nemuseli mať. Preto si &lt;strong&gt;používanie implicitných konverzii typov zakazujeme&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Pod implicitnými typovými konverziami myslíme:&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.php.net/manual/en/language.operators.php&quot;&gt;PHP operátory&lt;/a&gt; sa môžu používať len s takými hodnotami/premennými, aby nedošlo k implicitnej typovej konverzii, napr.:
    &lt;ul&gt;
      &lt;li&gt;logické operátory &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;!&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;amp;&amp;amp;&lt;/code&gt; alebo &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;||&lt;/code&gt; sa môžu použiť iba s typom boolean,&lt;/li&gt;
      &lt;li&gt;aritmetické operátory &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;+&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;*&lt;/code&gt; alebo &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/&lt;/code&gt; sa môžu použiť iba s typmi int alebo float,&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;porovnávacie operátory &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;==&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;!=&lt;/code&gt; a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;lt;&amp;gt;&lt;/code&gt; sú zakázané, treba namiesto nich použiť &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;===&lt;/code&gt; a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;!==&lt;/code&gt;,&lt;/li&gt;
  &lt;li&gt;zakázané sú aj verzie funkcií, ktoré robia implicitné typové konverzie,
    &lt;ul&gt;
      &lt;li&gt;napr. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;in_array($a, $b)&lt;/code&gt; alebo &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;in_array($a, $b, false)&lt;/code&gt;, povolené je iba volanie &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;in_array($a, $b, true)&lt;/code&gt;,&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;zakázané &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;empty()&lt;/code&gt; - premenná by mala mať hodnoty iba v 1 type - tým pádom sa pre každý typ dá napísať “empty()” podmienka ručne/explicitne; a na overenie, či existuje kľúč v poli treba použiť &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;isset()&lt;/code&gt;,&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;isset()&lt;/code&gt; sa môže použiť len na overenie, či v poli existuje kľúč (alebo field v objekte, alebo lokálna premenná, …), ak kľúč/field/premenná existuje, na overenie jej hodnoty treba použiť &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;=== null&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;!== null&lt;/code&gt;, alebo &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;is_null()&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Zákon umožňuje 1 výnimku - a to ak implicitné typové konverzie zjednodušujú navrhnuté API knižnice/modulu/triedy alebo implementáciu. A to iba za podmienky, že autor preukázateľne dokáže, že funkcia bude fungovať správne pre všetky možné typy/konverzie. Správne fungovanie môže byť aj exception pre nepodporované typy/konverzie. Najlepší spôsob, ako autor preukázateľne dokáže, že funkcia bude fungovať správne, sú unit testy.&lt;/p&gt;

&lt;p&gt;Referencie:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.php.net/manual/en/language.types.type-juggling.php&quot;&gt;PHP Type Juggling&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.php.net/manual/en/types.comparisons.php&quot;&gt;PHP Type Comparison Tables&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.php.net/manual/en/language.operators.php&quot;&gt;PHP Operators&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content><author><name></name></author><category term="Tech &gt; PHP" /><summary type="html">Implicitné typové konverzie sú niekedy zvláštne. A aj keď sa objektívne dajú vysvetliť, málokto v nich má prehľad a nikto si na všetky prípady nedáva pozor.</summary></entry><entry><title type="html"># 03 - Na ukladanie časov a dátumov do DB používame typ TIMESTAMP alebo typ DATETIME s hodnotami v UTC</title><link href="/programming-laws/apps/3-database-dates-and-times.html" rel="alternate" type="text/html" title="# 03 - Na ukladanie časov a dátumov do DB používame typ TIMESTAMP alebo typ DATETIME s hodnotami v UTC" /><published>2020-02-17T13:15:50+00:00</published><updated>2020-02-17T13:15:50+00:00</updated><id>/programming-laws/apps/3-database-dates-and-times</id><content type="html" xml:base="/programming-laws/apps/3-database-dates-and-times.html">&lt;p&gt;Existujú len 2 možnosti ako správne ukladať do databázy dátumy a časy:&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;TIMESTAMP&lt;/code&gt; - lebo MySQL/MariaDB interne ukladajú hodnotu nezávislú na timezone (TODO ako?),&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DATETIME&lt;/code&gt; s hodnotami v UTC.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Je to dôležité pre ďalšie operácie s dátami (napr. počítanie časového rozdielu medzi udalosťami, alebo zoraďovanie podľa toho, kedy udalosť nastala).&lt;/p&gt;

&lt;h2 id=&quot;prečo-je-datetime-v-utc-nezávislý-na-timezone&quot;&gt;Prečo je DATETIME v UTC nezávislý na timezone?&lt;/h2&gt;
&lt;blockquote&gt;
  &lt;p&gt;We use UTC because it has an offset of 00:00: in other words, it has no timezone offset. Other timezones are offset from UTC, not the other way around.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Akákoľvek iná timezone môže mať offset a ten sa môže meniť (jednorazovo sa región presunie do inej tz, alebo pravidelne - letný čas). Pri ukladaní hodnôt v inej tz sa teda môžu nejaké časy preskočiť, alebo opakovať. Operácie s takými dátami sa budú robiť ťažko.&lt;/p&gt;

&lt;p&gt;Pri preskočení času o 1 hodinu dopredu bude napr. nesprávny rozdiel medzi časmi. Reálne uplynulo 5 minút, rozdiel ale bude 1 hodina a 5 minút.
Pri posunutí času o 1 hodinu dozadu sa nebudú dať časy správne chronologicky zoradiť.&lt;/p&gt;

&lt;p&gt;UTC timezone má jediná offset 0 a navždy bude mať.&lt;/p&gt;

&lt;h2 id=&quot;povolené-výnimky&quot;&gt;Povolené výnimky&lt;/h2&gt;

&lt;ol&gt;
  &lt;li&gt;Dátumy a časy nezávislé na timezone, napríklad:
    &lt;ul&gt;
      &lt;li&gt;dátum narodenia, narodeniny (12.4.1985) - bez ohľadu na timezone, je to vždy konkrétny dátum/rok,&lt;/li&gt;
      &lt;li&gt;sviatky, inak významné dátumy (4.7., 24.12., …),&lt;/li&gt;
      &lt;li&gt;(fiktívny príklad) začiatok platnosti nového zákona v EU (v každej krajine začne platiť 1.10.2025 0:00 podľa lokálnej timezone krajiny) a pod.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Každý záznam/riadok ma vlastnú timezone:
    &lt;ul&gt;
      &lt;li&gt;tabuľka musí obsahovať stringové fully qualified timezone name v ďalšom stĺpci.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;h3 id=&quot;prečo-stringové-fully-qualified-timezone-name&quot;&gt;Prečo stringové fully qualified timezone name?&lt;/h3&gt;

&lt;blockquote&gt;
  &lt;p&gt;Instead of a numeric offset, use a string. Specifically, use the full qualified name in the Olson database, so something like Australia/Adelaide or America/Los_Angeles. These are standardized descriptors of the timezones used in the world, and you can use these in pretty much every programming language ever used in the last few decades.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Zlý spôsob:&lt;/p&gt;
&lt;blockquote&gt;
  &lt;p&gt;One way to do this is to treat this column as an integer; say, store -240 in a row to represent a shift of 4 hours (4*60 minutes). That’s cool, and it does get you closer, but again, we’re talking about a use case where it actually does matter to be as accurate as possible (and being off an hour might lead to nonsensical data). Just having a numerical offset doesn’t give you fidelity of location. Was it during Daylight Saving Time? What about comparing that to today’s time; do we account for DST or not? Also, do we need to account for changes in timezones that might have happened since that point in time?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;https://zachholman.com/talk/utc-is-enough-for-everyone-right#properly-storing-timezone-aware-times&lt;/p&gt;</content><author><name></name></author><category term="Apps" /><summary type="html">Existujú len 2 možnosti ako správne ukladať do databázy dátumy a časy: TIMESTAMP - lebo MySQL/MariaDB interne ukladajú hodnotu nezávislú na timezone (TODO ako?), DATETIME s hodnotami v UTC.</summary></entry><entry><title type="html"># 04 - Náhodné identifikátory majú minimálne 22 znakov v 64 znakovej abecede</title><link href="/programming-laws/apps/4-random-identifiers.html" rel="alternate" type="text/html" title="# 04 - Náhodné identifikátory majú minimálne 22 znakov v 64 znakovej abecede" /><published>2020-02-17T13:15:50+00:00</published><updated>2020-02-17T13:15:50+00:00</updated><id>/programming-laws/apps/4-random-identifiers</id><content type="html" xml:base="/programming-laws/apps/4-random-identifiers.html">&lt;p&gt;128 bitové náhodné číslo (inými slovami 128 bitov entropite) je dosť na to, aby sa nedali nikdy&lt;sup&gt;1&lt;/sup&gt; vyskúsať všetky možnosti.&lt;/p&gt;

&lt;p&gt;To vychádza na 22 znakov v 64 znakovej abecede. Lebo 64 znakov je 6 bitov (2^6 = 64). 6 bitov * 22 znakov = 132 náhodných bitov (na porovnanie, 6 bitov * 21 znakov je iba 126 bitov).&lt;/p&gt;

&lt;p&gt;Dôležitý predpoklad je, aby boli naozaj náhodné.&lt;/p&gt;

&lt;p&gt;V PHP treba použiť funkciu &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;openssl_random_pseudo_bytes&lt;/code&gt;.
V Martinus PHP na to máme class &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;\Martinus\Utils\Code\StringIdentifiersGenerator&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Príkladom 64 znakovej abecedy je base 64: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;a-z&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;A-Z&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0-9&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;+&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/&lt;/code&gt;.
Pre potreby URL sa viac hodí nahradiť znaky &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;+&lt;/code&gt; a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/&lt;/code&gt; za niečo iné.  StringIdentifiersGenerator používa znaky &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-&lt;/code&gt; a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;_&lt;/code&gt;.
V 16 znakovej abecede (hexadecimálne čísla) musí byť dĺžka strignu 32 znakov (16 = 2^4, 32 * 4 = 128).&lt;/p&gt;

&lt;p&gt;Referencie:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;https://security.stackexchange.com/questions/6141/amount-of-simple-operations-that-is-safely-out-of-reach-for-all-humanity/6149#6149&lt;/li&gt;
  &lt;li&gt;https://en.wikipedia.org/wiki/Password_strength&lt;/li&gt;
&lt;/ul&gt;

&lt;hr /&gt;

&lt;p&gt;&lt;sup&gt;1&lt;/sup&gt; 128 náhodných bitov je dosť preto, lebo iba samotná iterácia všetkých možností bude podľa odhadov v roku 2040 vyžadovať všetku energetickú produkciu Zeme a trvať 10 rokov.&lt;/p&gt;

&lt;p&gt;&lt;sup&gt;2&lt;/sup&gt; Tip: je to dobré pravidlo aj pre náhodne generované heslá.&lt;/p&gt;</content><author><name></name></author><category term="Apps" /><summary type="html">128 bitové náhodné číslo (inými slovami 128 bitov entropite) je dosť na to, aby sa nedali nikdy1 vyskúsať všetky možnosti.</summary></entry><entry><title type="html"># 05 - Minimálne požiadavky na commit message</title><link href="/programming-laws/tech%20%3E%20git/5-commit-messages.html" rel="alternate" type="text/html" title="# 05 - Minimálne požiadavky na commit message" /><published>2020-02-17T13:15:50+00:00</published><updated>2020-02-17T13:15:50+00:00</updated><id>/programming-laws/tech%20%3E%20git/5-commit-messages</id><content type="html" xml:base="/programming-laws/tech%20%3E%20git/5-commit-messages.html">&lt;p&gt;VSC/Git commit message sú minimálne 2 holé vety (4 slová, 2x podmet a 2x prísudok), pričom odpovedajú na otázky:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;veta: &lt;strong&gt;čo&lt;/strong&gt; sa zmenilo,&lt;/li&gt;
  &lt;li&gt;veta: &lt;strong&gt;prečo&lt;/strong&gt; bolo potrebné takúto zmenu spraviť.&lt;/li&gt;
&lt;/ol&gt;</content><author><name></name></author><category term="Tech &gt; Git" /><summary type="html">VSC/Git commit message sú minimálne 2 holé vety (4 slová, 2x podmet a 2x prísudok), pričom odpovedajú na otázky:</summary></entry><entry><title type="html"># 06 - Time, Date a FrozenDate sú zakázané, vždy používať iba FrozenTime</title><link href="/programming-laws/tech%20%3E%20php%20%3E%20cakephp/6-immutable-time.html" rel="alternate" type="text/html" title="# 06 - Time, Date a FrozenDate sú zakázané, vždy používať iba FrozenTime" /><published>2020-02-17T13:15:50+00:00</published><updated>2020-02-17T13:15:50+00:00</updated><id>/programming-laws/tech%20%3E%20php%20%3E%20cakephp/6-immutable-time</id><content type="html" xml:base="/programming-laws/tech%20%3E%20php%20%3E%20cakephp/6-immutable-time.html">&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Time&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Date&lt;/code&gt; a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;FrozenDate&lt;/code&gt; sú zakázané. Vždy treba používať iba FrozenTime. Pretože:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Time&lt;/code&gt; a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Date&lt;/code&gt; sú mutable,&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;FrozenDate&lt;/code&gt; a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Date&lt;/code&gt; nepodporujú timezone-y a zároveň majú niektoré metódy, ktoré na timezone závisia (napr. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;isToday()&lt;/code&gt;), je to Chronos bug.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Výnimka:&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;Historicky &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;FrozenTime&lt;/code&gt; neexistoval, písali sme kód, ktorý využíval mutable &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Time&lt;/code&gt;. Ak to vyžaduje existujúci kód, je povolené použiť &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Time&lt;/code&gt;. Týka sa to hlavne ORM.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&quot;ako-najlepšie-pracovať-s-existujúcim-mutable-time&quot;&gt;Ako najlepšie pracovať s existujúcim mutable Time?&lt;/h2&gt;

&lt;div class=&quot;language-php highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$entity&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Table&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$created&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;FrozenTime&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$entity&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;created&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;prečo-používať-immutable-frozentime-namiesto-time&quot;&gt;Prečo používať immutable FrozenTime namiesto Time?&lt;/h2&gt;

&lt;p&gt;Názov je trochu menej elegantný ako &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Time&lt;/code&gt;, ale je menej náchylný na chyby, ak si ho zvykneme používať.&lt;/p&gt;

&lt;p&gt;Vzorová situácia: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;$tomorrow = $now-&amp;gt;addDay();&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Time&lt;/code&gt; verzia:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;keďže &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Time&lt;/code&gt; je mutable, dá sa mu meniť hodnota,&lt;/li&gt;
  &lt;li&gt;volanie &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;addDay()&lt;/code&gt; zmení hodnotu toho objektu, na ktorom sa zavolá - čiže hodnotu objektu &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;$now&lt;/code&gt; posunie o 1 deň,&lt;/li&gt;
  &lt;li&gt;zároveň ten istý objekt priradíme do premennej &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;$tomorrow&lt;/code&gt;,&lt;/li&gt;
  &lt;li&gt;výsledkom je, že &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;$now&lt;/code&gt; aj &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;$tomorrow&lt;/code&gt; budú ukazovať na 1 inštanciu, v ktorej bude zajtrajší dátum.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;FrozenTime&lt;/code&gt; verzia:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;keďže &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;FrozenTime&lt;/code&gt; je immutable, nedá sa mu meniť hodnota,&lt;/li&gt;
  &lt;li&gt;volanie &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;addDay()&lt;/code&gt; teda musí vytvoriť nový objekt, do ktorého nastaví hodnotu posunutú o 1 deň,&lt;/li&gt;
  &lt;li&gt;nový objekt sa priradí do premennej &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;$tomorrow&lt;/code&gt;,&lt;/li&gt;
  &lt;li&gt;výsledkom je, že &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;$now&lt;/code&gt; a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;$tomorrow&lt;/code&gt; budú 2 rôzne inštancie s rôznymi hodnotami, v jednej dnešný, v druhej zajtrajší dátum,&lt;/li&gt;
  &lt;li&gt;stane sa teda to, čo by sme na pohľad očakávali.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;S &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;FrozenTime&lt;/code&gt; ako základnou verziou sa vyhneme týmto chybám a o nič neprídeme.&lt;/p&gt;

&lt;p&gt;Immutable object: https://en.wikipedia.org/wiki/Immutable_object&lt;/p&gt;

&lt;h2 id=&quot;aj-na-prácu-s-dátumom-bez-času-treba-používať-frozentime&quot;&gt;Aj na prácu s dátumom bez času treba používať FrozenTime&lt;/h2&gt;

&lt;p&gt;Chronos &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Date&lt;/code&gt; a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;FrozenDate&lt;/code&gt; nemajú timezone (vždy sa pri vytvorení použije UTC - Chronos 1, alebo timezone servera - Chronos 2). To z istého uhla pohľadu dáva zmysel. 14. marca je proste 14. marca v USA aj v Japonsku rovnako.&lt;/p&gt;

&lt;p&gt;Problém je, že &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Date&lt;/code&gt; a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;FrozenDate&lt;/code&gt; majú celé API rovnaké ako &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Time&lt;/code&gt; a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;FrozenTime&lt;/code&gt;. Vrátane takých funkcií, ktoré dátum porovnávajú s aktuálnym UTC dátumom a časom - napr. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;isToday()&lt;/code&gt;.&lt;/p&gt;

&lt;div class=&quot;language-php highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// now:&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// 2020-01-28 00:30:00 Europe/Bratislava&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// 2020-01-27 23:30:00 UTC&lt;/span&gt;

&lt;span class=&quot;nv&quot;&gt;$date&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;FrozenDate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;2020-01-28&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; 
&lt;span class=&quot;c1&quot;&gt;// =&amp;gt; 2020-01-28 00:00:00 UTC&lt;/span&gt;

&lt;span class=&quot;nv&quot;&gt;$date&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;isToday&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt; 
&lt;span class=&quot;c1&quot;&gt;// =&amp;gt; false&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Vysvetlenie: implementácia isToday():&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// return $this-&amp;gt;toDateString() === static::now($this-&amp;gt;tz)-&amp;gt;toDateString();&lt;/span&gt;

&lt;span class=&quot;nv&quot;&gt;$first&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$date&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;toDateString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt; 
&lt;span class=&quot;c1&quot;&gt;// =&amp;gt; 2020-01-28&lt;/span&gt;

&lt;span class=&quot;nv&quot;&gt;$date&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tz&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; 
&lt;span class=&quot;c1&quot;&gt;// =&amp;gt; UTC&lt;/span&gt;

&lt;span class=&quot;nv&quot;&gt;$now&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;static&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;now&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tz&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; 
&lt;span class=&quot;c1&quot;&gt;// =&amp;gt; 2020-01-27 23:30:00 UTC&lt;/span&gt;

&lt;span class=&quot;nv&quot;&gt;$second&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$now&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;toDateString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt; 
&lt;span class=&quot;c1&quot;&gt;// =&amp;gt; 2020-01-27&lt;/span&gt;

&lt;span class=&quot;nv&quot;&gt;$first&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$second&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// =&amp;gt; false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Výsledkom je bug, ktorý sa deje iba 1 hodinu denne, keď nikto nepracuje, a nedá sa dobre nasimulovať ani debugovať.&lt;/p&gt;

&lt;p&gt;Čiže ak dátum uložíme do &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;FrozenTime&lt;/code&gt; s časom &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;00:00:00&lt;/code&gt; a so správnou timezone, vyhneme sa tomuto bugu.&lt;/p&gt;

&lt;h2 id=&quot;ako-pracovať-s-dátumami-ktoré-nemajú-timezone&quot;&gt;Ako pracovať s dátumami, ktoré nemajú timezone?&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;Účtovníctvo: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AccountingDate&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ostatné?&lt;/p&gt;

&lt;p&gt;🤷‍♂️&lt;/p&gt;

&lt;p&gt;Zákon nateraz nešpecifikuje. Niektoré z možností:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;môžu ostať ako stringy,&lt;/li&gt;
  &lt;li&gt;alebo si spravíme vlastný Date,&lt;/li&gt;
  &lt;li&gt;alebo použijeme &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;FrozenTime&lt;/code&gt; s nejakou rozumnou timezone (napr. rozumná timezone pre moje narodeniny je taká, kde práve žijem - narodeninový email by som nemal dostať skôr alebo neskôr).&lt;/li&gt;
&lt;/ul&gt;</content><author><name></name></author><category term="Tech &gt; PHP &gt; CakePHP" /><summary type="html">Time, Date a FrozenDate sú zakázané. Vždy treba používať iba FrozenTime. Pretože: Time a Date sú mutable, FrozenDate a Date nepodporujú timezone-y a zároveň majú niektoré metódy, ktoré na timezone závisia (napr. isToday()), je to Chronos bug.</summary></entry><entry><title type="html"># 07 Stav meniace HTTP služby sa nesmú dať spustiť cez GET metódu</title><link href="/programming-laws/tech%20%3E%20http/7-get-only-stateless.html" rel="alternate" type="text/html" title="# 07 Stav meniace HTTP služby sa nesmú dať spustiť cez GET metódu" /><published>2020-02-17T13:15:50+00:00</published><updated>2020-02-17T13:15:50+00:00</updated><id>/programming-laws/tech%20%3E%20http/7-get-only-stateless</id><content type="html" xml:base="/programming-laws/tech%20%3E%20http/7-get-only-stateless.html">&lt;p&gt;Zmena stavu je vykonanie nejakej trvalej zmeny/operácie. Štandardne tam patrí pridanie, editácia alebo zmazanie nejakého “resource”.&lt;/p&gt;

&lt;p&gt;HTTP služby spravené cez GET metódu by nemali robiť žiadne zo stav meniacich operácií, kvôli:&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;náchylnosti na druhy chýb/probémov, ktoré nemáme pod kontrolou my,&lt;/li&gt;
  &lt;li&gt;bezpečnosti používateľov.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&quot;1-náchylnosť-na-chybyproblémy-ktoré-nemáme-pod-kontrolou&quot;&gt;1. Náchylnosť na chyby/problémy, ktoré nemáme pod kontrolou&lt;/h2&gt;
&lt;p&gt;HTTP služby spravené cez GET sú bežne interpretované ako read-only. Preto sa dajú link-ovať, bookmark-ovať, cache-ovať alebo refresh-ovať.
Predpoklad je, že GET služby/linky sa môžu bezstarostne spúštať dookola a nič sa nestane. Cache si napríklad môže načitať novú verziu stránky, prehliadač môže zavolať bookmarknutý link aby zobrazil používateľovi náhľad stránky. Používateľ môže dookola stáčať F5/refresh, atď.&lt;/p&gt;

&lt;p&gt;Ak teda GET služba bude meniť stav, môžu vznikať bugy, ktoré sa budú javiť vzácne a nevysvetliteľné. Napríklad používateľovi vždy záhladne zmiznú rovnaké 2 knižky z wishlistu, alebo produkty, ktoré používateľ nehodnotil, budú mať 5 hviezdičiek, atď. A jediná možná oprava je tak či tak iba prepísať operáciu na inú HTTP metódu než GET.&lt;/p&gt;

&lt;p&gt;Aby sme teda zabránili neočakávanému správaniu, operácie, ktoré nejakým spôsobom menia stav, nesmú byť spustiteľné cez GET. Tieto operácie sa vďaka tomu nebudú dať link-ovať, bookmark-ovať, cache-ovať ani refresh-ovať. Používateľ musí explicitne stlačiť button na to, aby sa vykonali.&lt;/p&gt;

&lt;h2 id=&quot;2-bezpečnosť-používateľov&quot;&gt;2. Bezpečnosť používateľov&lt;/h2&gt;
&lt;p&gt;POST, PUT, PATCH, DELETE requesty vedia mať ďalšie úrovne ochrany - napr. CSRF prevention, form tampering prevention. GET requesty ich nevedia mať. Ak teda GET requesty menia stav, vie ich zneužiť útočník (napr. vložiť sebe do stránky ako obrázky linky, ktoré vymažú wishlisty na Martinuse, hodnotia nejaký produkt, …). Jediné možné riešenie je prepísať operáciu na inú HTTP metódu než GET (a pridať CSRF ochranu).&lt;/p&gt;

&lt;h2 id=&quot;povolené-výnimky&quot;&gt;Povolené výnimky&lt;/h2&gt;
&lt;ol&gt;
  &lt;li&gt;Ak GET služba využíva nejakú formu autentifikácie/overenia, ktorá zabráni opätovnému vykonaniu danej služby - ideálne nejaký jednorazový token, ktorý nepoužitý expiruje - napríklad schválenie dovolenky z email-u alebo rozdelenie objednávky z email-u. Proste link sa bude dať použiť iba raz a nepoužitý link expiruje.&lt;/li&gt;
  &lt;li&gt;Ak je to žiadaná feature aplikácie, ktorá sa nedá implementovať inak - napríklad link na vloženie produktu do košíka alebo link na odhlásenie.&lt;/li&gt;
&lt;/ol&gt;</content><author><name></name></author><category term="Tech &gt; HTTP" /><summary type="html">Zmena stavu je vykonanie nejakej trvalej zmeny/operácie. Štandardne tam patrí pridanie, editácia alebo zmazanie nejakého “resource”.</summary></entry><entry><title type="html"># 08 - Podmienky musia byť napísané jednoducho</title><link href="/programming-laws/apps/8-simple-conditions.html" rel="alternate" type="text/html" title="# 08 - Podmienky musia byť napísané jednoducho" /><published>2020-02-17T13:15:50+00:00</published><updated>2020-02-17T13:15:50+00:00</updated><id>/programming-laws/apps/8-simple-conditions</id><content type="html" xml:base="/programming-laws/apps/8-simple-conditions.html">&lt;p&gt;Pod podmienkami sa myslia všetky &lt;em&gt;boolean expressions&lt;/em&gt;. Komplikované podmienky sa ťažko čítajú, ťažko chápu a sú náchylné na chyby.&lt;/p&gt;

&lt;h2 id=&quot;presné-pravidlá&quot;&gt;Presné pravidlá&lt;/h2&gt;

&lt;h3 id=&quot;1-v-jednej-podmienke-je-zakázané-miešať-and-a-or-operátory&quot;&gt;1. V jednej podmienke je zakázané miešať AND a OR operátory&lt;/h3&gt;

&lt;p&gt;Nesprávne:&lt;/p&gt;
&lt;div class=&quot;language-php highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(((&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;is_null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$deliveryType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$deliveryType&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;id&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;DeliveryType&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;POST_SK_FOREIGN&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;is_null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$deliveryAddress&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$deliveryAddress&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;isSlovakia&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$deliveryAddress&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;isCzechRepublic&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())))&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;is_null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$paymentType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$paymentType&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;isCash&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()))&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// ...&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Správne:&lt;/p&gt;
&lt;div class=&quot;language-php highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$isDeliveryForeign&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;is_null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$deliveryType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; 
    &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$deliveryType&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;id&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;DeliveryType&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;POST_SK_FOREIGN&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;nv&quot;&gt;$isAddressForeign&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;is_null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$deliveryAddress&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; 
    &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$deliveryAddress&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;isSlovakia&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; 
    &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$deliveryAddress&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;isCzechRepublic&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;

&lt;span class=&quot;nv&quot;&gt;$isOrderForeign&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$isDeliveryForeign&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$isAddressForeign&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;nv&quot;&gt;$isPaymentCash&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;is_null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$paymentType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$paymentType&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;isCash&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$isOrderForeign&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$isPaymentCash&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// ...&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;</content><author><name></name></author><category term="Apps" /><summary type="html">Pod podmienkami sa myslia všetky boolean expressions. Komplikované podmienky sa ťažko čítajú, ťažko chápu a sú náchylné na chyby.</summary></entry></feed>