smtps.class.php 53 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867
  1. <?php
  2. /*
  3. * Copyright (C) Walter Torres <walter@torres.ws> [with a *lot* of help!]
  4. * Copyright (C) 2005-2015 Laurent Destailleur <eldy@users.sourceforge.net>
  5. * Copyright (C) 2006-2011 Regis Houssin
  6. *
  7. * This program is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation; either version 3 of the License, or
  10. * (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  19. */
  20. /**
  21. * \file htdocs/core/class/smtps.class.php
  22. * \brief Class to construct and send SMTP compliant email, even to a secure
  23. * SMTP server, regardless of platform.
  24. * Goals:
  25. * - mime compliant
  26. * - multiple Reciptiants
  27. * - TO
  28. * - CC
  29. * - BCC
  30. * - multi-part message
  31. * - plain text
  32. * - HTML
  33. * - inline attachments
  34. * - attachments
  35. * - GPG access
  36. * This Class is based off of 'SMTP PHP MAIL' by Dirk Paehl, http://www.paehl.de
  37. */
  38. /**
  39. * Class to construct and send SMTP compliant email, even
  40. * to a secure SMTP server, regardless of platform.
  41. */
  42. class SMTPs
  43. {
  44. /**
  45. * Host Name or IP of SMTP Server to use
  46. */
  47. var $_smtpsHost = 'localhost';
  48. /**
  49. * SMTP Server Port definition. 25 is default value
  50. * This can be defined via a INI file or via a setter method
  51. */
  52. var $_smtpsPort = '25';
  53. /**
  54. * Secure SMTP Server access ID
  55. * This can be defined via a INI file or via a setter method
  56. */
  57. var $_smtpsID = null;
  58. /**
  59. * Secure SMTP Server access Password
  60. * This can be defined via a INI file or via a setter method
  61. */
  62. var $_smtpsPW = null;
  63. /**
  64. * Who sent the Message
  65. * This can be defined via a INI file or via a setter method
  66. */
  67. var $_msgFrom = null;
  68. /**
  69. * Where are replies and errors to be sent to
  70. * This can be defined via a INI file or via a setter method
  71. */
  72. var $_msgReplyTo = null;
  73. /**
  74. * Who will the Message be sent to; TO, CC, BCC
  75. * Multi-diminsional array containg addresses the message will
  76. * be sent TO, CC or BCC
  77. */
  78. var $_msgRecipients = null;
  79. /**
  80. * Message Subject
  81. */
  82. var $_msgSubject = null;
  83. /**
  84. * Message Content
  85. */
  86. var $_msgContent = null;
  87. /**
  88. * Custom X-Headers
  89. */
  90. var $_msgXheader = null;
  91. /**
  92. * Character set
  93. * Defaulted to 'iso-8859-1'
  94. */
  95. var $_smtpsCharSet = 'iso-8859-1';
  96. /**
  97. * Message Sensitivity
  98. * Defaults to ZERO - None
  99. */
  100. var $_msgSensitivity = 0;
  101. /**
  102. * Message Sensitivity
  103. */
  104. var $_arySensitivity = array ( false,
  105. 'Personal',
  106. 'Private',
  107. 'Company Confidential' );
  108. /**
  109. * Message Sensitivity
  110. * Defaults to 3 - Normal
  111. */
  112. var $_msgPriority = 3;
  113. /**
  114. * Message Priority
  115. */
  116. var $_aryPriority = array ( 'Bulk',
  117. 'Highest',
  118. 'High',
  119. 'Normal',
  120. 'Low',
  121. 'Lowest' );
  122. /**
  123. * Content-Transfer-Encoding
  124. * Defaulted to 0 - 7bit
  125. */
  126. var $_smtpsTransEncodeType = 0;
  127. /**
  128. * Content-Transfer-Encoding
  129. */
  130. var $_smtpsTransEncodeTypes = array( '7bit', // Simple 7-bit ASCII
  131. '8bit', // 8-bit coding with line termination characters
  132. 'base64', // 3 octets encoded into 4 sextets with offset
  133. 'binary', // Arbitrary binary stream
  134. 'mac-binhex40', // Macintosh binary to hex encoding
  135. 'quoted-printable', // Mostly 7-bit, with 8-bit characters encoded as "=HH"
  136. 'uuencode' ); // UUENCODE encoding
  137. /**
  138. * Content-Transfer-Encoding
  139. * Defaulted to '7bit'
  140. */
  141. var $_smtpsTransEncode = '7bit';
  142. /**
  143. * Boundary String for MIME seperation
  144. */
  145. var $_smtpsBoundary = null;
  146. /**
  147. * Related Boundary
  148. */
  149. var $_smtpsRelatedBoundary = null;
  150. /**
  151. * Alternative Boundary
  152. */
  153. var $_smtpsAlternativeBoundary = null;
  154. /**
  155. * Determines the method inwhich the message are to be sent.
  156. * - 'sockets' [0] - conect via network to SMTP server - default
  157. * - 'pipe [1] - use UNIX path to EXE
  158. * - 'phpmail [2] - use the PHP built-in mail function
  159. * NOTE: Only 'sockets' is implemented
  160. */
  161. var $_transportType = 0;
  162. /**
  163. * If '$_transportType' is set to '1', then this variable is used
  164. * to define the UNIX file system path to the sendmail execuable
  165. */
  166. var $_mailPath = '/usr/lib/sendmail';
  167. /**
  168. * Sets the SMTP server timeout in seconds.
  169. */
  170. var $_smtpTimeout = 10;
  171. /**
  172. * Determines whether to calculate message MD5 checksum.
  173. */
  174. var $_smtpMD5 = false;
  175. /**
  176. * Class error codes and messages
  177. */
  178. var $_smtpsErrors = null;
  179. /**
  180. * Defines log level
  181. * 0 - no logging
  182. * 1 - connectivity logging
  183. * 2 - message generation logging
  184. * 3 - detail logging
  185. */
  186. var $_log_level = 0;
  187. /**
  188. * Place Class in" debug" mode
  189. */
  190. var $_debug = false;
  191. // DOL_CHANGE LDR
  192. var $log = '';
  193. var $_errorsTo = '';
  194. var $_deliveryReceipt = 0;
  195. var $_trackId = '';
  196. /**
  197. * Set delivery receipt
  198. *
  199. * @param int $_val Value
  200. * @return void
  201. */
  202. function setDeliveryReceipt($_val = 0)
  203. {
  204. $this->_deliveryReceipt = $_val;
  205. }
  206. /**
  207. * get delivery receipt
  208. *
  209. * @return int Delivery receipt
  210. */
  211. function getDeliveryReceipt()
  212. {
  213. return $this->_deliveryReceipt;
  214. }
  215. /**
  216. * Set trackid
  217. *
  218. * @param string $_val Value
  219. * @return void
  220. */
  221. function setTrackId($_val = '')
  222. {
  223. $this->_trackId = $_val;
  224. }
  225. /**
  226. * get trackid
  227. *
  228. * @return string Delivery receipt
  229. */
  230. function getTrackId()
  231. {
  232. return $this->_trackId;
  233. }
  234. /**
  235. * Set errors to
  236. *
  237. * @param string $_strErrorsTo Errors to
  238. * @return void
  239. */
  240. function setErrorsTo($_strErrorsTo)
  241. {
  242. if ( $_strErrorsTo )
  243. $this->_errorsTo = $this->_strip_email($_strErrorsTo);
  244. }
  245. /**
  246. * Get errors to
  247. *
  248. * @param boolean $_part Variant
  249. * @return string Errors to
  250. */
  251. function getErrorsTo($_part = true )
  252. {
  253. $_retValue = '';
  254. if ( $_part === true )
  255. $_retValue = $this->_errorsTo;
  256. else
  257. $_retValue = $this->_errorsTo[$_part];
  258. return $_retValue;
  259. }
  260. /**
  261. * Set debug
  262. *
  263. * @param boolean $_vDebug Value for debug
  264. * @return void
  265. */
  266. function setDebug($_vDebug = false )
  267. {
  268. $this->_debug = $_vDebug;
  269. }
  270. /**
  271. * build RECIPIENT List, all addresses who will recieve this message
  272. *
  273. * @return void
  274. */
  275. function buildRCPTlist()
  276. {
  277. // Pull TO list
  278. $_aryToList = $this->getTO();
  279. }
  280. /**
  281. * Attempt a connection to mail server
  282. *
  283. * @return mixed $_retVal Boolean indicating success or failure on connection
  284. */
  285. function _server_connect()
  286. {
  287. // Default return value
  288. $_retVal = true;
  289. // We have to make sure the HOST given is valid
  290. // This is done here because '@fsockopen' will not give me this
  291. // information if it failes to connect because it can't find the HOST
  292. $host=$this->getHost();
  293. $host=preg_replace('@tcp://@i','',$host); // Remove prefix
  294. $host=preg_replace('@ssl://@i','',$host); // Remove prefix
  295. // DOL_CHANGE LDR
  296. include_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
  297. if ( (! is_ip($host)) && ((gethostbyname($host)) == $host))
  298. {
  299. $this->_setErr(99, $host . ' is either offline or is an invalid host name.');
  300. $_retVal = false;
  301. }
  302. else
  303. {
  304. //See if we can connect to the SMTP server
  305. if ($this->socket = @fsockopen(
  306. $this->getHost(), // Host to 'hit', IP or domain
  307. $this->getPort(), // which Port number to use
  308. $this->errno, // actual system level error
  309. $this->errstr, // and any text that goes with the error
  310. $this->_smtpTimeout
  311. )) // timeout for reading/writing data over the socket
  312. {
  313. // Fix from PHP SMTP class by 'Chris Ryan'
  314. // Sometimes the SMTP server takes a little longer to respond
  315. // so we will give it a longer timeout for the first read
  316. // Windows still does not have support for this timeout function
  317. if (function_exists('stream_set_timeout')) stream_set_timeout($this->socket, $this->_smtpTimeout, 0);
  318. // Check response from Server
  319. if ( $_retVal = $this->server_parse($this->socket, "220") )
  320. $_retVal = $this->socket;
  321. }
  322. // This connection attempt failed.
  323. else
  324. {
  325. // DOL_CHANGE LDR
  326. if (empty($this->errstr)) $this->errstr='Failed to connect with fsockopen host='.$this->getHost().' port='.$this->getPort();
  327. $this->_setErr($this->errno, $this->errstr);
  328. $_retVal = false;
  329. }
  330. }
  331. return $_retVal;
  332. }
  333. /**
  334. * Attempt mail server authentication for a secure connection
  335. *
  336. * @return mixed $_retVal Boolean indicating success or failure of authentication
  337. */
  338. function _server_authenticate()
  339. {
  340. // Send the RFC2554 specified EHLO.
  341. // This improvment as provided by 'SirSir' to
  342. // accomodate both SMTP AND ESMTP capable servers
  343. $host=$this->getHost();
  344. $host=preg_replace('@tcp://@i','',$host); // Remove prefix
  345. $host=preg_replace('@ssl://@i','',$host); // Remove prefix
  346. if ( $_retVal = $this->socket_send_str('EHLO ' . $host, '250') )
  347. {
  348. // Send Authentication to Server
  349. // Check for errors along the way
  350. $this->socket_send_str('AUTH LOGIN', '334');
  351. // User name will not return any error, server will take anything we give it.
  352. $this->socket_send_str(base64_encode($this->_smtpsID), '334');
  353. // The error here just means the ID/password combo doesn't work.
  354. // There is not a method to determine which is the problem, ID or password
  355. if ( ! $_retVal = $this->socket_send_str(base64_encode($this->_smtpsPW), '235') )
  356. $this->_setErr(130, 'Invalid Authentication Credentials.');
  357. }
  358. else
  359. {
  360. $this->_setErr(126, '"' . $host . '" does not support authenticated connections.');
  361. }
  362. return $_retVal;
  363. }
  364. /**
  365. * Now send the message
  366. *
  367. * @param boolean $_bolTestMsg whether to run this method in 'Test' mode.
  368. * @param boolean $_bolDebug whether to log all communication between this Class and the Mail Server.
  369. * @return mixed void
  370. * $_strMsg If this is run in 'Test' mode, the actual message structure will be returned
  371. */
  372. function sendMsg($_bolTestMsg = false, $_bolDebug = false)
  373. {
  374. /**
  375. * Default return value
  376. */
  377. $_retVal = false;
  378. // Connect to Server
  379. if ( $this->socket = $this->_server_connect() )
  380. {
  381. // If a User ID *and* a password is given, assume Authentication is desired
  382. if( !empty($this->_smtpsID) && !empty($this->_smtpsPW) )
  383. {
  384. // Send the RFC2554 specified EHLO.
  385. $_retVal = $this->_server_authenticate();
  386. }
  387. // This is a "normal" SMTP Server "handshack"
  388. else
  389. {
  390. // Send the RFC821 specified HELO.
  391. $host=$this->getHost();
  392. $host=preg_replace('@tcp://@i','',$host); // Remove prefix
  393. $host=preg_replace('@ssl://@i','',$host); // Remove prefix
  394. $_retVal = $this->socket_send_str('HELO ' . $host, '250');
  395. }
  396. // Well, did we get to the server?
  397. if ( $_retVal )
  398. {
  399. // From this point onward most server response codes should be 250
  400. // Specify who the mail is from....
  401. // This has to be the raw email address, strip the "name" off
  402. $this->socket_send_str('MAIL FROM: ' . $this->getFrom('addr'), '250');
  403. // 'RCPT TO:' must be given a single address, so this has to loop
  404. // through the list of addresses, regardless of TO, CC or BCC
  405. // and send it out "single file"
  406. foreach ( $this->get_RCPT_list() as $_address )
  407. {
  408. /*
  409. * TODO
  410. * After each 'RCPT TO:' is sent, we need to make sure it was kosher,
  411. * if not, the whole message will fail
  412. * If any email address fails, we will need to RESET the connection,
  413. * mark the last address as "bad" and start the address loop over again.
  414. * If any address fails, the entire message fails.
  415. */
  416. $this->socket_send_str('RCPT TO: <' . $_address . '>', '250');
  417. }
  418. // Tell the server we are ready to start sending data
  419. // with any custom headers...
  420. // This is the last response code we look for until the end of the message.
  421. $this->socket_send_str('DATA', '354');
  422. // Now we are ready for the message...
  423. // Ok, all the ingredients are mixed in let's cook this puppy...
  424. $this->socket_send_str($this->getHeader().$this->getBodyContent() . "\r\n" . '.', '250');
  425. // Now tell the server we are done and close the socket...
  426. fputs($this->socket, 'QUIT');
  427. fclose($this->socket);
  428. }
  429. }
  430. return $_retVal;
  431. }
  432. // =============================================================
  433. // ** Setter & Getter methods
  434. // ** Basic System configuration
  435. /**
  436. * setConfig() is used to populate select class properties from either
  437. * a user defined INI file or the systems 'php.ini' file
  438. *
  439. * If a user defined INI is to be used, the files complete path is passed
  440. * as the method single parameter. The INI can define any class and/or
  441. * user properties. Only properties defined within this file will be setter
  442. * and/or orverwritten
  443. *
  444. * If the systems 'php.ini' file is to be used, the method is called without
  445. * parameters. In this case, only HOST, PORT and FROM properties will be set
  446. * as they are the only properties that are defined within the 'php.ini'.
  447. *
  448. * If secure SMTP is to be used, the user ID and Password can be defined with
  449. * the user INI file, but the properties are not defined with the systems
  450. * 'php.ini'file, they must be defined via their setter methods
  451. *
  452. * This method can be called twice, if desired. Once without a parameter to
  453. * load the properties as defined within the systems 'php.ini' file, and a
  454. * second time, with a path to a user INI file for other properties to be
  455. * defined.
  456. *
  457. * @param mixed $_strConfigPath path to config file or VOID
  458. * @return void
  459. */
  460. function setConfig($_strConfigPath = null)
  461. {
  462. /**
  463. * Returns constructed SELECT Object string or boolean upon failure
  464. * Default value is set at TRUE
  465. */
  466. $_retVal = true;
  467. // if we have a path...
  468. if ( ! empty ($_strConfigPath) )
  469. {
  470. // If the path is not valid, this will NOT generate an error,
  471. // it will simply return FALSE.
  472. if ( ! @include ( $_strConfigPath ) )
  473. {
  474. $this->_setErr(110, '"' . $_strConfigPath . '" is not a valid path.');
  475. $_retVal = false;
  476. }
  477. }
  478. // Read the Systems php.ini file
  479. else
  480. {
  481. // Set these properties ONLY if they are set in the php.ini file.
  482. // Otherwise the default values will be used.
  483. if ( $_host = ini_get('SMTPs') )
  484. $this->setHost($_host);
  485. if ( $_port = ini_get('smtp_port') )
  486. $this->setPort($_port);
  487. if ( $_from = ini_get('sendmail_from') )
  488. $this->setFrom($_from);
  489. }
  490. // Send back what we have
  491. return $_retVal;
  492. }
  493. /**
  494. * Determines the method inwhich the messages are to be sent.
  495. * - 'sockets' [0] - conect via network to SMTP server
  496. * - 'pipe [1] - use UNIX path to EXE
  497. * - 'phpmail [2] - use the PHP built-in mail function
  498. *
  499. * @param int $_type Interger value representing Mail Transport Type
  500. * @return void
  501. */
  502. function setTransportType($_type = 0)
  503. {
  504. if ( ( is_numeric($_type) ) &&
  505. ( ( $_type >= 0 ) && ( $_type <= 3 ) ) )
  506. $this->_transportType = $_type;
  507. }
  508. /**
  509. * Return the method inwhich the message is to be sent.
  510. * - 'sockets' [0] - conect via network to SMTP server
  511. * - 'pipe [1] - use UNIX path to EXE
  512. * - 'phpmail [2] - use the PHP built-in mail function
  513. *
  514. * @return int $_strHost Host Name or IP of the Mail Server to use
  515. */
  516. function getTransportType()
  517. {
  518. return $this->_transportType;
  519. }
  520. /**
  521. * Path to the sendmail execuable
  522. *
  523. * @param string $_path Path to the sendmail execuable
  524. * @return void
  525. *
  526. */
  527. function setMailPath($_path)
  528. {
  529. // This feature is not yet implemented
  530. return true;
  531. //if ( $_path ) $this->_mailPath = $_path;
  532. }
  533. /**
  534. * Defines the Host Name or IP of the Mail Server to use.
  535. * This is defaulted to 'localhost'
  536. * This is used only with 'socket' based mail transmission
  537. *
  538. * @param string $_strHost Host Name or IP of the Mail Server to use
  539. * @return void
  540. */
  541. function setHost($_strHost)
  542. {
  543. if ( $_strHost )
  544. $this->_smtpsHost = $_strHost;
  545. }
  546. /**
  547. * Retrieves the Host Name or IP of the Mail Server to use
  548. * This is used only with 'socket' based mail transmission
  549. *
  550. * @return string $_strHost Host Name or IP of the Mail Server to use
  551. */
  552. function getHost()
  553. {
  554. return $this->_smtpsHost;
  555. }
  556. /**
  557. * Defines the Port Number of the Mail Server to use
  558. * This is defaulted to '25'
  559. * This is used only with 'socket' based mail transmission
  560. *
  561. * @param int $_intPort Port Number of the Mail Server to use
  562. * @return void
  563. */
  564. function setPort($_intPort)
  565. {
  566. if ( ( is_numeric($_intPort) ) &&
  567. ( ( $_intPort >= 1 ) && ( $_intPort <= 65536 ) ) )
  568. $this->_smtpsPort = $_intPort;
  569. }
  570. /**
  571. * Retrieves the Port Number of the Mail Server to use
  572. * This is used only with 'socket' based mail transmission
  573. *
  574. * @return string Port Number of the Mail Server to use
  575. */
  576. function getPort()
  577. {
  578. return $this->_smtpsPort;
  579. }
  580. /**
  581. * User Name for authentication on Mail Server
  582. *
  583. * @param string $_strID User Name for authentication on Mail Server
  584. * @return void
  585. */
  586. function setID($_strID)
  587. {
  588. $this->_smtpsID = $_strID;
  589. }
  590. /**
  591. * Retrieves the User Name for authentication on Mail Server
  592. *
  593. * @return string User Name for authentication on Mail Server
  594. */
  595. function getID()
  596. {
  597. return $this->_smtpsID;
  598. }
  599. /**
  600. * User Password for authentication on Mail Server
  601. *
  602. * @param string $_strPW User Password for authentication on Mail Server
  603. * @return void
  604. */
  605. function setPW($_strPW)
  606. {
  607. $this->_smtpsPW = $_strPW;
  608. }
  609. /**
  610. * Retrieves the User Password for authentication on Mail Server
  611. *
  612. * @return string User Password for authentication on Mail Server
  613. */
  614. function getPW()
  615. {
  616. return $this->_smtpsPW;
  617. }
  618. /**
  619. * Character set used for current message
  620. * Character set is defaulted to 'iso-8859-1';
  621. *
  622. * @param string $_strCharSet Character set used for current message
  623. * @return void
  624. */
  625. function setCharSet($_strCharSet)
  626. {
  627. if ( $_strCharSet )
  628. $this->_smtpsCharSet = $_strCharSet;
  629. }
  630. /**
  631. * Retrieves the Character set used for current message
  632. *
  633. * @return string $_smtpsCharSet Character set used for current message
  634. */
  635. function getCharSet()
  636. {
  637. return $this->_smtpsCharSet;
  638. }
  639. /**
  640. * Content-Transfer-Encoding, Defaulted to '7bit'
  641. * This can be changed for 2byte characers sets
  642. * Known Encode Types
  643. * - 7bit Simple 7-bit ASCII
  644. * - 8bit 8-bit coding with line termination characters
  645. * - base64 3 octets encoded into 4 sextets with offset
  646. * - binary Arbitrary binary stream
  647. * - mac-binhex40 Macintosh binary to hex encoding
  648. * - quoted-printable Mostly 7-bit, with 8-bit characters encoded as "=HH"
  649. * - uuencode UUENCODE encoding
  650. *
  651. * @param string $_strTransEncode Content-Transfer-Encoding
  652. * @return void
  653. */
  654. function setTransEncode($_strTransEncode)
  655. {
  656. if (array_search($_strTransEncode, $this->_smtpsTransEncodeTypes))
  657. $this->_smtpsTransEncode = $_strTransEncode;
  658. }
  659. /**
  660. * Retrieves the Content-Transfer-Encoding
  661. *
  662. * @return string $_smtpsTransEncode Content-Transfer-Encoding
  663. */
  664. function getTransEncode()
  665. {
  666. return $this->_smtpsTransEncode;
  667. }
  668. /**
  669. * Content-Transfer-Encoding, Defaulted to '0' [ZERO]
  670. * This can be changed for 2byte characers sets
  671. * Known Encode Types
  672. * - [0] 7bit Simple 7-bit ASCII
  673. * - [1] 8bit 8-bit coding with line termination characters
  674. * - [2] base64 3 octets encoded into 4 sextets with offset
  675. * - [3] binary Arbitrary binary stream
  676. * - [4] mac-binhex40 Macintosh binary to hex encoding
  677. * - [5] quoted-printable Mostly 7-bit, with 8-bit characters encoded as "=HH"
  678. * - [6] uuencode UUENCODE encoding
  679. *
  680. * @param string $_strTransEncodeType Content-Transfer-Encoding
  681. * @return void
  682. *
  683. */
  684. function setTransEncodeType($_strTransEncodeType)
  685. {
  686. if (array_search($_strTransEncodeType, $this->_smtpsTransEncodeTypes))
  687. $this->_smtpsTransEncodeType = $_strTransEncodeType;
  688. }
  689. /**
  690. * Retrieves the Content-Transfer-Encoding
  691. *
  692. * @return string Content-Transfer-Encoding
  693. */
  694. function getTransEncodeType()
  695. {
  696. return $this->_smtpsTransEncodeTypes[$this->_smtpsTransEncodeType];
  697. }
  698. // ** Message Construction
  699. /**
  700. * FROM Address from which mail will be sent
  701. *
  702. * @param string $_strFrom Address from which mail will be sent
  703. * @return void
  704. */
  705. function setFrom($_strFrom)
  706. {
  707. if ( $_strFrom )
  708. $this->_msgFrom = $this->_strip_email($_strFrom);
  709. }
  710. /**
  711. * Retrieves the Address from which mail will be sent
  712. *
  713. * @param boolean $_part To "strip" 'Real name' from address
  714. * @return string Address from which mail will be sent
  715. */
  716. function getFrom($_part = true)
  717. {
  718. $_retValue = '';
  719. if ( $_part === true )
  720. $_retValue = $this->_msgFrom;
  721. else
  722. $_retValue = $this->_msgFrom[$_part];
  723. return $_retValue;
  724. }
  725. /**
  726. * Reply-To Address from which mail will be the reply-to
  727. *
  728. * @param string $_strReplyTo Address from which mail will be the reply-to
  729. * @return void
  730. */
  731. function setReplyTo($_strReplyTo)
  732. {
  733. if ( $_strReplyTo )
  734. $this->_msgReplyTo = $this->_strip_email($_strReplyTo);
  735. }
  736. /**
  737. * Retrieves the Address from which mail will be the reply-to
  738. *
  739. * @param boolean $_part To "strip" 'Real name' from address
  740. * @return string Address from which mail will be the reply-to
  741. */
  742. function getReplyTo($_part = true)
  743. {
  744. $_retValue = '';
  745. if ( $_part === true )
  746. $_retValue = $this->_msgReplyTo;
  747. else
  748. $_retValue = $this->_msgReplyTo[$_part];
  749. return $_retValue;
  750. }
  751. /**
  752. * Inserts given addresses into structured format.
  753. * This method takes a list of given addresses, via an array
  754. * or a COMMA delimted string, and inserts them into a highly
  755. * structured array. This array is designed to remove duplicate
  756. * addresses and to sort them by Domain.
  757. *
  758. * @param string $_type TO, CC, or BCC lists to add addrresses into
  759. * @param mixed $_addrList Array or COMMA delimited string of addresses
  760. * @return void
  761. *
  762. */
  763. function _buildAddrList($_type, $_addrList)
  764. {
  765. // Pull existing list
  766. $aryHost = $this->_msgRecipients;
  767. // Only run this if we have something
  768. if ( !empty ($_addrList ))
  769. {
  770. // $_addrList can be a STRING or an array
  771. if ( is_string($_addrList) )
  772. {
  773. // This could be a COMMA delimited string
  774. if ( strstr($_addrList, ',') )
  775. // "explode "list" into an array
  776. $_addrList = explode(',', $_addrList);
  777. // Stick it in an array
  778. else
  779. $_addrList = array($_addrList);
  780. }
  781. // take the array of addresses and split them further
  782. foreach ( $_addrList as $_strAddr )
  783. {
  784. // Strip off the end '>'
  785. $_strAddr = str_replace('>', '', $_strAddr);
  786. // Seperate "Real Name" from eMail address
  787. $_tmpaddr = null;
  788. $_tmpaddr = explode('<', $_strAddr);
  789. // We have a "Real Name" and eMail address
  790. if ( count($_tmpaddr) == 2 )
  791. {
  792. $_tmpHost = explode('@', $_tmpaddr[1]);
  793. $_tmpaddr[0] = trim($_tmpaddr[0], ' ">');
  794. $aryHost[$_tmpHost[1]][$_type][$_tmpHost[0]] = $_tmpaddr[0];
  795. }
  796. // We only have an eMail address
  797. else
  798. {
  799. // Strip off the beggining '<'
  800. $_strAddr = str_replace('<', '', $_strAddr);
  801. $_tmpHost = explode('@', $_strAddr);
  802. $_tmpHost[0] = trim($_tmpHost[0]);
  803. $_tmpHost[1] = trim($_tmpHost[1]);
  804. $aryHost[$_tmpHost[1]][$_type][$_tmpHost[0]] = '';
  805. }
  806. }
  807. }
  808. // replace list
  809. $this->_msgRecipients = $aryHost;
  810. }
  811. /**
  812. * Returns an array of the various parts of an email address
  813. * This assumes a well formed address:
  814. * - "Real name" <username@domain.tld>
  815. * - "Real Name" is optional
  816. * - if "Real Name" does not exist, the angle brackets are optional
  817. * This will split an email address into 4 or 5 parts.
  818. * - $_aryEmail[org] = orignal string
  819. * - $_aryEmail[real] = "real name" - if there is one
  820. * - $_aryEmail[addr] = address part "username@domain.tld"
  821. * - $_aryEmail[host] = "domain.tld"
  822. * - $_aryEmail[user] = "userName"
  823. *
  824. * @param string $_strAddr Email address
  825. * @return array An array of the various parts of an email address
  826. */
  827. function _strip_email($_strAddr)
  828. {
  829. // Keep the orginal
  830. $_aryEmail['org'] = $_strAddr;
  831. // Set entire string to Lower Case
  832. $_strAddr = strtolower($_strAddr);
  833. // Drop "stuff' off the end
  834. $_strAddr = trim($_strAddr, ' ">');
  835. // Seperate "Real Name" from eMail address, if we have one
  836. $_tmpAry = explode('<', $_strAddr);
  837. // Do we have a "Real name"
  838. if ( count($_tmpAry) == 2 )
  839. {
  840. // We may not really have a "Real Name"
  841. if ( $_tmpAry[0])
  842. $_aryEmail['real'] = trim($_tmpAry[0], ' ">');
  843. $_aryEmail['addr'] = $_tmpAry[1];
  844. }
  845. else
  846. $_aryEmail['addr'] = $_tmpAry[0];
  847. // Pull User Name and Host.tld apart
  848. list($_aryEmail['user'], $_aryEmail['host'] ) = explode('@', $_aryEmail['addr']);
  849. // Put the brackets back around the address
  850. $_aryEmail['addr'] = '<' . $_aryEmail['addr'] . '>';
  851. return $_aryEmail;
  852. }
  853. /**
  854. * Returns an array of bares addresses for use with 'RCPT TO:'
  855. * This is a "build as you go" method. Each time this method is called
  856. * the underlaying array is destroyed and reconstructed.
  857. *
  858. * @return array Returns an array of bares addresses
  859. */
  860. function get_RCPT_list()
  861. {
  862. /**
  863. * An array of bares addresses for use with 'RCPT TO:'
  864. */
  865. $_RCPT_list=array();
  866. // walk down Recipients array and pull just email addresses
  867. foreach ( $this->_msgRecipients as $_host => $_list )
  868. {
  869. foreach ( $_list as $_subList )
  870. {
  871. foreach ( $_subList as $_name => $_addr )
  872. {
  873. // build RCPT list
  874. $_RCPT_list[] = $_name . '@' . $_host;
  875. }
  876. }
  877. }
  878. return $_RCPT_list;
  879. }
  880. /**
  881. * Returns an array of addresses for a specific type; TO, CC or BCC
  882. *
  883. * @param mixed $_which Which collection of adresses to return
  884. * @return array Array of emaill address
  885. */
  886. function get_email_list($_which = null)
  887. {
  888. // We need to know which address segment to pull
  889. if ( $_which )
  890. {
  891. // Make sure we have addresses to process
  892. if ( $this->_msgRecipients )
  893. {
  894. $_RCPT_list=array();
  895. // walk down Recipients array and pull just email addresses
  896. foreach ( $this->_msgRecipients as $_host => $_list )
  897. {
  898. if ( $this->_msgRecipients[$_host][$_which] )
  899. {
  900. foreach ( $this->_msgRecipients[$_host][$_which] as $_addr => $_realName )
  901. {
  902. if ( $_realName ) // DOL_CHANGE FIX
  903. {
  904. $_realName = '"' . $_realName . '"';
  905. $_RCPT_list[] = $_realName . ' <' . $_addr . '@' . $_host . '>';
  906. }
  907. else
  908. {
  909. $_RCPT_list[] = $_addr . '@' . $_host;
  910. }
  911. }
  912. }
  913. }
  914. return implode(', ', $_RCPT_list);
  915. }
  916. else
  917. {
  918. $this->_setErr(101, 'No eMail Address for message to be sent to.');
  919. return false;
  920. }
  921. }
  922. else
  923. {
  924. $this->_setErr(102, 'eMail type not defined.');
  925. return false;
  926. }
  927. }
  928. /**
  929. * TO Address[es] inwhich to send mail to
  930. *
  931. * @param mixed $_addrTo TO Address[es] inwhich to send mail to
  932. * @return void
  933. */
  934. function setTO($_addrTo)
  935. {
  936. if ( $_addrTo )
  937. $this->_buildAddrList('to', $_addrTo);
  938. }
  939. /**
  940. * Retrieves the TO Address[es] inwhich to send mail to
  941. *
  942. * @return string TO Address[es] inwhich to send mail to
  943. */
  944. function getTo()
  945. {
  946. return $this->get_email_list('to');
  947. }
  948. /**
  949. * CC Address[es] inwhich to send mail to
  950. *
  951. * @param string $_strCC CC Address[es] inwhich to send mail to
  952. * @return void
  953. */
  954. function setCC($_strCC)
  955. {
  956. if ( $_strCC )
  957. $this->_buildAddrList('cc', $_strCC);
  958. }
  959. /**
  960. * Retrieves the CC Address[es] inwhich to send mail to
  961. *
  962. * @return string CC Address[es] inwhich to send mail to
  963. */
  964. function getCC()
  965. {
  966. return $this->get_email_list('cc');
  967. }
  968. /**
  969. * BCC Address[es] inwhich to send mail to
  970. *
  971. * @param string $_strBCC Recipients BCC Address[es] inwhich to send mail to
  972. * @return void
  973. */
  974. function setBCC($_strBCC)
  975. {
  976. if ( $_strBCC )
  977. $this->_buildAddrList('bcc', $_strBCC);
  978. }
  979. /**
  980. * Retrieves the BCC Address[es] inwhich to send mail to
  981. *
  982. * @return string BCC Address[es] inwhich to send mail to
  983. */
  984. function getBCC()
  985. {
  986. return $this->get_email_list('bcc');
  987. }
  988. /**
  989. * Message Subject
  990. *
  991. * @param string $_strSubject Message Subject
  992. * @return void
  993. */
  994. function setSubject($_strSubject = '')
  995. {
  996. if ( $_strSubject )
  997. $this->_msgSubject = $_strSubject;
  998. }
  999. /**
  1000. * Retrieves the Message Subject
  1001. *
  1002. * @return string Message Subject
  1003. */
  1004. function getSubject()
  1005. {
  1006. return $this->_msgSubject;
  1007. }
  1008. /**
  1009. * Constructes and returns message header
  1010. *
  1011. * @return string Complete message header
  1012. */
  1013. function getHeader()
  1014. {
  1015. $_header = 'From: ' . $this->getFrom('org') . "\r\n"
  1016. . 'To: ' . $this->getTO() . "\r\n";
  1017. if ( $this->getCC() )
  1018. $_header .= 'Cc: ' . $this->getCC() . "\r\n";
  1019. if ( $this->getBCC() )
  1020. $_header .= 'Bcc: ' . $this->getBCC() . "\r\n";
  1021. $host=$this->getHost();
  1022. $host=preg_replace('@tcp://@i','',$host); // Remove prefix
  1023. $host=preg_replace('@ssl://@i','',$host); // Remove prefix
  1024. //NOTE: Message-ID should probably contain the username of the user who sent the msg
  1025. $_header .= 'Subject: ' . $this->getSubject() . "\r\n";
  1026. $_header .= 'Date: ' . date("r") . "\r\n";
  1027. $trackid = $this->getTrackId();
  1028. if ($trackid)
  1029. {
  1030. // References is kept in response and Message-ID is returned into In-Reply-To:
  1031. $_header .= 'Message-ID: <' . time() . '.SMTPs-dolibarr-'.$trackid.'@' . $host . ">\r\n";
  1032. $_header .= 'References: <' . time() . '.SMTPs-dolibarr-'.$trackid.'@' . $host . ">\r\n";
  1033. $_header .= 'X-Dolibarr-TRACKID: ' . $trackid . "\r\n";
  1034. }
  1035. else
  1036. {
  1037. $_header .= 'Message-ID: <' . time() . '.SMTPs@' . $host . ">\r\n";
  1038. }
  1039. //$_header .=
  1040. // 'Read-Receipt-To: ' . $this->getFrom( 'org' ) . "\r\n"
  1041. // 'Return-Receipt-To: ' . $this->getFrom( 'org' ) . "\r\n";
  1042. if ( $this->getSensitivity() )
  1043. $_header .= 'Sensitivity: ' . $this->getSensitivity() . "\r\n";
  1044. if ( $this->_msgPriority != 3 )
  1045. $_header .= $this->getPriority();
  1046. // DOL_CHANGE LDR
  1047. if ( $this->getDeliveryReceipt() )
  1048. $_header .= 'Disposition-Notification-To: '.$this->getFrom('addr') . "\r\n";
  1049. if ( $this->getErrorsTo() )
  1050. $_header .= 'Errors-To: '.$this->getErrorsTo('addr') . "\r\n";
  1051. if ( $this->getReplyTo() )
  1052. $_header .= "Reply-To: ".$this->getReplyTo('addr') ."\r\n";
  1053. $_header .= 'X-Mailer: Dolibarr version ' . DOL_VERSION .' (using SMTPs Mailer)' . "\r\n"
  1054. . 'Mime-Version: 1.0' . "\r\n";
  1055. return $_header;
  1056. }
  1057. /**
  1058. * Message Content
  1059. *
  1060. * @param string $strContent Message Content
  1061. * @param string $strType Type
  1062. * @return void
  1063. */
  1064. function setBodyContent($strContent, $strType = 'plain')
  1065. {
  1066. //if ( $strContent )
  1067. //{
  1068. if ( $strType == 'html' )
  1069. $strMimeType = 'text/html';
  1070. else
  1071. $strMimeType = 'text/plain';
  1072. // Make RFC821 Compliant, replace bare linefeeds
  1073. $strContent = preg_replace("/(?<!\r)\n/si", "\r\n", $strContent);
  1074. $strContent = rtrim(wordwrap($strContent, 75, "\r\n"));
  1075. $this->_msgContent[$strType] = array();
  1076. $this->_msgContent[$strType]['mimeType'] = $strMimeType;
  1077. $this->_msgContent[$strType]['data'] = $strContent;
  1078. if ( $this->getMD5flag() )
  1079. $this->_msgContent[$strType]['md5'] = dol_hash($strContent, 3);
  1080. //}
  1081. }
  1082. /**
  1083. * Retrieves the Message Content
  1084. *
  1085. * @return string Message Content
  1086. */
  1087. function getBodyContent()
  1088. {
  1089. // Generate a new Boundary string
  1090. $this->_setBoundary();
  1091. // What type[s] of content do we have
  1092. $_types = array_keys($this->_msgContent);
  1093. // How many content types do we have
  1094. $keyCount = count($_types);
  1095. // If we have ZERO, we have a problem
  1096. if( $keyCount === 0 )
  1097. die ("Sorry, no content");
  1098. // If we have ONE, we can use the simple format
  1099. else if( $keyCount === 1 )
  1100. {
  1101. $_msgData = $this->_msgContent;
  1102. $_msgData = $_msgData[$_types[0]];
  1103. $content = 'Content-Type: ' . $_msgData['mimeType'] . '; charset="' . $this->getCharSet() . '"' . "\r\n"
  1104. . 'Content-Transfer-Encoding: ' . $this->getTransEncodeType() . "\r\n"
  1105. . 'Content-Disposition: inline' . "\r\n"
  1106. . 'Content-Description: message' . "\r\n";
  1107. if ( $this->getMD5flag() )
  1108. $content .= 'Content-MD5: ' . $_msgData['md5'] . "\r\n";
  1109. $content .= "\r\n"
  1110. . $_msgData['data'] . "\r\n";
  1111. }
  1112. // If we have more than ONE, we use the multi-part format
  1113. else if( $keyCount > 1 )
  1114. {
  1115. // Since this is an actual multi-part message
  1116. // We need to define a content message Boundary
  1117. // NOTE: This was 'multipart/alternative', but Windows based mail servers have issues with this.
  1118. //$content = 'Content-Type: multipart/related; boundary="' . $this->_getBoundary() . '"' . "\r\n";
  1119. $content = 'Content-Type: multipart/mixed; boundary="' . $this->_getBoundary('mixed') . '"' . "\r\n";
  1120. // . "\r\n"
  1121. // . 'This is a multi-part message in MIME format.' . "\r\n";
  1122. $content .= "Content-Transfer-Encoding: 8bit\r\n";
  1123. $content .= "\r\n";
  1124. $content .= "--" . $this->_getBoundary('mixed') . "\r\n";
  1125. if (key_exists('image', $this->_msgContent))
  1126. {
  1127. $content.= 'Content-Type: multipart/alternative; boundary="'.$this->_getBoundary('alternative').'"' . "\r\n";
  1128. $content .= "\r\n";
  1129. $content .= "--" . $this->_getBoundary('alternative') . "\r\n";
  1130. }
  1131. // Loop through message content array
  1132. foreach ($this->_msgContent as $type => $_content )
  1133. {
  1134. if ( $type == 'attachment' )
  1135. {
  1136. // loop through all attachments
  1137. foreach ( $_content as $_file => $_data )
  1138. {
  1139. $content .= "--" . $this->_getBoundary('mixed') . "\r\n"
  1140. . 'Content-Disposition: attachment; filename="' . $_data['fileName'] . '"' . "\r\n"
  1141. . 'Content-Type: ' . $_data['mimeType'] . '; name="' . $_data['fileName'] . '"' . "\r\n"
  1142. . 'Content-Transfer-Encoding: base64' . "\r\n"
  1143. . 'Content-Description: File Attachment' . "\r\n";
  1144. if ( $this->getMD5flag() )
  1145. $content .= 'Content-MD5: ' . $_data['md5'] . "\r\n";
  1146. $content .= "\r\n" . $_data['data'] . "\r\n\r\n";
  1147. }
  1148. }
  1149. // DOL_CHANGE LDR
  1150. else if ( $type == 'image' )
  1151. {
  1152. // loop through all images
  1153. foreach ( $_content as $_image => $_data )
  1154. {
  1155. $content .= "--" . $this->_getBoundary('related') . "\r\n"; // always related for an inline image
  1156. $content .= 'Content-Type: ' . $_data['mimeType'] . '; name="' . $_data['imageName'] . '"' . "\r\n"
  1157. . 'Content-Transfer-Encoding: base64' . "\r\n"
  1158. . 'Content-Disposition: inline; filename="' . $_data['imageName'] . '"' . "\r\n"
  1159. . 'Content-ID: <' . $_data['cid'] . '> ' . "\r\n";
  1160. if ( $this->getMD5flag() )
  1161. $content .= 'Content-MD5: ' . $_data['md5'] . "\r\n";
  1162. $content .= "\r\n"
  1163. . $_data['data'] . "\r\n";
  1164. }
  1165. // always end related and end alternative after inline images
  1166. $content.= "--" . $this->_getBoundary('related') . "--" . "\r\n";
  1167. $content.= "\r\n" . "--" . $this->_getBoundary('alternative') . "--" . "\r\n";
  1168. $content.= "\r\n";
  1169. }
  1170. else
  1171. {
  1172. if (key_exists('image', $this->_msgContent))
  1173. {
  1174. $content.= "Content-Type: text/plain; charset=" . $this->getCharSet() . "\r\n";
  1175. $content.= "\r\n" . strip_tags($_content['data']) . "\r\n"; // Add plain text message
  1176. $content.= "--" . $this->_getBoundary('alternative') . "\r\n";
  1177. $content.= 'Content-Type: multipart/related; boundary="' . $this->_getBoundary('related') . '"' . "\r\n";
  1178. $content.= "\r\n";
  1179. $content.= "--" . $this->_getBoundary('related') . "\r\n";
  1180. }
  1181. $content .= 'Content-Type: ' . $_content['mimeType'] . '; '
  1182. // . 'charset="' . $this->getCharSet() . '"';
  1183. . 'charset=' . $this->getCharSet() . '';
  1184. // $content .= ( $type == 'html') ? '; name="HTML Part"' : '';
  1185. $content .= "\r\n";
  1186. // $content .= 'Content-Transfer-Encoding: ';
  1187. // $content .= ($type == 'html') ? 'quoted-printable' : $this->getTransEncodeType();
  1188. // $content .= "\r\n"
  1189. // . 'Content-Disposition: inline' . "\r\n"
  1190. // . 'Content-Description: ' . $type . ' message' . "\r\n";
  1191. if ( $this->getMD5flag() )
  1192. $content .= 'Content-MD5: ' . $_content['md5'] . "\r\n";
  1193. $content .= "\r\n" . $_content['data'] . "\r\n\r\n";
  1194. }
  1195. }
  1196. // Close message boundries
  1197. // $content .= "\r\n--" . $this->_getBoundary() . '--' . "\r\n" ;
  1198. $content .= "--" . $this->_getBoundary('mixed') . '--' . "\r\n" ;
  1199. }
  1200. return $content;
  1201. }
  1202. /**
  1203. * File attachments are added to the content array as sub-arrays,
  1204. * allowing for multiple attachments for each outbound email
  1205. *
  1206. * @param string $strContent File data to attach to message
  1207. * @param string $strFileName File Name to give to attachment
  1208. * @param string $strMimeType File Mime Type of attachment
  1209. * @return void
  1210. */
  1211. function setAttachment($strContent, $strFileName = 'unknown', $strMimeType = 'unknown')
  1212. {
  1213. if ( $strContent )
  1214. {
  1215. $strContent = rtrim(chunk_split(base64_encode($strContent), 76, "\r\n")); // 76 max is defined into http://tools.ietf.org/html/rfc2047
  1216. $this->_msgContent['attachment'][$strFileName]['mimeType'] = $strMimeType;
  1217. $this->_msgContent['attachment'][$strFileName]['fileName'] = $strFileName;
  1218. $this->_msgContent['attachment'][$strFileName]['data'] = $strContent;
  1219. if ( $this->getMD5flag() )
  1220. $this->_msgContent['attachment'][$strFileName]['md5'] = dol_hash($strContent, 3);
  1221. }
  1222. }
  1223. // DOL_CHANGE LDR
  1224. /**
  1225. * Image attachments are added to the content array as sub-arrays,
  1226. * allowing for multiple images for each outbound email
  1227. *
  1228. * @param string $strContent Image data to attach to message
  1229. * @param string $strImageName Image Name to give to attachment
  1230. * @param string $strMimeType Image Mime Type of attachment
  1231. * @param string $strImageCid CID
  1232. * @return void
  1233. */
  1234. function setImageInline($strContent, $strImageName = 'unknown', $strMimeType = 'unknown', $strImageCid = 'unknown')
  1235. {
  1236. if ($strContent)
  1237. {
  1238. $this->_msgContent['image'][$strImageName]['mimeType'] = $strMimeType;
  1239. $this->_msgContent['image'][$strImageName]['imageName'] = $strImageName;
  1240. $this->_msgContent['image'][$strImageName]['cid'] = $strImageCid;
  1241. $this->_msgContent['image'][$strImageName]['data'] = $strContent;
  1242. if ( $this->getMD5flag() )
  1243. $this->_msgContent['image'][$strImageName]['md5'] = dol_hash($strContent, 3);
  1244. }
  1245. }
  1246. // END DOL_CHANGE LDR
  1247. /**
  1248. * Message Content Sensitivity
  1249. * Message Sensitivity values:
  1250. * - [0] None - default
  1251. * - [1] Personal
  1252. * - [2] Private
  1253. * - [3] Company Confidential
  1254. *
  1255. * @param string $_value Message Sensitivity
  1256. * @return void
  1257. */
  1258. function setSensitivity($_value = 0)
  1259. {
  1260. if ( ( is_numeric($_value) ) &&
  1261. ( ( $_value >= 0 ) && ( $_value <= 3 ) ) )
  1262. $this->_msgSensitivity = $_value;
  1263. }
  1264. /**
  1265. * Returns Message Content Sensitivity string
  1266. * Message Sensitivity values:
  1267. * - [0] None - default
  1268. * - [1] Personal
  1269. * - [2] Private
  1270. * - [3] Company Confidential
  1271. *
  1272. * @return void
  1273. */
  1274. function getSensitivity()
  1275. {
  1276. return $this->_arySensitivity[$this->_msgSensitivity];
  1277. }
  1278. /**
  1279. * Message Content Priority
  1280. * Message Priority values:
  1281. * - [0] 'Bulk'
  1282. * - [1] 'Highest'
  1283. * - [2] 'High'
  1284. * - [3] 'Normal' - default
  1285. * - [4] 'Low'
  1286. * - [5] 'Lowest'
  1287. *
  1288. * @param string $_value Message Priority
  1289. * @return void
  1290. */
  1291. function setPriority ( $_value = 3 )
  1292. {
  1293. if ( ( is_numeric($_value) ) &&
  1294. ( ( $_value >= 0 ) && ( $_value <= 5 ) ) )
  1295. $this->_msgPriority = $_value;
  1296. }
  1297. /**
  1298. * Message Content Priority
  1299. * Message Priority values:
  1300. * - [0] 'Bulk'
  1301. * - [1] 'Highest'
  1302. * - [2] 'High'
  1303. * - [3] 'Normal' - default
  1304. * - [4] 'Low'
  1305. * - [5] 'Lowest'
  1306. *
  1307. * @return void
  1308. */
  1309. function getPriority()
  1310. {
  1311. return 'Importance: ' . $this->_aryPriority[$this->_msgPriority] . "\r\n"
  1312. . 'Priority: ' . $this->_aryPriority[$this->_msgPriority] . "\r\n"
  1313. . 'X-Priority: ' . $this->_msgPriority . ' (' . $this->_aryPriority[$this->_msgPriority] . ')' . "\r\n";
  1314. }
  1315. /**
  1316. * Set flag which determines whether to calculate message MD5 checksum.
  1317. *
  1318. * @param string $_flag Message Priority
  1319. * @return void
  1320. */
  1321. function setMD5flag($_flag = false)
  1322. {
  1323. $this->_smtpMD5 = $_flag;
  1324. }
  1325. /**
  1326. * Gets flag which determines whether to calculate message MD5 checksum.
  1327. *
  1328. * @return string Message Priority
  1329. */
  1330. function getMD5flag()
  1331. {
  1332. return $this->_smtpMD5;
  1333. }
  1334. /**
  1335. * Message X-Header Content
  1336. * This is a simple "insert". Whatever is given will be placed
  1337. * "as is" into the Xheader array.
  1338. *
  1339. * @param string $strXdata Message X-Header Content
  1340. * @return void
  1341. */
  1342. function setXheader($strXdata)
  1343. {
  1344. if ( $strXdata )
  1345. $this->_msgXheader[] = $strXdata;
  1346. }
  1347. /**
  1348. * Retrieves the Message X-Header Content
  1349. *
  1350. * @return string $_msgContent Message X-Header Content
  1351. */
  1352. function getXheader()
  1353. {
  1354. return $this->_msgXheader;
  1355. }
  1356. /**
  1357. * Generates Random string for MIME message Boundary
  1358. *
  1359. * @return void
  1360. */
  1361. function _setBoundary()
  1362. {
  1363. $this->_smtpsBoundary = "multipart_x." . time() . ".x_boundary";
  1364. $this->_smtpsRelatedBoundary = 'mul_'.dol_hash(uniqid("dolibarr2"), 3);
  1365. $this->_smtpsAlternativeBoundary = 'mul_'.dol_hash(uniqid("dolibarr3"), 3);
  1366. }
  1367. /**
  1368. * Retrieves the MIME message Boundary
  1369. *
  1370. * @param string $type Type of boundary
  1371. * @return string $_smtpsBoundary MIME message Boundary
  1372. */
  1373. function _getBoundary($type='mixed')
  1374. {
  1375. if ($type == 'mixed') return $this->_smtpsBoundary;
  1376. else if ($type == 'related') return $this->_smtpsRelatedBoundary;
  1377. else if ($type == 'alternative') return $this->_smtpsAlternativeBoundary;
  1378. }
  1379. /**
  1380. * This function has been modified as provided by SirSir to allow multiline responses when
  1381. * using SMTP Extensions
  1382. *
  1383. * @param Handler $socket Socket handler
  1384. * @param string $response Response
  1385. * @return boolean True or false
  1386. */
  1387. function server_parse($socket, $response)
  1388. {
  1389. /**
  1390. * Returns constructed SELECT Object string or boolean upon failure
  1391. * Default value is set at TRUE
  1392. */
  1393. $_retVal = true;
  1394. $server_response = '';
  1395. while ( substr($server_response,3,1) != ' ' )
  1396. {
  1397. if( !( $server_response = fgets($socket, 256) ) )
  1398. {
  1399. $this->_setErr(121, "Couldn't get mail server response codes");
  1400. $_retVal = false;
  1401. }
  1402. }
  1403. if( !( substr($server_response, 0, 3) == $response ) )
  1404. {
  1405. $this->_setErr(120, "Ran into problems sending Mail.\r\nResponse: $server_response");
  1406. $_retVal = false;
  1407. }
  1408. return $_retVal;
  1409. }
  1410. /**
  1411. * Send str
  1412. *
  1413. * @param string $_strSend String to send
  1414. * @param string $_returnCode Return code
  1415. * @param string $CRLF CRLF
  1416. * @return boolean True or false
  1417. */
  1418. function socket_send_str( $_strSend, $_returnCode = null, $CRLF = "\r\n" )
  1419. {
  1420. if ($this->_debug) $this->log.=$_strSend; // DOL_CHANGE LDR for log
  1421. fputs($this->socket, $_strSend . $CRLF);
  1422. if ($this->_debug) $this->log.=' ('.$_returnCode.')' . $CRLF;
  1423. if ( $_returnCode )
  1424. return $this->server_parse($this->socket, $_returnCode);
  1425. }
  1426. // =============================================================
  1427. // ** Error handling methods
  1428. /**
  1429. * Defines errors codes and messages for Class
  1430. *
  1431. * @param int $_errNum Error Code Number
  1432. * @param string $_errMsg Error Message
  1433. * @return void
  1434. */
  1435. function _setErr ( $_errNum, $_errMsg )
  1436. {
  1437. $this->_smtpsErrors[] = array( 'num' => $_errNum,
  1438. 'msg' => $_errMsg );
  1439. }
  1440. /**
  1441. * Returns errors codes and messages for Class
  1442. *
  1443. * @return string $_errMsg Error Message
  1444. */
  1445. function getErrors()
  1446. {
  1447. $_errMsg = array();
  1448. foreach ( $this->_smtpsErrors as $_err => $_info )
  1449. {
  1450. $_errMsg[] = 'Error [' . $_info['num'] .']: '. $_info['msg'];
  1451. }
  1452. return implode("\n", $_errMsg);
  1453. }
  1454. }
  1455. // =============================================================
  1456. // ** CSV Version Control Info
  1457. /**
  1458. * Revision 2011/09/12 07:49:59 eldy
  1459. * Doxygen
  1460. *
  1461. * Revision 2011/09/06 06:53:53 hregis
  1462. * Fix: use dol_hash instead md5 php function
  1463. *
  1464. * Revision 2011/09/03 00:14:27 eldy
  1465. * Doxygen
  1466. *
  1467. * Revision 2011/08/28 14:24:23 eldy
  1468. * Doxygen
  1469. *
  1470. * Revision 2011/07/12 22:19:02 eldy
  1471. * Fix: Attachment fails if content was empty
  1472. *
  1473. * Revision 2011/06/20 23:17:50 hregis
  1474. * Fix: use best structure of mail
  1475. *
  1476. * Revision 2010/04/13 20:58:37 eldy
  1477. * Fix: Can provide ip address on smtps. Better error reporting.
  1478. *
  1479. * Revision 2010/04/13 20:30:25 eldy
  1480. * Fix: Can provide ip address on smtps. Better error reporting.
  1481. *
  1482. * Revision 2010/01/12 13:02:07 hregis
  1483. * Fix: missing attach-files
  1484. *
  1485. * Revision 2009/11/01 14:16:30 eldy
  1486. * Fix: Sending mail with SMTPS was not working.
  1487. *
  1488. * Revision 2009/10/20 13:14:47 hregis
  1489. * Fix: function "split" is deprecated since php 5.3.0
  1490. *
  1491. * Revision 2009/05/13 19:10:07 eldy
  1492. * New: Can use inline images.Everything seems to work with thunderbird and webmail gmail. New to be tested on other mail browsers.
  1493. *
  1494. * Revision 2009/05/13 14:49:30 eldy
  1495. * Fix: Make code so much simpler and solve a lot of problem with new version.
  1496. *
  1497. * Revision 2009/02/09 00:04:35 eldy
  1498. * Added support for SMTPS protocol
  1499. *
  1500. * Revision 2008/04/16 23:11:45 eldy
  1501. * New: Add action "Test server connectivity"
  1502. *
  1503. * Revision 1.18 2007/01/12 22:17:08 ongardie
  1504. * - Added full_http_site_root() to utils-misc.php
  1505. * - Made SMTPs' getError() easier to use
  1506. * - Improved activity modified emails
  1507. *
  1508. * Revision 1.17 2006/04/05 03:15:40 ongardie
  1509. * -Fixed method name typo that resulted in a fatal error.
  1510. *
  1511. * Revision 1.16 2006/03/08 04:05:25 jswalter
  1512. * - '$_smtpsTransEncode' was removed and '$_smtpsTransEncodeType' is now used
  1513. * - '$_smtpsTransEncodeType' is defaulted to ZERO
  1514. * - corrected 'setCharSet()' internal vars
  1515. * - defined '$_mailPath'
  1516. * - added '$_smtpMD5' as a class property
  1517. * - added 'setMD5flag()' to set above property
  1518. * - added 'getMD5flag()' to retrieve above property
  1519. * - 'setAttachment()' will add an MD5 checksum to attachements if above property is set
  1520. * - 'setBodyContent()' will add an MD5 checksum to message parts if above property is set
  1521. * - 'getBodyContent()' will insert the MD5 checksum for messages and attachments if above property is set
  1522. * - removed leading dashes from message boundry
  1523. * - added propery "Close message boundry" tomessage block
  1524. * - corrected some comments in various places
  1525. * - removed some incorrect comments in others
  1526. *
  1527. * Revision 1.15 2006/02/21 02:00:07 vanmer
  1528. * - patch to add support for sending to exim mail server
  1529. * - thanks to Diego Ongaro at ETSZONE (diego@etszone.com)
  1530. *
  1531. * Revision 1.14 2005/08/29 16:22:10 jswalter
  1532. * - change 'multipart/alternative' to 'multipart/mixed', but Windows based mail servers have issues with this.
  1533. * Bug 594
  1534. *
  1535. * Revision 1.13 2005/08/21 01:57:30 vanmer
  1536. * - added initialization for array if no recipients exist
  1537. *
  1538. * Revision 1.12 2005/08/20 12:04:30 braverock
  1539. * - remove potentially binary characters from Message-ID
  1540. * - add getHost to get the hostname of the mailserver
  1541. * - add username to Message-ID header
  1542. *
  1543. * Revision 1.11 2005/08/20 11:49:48 braverock
  1544. * - fix typos in boundary
  1545. * - remove potentially illegal characters from boundary
  1546. *
  1547. * Revision 1.10 2005/08/19 20:39:32 jswalter
  1548. * - added _server_connect()' as a seperate method to handle server connectivity.
  1549. * - added '_server_authenticate()' as a seperate method to handle server authentication.
  1550. * - 'sendMsg()' now uses the new methods to handle server communication.
  1551. * - modified 'server_parse()' and 'socket_send_str()' to give error codes and messages.
  1552. *
  1553. * Revision 1.9 2005/08/19 15:40:18 jswalter
  1554. * - IMPORTANT: 'setAttachement()' is now spelled correctly: 'setAttachment()'
  1555. * - added additional comment to several methods
  1556. * - added '$_smtpsTransEncodeTypes' array to limit encode types
  1557. * - added parameters to 'sendMsg()' for future development around debugging and logging
  1558. * - added error code within 'setConfig()' if the given path is not found
  1559. * - 'setTransportType()' now has parameter validation
  1560. * [this still is not implemented]
  1561. * - 'setPort()' now does parameter validation
  1562. * - 'setTransEncode()' now has parameter validation against '$_smtpsTransEncodeTypes'
  1563. * - modified 'get_email_list()' to handle error handling
  1564. * - 'setSensitivity()' now has parameter validation
  1565. * - 'setPriority()' now has parameter validation
  1566. *
  1567. * Revision 1.8 2005/06/24 21:00:20 jswalter
  1568. * - corrected comments
  1569. * - corrected the defualt value for 'setPriority()'
  1570. * - modified 'setAttachement()' to process multiple attachments correctly
  1571. * - modified 'getBodyContent()' to handle multiple attachments
  1572. * Bug 310
  1573. *
  1574. * Revision 1.7 2005/05/19 21:12:34 braverock
  1575. * - replace chunk_split() with wordwrap() to fix funky wrapping of templates
  1576. *
  1577. * Revision 1.6 2005/04/25 04:55:06 jswalter
  1578. * - cloned from Master Version
  1579. *
  1580. * Revision 1.10 2005/04/25 04:54:10 walter
  1581. * - "fixed" 'getBodyContent()' to handle a "simple" text only message
  1582. *
  1583. * Revision 1.9 2005/04/25 03:52:01 walter
  1584. * - replace closing curly bracket. Removed it in last revision!
  1585. *
  1586. * Revision 1.8 2005/04/25 02:29:49 walter
  1587. * - added '$_transportType' and its getter/setter methods.
  1588. * for future use. NOT yet implemented.
  1589. * - in 'sendMsg()', added HOST validation check
  1590. * - added error check for initial Socket Connection
  1591. * - created new method 'socket_send_str()' to process socket
  1592. * communication in a unified means. Socket calls within
  1593. * 'sendMsg()' have been modified to use this new method.
  1594. * - expanded comments in 'setConfig()'
  1595. * - added "error" check on PHP ini file properties. If these
  1596. * properties not set within the INI file, the default values
  1597. * will be used.
  1598. * - modified 'get_RCPT_list()' to reset itself each time it is called
  1599. * - modified 'setBodyContent()' to store data in a sub-array for better
  1600. * parsing within the 'getBodyContent()' method
  1601. * - modified 'getBodyContent()' to process contents array better.
  1602. * Also modified to handle attachements.
  1603. * - added 'setAttachement()' so files and other data can be attached
  1604. * to messages
  1605. * - added '_setErr()' and 'getErrors()' as an attempt to begin an error
  1606. * handling process within this class
  1607. *
  1608. * Revision 1.7 2005/04/13 15:23:50 walter
  1609. * - made 'CC' a conditional insert
  1610. * - made 'BCC' a conditional insert
  1611. * - fixed 'Message-ID'
  1612. * - corrected 'getSensitivity()'
  1613. * - modified '$_aryPriority[]' to proper values
  1614. * - updated 'setConfig()' to handle external Ini or 'php.ini'
  1615. *
  1616. * Revision 1.6 2005/03/15 17:34:06 walter
  1617. * - corrected Message Sensitivity property and method comments
  1618. * - added array to Message Sensitivity
  1619. * - added getSensitivity() method to use new Sensitivity array
  1620. * - created seters and getter for Priority with new Prioity value array property
  1621. * - changed config file include from 'include_once'
  1622. * - modified getHeader() to ustilize new Message Sensitivity and Priorty properties
  1623. *
  1624. * Revision 1.5 2005/03/14 22:25:27 walter
  1625. * - added references
  1626. * - added Message sensitivity as a property with Getter/Setter methods
  1627. * - boundary is now a property with Getter/Setter methods
  1628. * - added 'builtRCPTlist()'
  1629. * - 'sendMsg()' now uses Object properties and methods to build message
  1630. * - 'setConfig()' to load external file
  1631. * - 'setForm()' will "strip" the email address out of "address" string
  1632. * - modifed 'getFrom()' to handle "striping" the email address
  1633. * - '_buildArrayList()' creates a multi-dimensional array of addresses
  1634. * by domain, TO, CC & BCC and then by User Name.
  1635. * - '_strip_email()' pulls email address out of "full Address" string'
  1636. * - 'get_RCPT_list()' pulls out "bare" emaill address form address array
  1637. * - 'getHeader()' builds message Header from Object properties
  1638. * - 'getBodyContent()' builds full messsage body, even multi-part
  1639. *
  1640. * Revision 1.4 2005/03/02 20:53:35 walter
  1641. * - core Setters & Getters defined
  1642. * - added additional Class Properties
  1643. *
  1644. * Revision 1.3 2005/03/02 18:51:51 walter
  1645. * - added base 'Class Properties'
  1646. *
  1647. * Revision 1.2 2005/03/01 19:37:52 walter
  1648. * - CVS logging tags
  1649. * - more comments
  1650. * - more "shell"
  1651. * - some constants
  1652. *
  1653. * Revision 1.1 2005/03/01 19:22:49 walter
  1654. * - initial commit
  1655. * - basic shell with some commets
  1656. *
  1657. */