Niezalogowany [ logowanie ]
Subskrybuj kanał ATOM Kanał ATOM

Autor wpisu: Śpiechu, dodany: 26.08.2010 15:56, tagi: php

Siedzę sobie w domu na urlopie i uskuteczniam to, co lubię najbardziej czyli programuję. Niektórzy lubią wylegiwać się na plaży czekając aż czerniak łaskawie zawita na ich skórę, inni chodzą po zagranicznych targowiskach i pilnują portfela, a ja lubię siedzieć sobie wygodnie przed komputerem cały dzień i dłubać. Dzisiaj przedmiotem mojego dłubania jest implementacja kolejek [...]

Autor wpisu: batman, dodany: 26.08.2010 08:00, tagi: zend_framework

Jednym z najczęstszych problemów związanych z Zend_Form jest brak możliwości dodawania kodu HTML między elementami formularza. Na szczęście Zend_Form jest na tyle rozbudowany, iż przy odrobinie pomysłowości wspomniany problem można dosyć łatwo obejść. Rozwiązań jest co najmniej kilka. Dzisiaj przedstawię dwa najprostsze.

Pierwszym rozwiązaniem jest zastosowanie opisu (description) w elemencie, po którym chcemy dodać kod HTML.

class Application_Form_Example1 extends Zend_Form
{
    public function init()
    {
        $this->setName('form-example1');

        $name = new Zend_Form_Element_Text('name');
        $name->setLabel('Nazwa');

        $email = new Zend_Form_Element_Text('email');
        $email->setLabel('E-mail')
              ->setDescription('<div id="some-id">lorem ippsum</div>');

        $phone = new Zend_Form_Element_Text('phone');
        $phone->setLabel('Telefon');

        $submit = new Zend_Form_Element_Submit('btn_save');
        $submit->setLabel('Zapisz');

        $this->addElement($name);
        $this->addElement($email);
        $this->addElement($phone);
        $this->addElement($submit);
    }
}

Kluczowym elementem powyższego kodu jest metoda setDescription, wywołana na obiekcie $email. Dzięki niej, do kodu formularza zostanie dodany kod HTML. Niestety kod zostanie wyświetlony w takiej formie, w jakiej został dodany – na stronie wyświetli się tekst

<div id="some-id">lorem ippsum</div>

Dzieje się tak dlatego, ponieważ kod HTML jest zamieniany na encje. Rozwiązaniem tego problemu jest ustawienie opcji escape dekoratora Description na false.

$email->addDecorator('Description', array('escape' => false));
Drugi sposób polega na zastosowaniu ukrytego elementu, w którym kod HTML wyświetlany jest w etykiecie.
class Application_Form_Example2 extends Zend_Form
{
    public function init()
    {
        $this->setName('form-example2');

        $name = new Zend_Form_Element_Text('name');
        $name->setLabel('Nazwa');

        $email = new Zend_Form_Element_Text('email');
        $email->setLabel('E-mail');

        $html = new Zend_Form_Element_Hidden('html');
        $html->setLabel('<div id="some-id">lorem ippsum</div>')
             ->setIgnore(true)
             ->addDecorator('Label', array('escape' => false));

        $phone = new Zend_Form_Element_Text('phone');
        $phone->setLabel('Telefon');

        $submit = new Zend_Form_Element_Submit('btn_save');
        $submit->setLabel('Zapisz');

        $this->addElement($name);
        $this->addElement($email);
        $this->addElement($html);
        $this->addElement($phone);
        $this->addElement($submit);
    }
}
Podobnie jak w przypadku opisu, etykieta również wymaga ustawienia opcji escape na false. Oczywistym jest, że podczas wysyłania formularza dodatkowe pole jest zbędne. Dzięki użyciu metody setIgnore, nadmiarowy element nie będzie występował w tablicy wartości przesłanych przez formularz.

Autor wpisu: sokzzuka, dodany: 25.08.2010 16:04, tagi: php

W niedawnym wpisie na liście php.internals, Pierrick Charron poinformował o stworzeniu patch’a dodającego obsługę adnotacji do php. Patch ten jest napisany zgodnie z odpowiednim RFC. Rozszerza on składnie języka, dodaje obsługę do refleksji i dwie nowe klasy ‘ReflectionAnnotation’ i ‘Inherited’ – pierwsza umożliwia tworzenie własnych adnotacji, natomiast druga umożliwia dziedziczenie adnotacji przez klasy dziedziczące z jakiejś klasy.

Jak dla mnie to ciekawy dodatek do języka, natomiast ja chętnie bym również widział jakąś implementacje Pythonowych dekoratorów o których już wcześniej wspominałem. A wy co o tym sądzicie ?

Autor wpisu: m1chu, dodany: 24.08.2010 22:38, tagi: css, javascript

Jak zmusić Internet Explorer 8 do obsługi HTML 5?

Sieć została ogarnięta szałem najnowszej, piątej wersji języka HTML. Jak to zazwyczaj bywa słabo z jej obsługą radzi sobie Internet Explorer. We wszystkich wydanych wersjach pojawia się problem z parsowaniem elementów języka HTML 5, a co za tym idzie nie ma domyślnie możliwości ich poprawnego ostylowania. Podobny problem w przeszłości występował w Firefoksie 2.

Zarys problemu

Załóżmy więc, że tworzymy nowy projekt i jesteśmy na etapie dodawania nagłówka oraz stopki dokumentu.

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>Obsługa HTML 5 z CSS</title>
    <style>
    body { text-align: center; margin: 0; padding: 0; font-family: Tahoma, Verdana, Arial; font-size: 11px; }
    header { font-style: italic; width: 770px; height: 70px; padding: 15px; margin: 5px auto; background-color: #FC0; text-align: left; }
    footer { font-weight: bold; clear: both; width: 770px; height: 15px; padding: 15px; margin: 5px auto; background-color: #FC0; text-align: left; }
    </style>
</head>
<body>
    <header>Nagłówek</header>
    <footer>Stopka</footer>
</body>
</html>

Nadaliśmy powyżej kilka atrybutów stylów pozycjonujących elementy oraz nadających im odpowiedni wygląd. Po przetestowaniu w Internet Explorerze i alternatywnych przeglądarkach zobaczymy jednak różne wyniki.

Wynik w Firefoksie 4Wynik w Firefoksie 4.

Wynik w Internet Explorerze 8Wynik w Internet Explorerze 8.

Internet Explorer – rozwiązanie pierwsze

Aby pozbyć się tego problemu należy do sekcji head wstawić:

<script>
document.createElement('header');
document.createElement('footer');
</script>

Internet Explorer – rozwiązanie drugie

Dla każdej wersji Internet Explorera można także dodać do dokumentu HTML (w sekcję head) zewnętrzny kod JavaScript, dzięki któremu osiągniemy wyżej opisany skutek.

<!--[if IE lt 9]>
  <script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->

Firefox 2

Niespełna jeden procent internautów nadal używa drugiej odsłony popularnego lisa. Zarówno on, jak i wszystkie przeglądarki oparte na silniku Gecko pre 1.9b5 (np. Camino 1.x) posiadają błąd parsowania dzięki któremu w przypadku otwarcia nowego znacznika każdy nieznany, wcześniej otwarty zostanie automatycznie zamknięty.

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

Autor wpisu: batman, dodany: 24.08.2010 08:00, tagi: javascript

W poprzedniej części przewodnika opisałem najważniejsze zagadnienia związane z gadżetami pulpitu dostępnymi w systemach operacyjnych Windows Vista oraz Windows 7. W dzisiejszym oraz kilku następnych wpisach skupię się na poszczególnych elementach tej technologii. Zacznę od okien Settings oraz Flyouts. Struktura aplikacji Zanim przejdziemy dalej, należy wspomnieć nieco o strukturze aplikacji. Nie różni sie ona zbytno od struktury aplikacji internetowej. Mamy dokument główny, dokumenty dodatkowe oraz zasoby (CSS, Javascript oraz obrazki). Proponowany przeze mnie układ katalogów wygląda następująco. struktura-katalogow Katalogi raczej nie wymagają wyjaśnienia – są przeznaczone do przechowywania obrazków, skryptów Javascript oraz plików CSS. Z kolei pliki to manifest (gadget.xml), główny dokument gadżetu (Main.html – nazwa definiowana w manifeście) oraz pozostałe dokumenty .W tym przypadku jest to tylko Settings.html, ale nic nie stoi na przeszkodzie, aby tych dokumentów było więcej. W dalszej części dzisiejszego przewodnika dojdzie jeszcze jeden plik – Flyout.html W przykładach wykorzystałem bibliotekę jQuery, dzięki której wiele czynności zostało uproszczonych, przez co kod jest bardziej czytelny. Nie jest to wymóg. Jeśli nie znacie/nie lubicie jQuery możecie skorzystać z innej biblioteki lub nie korzystać wcale. Settings Settings to nic innego jak okno ustawień. Jest ono reprezentowane przez osobny dokukent HTML, w którym powinny znaleźć się elementy formularza (pola tekstowe, checkboxy, radiobuttony itp). Nie ma konieczności stosowania przycisków, ponieważ są one dodawane automatycznie. Jeśli chcemy wykorzystać okno ustawień wystarczy, że do właściwości settingsUI obiektu System.Gadget przypisana zostanie ścieska wskazująca na plik HTML. Ścieżka może być relatywna lub bezwzględna. Przypisanie powinno nastąpić w głównym dokumencie.
System.Gadget.settingsUI = "/Settings.html";
Dodanie powyższego kodu do gadżetu spowoduje pojawienie się ikonki klucza (wyróżniona na czerwono), settings-icon kliknięcie której spowoduje otwarcie dokumentu wskazanego we właściwości settingsUI. Dokument ten zostanie zamieszczony w specjalnym oknie, zawierającym nagłówek oraz niezbędne przyciski. settings-window W prawym górnym roku tego okna pojawi się podgląd gadżetu. Ponieważ dzisiejszy wpis poświęcony jest jedynie oknom Settings oraz Flyout, gadżet nie będzie zawierał żadnych elementów graficznych. Stąd ten biały pionowy pasek na powyższym screenie. Jak już wspomniałem, okno ustawień to nic innego jak najzwyklejszy formularz HTML. W naszym przykładzie formularz będzie zawierał jedynie jedno pole.
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  <link type="text/css" rel="stylesheet" href="/styles/reset.css" />
  <link type="text/css" rel="stylesheet" href="/styles/global.css" />
  <script type="text/javascript" src="/scripts/jquery-1.4.2.min.js"></script>
 </head>
    <body class="settings">
  <label>Your name:</label>
  <input type="text" name="your-name" id="your-name" />
    </body>
</html>
Samo dodanie formularza oraz wskazanie go jako okno ustawień na nic się zda, jeśli chcemy przechowywać i odczytywać wprowadzone przez użytkownika dane. Na szzęście mamy do dyspozycji obiekt System.Gadget.Settings, który pozwala na zapisywanie i odczytywanie ustawień. Służą do tego cztery metody, przez ten obiekt udostępnione. Są to:
  • write
  • writeString
  • read
  • readString
Metody z przyrostkiem String służą odpowiednio do zapisania i odczytania danych tekstowych. Pozostałe typy danych powinny być zapisywane i odczytywane przez metody write oraz read. Jest to podyktowane względami wydajnościowymi. Warto mieć również na uwadze limity, które ograniczają ilość przechowywanych w ten sposób informacji. Klucze mogą mieć jedynie 1024 znaki, a przypisane im wartości 2048 znaki. W przypadku przekroczenia tych limitów, dane zostaną skrócone do maksymalnych wartości. Dane zapisywane w oknie ustawień można przechwycić w zdarzeniu onSettingsClosing obiektu System.Gadget. Przechwycenie tego zdarzenie musi nastąpić w pliku okna ustawień. W przeciwnym razie dane nie będą dostępne.
// przechwycenie zdarzenia zamykania okna ustawień
System.Gadget.onSettingsClosing = SettingsClosing;

// obsługa zdarzenia
function SettingsClosing(event)
{
 // czy zamknięcie nastąpiło na skutek kliknięcia w przycisk "OK"
 if(event.closeAction == event.Action.commit) {
  // zapisanie wprowadzonych danych
  System.Gadget.Settings.writeString("name", $("#your-name").val());
 }
}
Jeśli chcemy od razu po zamknięciu okna ustawień mieć dostęp do danych, musimy obsłużyć kolejne zdarzenie związane z ustawieniami – onSettingsClosed. Przy czym należy pamiętać, że obsługa tego zdarzenia musi – w przeciwieństwie do zdarzenia onSettingsClosing – odbyć się w głównym oknie gadżetu.
// przechwycenie zdarzenia zamknięcia okna ostawień
System.Gadget.onSettingsClosed = SettingsClosed;

// obsługa zdarzenia
function SettingsClosed(event)
{
 // odczytanie wprowadzonych danych
 var name = System.Gadget.Settings.readString("name");
 $("#entered-name").text(name);
}
Flyout Flyout jest specjalnym typem okna, które stosuje się do zaprezentowania dodatkowych informacji. Podobnie jak w przypadku okna ustawień, Flyout ma swój własny dokument HTML. Flyout jest wyświetlany w momencie ustawienia właściwości show obiektu System.Gadget.Flyout na true, a ukrywany po ustawieniu jej wartości na false.
// wskazanie pliku Flyout
System.Gadget.Flyout.file = "/Flyout.html";

$(document).ready(function() {
 $("#show-flyout a").click(function() {
  // wyświetlenie Flyout
  System.Gadget.Flyout.show = true;
  return false;
 });
});
Zamknięcie flyout odbywa się na tej samej zasadzie, przy czym kod odpowiedzialny za zamknięcie musi się znaleźć w pliku z flyout.

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

Autor wpisu: batman, dodany: 22.08.2010 17:35, tagi: javascript, jquery

Jakiś czas temu na blogu MIX Online pojawił się wpis na temat narzędzia pozwalającego tworzyć animacje jQuery. Podobnie jak wy teraz, podszedłem do tematu dosyć sceptycznie i odłożyłem jego zgłębianie na później. Dzisiaj zainstalowałem to narzędzie i przeprowadziłem kilka prostych testów. Ich wynik przeszedł moje najśmielsze oczekiwania. Okazuje się, że Glimmer został dokładnie przemyślany i oprócz przyjaznego interfejsu oferuje bardzo dobre narzędzia do tworzenia animacji. Wystarczy wspomnieć o wizadrach, dzięki którym w kilka chwil można stworzyć rozwijane menu lub tooltip. Oczywiście obok gotowych animacji mamy do dyspozycji edytor, który pozwoli zaprojektować animację od początku do końca. Po zainstalowaniu i uruchomieniu Glimmera, ujrzymy ekran powitalny, z poziomu którego można stworzyć własną animację, wybrać jedną z dostępnych lub przejść do strony projektu. glimmer Nie będę opisywał gotowych szablonów, ponieważ ich zastosowanie jest intuicyjne i sprowadza się do kilku prostych kroków. Poza tym wizardy zostały tak przygotowane, że nie wymagają dodatkowego opisu. O wiele bardziej interesujące są możliwości jakie daje edytor animacji. editor Wystarczy wczytać plik HTML, zawierający poprawnie sformatowany kod, a następnie wskazać źródło zdarzenia, typ zdarzenia oraz cel. Źródłem zdarzenia może być dowolny element znajdujący się we wczytanym dokumencie. Element można wskazać po tagu (np div), klasie (.jakas-klasa) lub identyfikatorze (#identyfikator). Typem zdarzenia są wszystkie przewidziane przez jQuery zdarzenia, np click, mouseover, blur, scroll, itp. new-action Cel wybiera się w taki sam sposób jak źródło. Po określeniu celu, należy wybrać rodzaj animacji oraz ustalić jej parametry. Np dla animacji przeźroczystości należy wybrać wartość początkową oraz końcową. Oprócz samej animacji mamy możliwość ustalenia dodatkowych parametrów, takich jak czas trwania oraz efekt przejścia. Co więcej, można wskazać animację jaka ma się wykonać po zakończeniu bieżącej. editor-expanded Edytor daje możliwość określenia więcej niż jednej animacji na cel oraz więcej niż jeden cel na zdarzenie. Przy odrobienie wysiłku można stworzyć skomplikowaną animację bez napisania ani jednego wiersza w Javascript. Jeśli martwicie się o jakość wygenerowanego kodu, spieszę wyjaśnić, że kod jest poprawnie wygenerowany i nie zawiera dziesiątek zbędnych zmiennych i dziwnych operacji. Jedyne co kiepsko wygląda w wygenerowanym kodzie, to komentarz zawierający informacje niezbędne dla Glimmera. Po zakończeniu pracy można ten komentarz śmiało usunąć. Oto przykładowy kod wygenerowany przez to narzędzie (nic w nim nie zmieniałem).
//Microsoft.Glimmer.OneWay
//<AnimationCollection FilePath="C:\test.html.glimmer.js" xmlns="clr-namespace:GlimmerLib;assembly=GlimmerLib" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"><Animation Name="ActionName1" EventType="click" Trigger="#link"><Animation.Targets><Target Name="#div" Duration="1000" Easing="linear" Callback="ActionName2"><Target.Effects><ColorEffect CSSName="color" DisplayName="Color Animation" MaxValue="1" MinValue="0" From="0" To=""darkred"" IsStartValue="False" IsActive="True" IsAnimatable="True" IsExpression="False" FormatString="" RequiresJQueryPlugin="True" JQueryPluginURI="effects.core.js" /></Target.Effects></Target></Animation.Targets></Animation><Animation Name="ActionName2" EventType="[none]" Trigger="{x:Null}"><Animation.Targets><Target Name="#div" Duration="1000" Easing="linear" Callback="null"><Target.Effects><RemoveHTMLEffect CSSName="#link" DisplayName="Remove HTML Effect" MaxValue="0" MinValue="0" From="0" To="0" IsStartValue="False" IsActive="True" IsAnimatable="False" IsExpression="False" FormatString="$({1}).remove();
" RequiresJQueryPlugin="False" JQueryPluginURI="" /></Target.Effects></Target></Animation.Targets></Animation></AnimationCollection>
jQuery(function($) {
var timer;
function ActionName1(event)
{
    $("#div").animate({"color":"blue"},1000, "linear", ActionName2);
}

function ActionName2(event)
{
     $("#link").remove();
}

$('#link').bind('click', ActionName1);


});
Więcej informacji na temat Glimmera oraz przykładowe animacje znajdziecie na oficjalnej stronie projektu.

Autor wpisu: batman, dodany: 21.08.2010 08:00, tagi: php

Na pytanie jak wysłać POST’a bez submitowania formularza, padają dwie odpowiedzi – AJAX lub cURL. Okazuje się, że jest jeszcze trzecia odpowiedź. Można skorzystać z kontekstu oraz standardowej funkcji operującej na plikach, np file_get_contents.

Kontekst umożliwia zmianę… kontekstu requesta. Najprościej będzie to wyjaśnić na przykładzie:

// przygotowanie zmiennych do wysłania
$post = http_build_query(array(
	'zmienna1' => 'wartosc 1',
	'zmienna2' => 'wartosc2'
));

// wysyłane nagłówki
$headers = array(
	'Content-type: application/x-www-form-urlencoded'
);

// utworzenie kontekstu
$context  = stream_context_create(array(
	'http' => array(
		'method' => 'POST',
		'header' => implode("\r\n", $headers),
		'content' => $post
	)
));

// wysłanie POST-a i zapisanie odpowiedzi do zmiennej
$content = file_get_contents('http://example.com/file.php', false, $context);

Kluczowym elementem powyższego kodu jest funkcja stream_context_create. To ona odpowiada za modyfikację standardowego zachowania funkcji file_get_contents. Stream_context_create przyjmuje dwa parametry. Pierwszym jest tablica zawierająca konfigurację kontekstu, drugim tablica zawierająca dodatkowe parametry.

Dlaczego warto korzystać z kontekstów zamiast cURL-a? Przede wszystkim nie wymaga instalacji. Wiem, że cURL jest zazwyczaj dostęny, ale… Ponadto użycie kontekstu jest prostsze i wymaga mniej kodu oraz umożliwia skorzystanie z funkcji zwrotnej. Oto przykład takiej funkcji zaczerpnięty z maunala.

function stream_notification_callback($notification_code, $severity, $message, $message_code, $bytes_transferred, $bytes_max) {

    switch($notification_code) {
        case STREAM_NOTIFY_RESOLVE:
        case STREAM_NOTIFY_AUTH_REQUIRED:
        case STREAM_NOTIFY_COMPLETED:
        case STREAM_NOTIFY_FAILURE:
        case STREAM_NOTIFY_AUTH_RESULT:
            var_dump($notification_code, $severity, $message, $message_code, $bytes_transferred, $bytes_max);
            /* Ignore */
            break;

        case STREAM_NOTIFY_REDIRECTED:
            echo "Being redirected to: ", $message;
            break;

        case STREAM_NOTIFY_CONNECT:
            echo "Connected...";
            break;

        case STREAM_NOTIFY_FILE_SIZE_IS:
            echo "Got the filesize: ", $bytes_max;
            break;

        case STREAM_NOTIFY_MIME_TYPE_IS:
            echo "Found the mime-type: ", $message;
            break;

        case STREAM_NOTIFY_PROGRESS:
            echo "Made some progress, downloaded ", $bytes_transferred, " so far";
            break;
    }
    echo "\n";
}

Dodanie funkcji zwrotnej do kontekstu jest niezwykle proste i sprowadza się do wskazania jej nazwy w drugim parametrze funkcji stream_context_create.

$context  = stream_context_create(
	array(
		'http' => array(
			'method' => 'POST',
			'header' => implode("\r\n", $headers),
			'content' => $post
		)
	),
	array(
		'notification' => 'stream_notification_callback'
	)
);

Wywołaniu funkcji file_get_contenst z kontekstem zawierającym funkcję zwrotną spowoduje wyświetlenie:

Connected...
Found the mime-type: text/html
Made some progress, downloaded 0 so far
Made some progress, downloaded 8192 so far
Made some progress, downloaded 16384 so far
Made some progress, downloaded 24216 so far

Prawda, że proste?

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