PageRenderTime 61ms CodeModel.GetById 33ms RepoModel.GetById 0ms app.codeStats 0ms

/library/Zend/Mail/Protocol/Pop3.php

https://bitbucket.org/baruffaldi/website-2008-computer-shopping-3
PHP | 464 lines | 209 code | 64 blank | 191 comment | 35 complexity | 24c11520d1eff2bff1676adc382fdfea MD5 | raw file
  1. <?php
  2. /**
  3. * Zend Framework
  4. *
  5. * LICENSE
  6. *
  7. * This source file is subject to the new BSD license that is bundled
  8. * with this package in the file LICENSE.txt.
  9. * It is also available through the world-wide-web at this URL:
  10. * http://framework.zend.com/license/new-bsd
  11. * If you did not receive a copy of the license and are unable to
  12. * obtain it through the world-wide-web, please send an email
  13. * to license@zend.com so we can send you a copy immediately.
  14. *
  15. * @category Zend
  16. * @package Zend_Mail
  17. * @subpackage Protocol
  18. * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
  19. * @license http://framework.zend.com/license/new-bsd New BSD License
  20. * @version $Id: Pop3.php 11468 2008-09-21 18:31:29Z nico $
  21. */
  22. /**
  23. * @category Zend
  24. * @package Zend_Mail
  25. * @subpackage Protocol
  26. * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
  27. * @license http://framework.zend.com/license/new-bsd New BSD License
  28. */
  29. class Zend_Mail_Protocol_Pop3
  30. {
  31. /**
  32. * saves if server supports top
  33. * @var null|bool
  34. */
  35. public $hasTop = null;
  36. /**
  37. * socket to pop3
  38. * @var null|resource
  39. */
  40. protected $_socket;
  41. /**
  42. * greeting timestamp for apop
  43. * @var null|string
  44. */
  45. protected $_timestamp;
  46. /**
  47. * Public constructor
  48. *
  49. * @param string $host hostname of IP address of POP3 server, if given connect() is called
  50. * @param int|null $port port of POP3 server, null for default (110 or 995 for ssl)
  51. * @param bool|string $ssl use ssl? 'SSL', 'TLS' or false
  52. * @throws Zend_Mail_Protocol_Exception
  53. */
  54. public function __construct($host = '', $port = null, $ssl = false)
  55. {
  56. if ($host) {
  57. $this->connect($host, $port, $ssl);
  58. }
  59. }
  60. /**
  61. * Public destructor
  62. */
  63. public function __destruct()
  64. {
  65. $this->logout();
  66. }
  67. /**
  68. * Open connection to POP3 server
  69. *
  70. * @param string $host hostname of IP address of POP3 server
  71. * @param int|null $port of POP3 server, default is 110 (995 for ssl)
  72. * @param string|bool $ssl use 'SSL', 'TLS' or false
  73. * @return string welcome message
  74. * @throws Zend_Mail_Protocol_Exception
  75. */
  76. public function connect($host, $port = null, $ssl = false)
  77. {
  78. if ($ssl == 'SSL') {
  79. $host = 'ssl://' . $host;
  80. }
  81. if ($port === null) {
  82. $port = $ssl == 'SSL' ? 995 : 110;
  83. }
  84. $this->_socket = @fsockopen($host, $port);
  85. if (!$this->_socket) {
  86. /**
  87. * @see Zend_Mail_Protocol_Exception
  88. */
  89. require_once 'Zend/Mail/Protocol/Exception.php';
  90. throw new Zend_Mail_Protocol_Exception('cannot connect to host');
  91. }
  92. $welcome = $this->readResponse();
  93. strtok($welcome, '<');
  94. $this->_timestamp = strtok('>');
  95. if (!strpos($this->_timestamp, '@')) {
  96. $this->_timestamp = null;
  97. } else {
  98. $this->_timestamp = '<' . $this->_timestamp . '>';
  99. }
  100. if ($ssl === 'TLS') {
  101. $this->request('STLS');
  102. $result = stream_socket_enable_crypto($this->_socket, true, STREAM_CRYPTO_METHOD_TLS_CLIENT);
  103. if (!$result) {
  104. /**
  105. * @see Zend_Mail_Protocol_Exception
  106. */
  107. require_once 'Zend/Mail/Protocol/Exception.php';
  108. throw new Zend_Mail_Protocol_Exception('cannot enable TLS');
  109. }
  110. }
  111. return $welcome;
  112. }
  113. /**
  114. * Send a request
  115. *
  116. * @param string $request your request without newline
  117. * @return null
  118. * @throws Zend_Mail_Protocol_Exception
  119. */
  120. public function sendRequest($request)
  121. {
  122. $result = @fputs($this->_socket, $request . "\r\n");
  123. if (!$result) {
  124. /**
  125. * @see Zend_Mail_Protocol_Exception
  126. */
  127. require_once 'Zend/Mail/Protocol/Exception.php';
  128. throw new Zend_Mail_Protocol_Exception('send failed - connection closed?');
  129. }
  130. }
  131. /**
  132. * read a response
  133. *
  134. * @param boolean $multiline response has multiple lines and should be read until "<nl>.<nl>"
  135. * @return string response
  136. * @throws Zend_Mail_Protocol_Exception
  137. */
  138. public function readResponse($multiline = false)
  139. {
  140. $result = @fgets($this->_socket);
  141. if (!is_string($result)) {
  142. /**
  143. * @see Zend_Mail_Protocol_Exception
  144. */
  145. require_once 'Zend/Mail/Protocol/Exception.php';
  146. throw new Zend_Mail_Protocol_Exception('read failed - connection closed?');
  147. }
  148. $result = trim($result);
  149. if (strpos($result, ' ')) {
  150. list($status, $message) = explode(' ', $result, 2);
  151. } else {
  152. $status = $result;
  153. $message = '';
  154. }
  155. if ($status != '+OK') {
  156. /**
  157. * @see Zend_Mail_Protocol_Exception
  158. */
  159. require_once 'Zend/Mail/Protocol/Exception.php';
  160. throw new Zend_Mail_Protocol_Exception('last request failed');
  161. }
  162. if ($multiline) {
  163. $message = '';
  164. $line = fgets($this->_socket);
  165. while ($line && rtrim($line, "\r\n") != '.') {
  166. if ($line[0] == '.') {
  167. $line = substr($line, 1);
  168. }
  169. $message .= $line;
  170. $line = fgets($this->_socket);
  171. };
  172. }
  173. return $message;
  174. }
  175. /**
  176. * Send request and get resposne
  177. *
  178. * @see sendRequest(), readResponse()
  179. *
  180. * @param string $request request
  181. * @param bool $multiline multiline response?
  182. * @return string result from readResponse()
  183. * @throws Zend_Mail_Protocol_Exception
  184. */
  185. public function request($request, $multiline = false)
  186. {
  187. $this->sendRequest($request);
  188. return $this->readResponse($multiline);
  189. }
  190. /**
  191. * End communication with POP3 server (also closes socket)
  192. *
  193. * @return null
  194. */
  195. public function logout()
  196. {
  197. if (!$this->_socket) {
  198. return;
  199. }
  200. try {
  201. $this->request('QUIT');
  202. } catch (Zend_Mail_Protocol_Exception $e) {
  203. // ignore error - we're closing the socket anyway
  204. }
  205. fclose($this->_socket);
  206. $this->_socket = null;
  207. }
  208. /**
  209. * Get capabilities from POP3 server
  210. *
  211. * @return array list of capabilities
  212. * @throws Zend_Mail_Protocol_Exception
  213. */
  214. public function capa()
  215. {
  216. $result = $this->request('CAPA', true);
  217. return explode("\n", $result);
  218. }
  219. /**
  220. * Login to POP3 server. Can use APOP
  221. *
  222. * @param string $user username
  223. * @param string $password password
  224. * @param bool $try_apop should APOP be tried?
  225. * @return void
  226. * @throws Zend_Mail_Protocol_Exception
  227. */
  228. public function login($user, $password, $tryApop = true)
  229. {
  230. if ($tryApop && $this->_timestamp) {
  231. try {
  232. $this->request("APOP $user " . md5($this->_timestamp . $password));
  233. return;
  234. } catch (Zend_Mail_Protocol_Exception $e) {
  235. // ignore
  236. }
  237. }
  238. $result = $this->request("USER $user");
  239. $result = $this->request("PASS $password");
  240. }
  241. /**
  242. * Make STAT call for message count and size sum
  243. *
  244. * @param int $messages out parameter with count of messages
  245. * @param int $octets out parameter with size in octects of messages
  246. * @return void
  247. * @throws Zend_Mail_Protocol_Exception
  248. */
  249. public function status(&$messages, &$octets)
  250. {
  251. $messages = 0;
  252. $octets = 0;
  253. $result = $this->request('STAT');
  254. list($messages, $octets) = explode(' ', $result);
  255. }
  256. /**
  257. * Make LIST call for size of message(s)
  258. *
  259. * @param int|null $msgno number of message, null for all
  260. * @return int|array size of given message or list with array(num => size)
  261. * @throws Zend_Mail_Protocol_Exception
  262. */
  263. public function getList($msgno = null)
  264. {
  265. if ($msgno !== null) {
  266. $result = $this->request("LIST $msgno");
  267. list(, $result) = explode(' ', $result);
  268. return (int)$result;
  269. }
  270. $result = $this->request('LIST', true);
  271. $messages = array();
  272. $line = strtok($result, "\n");
  273. while ($line) {
  274. list($no, $size) = explode(' ', trim($line));
  275. $messages[(int)$no] = (int)$size;
  276. $line = strtok("\n");
  277. }
  278. return $messages;
  279. }
  280. /**
  281. * Make UIDL call for getting a uniqueid
  282. *
  283. * @param int|null $msgno number of message, null for all
  284. * @return string|array uniqueid of message or list with array(num => uniqueid)
  285. * @throws Zend_Mail_Protocol_Exception
  286. */
  287. public function uniqueid($msgno = null)
  288. {
  289. if ($msgno !== null) {
  290. $result = $this->request("UIDL $msgno");
  291. list(, $result) = explode(' ', $result);
  292. return $result;
  293. }
  294. $result = $this->request('UIDL', true);
  295. $result = explode("\n", $result);
  296. $messages = array();
  297. foreach ($result as $line) {
  298. if (!$line) {
  299. continue;
  300. }
  301. list($no, $id) = explode(' ', trim($line), 2);
  302. $messages[(int)$no] = $id;
  303. }
  304. return $messages;
  305. }
  306. /**
  307. * Make TOP call for getting headers and maybe some body lines
  308. * This method also sets hasTop - before it it's not known if top is supported
  309. *
  310. * The fallback makes normale RETR call, which retrieves the whole message. Additional
  311. * lines are not removed.
  312. *
  313. * @param int $msgno number of message
  314. * @param int $lines number of wanted body lines (empty line is inserted after header lines)
  315. * @param bool $fallback fallback with full retrieve if top is not supported
  316. * @return string message headers with wanted body lines
  317. * @throws Zend_Mail_Protocol_Exception
  318. */
  319. public function top($msgno, $lines = 0, $fallback = false)
  320. {
  321. if ($this->hasTop === false) {
  322. if ($fallback) {
  323. return $this->retrieve($msgno);
  324. } else {
  325. /**
  326. * @see Zend_Mail_Protocol_Exception
  327. */
  328. require_once 'Zend/Mail/Protocol/Exception.php';
  329. throw new Zend_Mail_Protocol_Exception('top not supported and no fallback wanted');
  330. }
  331. }
  332. $this->hasTop = true;
  333. $lines = (!$lines || $lines < 1) ? 0 : (int)$lines;
  334. try {
  335. $result = $this->request("TOP $msgno $lines", true);
  336. } catch (Zend_Mail_Protocol_Exception $e) {
  337. $this->hasTop = false;
  338. if ($fallback) {
  339. $result = $this->retrieve($msgno);
  340. } else {
  341. throw $e;
  342. }
  343. }
  344. return $result;
  345. }
  346. /**
  347. * Make a RETR call for retrieving a full message with headers and body
  348. *
  349. * @deprecated since 1.1.0; this method has a typo - please use retrieve()
  350. * @param int $msgno message number
  351. * @return string message
  352. * @throws Zend_Mail_Protocol_Exception
  353. */
  354. public function retrive($msgno)
  355. {
  356. return $this->retrieve($msgno);
  357. }
  358. /**
  359. * Make a RETR call for retrieving a full message with headers and body
  360. *
  361. * @param int $msgno message number
  362. * @return string message
  363. * @throws Zend_Mail_Protocol_Exception
  364. */
  365. public function retrieve($msgno)
  366. {
  367. $result = $this->request("RETR $msgno", true);
  368. return $result;
  369. }
  370. /**
  371. * Make a NOOP call, maybe needed for keeping the server happy
  372. *
  373. * @return null
  374. * @throws Zend_Mail_Protocol_Exception
  375. */
  376. public function noop()
  377. {
  378. $this->request('NOOP');
  379. }
  380. /**
  381. * Make a DELE count to remove a message
  382. *
  383. * @return null
  384. * @throws Zend_Mail_Protocol_Exception
  385. */
  386. public function delete($msgno)
  387. {
  388. $this->request("DELE $msgno");
  389. }
  390. /**
  391. * Make RSET call, which rollbacks delete requests
  392. *
  393. * @return null
  394. * @throws Zend_Mail_Protocol_Exception
  395. */
  396. public function undelete()
  397. {
  398. $this->request('RSET');
  399. }
  400. }