Niezalogowany [ logowanie ]
Subskrybuj kanał ATOM Kanał ATOM    Subskrybuj kanał ATOM dla tagu php Kanał ATOM (tag: php)

Autor wpisu: Diabl0, dodany: 26.11.2008 12:15, tagi: zend_framework, php

Dzisiaj ponad 2 godziny spędziłem na dochodzeniu dlaczego Zend_Auth zapisuje do sesji “okrojony” rekord usera (bazujący na Zend_Db_Table_Row).

Rekord ten zawierał garść dodatkowych informacji (jak na przykład lista grup do których należy user) wypełnianych przed przekazaniem go do Zend_Auth_Storage, które jednak nie zapisywały się tam. Dopiero dokładna analiza wykazała że winowajcą była metoda __sleep() w Zend_Db_Table_Row_Abstract

Lekarstwem okazało się nadpisanie w modelu usera ( Main_Model_Users_Row ) tej metody, i tak teraz mój model wygląda mniej więcej tak:

class Main_Models_Users_Row extends Mao_Db_Table_Row {

	/**
	 * tablica z row'ami grup usera
	 *
	 * @var array
	 */
	private $_groups;

	/**
	 * trzeba przeciazyc sleepa i do tablicy $ret
	 * dodac wszystkie pola, ktore maja byc zserializowane
	 *
	 * @return array
	 */
	public function __sleep() {
		$ret = parent::__sleep ();
		$ret [] = '_groups';

		return $ret;
	}

}

Related posts

Autor wpisu: Diabl0, dodany: 20.11.2008 09:46, tagi: php, zend_framework

Ostatnio po raz kolejny w czasie prac nad jednym z projektów stanąłem przed problemem generowania dokumentów do druku. I po raz kolejny automatycznie wybór padł na PDF. I znowu ( ;) ) po raz kolejny stanąłem przed problemem jakiej klasy użyć aby ułatwić sobie zadanie. Tym razem mój wzrok padł na TCPDF i jak na razie spełnia on pokładane w nim nadzieje.

Poniżej natomiast znajdziecie mały wrapper aby korzystanie z TCPDF w Zend Framework było proste, wygodne i zgodne z standardami ZF.

Samą klasę znajdziecie na SF.net: http://sourceforge.net/project/showfiles.php?group_id=128076 - wystarczy ją pobrać i wrzucić do katalogu library/Mao/TCPDF/ (oczywiście Mao zamieniacie na własną nazwę).

Następnie wystarczy utworzyć prostą klasę Mao_TCPDF w library/Mao/TCPDF.php , a w niej:

<?php
/**
 * This is a Zend Framework wrapper for TCPDF class for generating PDF documents without requiring external extensions.
 *
 * {@link http://www.tcpdf.org TCPDF project} has been originally derived in 2002 from the Public Domain {@link http://www.fpdf.org FPDF class} by Olivier Plathey, but now is almost entirely rewritten.
 *  *
 * @category   Mao
 * @package    Mao_TCPDF
 * @author Krzysztof 'Diabl0' Szatanik
 * @copyright Copyright (c) 2008, MAO Group
 * @link http://www.tcpdf.org
 */

Zend_Loader::loadFile( 'tcpdf.php', '../library/Mao/TCPDF/', true );

/**
 * This is a Zend Framework wrapper for TCPDF class for generating PDF documents without requiring external extensions.
 *
 * {@link http://www.tcpdf.org TCPDF project} has been originally derived in 2002 from the Public Domain {@link http://www.fpdf.org FPDF class} by Olivier Plathey, but now is almost entirely rewritten.
 *
 * @category   Mao
 * @package    Mao_TCPDF
 * @author Krzysztof 'Diabl0' Szatanik
 * @copyright Copyright (c) 2008, MAO Group
 * @link http://www.tcpdf.org
 */
class Mao_TCPDF extends TCPDF
{

    /**
     * @var alias for total number of pages
     */
    protected $AliasNbPages = '{nb}';

    /**
     * This is the class constructor.
     *
     * It allows to set up the page format, the orientation and the measure unit used in all the methods (except for the font sizes).
     *
     * @param string $orientation page orientation. Possible values are (case insensitive):<ul><li>P or Portrait (default)</li><li>L or Landscape</li></ul>
     * @param string $unit User measure unit. Possible values are:<ul><li>pt: point</li><li>mm: millimeter (default)</li><li>cm: centimeter</li><li>in: inch</li></ul><br />A point equals 1/72 of inch, that is to say about 0.35 mm (an inch being 2.54 cm). This is a very common unit in typography; font sizes are expressed in that unit.
     * @param mixed $format The format used for pages. It can be either one of the following values (case insensitive) or a custom format in the form of a two-element array containing the width and the height (expressed in the unit given by unit).<ul><li>4A0</li><li>2A0</li><li>A0</li><li>A1</li><li>A2</li><li>A3</li><li>A4 (default)</li><li>A5</li><li>A6</li><li>A7</li><li>A8</li><li>A9</li><li>A10</li><li>B0</li><li>B1</li><li>B2</li><li>B3</li><li>B4</li><li>B5</li><li>B6</li><li>B7</li><li>B8</li><li>B9</li><li>B10</li><li>C0</li><li>C1</li><li>C2</li><li>C3</li><li>C4</li><li>C5</li><li>C6</li><li>C7</li><li>C8</li><li>C9</li><li>C10</li><li>RA0</li><li>RA1</li><li>RA2</li><li>RA3</li><li>RA4</li><li>SRA0</li><li>SRA1</li><li>SRA2</li><li>SRA3</li><li>SRA4</li><li>LETTER</li><li>LEGAL</li><li>EXECUTIVE</li><li>FOLIO</li></ul>
     * @param boolean $unicode TRUE means that the input text is unicode (default = true)
     * @param String $encoding charset encoding; default is UTF-8
     */
    public function __construct( $orientation = 'P' , $unit = 'mm' , $format = 'A4' , $unicode = true , $encoding = "UTF-8" )
    {
        parent::__construct( $orientation, $unit, $format, $unicode, $encoding );

        // Zawsze o tym zapominam, więc poleciało do konstruktora :)
        $this->AliasNbPages();
    }

    /**
     * Zwraca szerokość strony
     *
     * @return float
     */
    public function getPageWidth()
    {
        return $this->w - $this->rMargin - $this->x;
    }

    /**
     * Prints a cell (rectangular area) with optional borders, background color and character string. The upper-left corner of the cell corresponds to the current position. The text can be aligned or centered. After the call, the current position moves to the right or to the next line. It is possible to put a link on the text.<br />
     * If automatic page breaking is enabled and the cell goes beyond the limit, a page break is done before outputting.
     * @param float $w Cell width. If 0, the cell extends up to the right margin.
     * @param float $h Cell height. Default value: 0.
     * @param string $txt String to print. Default value: empty string.
     * @param mixed $border Indicates if borders must be drawn around the cell. The value can be either a number:<ul><li>0: no border (default)</li><li>1: frame</li></ul>or a string containing some or all of the following characters (in any order):<ul><li>L: left</li><li>T: top</li><li>R: right</li><li>B: bottom</li></ul>
     * @param int $ln Indicates where the current position should go after the call. Possible values are:<ul><li>0: to the right (or left for RTL languages)</li><li>1: to the beginning of the next line</li><li>2: below</li></ul>
		Putting 1 is equivalent to putting 0 and calling Ln() just after. Default value: 0.
     * @param string $align Allows to center or align the text. Possible values are:<ul><li>L or empty string: left align (default value)</li><li>C: center</li><li>R: right align</li><li>J: justify</li></ul>
     * @param int $fill Indicates if the cell background must be painted (1) or transparent (0). Default value: 0.
     * @param mixed $link URL or identifier returned by AddLink().
     * @param int $stretch stretch carachter mode: <ul><li>0 = disabled</li><li>1 = horizontal scaling only if necessary</li><li>2 = forced horizontal scaling</li><li>3 = character spacing only if necessary</li><li>4 = forced character spacing</li></ul>
     * @since 1.0
     * @see SetFont(), SetDrawColor(), SetFillColor(), SetTextColor(), SetLineWidth(), AddLink(), Ln(), MultiCell(), Write(), SetAutoPageBreak()
     */
    public function Cell( $w , $h = 0 , $txt = '' , $border = 0 , $ln = 0 , $align = '' , $fill = 0 , $link = '' , $stretch = 0 )
    {
        //html_entity_decode("€", ENT_COMPAT, "UTF-8");
        if( $txt != '' )
        {
            $txt = str_replace( '€', html_entity_decode( "€", ENT_COMPAT, "UTF-8" ), $txt );
        }

        parent::Cell( $w, $h, $txt, $border, $ln, $align, $fill, $link, $stretch );
    }

}
?>

W zasadzie wszystko powinno być jasne, ale na koniec jeszcze 2 uwagi.

1 - Własnego konstruktora używam z 2 powodów - AliasNbPages o którym zawsze zapominam w samym kodzie, i ładowanie własnego konfiga z Zend_Config (ten fragment dla czytelności pominąłem na powyższym listingu).

2 - metoda Cell - została lekko nadpisana z powodu często używanego przeze mnie znaku €. Po prostu wygodnie jest mi w kodzie używać znaku entity & euro ;.

Related posts

Autor wpisu: Diabl0, dodany: 15.11.2008 23:19, tagi: php

Dzisiaj odgrzewany kotlet, ale nadal wiele osób korzysta z Smarty i może im się to przydać.

Wiele osób korzystających z Smarty’ego używa go tylko jako systemu szablonów do separacji kodu PHP od HTML. Dużo mniej osób zdaje sobie natomiast sprawę z jego rozbudowanego mechanizmu cache i potencjału jaki w nim drzemie.

Zapewne dla wielu osób jednym z większych braków Smarty’ego jest możliwość określenia czasu trzymania cache (cache_lifetime) dla poszczególnych plików szablonów. Normalne włączenie cache i ustawienie jakiegoś cache_lifetime sprawia że strona traci swoją dynamiczność a przy bardziej rozbudowanych projektach potrafią się dziać „cuda” gdy na przykład po zalogowaniu wciąż pokazuje nam się formularz logowania zamiast profil użytkownika. Poniżej postaram się przedstawić swój pomysł na ominięcie tego efektu, a przy okazji często znaczne przyśpieszenie działania całego serwisu i ograniczenie ilości przetwarzanych danych.

Pomysł

Pracując nad jedym z projektów głównym celem było zminimalizowanie ilości zapytań do bazy danych. Pierwszym pomysłem było pobieranie danych z bazy i trzymanie ich w PEAR::Cache do ponownego wykorzystania. Jednakże przeglądając różne fora w poszukiwaniu innych pomysłów na optymalizację zwróciłem uwagę na wbudowany w Smarty’ego mechanizm cache i zastanowiło mnie czy nie dało by się go przerobić tak aby pasował do potrzeb obecnego projektu… Przeglądając dokumentację odnośnie cache zarysował mi się pewien pomysł który postanowiłem przetestować.

Z grubsza polega on na zbudowaniu szablonu na zasadzie modułów. W PHP wykonywane są podstawowe operacje w rodzaju rozpoznania akcji, pobrania danych użytkownika i wywołania odpowiedniego szablonu. Natomiast szablony zostały podzielone na „moduły” odpowiedzialne za wyświetlenie niewielkich fragmentów serwisu w rodzaju listy kategorii czy listy ostatnich tematów na forum.

Działanie

W typowym rozwiązaniu lista tematów czy kategorii została by na początku pobrana z bazy danych i w formie tablicy przekazana do szablonu. W moim rozwiązaniu nie pobieram tych danych tylko od razu wywołuję główny szablon. Tam natomiast znajdują się tagi  {insert} Smarty’ego realizujące za mnie brudną robotę. W zamierzeniu twórców powinny służyć one do wstawiania treści która nie jest cacheowana (funkcja wykonuje się nawet w szablonie który jest w cache). Ja postanowiłem wykorzystać to do przeciwnego celu – wstawiania cacheowanego szablonu do szablonu który nie jest cacheowany. Aby lepiej to zrozumieć proszę przyjrzeć się poniższym kawałkom kodu:

strona.tpl (nie jest cacheowana)

<HTML>
        <HEAD>
        </HEAD>
        <BODY>
                {$smarty.now|date_format}
                <HR>
                {insert file=’tematy_forum’}
        </BODY>
</HTML>

tematy_forum.tpl (ma być cacheowany)

<TABLE>
<TBODY>
{foreach from=$forum_latest_topics item=topic}
<TR>
        <TD>{$topic.title|truncate:30}</TD>
</TR>
{/foreach}
<TR><TD>{$smarty.now|date_format}</TD></TR>
</TBODY>
</TABLE>

I najważniejszy plik insert.tematy_forum.php który powinien zostać utworzony w katalogu funkcji Smarty’ego

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

Autor wpisu: Athlan, dodany: 15.11.2008 11:57, tagi: internet, php

Rzadko bo rzadko, ale jestem zmuszony używać funkcji wordwrap(). Zawsze denerwowało mnie, że wordwrap łamie linię (ciągi znaków) a nie wyrazy (jak na to nazwa funkcji wskazuje). Czy aby na pewno nazwa funkcji jest trafna?

Zwraca łańcuch str zawinięty w kolumny o odpowiedniej ilości znaków określonej przez opcjonalny parametr szerokość . Linia jest łamana przy użyciu (opcjonalnego)parametru break .

Niestety, potrzebowałem załamać wyrazy, a nie linie. Z pomocą przychodzi preg_replace(). Założenie jest takie, że wyrazem jest każdy ciąg znaków nie zawierający spacji. Łamiemy nawet ciągi liczb oraz znaków specjalnych, niekoniecznie zawierających litery:

function _wordwrap($sString, $iLimit = 32)
{
  return preg_replace('/([^ ]{’ . (int)$iLimit . ‘})/’, ‘$1 ‘, $sString);
}

Paradoksy w nazewnictwie się zdarzają.

Autor wpisu: widmogrod, dodany: 12.11.2008 22:09, tagi: zend_framework, php

Zend Framework umożliwia specjalizację finalnego widoku(layoutu) dla każdej z akcji poprzez tzw. helpery("pomocniki") widoku. Jak to się dzieje odsyłam do podręcznika.Wszystko działało idealnie do dnia gdy nadeszła chwila integracji stronki z Google Maps API.W widoku akcji korzystam z wymiotnego w temacie pomocnika:$this->headScript()->appendFile('http://maps.google.com/maps?file=api&v=2&key='.$this->apiKey);nagłówek strony produkuje mi coś takiego:<script src="http://maps.google.com/maps?file=api&amp;amp;v=2&amp;amp;key=ABQIAAAAnCqO9l1WMOgTCJlg9kVlMRREqxHjot-MVdGv4W7rNtdAWxNh4hS2-gRBnLrWFzhAC8SpBzYmGVYZgA" type="text/javascript"/>a powinien<script src="http://maps.google.com/maps?file=api&amp;v=2&amp;key=ABQIAAAAnCqO9l1WMOgTCJlg9kVlMRREqxHjot-MVdGv4W7rNtdAWxNh4hS2-gRBnLrWFzhAC8SpBzYmGVYZgA" type="text/javascript"></script>jak łatwo zauważyć problem leży w &amp; -> &.Inicjowanie map googla tej zmiany nie lubi. Problem tkwi w funkcji htmlspecialchars, użytej w Zend_View_Helper_HeadScript::append() itd.Żeby nie ingerować w kod w/w klasy można zastosować funkcję htmlspecialchars_decode w szablonie w następujący sposób...// &amp; -> & becouse gmaps crash!print htmlspecialchars_decode($this->headScript());.. i wszystko działa, tak jak powinno od samego początku.

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

Autor wpisu: Zyx, dodany: 06.11.2008 19:17, tagi: php

Zabrałem się dzisiaj za rozeznanie, jak tu spakować biblioteki OPL do postaci archiwów PHAR tak, by wciąż zachować ich własności. Z tego powodu musiałem napisać m.in. skrypt pakujący, a z niego zrodził się pomysł skrobnięcia paru słów na blogu pokazujących, jak to się robi. Tak więc do dzieła!

Autor wpisu: widmogrod, dodany: 17.10.2008 01:14, tagi: php, eclipse

PHP Development Tools w wersji 2.0 ujrzy światło dzienne 29 grudnia 2008 roku, ale to mi nie przeszkadza by pracować na wersji rozwojowej (:.Poniżej przedstawiam przetłumaczony poradnik instalacji PDT2.0 na najnowszej wersji mojego ulubionego IDE Eclipse.Pobieramy i rozpakowujemy Eclipse IDE for Java EE Developers (162 MB) do wybranego katalogu.Do pełni szczęścia brakuje nam jeszcze trzech paczek.
  1. DLTK (Integration) link bezpośredni do paczki
  2. PDT2.0 (2.0.0 Integration Builds) link bezpośredni
  3. WTP (tą paczkę sugeruję pominąć, bo w Java EE już jest!)
Powyższe paczki rozpakowujemy i dodajemy do managera pakietów
  1. Help > Software Updates... > Available Software
  2. Add Site... > Local > dodajemy katalog rozpakowanego pakietu DLTK
  3. Add Site... > Local > dodajemy katalog rozpakowanego pakietu PDT2.0
  4. Add Site... > Local > dodajemy katalog rozpakowanego pakietu WTP
  5. Gdy odświeżenie listy pakietów nie wykona się automatycznie - wciskamy "Refresh"
  6. Zaznaczamy pakiet the "Dynamic Languages Toolkit - Core Frameworks .."
  7. Zaznaczamy pakiet "PDT Feature"
  8. Zaznaczamy "WTP Feature" (jeżeli jeszcze nie jest jest zainstalowany)
  9. Klikamy "Install"
Gdy wszystko przebiegnie pomyślnie uruchamiamy ponownie Eclipse i mamy PHP Development Tools w wersji 2.0 :). Teraz tylko New PHP Project i zabawa się zaczyna (:.Uwaga na koniec, w Eclipse Ganymede w okienku "Software Updates" jest możliwość wpisywania nazw pakietów należy w tym polu wpisywać pełne nazwy pakietów do instalacji a nie ich akronimy tj. zamiast DLTK należy wpisać Dynamic Languages Toolkit
Wszystkie wpisy należą do ich twórców. PHP.pl nie ponosi odpowiedzialności za treść wpisów.