Niezalogowany [ logowanie ]
Subskrybuj kanał ATOM Kanał ATOM

Autor wpisu: Diabl0, dodany: 23.12.2008 17:15, tagi: zend_framework

KalendarzBardzo często tworząc różnego rodzaju formularze korzystamy z pól do wprowadzania daty. Miłym uzupełnieniem dla użytkowników takiego pola jest dodanie kalendarza z którego mogą sobie oni wybrać datę. Jednym z najbardziej znanych narzędzi tego typu jest The Coolest DHTML Calendar. A jako zwolennik Zend_Form, zaraz pokażę wam jak ułatwić sobie życie i stworzyć Zend_Form_Element do szybkiego i prostego podłączania takiego kalendarza do formy.

Dotychczas chcąc dać użytkownikom możliwość wyboru daty z kalendarza używałem albo Dojo i jego dijit.form.DateTextBox (rozwiązanie mocno ograniczone pod względem możliwości), albo tworzyłem w formie zwykły element text i w widoku formy dodawałem kod odpowiedzialny z a DHTML Calendar. Aż ostatecznie dzisiaj rano stwierdziłem że można to rozwiązać znacznie prościej i wygodniej pisząc własny element Zend_Form_Element. I poniżej znajdziecie tego wstępne rezultaty.

Zacznijmy od elementu formy:

/**
 * calendar form element
 *
 * @uses Mao_View_Helper_FormCalendar
 */
class Mao_Form_Element_Calendar extends Zend_Form_Element_Xhtml
{
    /**
     * Default form view helper to use for rendering
     * @var string
     */
    public $helper = 'formCalendar';

}

Klasa ta jest kalką Zend_Form_Element_Text i jej głównym przeznaczeniem jest określenie helpera widoku - formCalendar gdzie odbywa się większość “magii

/**
 * Helper to generate a "calendar" element
 *
 * @todo uporządkować
 * @todo obsługa parametrów
 */
class Mao_View_Helper_FormCalendar extends Zend_View_Helper_FormElement
{
    /**
     * Generates a 'text' element.
     *
     * @access public
     *
     * @param string|array $name If a string, the element name.  If an
     * array, all other parameters are ignored, and the array elements
     * are used in place of added parameters.
     *
     * @param mixed $value The element value.
     *
     * @param array $attribs Attributes for the element tag.
     *
     * @return string The element XHTML.
     */
    public function formCalendar($name, $value = null, $attribs = null)
    {
        $info = $this->_getInfo($name, $value, $attribs);
        extract($info); // name, value, attribs, options, listsep, disable

        // build the element
        $disabled = '';
        if ($disable) {
            // disabled
            $disabled = ' disabled="disabled"';
        }

        // XHTML or HTML end tag?
        $endTag = ' />';
        if (($this->view instanceof Zend_View_Abstract) && !$this->view->doctype()->isXhtml()) {
            $endTag= '>';
        }

        $xhtml = '<input type="text"'
                . ' name="' . $this->view->escape($name) . '"'
                . ' id="' . $this->view->escape($id) . '"'
                . ' value="' . $this->view->escape($value) . '"'
                . $disabled
                . $this->_htmlAttribs($attribs)
                . $endTag;

        if ( !$disable) {

            $this->view->headLink ()->appendStylesheet('http://cdn.local.ss/js/calendar/calendar-system.css');
            $this->view->headScript()
                ->appendFile ( 'http://cdn.local.ss/js/calendar/calendar.js', 'text/javascript')
                ->appendFile ( 'http://cdn.local.ss/js/calendar/lang/calendar-en.js', 'text/javascript')
                ->appendFile ( 'http://cdn.gazeta.ie/js/calendar/calendar-setup.js', 'text/javascript');

            $xhtml .= '<button' . ' id="' . $this->view->escape($id) . '_trigger"' . '><img src="http://cdn.local.ss/images/crystal/16x16/actions/1day.png"></button>';

            $xhtml .= '
            <script type="text/javascript">
                //<![CDATA[
    			  Calendar.setup(
    			    {
    			      inputField  : "' . $this->view->escape($id) . '",         // ID of the input field
    			      ifFormat    : "%Y-%m-%d",    // the date format
    			      button      : "' . $this->view->escape($id) . '_trigger"       // ID of the button
    			    }
    			  );
    		    //]]>
        	</script>
    		';
        }

        return $xhtml;
    }
}

Początek jest żywcem przekopiowany z dowolnego Zend_View_Helper_Form*, jednak końcówka zawiera już sam miodzik

  1. po sprawdzeniu czy element nie jest wyłączony ( $disabled ) za pomocą helperów headLink i headScript dodajemy linki do skryptów JS i CSS.  W powyższym przykładzie odpowiednie pliki znajdują się na firmowym CDNie i są wpisane na stałe. W ostatecznym kodzie wypadało by użyć helpera baseUrl.
  2. do pola <input type=”text” (zawartego w zmiennej $xhtml) dodajemy element button który będzie naszym triggerem (id = $id . ‘_trigger’)
  3. Dodawany jest kawałek kodu JS inicializujący DHTML dla triggera

I… to na razie wszystko, gdyż moja doza zapału w te święta chwilowo się wyczerpała ;) Oczywiście, cały zaprezentowany powyżej kod to tylko szybka wstępna wersja (szkic) który należy jeszcze odpowiednio rozbudować (np. możliwość ustalania formatu daty z poziomu formy, własny kod triggera itp), ale po świętach kogoś do niego posadzę i może kiedyś zaprezentuję bardziej rozbudowaną i elastyczną wersję. W ostateczności powinna to być także dobra podstawa do własnych eksperymentów jako prosty i działający przykład własnego elementu.

Related posts

Autor wpisu: Athlan, dodany: 22.12.2008 19:50, tagi: php

Przeglądając forum.php.pl często widziałem, jak użytkownicy przechowują hasła w swoich bazach danych. Najczęściej używają funkcji hashujących md5, sha1 i sha2. Wszystko wygląda bardzo dobrze, hasła są przechowywanie bezpiecznie. No właśnie… na ile bezpiecznie.

Nie będę tutaj rozwodził się nad zabezpieczeniem baz danych, w których owa baza haseł się znajduje, ale nad samym zahashowanym ciągu. Wszyscy doskonale wiemy, że istnieją bazy md5 (sha1, sha2 również).

Przezorny zawsze ubezpieczony. Wiadomo, że nigdy nic nie wiadomo.

Pokażę, jak dodatkowo zabezpieczyć nasze hasła. Będą przechowywane w tej samej bazie danych, używając tych samych metod hashowania, a jednak szansa na “złamanie” hasła (wyszukania w bazie) będzie niemożliwa. Posłużymy się ciągiem znaków zwanym przez programistów solą (salt). Przykład implementacji możemy znaleźć w forum IPB, natomiast phpBB pozbawione jest tego fjuczuru ficzera. Cała sprawa sprowadza się do wygenerowania dowolnego kawałka ciągu znaków i doklejenia go do hasła. Sól potrzebna nam będzie również przy porównaniu hasła, więc trzeba ją zapisać w bazie danych obok hasła.

Poniżej zamieszczam przykładową klasę, która obsługuje solenie haseł. Doklejanie soli może być napisane w dowolny sposób, zależy to od Waszej wyobraźni. Ja dodatkowo dodałem element “losowy” w postaci doklejenia do soli wyniku działania funkcji microtime().

Autor wpisu: Zyx, dodany: 22.12.2008 16:44, tagi: php

Skuteczne zabezpieczenia nie muszą być skomplikowane, aby dawały pożądany efekt. Powszechnie znanych rozwiązań jest kilkanaście i każde chroni przed pewnymi rodzajami ataków. Ich implementacja nie powinna być rzeczą trudną, lecz w rękach niedoświadczonego programisty może być zabójcza dla serwisu WWW. W tym wpisie chciałbym przedstawić dziury, z jakimi się ostatnio spotkałem, będące bardziej błędem mózgu ich autorów, niż samego algorytmu.

Autor wpisu: m1chu, dodany: 22.12.2008 03:10, tagi: css

Dla zwykłego użytkownika Internet Explorer to po prostu pierwsza linia dostępu do Internetu. Nie każdy z nich wie jednak, że jest to linia stosunkowo mało bezpieczna i niestabilna. Wiele mówi się o istniejących już od wielu lat i ciągle rozwijanych alternatywach. I pomimo, że sporo osób skusiło się już na wymianę używanej przeglądarki to rynek nie tylko najnowszej, ale i starszych odsłon IE jest nadal prężny. Zbyt prężny, co najbardziej odbija się na twórcach witryn internetowych. Niepodporządkowanie się standardom powoduje, że często aby praca wychodząca spod ich ręki była prawidłowo interpretowana przez przeglądarkę Microsoftu trzeba użyć pewnego typu zamienników...

Stop użytkowaniu IE!

Dlaczego dyskryminuję IE?

Bo mam przez tą przeglądarkę więcej pracy. Pracy której by nie było, gdyby wielce wykształceni, po jeszcze większych pod względem stopnia prestiżu uczelniach programiści potrafili "sklepać" ten twór porządnie, wg. istniejących od wielu lat standardów. I nie tylko mi to przysparza nerwów. Wiem, wiem - za chwilę znajdzie się tutaj jakiś specjalista z ogromnej korporacji developerskiej który wytknie mi, że nie szanuję przez to swoich klientów. Ich akurat traktuję poważnie i poświęcam swój czas w takiej ilości, aby zrobić co ma być wykonane porządnie. W hobbistycznych projektach powiem dobitnie i szczerze... w pewnym stopniu lekceważę użytkowników tegoż browsera. Przynajmniej tych którzy świadomie go używają i co najmniej w wersjach niższych niż siódemka. Bo z całej serii chłamu którą wydała korporacja z Redmond tylko ostatnia, "stabilna" (z nazwy) wersja choć odrobinę pokrywa się z wyznaczonymi regułami. Użytkownikom wersji szóstej... współczuję, a ci którzy z premedytacją korzystają z jeszcze starszych odsłon nie zasługują nawet na to.

Żeby nie być gołosłownym wypadałoby podać kilka przyczyn moich ostrych słów.

  • ilość wykrywanych luk i prędkość ich łatania jest niekiedy zastraszająco długa - przykładem są tutaj niektóre błędy opisane na Secunii (dla IE7 w tym przypadku).
  • fakt braku wsparcia dla wersji niższych niż szósta tej przeglądarki, a co za tym idzie niełatanie dziur wykrywanych w nich (niemiło byłoby wstać kiedyś rano i zobaczyć, że konto bankowe z którego korzystaliśmy dzień wcześniej poprzez przeglądarkę z Redmond jest puste, prawda?).
  • pomimo zrobienia kilku kroków w przód nadal MSIE jest jednym z wolniejszych tego typu rozwiązań.
  • jest wiele alternatyw takich jak Firefox, Opera (recenzja Opery 9.6x), czy Safari. Są one proste w obsłudze, wręcz intuicyjne, a dzięki zaimplementowanym, dodatkowym modułom, czy wtyczkom potrafią w znaczny sposób pomóc w surfowaniu po sieci.
  • alternatywne przeglądarki względnie poprawnie interpretują standardy sieciowe dotyczące wyświetlania stron przez co nigdy nie zobaczysz prawidłowo napisanej strony w niepoprawnie ułożonym stylu.

To tylko namiastka różnic. W sieci znajduje się wiele artykułów pokazujących wyższość przeglądarek, jeszcze kilka lat temu niszowych od tej promowanej przez amerykańskiego giganta. Dlatego nawracajcie swoich znajomych, bo w tym wypadku naprawdę "pozornie inne" znaczy lepsze...

Ranking przeglądarek polskiej części internetu

Nie w jeden dzień Rzym zbudowano...

Pomimo kilku słów mojej dezaprobaty, i wielu przeszłych lat negatywnych opinii innych ludzi nie da się oczywiście z dnia na dzień nawrócić wszystkich "niewiernych" :] Dlatego meritum dzisiejszego wpisu będzie tematyka komentarzy warunkowych i haków dla "zbuntowanej" przeglądarki.

Różne typy komentarzyRóżne typy komentarzy.

Ukryte komentarze warunkowe

Od wersji 5 Internet Explorer obsługuje ukryte (pozytywne) komentarze warunkowe (z angielskiego downlevel-hidden (positive) conditional comments). Obsługuje, ale tylko w wersji pod Windowsem (IE/Win), pod Macintoshem już nie (IE/Mac). W zależności od treści w nich zawartych są one widzialne lub nie przez daną przeglądarkę. Jest to szczególnie przydatne jeżeli dany element strony musimy inaczej opisać w IE, niż w jej zamiennikach. Za pewnie sami twórcy zorientowali się wtedy jaki dziki twór stworzyli i choć ciut chcieli się zrehabilitować pozwalając webmasterom chociażby w nadmiarowy sposób tworzyć strony zgodne z ich "dziełem".

PLAIN TEXT CODE:
  1. <!--[if IE]>
  2. kod pomiędzy tymi komentarzami zadziała tylko w odsłonach IE
  3. <![endif]-->

Oto przykład najprostszego zastosowania komentarzy. Można ją wykorzystać np. w sekcji head w celu zaimportowania arkusza stylów wykorzystywanego przez produkt z Doliny Krzemowej.

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

Autor wpisu: Athlan, dodany: 20.12.2008 15:00, tagi: zend_framework

Pisząc nowy projekt natknąłem na problem z procesem uploadu filmiku do serwisu YouTube. Sam upload jest bardzo łatwy do napisania z Zend_Gdata_YouTube - przykład można znaleźć w manualu. Myślę, że zainteresowani przeczytają manual i wszystko będzie jasne. Więc jeżeli to takie proste, to w czym problem?

Zakładamy, że userzy uloadują filmiki bezpośrednio na nasz serwis. Nasz serwer ma za zadanie:

  1. Skompresować video i zapisać go w formacie flv.
  2. Nałożyć watermark.
  3. Wysłać obrobiony film do serwisu Youtube logując się na zdefiniowane przez użytkownika konto lub założone przez administratora strony.

Pierwsze 2 kroki wykonają się błyskawicznie w porównaniu do trzeciego. Kompresja i nałożenie watermarku na 30 megowy plik z wykorzystaniem FFMPEG to nic nadzwyczajnego. Natomiast wysyłka pliku na serwery Youtube’a może zawiesić apache’a, gdy jest ich kilka.

Rozwiązanie? Wpadłem na pomysł, aby upload filmików ustawiony był w pewnego rodzaju kolejce, która uruchamiana by była co minutę (cron), a czas jednego wysłania elemntu nie mógłby przekroczyć 50 sekund. Oczywiście takie działanie uruchamiałoby swój osobny proces apache’a. Ten sposób jest ograniczony dwoma limitami: wielkością pliku oraz czasem jego uploadu na serwer (jednocześniem interwałem uruchamiania kolejki).

Autor wpisu: Diabl0, dodany: 19.12.2008 21:53, tagi: zend_framework, php

Tym razem zadanie wydawało się banalne - ułatwić życie użytkownikom umożliwiając im masowe drukowanie zleceń raz na jakiś czas, zamiast przy każdym nowym zleceniu. Zlecenia w formacie PDF były zapisywane do plików. Teraz wystarczyło tylko połączyć te kilka/naście plików w jeden wielostronnicowy PDF (użytkownicy powiesili by mnie za jaja jakby musieli klikać po koleji każdy PDF i klikać “Drukuj”). Tylko…

Pierwszy pomysł jaki mi się nasunął to Zend_Pdf. Widziałem tam i Zend_Pdf_Page, i możliwość wczytania gotowego pliku. Prawie się zdziwiłem na myśl że w końcu ten  IMHO bezcelowy komponent Zend_Pdf do czegoś się przyda. Niestety, po raz kolejny okazało się że jest nieprzydatna do niczego. Pomijając problemy z wczytaniem PDF’a wygenerowanego przez TCPDF:

(”Unsupported PDF version. Zend_Pdf supports PDF 1.0-1.4. Current version - ‘1.7′“)

gdzie w kodzie warunek wygląda następująco:

        $pdfVersion = (float)substr($pdfVersionComment, 5);
        if ($pdfVersion < 0.9 || $pdfVersion >= 1.61) {
            /**
             * @todo
             * To support PDF versions 1.5 (Acrobat 6) and PDF version 1.7 (Acrobat 7)
             * Stream compression filter must be implemented (for compressed object streams).
             * Cross reference streams must be implemented
             */
            throw new Zend_Pdf_Exception(sprintf('Unsupported PDF version. Zend_Pdf supports PDF 1.0-1.4. Current version - \'%f\'', $pdfVersion));
        }

To jeszcze przy próbie utworzenia nowego dokumentu i przypisania mu stron z innego dokumentu ładny wyjątek:

Page is attached to one documen, but rendered in context of another.

Pozostało w takim razie Google, a tam… niewiele możliwości. Albo komercja, albo rozwiązania systemowe, i… mała perełka: FPDI

FPDI is a collection of PHP classes facilitating developers to read pages from existing PDF documents and use them as templates in FPDF, which was developed by Olivier Plathey. Apart from a copy of FPDF, FPDI does not require any special PHP extensions.

Since version 1.2.1, FPDI only supports the 1.6 version of FPDF.

Po chwili moją uwagę przyciągnęło jeszcze jedno (dość ciekawie brzmiące) zdanie:

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

Autor wpisu: Jaroslaw Mężyk, dodany: 16.12.2008 21:41, tagi: php

Tak to jest - człowiek całe życie się uczy a i tak głupi umiera ;) PHPem zajmuję się już ładnych parę lat (6 albo 7 - nie mogę się doliczyć) a dopiero ostatnio dowiedziałem się o dwóch ciekawostkach, którymi chętnie się z Wami podzielę. dla zwolenników wcięć i ogólnie wymyślnego formatowania… Czy wiedzieliście o tym, że w wywołaniu [...]
Wszystkie wpisy należą do ich twórców. PHP.pl nie ponosi odpowiedzialności za treść wpisów.