<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:creativeCommons="http://backend.userland.com/creativeCommonsRssModule" version="2.0"><channel><title>/home/Śpiechu-&gt;Blog</title> <link>http://spiechu.pl</link> <description>o wszystkim co się nawinie… a najczęściej o PHP, Linuksie i szerzącej się głupocie</description> <lastBuildDate>Thu, 17 May 2012 05:51:04 +0000</lastBuildDate> <language>en</language> <sy:updatePeriod>hourly</sy:updatePeriod> <sy:updateFrequency>1</sy:updateFrequency> <generator>http://wordpress.org/?v=3.3.2</generator> <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/spiechu" /><feedburner:info xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" uri="spiechu" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><creativeCommons:license>http://creativecommons.org/licenses/by-nc-sa/2.5/</creativeCommons:license><image><link>http://creativecommons.org/licenses/by-nc-sa/2.5/</link><url>http://creativecommons.org/images/public/somerights20.gif</url><title>Some Rights Reserved</title></image><item><title>Tworzenie pakietów ICMP w PHP</title><link>http://spiechu.pl/2012/05/16/tworzenie-pakietow-icmp-w-php/</link> <comments>http://spiechu.pl/2012/05/16/tworzenie-pakietow-icmp-w-php/#comments</comments> <pubDate>Wed, 16 May 2012 17:26:00 +0000</pubDate> <dc:creator>Śpiechu</dc:creator> <category><![CDATA[webmastering]]></category> <category><![CDATA[gist]]></category> <category><![CDATA[github]]></category> <category><![CDATA[icmp]]></category> <category><![CDATA[php]]></category><guid isPermaLink="false">http://spiechu.pl/?p=1305</guid> <description><![CDATA[Od tygodnia na poważnie wziąłem się za rozpracowywanie protokołów sieciowych. Dzisiaj schodzimy na poziom najniższy jaki się da w programowaniu, czyli zer i jedynek. Ja jako osoba za 2 miesiące rozpoczynająca zawodowo przygodę z programowaniem (ojej, wydało się ;-) ) muszę mieć dosyć dobre pojęcie jak to się dzieje, że wpisuję adres www w pasku <a
href="http://spiechu.pl/2012/05/16/tworzenie-pakietow-icmp-w-php/"> read more <span
class="meta-nav">&#187;</span></a>]]></description> <content:encoded><![CDATA[<p>Od tygodnia na poważnie wziąłem się za rozpracowywanie protokołów sieciowych. Dzisiaj schodzimy na poziom najniższy jaki się da w programowaniu, czyli zer i jedynek. Ja jako osoba za 2 miesiące rozpoczynająca zawodowo przygodę z programowaniem (ojej, wydało się ;-) ) muszę mieć dosyć dobre pojęcie jak to się dzieje, że wpisuję adres www w pasku adresu przeglądarki, naciskam enter i pokazuje się Fejsbuk. Oczywiście zwykli użytkownicy internetu nie muszą wiedzieć jak to dokładnie działa w myśl zasady „nie muszę być mechanikiem samochodowym żeby jeździć autem”.</p><p>Wobec tego na warsztat wziąłem na początek rzecz dosyć prostą: ICMP, a nawet tylko jego wycinek pod nazwą <em><a
href="http://en.wikipedia.org/wiki/ICMP_Echo_Request">Echo request/Echo reply</a></em>. Komunikaty ICMP stanowią podstawę działania internetu. Każda maszyna podłączona do sieci potrafi zadawać pytania i otrzymywać odpowiedzi w postaci ICMP. Tak naprawdę zdubluję funkcjonalność wbudowaną w każdy system operacyjny pod powszechnie znaną nazwą <em>ping</em>.</p><p>Ręczne tworzenie pakietów w PHP nie ma oczywiście większego sensu poza edukacyjnym (no chyba, że tworzymy coś nietypowego lub dostosowujemy się do już istniejącego protokołu). Jeśli potrzebujemy coś „pingnąć”, wywołujemy polecenie <em>ping</em> shella z poziomu skryptu PHP i tyle.</p><p><a
href="https://gist.github.com/2661592">W Gist zamieściłem klasę</a> gotową do użytku. Na Linuksie będzie problem z jej odpaleniem, gdyż bez roota nie wywołamy funkcji <code>socket_create()</code>. Ten temat jest na tyle ciekawy, że zostawię sobie na następny wpis.</p><p>Sama struktura protokołu jest dosyć prosta. Mamy 6 elementów:</p><ul><li>8 bitów typ żądania (<code>0x08</code> w przypadku echo request, <code>0x00</code> w przypadku echo reply),</li><li>8 bitów kod żądania (<code>0x00</code>),</li><li>16 bitów suma kontrolna (tzw. <em>internet checksum</em>, o którym trochę niżej),</li><li>16 bitów identyfikator (losowa liczba z zakresu <code>0x000 - 0xFFFF</code>),</li><li>16 bitów nr sekwencyjny (<code>0x00</code>),</li><li>8– bitów dane (znaki ASCII).</li></ul><p>Operując niskopoziomowo musimy zaprzyjaźnić się z funkcjami <code>pack()</code> i <code>unpack()</code> w celu stworzenia i odczytu reprezentacji bitowej ciągu. W przypadku ICMP będzie to wyglądało tak:</p><div
class="wp_syntax"><div
class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">const</span> PACKET_REQUEST_TEMPLATE <span style="color: #339933;">=</span> <span style="color: #0000ff;">'CCnnnA*'</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">const</span> PACKET_RESPOND_TEMPLATE <span style="color: #339933;">=</span> <span style="color: #0000ff;">'Ctype/Ccode/nchecksum/nuid/nseq/A*message'</span><span style="color: #339933;">;</span></pre></div></div><p>Widać, że 1 bajt możemy odzwierciedlić w postaci typu <em>unsigned char</em>, a 2 bajty w postaci <em>unsigned short</em>.</p><p>Teraz może nasunąć się pytanie jak wypełnić pole checksum, skoro jest gdzieś w środku? Odpowiedź jest prosta: w pole wpisujemy tymczasowo <code>0x00</code>, obliczamy sumę kontrolną dla całości, a następnie zastępujemy wynikiem. Jest to dokładnie 3 i 4 bajt. Jak obliczyć sumę kontrolną? Jest do tego <a
href="http://www.ietf.org/rfc/rfc1071.txt">RFC z 1988 r.</a> pod nazwą <em>Computing the Internet Checksum</em>. Jednak zanim zniechęcicie się suchym żargonem informatycznym wytłumaczę po ludzku:</p><ol><li>Cały pakiet ćwiartujemy na kawałki po 16 bitów,</li><li>sumujemy wszystko,</li><li>jeśli w wyniku powstaje nam jakaś nadwyżka w postaci 17 i więcej bitu, odcinamy ją, a następnie dodajemy do pozostałych 16tu,</li><li>ponownie sprawdzamy czy nie powstała nam nadwyżka,</li><li>odwracamy wynik.</li></ol><p>Zapis w PHP:</p><div
class="wp_syntax"><div
class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000000; font-weight: bold;">function</span> computeChecksum<span style="color: #009900;">&#40;</span><span style="color: #000088;">$packet</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
  <span style="color: #666666; font-style: italic;">// treat the whole packet as 16 bits unsigned short integers</span>
  <span style="color: #000088;">$seqPer16bits</span> <span style="color: #339933;">=</span> <span style="color: #990000;">unpack</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'n*'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$packet</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #000088;">$sum</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array_sum</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$seqPer16bits</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #666666; font-style: italic;">// if there is a carry above 16 bit, add it at the beginning</span>
  <span style="color: #000088;">$sum</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$sum</span> <span style="color: #339933;">&gt;&gt;</span> <span style="color: #cc66cc;">16</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">+</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$sum</span> <span style="color: #339933;">&amp;</span> <span style="color: #208080;">0xFFFF</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #666666; font-style: italic;">// double check if there is no new carry after previous addition</span>
  <span style="color: #000088;">$sum</span> <span style="color: #339933;">+=</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$sum</span> <span style="color: #339933;">&gt;&gt;</span> <span style="color: #cc66cc;">16</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #666666; font-style: italic;">// return 16 bits negate</span>
  <span style="color: #b1b100;">return</span> <span style="color: #990000;">pack</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'n'</span><span style="color: #339933;">,</span> ~<span style="color: #000088;">$sum</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div><p>Jak „wkleić” wynik w dobre miejsce? Mała sztuczka:</p><div
class="wp_syntax"><div
class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$packet</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">2</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$checkSum</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// 3 bajt pakietu</span>
<span style="color: #000088;">$packet</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">3</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$checkSum</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// 4 bajt pakietu</span></pre></div></div><p>Następnie możemy sobie stworzyć gniazdo i ustawić jakiś timeout:</p><div
class="wp_syntax"><div
class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_socket <span style="color: #339933;">=</span> <span style="color: #990000;">socket_create</span><span style="color: #009900;">&#40;</span>
  AF_INET<span style="color: #339933;">,</span> SOCK_RAW<span style="color: #339933;">,</span> <span style="color: #990000;">getprotobyname</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'icmp'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #990000;">socket_set_option</span><span style="color: #009900;">&#40;</span>
  <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_socket<span style="color: #339933;">,</span> SOL_SOCKET<span style="color: #339933;">,</span> SO_RCVTIMEO<span style="color: #339933;">,</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
    <span style="color: #0000ff;">'sec'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">,</span>
    <span style="color: #0000ff;">'usec'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div><p>Jesteśmy gotowi do wysyłki:</p><div
class="wp_syntax"><div
class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> sendPacket<span style="color: #009900;">&#40;</span><span style="color: #000088;">$destination</span><span style="color: #339933;">,</span> <span style="color: #000088;">$message</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">self</span><span style="color: #339933;">::</span><span style="color: #004000;">DEFAULT_MSG</span><span style="color: #339933;">,</span> <span style="color: #000088;">$port</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #000088;">$packet</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getNewPacket</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$message</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #990000;">socket_sendto</span><span style="color: #009900;">&#40;</span>
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_socket<span style="color: #339933;">,</span> <span style="color: #000088;">$packet</span><span style="color: #339933;">,</span> <span style="color: #990000;">strlen</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$packet</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">,</span> <span style="color: #000088;">$destination</span><span style="color: #339933;">,</span> <span style="color: #000088;">$port</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #000088;">$respond</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
  <span style="color: #990000;">socket_recvfrom</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_socket<span style="color: #339933;">,</span> <span style="color: #000088;">$respond</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">255</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">,</span> <span style="color: #000088;">$destination</span><span style="color: #339933;">,</span> <span style="color: #000088;">$port</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #666666; font-style: italic;">// strip IP header</span>
  <span style="color: #b1b100;">return</span> <span style="color: #990000;">substr</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$respond</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">20</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div><p>Jeśli odbieramy pakiet, warto poddać go analizie:</p><div
class="wp_syntax"><div
class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> analyzeRespond<span style="color: #009900;">&#40;</span><span style="color: #000088;">$responsePacket</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #000088;">$unpackedRespond</span> <span style="color: #339933;">=</span> <span style="color: #990000;">unpack</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">self</span><span style="color: #339933;">::</span><span style="color: #004000;">PACKET_RESPOND_TEMPLATE</span><span style="color: #339933;">,</span> <span style="color: #000088;">$responsePacket</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$unpackedRespond</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'type'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">!==</span> <span style="color: #000000; font-weight: bold;">self</span><span style="color: #339933;">::</span><span style="color: #004000;">TYPE_RESPONSE</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">throw</span> <span style="color: #000000; font-weight: bold;">new</span> Exception<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Bad response type'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$unpackedRespond</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'uid'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">!==</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_uid<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">throw</span> <span style="color: #000000; font-weight: bold;">new</span> Exception<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Bad unique id'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #666666; font-style: italic;">// set 3rd and 4th checksum byte to 0x00</span>
  <span style="color: #666666; font-style: italic;">// in order to calculate correct checksum</span>
  <span style="color: #000088;">$responsePacket</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">2</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #990000;">pack</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'C'</span><span style="color: #339933;">,</span> <span style="color: #000000; font-weight: bold;">self</span><span style="color: #339933;">::</span><span style="color: #004000;">INITIAL_CHECKSUM</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #000088;">$responsePacket</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">3</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #990000;">pack</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'C'</span><span style="color: #339933;">,</span> <span style="color: #000000; font-weight: bold;">self</span><span style="color: #339933;">::</span><span style="color: #004000;">INITIAL_CHECKSUM</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">pack</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'n*'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$unpackedRespond</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'checksum'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">!==</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">computeChecksum</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$responsePacket</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">throw</span> <span style="color: #000000; font-weight: bold;">new</span> Exception<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Bad checksum'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
  <span style="color: #b1b100;">return</span> <span style="color: #000088;">$unpackedRespond</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'message'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div><p>Zdaję sobie sprawę, że opis jest niepełny. Chciałem zwrócić uwagę na ciekawsze/trudniejsze momenty. Proponuję dokładnie przeanalizować sobie całą klasę z linka podanego powyżej.</p><p>Tak jak obiecałem, w następnym wpisie opiszę jak to wywoływać w możliwie bezpiecznym środowisku.</p><div
class="google_plusone_widget" style="margin-bottom:10px"><g:plusone
count="false" href="http://spiechu.pl/2012/05/16/tworzenie-pakietow-icmp-w-php/" size="standard"></g:plusone></div>]]></content:encoded> <wfw:commentRss>http://spiechu.pl/2012/05/16/tworzenie-pakietow-icmp-w-php/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>Creating EAN-13 barcode using CoffeeScript and HTML5 Canvas</title><link>http://spiechu.pl/2012/04/30/creating-ean-13-barcode-using-coffeescript-and-html5-canvas/</link> <comments>http://spiechu.pl/2012/04/30/creating-ean-13-barcode-using-coffeescript-and-html5-canvas/#comments</comments> <pubDate>Mon, 30 Apr 2012 09:44:30 +0000</pubDate> <dc:creator>Śpiechu</dc:creator> <category><![CDATA[webmastering]]></category> <category><![CDATA[canvas]]></category> <category><![CDATA[coffeescript]]></category> <category><![CDATA[english]]></category> <category><![CDATA[github]]></category> <category><![CDATA[javascript]]></category><guid isPermaLink="false">http://spiechu.pl/?p=1294</guid> <description><![CDATA[It’s been a long time since I’ve written my last english-spoken text. It was about Webworkers API. The visitors number has been achieved, so it’s time for the next topic. Now I’m going to talk about Canvas and some CoffeeScript tricks. Again I’m asking You to forgive me my „language glitches”. Since I don’t like <a
href="http://spiechu.pl/2012/04/30/creating-ean-13-barcode-using-coffeescript-and-html5-canvas/"> read more <span
class="meta-nav">&#187;</span></a>]]></description> <content:encoded><![CDATA[<p>It’s been a long time since I’ve written my last english-spoken text. <a
href="http://spiechu.pl/2010/07/28/multithreading-in-web-browser-web-workers-jquery/">It was about Webworkers API</a>. The visitors number has been achieved, so it’s time for the next topic. Now I’m going to talk about Canvas and some CoffeeScript tricks. Again I’m asking You to forgive me my „language glitches”.</p><p>Since I don’t like to get to know about something new in an abstract way, we’ll going to write a simple EAN-13 barcode generator. You meet it at every store, it saves time and money for merchants. Price can be attached to barcode instead of price tags. Imagine changing a price in the same 100 products. But how to generate one? Wikipedia has a <a
href="http://en.wikipedia.org/wiki/International_Article_Number_%28EAN%29">nice description</a>. EAN-13 is composed of GS1 organization numbers, company numbers, item reference and check digit.</p><p>This time I’m going to cover some CoffeScript features I didn’t talk about 2 posts earlier: extending classes and static properties. I’ll write one class computing „0101…” EAN-13 code and another one capable of drawing the code on HTML canvas element. I even created a <a
href="https://github.com/spiechu/EAN-13-Barcode-Canvas-Drawer">public GitHub repository</a>, so feel free to steal some code. Working example <a
href="http://spiechu.pl/ean13/test.html">can be found here</a>.</p><p>I won’t explain You all code here, only the most important parts. For example how to compute control digit?</p><div
class="wp_syntax"><div
class="code"><pre class="python" style="font-family:monospace;">computeControlSum: -<span style="color: #66cc66;">&gt;</span>
  <span style="color: #008000;">sum</span> = <span style="color: #ff4500;">0</span>
&nbsp;
  <span style="color: #808080; font-style: italic;"># this one line of array comprehension substitutes four lines in pure JS</span>
  <span style="color: #008000;">sum</span> += <span style="color: black;">&#40;</span><span style="color: #ff7700;font-weight:bold;">if</span> key <span style="color: #66cc66;">%</span> <span style="color: #ff4500;">2</span> then <span style="color: #ff4500;">3</span> <span style="color: #ff7700;font-weight:bold;">else</span> <span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span> <span style="color: #66cc66;">*</span> value <span style="color: #ff7700;font-weight:bold;">for</span> value, key <span style="color: #ff7700;font-weight:bold;">in</span> @eanArray
  controlSum = <span style="color: #ff4500;">10</span> - <span style="color: #008000;">sum</span> <span style="color: #66cc66;">%</span> <span style="color: #ff4500;">10</span>
  <span style="color: #ff7700;font-weight:bold;">if</span> controlSum == <span style="color: #ff4500;">10</span> then controlSum = <span style="color: #ff4500;">0</span>
  <span style="color: #ff7700;font-weight:bold;">return</span> controlSum</pre></div></div><p>Piece of code above is translated into:</p><div
class="wp_syntax"><div
class="code"><pre class="javascript" style="font-family:monospace;">EAN13Generator.<span style="color: #660066;">prototype</span>.<span style="color: #660066;">computeControlSum</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #003366; font-weight: bold;">var</span> controlSum<span style="color: #339933;">,</span> key<span style="color: #339933;">,</span> sum<span style="color: #339933;">,</span> value<span style="color: #339933;">,</span> _i<span style="color: #339933;">,</span> _len<span style="color: #339933;">,</span> _ref<span style="color: #339933;">;</span>
  sum <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span>
  _ref <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">eanArray</span><span style="color: #339933;">;</span>
  <span style="color: #000066; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span>key <span style="color: #339933;">=</span> _i <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">,</span> _len <span style="color: #339933;">=</span> _ref.<span style="color: #660066;">length</span><span style="color: #339933;">;</span> _i <span style="color: #339933;">&lt;</span> _len<span style="color: #339933;">;</span> key <span style="color: #339933;">=</span> <span style="color: #339933;">++</span>_i<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    value <span style="color: #339933;">=</span> _ref<span style="color: #009900;">&#91;</span>key<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
    sum <span style="color: #339933;">+=</span> <span style="color: #009900;">&#40;</span>key <span style="color: #339933;">%</span> <span style="color: #CC0000;">2</span> <span style="color: #339933;">?</span> <span style="color: #CC0000;">3</span> <span style="color: #339933;">:</span> <span style="color: #CC0000;">1</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">*</span> value<span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
  controlSum <span style="color: #339933;">=</span> <span style="color: #CC0000;">10</span> <span style="color: #339933;">-</span> sum <span style="color: #339933;">%</span> <span style="color: #CC0000;">10</span><span style="color: #339933;">;</span>
  <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>controlSum <span style="color: #339933;">===</span> <span style="color: #CC0000;">10</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    controlSum <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
  <span style="color: #000066; font-weight: bold;">return</span> controlSum<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span></pre></div></div><p>As we can see we don’t need to worry about some temporary variables in CoffeScript.</p><p>Digits 2–7 in barcode (before the central „whiskers”) can be written as odd or even. Pattern depends on first barcode digit. It has been written as object literal:</p><div
class="wp_syntax"><div
class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">class</span> EAN13Generator
&nbsp;
<span style="color: #808080; font-style: italic;"># some code here</span>
&nbsp;
  <span style="color: #808080; font-style: italic;"># this is how we create class properties</span>
  <span style="color: #808080; font-style: italic;"># we can call to such property like EAN13Generator.LEFT_SIDE_CODING</span>
  @LEFT_SIDE_CODING:
    <span style="color: #ff4500;">0</span>: <span style="color: black;">&#91;</span><span style="color: #483d8b;">'odd'</span>, <span style="color: #483d8b;">'odd'</span>,  <span style="color: #483d8b;">'odd'</span>,  <span style="color: #483d8b;">'odd'</span>,  <span style="color: #483d8b;">'odd'</span>,  <span style="color: #483d8b;">'odd'</span> <span style="color: black;">&#93;</span>
    <span style="color: #ff4500;">1</span>: <span style="color: black;">&#91;</span><span style="color: #483d8b;">'odd'</span>, <span style="color: #483d8b;">'odd'</span>,  <span style="color: #483d8b;">'even'</span>, <span style="color: #483d8b;">'odd'</span>,  <span style="color: #483d8b;">'even'</span>, <span style="color: #483d8b;">'even'</span><span style="color: black;">&#93;</span>
    <span style="color: #ff4500;">2</span>: <span style="color: black;">&#91;</span><span style="color: #483d8b;">'odd'</span>, <span style="color: #483d8b;">'odd'</span>,  <span style="color: #483d8b;">'even'</span>, <span style="color: #483d8b;">'even'</span>, <span style="color: #483d8b;">'odd'</span>,  <span style="color: #483d8b;">'even'</span><span style="color: black;">&#93;</span>
    <span style="color: #ff4500;">3</span>: <span style="color: black;">&#91;</span><span style="color: #483d8b;">'odd'</span>, <span style="color: #483d8b;">'odd'</span>,  <span style="color: #483d8b;">'even'</span>, <span style="color: #483d8b;">'even'</span>, <span style="color: #483d8b;">'even'</span>, <span style="color: #483d8b;">'odd'</span> <span style="color: black;">&#93;</span>
    <span style="color: #ff4500;">4</span>: <span style="color: black;">&#91;</span><span style="color: #483d8b;">'odd'</span>, <span style="color: #483d8b;">'even'</span>, <span style="color: #483d8b;">'odd'</span>,  <span style="color: #483d8b;">'odd'</span>,  <span style="color: #483d8b;">'even'</span>, <span style="color: #483d8b;">'even'</span><span style="color: black;">&#93;</span>
    <span style="color: #ff4500;">5</span>: <span style="color: black;">&#91;</span><span style="color: #483d8b;">'odd'</span>, <span style="color: #483d8b;">'even'</span>, <span style="color: #483d8b;">'even'</span>, <span style="color: #483d8b;">'odd'</span>,  <span style="color: #483d8b;">'odd'</span>,  <span style="color: #483d8b;">'even'</span><span style="color: black;">&#93;</span>
    <span style="color: #ff4500;">6</span>: <span style="color: black;">&#91;</span><span style="color: #483d8b;">'odd'</span>, <span style="color: #483d8b;">'even'</span>, <span style="color: #483d8b;">'even'</span>, <span style="color: #483d8b;">'even'</span>, <span style="color: #483d8b;">'odd'</span>,  <span style="color: #483d8b;">'odd'</span> <span style="color: black;">&#93;</span>
    <span style="color: #ff4500;">7</span>: <span style="color: black;">&#91;</span><span style="color: #483d8b;">'odd'</span>, <span style="color: #483d8b;">'even'</span>, <span style="color: #483d8b;">'odd'</span>,  <span style="color: #483d8b;">'even'</span>, <span style="color: #483d8b;">'odd'</span>,  <span style="color: #483d8b;">'even'</span><span style="color: black;">&#93;</span>
    <span style="color: #ff4500;">8</span>: <span style="color: black;">&#91;</span><span style="color: #483d8b;">'odd'</span>, <span style="color: #483d8b;">'even'</span>, <span style="color: #483d8b;">'odd'</span>,  <span style="color: #483d8b;">'even'</span>, <span style="color: #483d8b;">'even'</span>, <span style="color: #483d8b;">'odd'</span> <span style="color: black;">&#93;</span>
    <span style="color: #ff4500;">9</span>: <span style="color: black;">&#91;</span><span style="color: #483d8b;">'odd'</span>, <span style="color: #483d8b;">'even'</span>, <span style="color: #483d8b;">'even'</span>, <span style="color: #483d8b;">'odd'</span>,  <span style="color: #483d8b;">'even'</span>, <span style="color: #483d8b;">'odd'</span> <span style="color: black;">&#93;</span></pre></div></div><p>The next interesing part is how to concatenate barcode string. Here’s how:</p><div
class="wp_syntax"><div
class="code"><pre class="python" style="font-family:monospace;">generateEANcode: -<span style="color: #66cc66;">&gt;</span>
&nbsp;
  <span style="color: #808080; font-style: italic;"># we're using class property to find out first 6 digits coding</span>
  codingStyle = EAN13Generator.<span style="color: black;">LEFT_SIDE_CODING</span><span style="color: black;">&#91;</span>@eanArray<span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span><span style="color: black;">&#93;</span>
  eanCode = EAN13Generator.<span style="color: black;">START_SENTINEL</span>
  <span style="color: #ff7700;font-weight:bold;">for</span> i <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span>..<span style="color: #ff4500;">6</span><span style="color: black;">&#93;</span>
    <span style="color: #ff7700;font-weight:bold;">if</span> codingStyle<span style="color: black;">&#91;</span>i-<span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span> == <span style="color: #483d8b;">'odd'</span>
      eanCode += EAN13Generator.<span style="color: black;">EAN_13_CODE_TABLE</span><span style="color: black;">&#91;</span>@eanArray<span style="color: black;">&#91;</span>i<span style="color: black;">&#93;</span><span style="color: black;">&#93;</span>.<span style="color: black;">left</span>.<span style="color: black;">odd</span>
    <span style="color: #ff7700;font-weight:bold;">else</span>
      eanCode += EAN13Generator.<span style="color: black;">EAN_13_CODE_TABLE</span><span style="color: black;">&#91;</span>@eanArray<span style="color: black;">&#91;</span>i<span style="color: black;">&#93;</span><span style="color: black;">&#93;</span>.<span style="color: black;">left</span>.<span style="color: black;">even</span>
  eanCode += EAN13Generator.<span style="color: black;">CENTRAL_SENTINEL</span>       
  eanCode += <span style="color: black;">&#40;</span>EAN13Generator.<span style="color: black;">EAN_13_CODE_TABLE</span><span style="color: black;">&#91;</span>@eanArray<span style="color: black;">&#91;</span>i<span style="color: black;">&#93;</span><span style="color: black;">&#93;</span>.<span style="color: black;">right</span><span style="color: black;">&#41;</span> <span style="color: #ff7700;font-weight:bold;">for</span> i <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: black;">&#91;</span><span style="color: #ff4500;">7</span>..<span style="color: #ff4500;">12</span><span style="color: black;">&#93;</span>
  eanCode += EAN13Generator.<span style="color: black;">END_SENTINEL</span></pre></div></div><p>Class extension is realized through extends keyword.</p><div
class="wp_syntax"><div
class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">class</span> EAN13CanvasDrawer extends EAN13Generator
&nbsp;
  <span style="color: #808080; font-style: italic;"># @canvasId is shorthand for @canvasId = canvasId</span>
  constructor: <span style="color: black;">&#40;</span>eanString, @canvasId<span style="color: black;">&#41;</span> -<span style="color: #66cc66;">&gt;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;"># we're launching EAN13Generator constructor</span>
    <span style="color: #008000;">super</span><span style="color: black;">&#40;</span>eanString<span style="color: black;">&#41;</span></pre></div></div><p>I’m using jCanvaScript JS library to draw on canvas. Below is the whole drawBarcode() method:</p><div
class="wp_syntax"><div
class="code"><pre class="python" style="font-family:monospace;">drawBarcode: -<span style="color: #66cc66;">&gt;</span>
  jc.<span style="color: black;">clear</span> @canvasId
  jc.<span style="color: black;">start</span> @canvasId
  splitArray = @generateEANcode<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>.<span style="color: black;">split</span> <span style="color: #483d8b;">''</span>   
  barStartActual = @barStartX  
  <span style="color: #ff7700;font-weight:bold;">for</span> i, key <span style="color: #ff7700;font-weight:bold;">in</span> splitArray
    barHeightActual = @barHeight
&nbsp;
    <span style="color: #808080; font-style: italic;"># barcode longer 'whiskers'</span>
    <span style="color: #ff7700;font-weight:bold;">if</span> key <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span>,<span style="color: #ff4500;">1</span>,<span style="color: #ff4500;">2</span>,<span style="color: #ff4500;">45</span>,<span style="color: #ff4500;">46</span>,<span style="color: #ff4500;">47</span>,<span style="color: #ff4500;">48</span>,<span style="color: #ff4500;">49</span>,<span style="color: #ff4500;">92</span>,<span style="color: #ff4500;">93</span>,<span style="color: #ff4500;">94</span><span style="color: black;">&#93;</span> then barHeightActual = @barLongerHeight
&nbsp;
    <span style="color: #808080; font-style: italic;"># draw white stripe</span>
    <span style="color: #ff7700;font-weight:bold;">if</span> i == <span style="color: #483d8b;">'0'</span>
      jc.<span style="color: black;">rect</span> barStartActual, @barStartY, @barWidth, barHeightActual, <span style="color: #483d8b;">'rgb(255,255,255)'</span>, true
    <span style="color: #ff7700;font-weight:bold;">else</span>
      jc.<span style="color: black;">rect</span> barStartActual, @barStartY, @barWidth, barHeightActual, <span style="color: #483d8b;">'rgb(0,0,0)'</span>, true
  barStartActual += @barWidth    
  jc.<span style="color: black;">start</span> @canvasId
&nbsp;
  <span style="color: #808080; font-style: italic;"># drawing numbers below the stripes</span>
  textStartActual = @textStartX
  <span style="color: #ff7700;font-weight:bold;">for</span> i, key <span style="color: #ff7700;font-weight:bold;">in</span> @eanArray
    <span style="color: #ff7700;font-weight:bold;">if</span> key <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span>,<span style="color: #ff4500;">7</span><span style="color: black;">&#93;</span> then textStartActual += @textBreak
    jc.<span style="color: black;">text</span><span style="color: black;">&#40;</span>i, textStartActual, @textStartY<span style="color: black;">&#41;</span>.<span style="color: black;">font</span> <span style="color: #483d8b;">&quot;#{@textSize}px courier bold&quot;</span>
    textStartActual += @textStep
  jc.<span style="color: black;">start</span> @canvasId</pre></div></div><p>The final execution of code is just as simple as:</p><div
class="wp_syntax"><div
class="code"><pre class="python" style="font-family:monospace;">barcodeDrawer = <span style="color: #dc143c;">new</span> EAN13CanvasDrawer $<span style="color: black;">&#40;</span><span style="color: #483d8b;">'input#ean_13'</span><span style="color: black;">&#41;</span>.<span style="color: black;">val</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>, <span style="color: #483d8b;">'canvas_1'</span>
barcodeDrawer.<span style="color: black;">drawBarcode</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></div></div><div
class="google_plusone_widget" style="margin-bottom:10px"><g:plusone
count="false" href="http://spiechu.pl/2012/04/30/creating-ean-13-barcode-using-coffeescript-and-html5-canvas/" size="standard"></g:plusone></div>]]></content:encoded> <wfw:commentRss>http://spiechu.pl/2012/04/30/creating-ean-13-barcode-using-coffeescript-and-html5-canvas/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>Testowanie localStorage, embedded gist i CoffeeScript</title><link>http://spiechu.pl/2012/04/15/testowanie-localstorage-embedded-gist-i-coffeescript/</link> <comments>http://spiechu.pl/2012/04/15/testowanie-localstorage-embedded-gist-i-coffeescript/#comments</comments> <pubDate>Sun, 15 Apr 2012 19:17:30 +0000</pubDate> <dc:creator>Śpiechu</dc:creator> <category><![CDATA[webmastering]]></category> <category><![CDATA[coffeescript]]></category> <category><![CDATA[gist]]></category> <category><![CDATA[github]]></category> <category><![CDATA[javascript]]></category><guid isPermaLink="false">http://spiechu.pl/?p=1277</guid> <description><![CDATA[Mamy niedzielę, więc warto trochę poprogramować dla sportu (oczywiście zamiast uprawiania „normalnego” sportu :-) ). Z głupoty chciałem rozpracować kilka rzeczy. Przede wszystkim wprawić się trochę w CoffeeScript, a przy okazji sprawdzić w działaniu zapisywanie danych po stronie przeglądarki przy użyciu localStorage. Moim dzisiejszym zamiarem było stworzenie strony z formularzem, w którym wpisywane wartości zapisywałyby <a
href="http://spiechu.pl/2012/04/15/testowanie-localstorage-embedded-gist-i-coffeescript/"> read more <span
class="meta-nav">&#187;</span></a>]]></description> <content:encoded><![CDATA[<p>Mamy niedzielę, więc warto trochę poprogramować dla sportu (oczywiście zamiast uprawiania „normalnego” sportu :-) ). Z głupoty chciałem rozpracować kilka rzeczy. Przede wszystkim wprawić się trochę w CoffeeScript, a przy okazji sprawdzić w działaniu zapisywanie danych po stronie przeglądarki przy użyciu <a
href="http://dev.w3.org/html5/webstorage/#the-localstorage-attribute">localStorage</a>.</p><p>Moim dzisiejszym zamiarem było stworzenie strony z formularzem, w którym wpisywane wartości zapisywałyby się na bieżąco po stronie przeglądarki wpisującego. Powiedzmy, że jakaś sierotka podczas wypełniania formularza zamknie kartę/przeglądarkę i całe mozolne wpisywanie poszło w las. Dzięki localStorage wpisane dane nie zostaną skasowane, a formularz wypełni się automatycznie. Oczywiście niesie to za sobą szereg niebezpieczeństw, jak np. co w przypadku kogoś korzystającego z publicznego komputera, chcącego zamówić coś w sklepie internetowym i mu się nagle „odwidzi”? Następna osoba dostanie dane osobowe poprzednika na tacy. Minimalnym zabezpieczeniem byłby mechanizm kasujący dane jeśli są sprzed dłużej niż np. 2 minut.</p><p>Dodatkowo chciałem zrobić przycisk, który daje jakąś kontrolę nad przechowywanymi danymi. Efekt można sobie <a
href="http://spiechu.pl/local_storage/local_storage_test.html">oglądać tutaj</a>.</p><p>Używana przeze mnie wtyczka do kolorowania składni (WP-Syntax) nie obsługuje CS. Zamiast tego kod umieszczę za pomocą embedded gist z GitHub. Efekt jest bardzo ładny. Poniżej „mózg” formularza:<br
/><script src="https://gist.github.com/2394174.js?file=storager.coffee"></script><br
/> Efektu kompilacji nie pokazuję. Jeśli ktoś bardzo chce to może sobie <a
href="http://spiechu.pl/local_storage/storager.js">podejrzeć plik storager.js</a>.</p><p>Jeśli szukasz biblioteki backupu danych formularza w czasie rzeczywistym opartego o localStorage to polecam wtyczkę jQuery: <a
href="http://simsalabim.github.com/sisyphus/">Sisyphus</a>.</p><div
class="google_plusone_widget" style="margin-bottom:10px"><g:plusone
count="false" href="http://spiechu.pl/2012/04/15/testowanie-localstorage-embedded-gist-i-coffeescript/" size="standard"></g:plusone></div>]]></content:encoded> <wfw:commentRss>http://spiechu.pl/2012/04/15/testowanie-localstorage-embedded-gist-i-coffeescript/feed/</wfw:commentRss> <slash:comments>1</slash:comments> </item> <item><title>Wygrzebane z GitHuba (5) : CoffeeConsole</title><link>http://spiechu.pl/2012/04/09/wygrzebane-z-githuba-5-coffeeconsole/</link> <comments>http://spiechu.pl/2012/04/09/wygrzebane-z-githuba-5-coffeeconsole/#comments</comments> <pubDate>Mon, 09 Apr 2012 10:30:50 +0000</pubDate> <dc:creator>Śpiechu</dc:creator> <category><![CDATA[webmastering]]></category> <category><![CDATA[coffeescript]]></category> <category><![CDATA[javascipt]]></category><guid isPermaLink="false">http://spiechu.pl/?p=1260</guid> <description><![CDATA[W piątym odcinku Waszego ulubionego cyklu pojawi się projekt z tygodniowym stażem na GitHubie pod tytułem CoffeeConsole. Jest to interaktywna konsola języka CoffeeScript dla przeglądarki Chrome. Do tej pory trzeba było używać okienka „TRY COFFEESCRIPT” na stronie http://coffeescript.org (brak podświetlanej składni) lub instalować Node.js i npm. Dla niewtajemniczonych, CS jest tzw. „lukrem składniowym” na JavaScript, tzn. wynikiem kompilacji <a
href="http://spiechu.pl/2012/04/09/wygrzebane-z-githuba-5-coffeeconsole/"> read more <span
class="meta-nav">&#187;</span></a>]]></description> <content:encoded><![CDATA[<p>W piątym odcinku Waszego ulubionego cyklu pojawi się projekt z tygodniowym stażem na GitHubie pod tytułem <a
href="http://github.com/snookca/CoffeeConsole">CoffeeConsole</a>. Jest to interaktywna konsola języka <a
href="http://coffeescript.org/">CoffeeScript</a> dla przeglądarki Chrome. Do tej pory trzeba było używać okienka „TRY COFFEESCRIPT” na stronie <a
href="http://coffeescript.org/">http://coffeescript.org</a> (brak podświetlanej składni) lub instalować <a
href="http://nodejs.org/">Node.js</a> i <a
href="http://npmjs.org/">npm</a>.</p><p>Dla niewtajemniczonych, CS jest tzw. „lukrem składniowym” na JavaScript, tzn. wynikiem kompilacji CS jest czysty JS (który z kolei jeszcze można ścieśnić jakimś „zmniejszaczem” — minifierem). Składnia CS przypomina najbardziej Pythona (bloki kodu rozdzielane na podstawie wcięć, array comprehensions). Domieszano również nieco Rubyego (znak „?” przy zmiennych będący sprawdzeniem czy zmienna istnieje i „@” dla pól obieku).</p><p>Po ściągnięciu i rozpakowaniu pakietu wystarczy przeciągnąć plik coffeeconsole.crx na okno otwartego Chroma i rozpocznie się instalacja dodatku. Otrzymamy 2 pola edycji — lewy dla źródłowego CS i prawy dla wynikowego kodu JS.</p><p>Poniżej zademonstruję działanie tego cuda:</p><div
class="wp_syntax"><div
class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">###</span>
Przykladowy kod naskrobany w <span style="color: #ff4500;">5</span> <span style="color: #008000;">min</span>., nie zwracajcie na niego uwagi.
&nbsp;
<span style="color: black;">W</span> ten sposob w wynikowym JS powstanie komentarz np. <span style="color: black;">dotyczacy</span> licencji.
<span style="color: #808080; font-style: italic;">###</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># wartosc od ktorej humor jest dobry</span>
goodMoodThrottle = <span style="color: #ff4500;">51</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># tworze literal obiektowy</span>
peopleMood = 
    <span style="color: #483d8b;">'Dawid'</span>  : <span style="color: #ff4500;">100</span>
    <span style="color: #483d8b;">'Marta'</span>  : <span style="color: #ff4500;">78</span>
    <span style="color: #483d8b;">'Adam'</span>   : <span style="color: #ff4500;">53</span>
    <span style="color: #483d8b;">'Marian'</span> : <span style="color: #ff4500;">45</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># tworze funkcje o 2 parametrach</span>
getMoodString = <span style="color: black;">&#40;</span>name, goodMood<span style="color: black;">&#41;</span> -<span style="color: #66cc66;">&gt;</span>
    <span style="color: #808080; font-style: italic;"># zwracam uwage na konstrukcje if-then-else</span>
    <span style="color: #808080; font-style: italic;"># is zamieniane na ===</span>
    <span style="color: #808080; font-style: italic;"># oraz &quot;#{zmienna} cos tam dalej&quot;</span>
    <span style="color: #ff7700;font-weight:bold;">if</span> goodMood <span style="color: #ff7700;font-weight:bold;">is</span> true then <span style="color: #483d8b;">&quot;#{name} ma dobry humor&quot;</span> <span style="color: #ff7700;font-weight:bold;">else</span> <span style="color: #483d8b;">&quot;#{name} ma zły humor jak cholera&quot;</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># konstrukcja for-of dla petli po literalach obiektowych</span>
<span style="color: #ff7700;font-weight:bold;">for</span> name, moodLevel of peopleMood
    <span style="color: #808080; font-style: italic;"># kompilator sam domysli sie, ze chodzi nam o alert(getMoodString(name,(bool)))</span>
    alert getMoodString name, goodMoodThrottle <span style="color: #66cc66;">&lt;</span>= moodLevel <span style="color: #66cc66;">&lt;</span>= <span style="color: #ff4500;">100</span></pre></div></div><p>W okienku z prawej strony otrzymamy następujący wynik kompilacji:</p><div
class="wp_syntax"><div
class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">/*
Przykladowy kod naskrobany w 5 min., nie zwracajcie na niego uwagi.
&nbsp;
W ten sposob w wynikowym JS powstanie komentarz np. dotyczacy licencji.
*/</span>
&nbsp;
<span style="color: #003366; font-weight: bold;">var</span> getMoodString<span style="color: #339933;">,</span> goodMoodThrottle<span style="color: #339933;">,</span> moodLevel<span style="color: #339933;">,</span> <span style="color: #000066;">name</span><span style="color: #339933;">,</span> peopleMood<span style="color: #339933;">;</span>
&nbsp;
goodMoodThrottle <span style="color: #339933;">=</span> <span style="color: #CC0000;">51</span><span style="color: #339933;">;</span>
&nbsp;
peopleMood <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #3366CC;">'Dawid'</span><span style="color: #339933;">:</span> <span style="color: #CC0000;">100</span><span style="color: #339933;">,</span>
  <span style="color: #3366CC;">'Marta'</span><span style="color: #339933;">:</span> <span style="color: #CC0000;">78</span><span style="color: #339933;">,</span>
  <span style="color: #3366CC;">'Adam'</span><span style="color: #339933;">:</span> <span style="color: #CC0000;">53</span><span style="color: #339933;">,</span>
  <span style="color: #3366CC;">'Marian'</span><span style="color: #339933;">:</span> <span style="color: #CC0000;">45</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
getMoodString <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #000066;">name</span><span style="color: #339933;">,</span> goodMood<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>goodMood <span style="color: #339933;">===</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #3366CC;">&quot;&quot;</span> <span style="color: #339933;">+</span> <span style="color: #000066;">name</span> <span style="color: #339933;">+</span> <span style="color: #3366CC;">&quot; ma dobry humor&quot;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span> <span style="color: #000066; font-weight: bold;">else</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #3366CC;">&quot;&quot;</span> <span style="color: #339933;">+</span> <span style="color: #000066;">name</span> <span style="color: #339933;">+</span> <span style="color: #3366CC;">&quot; ma zły humor jak cholera&quot;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000066; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #000066;">name</span> <span style="color: #000066; font-weight: bold;">in</span> peopleMood<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  moodLevel <span style="color: #339933;">=</span> peopleMood<span style="color: #009900;">&#91;</span><span style="color: #000066;">name</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
  <span style="color: #000066;">alert</span><span style="color: #009900;">&#40;</span>getMoodString<span style="color: #009900;">&#40;</span><span style="color: #000066;">name</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#40;</span>goodMoodThrottle <span style="color: #339933;">&lt;=</span> moodLevel <span style="color: #339933;">&amp;&amp;</span> moodLevel <span style="color: #339933;">&lt;=</span> <span style="color: #CC0000;">100</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div><p>Patrząc na liczbę linii kodu mamy spory zysk w stosunku do wynikowego kodu JS. Przy okazji nie zajmujemy się zbędnymi średnikami i nawiasami.</p><p>Jeśli jeszcze Was nie przekonałem do użycia to proponuję zobaczyć tworzenie klas:</p><div
class="wp_syntax"><div
class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">class</span> Human
    constructor: <span style="color: black;">&#40;</span>@name<span style="color: black;">&#41;</span> -<span style="color: #66cc66;">&gt;</span>
&nbsp;
    whatIsYourName: -<span style="color: #66cc66;">&gt;</span>
        <span style="color: #483d8b;">&quot;Mam na imie #{@name}&quot;</span>
&nbsp;
people = <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span>
&nbsp;
people.<span style="color: black;">push</span> <span style="color: #dc143c;">new</span> Human <span style="color: #483d8b;">'Andrzej'</span>
people.<span style="color: black;">push</span> <span style="color: #dc143c;">new</span> Human <span style="color: #483d8b;">'Marian'</span>
people.<span style="color: black;">push</span> <span style="color: #dc143c;">new</span> Human <span style="color: #483d8b;">'Lucjan'</span>
&nbsp;
alert human.<span style="color: black;">whatIsYourName</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> <span style="color: #ff7700;font-weight:bold;">for</span> human <span style="color: #ff7700;font-weight:bold;">in</span> people</pre></div></div><p>Wynik w JS:</p><div
class="wp_syntax"><div
class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> Human<span style="color: #339933;">,</span> human<span style="color: #339933;">,</span> people<span style="color: #339933;">,</span> _i<span style="color: #339933;">,</span> _len<span style="color: #339933;">;</span>
&nbsp;
Human <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
  Human.<span style="color: #000066;">name</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">'Human'</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #003366; font-weight: bold;">function</span> Human<span style="color: #009900;">&#40;</span><span style="color: #000066;">name</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #000066;">name</span> <span style="color: #339933;">=</span> <span style="color: #000066;">name</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  Human.<span style="color: #660066;">prototype</span>.<span style="color: #660066;">whatIsYourName</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #3366CC;">&quot;Mam na imie &quot;</span> <span style="color: #339933;">+</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #000066;">name</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #000066; font-weight: bold;">return</span> Human<span style="color: #339933;">;</span>
&nbsp;
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
people <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
&nbsp;
people.<span style="color: #660066;">push</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">new</span> Human<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'Andrzej'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
people.<span style="color: #660066;">push</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">new</span> Human<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'Marian'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
people.<span style="color: #660066;">push</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">new</span> Human<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'Lucjan'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000066; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span>_i <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">,</span> _len <span style="color: #339933;">=</span> people.<span style="color: #660066;">length</span><span style="color: #339933;">;</span> _i <span style="color: #339933;">&lt;</span> _len<span style="color: #339933;">;</span> _i<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  human <span style="color: #339933;">=</span> people<span style="color: #009900;">&#91;</span>_i<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
  <span style="color: #000066;">alert</span><span style="color: #009900;">&#40;</span>human.<span style="color: #660066;">whatIsYourName</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div><p>Dla bardziej zainteresowanych tematem CoffeeScriptu polecam książkę <em>The Little Book on Coffee Script</em> <a
href="http://arcturo.github.com/library/coffeescript/">dostępną online</a>.</p><div
class="google_plusone_widget" style="margin-bottom:10px"><g:plusone
count="false" href="http://spiechu.pl/2012/04/09/wygrzebane-z-githuba-5-coffeeconsole/" size="standard"></g:plusone></div>]]></content:encoded> <wfw:commentRss>http://spiechu.pl/2012/04/09/wygrzebane-z-githuba-5-coffeeconsole/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>O modyfikatorach w Smarty i opisie słownym interwałów czasu</title><link>http://spiechu.pl/2012/03/16/o-modyfikatorach-w-smarty-i-opisie-slownym-interwalow-czasu/</link> <comments>http://spiechu.pl/2012/03/16/o-modyfikatorach-w-smarty-i-opisie-slownym-interwalow-czasu/#comments</comments> <pubDate>Fri, 16 Mar 2012 15:06:53 +0000</pubDate> <dc:creator>Śpiechu</dc:creator> <category><![CDATA[webmastering]]></category> <category><![CDATA[php]]></category> <category><![CDATA[smarty]]></category><guid isPermaLink="false">http://spiechu.pl/?p=1243</guid> <description><![CDATA[Pomysł na wpis dał mi kilka dni temu Facebook, a dokładniej ich totalnie niekonsekwentne oznaczenia co się kiedy wydarzyło na naszej tablicy. Raz jest to 23 minut(y) temu, raz 7 godz. temu, jeszcze inaczej około godziny temu. Być może różne ekipy robią osobno opisy czasu i stąd różnice. Postanowiłem dla sportu zmierzyć się z problemem. <a
href="http://spiechu.pl/2012/03/16/o-modyfikatorach-w-smarty-i-opisie-slownym-interwalow-czasu/"> read more <span
class="meta-nav">&#187;</span></a>]]></description> <content:encoded><![CDATA[<p>Pomysł na wpis dał mi kilka dni temu Facebook, a dokładniej ich totalnie niekonsekwentne oznaczenia co się kiedy wydarzyło na naszej tablicy. Raz jest to <em>23 minut(y) temu</em>, raz <em>7 godz. temu</em>, jeszcze inaczej <em>około godziny temu</em>. Być może różne ekipy robią osobno opisy czasu i stąd różnice. Postanowiłem dla sportu zmierzyć się z problemem. Powstało takie coś jak <a
href="https://github.com/spiechu/timespan-smarty-modifier">Timespan Smarty Modifier</a>.</p><p>Opis jak to zainstalować, wymagania i sposób użycia możecie sobie przeczytać w moim kaleczonym angielskim w GitHubie. Tutaj chciałbym się skupić jak to działa. Najwygodniejszym sposobem korzystania z biblioteki jest poprzez modyfikator w szablonach Smarty, a więc <code>{$jakaśZmienna|naszModyfikator}</code>.</p><p>Przede wszystkim sama nazwa pliku musi nazywać się <em>modifier.nazwa.php</em>, za to funkcja <em>smarty_modifier_nazwa($argument)</em>. Pierwszy argument automatycznie dostaje wartość zmiennej, dla której wywołujemy modyfikator. Jeśli chcemy, następne podajemy po dwukropku. Drobna uwaga: nigdy niczego nie „echujemy”, tylko zwracamy poprzez return. Chodzi o łańcuchowe łączenie modyfikatorów.</p><p>Z uwagi na to, że całość rozrosła się do ponad 400 linii kodu, nie ma sensu wszystkiego tutaj przytaczać. Skupię się na najważniejszych rzeczach.</p><p>Całość ma formę klasy abstrakcyjnej rozszerzanej przez poszczególne języki. Na podstawie zadeklarowanego języka skrypt próbuje znaleźć sobie właściwą klasę (fragm. <em>modifier.timespan.php</em>):</p><div
class="wp_syntax"><div
class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$className</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'Spiechu\TimeSpan\TimeSpan'</span> <span style="color: #339933;">.</span> <span style="color: #990000;">strtoupper</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$lang</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">class_exists</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$className</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #000088;">$timeSpan</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #000088;">$className</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
      <span style="color: #666666; font-style: italic;">// sprawdz czy klasa rozszerza AbstractTimeSpan</span>
      <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$timeSpan</span> instanceof Spiechu\TimeSpan\AbstractTimeSpan<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
         <span style="color: #000088;">$timeSpan</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Spiechu\TimeSpan\TimeSpanEN<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #009900;">&#125;</span>
   <span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
&nbsp;
      <span style="color: #666666; font-style: italic;">// jesli nie ma takiego jezyka lub klasa niewlasciwa uzywam angielskiego</span>
      <span style="color: #000088;">$timeSpan</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Spiechu\TimeSpan\TimeSpanEN<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   <span style="color: #009900;">&#125;</span></pre></div></div><p>Potem tylko konfigurujemy klasę i zwracamy wynik:</p><div
class="wp_syntax"><div
class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$timeSpan</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setStartDate</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$date</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">showSuffix</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$suffix</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">return</span> <span style="color: #000088;">$timeSpan</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getTimeSpan</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div><p>W klasie <em>AbstractTimeSpan</em> z kolei mamy trochę logiki związanej z obliczaniem interwału:</p><div
class="wp_syntax"><div
class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$curDate</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> \DateTime<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'now'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$diff</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$curDate</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">diff</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_startDate<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">//otrzymujemt obiekt DateInterval</span></pre></div></div><p>Począwszy od największej jednostki (rok) odpytujemy <em>$diff</em> która z jego zmiennych publicznych jest większa od 0 oraz za pomocą metod <code>isHalfUnit($actualUnit, $fullUnit)</code>, <code>almostFullUnit($actualUnit, $fullUnit)</code> sprawdzamy czy może przekroczyliśmy połowę obecnej jednostki, większej jednostki oraz czy nie można jej zaokrąglić do następnej całej.</p><p>Klasy rozszerzające implementują m.in. metodę <em>getUnit($howMany, $unitSymbol, $half)</em>. Liczebniki angielskie są tak trudne, że potrzeba na nie aż 1 linijki:</p><div
class="wp_syntax"><div
class="code"><pre class="php" style="font-family:monospace;"><span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$howMany</span> <span style="color: #339933;">&gt;</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span> <span style="color: #000088;">$howMany</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">2</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">return</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_units<span style="color: #009900;">&#91;</span><span style="color: #000088;">$howMany</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$unitSymbol</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span></pre></div></div><p>Jeśli mowa o <em>$this-&gt;_units</em> to wygląda to tak:</p><div
class="wp_syntax"><div
class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000088;">$_units</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
   <span style="color: #339933;">-</span><span style="color: #cc66cc;">1</span> <span style="color: #339933;">=&gt;</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'s'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'just now'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
   <span style="color: #cc66cc;">0</span> <span style="color: #339933;">=&gt;</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'i'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'half minute'</span><span style="color: #339933;">,</span>
      <span style="color: #0000ff;">'h'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'half hour'</span><span style="color: #339933;">,</span>
      <span style="color: #0000ff;">'d'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'half day'</span><span style="color: #339933;">,</span>
      <span style="color: #0000ff;">'m'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'half month'</span><span style="color: #339933;">,</span>
      <span style="color: #0000ff;">'y'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'half year'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
   <span style="color: #cc66cc;">1</span> <span style="color: #339933;">=&gt;</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'s'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'a second'</span><span style="color: #339933;">,</span>
      <span style="color: #0000ff;">'i'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'a minute'</span><span style="color: #339933;">,</span>
      <span style="color: #0000ff;">'h'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'an hour'</span><span style="color: #339933;">,</span>
      <span style="color: #0000ff;">'d'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'a day'</span><span style="color: #339933;">,</span>
      <span style="color: #0000ff;">'m'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'a month'</span><span style="color: #339933;">,</span>
      <span style="color: #0000ff;">'y'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'a year'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
   <span style="color: #cc66cc;">2</span> <span style="color: #339933;">=&gt;</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'s'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'seconds'</span><span style="color: #339933;">,</span>
      <span style="color: #0000ff;">'i'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'minutes'</span><span style="color: #339933;">,</span>
      <span style="color: #0000ff;">'h'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'hours'</span><span style="color: #339933;">,</span>
      <span style="color: #0000ff;">'d'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'days'</span><span style="color: #339933;">,</span>
      <span style="color: #0000ff;">'m'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'months'</span><span style="color: #339933;">,</span>
      <span style="color: #0000ff;">'y'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'years'</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div><p>Polskie jednostki z kolei prezentują się dużo bardziej okazale (3 odmiany):</p><div
class="wp_syntax"><div
class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000088;">$_units</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
   <span style="color: #339933;">-</span><span style="color: #cc66cc;">1</span> <span style="color: #339933;">=&gt;</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'s'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'przed chwilą'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
   <span style="color: #cc66cc;">0</span> <span style="color: #339933;">=&gt;</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'i'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'pół minuty'</span><span style="color: #339933;">,</span>
      <span style="color: #0000ff;">'h'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'pół godziny'</span><span style="color: #339933;">,</span>
      <span style="color: #0000ff;">'d'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'pół dnia'</span><span style="color: #339933;">,</span>
      <span style="color: #0000ff;">'m'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'pół miesiąca'</span><span style="color: #339933;">,</span>
      <span style="color: #0000ff;">'y'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'pół roku'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
   <span style="color: #cc66cc;">1</span> <span style="color: #339933;">=&gt;</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'s'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'sekundę'</span><span style="color: #339933;">,</span>
      <span style="color: #0000ff;">'i'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'minutę'</span><span style="color: #339933;">,</span>
      <span style="color: #0000ff;">'h'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'godzinę'</span><span style="color: #339933;">,</span>
      <span style="color: #0000ff;">'d'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'dzień'</span><span style="color: #339933;">,</span>
      <span style="color: #0000ff;">'m'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'miesiąc'</span><span style="color: #339933;">,</span>
      <span style="color: #0000ff;">'y'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'rok'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
   <span style="color: #cc66cc;">2</span> <span style="color: #339933;">=&gt;</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'s'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'sekundy'</span><span style="color: #339933;">,</span>
      <span style="color: #0000ff;">'i'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'minuty'</span><span style="color: #339933;">,</span>
      <span style="color: #0000ff;">'h'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'godziny'</span><span style="color: #339933;">,</span>
      <span style="color: #0000ff;">'d'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'dni'</span><span style="color: #339933;">,</span>
      <span style="color: #0000ff;">'m'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'miesiące'</span><span style="color: #339933;">,</span>
      <span style="color: #0000ff;">'y'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'lata'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
   <span style="color: #cc66cc;">5</span> <span style="color: #339933;">=&gt;</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'s'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'sekund'</span><span style="color: #339933;">,</span>
      <span style="color: #0000ff;">'i'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'minut'</span><span style="color: #339933;">,</span>
      <span style="color: #0000ff;">'h'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'godzin'</span><span style="color: #339933;">,</span>
      <span style="color: #0000ff;">'d'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'dni'</span><span style="color: #339933;">,</span>
      <span style="color: #0000ff;">'m'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'miesięcy'</span><span style="color: #339933;">,</span>
      <span style="color: #0000ff;">'y'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'lat'</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div><p>Mało tego, w polskiej klasie mamy jeszcze jednostki specjalne :-) :</p><div
class="wp_syntax"><div
class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000088;">$_specialUnits</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
   <span style="color: #0000ff;">'poltora'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'s'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'półtorej sekundy'</span><span style="color: #339933;">,</span> <span style="color: #666666; font-style: italic;">// nigdy nie uzywane</span>
      <span style="color: #0000ff;">'i'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'półtorej minuty'</span><span style="color: #339933;">,</span>
      <span style="color: #0000ff;">'h'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'półtorej godziny'</span><span style="color: #339933;">,</span>
      <span style="color: #0000ff;">'d'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'półtora dnia'</span><span style="color: #339933;">,</span>
      <span style="color: #0000ff;">'m'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'półtora miesiąca'</span><span style="color: #339933;">,</span>
      <span style="color: #0000ff;">'y'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'półtora roku'</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div><p>Metodę <em>getUnit()</em> przytaczam w całości:</p><div
class="wp_syntax"><div
class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000000; font-weight: bold;">function</span> getUnit<span style="color: #009900;">&#40;</span><span style="color: #000088;">$howMany</span><span style="color: #339933;">,</span> <span style="color: #000088;">$unitSymbol</span><span style="color: #339933;">,</span> <span style="color: #000088;">$half</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
   <span style="color: #666666; font-style: italic;">// kluczowa liczba, do ktorej wszystkie maja odmiane jak '5', potem tylko z jedynka na koncu</span>
   <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$howMany</span> <span style="color: #339933;">&gt;</span> <span style="color: #cc66cc;">21</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
      <span style="color: #666666; font-style: italic;">// badamy ostatnia cyfre </span>
      <span style="color: #000088;">$howMany</span> <span style="color: #339933;">=</span> <span style="color: #990000;">substr</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$howMany</span><span style="color: #339933;">,</span> <span style="color: #339933;">-</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
         <span style="color: #666666; font-style: italic;">// jesli to 1 to odmienia sie jak '5'</span>
         <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$howMany</span> <span style="color: #339933;">&lt;=</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000088;">$howMany</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">5</span><span style="color: #339933;">;</span>
&nbsp;
         <span style="color: #666666; font-style: italic;">// jesli nie to rekurencyjnie dla samej ostatniej cyfry</span>
         <span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #b1b100;">return</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getUnit</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$howMany</span><span style="color: #339933;">,</span> <span style="color: #000088;">$unitSymbol</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
         <span style="color: #009900;">&#125;</span>
   <span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">elseif</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$howMany</span> <span style="color: #339933;">&gt;=</span> <span style="color: #cc66cc;">5</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #000088;">$howMany</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">5</span><span style="color: #339933;">;</span>
   <span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">elseif</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$howMany</span> <span style="color: #339933;">&gt;=</span> <span style="color: #cc66cc;">2</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #000088;">$howMany</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">2</span><span style="color: #339933;">;</span>
&nbsp;
   <span style="color: #666666; font-style: italic;">// jesli mamy '1 i pol' to odpytujemy specjalne jednostki</span>
   <span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">elseif</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$howMany</span> <span style="color: #339933;">==</span> <span style="color: #cc66cc;">1</span> <span style="color: #339933;">&amp;&amp;</span> <span style="color: #000088;">$half</span> <span style="color: #339933;">==</span> <span style="color: #009900; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #b1b100;">return</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_specialUnits<span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'poltora'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$unitSymbol</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
   <span style="color: #009900;">&#125;</span>
   <span style="color: #b1b100;">return</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_units<span style="color: #009900;">&#91;</span><span style="color: #000088;">$howMany</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$unitSymbol</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div><p>Mamy już jednostki, teraz tylko skleić to w jeden ciąg znaków. Zajmuje się tym metoda <em>getTimeSpan()</em> z klasy <em>AbstractTimeSpan</em>:</p><div
class="wp_syntax"><div
class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> getTimeSpan<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
   <span style="color: #000088;">$interval</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getInterval</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   <span style="color: #000088;">$timeUnit</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getUnit</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$interval</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'counter'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$interval</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'unit'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$interval</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'half'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
   <span style="color: #666666; font-style: italic;">// jesli gdziekolwiek dane byly szacowane to dorzucamy 'okolo'</span>
   <span style="color: #000088;">$prefix</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$interval</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'approx'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span> ? <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getPrefix</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">' '</span> <span style="color: #339933;">:</span> <span style="color: #0000ff;">''</span><span style="color: #339933;">;</span>
&nbsp;
   <span style="color: #666666; font-style: italic;">// jesli mamy co najmniej 1 i pol</span>
   <span style="color: #000088;">$half</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$interval</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'half'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">&amp;&amp;</span> <span style="color: #000088;">$interval</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'counter'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">&gt;</span> <span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span> ? <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getHalf</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">' '</span> <span style="color: #339933;">:</span> <span style="color: #0000ff;">''</span><span style="color: #339933;">;</span>
&nbsp;
   <span style="color: #666666; font-style: italic;">// sprawdzamy czy chcemy 'temu'</span>
   <span style="color: #000088;">$suffix</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_showSuffix<span style="color: #009900;">&#41;</span> ? <span style="color: #0000ff;">' '</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getSuffix</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">:</span> <span style="color: #0000ff;">''</span><span style="color: #339933;">;</span>
&nbsp;
   <span style="color: #666666; font-style: italic;">// podajemy razem z liczba jednostkek</span>
   <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$interval</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'counter'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">&gt;</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #b1b100;">return</span> <span style="color: #000088;">$prefix</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$interval</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'counter'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">' '</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$half</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$timeUnit</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$suffix</span><span style="color: #339933;">;</span>
&nbsp;
   <span style="color: #666666; font-style: italic;">// podajemy bez liczby jednostek</span>
   <span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">elseif</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$interval</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'counter'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">&gt;=</span> <span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #b1b100;">return</span> <span style="color: #000088;">$prefix</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$timeUnit</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">' '</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$half</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$suffix</span><span style="color: #339933;">;</span>
&nbsp;
   <span style="color: #666666; font-style: italic;">// zostala tylko mozliwosc, ze to 'przed chwila', czyli offset -1</span>
   <span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #b1b100;">return</span> <span style="color: #000088;">$timeUnit</span><span style="color: #339933;">;</span>
   <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div><p>Domyślne wartości to 10 sekund dla komunikatu <em>przed chwilą</em>, 15% tolerancji dla połowy jednostki (np. <em>około 2 i pół godziny temu</em> lub <em>około pół godziny temu</em>) i 15% tolerancji dla całości jednostki (np. <em>około godzinę temu</em>).</p><p>Myślę, że całość da się łatwo przenieść do innych systemów szablonów (od biedy w samym PHP też w końcu można). Póki co brakuje testów jednostkowych, I’m working on it :-D</p><div
class="google_plusone_widget" style="margin-bottom:10px"><g:plusone
count="false" href="http://spiechu.pl/2012/03/16/o-modyfikatorach-w-smarty-i-opisie-slownym-interwalow-czasu/" size="standard"></g:plusone></div>]]></content:encoded> <wfw:commentRss>http://spiechu.pl/2012/03/16/o-modyfikatorach-w-smarty-i-opisie-slownym-interwalow-czasu/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> </channel> </rss><!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Minified using disk: basic
Page Caching using disk: enhanced
Database Caching using disk: basic
Object Caching 1008/1029 objects using disk: basic

Served from: spiechu.pl @ 2012-05-17 06:51:27 -->

