<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	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/"
	>

<channel>
	<title>Rafał Pitoń devBlog</title>
	<atom:link href="http://rpiton.com/?feed=rss2" rel="self" type="application/rss+xml" />
	<link>http://rpiton.com</link>
	<description>Trochę o forach i PHP</description>
	<lastBuildDate>Mon, 06 Sep 2010 20:23:48 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Nowe API uniBoard</title>
		<link>http://rpiton.com/?p=175</link>
		<comments>http://rpiton.com/?p=175#comments</comments>
		<pubDate>Mon, 06 Sep 2010 17:52:34 +0000</pubDate>
		<dc:creator>Rafał Pitoń</dc:creator>
				<category><![CDATA[0.1]]></category>
		<category><![CDATA[Php]]></category>
		<category><![CDATA[Unisolutions]]></category>
		<category><![CDATA[uniBoard]]></category>

		<guid isPermaLink="false">http://rpiton.com/?p=175</guid>
		<description><![CDATA[Jest jeden rodzaj klasy, którego posiadanie bardzo ułatwia mi pisanie akcji w uniBoard, a na samą myśl o pisaniu którego zawsze robi mi się słabo&#8230; Chodzi tutaj o klasy api_*, służące do manipulacji pojedynczymi wpisami w Bazie. API uniBoard do pracy z użytkownikami, forami, postami, grupami ustawień a nawet emotikonami używa specjalnych klas. Za każdym [...]]]></description>
			<content:encoded><![CDATA[<p>Jest jeden rodzaj klasy, którego posiadanie bardzo ułatwia mi pisanie akcji w uniBoard, a na samą myśl o pisaniu którego zawsze robi mi się słabo&#8230;</p>
<p>Chodzi tutaj o klasy api_*, służące do manipulacji pojedynczymi wpisami w Bazie.</p>
<p><span id="more-175"></span></p>
<h2>API</h2>
<p>uniBoard do pracy z użytkownikami, forami, postami, grupami ustawień a nawet emotikonami używa specjalnych klas. Za każdym razem kiedy chcemy dłubać np. przy profilu użytkownika i potrzebujemy walidacji wprowadzanych danych, możemy wykorzystać api_user, które tworzy się w następujący sposób:</p>
<p><code><br />
$user = new api( $appCore, $appCore -> _REQ( 'id_usera'));<br />
</code></p>
<p>Jeśli user został znaleziony i załadowany, własność &#8222;data_loaded&#8221; ma wartość true.</p>
<h3>set</h3>
<p>Do ustawiania wartości w API służą metody dostępowe set*():</p>
<p><code><br />
// Fill API with data<br />
$this -> api -> setUserName( $this -> appCore -> _POST( 'user_name'));<br />
$this -> api -> setUserLogin( $this -> appCore -> _POST( 'user_login'));<br />
</code></p>
<p>Każda metoda wykonuje przynajmniej dwa kroki:</p>
<ol>
<li>Zapis danych wewnątrz API</li>
<li>Poinformowanie metody saveData() o nowych zmianach</li>
</ol>
<p>Opcjonalnym trzecim krokiem jest sprawdzenie poprawności danych. Jeśli pojawi się błąd zapisu, API zablokuje metodę saveData() i ustawi własność &#8222;error&#8221; na true. Dodatkowo komunikat błędu znajdzie się w liście &#8222;errors&#8221;. Co dalej zrobi z tym kod, zależy od programisty.</p>
<h3>get</h3>
<p>Tutaj zaczynają się problemy. Każda własność znajdująca się w API wymagania metody get. O to api_smiley:</p>
<p><code><br />
$api -> getSmileyName();<br />
$api -> getSmileyReplace();<br />
$api -> getSmileyImage();<br />
</code></p>
<p>Wygląda dobrze. 3 Fajne metody&#8230; niestety api_user ma ich aż 46. Pisanie takiej ilości getów jest niesłychanie upierdliwe i pożera sporo czasu który mógłbym poświęcić na coś ciekawszego, np. pisanie akcji które z tego api korzystają.</p>
<p>Dlatego postanowiłem wywalić wszystkie te gety i zamiast tego używać bezpośrednio własności API:</p>
<p><code><br />
$api -> smiley_name;<br />
$api -> smiley_replace;<br />
$api -> smiley_image;<br />
</code></p>
<p>Pisanie api jest teraz dużo szybsze.</p>
<h2>__GET __SET &#8211; STOP!</h2>
<p>PHP 5 udostępnia obiektom magiczne metody __GET i __SET. Dlaczego więc ich nie wykorzystuję? Funkcje te zostały wprowadzone do PHP5 jako rozwiązanie problemów projektowych i odciążenie dla biednego eval().</p>
<p>Problem w tym że wielu ludzi używa ich do ułatwienia sobie pracy podczas pisania kodu. Napisanie jednego __SET jest wygodniejsze niż 46 własnych. Metody te nie bez powodu nazywane są magicznymi. Magiczność nie oznacza jednak &#8222;magiczne zrób się samo&#8221; tylko &#8222;niech php wykona testy i uruchomi specjalny kod ze skryptu&#8221;.</p>
<p>Problem w tym że $obiekt -> zmienna; dla zmiennej publicznej oznacza dla php sprawdzenie czy zmienna istnieje w obiekcie i zwrócenie wyniku. Zmienna prywatna dokłada tutaj wymóg sprawdzenia przez php możliwości dostępu (trochę wolniejsze), istnienia metody __SET (wolniej) i zinterpretowanie kodu PHP użytkownika (z ang. Bottleneck &#8211; wąskie gardło). Większość standardowych funkcji PHP to nakładki na leżący pod nimi gotowy kod C++, który <strong>zawsze jest szybszy</strong> od odpowiadającego mu kodu impretowanego!</p>
<p>Szukającym liczb polecam jeden z <a href="http://www.garfieldtech.com/blog/magic-benchmarks">przykładowych</a> benchmarków z Google.</p>
]]></content:encoded>
			<wfw:commentRss>http://rpiton.com/?feed=rss2&amp;p=175</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Założyłem galerię porażek reCAPTCHA</title>
		<link>http://rpiton.com/?p=171</link>
		<comments>http://rpiton.com/?p=171#comments</comments>
		<pubDate>Sun, 05 Sep 2010 21:25:27 +0000</pubDate>
		<dc:creator>Rafał Pitoń</dc:creator>
				<category><![CDATA[Php]]></category>

		<guid isPermaLink="false">http://rpiton.com/?p=171</guid>
		<description><![CDATA[uniBoard do ochrony przeciw botami wykorzystuje rozwiązanie reCAPTCHA. Znane i popularne w całej sieci, nie jest jednak doskonałe. Wiek tego rozwiązania wymusza na twórcach implementację coraz to nowych algorytmów zniekształcających. Niestety rC przyłożyło już w przysłowiową ścianę. Na jeden czytelny obrazek przypada kilka nieczytelnych i kilka kosmicznych. Te ostatnie postanowiłem zbierać. Szczególnym rodzajem obrazków kosmicznych [...]]]></description>
			<content:encoded><![CDATA[<p>uniBoard do ochrony przeciw botami wykorzystuje rozwiązanie reCAPTCHA. Znane i popularne w całej sieci, nie jest jednak doskonałe. Wiek tego rozwiązania wymusza na twórcach implementację coraz to nowych algorytmów zniekształcających. Niestety rC przyłożyło już w przysłowiową ścianę.</p>
<p>Na jeden czytelny obrazek przypada kilka nieczytelnych i kilka kosmicznych. Te ostatnie postanowiłem zbierać.</p>
<p>Szczególnym rodzajem obrazków kosmicznych są te ze słowami <strong>niemożliwymi</strong> do przepisania. Słowa reCAPTCHA bierze z książek, a te nie zawsze zawierają znaki wyłącznie z angielskiego alfabetu, bądź używają formatowania niemożliwego do napisania &#8222;z palca&#8221;. A to trzeba przepisać coś z indeksu górnego, a to pojawi się cyrylica, klasyczna greka albo orientalne kaji.</p>
<p>Zbiór można przeglądać tutaj:</p>
<p><a href="http://rpiton.com/recaptcha/">reCAPTCHA FAIL GALLERY</a></p>
<p>Kolekcję będę uzupełniał w miarę chęci.</p>
]]></content:encoded>
			<wfw:commentRss>http://rpiton.com/?feed=rss2&amp;p=171</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Przeprowadzka</title>
		<link>http://rpiton.com/?p=168</link>
		<comments>http://rpiton.com/?p=168#comments</comments>
		<pubDate>Tue, 31 Aug 2010 20:30:23 +0000</pubDate>
		<dc:creator>Rafał Pitoń</dc:creator>
				<category><![CDATA[0.1]]></category>
		<category><![CDATA[Unisolutions]]></category>
		<category><![CDATA[uniBoard]]></category>

		<guid isPermaLink="false">http://rpiton.com/?p=168</guid>
		<description><![CDATA[Ponieważ chcę aby mój projekt był obecny na scenie międzynarodowej, a sam uniBoard powstaje po angielsku, postanowiłem zrezygnować z domen *.pl na rzecz jednego uniwersalnego adresu. www.uniboard-project.org Na razie nic tam nie ma, ale kto wie co przyniesie przyszłość.]]></description>
			<content:encoded><![CDATA[<p>Ponieważ chcę aby mój projekt był obecny na scenie międzynarodowej, a sam uniBoard powstaje po angielsku, postanowiłem zrezygnować z domen *.pl na rzecz jednego uniwersalnego adresu.</p>
<h2><a href="www.uniboard-project.org">www.uniboard-project.org</a></h2>
<p>Na razie nic tam nie ma, ale kto wie co przyniesie przyszłość.</p>
]]></content:encoded>
			<wfw:commentRss>http://rpiton.com/?feed=rss2&amp;p=168</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Czego NIE będzie w uniBoard 0.1</title>
		<link>http://rpiton.com/?p=162</link>
		<comments>http://rpiton.com/?p=162#comments</comments>
		<pubDate>Mon, 30 Aug 2010 19:51:05 +0000</pubDate>
		<dc:creator>Rafał Pitoń</dc:creator>
				<category><![CDATA[0.1]]></category>
		<category><![CDATA[Php]]></category>
		<category><![CDATA[Unisolutions]]></category>
		<category><![CDATA[uniBoard]]></category>

		<guid isPermaLink="false">http://rpiton.com/?p=162</guid>
		<description><![CDATA[Ponieważ od Alfy 0.1 dzieli nas mniej niż miesiąc, wypada napisać czego NIE będzie w uniBoard 0.1. Aby łatwiej było to sobie wyobrazić, wypiszę jedynie rzeczy które były w uB przed restartem projektu. Komentarze profilów Własne pola profilów Reputacje użytkowników Podział na zdjęcia i avatary System przyjaciół i wrogów Lista gości w profilu Prywatne dyskusje [...]]]></description>
			<content:encoded><![CDATA[<p>Ponieważ od Alfy 0.1 dzieli nas mniej niż miesiąc, wypada napisać czego NIE będzie w uniBoard 0.1. Aby łatwiej było to sobie wyobrazić, wypiszę jedynie rzeczy które były w uB przed restartem projektu.</p>
<p><span id="more-162"></span></p>
<ol>
<li>Komentarze profilów</li>
<li>Własne pola profilów</li>
<li>Reputacje użytkowników</li>
<li>Podział na zdjęcia i avatary</li>
<li>System przyjaciół i wrogów</li>
<li>Lista gości w profilu</li>
<li>Prywatne dyskusje</li>
<li>System Powiadomień</li>
<li>BBCode [Flash]</li>
<li>&#8222;Agresywny&#8221; Parser Postów</li>
<li>Ajaxowe bajerki przy rejestracji</li>
<li>Opisy tematów</li>
</ol>
<h2>A co nowego?</h2>
<p>Z nowości na chwilę obecną podam tylko dwie: pierwszą jest nowy styl, drugą zmiana domyślnego języka projektu na Angielski. W trakcie Beta-testów równolegle do poprawek w tym pierwszym powstawać będzie tłumaczenie skryptu na język Polski.</p>
]]></content:encoded>
			<wfw:commentRss>http://rpiton.com/?feed=rss2&amp;p=162</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Co dalej z uniBoard?</title>
		<link>http://rpiton.com/?p=118</link>
		<comments>http://rpiton.com/?p=118#comments</comments>
		<pubDate>Fri, 27 Aug 2010 20:57:05 +0000</pubDate>
		<dc:creator>Rafał Pitoń</dc:creator>
				<category><![CDATA[0.1]]></category>
		<category><![CDATA[Php]]></category>
		<category><![CDATA[Stare]]></category>
		<category><![CDATA[Unisolutions]]></category>
		<category><![CDATA[uniBoard]]></category>

		<guid isPermaLink="false">http://rpiton.com/?p=118</guid>
		<description><![CDATA[Od czasu kiedy ukazało się Callisto minęło dwa i pół roku, a jednak jego następcy, uniBoard wciąż nie ma. Coraz więcej ludzi w końcu dochodzi do wniosku że nigdy nie będzie, wrzucając go do jednego worka z tak zacnym towarzystwem jak DukeNukem Forever. Nie oznacza to jednak że nic w kierunku ukończenia uB nie robię. [...]]]></description>
			<content:encoded><![CDATA[<p>Od czasu kiedy ukazało się Callisto minęło dwa i pół roku, a jednak jego następcy, uniBoard wciąż nie ma. Coraz więcej ludzi w końcu dochodzi do wniosku że nigdy nie będzie, wrzucając go do jednego worka z tak zacnym towarzystwem jak DukeNukem Forever.</p>
<p>Nie oznacza to jednak że nic w kierunku ukończenia uB nie robię. W tym wpisie postaram się przybliżyć wam zmiany w projekcie które zaszły w tym miesiącu.</p>
<p><span id="more-118"></span></p>
<h2>Siódmy Sierpnia</h2>
<p>Siódmego Sierpnia Anno Domini 2010 po powrocie z wakacji zasiadłem do kodu i postanowiłem przejrzeć to co już mam pod kątem wydajności i jakości. Wynikiem tego przeglądu było załamanie nerwowe.</p>
<h3>Jakość Kodu</h3>
<p>W trakcie powstawania uniBoard przeszedł przepisanie sporych części kodu od nowa. Wynikiem tego był kompletny śmietnik w kodzie, który czynił go nieczytelnym dla nikogo oprócz mnie, i tylko dzięki faktowi że to ja za nim stałem. Kod nie był pisany według żadnych standardów, a długi okres jego powstawania skutkował różnicą w wieku między poszczególnymi plikami wynoszącą nawet 22 miesiące.</p>
<p>Wydajność również nie powalała. Chociaż nowy kod nie był takim pożeraczem zasobów jak Callisto, uniBoard był średnio 2-3 razy wolniejszy od IP.B 2.3, a wyświetlenie tematu zajmowało mu tyle samo co paskudnie napisanemu poprzednikowi. Dodatkowo mimo kolejnych zmian w parserze postów ciągle możliwe było pisanie wiadomości, przy których wyświetlaniu server po prostu klękał i błagał aby go dobić.</p>
<p>Ważną cechą którą każdy twórca aplikacji powinien posiąść jest samo-krytyka. Twój kod może ci się wydawać najdoskonalszym rozwiązaniem problemu jakie kiedykolwiek powstało, ale tak nigdy nie będzie. Uznałem więc że jako twórcy skrypt w pierwszej kolejności powinien odpowiadać mi. Nie ma być doskonały. Ma mi się podobać.</p>
<p>uniBoard nie spełniał tego warunku&#8230;</p>
<h2>Po Siódmym Sierpnia</h2>
<p>Ósmego Sierpnia postanowiłem zastanowić się od nowa nad całym projektem. </p>
<p>Dlatego zadałem sobie kilka pytań:</p>
<ol>
<li>Czy naprawdę muszę zaimplementować każdą funkcję?</li>
<li>Czy funkcjonalność jest cenniejsza od wydajności i skalowalności?</li>
<li>Czy koniecznie wszystko ma być zawarte już w pierwszym wydaniu?</li>
<li>Czy warto zawsze słuchać sugestii potencjalnych użytkowników?</li>
</ol>
<p>Nim zaczniesz czytać odpowiedzi, pamiętaj że są one moimi opiniami. Jeśli się z nimi nie zgadzasz&#8230; cóż, jestem pewien że znajdziesz na rynku bardziej odpowiednie dla ciebie rozwiązanie forum.</p>
<h3>Czy naprawdę muszę zaimplementować każdą funkcję?</h3>
<p><b>NIE</b> &#8211; Ani phpBB ani SMF czy inny PunBB nie powalą nikogo kto przynajmniej raz bawił się ACP IPB bądź vBulletina oferowaną funkcjonalnością, a jednak każde z tych rozwiązań skupia wokół siebie wierną i aktywną społeczność. Quality over Quantity &#8211; <em>Jakość ponad ilość</em>.</p>
<h3>Czy funkcjonalność jest cenniejsza od wydajności i skalowalności?</h3>
<p><b>NIE</b> &#8211; Odpowiedz sobie na następujące pytania: Czy chcesz aby społeczność na twoim forum była duża i aktywna? Czy gdy stanie się ona zbyt duża, zmienisz rozwiązanie czy server? Duża funkcjonalność to fajna sprawa (tyle &quot;ptaszków&quot; w ACP!), ale w dalszej perspektywie lepiej jest poświęcić funkcjonalność na rzecz umożliwienia dalszego wzrostu społeczności. Mniejsza funkcjonalność jest tańsza od konwersji na inne rozwiązanie lub zmiany platformy na wydajniejszą. Less is More &#8211; <em>Mniej znaczy Więcej</em></p>
<h3>Czy koniecznie wszystko ma być zawarte już w pierwszym wydaniu?</h3>
<p><b>NIE</b> &#8211; Na razie udajmy że nie ma związku między czasem potrzebnym na zawarcie zaplanowanej funkcjonalności a jej rozmiarem i zabawmy się w abstrakcję. Powiedzmy że 5% błędów w kodzie zostaje niewykryte aż do wejścia w fazę produkcyjną. Niech nasz kod ma na starcie 40 funkcji z czego połowa jest błędna. Z dwudziestu funkcji 2 będą błędne. Doświadczenie nauczyło mnie że im większy projekt, tym mniejsza wykrywalność błędów. W euforii użytkownicy rzucają się na dane główne ignorując funkcje dodatkowe.</p>
<h3>Czy warto zawsze słuchać sugestii potencjalnych użytkowników?</h3>
<p><b>NIE</b> &#8211; Każdy może mieć swoje oczekiwania względem projektu, jednak spełnianie wszystkich zachcianek zgłaszanych przez użytkowników to prosta droga do klęski. Zamiast poświęcić czas na rozwój aplikacji i poprawienie jej jakości, twórca idzie &#8222;w bok&#8221; implementując funkcje które będą wykorzystywane przez drobną część użytkowników, a które będą przecież wymagać poprawek, rozwoju i aktualizacji. Lepszym rozwiązaniem będzie implementowanie tylko tego co według ciebie pasuje do systemu forum i będzie popularne wśród użytkowników. Z drugiej strony jeśli zapotrzebowanie na jakąś funkcję będzie realne, zawsze istnieje szansa że ktoś wykona odpowiednią modyfikację, w ten sposób biorąc na siebie jej rozwój.</p>
<h2>Co to znaczy dla projektu?</h2>
<p>uniBoard powstaje od nowa. Jest to trzeci rewrite w burzliwej historii skryptu, jednakże tym razem różni się on od poprzednich. Nim jednak przejdziemy dalej, uprzedzę ewentualne zarzuty o zmarnowaniu 2.5 roku na tworzenie kodu który i tak pójdzie do śmietnika. Wraz z kodem nie wyrzucę doświadczeń i wiedzy które zdobyłem w trakcie prac nad nim, a te posłużą mi do stworzenia jeszcze lepszego projektu.</p>
<p>Nie mam zamiaru zanudzać was technicznymi szczegółami pokroju &#8222;php 5.3.0&#8243;, &#8222;MySQLi&#8221;, &#8222;MVC&#8221; czy &#8222;agresywne cache&#8221;. Zamiast tego w oparciu o pytania z poprzedniego rozdziału przedstawię Wam nowe założenia projektu:</p>
<h3>uniBoard ma być aplikacją Forum</h3>
<p>Jeszcze raz &#8211; <b>aplikacją forum</b>. Tak, forum. Wiesz czym jest forum? Spójrz tam. Nie, to nie forum, to kombajn. Teraz tam. To też nie forum, to CMS. Teraz tam. Widzisz? Działy, a w działach tematy i posty. To jest forum. A tam? Tam jest platforma startowa dla rakiet kosmicznych.</p>
<p>uniBoard będzie oferować funkcjonalność forum. Nie założycie na nim portalu newsowego, nie będziecie pisać na nim artykułów używając rozbudowanych opcji edycji*, nie będzie też śledził torrentów i nie pokieruje budową domu. Nie znajdziecie też w nim na standardzie takich zajefajnych funkcji jak kolorowe tytuły tematów, shoutbox czy piwa (całkiem dobre, ale nie na forum).</p>
<p>* &#8211; Tak, spotkałem kogoś kto chciał przy użyciu skryptu forum prowadzić&#8230; gazetę. Ten ktoś na sugestię braku rozsądku wielce się obraził i z miejsca uznał że uniBoard kiepskim skryptem forum będzie&#8230; chociaż nie jestem pewien czy nie chodziło mu o CMS.</p>
<h3>Po pierwsze: wydajność</h3>
<p>Powiedzmy sobie że prowadzisz forum hobbystyczne np. o uprawie paprotek i nie masz wielkiego pojęcia o technikaliach. Kupiłeś server za 60zł rocznie i domenę za drugie tyle, a więc utrzymanie tego wszystkiego to 120zł rocznie. Nagle w całym kraju wybucha moda na paprotki. Posiadanie paprotki jest &#8222;trendy&#8221; i twoje forum zaczyna rosnąć. W końcu dochodzi do rozmiaru przy którym forum po prostu zwalnia, a część użytkowników zaczyna zgłaszać białe strony a twoi znajomi dzwonić &#8222;coś się stało bo chyba ktoś zhakerował bo jakieś pięćset errorów jest&#8221;.</p>
<p>Szybkość i generowanie obciążenie to nie są tylko abstrakcyjne terminy których używają admini by być pro. Rozmiar aktywności na forum przekłada się na wymagania względem servera który to forum utrzymuje, a to oznacza koszta. Skrypt może być darmowy, prowadzenie forum na początku też, ale gdy zacznie rosnąć, w końcu zacznie wymagać inwestycji. A wtedy bądź pewien, bardziej od funkcji będzie interesować ciebie zmniejszenie wykorzystania zasobów.</p>
<p>Weźmy <a href="http://bb-bench.com/">pierwszy lepszy benchmark</a> porównujący liczbę obsłużonych żądań strony z tematem między <a href="http://bb-bench.com/raw/phpbb3-topic.txt">phpBB 3</a> a <a href="http://bb-bench.com/raw/mybb-topic.txt">MyBB 1.6</a>. Dla ludzi nie mówiących w języku Apache Benchmark wyjaśnienie: w jedną sekundę MyBB 1.6 wypluło z siebie 86 stron z odpowiedziami w temacie, podczas gdy  stare i zacofane** phpBB 3 &#8222;jedyne&#8221; 200. Oznacza to że gdyby nasze paprotkowe forum w pewnym momencie uznało &#8222;do nawozu z tym!&#8221; i przeszło z MyBB na phpBB3, straciło by fajne funkcje typu system reputacji albo szybka odpowiedź na ajaxie, ale byłoby wstanie wyświetlić odpowiedzi w temacie około 120 osobom więcej niż poprzednio. To 150% zysk przy zerowych wydatkach na sprzęt.</p>
<p>Funkcjonalność lub użytkownicy, sami wybierzcie. Pamiętajcie jednak że wyłączenie czegoś w ACP przy większych funkcjach oznacza mniejszy zysk niż gdyby takiej funkcji w ogóle w kodzie nie było. Takie funkcje zwykle siedzą głęboko w programie, więc część kodu który za nimi stoi wykonywany jest bez znaczenia czy funkcja została odfajkowana w ACP, czy nie.</p>
<p>** ironia</p>
<h3>Model przyrostowy</h3>
<p>Największa zmiana w porównaniu z poprzednimi uniBoard&#8217;ami to nowe podejście do kwestii wydań. Gdy uniBoard będzie posiadać to co w forum najważniejsze, a więc fora, posty, rejestracje, etc ect, zostanie wydany jako 0.1. <strong>Zero-kropka-jeden</strong>, nie <strong>jeden-kropka-zero</strong>. Oznaczać to będzie że kto chce skrypt forum z podstawowymi funkcjami, już może go wykorzystać, ale wszystkie zaplanowane funkcje nie zostały jeszcze zaimplementowane, więc w przyszłości ukażą się kolejne wydania noszące numerki między 0.2 a 0.9, aby w końcu osiągnąć wersję 1.0 gdy wszystkie funkcje które były zaplanowane zostały zaimplementowane.</p>
<p>Powolutku, pomalutku&#8230;</p>
<h3>Prośby o nowe funkcje</h3>
<p>Zmiana podejścia nie tyle do kodu co prowadzenia projektu. O ile poprzednio byłem otwarty na wszystkie funkcje, osiągnąłem w tym ekstremum, implementując praktycznie wszystko o co ktoś poprosił a ja miałem wiedzę i umiejętności do zrobienia. Dlatego postanowiłem co następuje: Każdy będzie mógł napisać prośbę o nową funkcję, ale tylko te które pasują do skryptu forum i według mnie są naprawdę tego warte, zostaną zaimplementowane. Pozostałe będę zwyczajnie ignorować.</p>
<p>Możesz teraz krzyknąć &#8222;co za ignorancki egoista!&#8221;, ale prawdziwy powód jest inny. Jako twórca projektu mam pewną wizję którą chcę zrealizować. Nie którzy nie będą mogli zrozumieć że ich funkcja nie nadaje się do tego aby być na standardzie. Próby wyjaśniania tego w większości kończyły by się dosłownym &#8222;pierniczeniem kotka za pomocą młotka&#8221;.</p>
<p>Pamiętajcie jednak o modyfikacjach. Fakt że nie ma czegoś w wersji &#8222;z pudełka&#8221;, nie oznacza że nikt nie będzie mógł we własnym zakresie stworzyć i wydać modyfikację która to umożliwi.</p>
<p>Projekt ma realizować moją wizję skryptu forum. Jeśli wizja ta ci się nie podoba, nie będę jej zmieniał aby ci dogodzić. Na rynku dostępnych jest wiele rozwiązań. Jeśli chcesz funkcji jak w &#8222;przemie&#8221; lub MyBB to wybierz je. Nie będę &#8222;przebierał&#8221; mojego skryptu aby zaspokoić czyjąś zachciankę posiadani imitacji &#8222;made in Poland&#8221;.</p>
<h2>Na Koniec</h2>
<p>Alfa uB 0.1 zaplanowana jest na Wrzesień, a postępy w pracach oraz sam kod można oglądać w <a href="http://code.google.com/p/uniboard-forum/source/browse/#svn/trunk">SVN projeku na Google-Code</a>.</p>
<p>Licencja pozostaje bez zmian &#8211; <strong>Gnu GPL v3</strong></p>
<p>Mam nadzieję że ten przydługi tekst wyjaśnił wszystkim sytuację projektu i powody stojące za moimi decyzjami.</p>
]]></content:encoded>
			<wfw:commentRss>http://rpiton.com/?feed=rss2&amp;p=118</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Update</title>
		<link>http://rpiton.com/?p=115</link>
		<comments>http://rpiton.com/?p=115#comments</comments>
		<pubDate>Tue, 17 Nov 2009 05:45:05 +0000</pubDate>
		<dc:creator>Rafał Pitoń</dc:creator>
				<category><![CDATA[Php]]></category>
		<category><![CDATA[Reszta]]></category>
		<category><![CDATA[Stare]]></category>
		<category><![CDATA[Unisolutions]]></category>
		<category><![CDATA[uniBoard]]></category>

		<guid isPermaLink="false">http://rpiton.com/?p=115</guid>
		<description><![CDATA[Co prawda dawno nic nie pisałem, ale nie znaczy to że nic nie robię. Prace nad uniBoard postępują, o czym można się przekonać przeglądając folder ze screenami z tegoż. Dodatkowo przekonałem się do Tweetera. Co aktualnie robię, można sprawdzić tutaj.]]></description>
			<content:encoded><![CDATA[<p>Co prawda dawno nic nie pisałem, ale nie znaczy to że nic nie robię. Prace nad uniBoard postępują, o czym można się przekonać przeglądając <a href="http://rpiton.com/_work/uniboard/">folder ze screenami</a> z tegoż.</p>
<p>Dodatkowo przekonałem się do Tweetera. Co aktualnie robię, można sprawdzić <a href="http://twitter.com/rafio_uni">tutaj</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://rpiton.com/?feed=rss2&amp;p=115</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Nowy system szablonów w uniBoard</title>
		<link>http://rpiton.com/?p=111</link>
		<comments>http://rpiton.com/?p=111#comments</comments>
		<pubDate>Sat, 04 Jul 2009 05:09:21 +0000</pubDate>
		<dc:creator>Rafał Pitoń</dc:creator>
				<category><![CDATA[Php]]></category>
		<category><![CDATA[Stare]]></category>
		<category><![CDATA[Unisolutions]]></category>
		<category><![CDATA[uniBoard]]></category>

		<guid isPermaLink="false">http://rpiton.com/?p=111</guid>
		<description><![CDATA[Witajcie! Po długiej przerwie wkońcu pojawił się odpowiedni materiał na nowy wpis. Ponownie bedzie on poświęcony systemowi szablonów uniBoard ;) Bardziej zainteresowani moim blogiem czytelnicy zapewne pamiętają, że w uniBoard templaty były parsowane w locie. Bardzo zachwalałem ten system, lecz miał on dwie istotne wady.  Parsowane klucze działały, jeśli zostały zapisane w odpowiedniej kolejności, inaczej [...]]]></description>
			<content:encoded><![CDATA[<p>Witajcie!</p>
<p>Po długiej przerwie wkońcu pojawił się odpowiedni materiał na nowy wpis. Ponownie bedzie on poświęcony systemowi szablonów uniBoard ;)<br />
<span id="more-111"></span><br />
Bardziej zainteresowani moim blogiem czytelnicy zapewne pamiętają, że w uniBoard templaty były parsowane w locie. Bardzo zachwalałem ten system, lecz miał on dwie istotne wady.  Parsowane klucze działały, jeśli zostały zapisane w odpowiedniej kolejności, inaczej parser głupiał.  Oprócz tego parser templat potrzebował trochę pamięci aby działać (liczba ta zaczynała się od 100kb i dobiegała do 10mb), co było absolutnie nie do zaakceptowania zwłaszcza, że chciałbym aby mój skrypt przeważnie mieścił się w 4mb ram, zaś gdy trzeba wykonać więcej operacji, i tak nie przekraczał 8mb. Ale to wymagało czegoś wiecej niż poprawek w istniejącym kodzie.</p>
<p>Tak, od tygodnia piszę uniBoard od nowa. Engine który poprzednio potrzebował 6mb aby wyświetlić nagłówek i stopkę, teraz robi to samo nie przekraczając 1mb.  Spadły również czasy generowania strony, co docenia ludzie z wolniejszymi hostami. Ale najwieksza zmiana dotyczy właśnie szablonów.</p>
<p><strong>Jak było? </strong></p>
<p>Poprzednio w uniBoard gdy jakiś szablon był potrzebny, prosiło się obiekt $style aby ten załadował grupę do której on należał. Następnie tworzyło się instancję klasy api_get_template, w konstruktorze zawierającej id szablonu. Potem wrzucało się mu kilka zmiennych metodą &#8222;registerValue()&#8221;, i parsowało przez &#8222;drawTemplate()&#8221;.</p>
<p><strong>Jak jest?</strong></p>
<p>Całkiem podobnie. Gdy potrzebujesz jakiegoś szablonu, prosisz obiekt $style, o wskaźnik na grupę. Ten ładuje szablon, lub też tylko zwraca wskaźnik na obiekt. I tutaj zasadnicza różnica. O ile poprzednio obiekt tworzyło się &#8222;na miejscu&#8221;, o tyle teraz wszystkie szablony są pierw &#8222;kompilowane&#8221; do obiektów php, i w takiej formie ładowane do kodu. Ma to dwie zalety. Po pierwsze, odpada parsowanie surowego tekstu za każdym razem gdy wyświetlamy szablon. Po drugie, jeśli szablon jest dobrze napisany, nie musimy się martwic o kolejność parsowania elementów, całą robotę odwala za nas parser php. No i po trzecie, szablony cachowane są już w formie funkcjonalnej, do której wystarczy już tylko wrzucić dane.</p>
<p>Trzeba jednak pamiętać że kompilator szablonów jest leniwy. Szablony budowane są tylko w określonych momentach:</p>
<ol>
<li>Utworzenie nowego szablonu</li>
<li>Wykonanie edycji szablonu</li>
<li>Reczne przebudowanie cache stylu przez ACP</li>
<li>W ostatnim etapie instalacji</li>
</ol>
<p>Jeśli dokonasz zmien w szablonie bezpośrednio w DB, ale nie wykonasz przebudowy cache w ACP, skrypt dalej będzie używać przestarzałych szablonów, bądź raczyć twoich użytkowników błędęm krytycznym.</p>
<p><strong>&lt;uni[$hello_world]/&gt;</strong></p>
<p>Ostatnią zmianą w szablonach uniBoard są tagi. Tagi to specjalne słowa-klucze, które podczas kompilacji zamieniane są na specjalne odpowiedniki. O ile poprzednio parser doszukiwał się tagów wszędzie gdzie mógł, o tyle kompilator nie jest już taki chętny do zgadywania, co autor templaty miał namyśli umieszczając gdzieś jakiś tag.  Zamiast tego kompilator odróżnia surowy html od tego co ma być skompilowane w taki sam sposób jak parser (np.) php.</p>
<p>Zasada jest prosta. Pierw w szablonie wyszukiwany jest kod który ma zostać skompilowany. Kod ten jest rozpoznawany właśnie wtedy, kiedy znajduje się między <strong>&lt;uni[</strong> a <strong>]/&gt;</strong>. Następnie następuje sprawdzenie, czy w tagu znajduje się struktura warunkowa, zwykła zmienna, czy funkcja(e).  W zależności od sprawdzenia, zawartość tagu zostanie skompilowana inaczej. Jeśli tag zawiera tylko jakąś wartość, zostanie ona zastąpiona kodem php odpowiedzialnym za jej zwrócenie. Jeśli instrukcję warunkową, ta zostanie zastąpiona odpowiednią pętlą, zaś warunek zostanie przepisany tak, aby działał i niezawierał nieporządanego kodu. Gdy zostanie napotkany blok zawierający funkcje, te zostąną przetłumaczone na odpowiadający im kod php. Z różnych względów, zdecydowałem się nie implementować obsługi funkcji do warunków. I tak do niczego by się w nich nie przydały.</p>
<p><strong>Porównanie</strong></p>
<p>Na zakończenie zademonstruję dwa fragemnty kodu, demonstrujące wykorzystanie templat kiedyś, i dziś:</p>
<p><code><br />
$this -> style -> loadTemplatesGroup( 'some_templates');<br />
$template = new api_get_template( 'template_id');<br />
$template -> registerValue( 'var_a', 3.14);<br />
$template -> registerValue( 'var_boing_boing', 'Want to register?');<br />
$this -> output -> addToOutput( $template -> drawTemplate());<br />
</code></p>
<p>I nowy kod:</p>
<p><code><br />
$template = $this -> unisolutions -> style -> loadTemplate( 'some_templates');<br />
echo $template -> template_template_id( array(<br />
var_a' => 3.14,<br />
'var_boing_boing' => 'Want to register?'<br />
));<br />
$this -> output -> drawFullOutput(); //metoda wykonywana na końcu generowania html przez akcję<br />
</code></p>
]]></content:encoded>
			<wfw:commentRss>http://rpiton.com/?feed=rss2&amp;p=111</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Callisto NIE jest przerobionym IPB</title>
		<link>http://rpiton.com/?p=109</link>
		<comments>http://rpiton.com/?p=109#comments</comments>
		<pubDate>Tue, 03 Mar 2009 21:57:24 +0000</pubDate>
		<dc:creator>Rafał Pitoń</dc:creator>
				<category><![CDATA[1.x (Callisto)]]></category>
		<category><![CDATA[Unisolutions]]></category>
		<category><![CDATA[uniBoard]]></category>

		<guid isPermaLink="false">http://rpiton.com/?p=109</guid>
		<description><![CDATA[Kto tak twierdzi? Sam Invision: Hello, We have looked over software and we can tell that this is not our software, it does look as if some parts may have been inspired by our software but, ultimately all the code looks original. If you have any other questions, please ask. Have a great day! Nakisha [...]]]></description>
			<content:encoded><![CDATA[<p>Kto tak twierdzi? Sam Invision:</p>
<blockquote><p>
Hello,</p>
<p>We have looked over software and we can tell that this is not our software, it does look as if some parts may have been inspired by our software but, ultimately all the code looks original.</p>
<p>If you have any other questions, please ask.  Have a great day!</p>
<p>Nakisha Thomas<br />
Invision Power Services<br />
Director of Customer Satisfaction
</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://rpiton.com/?feed=rss2&amp;p=109</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Podróż w przeszłość</title>
		<link>http://rpiton.com/?p=107</link>
		<comments>http://rpiton.com/?p=107#comments</comments>
		<pubDate>Thu, 26 Feb 2009 22:46:34 +0000</pubDate>
		<dc:creator>Rafał Pitoń</dc:creator>
				<category><![CDATA[1.x (Callisto)]]></category>
		<category><![CDATA[Stare]]></category>
		<category><![CDATA[Unisolutions]]></category>
		<category><![CDATA[uniBoard]]></category>

		<guid isPermaLink="false">http://rpiton.com/?p=107</guid>
		<description><![CDATA[Jeśli kogoś interesuje, jak rok temu wyglądało Callisto, oto screen z 26 lutego 2008: http://rpiton.com/_work/old/Callisto/dark.jpg Dla zainteresowanych powiem że na dzień dzisiejszy uniBoard generuje to samo + listę for ;)]]></description>
			<content:encoded><![CDATA[<p>Jeśli kogoś interesuje, jak rok temu wyglądało Callisto, oto screen z 26 lutego 2008:</p>
<p>http://rpiton.com/_work/old/Callisto/dark.jpg</p>
<p>Dla zainteresowanych powiem że na dzień dzisiejszy uniBoard generuje to samo + listę for ;)</p>
]]></content:encoded>
			<wfw:commentRss>http://rpiton.com/?feed=rss2&amp;p=107</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Nagroda za perfekcyjny design roku 2008</title>
		<link>http://rpiton.com/?p=104</link>
		<comments>http://rpiton.com/?p=104#comments</comments>
		<pubDate>Sun, 15 Feb 2009 22:24:20 +0000</pubDate>
		<dc:creator>Rafał Pitoń</dc:creator>
				<category><![CDATA[Reszta]]></category>

		<guid isPermaLink="false">http://rpiton.com/?p=104</guid>
		<description><![CDATA[Zapukała do HavenWorks, i uciekła z krzykiem ;)]]></description>
			<content:encoded><![CDATA[<p>Zapukała do <a href="http://www.havenworks.com">HavenWorks</a>, i uciekła z krzykiem ;)</p>
]]></content:encoded>
			<wfw:commentRss>http://rpiton.com/?feed=rss2&amp;p=104</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>
