Niezalogowany [ logowanie ]
Subskrybuj kanał ATOM Kanał ATOM

Autor wpisu: batman, dodany: 31.05.2010 18:00, tagi: sql

Zdarza się czasami, że musimy posortować dane inaczej niż zgodnie z kolejnością alfabetyczną. Załóżmy taką sytuację. Mamy tabelę zawierającą statusy produktów. Tak się zdarzyło, że zostały one zapisane w postaci tekstowej. Poniżej schemat tabeli

CREATE TABLE produkty
(
  id serial NOT NULL,
  nazwa character varying(500),
  status character varying(50)
)
WITH (
  OIDS=TRUE
);

oraz przykładowe dane

INSERT INTO produkty (id, nazwa, status) VALUES (1, 'produkt 1', 'magazyn 1');
INSERT INTO produkty (id, nazwa, status) VALUES (2, 'inny produkt', 'magazyn 2');
INSERT INTO produkty (id, nazwa, status) VALUES (3, 'super produkt', 'brak');
INSERT INTO produkty (id, nazwa, status) VALUES (4, 'produkt 2', 'magazyn 1');
INSERT INTO produkty (id, nazwa, status) VALUES (5, 'inny super produkt', 'dostawa');
INSERT INTO produkty (id, nazwa, status) VALUES (6, 'produkt 3', 'magazyn 2');

Jeśli chcielibyśmy posortować te dane w taki sposób, że najpierw wyświetlają się produkty znajdujące się w dowolnym magazynie, następnie produkty, których nie ma na składzie, a na końcu wszystkie, które są w dostawie, mielibyśmy spory problem. Na szczęście w postgresie jest takie coś jak wyrażenie warunkowe CASE, które idealnie nada się  do naszego problemu. Wprawdzie zapytanie się nieco rozrośnie, zwłaszcza jeśli mamy dużo warunków do sprawdzenia, ale pożądany efekt zostanie uzyskany bez konieczności zaprzęgania do pracy dodatkowego języka.

select 
	* 
from 
	produkty
order by 
	case
		when status = 'magazyn 1' then 1
		when status = 'magazyn 2' then 2
		when status = 'brak' then 3
		when status = 'dostawa' then 4
		else 5
	end

Powyższy sposób sprawdzi się również w przypadku sortowania danych numerycznych. Uzyskanie kolejności 6, 2, 3, pozostałe liczby malejąco,  jest równie prosty. Dla powyższych danych będzie to wyglądało następująco

select 
	* 
from 
	produkty
order by 
	case
		when id = 6 then 1
		when id = 2 then 2
		when id = 3 then 3
		else 4
	end
	, id desc

W ten oto prosty sposób, uzyskaliśmy niestandardowe sortowanie naszych danych.

Autor wpisu: Damian Rusinek, Piotr Wierzgała, dodany: 31.05.2010 16:18, tagi: css

Dzisiaj spotkałem się z problemem podczas wstawiania do aplikacji własnej embeed’owanej czcionki. Robi się to w CSSie w ten sposób:

@font-face {
src: url("../fonts/moja-czcionka.ttf");
fontFamily: MyFont;
}

Następnie w prosty sposób można ustawić czcionke dla np. Aplikacji:

Application {
fontFamily: MyFont;
}

Do tej pory wszystko działa bez zarzutu. Jednak, gdy ustawiałem czcionke dla przycisku:

Button {
fontFamily: MyFont;
}

no to coś nie grało, bo czcionka nie pojawiała się. Była to zwykła polska czcionka:

  • styl – normalny
  • grubość – normalna

Okazało się, że problemem był fakt, że Flex jako domyślną grubość czcionki dla przycisków ustawia bold, a moja czcionka była normalnej grubości. Stąd, po dodaniu jednej linijki do stylu przycisku:

Button {
fontFamily: MyFont;
fontWeight: normal;
}

wszystko działało. Trochę mnie zdenerwowała taka błahostka, bo spędziłem nad nią trochę czasu, dlatego mam nadzieje, że ten wpis go komuś zaoszczędzi.

Autor wpisu: Damian Rusinek, Piotr Wierzgała, dodany: 31.05.2010 14:05, tagi: symfony

Szeroki wybór możliwości połączenia PHP i Flexa możemy uważać za coś pozytywnego, ponieważ każdy może sobie odnaleźć swój sposób integracji server-side z client-side. Jednakże na długą metę okazuje się to zmorą, bo człowiek (przynajmniej ja tak mam) zaczyna się zastanawiać, czy to drugie rozwiązanie nie jest lepsze.

Dlatego postanowiłem znaleźć jakiś sposób integracji, który będzie szybki i dobry :). Przeglądając różne stronki o Flexie, odnalazłem prezentację (niestety nie pamiętam adresu), na której ładnie przedstawiony był fakt, że AMF to idealny protokół komunikacji z Flexem. Nic dziwnego, w końcu to twór Adobe.

Ok, protokół mamy. Teraz wypada wybrać implementację. Jako, że jestem użytkownikiem frameworka Symfony, to właśnie z nim chciałbym zintegrować Flexa.

Wiem, że istnieje plugin do symfony sfAmfPlugin (strona głowna). Nie będe się o nim rozpisywał. Jak ktoś jest ciekawy, to niech śmiga na jego stronę główną. Powiem tylko, że jest on oparty na bibliotece SabreAMF, której szczerze mówiąc nie znam. Wiem natomiast, że biblioteka Zend’a jest dobra do wsyztskiego :), dlatego właśnie z niej korzystam.

Poniżej przedstawiam opis jak zrobić szybko HelloWorld we Flexie, z wykorzystaniem Symfony i AMF oraz bibliotek Zenda. We wszystkich HelloWorld’ach w necie brakowało mi tego połączenia.

Zaczynamy

Na początku trzeba postawić zwykły projekt Symfony i dodać jakąś aplikację – ja dodałem aplikacje o nazwie frontend. Zakładam, że ludzie czytający wpis o symfony wiedzą jak to zrobić :)

Następnie należy zintegrować odpowiednie biblioteki Zenda. Integracja została opisana we wpisie Integracja Symfony + Zend.

Oto lista plików jakie należy umieścić w katalogu /lib/vendor/Zend:

Czytaj dalej tutaj (rozwija treść wpisu)
Czytaj dalej na blogu autora...

Autor wpisu: batman, dodany: 30.05.2010 17:00, tagi: php

Najpopularniejszym pakietem biurowym na świecie jest Microsoft Office. Od dobrych kilku lat, programy takie jak Word, Excel, czy PowerPoint, zapisują dokumenty w formacie Office Open XML. Jak sama nazwa wskazuje, jest to format bazujący na XML, a co za tym idzie, możliwy do odczytania w PHP.

Struktura dokumentu

Dokument Office Open XML jest niczym innym jak archiwum zip, które zawiera określoną strukturę katalogów i plików. Pliki zapisane są w formacie XML. Tak wygląda zawartość archiwum dla pliku docx.

docx-as-zip

Jak widać, struktura katalogów jest bardzo prosta. Przeznaczeniem tych katalogów jest:

  • docProps – znajdują się w nim dwa dokumenty core.xml oraz app.xml, które opisują podstawowe właściwości dokumentu
  • word – katalog znajdujący się tylko w plikach docx. Inne dokumenty Office będą zawierały katalog xl w przypadku plików Excel lub ppt w przypadku plików PowerPoint. Katalog ten zawiera kilka plików XML oraz dodatkowe podfoldery, jednak jedynym interesującym nas elementem jest plik document.xml. Jeśli w dokumencie będą osadzone jakieś obrazki, to warto zainteresować się katalogiem media, w którym są one umiejscowione.
  • _rels – zawiera plik opisujący relację między plikami w archiwum a ich przeznaczeniem
  • [Content_Types].xml – jak sama nazwa wskazuje jest to plik określający typy plików znajdujących się w archiwum

PHP i archiwa ZIP

Od wersji 5.2 PHP zawiera klasę ZipArchive, która oferuje szereg możliwości, między innymi przeglądanie zawartości archiwum. Klasa ta idealnie nadaje się do rozpoczęcia pracy z dokumentami Open XML.

$zip = new ZipArchive();
$res = $zip->open('./Dokument testowy.docx');

if($res === true) {
	// operacje na pliku
}
else {
	// obsługa błedu
	echo 'Error: ' . $res;
}

Jedyne co pozostało to przeparsować dokument XML w celu pobrania treści. Do dyspozycji mamy kilka sposobów. Jeśli plik docx zawiera jedynie niesformatowany tekst, bez żadnych obrazków, tabel i innych elementów, wystarczy że pobierzemy treść pliku document.xml, znajdującego się w katalogu word i potraktujemy go funkcją strip_tags.

$document = $zip->getFromName('word/document.xml');
echo strip_tags($document);

Jeśli jednak potrzebujemy zachować formatowanie dokumentu, trzeba nieco się wysilić. W przypadku niewielkich dokumentów warto skorzystać z SimpleXML, które idealnie się nada. Duże dokumenty będą wymagały zaprzęgnięcia klasy XMLReader.

Parsowanie dokumentu

Czytaj dalej tutaj (rozwija treść wpisu)
Czytaj dalej na blogu autora...

Autor wpisu: sokzzuka, dodany: 29.05.2010 00:12, tagi: php

Pewnie wielu z was zastanawia się, jaka będzie przyszłość języka PHP. Co będzie w nowych wersjach, a czego nie będzie i dlaczego. Dlatego powiem kilka słów o tym jak wygląda ewolucja języka.

Proces decyzyjny.

Typowo proces decyzyjny wygląda tak: ktoś wymyśla feature, tworzy nową propozycję rfc. Następnie zapisuje się na listę mailingową internals tam obwieszcza, że stworzył propozycje i zaprasza do dyskusji.

Następnie osoby zapisane do listy, które to są core developerami PHP dyskutują na temat propozycji. Zwykle pojawia się wiele opinii za i przeciw oraz prośby na uściślenie propozycji. Losy propozycji zależą od tego czy po pierwsze ma sens, jeżeli nie ma, to już na początku osoba proponująca jest pozbawiana złudzeń, że to nie przejdzie.

Jeżeli propozycja ma sens i jest czymś co większość może zaakceptować, to osoba proponująca proszona jest o napisanie prototypowej implementacji i udostępnienie jej jako svn-patch do trunka, do testów. Ostateczną decyzje czy uwzględnić nowy feature podejmuje release manager wydania.

Generalnie proces wprowadzenia nowych funkcjonalności do języka jest procesem demokratycznym, jednak trzeba być dobrym “mówcą” i mieć naprawdę mocne argumenty, żeby wprowadzić coś nowego. Z tego co zauważyłem czytając listę internals, prawie nigdy nie przechodzą featury, które zrywają wsteczną kompatybilność.

Interesujące propozycje.

Z kilkunastu propozycji rfc wybrałem do opisu kilka, które wg. mnie zasługują na szczególną uwagę i zmieniają jakość obcowania z językiem.

1.Błędy jako wyjątki

Proponuje zamianę prawie wszystkich błędów ( oprócz parse i compile errors ) na wyjątki. Czyli defakto ukonstytuowuje to co wiele osób robi ustawiając swój error handler, który wyrzuca exception.

2.Typowanie zmiennych skalarnych

Czytaj dalej tutaj (rozwija treść wpisu)
Czytaj dalej na blogu autora...

Autor wpisu: batman, dodany: 25.05.2010 21:42, tagi: internet, jquery

Dzisiaj (25.05.2010) w Poznaniu miała miejsce pierwsza edycja konferencji SparkUp 2010, gromadząca międzynarodowej klasy ekspertów z dziedziny tworzenia i projektowania aplikacji internetowych. Konferencja była podzielona na dwie ścieżki: UX/Web Design oraz Web Development. Z racji wykonywanego zawodu oraz zainteresowań, wybrałem drugą ścieżkę.

Microsoft Surface

Zanim rozpoczęła się konferencja, miałem okazję zapoznać się z Microsoft Surface. Jest to komputer z dotykowym interfejsem, pozwalający na interakcję z treściami cyfrowymi w intuicyjny dla człowieka sposób. Prezentowany model pracował pod kontrolą systemu operacyjnego Windows Vista i miał “pod maską” 2GHz procesor, 2GB pamięci RAM oraz kartę graficzną z 256MB pamięci. 30 calowy ekran wyświetlał obraz o rozdzielczości 1024 x 768. Mimo dosyć przeciętnych parametrów, Surface doskonale spełnił swoje zadanie. Aplikacje, które testowałem działały bez zarzutu. Wszystko reagowało na dotyk bez widocznego opóźnienia, a ładowanie aplikacji przebiegało stosunkowo szybko. Jeśli chcecie poznać więcej szczegółów na temat tego produktu, polecam odwiedzić oficjalną witrynę Microsoft Surface.

Web Development 2.o

Pierwszym wykładem, w  którym uczestniczyłem był Web Development 2.0, poprowadzony przez Bruce Lawson’a. Pracuje on w firmie Opera jako web evangelist.

Podczas wykładu przedstawiono możliwości jakie daje najnowsza wersja HTML oznaczona numerem 5. Spośród wszystkich zaprezentowanych nowości, największe wrażenie wywarło na mnie nowe podejście do formularzy, które jakimś cudem umknęło mojej uwadze. HTML5 wprowadza nowe elementy formularza, np kalendarz, czy suwak oraz umożliwia walidację elementów formularza bez konieczności korzystania z języka Javascript. Oprócz formularzy, zaprezentowane zostały  w skrócie nowe możliwości CSS3, sposób działania nowgo taga video oraz jak można stworzyć aplikację działającą na wszystkich możliwych urządzeniach bez dodatkowego nakładu pracy.

Co mi się podobało w tym wykładzie, to sposób w jaki HTML5 został zaprezentowany. Nie był on rysowany jako lekarstwo na całe zło, lecz jako uzupełnienie braków w obecnej wersji tego języka, z których – jeśli nie ma takiej potrzeby – nie trzeba korzystać.

jQuery: Write Less, Do More

Kolejny wykład poświęcony był jQuery, poprowadzony przez Remy Sharp’a. Podczas wykładu zaprezentowana została najnowsza wersja biblioteki, oznaczona numerem 1.4.2. jQuery znam dobrze, więc prezentowane informacje nie były dla mnie nowe, niemniej jednak, ciekawy sposób ich przedstawienia (7 śmiertelnych grzechów), otworzył mi oczy na niektóre aspekty tej biblioteki.

RIA i Silverlight 4

Czytaj dalej tutaj (rozwija treść wpisu)
Czytaj dalej na blogu autora...

Autor wpisu: sokzzuka, dodany: 24.05.2010 23:51, tagi: php

Dzisiejszy post będzie o moim własnonożnie zrobionym kontenerze IOC (inversion of control). Najpierw kilka słów, czym jest wzorzec IOC.

W wielkim uproszczeniu wzorzec IOC polega na przeniesieniu poza obiekt wszelkich funkcjonalności nie związanych bezpośrednio z jego przeznaczeniem. Celem jest:

  • zdefiniowanie jasnych odpowiedzialności poszczególnych klas
  • stworzeniem abstrakcji dzięki której zmiana jednego elementu systemu nie będzie wpływała na inne
  • uniezależnienie się od implementacji poszczególnych części systemu

Tyle do IOC, natomiast kontener IOC jest specjalną klasą, która na nasz zlecenie konstruuje za nas obiekty, których potrzebujemy dbając o wszelkie zależności między nimi.

Realizacja wygląda w ten sposób, że deklaratywnie określamy jakie są zależności między obiektami i na podstawie naszego opisu całą techniczną stroną tworzenia obiektów zajmuje się kontener IOC.

Kontener wraz z przykładem użycia można ściągnąć z tąd (licencja BSD).

Mój kontener IOC składa się z dwóch podstawowych częsci:

  • fabryka obiektów
  • adaptery dla różnych formatów określania zależności między obiektami

Fabryka obiektów tworzy i zarządza obiektami biorąc pod uwagę czas ich istnienia. Zarządza obiektami, których stan trzymany jest przez całą sesję użytkownika jak i może ich stan być trzymany nieskończenie długo i dostępny między sesjami użytkowników ( do tego potrzebny jest mechanizm cache typu APC lub XCache z odpowiednim adapterem).

Co do adapterów to na dziś dzień stworzony jest jeden adapter, który czyta XML-e. Pokrótce o tym jak opisywać obiekty w tymże XML-u.

<object-config>
    <application>
        <!-- For now empty, objects declared here will be cached by APC or something similiar -->
    </application>
    <session>
        <object class="FooFoo">
            <property name="someParameter">baz_foo</property>
        </object>
    </session>
    <request>      
        <object class="Foo1">
            <property name="param2">other_baz</property>
            <property name="param1">baz</property>
        </object>
 
        <object class="Foo2">
            <property name="param2">baz_faz</property>
            <property name="param1">baz_baz</property>
        </object>
 
        <object class-match="/Foo[0-9]+/">
            <property name="param3" type="class">@self</property>
        </object>
 
        <object class="Bar" id="FooBar">
            <property type="class" name="param1">Foo1</property>
            <property type="const" name="param2">FooConst</property>
            <property type="id" name="param3">Foo2</property>
            <proxy class="FooProxy"/>
        </object>
 
    </request>    
</object-config>

Jak widać albo i nie ;) . Stopień niżej od roota są trzy tagi – “application”, “session”, “request”, które grupują w sobie tagi object. Te trzy tagi określają czy stan obiektu będzie trwał dla sesji czy dla pojedynczego requestu czy wiecznie dla całej aplikacji.

Tagi object określają konfigurację poszczególnych obiektów. Kolejne właściwości obiektu ustawiamy za pomocą tagów “property”. Obowiązkowym atrybutem tagu “property” jest “name”, mówi on o nazwie parametru w konstruktorze lub nazwie settera przez który ma być wstrzyknięta właściwość obiektu. Dzięki temu rozwiązaniu, nie ma znaczenia w jakiej kolejności podamy właściwości, zawsze zostaną one właściwie wstrzyknięte.

Czytaj dalej tutaj (rozwija treść wpisu)
Czytaj dalej na blogu autora...

Wszystkie wpisy należą do ich twórców. PHP.pl nie ponosi odpowiedzialności za treść wpisów.