<?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>Splatch's devblog &#187; PHP</title>
	<atom:link href="http://blog.dywicki.pl/category/php/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.dywicki.pl</link>
	<description>Pragmatyzm kontrolowany</description>
	<lastBuildDate>Fri, 05 Jun 2009 14:30:15 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=abc</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Typ wyliczeniowy TimeUnit w Javie oraz klasa w PHP</title>
		<link>http://blog.dywicki.pl/2008/12/09/timeunit-enum-in-java-and-class-inphp/</link>
		<comments>http://blog.dywicki.pl/2008/12/09/timeunit-enum-in-java-and-class-inphp/#comments</comments>
		<pubDate>Tue, 09 Dec 2008 16:10:00 +0000</pubDate>
		<dc:creator>Łukasz Dywicki</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://blog.dywicki.pl/?p=242</guid>
		<description><![CDATA[Java od wersji 5.0 zawiera możliwość definiowania typów wyliczeniowych. Jednym z praktycznych przykładów zastosowania tego mechanizmu jest TimeUnit. Enum ten służy do konwertowania jednostek czasu pomiędzy różnymi wielkościami &#8211; na przykład z minut na sekundy:

import java.util.concurrent.TimeUnit;
// ...
TimeUnit.MINUTES.toSeconds(55);

Fajna sprawa &#8211; jeśli mamy do czynienia z konwersjami. Inny pożyteczny przykład to przekazywanie czasu jako argumentu:

package org.code_house.concurrent;

import java.util.Date;
import [...]]]></description>
			<content:encoded><![CDATA[<p>Java od wersji 5.0 zawiera możliwość definiowania typów wyliczeniowych. Jednym z praktycznych przykładów zastosowania tego mechanizmu jest <a href="http://www.docjar.com/docs/api/java/util/concurrent/TimeUnit.html">TimeUnit</a>. Enum ten służy do konwertowania jednostek czasu pomiędzy różnymi wielkościami &#8211; na przykład z minut na sekundy:</p>
<pre class="brush: java;">
import java.util.concurrent.TimeUnit;
// ...
TimeUnit.MINUTES.toSeconds(55);
</pre>
<p>Fajna sprawa &#8211; jeśli mamy do czynienia z konwersjami. Inny pożyteczny przykład to przekazywanie czasu jako argumentu:</p>
<pre class="brush: java;">
package org.code_house.concurrent;

import java.util.Date;
import java.util.concurrent.TimeUnit;

public class Lock {
    void lock(TimeUnit unit, long value) throws InterruptedException {
        Thread.sleep(unit.toMillis(value));
    }

    public static void main(String[] args) throws Exception {
        System.out.println(&quot;before &quot; + new Date());

        new Lock().lock(TimeUnit.SECONDS, 30);

        System.out.println(&quot;after &quot; + new Date());
    }

}
</pre>
<p>Programista, który używa takiej klasy nie musi się więc przejmować konwertowaniem jednostek na milisekundy, które są podstawą do wywołania metody Thread.sleep.</p>
<p>TimeUnit obsługuje następujące wielkości:</p>
<ul>
<li>nanosekundy</li>
<li>mikrosekundy</li>
<li>milisekundy</li>
<li>sekundy</li>
<li>minuty</li>
<li>godziny</li>
<li>dni</li>
</ul>
<p>Posługując się kodem z Javy postanowiłem sobie przypomnieć nieco <acronym title="Pre-Hypertext Processing">PHP</acronym> i napisałem wersję tego typu wyliczeniowego dla PHP:</p>
<pre class="brush: php;">&lt;?php
// namespace org\code_house\util;
/**
 * A simple class for converting between time units.
 *
 * @author Łukasz Dywicki &lt;luke@code-house.org&gt;
 */
class TimeUnit {

    /**
     * Nanoseconds.
     */
    const NANOS     = 0;

    /**
     * Microseconds.
     */
    const MICROS    = 1;

    /**
     * Milliseconds
     */
    const MILLIS    = 2;

    /**
     * Seconds.
     */
    const SECONDS   = 3;

    /**
     * Minutes.
     */
    const MINUTES   = 4;

    /**
     * Hours.
     */
    const HOURS     = 5;

    /**
     * Days.
     */
    const DAYS      = 6;

    /**
     * Conversion table between time units.
     * @var array
     */
    private static $modifiers = array(
         self::NANOS     =&gt; 0.000000001,
         self::MICROS    =&gt; 0.000001,
         self::MILLIS    =&gt; 0.001,
         self::SECONDS   =&gt; 1,
         self::MINUTES   =&gt; 60,
         self::HOURS     =&gt; 3600,
         self::DAYS      =&gt; 86400,
    );

    /**
     * Constructs new time unit.
     *
     * @param $type TimeUnit Time unit base.
     */
    public function __construct($type) {
        if ($type &lt; TimeUnit::NANOS || $type &gt; TimeUnit::DAYS) {
            throw new RuntimeException('Time unit base is out of range');
        }
        $this-&gt;type = $type;
    }

    public function toNanos($value) {
        return TimeUnit::convert($this-&gt;type, $value, TimeUnit::NANOS);
    }

    public function toMicros($value) {
        return TimeUnit::convert($this-&gt;type, $value, TimeUnit::MICROS);
    }

    public function toMilis($value) {
        return TimeUnit::convert($this-&gt;type, $value, TimeUnit::MILLIS);
    }

    public function toSeconds($value) {
        return TimeUnit::convert($this-&gt;type, $value, TimeUnit::SECONDS);
    }

    public function toMinutes($value) {
        return TimeUnit::convert($this-&gt;type, $value, TimeUnit::MINUTES);
    }

    public function toHours($value) {
        return TimeUnit::convert($this-&gt;type, $value, TimeUnit::HOURS);
    }

    public function toDays($value) {
        return TimeUnit::convert($this-&gt;type, $value, TimeUnit::DAYS);
    }

    /**
     * Convert method.
     *
     * @param $from Time unit
     * @param $value Number of values.
     * @param $to Time unit
     * @return decimal
     */
    private final static function convert($from, $value, $to) {
        if ($from === $to) {
            return $value;
        }

        $value *= self::$modifiers[$from];
        return $value / self::$modifiers[$to];
    }
}

// przykład użycia
$unit = new TimeUnit(TimeUnit::SECONDS);
echo $unit-&gt;toMinutes(60) .&quot;\n&quot;;

$unit = new TimeUnit(TimeUnit::HOURS);
echo $unit-&gt;toMinutes(1) .&quot;\n&quot;;

?&gt;</pre>
<p>Niestety brak pól z modyfikatorami <b>public static final</b> w <acronym title="Pre-Hypertext Processing">PHP</acronym> uniemożliwił zastosowanie choćby czegoś podobnego do typu wyliczeniowego.. Kod klasy dla <acronym title="Pre-Hypertext Processing">PHP</acronym> jest wolnodostępny. :-)</p>]]></content:encoded>
			<wfw:commentRss>http://blog.dywicki.pl/2008/12/09/timeunit-enum-in-java-and-class-inphp/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Adnotacje w Javie i w PHP</title>
		<link>http://blog.dywicki.pl/2008/01/20/adnotacje-w-javie-i-w-php/</link>
		<comments>http://blog.dywicki.pl/2008/01/20/adnotacje-w-javie-i-w-php/#comments</comments>
		<pubDate>Sun, 20 Jan 2008 21:55:28 +0000</pubDate>
		<dc:creator>Łukasz Dywicki</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://blog.dywicki.pl/2008/01/20/adnotacje-w-javie-i-w-php/</guid>
		<description><![CDATA[Parę dni wstecz trafiłem na ciekawe rozszerzenie Reflection API do PHP. Umożliwia ono używanie tagów phpdoc w charakterze adnotacji. Rozwiązanie te jest zbliżone do znanego mi z Javy xdocleta. Drobną, aczkolwiek zauważalną, różnicą jest fakt, że xdoclet był odpalany przed kompilacją kodu ponieważ bytecode nie zawierał adnotacji. Oczywiście po wejściu Javy 5 xdoclet podupadł, jako [...]]]></description>
			<content:encoded><![CDATA[<p>Parę dni wstecz trafiłem na ciekawe rozszerzenie <a href="http://pl2.php.net/manual/en/language.oop5.reflection.php">Reflection <acronym title="Application Programming Interface">API</acronym></a> do <acronym title="Pre-Hypertext Processing">PHP</acronym>. Umożliwia ono używanie tagów <a href="http://phpdoc.org">phpdoc </a>w charakterze adnotacji. Rozwiązanie te jest zbliżone do znanego mi z Javy <a href="http://xdoclet.sourceforge.net/">xdocleta</a>. Drobną, aczkolwiek zauważalną, różnicą jest fakt, że xdoclet był odpalany przed kompilacją kodu ponieważ bytecode nie zawierał adnotacji. Oczywiście po wejściu Javy 5 xdoclet podupadł, jako coś co wyparły właśnie adnotacje. Może dla tych, którzy nie mieli okazji spotkania sie z takim rozwiązaniem drobny przykład kodu w Javie:</p>
<pre class="brush: java;">package pl.dywicki.swe.domain;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity(name = &quot;user&quot;)
@Table(name = &quot;user&quot;, schema = &quot;public&quot;)
public class User {

	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	@Column(name = &quot;user_id&quot;)
	private long id;

	@Column(name=&quot;user_login&quot;)
	private String login;

	@Column(name=&quot;user_password&quot;)
	private String password;

	public long getId() {
		return id;
	}

	public void setId(long id) {
		this.id = id;
	}

	public String getLogin() {
		return login;
	}

	public void setLogin(String login) {
		this.login = login;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

}
</pre>
<p>Co umożliwia takie rozwiązanie? Przede wszystkim dzięki zastosowaniu adnotacji spada ilość dodatkowych plików zawierających konfiguracje i mapowania. Oczywiście nie da się ich dzięki temu rozwiązaniu wykluczyć zupełnie, aczkolwiek da się znacznie ograniczyć ich użycie. Wielką zaletą, o której do tej pory nie wspomniałem, w przypadku Javy, jest to, że adnotacje możemy odczytywać w czasie uruchamiania programu a nie przed jego kompilacją.</p>
<h3>Adnotacja od strony technicznej</h3>
<p>Jak można zadeklarować własną adnotację? Służy do tego specjalna konstrukcja:</p>
<pre class="brush: java;">public @interface Name {
   String value() default &quot;anonymous&quot;;
}</pre>
<p>Użycie takiej adnotacji:</p>
<pre class="brush: java;">@Name // poprawnie
public class Component {}

@Name(&quot;user.session&quot;) // również poprawnie
public class User {}
</pre>
<p>Możemy również przekazać kilka wartości gdy zadeklarujemy w adnotacji odpowiednie pole:</p>
<pre class="brush: java;">public @interface Relation {
   String[] belongsTo();
   String offer();
}</pre>
<p>Użycie takiej adnotacji:</p>
<pre class="brush: java;">@Relation(belongTo = {&quot;users&quot;, &quot;groups&quot;}, offer = &quot;privileges&quot;)
public class PrivilegesEntityMapping {}</pre>
<p>Warto tutaj wspomnieć o dwóch magicznych umowach. Po pierwsze atrybut o nazwie <b>value</b> jest domyślnym przypisaniem wartości podanej w nawiasach. Tzn przy wywołaniu @Name(&#8221;user.session&#8221;) możemy pobrać atrybut poprzez <b>annotationInstance.value()</b>. Po drugie dodanie po nazwie pola <b>default &#8220;wartość&#8221;</b> pozwala na pominięcie atrybutu przy definicji. Z ograniczeń, jakie mają adnotacje w Javie &#8211; wartościami atrybutów mogą być ciągi znaków, typy (klasy) oraz typy wyliczeniowe (enumy).</p>
<p>Jak użyć adnotacji? Korzystając z reflection api.</p>
<pre class="brush: java;">Name instance = getClass().getAnnotation(Name.class); // Name.class to typ naszej adnotacji.
System.out.println(instance.value());</pre>
<h3>Adnotacje a <acronym title="Pre-Hypertext Processing">PHP</acronym></h3>
<p>Jak wcześniej wspominałem, adnotacje nie są elementem <acronym title="Pre-Hypertext Processing">PHP</acronym>, chociaż ludzie pokusili się już o zbudowanie mechanizmu podobnego do tego, który jest w Javie. Jednym z takich projektów jest <a href="http://code.google.com/p/addendum/">Addendum</a>. Warto zaznaczyć, że nie jest to nazwa wyssana z palca a słowo &#8220;addendum&#8221; ma swoje znaczenie również w języku polskim i ogólnie rzecz biorąc znaczy dodatek do jakiegoś tekstu (więcej informacji na <a href="http://pl.wiktionary.org/wiki/addendum">wikisłowniku</a>).</p>
<p>Jak wygląda użycie adnotacji w <acronym title="Pre-Hypertext Processing">PHP</acronym>? Jednym z przykładów może być <a href="http://code.google.com/p/torpedeo/">Torpedeo</a>. Projekt tego samego autora co Addendum, będący implementacją lekkiego ORMa. Przykładowa deklaracja obsługiwana przez Torpedeo:</p>
<pre class="brush: php;">&lt;?php
/**
 * @Table('nodes')
 */
class Node {
	/** @Integer */
	public $id;

	/** @String */
	public $title;

	/**
	 * @Integer
	 * @Nullable
	 * @Column('parent_id');
	 */
	public $parentId;

	/** @Boolean */
	public $visible;
}
?&gt;</pre>
<p>Addendum wymaga by klasy adnotacji rozszerzały klasę Annotation:</p>
<pre class="brush: php;">&lt;?php
class Nullable extends Annotation {}
class Transient extends Annotation {}
?&gt;</pre>
<p>Dodatkowo biblioteka dostarcza rozszerzeń reflection <acronym title="Application Programming Interface">API</acronym> z PHP5 umożliwiające odczytywanie adnotacji. <a href="http://code.google.com/p/addendum/wiki/ShortTutorialByExample">Dokładny tutorial</a> jak używać tego narzędzia można znaleźć na <a href="http://code.google.com/p/addendum/">oficjalnej stronie projektu</a>.</p>
<h3>Adnotacje w <acronym title="Pre-Hypertext Processing">PHP</acronym>?</h3>
<p>Pytanie czy adnotacje w <acronym title="Pre-Hypertext Processing">PHP</acronym> przyjmą się tak samo dobrze jak w Javie? Zdaje się, że by o tym mówić jest zbyt wcześnie, ponieważ projektów, które korzystają z tego mechanizmu jest na chwilę obecną bardzo mało. Sądząc jednak po tym jak szybko rozwinął się xdoclet można twierdzić, że to tylko kwestia czasu. Chociaż.. może w Javie po prostu jest więcej plików konfiguracyjnych?</p>]]></content:encoded>
			<wfw:commentRss>http://blog.dywicki.pl/2008/01/20/adnotacje-w-javie-i-w-php/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Weź do Javy to co chcesz z PHP!</title>
		<link>http://blog.dywicki.pl/2007/11/09/wez-do-javy-to-co-chcesz-z-php/</link>
		<comments>http://blog.dywicki.pl/2007/11/09/wez-do-javy-to-co-chcesz-z-php/#comments</comments>
		<pubDate>Thu, 08 Nov 2007 23:52:05 +0000</pubDate>
		<dc:creator>Łukasz Dywicki</dc:creator>
				<category><![CDATA[JAXB]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[XML]]></category>

		<guid isPermaLink="false">http://blog.dywicki.pl/?p=197</guid>
		<description><![CDATA[Integracja między językami czy też platformami to kwestia poruszana nie od dzisiaj. Na poziomie platform funkcjonuje od dłuższego czasu CORBA i Web Services z trio SOAP + WSDL + XML Schema na czele. Integracja systemów napisanych w tym samym języku sprowadza się zwykle do wykorzystania serializacji, która jest najszybsza i najwygodniejsza. Gorzej jeśli idzie o [...]]]></description>
			<content:encoded><![CDATA[<p>Integracja między językami czy też platformami to kwestia poruszana nie od dzisiaj. Na poziomie platform funkcjonuje od dłuższego czasu CORBA i Web Services z trio <acronym title="Simple Object Access Protocol">SOAP</acronym> + <acronym title="Web Services Description Language">WSDL</acronym> + <acronym title="eXtensible Markup Language">XML</acronym> Schema na czele. Integracja systemów napisanych w tym samym języku sprowadza się zwykle do wykorzystania serializacji, która jest najszybsza i najwygodniejsza. Gorzej jeśli idzie o połączenie dwóch języków - w moim przypadku <acronym title="Pre-Hypertext Processing">PHP</acronym> i Javy.<br />
Zend ma swój mostek, który umożliwia na zintegrowanie Javy i <acronym title="Pre-Hypertext Processing">PHP</acronym>, jest też dodatkowe rozszerzenie do <acronym title="Pre-Hypertext Processing">PHP</acronym>, które pozwala na wykorzystanie Javy w <acronym title="Pre-Hypertext Processing">PHP</acronym>, jednakże moje oczekiwania nie był aż tak wielkie. Potrzebowałem po prostu odczytać dane specyficzne dla <acronym title="Pre-Hypertext Processing">PHP</acronym> - powiedzmy informacje o jakiejś klasie. Standardowo taka operacja wymagała stworzenia parsera, co jest zadaniem powiedzmy, nie na moje siły i umiejętności.. stąd też postanowiłem sobie nieco uprościć pracę. :)</p>
<p>Wspólny, najwygodniejszy format (zarówno w odczycie i zapisie danych) z jednej i drugiej strony to oczywiście <acronym title="eXtensible Markup Language">XML</acronym>. Problem w tym, jaki format ma być wykorzystany. Nie da się przecież bezpośrednio odwzorować obiektu z <acronym title="Pre-Hypertext Processing">PHP</acronym> do Javy głównie z racji na dynamikę. Jeśli w <acronym title="Pre-Hypertext Processing">PHP</acronym> ktoś dorzuci pole do obiektu, poprzez proste <b>$someUser->city = 'Białystok'</b> to Java bazująca tylko na statycznych, zadeklarowanych polach w klasie nie odczyta tej informacji. Serializacja w postaci specyficznej dla <acronym title="Pre-Hypertext Processing">PHP</acronym> również wiąże się ze stworzeniem parsera po stronie Javy by to wszystko obsługiwać i dodatkowo coś co by później mapowało obiekty z Javy do XMLa w postaci przyjaznej dla <acronym title="Pre-Hypertext Processing">PHP</acronym>. Wyjściem z całej sytuacji okazały się funkcje <a href="http://pl2.php.net/manual/en/ref.wddx.php">wddx_*</a>. Po prostu strzał w dziesiątkę. <a href="http://www.openwddx.org/">WDDX</a> to standard może nie najnowszy, ale dosyć spójny, i co najważniejsze umożliwiający przesyłanie złożonych obiektów bez zbytniej walki. Po chwili poszukiwań znalazłem <a href="http://www.openwddx.org/downloads/dtd/wddx_dtd_10.txt"><acronym title="Document Type Definition">DTD</acronym></a>, zatem ze strony Javy wystarczy odpalić <a href="http://java.sun.com/webservices/jaxb/index.jsp">JAXB</a> i jesteśmy na miejscu.</p>
<p>Przykładowy skrypt <acronym title="Pre-Hypertext Processing">PHP</acronym>, który uzyskuje informacje o konfiguracji Agavi:</p>
<div class="igBar"><span id="lphp-6"><a href="#" onclick="javascript:showPlainTxt('php-6'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">PHP:</span>
<div id="php-6">
<div class="php">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#007700; font-weight:bold;">&lt;?php</span></div>
</li>
<li style="font-weight: normal;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#007700;">include_once</span> <span style="color:#DD0000;">'E:/htdocs/shop/agavi/agavi.php'</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#0000BB;">$value</span> = <span style="color:#3A6A8B;">wddx_serialize_value</span><span style="color:#0000BB; font-style: bold;">&#40;</span>AgaviConfig::<span style="color:#3A6A8B;">export</span><span style="color:#0000BB; font-style: bold;">&#40;</span><span style="color:#0000BB; font-style: bold;">&#41;</span><span style="color:#0000BB; font-style: bold;">&#41;</span>;</div>
</li>
<li style="font-weight: normal;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#0000BB;">$value</span> = <span style="color:#DD0000;">"&lt;?xml version='1.0' encoding='utf-8' ?&gt;<span style="color:#DD0000;">\n</span>&lt;!DOCTYPE wddxPacket SYSTEM 'wddx.dtd'&gt;<span style="color:#DD0000;">\n</span>"</span> . <span style="color:#0000BB;">$value</span>;</div>
</li>
<li style="font-weight: normal;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#007700;">echo</span> <span style="color:#0000BB;">$value</span>; </div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<p>A teraz część wyniku, który <acronym title="Pre-Hypertext Processing">PHP</acronym> wyświetla w konsoli:</p>
<div class="igBar"><span id="lxml-7"><a href="#" onclick="javascript:showPlainTxt('xml-7'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">XML:</span>
<div id="xml-7">
<div class="xml">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;</span>?xml <span style="color: #000066;">version</span>=<span style="color: #ff0000;">"1.0"</span> <span style="color: #000066;">encoding</span>=<span style="color: #ff0000;">"utf-8"</span> ?<span style="font-weight: bold; color: black;">&gt;</span></span></div>
</li>
<li style="font-weight: normal;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #00bbdd;">&lt;!DOCTYPE wddxPacket SYSTEM 'wddx.dtd'&gt;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;wddxpacket</span> <span style="color: #000066;">version</span>=<span style="color: #ff0000;">'1.0'</span><span style="font-weight: bold; color: black;">&gt;</span></span></div>
</li>
<li style="font-weight: normal;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;header</span> <span style="font-weight: bold; color: black;">/&gt;</span></span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;data<span style="font-weight: bold; color: black;">&gt;</span></span></span></div>
</li>
<li style="font-weight: normal;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;struct<span style="font-weight: bold; color: black;">&gt;</span></span></span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;var</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">'core.minimum_php_version'</span><span style="font-weight: bold; color: black;">&gt;</span></span></div>
</li>
<li style="font-weight: normal;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;string<span style="font-weight: bold; color: black;">&gt;</span></span></span>5.1.0<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/string<span style="font-weight: bold; color: black;">&gt;</span></span></span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/var<span style="font-weight: bold; color: black;">&gt;</span></span></span></div>
</li>
<li style="font-weight: normal;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;var</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">'core.agavi_dir'</span><span style="font-weight: bold; color: black;">&gt;</span></span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;string<span style="font-weight: bold; color: black;">&gt;</span></span></span>E:\htdocs\shop\agavi<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/string<span style="font-weight: bold; color: black;">&gt;</span></span></span></div>
</li>
<li style="font-weight: normal;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/var<span style="font-weight: bold; color: black;">&gt;</span></span></span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #808080; font-style: italic;">&lt;!-- i tak dalej --&gt;</span></span></div>
</li>
<li style="font-weight: normal;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/struct<span style="font-weight: bold; color: black;">&gt;</span></span></span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/data<span style="font-weight: bold; color: black;">&gt;</span></span></span></div>
</li>
<li style="font-weight: normal;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/wddxpacket<span style="font-weight: bold; color: black;">&gt;</span></span></span> </div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<p>Teraz kod Javy, który odczytuje sobie informacje.. (nawiasy kwadratowe przy listach podyktowane błędami w skrypcie, który koloruje składnię)</p>
<pre class="brush: java;">

		// odpalamy interpreter <acronym title="Pre-Hypertext Processing">PHP</acronym>
		Runtime runtime = Runtime.getRuntime();
		Process exec = runtime.exec(&quot;php -q E:/agavi-ide/org.codehouse.bridge/src/org/codehouse/bridge/test2.php&quot;);

		// podnosimy kontekst JAXB
		JAXBContext context = JAXBContext.newInstance(ObjectFactory.class);
		// deserializujemy <acronym title="eXtensible Markup Language">XML</acronym> wygenerowany przez <acronym title="Pre-Hypertext Processing">PHP</acronym>
		WddxPacket object = (WddxPacket) context.createUnmarshaller().unmarshal(exec.getInputStream());

		// odczytujemy informacje
		for (Object stc : object.getData().getWDDXData()) {
			// spodziewamy się informacji o typie złożonym
			if (stc instanceof Struct) {
				List[generated.Var] vara = ((Struct) stc).getVar();
				for (Var value : vara) {
					// pozostaje nam tylko odczytanie zserializowanej wartości
					List[Object] configurationValue = value.getWDDXData();
					System.out.println(value.getName() + &quot;: &quot; + ((generated.String) configurationValue.get(0)).getvalue());
				}
			}
		}
</pre>
<p>Wynik działania poniższego kodu to:</p>
<div class="igBar"><span id="lcode-8"><a href="#" onclick="javascript:showPlainTxt('code-8'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">CODE:</span>
<div id="code-8">
<div class="code">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">core.<span style="">minimum_php_version</span>: <span style="color:#800000;color:#800000;">5</span>.<span style="color:#800000;color:#800000;">1</span>.<span style="color:#800000;color:#800000;">0</span></div>
</li>
<li style="font-weight: normal;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">core.<span style="">agavi_dir</span>: E:\htdocs\shop\agavi</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">exception.<span style="">default_template</span>: E:\htdocs\shop\agavi/exception/templates/shiny.<span style="">php</span></div>
</li>
<li style="font-weight: normal;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">agavi.<span style="">name</span>: Agavi</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">agavi.<span style="">major_version</span>: <span style="color:#800000;color:#800000;">0</span></div>
</li>
<li style="font-weight: normal;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">agavi.<span style="">minor_version</span>: <span style="color:#800000;color:#800000;">11</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">agavi.<span style="">micro_version</span>: <span style="color:#800000;color:#800000;">0</span></div>
</li>
<li style="font-weight: normal;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">agavi.<span style="">status</span>: DEV</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">agavi.<span style="">branch</span>: trunk</div>
</li>
<li style="font-weight: normal;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">agavi.<span style="">version</span>: <span style="color:#800000;color:#800000;">0</span>.<span style="color:#800000;color:#800000;">11</span>.<span style="color:#800000;color:#800000;">0</span>-DEV</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">agavi.<span style="">release</span>: Agavi <span style="color:#800000;color:#800000;">0</span>.<span style="color:#800000;color:#800000;">11</span>.<span style="color:#800000;color:#800000;">0</span>-DEV</div>
</li>
<li style="font-weight: normal;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">agavi.<span style="">url</span>: http:<span style="color:#FF9933; font-style:italic;">//www.agavi.org</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">agavi_info: Agavi <span style="color:#800000;color:#800000;">0</span>.<span style="color:#800000;color:#800000;">11</span>.<span style="color:#800000;color:#800000;">0</span>-DEV <span style="color:#006600; font-weight:bold;">&#40;</span>http:<span style="color:#FF9933; font-style:italic;">//www.agavi.org) </span></div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<p>Czyli wszystko czego trzeba było nam do szczęścia! :)</p>
<p>Pora na przykład bardziej złożony, wyciągnięcie informacji o jakiejś klasie widoku użytej w aplikacji opartej o Agavi.</p>
<div class="igBar"><span id="lphp-9"><a href="#" onclick="javascript:showPlainTxt('php-9'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">PHP:</span>
<div id="php-9">
<div class="php">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#007700; font-weight:bold;">&lt;?php</span></div>
</li>
<li style="font-weight: normal;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#007700;">include_once</span> <span style="color:#DD0000;">'E:/htdocs/shop/agavi/agavi.php'</span>;</div>
</li>
<li style="font-weight: normal;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">AgaviConfig::<span style="color:#3A6A8B;">set</span><span style="color:#0000BB; font-style: bold;">&#40;</span><span style="color:#DD0000;">'core.app_dir'</span>, <span style="color:#DD0000;">'E:/htdocs/shop/project/'</span><span style="color:#0000BB; font-style: bold;">&#41;</span>;</div>
</li>
<li style="font-weight: normal;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">AgaviConfig::<span style="color:#3A6A8B;">set</span><span style="color:#0000BB; font-style: bold;">&#40;</span><span style="color:#DD0000;">'core.system_config_dir'</span>, <span style="color:#DD0000;">'E:/htdocs/shop/agavi/config/defaults/'</span><span style="color:#0000BB; font-style: bold;">&#41;</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-weight: normal;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#FF8000; font-style:italic;">// metoda dopisana przeze mnie, konfiguruje Agavi bez wyrzucania wyjątków.</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">Agavi::<span style="color:#3A6A8B;">bootstrap2</span><span style="color:#0000BB; font-style: bold;">&#40;</span><span style="color:#DD0000;">''</span><span style="color:#0000BB; font-style: bold;">&#41;</span>;</div>
</li>
<li style="font-weight: normal;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#007700;">include_once</span> <span style="color:#DD0000;">'E:/htdocs/shop/project/modules/Cart/lib/BaseInputView.class.php'</span>;</div>
</li>
<li style="font-weight: normal;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#0000BB;">$obj</span> = <span style="color:#007700; font-weight:bold;">new</span> ReflectionClass<span style="color:#0000BB; font-style: bold;">&#40;</span><span style="color:#DD0000;">'Cart_BaseInputView'</span><span style="color:#0000BB; font-style: bold;">&#41;</span>;</div>
</li>
<li style="font-weight: normal;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#0000BB;">$orig</span> = <span style="color:#0000BB;">$obj</span>-&gt;<span style="color:#3A6A8B;">getFileName</span><span style="color:#0000BB; font-style: bold;">&#40;</span><span style="color:#0000BB; font-style: bold;">&#41;</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-weight: normal;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#0000BB;">$myMethods</span> = <span style="color:#0000BB;">$obj</span>-&gt;<span style="color:#3A6A8B;">getMethods</span><span style="color:#0000BB; font-style: bold;">&#40;</span><span style="color:#0000BB; font-style: bold;">&#41;</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-weight: normal;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#0000BB;">$methods</span> = <span style="color:#3A6A8B;">array</span><span style="color:#0000BB; font-style: bold;">&#40;</span><span style="color:#0000BB; font-style: bold;">&#41;</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-weight: normal;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#007700;">foreach</span> <span style="color:#0000BB; font-style: bold;">&#40;</span><span style="color:#0000BB;">$myMethods</span> <span style="color:#007700;">as</span> <span style="color:#0000BB;">$method</span><span style="color:#0000BB; font-style: bold;">&#41;</span> <span style="color:#0000BB; font-style: bold;">&#123;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color:#FF8000; font-style:italic;">// sprawdzenie czy plik w którym jest zadeklarowana metoda</span></div>
</li>
<li style="font-weight: normal;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color:#FF8000; font-style:italic;">// pokrywa się z plikiem w którym jest zadeklarowana klasa</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color:#FF8000; font-style:italic;">// w ten sposób pozbywam się niepotrzebnych metod z klas nadrzędnych</span></div>
</li>
<li style="font-weight: normal;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color:#007700;">if</span> <span style="color:#0000BB; font-style: bold;">&#40;</span><span style="color:#0000BB;">$method</span>-&gt;<span style="color:#3A6A8B;">getFileName</span><span style="color:#0000BB; font-style: bold;">&#40;</span><span style="color:#0000BB; font-style: bold;">&#41;</span> == <span style="color:#0000BB;">$orig</span><span style="color:#0000BB; font-style: bold;">&#41;</span> <span style="color:#0000BB; font-style: bold;">&#123;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#0000BB;">$methods</span><span style="color:#0000BB; font-style: bold;">&#91;</span><span style="color:#0000BB; font-style: bold;">&#93;</span> = <span style="color:#0000BB;">$method</span>;</div>
</li>
<li style="font-weight: normal;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color:#0000BB; font-style: bold;">&#125;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#0000BB; font-style: bold;">&#125;</span></div>
</li>
<li style="font-weight: normal;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-weight: normal;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#0000BB;">$value</span> = <span style="color:#3A6A8B;">wddx_serialize_value</span><span style="color:#0000BB; font-style: bold;">&#40;</span><span style="color:#0000BB;">$methods</span><span style="color:#0000BB; font-style: bold;">&#41;</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#0000BB;">$value</span> = <span style="color:#DD0000;">"&lt;?xml version='1.0' encoding='utf-8' ?&gt;&lt;!DOCTYPE wddxPacket SYSTEM 'wddx.dtd'&gt;<span style="color:#DD0000;">\n</span>"</span> . <span style="color:#0000BB;">$value</span>;</div>
</li>
<li style="font-weight: normal;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#007700;">echo</span> <span style="color:#0000BB;">$value</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-weight: normal;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#007700; font-weight:bold;">?&gt;</span> </div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<p>Drobna przeróbka kodu Javy, który był użyty wcześniej i wynikiem jest</p>
<div class="igBar"><span id="lcode-10"><a href="#" onclick="javascript:showPlainTxt('code-10'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">CODE:</span>
<div id="code-10">
<div class="code">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">php_class_name: ReflectionMethod</div>
</li>
<li style="font-weight: normal;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">name: execute</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">class: Cart_BaseInputView </div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<p>Tym, którzy dobrnęli do końca tej noty dziękuję za wytrwałość. :) Kolejna nota będzie być może o tym jak wywoływać metody statyczne klas Javy z poziomu <acronym title="eXtensible Stylesheet Language Transformations">XSLT</acronym> (wierzcie mi, da się!).</p>]]></content:encoded>
			<wfw:commentRss>http://blog.dywicki.pl/2007/11/09/wez-do-javy-to-co-chcesz-z-php/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Mój pierwszy edytor&#8230;</title>
		<link>http://blog.dywicki.pl/2007/11/07/moj-pierwszy-edytor/</link>
		<comments>http://blog.dywicki.pl/2007/11/07/moj-pierwszy-edytor/#comments</comments>
		<pubDate>Tue, 06 Nov 2007 22:44:39 +0000</pubDate>
		<dc:creator>Łukasz Dywicki</dc:creator>
				<category><![CDATA[Agavi]]></category>
		<category><![CDATA[Eclipse]]></category>
		<category><![CDATA[JAXB]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[SWT]]></category>
		<category><![CDATA[Wiadomości]]></category>
		<category><![CDATA[XML]]></category>

		<guid isPermaLink="false">http://blog.dywicki.pl/?p=196</guid>
		<description><![CDATA[
Czas jakiś temu udało mi się stworzyć pierwszy działający edytor w oparciu o Eclipse.
Kilka informacji co pod spodem:

SharedHeaderFormEditor - ładny tekstowy nagłówek oraz możliwość dodawania zakładek
FormPage i FormToolkit - użyte do stworzenia układu, który widać na załączonym obrazku
JFace Databinding - zapewnia propagowanie zmian z formularza do obiektów
JAXB 2 - mapowanie plików XML do odpowiednich klas
JFace [...]]]></description>
			<content:encoded><![CDATA[<p><a href='http://blog.dywicki.pl/wp-content/uploads/2007/11/agavi-editor.JPG' title='Agavi module configuration editor' rel="lightbox"><img align="right" src='http://blog.dywicki.pl/wp-content/uploads/2007/11/agavi-editor.thumbnail.JPG' alt='Agavi module configuration editor'  rel="lightbox"/></a></p>
<p>Czas jakiś temu udało mi się stworzyć pierwszy działający edytor w oparciu o Eclipse.<br />
Kilka informacji co pod spodem:</p>
<ul>
<li>SharedHeaderFormEditor - ładny tekstowy nagłówek oraz możliwość dodawania zakładek</li>
<li>FormPage i FormToolkit - użyte do stworzenia układu, który widać na załączonym obrazku</li>
<li>JFace Databinding - zapewnia propagowanie zmian z formularza do obiektów</li>
<li>JAXB 2 - mapowanie plików <acronym title="eXtensible Markup Language">XML</acronym> do odpowiednich klas</li>
<li>JFace - table viewer i parę innych dodatków</li>
</ul>
<p>Całość ogólnie jest prosta niczym konstrukcja cepa, w działaniu sprawia się dobrze. Jak tylko ogarnę kod postaram się opisać krok po kroku jak można coś podobnego stworzyć na własny użytek. </p>
<p>Splatch wraca do gry i będzie grać wysoko! ;-)</p>]]></content:encoded>
			<wfw:commentRss>http://blog.dywicki.pl/2007/11/07/moj-pierwszy-edytor/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Agavi 0.11 RC5</title>
		<link>http://blog.dywicki.pl/2007/06/18/agavi-011-rc5/</link>
		<comments>http://blog.dywicki.pl/2007/06/18/agavi-011-rc5/#comments</comments>
		<pubDate>Mon, 18 Jun 2007 21:41:11 +0000</pubDate>
		<dc:creator>Łukasz Dywicki</dc:creator>
				<category><![CDATA[Agavi]]></category>
		<category><![CDATA[Framework]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Wiadomości]]></category>

		<guid isPermaLink="false">http://blog.dywicki.pl/?p=146</guid>
		<description><![CDATA[Dzisiaj rano światło dzienne ukazało się Agavi 0.11 RC5, oprócz poprawek błędów z wersji RC4 doszło parę nowości:
- Pełne wsparcie dla generowania WSDL, automatyczne mapowanie akcji a nawet wsparcie dla obsługi nagłówków SOAP.
- Wsparcie dla transformacji plików konfiguracyjnych poprzez zamieszczanie instrukcji < ?xml-stylesheet?>
- Wsparcie dla przestrzeni nazw w plikach konfiguracyjnych
- Automatyczna obsługa magic_quotes dla zmiennych [...]]]></description>
			<content:encoded><![CDATA[<p>Dzisiaj rano światło dzienne ukazało się Agavi 0.11 RC5, oprócz poprawek błędów z wersji RC4 doszło parę nowości:<br />
- Pełne wsparcie dla generowania <acronym title="Web Services Description Language">WSDL</acronym>, automatyczne mapowanie akcji a nawet wsparcie dla obsługi nagłówków <acronym title="Simple Object Access Protocol">SOAP</acronym>.<br />
- Wsparcie dla transformacji plików konfiguracyjnych poprzez zamieszczanie instrukcji < ?xml-stylesheet?><br />
- Wsparcie dla przestrzeni nazw w plikach konfiguracyjnych<br />
- Automatyczna obsługa magic_quotes dla zmiennych superglobalnych</p>
<p>Pojawiły się drobne zmiany w <acronym title="Application Programming Interface">API</acronym> do obsługi configów oraz nowy sposób ich odczytu, który wejdzie do użytku w wersji 1.0. Póki co jest tylko testowy a jedynym handlerem, który został zaimplementowany "na nowo" jest ten obsługujący <acronym title="Web Services Description Language">WSDL</acronym>.</p>
<p>Dodam, że <a href="http://agavi.org">Agavi</a> to pierwszy framework <acronym title="Pre-Hypertext Processing">PHP</acronym>, który rozwiązuje kwestie dostępu do akcji w tak elastyczny sposób. Niezależnie od tego jakim sposobem zostało przysłane żądanie akcja wygląda tak samo. Jest to krok w stronę dojrzałych rozwiązań tj <a href="http://springframework.org">Spring Framework</a>. Pytanie tylko - czy developerom uda się zachować pierwotną prostotę i ile pracy trzeba będzie włożyć w użycie danego rozwiązania? Odpowiedź na nie pozostaje póki co zagadką a pełnej oceny będziemy mogli dokonać po ukazaniu się wersji 1.0 wraz z dokumentacją.</p>
<p>Zainteresowanych naturalnie Agavi zapraszam do <a href="http://trac.agavi.org/">traca</a> i przeglądania <a href="http://trac.agavi.org/browser/tags/0.11.0RC5/">źródeł wersji 0.11 RC5</a>. :)</p>]]></content:encoded>
			<wfw:commentRss>http://blog.dywicki.pl/2007/06/18/agavi-011-rc5/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>O abstrakcji klas i interfejsów</title>
		<link>http://blog.dywicki.pl/2007/04/04/o-abstrakcji-klas-i-interfejsow/</link>
		<comments>http://blog.dywicki.pl/2007/04/04/o-abstrakcji-klas-i-interfejsow/#comments</comments>
		<pubDate>Tue, 03 Apr 2007 22:01:47 +0000</pubDate>
		<dc:creator>Łukasz Dywicki</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Ogólne]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://blog.dywicki.pl/2007/04/04/o-abstrakcji-klas-i-interfejsow/</guid>
		<description><![CDATA[Od jakiegoś czasu na forum.php.pl spotykam się z różnymi zdaniami na temat interfejsów i klas abstrakcyjnych. Argumenty, które czasami się trafiają są chybione.
Zacznijmy od tego, że trzeba potrafić rozróżnić interfejs od klasy abstrakcyjnej, to nie to samo!
Interfejs jest najwyższym poziomem abstrakcji, który definiuje nowy, wolny od implementacji typ. Bez jakiejkolwiek linii kodu, tylko sygnatury metod [...]]]></description>
			<content:encoded><![CDATA[<p>Od jakiegoś czasu na <a href="http://forum.php.pl/">forum.php.pl</a> spotykam się z różnymi zdaniami na temat interfejsów i klas abstrakcyjnych. Argumenty, które czasami się trafiają są chybione.</p>
<p>Zacznijmy od tego, że trzeba potrafić rozróżnić interfejs od klasy abstrakcyjnej, <b>to nie to samo</b>!<br />
Interfejs jest najwyższym poziomem abstrakcji, który definiuje nowy, wolny od implementacji typ. Bez jakiejkolwiek linii kodu, tylko sygnatury metod publicznych.<br />
Klasa abstrakcyjna jest już początkiem konkretnej implementacji, zawiera kod ogólny i wymusza w klasach dziedziczących dorzucenie konkretnych metod, które są specyficzne, inne, różne. Mogą trafić się takie przypadki, że klasa abstrakcyjna zawiera 5 metod, a jej pochodne tylko jedną. Czy jest to uzasadnione? Oczywiście. Ta jedna metoda determinuje nowy typ, który jest jawną specjalizacją.</p>
<p>Warto pamiętać, że w chwili gdy mamy klasę abstrakcyjną i kilka jej pochodnych dorzucenie interfejsu jest polisą na życie. Spójrzmy, na praktykę - co się powinno dziać w chwili, gdy pojawiają się kolejne pochodne oraz klasa abstrakcyjna rozrasta się do niebagatelnych rozmiarów? Wyodrębniamy wspólny interfejs (patrz <a href="http://refactoring.com/catalog/extractInterface.html">extract interface</a>) i kolejne klasy abstrakcyjne.<br />
Bez problemu dorzucamy kolejny typ i lecimy bez przestojów. W chwili gdy uzależnimy się od klasy abstrakcyjnej z jakimkolwiek kodem z biegiem czasu możemy mieć do czynienia z klasami, które zawierają po 10, 20 i więcej metod. Nawigacja po tak rozbudowanym typie jest uciążliwa a zrozumienie kodu wymaga przebrnięcia przez stos metod, które tworzą swoisty labirynt.<br />
Rozsądne użycie interfejsów i klas pozwala nam tworzyć złożone ale przejrzyste struktury. Separacja abstrakcji od implementacji określana mianem wzorca projektowego, nazwa <a href="http://www.google.pl/search?hl=pl&#038;q=bridge+design+pattern&#038;lr=&#038;btnG=Szukaj+w+Google">mostem</a> (ang. <i>bridge</i>). </p>
<p>Budowa złożonej aplikacji bez użycia interfejsów jest posunięciem wysoce nierozsądnym, ponieważ to właśnie dzięki nim, nawet w językach kompilowanych ze statycznym typowaniem jesteśmy w stanie zyskać nadzwyczajnie elastyczny kod. W aplikacji, która jest rozwijana od dłuższego czasu  (powiedzmy, ponad pół roku) to właśnie interfejsy są miejscami zawierającymi definicję poszczególnych warstw. To one powinny być trzonem każdej aplikacji (pomijając warstwę obiektów domenowych, gdzie ich rola nie musi być dominująca). Nawet jeśli koncepcja implementacji obróci się o 180 stopni to nasz interfejs, będący swoistą fasadą, ukryje te zmiany przed osobami, których one nie dotyczą bądź nie interesują.</p>
<p>Dorzucę tutaj przykład pewnego mechanizmu, który jakiś czas temu projektowałem i implementowałem. Jest to uproszczony schemat. Singletonu chciałem uniknąć, ale przesłanki ku jego zastosowaniu były na tyle duże, że pozostał. Duże <b>I</b> na początku nazwy oznacza interfejs, w nawiasach, dużymi literami wzorce. </p>
<div class="igBar"><span id="lcode-12"><a href="#" onclick="javascript:showPlainTxt('code-12'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">CODE:</span>
<div id="code-12">
<div class="code">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#006600; font-weight:bold;">&#40;</span>zdarzenie<span style="color:#006600; font-weight:bold;">&#41;</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&#40;</span>Mediator<span style="color:#006600; font-weight:bold;">&#41;</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&#40;</span>odbiorca<span style="color:#006600; font-weight:bold;">&#41;</span></div>
</li>
<li style="font-weight: normal;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">ProgressEvent ---&gt; <span style="">IProgressMonitor</span>&nbsp; &lt;---&nbsp; IProgressListener</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; <span style="color:#006600; font-weight:bold;">&#40;</span>generuj zdarzenie<span style="color:#006600; font-weight:bold;">&#41;</span>&nbsp; &nbsp; &nbsp; ^&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;^</div>
</li>
<li style="font-weight: normal;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp;IDownloader ----------+&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;|</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp;IMerger&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| <span style="color:#006600; font-weight:bold;">&#40;</span>Composite<span style="color:#006600; font-weight:bold;">&#41;</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| <span style="color:#006600; font-weight:bold;">&#40;</span>Singleton<span style="color:#006600; font-weight:bold;">&#41;</span></div>
</li>
<li style="font-weight: normal;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; IProgressMonitorGroup &lt;- - - SynchronizeManager</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-weight: normal;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ISynchronizeRequest</div>
</li>
<li style="font-weight: normal;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ^</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | <span style="color:#006600; font-weight:bold;">&#40;</span>Strategy<span style="color:#006600; font-weight:bold;">&#41;</span></div>
</li>
<li style="font-weight: normal;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;AbstractSynchronizeRequest</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;+--------------+--------------+</div>
</li>
<li style="font-weight: normal;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;|&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; |&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; |</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;|&nbsp; &nbsp;TableSynchronizeRequest&nbsp; &nbsp;|</div>
</li>
<li style="font-weight: normal;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">ClassSynchronizeRequest&nbsp; &nbsp; &nbsp; &nbsp; ModuleSynchronizeRequest </div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<p>Panowie, jak byście zaimplementowali te mechanizmy bez interfejsów? Jedną, wielką protezą?</p>]]></content:encoded>
			<wfw:commentRss>http://blog.dywicki.pl/2007/04/04/o-abstrakcji-klas-i-interfejsow/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Obiekty biznesowe w aplikacji.</title>
		<link>http://blog.dywicki.pl/2007/03/18/obiekty-biznesowe-w-aplikacji/</link>
		<comments>http://blog.dywicki.pl/2007/03/18/obiekty-biznesowe-w-aplikacji/#comments</comments>
		<pubDate>Sun, 18 Mar 2007 21:57:05 +0000</pubDate>
		<dc:creator>Łukasz Dywicki</dc:creator>
				<category><![CDATA[MVC]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://blog.dywicki.pl/2007/03/18/obiekty-biznesowe-w-aplikacji/</guid>
		<description><![CDATA[Pierwsze błędy
Pamiętam swoje pierwsze implementacje MVC, w czasach gdy słowo framework nie było jeszcze trendy a wiele osób, w tym i ja, nawet go nie używało. W owych pierwszych implementacjach MVC model był pewnego rodzaju fasadą, która zapewniała dostęp do danych.
Problem polegał na tym, że kod np klasy User wyglądał następująco:

&#60;?php
class User extends Model {
 [...]]]></description>
			<content:encoded><![CDATA[<h3>Pierwsze błędy</h3>
<p>Pamiętam swoje pierwsze implementacje MVC, w czasach gdy słowo framework nie było jeszcze trendy a wiele osób, w tym i ja, nawet go nie używało. W owych pierwszych implementacjach MVC model był pewnego rodzaju fasadą, która zapewniała dostęp do danych.<br />
Problem polegał na tym, że kod np klasy User wyglądał następująco:<br />
<span id="more-122"></span></p>
<pre class="brush: php;">&lt;?php
class User extends Model {
    function User(DB $db) {
        parent::Model($db);
    }

    function getById($id) {
        $sql = 'SELECT * FROM user WHERE user_id = '. $id;
        return $db-&gt;query($sql);
    }
}
?&gt;</pre>
<p>Jak widać na powyższym listingu klasa jest odpowiedzialna za pobieranie danych. Problem takiej implementacji polega na tym, że wciąż operujemy na tablicach bądź na ResultSetach zwracanych przez obiekt odpowiedzialny za wykonywanie zapytań. Kod w takim wykonaniu jest mocno związany z bazą danych i jest ciężki do użycia w innych projektach. Co więcej w pierwszym podejściu nie korzystałem z wielu możliwości jakie daje programowanie obiektowe i po prostu odwołania do klasy nadrzędnej czy też metody abstrakcyjne były co najmniej sporadyczne. Także, każdy "model" miał swoją metodę getById, która miała swoje zapytanie. Jest to najprostsza implementacja, która zapewnia tylko jedno - wyłączenie zapytań do oddzielnych plików.</p>
<h3>Wzorce</h3>
<p>Znacznie lepszym krokiem byłoby wykorzystanie możliwości chociażby dziedziczenia i użyć nazwanego przez <a href="http://martinfowler.com">Martina Fowlera</a> wzorca <a href="http://martinfowler.com/eaaCatalog/activeRecord.html">ActiveRecord</a>, który zapewnia nam mapowanie pojedynczej encji do klasy.</p>
<p>Problem, jaki powstaje przy użyciu ActiveRecordu to niestety uzależnienie kodu od wybranej implementacji wzorca, co więcej kod będzie nieprzenośny, np nie da się go użyć bez zewnętrznych bibliotek. Zatem problem pozostaje taki jak był wcześniej - logika, która była związana z danymi (np przeliczanie wartości jednego pola w zależności od drugiego) została zawarta w modelu staje się bezużyteczna.</p>
<p>Problemy te można rozwiązać wyraźnie oddzielając obiekty z których korzysta aplikacja od warstwy dostępu do nich. Tutaj rodzi się pojęcie <a href="http://martinfowler.com/eaaCatalog/domainModel.html">Domain Model</a> czy też Domain Object. Przede wszystkim jest to kod, który jest niezależny od źródła danych np obiekt Invoice możemy pobrać zarówno z bazy jak i z zewnętrznego systemu powiedzmy przez usługę sieciową. Obiekt zawsze zachowa się w ten sam sposób i jego użycie nie będzie zależne od miejsca z którego je uzyskaliśmy. Idealnym przykładem implementacji Domain Modelu są np beany utrwalane przy pomocy <a href="http://hibernate.org">Hibernate</a>. Mamy kod, który jest przenośny, w którym nie ma żadnych jawnych odwołań do informacji zawartych poza "obiektami domenowymi", jest ona po prostu autonomiczna.</p>
<p>Ciężko jest określić czym w pierwszej kolejności się zająć bazą czy obiektami biznesowymi? Wydaje mi się, że modelując najpierw bazę danych ciężko jest wychwycić dziedziczenia pomiędzy obiektami biznesowymi i najzwyczajniej w świecie zostaną one pominięte. Z drugiej strony tworząc najpierw obiekty biznesowe możemy natrafić na trudności z odwzorowaniem całej, nie raz, złożonej struktury do encji w bazie.</p>
<h3>Data Access Objects</h3>
<p>Dostęp warstwy z obiektami domenowymi realizujemy przez Data Access Objects. Jest to zespół klas, które zapewniają odczyt, usuwanie oraz zapisywanie obiektów (całość modyfikujemy przez dostępne w obiektach domenowych metody). DAO ma na celu zapewnienie jednolitego interfejsu dla dostępu do obiektów bez pojawiania się kodu specyficznego dla danego źródła danych, niezależnie czy to będzie baza danych czy usługa sieciowa.</p>
<h3>Service Layer</h3>
<p>Warstwa usług to miejsce przecięć różnych źródeł danych. Granica między DAO a Service Layer jest dość istotna - DAO obejmuje transakcje systemowe podczas gdy Service Layer transakcje biznesowe. Może słowo wyjaśnienia na temat tych dwóch rodzai transakcji - pierwsza jest zwykle kontrolowana przez bazę danych i zawiera ciąg poleceń <acronym title="Structured Query Language">SQL</acronym>. Transakcja biznesowa obejmuje jedną konkretną operację np przelew bankowy - to logowanie, określenie kwoty i odbiorcy, weryfikacja kodu jednorazowego oraz zablokowanie środków. Powodzenie takiej operacji zależy od wielu czynników w tym od systemów zewnętrznych.<br />
Warstwa usług jest bardzo przydatna w chwili gdy z tej samej logiki korzysta więcej niż jeden system. Niestety nie mam wielkiego doświadczenia z takimi sytuacjami i nie czuję się na siłach by o tym pisać, a to co tu przytoczyłem to głównie to co pamiętam z PoEAA.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.dywicki.pl/2007/03/18/obiekty-biznesowe-w-aplikacji/feed/</wfw:commentRss>
		<slash:comments>20</slash:comments>
		</item>
		<item>
		<title>Agavi 0.11 RC3, flow</title>
		<link>http://blog.dywicki.pl/2007/02/24/agavi-011-rc3-flow/</link>
		<comments>http://blog.dywicki.pl/2007/02/24/agavi-011-rc3-flow/#comments</comments>
		<pubDate>Fri, 23 Feb 2007 22:48:53 +0000</pubDate>
		<dc:creator>Łukasz Dywicki</dc:creator>
				<category><![CDATA[Agavi]]></category>
		<category><![CDATA[Framework]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://blog.dywicki.pl/2007/02/24/agavi-011-rc3-flow/</guid>
		<description><![CDATA[Mam niebywałą przyjemność oznajmić, że dnia 23 lutego zostało wydane, jak sam tytuł posta wskazuje, Agavi 0.11 RC3. Do pierwszej, w pełni stabilnej wersji jest już coraz bliżej.
Zgodnie z rozkładem jazdy został otwarty jeden ticket, którego realizacja została odsunięta na sam koniec. Mianowicie, opis migracji z wersji 0.10 do 0.11. Ogrom zmian, które przetaczały się [...]]]></description>
			<content:encoded><![CDATA[<p>Mam niebywałą przyjemność oznajmić, że dnia <a href="http://trac.agavi.org/log/tags/0.11.0RC3">23 lutego</a> zostało wydane, jak sam tytuł posta wskazuje, Agavi 0.11 RC3. Do pierwszej, w pełni stabilnej wersji jest już coraz bliżej.<br />
Zgodnie z rozkładem jazdy został otwarty <a href="http://trac.agavi.org/ticket/340">jeden ticket</a>, którego realizacja została odsunięta na sam koniec. Mianowicie, opis migracji z wersji 0.10 do 0.11. Ogrom zmian, które przetaczały się przez trunk repozytorium mógł przyprawić o zawrót głowy. Zmiany z rewizji na rewizję potrafiły w jednym momencie zniszczyć skrzętnie budowane narzędzia, które opierały się na zmieniających się wciąż mechanizmach.<br />
Co zyskało Agavi o wersji 0.10? Przede wszystkim developerzy uwolnili projekt od niezręcznej i nieporęcznej konfiguracji w plikach INI, która poza łatwością odczytu nastręczała przede wszystkim problemów... a to brak hierarchiczności, brak możliwości łączenia konfiguracji, w końcu brak narzędzia do walidacji zapisanych danych. W poście "<a href="http://blog.dywicki.pl/2006/09/07/dlaczego-konfiguracja-w-xml/">Dlaczego konfiguracja w <acronym title="eXtensible Markup Language">XML</acronym></a>" porównywałem <acronym title="eXtensible Markup Language">XML</acronym> również do YAMLa.<br />
Sporą zmianą, naturalnie, na lepsze było zrezygnowanie z tradycyjnego flowu Mojavi 3. Do tej pory wyglądało to w ten sposób, że każda akcja miała metodę getRequestMethods, która zwracała informacje o tym w jaki sposób dostępna jest akcja. Czy to GET, POST, bądź cokolwiek (odpowiednie stałę w klasie Request - GET, POST, NONE). Teraz o sposób dostępu do akcji determinuje nazw akcji. Akcja o nazwie executeRead będzie wykonana w chwili żądania typu GET. Metoda o nazwie executeWrite będzie wykonana w chwili gdy otrzymamy formularz via POST. Metoda execute będzie wykonywana zawsze (o ile walidacja przebiegnie bez zakłuceń). Zysk z tego jest taki, że implementacja różnych kontrolerów nie wpływa na kształt akcji. W chwili gdy wiązały się z tym stałe GET/POST implementacja wywołań z poziomu konsoli była ciężka. W zapowiedziach pojawia się ConsoleRequest, ponieważ z Agavi 0.11 wyleciały kontrolery zależne od kontekstu. Jest jeden <a href="http://trac.agavi.org/browser/tags/0.11.0RC3/src/controller/AgaviController.class.php">Controller</a>, różne są implementacje requestu vide <a href="http://trac.agavi.org/browser/tags/0.11.0RC3/src/request/AgaviConsoleRequest.class.php">ConsoleRequest</a> (jeszcze niegotowy, będzie w 1.0), <a href="http://trac.agavi.org/browser/tags/0.11.0RC3/src/request/AgaviWebRequest.class.php">WebRequest</a> oraz <a href="http://trac.agavi.org/browser/tags/0.11.0RC3/src/request/AgaviSecureWebRequest.class.php">SecureWebRequest</a>.<br />
W międzyczasie pożegnaliśmy również stałe View::SUCCESS, ERROR, INPUT, ALERT, a metoda <a href="http://trac.agavi.org/browser/tags/0.11.0RC3/samples/app/modules/Default/actions/IndexAction.class.php#L69">getDefaultViewName</a> każdej akcji zwraca po prostu suffix do nazwy widoku (np. metoda akcji "Cart" zwraca wartość "Product", stąd klasa widoku to CartProductView).<br />
Co więcej w połączeniu z innym mechanizmem <a href="http://blog.dywicki.pl/2007/02/22/agavi-output-types/">Agavi, Output types</a>, zmiany formatu widoku oraz języka nie wiążą się z implementacją bądź powielaniem logiki biznesowej. Implementujemy tylko logikę związaną z widokiem.<br />
Warto również wspomnieć, że od tej chwili <strong>metoda Controller::forward(module, action) jak i samo używanie powiązanych akcji jest odradzane</strong>, jako źródło potencjalnych problemów (dlaczego widok nie jest uruchamiany) tym bardziej, że tworzenie widoków i akcji załatwia samo Agavi przez taski dla <a href="http://phing.info">Phinga</a>. W chwili, gdy chcemy użyć innego widoku, spoza tych, które dostarcza sama akca po prostu zwracamy array(module, view name, parameters). Zniknęła również możliwości zrobienia forwarda z widoku (ogólnie problemy z request methods, to co było post-only nie szło przy fowardzie przy żądaniu otrzymanym via get), co wydaje się jak najbardziej uzasadnione.<br />
Widok nie jest organem decyzyjnym, który powinien wskazywać na wykonanie logiki biznesowej. Nie mniej jest możliwość przekierowania do widoku innej akcji.. poprzez redirect bądź poprzez zwrócenie array(module, view name, parameters).</p>
<p>To co jest bolesne w execution flow oferowanym w Agavi to niestety jego prostota. Przede wszystkim brakuje mi (jak w wielu miejscach Agavi) interfejsów. Jest to dla mnie naturalne, że dążę do generalizacji, interfejs jest podstawowym elementem, który uniezależnia od implementacji. Interesuje nas to, co jest widoczne na zewnątrz a nie to co wewnątrz implementacji. Brakuje mi opakowań dla tych tablic, które informacje o widoku. Prosty kontener, bean, który zawiera tylko informacje, ale nie jest tablicą. Przede wszystkim mam możliwość kontroli danych, które otrzymuje. Mogę już w fazie tworzenia obiektu reprezentującego flow wstępnie przeprowadzić jego walidację (czy widok istnieje?).<br />
Zmiany w akcjach i widokach jest jak najbardziej pozytywna i rzeczywiście usprawnia działanie całości. Nie mniej <a href="http://trac.agavi.org/milestone/2.0">do wersji 2.0 </a> w Agavi na pewno zajdzie ich jeszcze sporo, miejmy nadzieję, że również w celu uporządkowania struktur, usunięcia nadmiaru klas abstrakcyjnych i zastąpienia ich interfejsami (pamiętaj, zanim napiszesz linijkę w klasie, która jest autonomiczna, a której implementacja może się zmieniać, generalizuj, twórz typ bazowy).</p>
<p>Pytaniem ciągle jest czy Agavi podąży w stronę Symfony? Jak najmniej pisania.. <a href="http://www.symfony-project.com/weblog/2007/02/19/symfony-1-0-released.html">Twórcy Symfony</a> ochrzcili wersję 1.0 swojego frameworka nazwą, czy też przydomkiem "enterprise". Ciężko mi powiedzieć czy było to uzasadnione. Temat Symfony-Agavi często pojawia się w rozmowach między <a href="http://michalmech.pl">Michałem Mechem</a> a mną. Obaj jesteśmy zgodni w dwóch kwestiach - w Symfony pisze się bardzo szybko oraz ma ono bardzo dobrą dokumentację. Nie ustępuje ona pod żadnym względem dokumentacji <a href="http://framework.zend.com">Zend Frameworka</a>.</p>
<p>Myślę, że najlepszym życzeniem dla nas wszystkich będzie to: <strong>by developerzy Agavi nadążyli z dokumentacją za implementacją</strong>.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.dywicki.pl/2007/02/24/agavi-011-rc3-flow/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Agavi, Output types</title>
		<link>http://blog.dywicki.pl/2007/02/22/agavi-output-types/</link>
		<comments>http://blog.dywicki.pl/2007/02/22/agavi-output-types/#comments</comments>
		<pubDate>Thu, 22 Feb 2007 20:41:37 +0000</pubDate>
		<dc:creator>Łukasz Dywicki</dc:creator>
				<category><![CDATA[Agavi]]></category>
		<category><![CDATA[Framework]]></category>
		<category><![CDATA[MVC]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://blog.dywicki.pl/2007/02/22/agavi-output-types/</guid>
		<description><![CDATA[Jedną z nowości jaką niesie Agavi w wersji &#62; 0.10 jest mechanizm output types. Jest to bardzo proste rozwiązanie, które umożliwia uniknięcie gimnastyki z tworzeniem widoków w różnych technologiach, z którymi wiąże się różna logika. Banalny przykład. Te same dane prezentujemy w postaci HTML jak i PDF a do tego możemy je pobierać przez XmlHttpRequest. [...]]]></description>
			<content:encoded><![CDATA[<p>Jedną z nowości jaką niesie Agavi w wersji &gt; 0.10 jest mechanizm output types. Jest to bardzo proste rozwiązanie, które umożliwia uniknięcie gimnastyki z tworzeniem widoków w różnych technologiach, z którymi wiąże się różna logika. Banalny przykład. Te same dane prezentujemy w postaci <acronym title="HyperText Markup Language">HTML</acronym> jak i <acronym title="Portable Document Format">PDF</acronym> a do tego możemy je pobierać przez XmlHttpRequest. Dane są praktycznie identyczne, różny jest format wynikowy i proces jego tworzenia. Dla zwykłej strony wskazujemy szablon, dorzucamy dane i koniec, dla XmlHttp zwracamy JSONa. Stworzenie outputu w formacie <acronym title="Portable Document Format">PDF</acronym> nie będzie tak proste jak pozostałych, ponieważ konieczne będzie stworzenie układu strony, dorzucenie fontów etc. Ogólnie w żaden sposób nie da się połączyć tych formatów w jednym widoku bez sporej ilości warunków i "protez". By uniknąć zakopania się w tym wszystkim zwykle tworzy się dodatkową akcję, która w sporej części pokrywała się z pierwotną a różni się tylko widokiem i szablonami. Począwszy od Agavi 0.11 problem przestaje istnieć.</p>
<p>W pliku konfiguracyjnym <a href="http://trac.agavi.org/browser/trunk/samples/app/config/output_types.xml">output_types.xml</a> określamy <a href="http://trac.agavi.org/browser/trunk/src/config/xsd/output_types.xsd#L31">renderer</a> dla danej technologii, dodajemy obiekty przedefiniowane (parameters name="assigns") i następnie konfigurujemy mapowania adresów do plików (swoją drogą najlepsza implementacja tego mechanizmu z jaką się do tej pory spotkałem). Jest <a href="http://trac.agavi.org/browser/trunk/samples/app/config/routing.xml">odpowiedni plik</a> zawierający <a href="http://trac.agavi.org/browser/trunk/src/config/xsd/routing.xsd">definicję routingu</a>.</p>
<p>Zajmijmy się jednak w pierwszej kolejności konfiguracją output types:</p>
<div class="igBar"><span id="lxml-15"><a href="#" onclick="javascript:showPlainTxt('xml-15'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">XML:</span>
<div id="xml-15">
<div class="xml">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;</span>?xml <span style="color: #000066;">version</span>=<span style="color: #ff0000;">"1.0"</span> <span style="color: #000066;">encoding</span>=<span style="color: #ff0000;">"UTF-8"</span>?<span style="font-weight: bold; color: black;">&gt;</span></span></div>
</li>
<li style="font-weight: normal;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;output_type</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">"html"</span><span style="font-weight: bold; color: black;">&gt;</span></span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;renderer</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">"AgaviPhpRenderer"</span> <span style="color: #000066;">extension</span>=<span style="color: #ff0000;">"tpl.php"</span><span style="font-weight: bold; color: black;">&gt;</span></span></div>
</li>
<li style="font-weight: normal;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;parameters<span style="font-weight: bold; color: black;">&gt;</span></span></span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;parameter</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">"assigns"</span><span style="font-weight: bold; color: black;">&gt;</span></span></div>
</li>
<li style="font-weight: normal;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;parameters<span style="font-weight: bold; color: black;">&gt;</span></span></span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;parameter</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">"routing"</span><span style="font-weight: bold; color: black;">&gt;</span></span>r<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/parameter<span style="font-weight: bold; color: black;">&gt;</span></span></span></div>
</li>
<li style="font-weight: normal;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;parameter</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">"request"</span><span style="font-weight: bold; color: black;">&gt;</span></span>req<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/parameter<span style="font-weight: bold; color: black;">&gt;</span></span></span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;parameter</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">"controller"</span><span style="font-weight: bold; color: black;">&gt;</span></span>ctl<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/parameter<span style="font-weight: bold; color: black;">&gt;</span></span></span></div>
</li>
<li style="font-weight: normal;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;parameter</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">"user"</span><span style="font-weight: bold; color: black;">&gt;</span></span>usr</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/parameter<span style="font-weight: bold; color: black;">&gt;</span></span></span></div>
</li>
<li style="font-weight: normal;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;parameter</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">"translation_manager"</span><span style="font-weight: bold; color: black;">&gt;</span></span>tm<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/parameter<span style="font-weight: bold; color: black;">&gt;</span></span></span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/parameters<span style="font-weight: bold; color: black;">&gt;</span></span></span></div>
</li>
<li style="font-weight: normal;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/parameter<span style="font-weight: bold; color: black;">&gt;</span></span></span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;parameter</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">"i18n"</span><span style="font-weight: bold; color: black;">&gt;</span></span></div>
</li>
<li style="font-weight: normal;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;parameters<span style="font-weight: bold; color: black;">&gt;</span></span></span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;parameter</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">"mode"</span><span style="font-weight: bold; color: black;">&gt;</span></span>subdir<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/parameter<span style="font-weight: bold; color: black;">&gt;</span></span></span></div>
</li>
<li style="font-weight: normal;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/parameters<span style="font-weight: bold; color: black;">&gt;</span></span></span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/parameter<span style="font-weight: bold; color: black;">&gt;</span></span></span></div>
</li>
<li style="font-weight: normal;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/parameters<span style="font-weight: bold; color: black;">&gt;</span></span></span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/renderer<span style="font-weight: bold; color: black;">&gt;</span></span></span></div>
</li>
<li style="font-weight: normal;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;parameters<span style="font-weight: bold; color: black;">&gt;</span></span></span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;parameter</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">"Content-Type"</span><span style="font-weight: bold; color: black;">&gt;</span></span></div>
</li>
<li style="font-weight: normal;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; text/html; charset=UTF-8</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/parameter<span style="font-weight: bold; color: black;">&gt;</span></span></span></div>
</li>
<li style="font-weight: normal;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/parameters<span style="font-weight: bold; color: black;">&gt;</span></span></span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/output_type<span style="font-weight: bold; color: black;">&gt;</span></span></span></div>
</li>
<li style="font-weight: normal;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;output_type</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">"json"</span><span style="font-weight: bold; color: black;">&gt;</span></span></div>
</li>
<li style="font-weight: normal;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;renderer</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">"AgaviPhpRenderer"</span> <span style="color: #000066;">extension</span>=<span style="color: #ff0000;">"js.php"</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; ignore_<span style="color: #000066;">slots</span>=<span style="color: #ff0000;">"true"</span> ignore_<span style="color: #000066;">decorators</span>=<span style="color: #ff0000;">"true"</span><span style="font-weight: bold; color: black;">&gt;</span></span></div>
</li>
<li style="font-weight: normal;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;parameters<span style="font-weight: bold; color: black;">&gt;</span></span></span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;parameter</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">"Content-Type"</span><span style="font-weight: bold; color: black;">&gt;</span></span></div>
</li>
<li style="font-weight: normal;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; text/javascript; charset=UTF-8</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/parameter<span style="font-weight: bold; color: black;">&gt;</span></span></span></div>
</li>
<li style="font-weight: normal;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/parameters<span style="font-weight: bold; color: black;">&gt;</span></span></span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/renderer<span style="font-weight: bold; color: black;">&gt;</span></span></span></div>
</li>
<li style="font-weight: normal;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/output_type<span style="font-weight: bold; color: black;">&gt;</span></span></span> </div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<p>Jak widać trochę tej konfiguracji jest, nie mniej celowo usunąłem przekazywanie parametrów do drugiego formatu wynikowego by pokazać, że w najskromniejszej wersji definicja taka potrafi się zmieścić maksymalnie w 10 linijkach.<br />
Do wszystkich parametrów możemy odwoływać się w widoku. Specyficzne są parametry o nazwie assigns oraz i18n. Pierwszy z nich Agavi wykorzysta po to by od razu w fazie tworzenia renderera wrzucić do niego wskazane obiekty, które znajdują się w kontekście. Drugi z atrybutów jest szczególnie przydatny podczas tworzenia aplikacji z wieloma językami. Parametr i18n jest prefiksem dla nazwy pliku. W przypadku gdy przypiszemy mu wartość subdir framework będzie szukał szablonów po katalogach np. <strong>pl/IndexSuccess</strong>, <strong>en/IndexSuccess</strong>. Inne, dopuszczalne wartości to postfix oraz prefix. Nazwy szablonów to odpowiednio <strong>IndexSuccess_pl</strong> oraz <strong>pl_IndexSuccess</strong><br />
Atrybut extension określa suffix dla nazwy pliku, którego użyje Agavi przy wczytywaniu szablonu np <strong>IndexSuccess.tpl.php</strong>.<br />
Argumenty ignore_slots oraz ignore_decorators odnoszą się do strategii budowania widoku. W chwili gdy zrezygnujemy z nich wynik nie będzie dekorowany. Tzn. w odpowiedzi użytkownik zobaczy tylko treść wygenerowaną przez widok akcji.<br />
<b>Tutaj drobna uwaga. W wersji stabilnej Agavi 0.11 mechanizm ten zachowuje się nieco inaczej. Wybór plików oraz zachowanie dekoratora determinuje layout i elementy layer.</b></p>
<p>Następnie w routes.xml dla każdej ścieżki możemy określić również format wynikowy danych. Np:</p>
<div class="igBar"><span id="lxml-16"><a href="#" onclick="javascript:showPlainTxt('xml-16'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">XML:</span>
<div id="xml-16">
<div class="xml">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;route</span> <span style="color: #000066;">pattern</span>=<span style="color: #ff0000;">"/ajax$"</span> output_<span style="color: #000066;">type</span>=<span style="color: #ff0000;">"json"</span> <span style="color: #000066;">stop</span>=<span style="color: #ff0000;">"false"</span> <span style="font-weight: bold; color: black;">/&gt;</span></span> </div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<p>W tym momencie, wszystkie adresy kończące się na <strong>/ajax</strong> będą obsługiwane w nieco inny sposób niż pozostałe. To znaczy, że nie będzie dekorowany output. Dodatkowo zostaną użyte inne pliki szablonów do generowania treści.</p>
<p>Zdaję sobie sprawę z tego, że opisałem ten mechanizm dość chaotycznie i bardziej skupiłem się na jego konfiguracji, ale na przykładową aplikację będziecie musieli poczekać do czasu gdy skończę artykuł dla <acronym title="Pre-Hypertext Processing">PHP</acronym> Solutions (czyżby Agavi tematem numeru?) bądź do pojawienia się nowego Code-House. :)</p>]]></content:encoded>
			<wfw:commentRss>http://blog.dywicki.pl/2007/02/22/agavi-output-types/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Propel 1.2 a istniejąca baza danych</title>
		<link>http://blog.dywicki.pl/2007/02/11/propel-12-a-istniejaca-baza-danych/</link>
		<comments>http://blog.dywicki.pl/2007/02/11/propel-12-a-istniejaca-baza-danych/#comments</comments>
		<pubDate>Sun, 11 Feb 2007 19:41:36 +0000</pubDate>
		<dc:creator>Łukasz Dywicki</dc:creator>
				<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://blog.dywicki.pl/2007/02/11/propel-12-a-istniejaca-baza-danych/</guid>
		<description><![CDATA[Wiele razy spotykałem się z negatywnymi opiniami na temat Propela. Przyznaję, nie jest to narzędzie doskonałe, ale bez wątpienia, w tej chwili jest to wiodący ORM dla PHP.
Jedną z wad Propela, która pojawia się chyba najczęściej jest XML i definiowanie tabel w pliku XML. Otóż drodzy moi, nie jest to konieczność. Schemat z istniejącej bazy [...]]]></description>
			<content:encoded><![CDATA[<p>Wiele razy spotykałem się z negatywnymi opiniami na temat Propela. Przyznaję, nie jest to narzędzie doskonałe, ale bez wątpienia, w tej chwili jest to wiodący ORM dla <acronym title="Pre-Hypertext Processing">PHP</acronym>.</p>
<p>Jedną z wad Propela, która pojawia się chyba najczęściej jest <acronym title="eXtensible Markup Language">XML</acronym> i definiowanie tabel w pliku <acronym title="eXtensible Markup Language">XML</acronym>. Otóż drodzy moi, nie jest to konieczność. Schemat z istniejącej bazy danych można bez problemu przenieść do XMLa a następnie bez najmniejszego problemu wygenerować z niego klasy. Możemy zrobić to dwoma poleceniami. Pierwsze jest dostępne po instalacji przy pomocy PEARa, drugie przy korzystaniu z Phinga:</p>
<div class="igBar"><span id="lcode-19"><a href="#" onclick="javascript:showPlainTxt('code-19'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">CODE:</span>
<div id="code-19">
<div class="code">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#FF9933; font-style:italic;">// propel-gen project target</span></div>
</li>
<li style="font-weight: normal;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">propel-gen sheep creole</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">propel-gen sheep om</div>
</li>
<li style="font-weight: normal;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#FF9933; font-style:italic;">// bądź phing -Dproject=project -Dtarget=target</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">phing -Dproject=sheep -Dtarget=creole</div>
</li>
<li style="font-weight: normal;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">phing -Dproject=sheep -Dtarget=om </div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<p>Naszym oczom ukaże się kilka informacji o przebiegu całego procesu, po czym będziemy mogli korzystać z wygenerowanych klas. :)</p>
<p><strong>Propel 1.3</strong><br />
Propel 1.3 korzysta z PDO dlatego też, task "creole" niestety nie działa. Jeśli ktoś chce korzystać z możliwości generowania schematu musi niestety korzystać na przemian z wersji 1.2 i 1.3 (1.2 generuje schemat, 1.3 generuje klasy).</p>
<p><strong>Migrowanie pomiędzy bazami danych</strong><br />
Propel umożliwia zrzucenie struktury bazy danych do pliku zawierającego definicje tabel. Aby to zrobić wystarczy skorzystać z taska <em>sql</em>. Warto pamiętać, że schemat <acronym title="Structured Query Language">SQL</acronym> jest budowany na podstawie pliku <acronym title="eXtensible Markup Language">XML</acronym>. Zmieniając jedną dyrektywę w konfiguracji generatora (propel.database.url) można bez problemu przenieść całą bazę</p>
<p><strong>Przenoszenie danych</strong><br />
Istnieje również możliwość przeniesienia danych z istniejącej bazy, służy do tego task datadump. Propel zrzuca zawartość wszystkich tabeli do plików <acronym title="eXtensible Markup Language">XML</acronym> po to by móc następnie wygenerować z niego zapytania insert. Aby to zrobić wystarczą dwa polecenia:</p>
<div class="igBar"><span id="lcode-20"><a href="#" onclick="javascript:showPlainTxt('code-20'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">CODE:</span>
<div id="code-20">
<div class="code">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">propel-gen sheep datadump</div>
</li>
<li style="font-weight: normal;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">propel-gen sheep datasql </div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<p><strong>Propel a ociężałość</strong><br />
Trudno się nie zgodzić, że używanie narzędzi typu ORM powoduje wydłużenie czasu wykonywania skryptu, ale jak by nie patrzeć, znacznie też skraca czas potrzebny na tworzenie kodu odpowiedzialnego za warstwę DAO, co zwykle tuż po tworzeniu widoku zajmuje najwięcej czasu.<br />
Myślę, że warto tu wspomnieć o Propelu 2.0, który ma obsługiwać dostęp do pól przez metody __get i __set dzięki czemu całość może stać się lżejsza a ilość kodu, który jest generowanego ulegnie widocznemu zmniejszeniu.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.dywicki.pl/2007/02/11/propel-12-a-istniejaca-baza-danych/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>
