Zend_Mail_Read.xml 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662
  1. <sect1 id="zend.mail.read">
  2. <title>Lettura di messaggi e-mail</title>
  3. <para>
  4. <code>Zend_Mail</code> può leggere messaggi e-mail da diversi sistemi di salvataggio locali o remoti.
  5. Ciascuno di essi ha le stesse API alla base per contare e leggere i messaggi ed alcuni implementano interfacce aggiuntive per funzionalità non così comuni.
  6. Per una panoramica delle funzionalità dei sistemi di raccolta consultare la tabella seguente.
  7. </para>
  8. <table id="zend.mail.read.table-1">
  9. <title>Panoramica delle caratteristiche dei sistemi di lettura di e-mail</title>
  10. <tgroup cols="5">
  11. <thead>
  12. <row>
  13. <entry>Funzionalità</entry>
  14. <entry>Mbox</entry>
  15. <entry>Maildir</entry>
  16. <entry>Pop3</entry>
  17. <entry>IMAP</entry>
  18. </row>
  19. </thead>
  20. <tbody>
  21. <row>
  22. <entry>Tipo di salvataggio</entry>
  23. <entry>locale</entry>
  24. <entry>locale</entry>
  25. <entry>remoto</entry>
  26. <entry>remoto</entry>
  27. </row>
  28. <row>
  29. <entry>Estrazione dei messaggi</entry>
  30. <entry>Yes</entry>
  31. <entry>Yes</entry>
  32. <entry>Yes</entry>
  33. <entry>Yes</entry>
  34. </row>
  35. <row>
  36. <entry>Estrazione delle parti mime</entry>
  37. <entry>emulata</entry>
  38. <entry>emulata</entry>
  39. <entry>emulata</entry>
  40. <entry>emulata</entry>
  41. </row>
  42. <row>
  43. <entry>Cartelle</entry>
  44. <entry>Si</entry>
  45. <entry>Si</entry>
  46. <entry>No</entry>
  47. <entry>Si</entry>
  48. </row>
  49. <row>
  50. <entry>Creazione messaggio/cartella</entry>
  51. <entry>No</entry>
  52. <entry>Da fare</entry>
  53. <entry>No</entry>
  54. <entry>Da fare</entry>
  55. </row>
  56. <row>
  57. <entry>Flags</entry>
  58. <entry>No</entry>
  59. <entry>Si</entry>
  60. <entry>No</entry>
  61. <entry>Si</entry>
  62. </row>
  63. </tbody>
  64. </tgroup>
  65. </table>
  66. <sect2 id="zend.mail.read-example">
  67. <title>Semplice esempio usando Pop3</title>
  68. <programlisting role="php"><![CDATA[<?php
  69. $mail = new Zend_Mail_Storage_Pop3(array('host' => 'localhost',
  70. 'user' => 'test',
  71. 'password' => 'test'));
  72. echo $mail->countMessages() . " messaggi trovati\n";
  73. foreach ($mail as $message) {
  74. echo "E-mail da '{$message->from}': {$message->subject}\n";
  75. }]]>
  76. </programlisting>
  77. </sect2>
  78. <sect2 id="zend.mail.read-open-local">
  79. <title>Apertura di un sistema di salvataggio locale</title>
  80. <para>
  81. Mbox e Maildir sono due formati supportati per lo salvataggio locale delle e-mail, entrambi nel loro formato più semplice.
  82. </para>
  83. <para>
  84. Se si desidera leggere da un file Mbox è sufficiente fornire il nome del file al costruttore di <code>Zend_Mail_Storage_Mbox</code>:
  85. </para>
  86. <programlisting role="php"><![CDATA[<?php
  87. $mail = new Zend_Mail_Storage_Mbox(array('filename' => '/home/test/mail/inbox'));]]>
  88. </programlisting>
  89. <para>Maildir è molto simile ma necessita il nome di una cartella:</para>
  90. <programlisting role="php"><![CDATA[<?php
  91. $mail = new Zend_Mail_Storage_Maildir(array('dirname' => '/home/test/mail/'));]]>
  92. </programlisting>
  93. <para>Entrambi i costruttori generano un'eccezione <code>Zend_Mail_Exception</code> se l'archivio non può essere letto.</para>
  94. </sect2>
  95. <sect2 id="zend.mail.read-open-remote">
  96. <title>Apertura di un sistema di salvataggio remoto</title>
  97. <para>
  98. Per quanto riguarda i sistemi di salvataggio remoto i due protocolli più popolari sono entrambi supportati: Pop3 e Imap.
  99. Entrambi necessitano almeno di un host ed un utente per connettersi ed autenticarsi.
  100. La password predefinita è una stringa vuota, la porta predefinita quella specificata nel protocollo RFC.
  101. </para>
  102. <programlisting role="php"><![CDATA[<?php
  103. // connessione con Pop3
  104. $mail = new Zend_Mail_Storage_Pop3(array('host' => 'example.com'
  105. 'user' => 'test',
  106. 'password' => 'test'));
  107. // connessione con Imap
  108. $mail = new Zend_Mail_Storage_Imap(array('host' => 'example.com'
  109. 'user' => 'test',
  110. 'password' => 'test'));
  111. // esempio di una porta non standard
  112. $mail = new Zend_Mail_Storage_Pop3(array('host' => 'example.com',
  113. 'port' => 1120
  114. 'user' => 'test',
  115. 'password' => 'test'));]]>
  116. </programlisting>
  117. <para>
  118. Per entrambi i protocolli sono supportate le connessioni SSL e TSL.
  119. Se si utilizza SSL, la porta predefinita cambia come specificato in RFC.
  120. </para>
  121. <programlisting role="php"><![CDATA[<?php
  122. // esempi per Zend_Mail_Storage_Pop3, gli stessi funzionano per Zend_Mail_Storage_Imap
  123. // utilizzo di SSL su una porta differente
  124. // (i valori predefiniti sono 995 per Pop3 e 993 per Imap)
  125. $mail = new Zend_Mail_Storage_Pop3(array('host' => 'example.com'
  126. 'user' => 'test',
  127. 'password' => 'test',
  128. 'ssl' => 'SSL'));
  129. // use TLS
  130. $mail = new Zend_Mail_Storage_Pop3(array('host' => 'example.com'
  131. 'user' => 'test',
  132. 'password' => 'test',
  133. 'ssl' => 'TLS'));]]>
  134. </programlisting>
  135. <para>
  136. Entrambi i costruttori possono restituire un'eccezione <code>Zend_Mail_Exception</code> o <code>Zend_Mail_Protocol_Exception</code>, a seconda del tipo di errore.
  137. </para>
  138. </sect2>
  139. <sect2 id="zend.mail.read-fetching">
  140. <title>Lettura dei messaggi e semplici metodi</title>
  141. <para>
  142. Una volta aperta la connessione, è possibile estrarre i messaggi.
  143. E' necessario il numero di messaggi, che rappresenta un contatore che parte da 1 per il primo messaggio.
  144. Per estrarre il messaggio si utilizza il metodo <code>getMessage()</code>:
  145. </para>
  146. <programlisting role="php"><![CDATA[<?php
  147. $message = $mail->getMessage($messageNum);]]>
  148. </programlisting>
  149. <para>
  150. L'accesso sotto forma di array è supportato, ma non consente di specificare alcun parametro aggiuntivo al metodo <code>getMessage()</code>.
  151. Se questo non è un problema e si può vivere anche solo con i valori predefiniti, allora si può usare:
  152. </para>
  153. <programlisting role="php"><![CDATA[<?php
  154. $message = $mail[$messageNum];]]>
  155. </programlisting>
  156. <para>L'interfaccia Iterator è implementata e consente di scorrere tutti i messaggi:</para>
  157. <programlisting role="php"><![CDATA[<?php
  158. foreach ($mail as $messageNum => $message) {
  159. // fai qualcosa ...
  160. }]]>
  161. </programlisting>
  162. <para>
  163. Per contare i messaggi salvati è possibile usare sia il metodo <code>countMessages()</code> sia l'accesso del tipo array:
  164. </para>
  165. <programlisting role="php"><![CDATA[<?php
  166. // metodo
  167. $maxMessage = $mail->countMessages();
  168. // accesso array
  169. $maxMessage = count($mail);]]>
  170. </programlisting>
  171. <para>Per rimuovere un'e-mail si utilizzi il metodo <code>removeMessage()</code> o, nuovamente, l'accesso del tipo array:</para>
  172. <programlisting role="php"><![CDATA[<?php
  173. // metodo
  174. $mail->removeMessage($messageNum);
  175. // accesso array
  176. unset($mail[$messageNum]);]]>
  177. </programlisting>
  178. </sect2>
  179. <sect2 id="zend.mail.read-message">
  180. <title>Interazione con i messaggi</title>
  181. <para>
  182. Dopo aver estratto i messaggi <code>getMessage()</code> potrebbe essere necessario estrarre le intestazioni, il contenuto o singole parti di un messaggio multipart.
  183. Tutte le intestazioni sono accessibili come proprietà o grazie al metodo <code>getHeader()</code> se è necessario maggiore controllo o in caso di nomi di intestazioni poco comuni.
  184. Internamente, tutte le intestazioni sono convertite in minuscolo dunque il caso del testo nel nome non è importante. Inoltre, le intestazioni che contengono un trattino "-" possono essere scritte con la notazione CamelCase.
  185. </para>
  186. <programlisting role="php"><![CDATA[<?php
  187. // recupera l'oggetto messaggio
  188. $message = $mail->getMessage(1);
  189. // stampa l'oggetto del messaggio
  190. echo $message->subject . "\n";
  191. // recupera l'intestazione content-type
  192. $type = $message->contentType;]]>
  193. </programlisting>
  194. <para>
  195. In caso di più intestazioni con lo stesso nome, esempio l'intestazione <code>Received</code>, è possibile recuperare il valore come array invece che stringa con il metodo <code>getHeader()</code>.
  196. </para>
  197. <programlisting role="php"><![CDATA[<?php
  198. // recupera l'intestazione come proprietà
  199. // il risultato è sempre una stringa,
  200. // dove le diverse occorrenze sono separate dal carattere carattere newline (\n)
  201. $received = $message->received;
  202. // stesso risultato usando il metodo getHeader()
  203. $received = $message->getHeader('received', 'string');
  204. // o, meglio, un array contenente un elemento per ogni occorrenza
  205. $received = $message->getHeader('received', 'array');
  206. foreach ($received as $line) {
  207. // fai qualcosa
  208. }
  209. // se non si definisce un formato si ottiene la rappresentazione interna
  210. // (stringa per singole intestazioni, array per multipli)
  211. $received = $message->getHeader('received');
  212. if (is_string($received)) {
  213. // trovata una sola intestazione received nel messaggio
  214. }]]>
  215. </programlisting>
  216. <para>
  217. Il metodo <code>getHeaders()</code> restituisce tutte le intestazioni come array.
  218. Per ogni elemento, la chiave corrisponde al nome dell'intestazione in minuscolo, il valore è un array nel caso di intestazioni multiple, una stringa per intestazioni singole.
  219. </para>
  220. <programlisting role="php"><![CDATA[<?php
  221. // stampa tutte le intestazioni
  222. foreach ($message->getHeaders() as $name => $value) {
  223. if (is_string($value)) {
  224. echo "$name: $value\n";
  225. continue;
  226. }
  227. foreach ($value as $entry) {
  228. echo "$name: $entry\n";
  229. }
  230. }]]>
  231. </programlisting>
  232. <para>
  233. Se il messaggio non è di tipo multipart la sua lettura è immediata con il metodo <code>getContent()</code>.
  234. A differenza delle intestazioni, il contenuto è caricato solo in caso di necessità (late-fetch).
  235. </para>
  236. <programlisting role="php"><![CDATA[<?php
  237. // stampa il contenuto del messaggio
  238. echo '<pre>';
  239. echo $message->getContent();
  240. echo '</pre>';]]>
  241. </programlisting>
  242. <para>
  243. La verifica di un messaggio multipart avviene con il metodo <code>isMultipart()</code>.
  244. In caso positivo, è possibile ottenere un'istanza di <code>Zend_Mail_Part</code> con il metodo <code>getPart()</code>. <code>Zend_Mail_Part</code> è la classe alla base di <code>Zend_Mail_Message</code>, quindi si ha accesso agli stessi metodi: <code>getHeader()</code>, <code>getHeaders()</code>, <code>getContent()</code>, <code>getPart()</code>, <code>isMultipart</code> e le proprietà per le intestazioni.
  245. </para>
  246. <programlisting role="php"><![CDATA[<?php
  247. // recupera la prima parte non multipart
  248. $part = $message;
  249. while ($part->isMultipart()) {
  250. $part = $message->getPart(1);
  251. }
  252. echo 'Il tipo di questa parte è ' . strtok($part->contentType, ';') . "\n";
  253. echo "Contenuto:\n";
  254. echo $part->getContent();]]>
  255. </programlisting>
  256. <para>
  257. <code>Zend_Mail_Part</code> implementa <code>RecursiveIterator</code> che semplifica l'iterazione di tutte le parti. Inoltre, per agevolare l'ouput, implementa il metodo magico <code>__toString()</code> che restituisce il contenuto.
  258. </para>
  259. <programlisting role="php"><![CDATA[<?php
  260. // stampa la prima parte text/plain
  261. $foundPart = null;
  262. foreach (new RecursiveIteratorIterator($mail->getMessage(1)) as $part) {
  263. try {
  264. if (strtok($part->contentType, ';') == 'text/plain') {
  265. $foundPart = $part;
  266. break;
  267. }
  268. } catch (Zend_Mail_Exception $e) {
  269. // ignora
  270. }
  271. }
  272. if (!$foundPart) {
  273. echo 'Nessuna parte solo testo trovata';
  274. } else {
  275. echo "Parte solo testo: \n" . $foundPart;
  276. }]]>
  277. </programlisting>
  278. </sect2>
  279. <sect2 id="zend.mail.read-flags">
  280. <title>Controllo dei contrassegni</title>
  281. <para>
  282. Maildir e IMAP supportano il salvataggio dei contrassegni.
  283. La classe Zend_Mail_Storage include costanti per tutti i tipi di contrassegno IMAP e maildir conosciuti, chiamati <code>Zend_Mail_Storage::FLAG_&lt;flagname&gt;</code>.
  284. <code>Zend_Mail_Message</code> contiene un metodo chiamato <code>hasFlag()</code> per eseguire un controllo dei contrassegni. Il metodo <code>getFlags()</code> restituisce invece tutti i contrassegni impostati.
  285. </para>
  286. <programlisting role="php"><![CDATA[<?php
  287. // cerca i messaggi non letti
  288. echo "E-mail da leggere:\n";
  289. foreach ($mail as $message) {
  290. if ($message->hasFlag(Zend_Mail_Storage::FLAG_SEEN)) {
  291. continue;
  292. }
  293. // distingui le e-mail recenti/nuove
  294. if ($message->hasFlag(Zend_Mail_Storage::FLAG_RECENT)) {
  295. echo '! ';
  296. } else {
  297. echo ' ';
  298. }
  299. echo $message->subject . "\n";
  300. }
  301. // verifica i contrassegni conosciuti
  302. $flags = $message->getFlags();
  303. echo "Il messaggio è contrassegnato come: ";
  304. foreach ($flags as $flag) {
  305. switch ($flag) {
  306. case Zend_Mail_Storage::FLAG_ANSWERED:
  307. echo 'Risposto ';
  308. break;
  309. case Zend_Mail_Storage::FLAG_FLAGGED:
  310. echo 'Contrassegnato ';
  311. break;
  312. // ...
  313. // verifica altri contrassegni
  314. // ...
  315. default:
  316. echo $flag . '(contrassegno sconosciuto) ';
  317. }
  318. }]]>
  319. </programlisting>
  320. <para>
  321. Poiché IMAP permette all'utente o al client di definire contrassegni personalizzati, potrebbero esistere contrassegni senza una costante corrispondente in <code>Zend_Mail_Storage</code>.
  322. In questo caso i valori sono restituiti come stringa e possono essere verificati allo stesso modo con <code>hasFlag()</code>.
  323. </para>
  324. <programlisting role="php"><![CDATA[<?php
  325. // verifica il messaggio alla ricerca dei contrassegni
  326. // $IsSpam, $SpamTested impostati dal client
  327. if (!$message->hasFlag('$SpamTested')) {
  328. echo 'Messaggio non verificato dal controllo anti spam';
  329. } else if ($message->hasFlag('$IsSpam')) {
  330. echo 'Questo messaggio è spam';
  331. } else {
  332. echo 'Questo messaggio è sicuro';
  333. }]]>
  334. </programlisting>
  335. </sect2>
  336. <sect2 id="zend.mail.read-folders">
  337. <title>Utilizzo delle cartelle</title>
  338. <para>
  339. Tutti i sistemi di salvataggio, eccetto Pop3, supportano le cartelle anche chiamate mailbox.
  340. L'interfaccia implementata dai sistemi che supportano le cartelle si chiama <code>Zend_Mail_Storage_Folder_Interface</code>. Inoltre, tutte queste classi contengono un parametro opzionale aggiuntivo chiamato <code>folder</code> che rappresenta la cartella selezionata dopo l'autenticazione, nel costruttore.
  341. </para>
  342. <para>
  343. Per i sistemi di salvataggio locali è necessario usare delle classi a parte chiamate <code>Zend_Mail_Storage_Folder_Mbox</code> o <code>Zend_Mail_Storage_Folder_Maildir</code>.
  344. Entrambe necessitano di un parametro chiamato <code>dirname</code> che corrisponde alla cartella principale.
  345. Il formato per maildir è definito in maildir++ (con un punto come delimitatore predefinito), in Mbox è una gerarchia di directory contenenti file Mbox. Se nella cartella principale di Mbox non è presente un file Mbox chiamato INBOX, allora è necessario specificare un'altra cartella nel costruttore.
  346. </para>
  347. <para>
  348. Il supporto alle cartelle è nativo in <code>Zend_Mail_Storage_Imap</code>.
  349. Alcuni esempi per aprire questi sistemi di salvataggio:
  350. </para>
  351. <programlisting role="php"><![CDATA[<?php
  352. // mbox con cartelle
  353. $mail = new Zend_Mail_Storage_Folder_Mbox(array('dirname' => '/home/test/mail/'));
  354. // mbox con una cartella predefinita non chiamata INBOX,
  355. // funziona anche con Zend_Mail_Storage_Folder_Maildir e Zend_Mail_Storage_Imap
  356. $mail = new Zend_Mail_Storage_Folder_Mbox(array('dirname' => '/home/test/mail/',
  357. 'folder' => 'Archive'));
  358. // maildir con cartelle
  359. $mail = new Zend_Mail_Storage_Folder_Maildir(array('dirname' => '/home/test/mail/'));
  360. // maildir con due punti come delimitatore, come suggerito in Maildir++
  361. $mail = new Zend_Mail_Storage_Folder_Maildir(array('dirname' => '/home/test/mail/'
  362. 'delim' => ':'));
  363. // imap è lo stesso con o senza cartelle
  364. $mail = new Zend_Mail_Storage_Imap(array('host' => 'example.com'
  365. 'user' => 'test',
  366. 'password' => 'test'));]]>
  367. </programlisting>
  368. <para>
  369. Con il metodo getFolders($root = null) si ottiene la gerarchia delle cartelle a partire dalla cartella root o da quella specificata.
  370. Restituisce un'istanza di <code>Zend_Mail_Storage_Folder</code>, che implementa <code>RecursiveIterator</code> e tutte le sottocartelle sono a loro volta istanze di <code>Zend_Mail_Storage_Folder</code>.
  371. Ciascuna di queste istanze contiene un nome locale e globale restituiti rispettivamente dai metodi <code>getLocalName()</code> e <code>getGlobalName()</code>.
  372. Il nome globale è il nome assoluto a partire dalla cartella principale (inclusi i delimitatori), il nome locale è invece il nome specifico assunto nella cartella di livello superiore.
  373. </para>
  374. <table id="zend.mail.read-folders.table-1">
  375. <title>Nomi delle cartelle e-mail</title>
  376. <tgroup cols="2">
  377. <thead>
  378. <row>
  379. <entry>Nome Globale</entry>
  380. <entry>Nome Locale</entry>
  381. </row>
  382. </thead>
  383. <tbody>
  384. <row>
  385. <entry>/INBOX</entry>
  386. <entry>INBOX</entry>
  387. </row>
  388. <row>
  389. <entry>/Archive/2005</entry>
  390. <entry>2005</entry>
  391. </row>
  392. <row>
  393. <entry>List.ZF.General</entry>
  394. <entry>General</entry>
  395. </row>
  396. </tbody>
  397. </tgroup>
  398. </table>
  399. <para>
  400. Se si utilizza un iteratore la chiave dell'elemento corrente corrisponde al nome locale.
  401. Il nome globale è anche restituito dal metodo magico <code>__toString()</code>.
  402. Alcune cartelle non sono selezionabili, ovvero non è possibile salvare all'interno dei messaggi e se selezionate il risultato è un errore. E' possibile eseguire un controllo con il metodo <code>isSelectable()</code>.
  403. E' molto semplice stampare la visualizzazione dell'intero albero delle cartelle:
  404. </para>
  405. <programlisting role="php"><![CDATA[<?php
  406. $folders = new RecursiveIteratorIterator($this->mail->getFolders(),
  407. RecursiveIteratorIterator::SELF_FIRST);
  408. echo '<select name="folder">';
  409. foreach ($folders as $localName => $folder) {
  410. $localName = str_pad('', $folders->getDepth(), '-', STR_PAD_LEFT) . $localName;
  411. echo '<option';
  412. if (!$folder->isSelectable()) {
  413. echo ' disabled="disabled"';
  414. }
  415. echo ' value="' . htmlspecialchars($folder) . '">'
  416. . htmlspecialchars($localName) . '</option>';
  417. }
  418. echo '</select>';]]>
  419. </programlisting>
  420. <para>
  421. Il metodo <code>getCurrentFolder()</code> restituisce la cartella corrente selezionata.
  422. Per cambiare la cartella utilizzare il metodo <code>selectFolder()</code>, che necessita del nome globale come parametro. Per evitare di scrivere i delimitatori è possibile utilizzare le proprietà di un'istanza <code>Zend_Mail_Storage_Folder</code>:
  423. </para>
  424. <programlisting role="php"><![CDATA[<?php
  425. // a seconda del sistema di salvataggio e delle impostazioni $rootFolder->Archive->2005
  426. // è identico a:
  427. // /Archive/2005
  428. // Archive:2005
  429. // INBOX.Archive.2005
  430. // ...
  431. $folder = $mail->getFolders()->Archive->2005;
  432. echo "L'ultima cartella era " . $mail->getCurrentFolder() . " la nuova cartella è $folder\n";
  433. $mail->selectFolder($folder);]]>
  434. </programlisting>
  435. </sect2>
  436. <sect2 id="zend.mail.read-advanced">
  437. <title>Utilizzo avanzato</title>
  438. <sect3 id="zend.mail.read-advanced.noop">
  439. <title>Utilizzo di NOOP</title>
  440. <para>
  441. Se si utilizza un sistema di salvataggio remoto e si devono eseguire alcune attività di lunga durata, è necessario mantenere attiva la connessione via noop:
  442. </para>
  443. <programlisting role="php"><![CDATA[<?php
  444. foreach ($mail as $message) {
  445. // esegui qualche elaborazione ...
  446. $mail->noop(); // keep alive
  447. // esegui qualche altra elaborazione ...
  448. $mail->noop(); // keep alive
  449. }]]>
  450. </programlisting>
  451. </sect3>
  452. <sect3 id="zend.mail.read-advanced.caching">
  453. <title>Salvataggio in cache delle istanze</title>
  454. <para>
  455. <code>Zend_Mail_Storage_Mbox</code>, <code>Zend_Mail_Storage_Folder_Mbox</code>, <code>Zend_Mail_Storage_Maildir</code> e <code>Zend_Mail_Storage_Folder_Maildir</code> implementano i metodi magici <code>__sleep()</code> e <code>__wakeup()</code>, dunque sono serializzabili. Questo evita di eseguire la lettura dei file o delle cartelle più di una volta.
  456. Lo svantaggio è che la struttura Mbox o Maildir non deve cambiare. Sono eseguiti alcuni semplici controlli, come ad esempio la rilettura del file Mbox corrente in caso di variazione della data di ultima modifica o la rilettura della struttura delle cartelle se una cartella è scomparsa (l'errore persiste, ma è possibile cercare una nuova cartella successivamente).
  457. Ad ogni modo, è meglio mantenere qualcosa come un file indicatore dei cambiamenti e verificarlo prima di utilizzare un'istanza salvata in cache.
  458. </para>
  459. <programlisting role="php"><![CDATA[<?php
  460. // non c'è alcuna classe/gestore per la cache specificato qui,
  461. // modificare il codice con il gestore di cache in uso
  462. $signal_file = '/home/test/.mail.last_change';
  463. $mbox_basedir = '/home/test/mail/';
  464. $cache_id = 'esempio di email in cache ' . $mbox_basedir . $signal_file;
  465. $cache = new Your_Cache_Class();
  466. if (!$cache->isCached($cache_id) || filemtime($signal_file) > $cache->getMTime($cache_id)) {
  467. $mail = new Zend_Mail_Storage_Folder_Pop3(array('dirname' => $mbox_basedir));
  468. } else {
  469. $mail = $cache->get($cache_id);
  470. }
  471. // fai qualcosa ...
  472. $cache->set($cache_id, $mail);]]>
  473. </programlisting>
  474. </sect3>
  475. <sect3 id="zend.mail.read-advanced.extending">
  476. <title>Estensione delle classi dei protocolli</title>
  477. <para>
  478. I sistemi di salvataggio remoti utilizzano due classi: <code>Zend_Mail_Storage_&lt;Name&gt;</code> e <code>Zend_Mail_Protocol_&lt;Name&gt;</code>.
  479. La classe protocol traduce i comandi e le risposte da e in PHP, come ad esempio i metodi per i comandi o le variabili con strutture di dati differenti.
  480. L'altra classe principale implementa l'interfaccia comune.
  481. </para>
  482. <para>
  483. Per aggiungere ulteriori funzionalità ad un protocollo è possibile estendere la classe ed utilizzarla nel costruttore della classe principale.
  484. Per esempio si assuma di dover utilizzare una porta differente per aprire una connessione POP3.
  485. </para>
  486. <programlisting role="php"><![CDATA[<?php
  487. require_once 'Zend/Loader.php';
  488. Zend_Loader::loadClass('Zend_Mail_Storage_Pop3');
  489. class Example_Mail_Exception extends Zend_Mail_Exception
  490. {
  491. }
  492. class Example_Mail_Protocol_Exception extends Zend_Mail_Protocol_Exception
  493. {
  494. }
  495. class Example_Mail_Protocol_Pop3_Knock extends Zend_Mail_Protocol_Pop3
  496. {
  497. private $host, $port;
  498. public function __construct($host, $port = null)
  499. {
  500. // nessuna connessione automatica in questa classe
  501. $this->host = $host;
  502. $this->port = $port;
  503. }
  504. public function knock($port)
  505. {
  506. $sock = @fsockopen($this->host, $port);
  507. if ($sock) {
  508. fclose($sock);
  509. }
  510. }
  511. public function connect($host = null, $port = null, $ssl = false)
  512. {
  513. if ($host === null) {
  514. $host = $this->host;
  515. }
  516. if ($port === null) {
  517. $port = $this->port;
  518. }
  519. parent::connect($host, $port);
  520. }
  521. }
  522. class Example_Mail_Pop3_Knock extends Zend_Mail_Storage_Pop3
  523. {
  524. public function __construct(array $params)
  525. {
  526. // ... verifica qui $params! ...
  527. $protocol = new Example_Mail_Protocol_Pop3_Knock($params['host']);
  528. // esegui i nostri comandi "speciali"
  529. foreach ((array)$params['knock_ports'] as $port) {
  530. $protocol->knock($port);
  531. }
  532. // recupera lo status corretto
  533. $protocol->connect($params['host'], $params['port']);
  534. $protocol->login($params['user'], $params['password']);
  535. // inizializza la classe genitore
  536. parent::__construct($protocol);
  537. }
  538. }
  539. $mail = new Example_Mail_Pop3_Knock(array('host' => 'localhost',
  540. 'user' => 'test',
  541. 'password' => 'test',
  542. 'knock_ports' => array(1101, 1105, 1111)));]]>
  543. </programlisting>
  544. <para>
  545. Come è possibile notare si suppone sempre di essere connessi, autenticati e, se supportato, una cartella è selezionata nel costruttore della classe principale.
  546. Quindi, se si assegna una classe protocollo personalizzata è necessario assicurarsi che tutto questo sia avvenuto correttamente o il metodo seguente non andrà a buon fine se il server non lo permette nello status corrente.
  547. </para>
  548. </sect3>
  549. </sect2>
  550. </sect1>
  551. <!--
  552. vim:se ts=4 sw=4 et:
  553. -->