Joostina CMS / CMF v2.* API
  • Docs
  • Package
  • Class
  • Tree
  • Todo
Overview

Packages

  • Components
    • Acls
      • Models
        • Admin
        • Site
    • BlogCategory
      • Models
        • Admin
        • Site
    • Blogs
      • Controllers
        • Admin
        • Site
      • Helpers
      • Models
        • Admin
        • Site
    • Coder
      • Controllers
        • Admin
      • Models
        • Admin
    • Comments
      • Controllers
        • Admin
        • Site
      • Helpers
      • Models
        • Admin
        • Site
    • CommentsCounter
      • Models
        • Admin
        • Site
    • Mainpage
      • Controllers
        • Site
    • News
      • Controllers
        • Admin
        • Site
      • Helpers
      • Models
        • Admin
        • Site
    • Pages
      • Controllers
        • Admin
        • Site
      • Models
        • Site
    • Search
      • Controllers
        • Site
    • Site
      • Controllers
        • Admin
        • Site
    • Sitemap
      • Controllers
        • Admin
        • Site
      • Models
        • Admin
        • Site
    • Test
      • Controllers
        • Site
    • Torrents
      • Controllers
        • Site
    • Users
      • Controllers
        • Admin
        • Site
      • Models
        • Admin
        • Site
  • Compression
  • Core
    • Libraries
      • Arhive
      • Array
      • Attached
      • Autoadmin
      • Autoloader
      • Benchmark
      • Breadcrumbs
      • Cache
      • Config
      • Cookie
      • Csrf
      • Database
        • Drivers
          • Interfaces
      • Datetime
      • Debug
      • Editor
      • Events
      • File
      • Filter
      • Flashmessage
      • Folder
      • Hit
      • Html
      • Image
      • Inflector
      • Inputfilter
      • Libraries
      • Mail
      • Module
      • Nestedset
      • Pager
      • Pages
      • Params
      • Randomizer
      • Request
      • RobotLoader
      • Route
      • Security
      • Session
      • Static
      • String
      • Text
      • Trash
      • Validate
  • Email
  • Extra
    • Libraries
      • Basket
  • Joostina
    • Controller
    • Core
    • Document
  • JSMin
  • Libraries
    • Extra
      • Basket
        • Models
          • Site
  • None
  • Plugins
    • Autoadmin
    • Editor
    • Sitemap
  • SimpleMail
  • Vendors
    • Libraries
      • Email

Classes

  • SimpleMail
  1: <?php
  2: 
  3: /**
  4:  * This function is used to transform the given text into quoted printable format
  5:  * In fact the decode function exists in Php core, but not the encode ...
  6:  *
  7:  * @param String $sStr
  8:  *
  9:  * @return String
 10:  */
 11: if (!function_exists ('quoted_printable_encode')) {
 12:     public function quoted_printable_encode ($sStr)
 13:     {
 14:         return str_replace ("%", "=", rawurlencode ($sStr));
 15:     }
 16: }
 17: /**
 18:  * Used to send basic or complex emails
 19:  *
 20:  * @package SimpleMail
 21:  * @filesource SimpleMail.php
 22:  *
 23:  * @author Cyril Nicodème
 24:  * @version 0.1
 25:  *
 26:  * @since 09/07/2008
 27:  *
 28:  * @license GNU/GPL
 29:  */
 30: class SimpleMail
 31: {
 32:     /**
 33:      * @var Array $_aProperties
 34:      * Contain the property for the email
 35:      */
 36:     private $_aProperties = array ( 'XPriority'                 => 3,   // To 1 (High) at 5 (Low), 3 is the common
 37:                                 'Sender'                    => '',  // Default is FROM value
 38:                                 'ReplyTo'               => '',  // Default is FROM value, Reply to this email
 39:                                 'ReturnPath'                => '',  // Default is FROM value, Mail for delivery failed response
 40:                                 'From'                  => '',
 41:                                 'To'                    => array (),
 42:                                 'Cc'                    => array (),
 43:                                 'Bcc'                   => array (),
 44:                                 'DispositionNotificationTo' => '',
 45:                                 'XMailer'               => 'MyPrettySociety Mailer',
 46:                                 'Organisation'          => 'MyPrettySociety',
 47:                                 'Date'                  => '',
 48:                                 'MimeVersion'               => '1.0',
 49:                                 'Subject'               => '',
 50:                                 'AbuseContact'              => '',
 51:                                 'Charset'                   => 'Utf-8',
 52:                                 'Bodies'                    => array (),
 53:                                 'Attachment'                => array ()
 54:                                 );
 55: 
 56:     /**
 57:      * @var String $_sBreakLine
 58:      * Breakline style
 59:      */
 60:     private $_sBreakLine = "\n";
 61: 
 62:     /**
 63:      * Constructor. Set the Date and optionnaly some properties
 64:      *
 65:      * @param Array $aProperties (Optionnal) : The properties to set more quickly
 66:      */
 67:     public function __construct ($aProperties = null)
 68:     {
 69:         if (!function_exists ('mail'))
 70:             throw new Exception ('Function "mail" must exists to use this class');
 71: 
 72:         $this->_aProperties['Date'] = date("D, j M Y H:i:s -0600");
 73: 
 74:         if (isset ($aProperties)) {
 75:             foreach ($aProperties as $sKey=>$mProperty) {
 76:                 $this->__set ($sKey, $mProperty);
 77:             }
 78:         }
 79:     }
 80: 
 81:     /**
 82:      * Magic Method setter.
 83:      * Set the properties easily
 84:      *
 85:      * @param String $sKey   : The name of the property
 86:      * @param Mixed  $mValue : The value to set
 87:      *
 88:      * @return Void
 89:      */
 90:     public function __set ($sKey, $mValue)
 91:     {
 92:         if (is_int ($this->_aProperties[$sKey]) && !is_int ($mValue))
 93:             throw new Exception ('Invalid type, must be an Int');
 94:         else if (is_string ($this->_aProperties[$sKey]) && !is_string ($mValue))
 95:             throw new Exception ('Invalid type, must be an String');
 96:         else if (is_array ($this->_aProperties[$sKey]) && !is_array ($mValue))
 97:             throw new Exception ('Invalid type, must be an String');
 98:         else {
 99:             $this->_aProperties[$sKey] = $mValue;
100:         }
101:     }
102: 
103:     /**
104:      * Magic Method getter.
105:      * Retrieve the property nicely
106:      *
107:      * @param String $sKey : The name of the property to retrieve
108:      *
109:      * @return Mixed
110:      */
111:     public function __get ($sKey)
112:     {
113:         if (!isset ($this->_aProperties[$sKey]))
114:             throw new Exception ('Invalid key "'.$sKey.'"');
115: 
116:         return $this->_aProperties[$sKey];
117:     }
118: 
119:     /**
120:      * Add an attachment to the email (will be found on Multipart/mixed)
121:      *
122:      * @param String       $sFilePath : The path of the file to send
123:      * @param String       $sType     (Optionnal, default set to 'Application/Octet-Stream') : The content Type
124:      * @param String       $sFileName (Optionnal) : The filename to display for the recipient
125:      * @param iCompression $oCompress (Optionnal) : An instance of iCompress Class for compress the file
126:      *
127:      * @return Void
128:      */
129:     public function addAttachment ($sFilePath, $sType = 'Application/Octet-Stream', $sFileName = null, iCompression $oCompress = null, $sCid = null)
130:     {
131:         if (!file_exists ($sFilePath) || !is_readable ($sFilePath))
132:             throw new Exception ('The file "'.$sFilePath.'" is unreadable.');
133: 
134:         if (!is_string ($sType))
135:             throw new Exception ('Type must be a String');
136: 
137:         if (!isset ($sFileName))
138:             $sFileName = substr ($sFilePath, strrpos ($sFilePath, '/'));
139:         else if (!is_string ($sFileName))
140:             throw new Exception ('Filename must be a String');
141: 
142:         $sContent = file_get_contents ($sFilePath);
143: 
144:         if (isset ($oCompress))
145:             $sContent = $oCompress->compress ($sContent);
146: 
147:         $iCountAttachments = count ($this->_aProperties['Attachment']);
148: 
149:         $this->_aProperties['Attachment'][$iCountAttachments]['ContentType'] = $sType;
150:         $this->_aProperties['Attachment'][$iCountAttachments]['ContentTransfertEncoding'] = 'base64';
151:         $this->_aProperties['Attachment'][$iCountAttachments]['ContentDisposition'] = (isset ($sCid)) ? 'inline' : 'attachment';
152:         $this->_aProperties['Attachment'][$iCountAttachments]['Filename'] = $sFileName;
153: 
154:         if (isset ($sCid))
155:             $this->_aProperties['Attachment'][$iCountAttachments]['Content-ID'] = $sCid;
156: 
157:         $this->_aProperties['Attachment'][$iCountAttachments]['Content'] = chunk_split (base64_encode ($sContent));
158:     }
159: 
160:     /**
161:      * Add a text to the email
162:      *
163:      * @param String $sBody    : The text to add
164:      * @param String $sType    (Optionnal, default to 'text/plain') : The content type
165:      * @param String $sCharset (Optionnal, default to 'Utf-8') : The Charset
166:      *
167:      * @return Void
168:      */
169:     public function addBody ($sBody, $sType = 'text/plain', $sCharset = null)
170:     {
171:         if (!is_string ($sBody))
172:             throw new Exception ('Body must be a String');
173: 
174:         if (!is_string ($sType))
175:             throw new Exception ('Type must be a String');
176: 
177:         if (!isset ($sCharset))
178:             $sCharset = $this->_aProperties['Charset'];
179: 
180:         if (!is_string ($sCharset))
181:             throw new Exception ('Charset must be a String');
182: 
183:         $iCountBodies = count ($this->_aProperties['Bodies']);
184: 
185:         $this->_aProperties['Bodies'][$iCountBodies]['ContentType'] = $sType;
186:         $this->_aProperties['Bodies'][$iCountBodies]['Charset'] = $sCharset;
187:         $this->_aProperties['Bodies'][$iCountBodies]['ContentTransfertEncoding'] = 'quoted-printable';
188:         $this->_aProperties['Bodies'][$iCountBodies]['ContentDisposition'] = 'inline';
189: 
190:         if ($sType == 'text/html')
191:             $sBody = preg_replace_callback ('#src[\ ]*=[\ ]*["|\']([^"|\']*)["|\']#i', array ($this, 'inlineAttachment'), $sBody);
192: 
193:         $this->_aProperties['Bodies'][$iCountBodies]['Content'] = quoted_printable_encode (chunk_split ($sBody, 76, $this->_sBreakLine));
194:     }
195: 
196:     /**
197:      * Send an Email after checking the kind of structure (Normal, Multipart/Alternative, Multipart/Mixed, etc)
198:      *
199:      * @return Void
200:      */
201:     public function send ()
202:     {
203:         if (count ($this->_aProperties['To']) == 0 && count ($this->_aProperties['Cc']) == 0 && count ($this->_aProperties['Bcc']) == 0)
204:             throw new Exception ('You need to specify at least one recipient (To, Cc or Bcc)');
205: 
206:         $iCountBodies = count ($this->_aProperties['Bodies']);
207:         $iCountAttachments = count ($this->_aProperties['Attachment']);
208: 
209:         if (($iCountBodies + $iCountAttachments) == 1) { // Qu'un seul truc !
210:             $sHeaders = $this->_createHeaders ();
211: 
212:             if ($iCountBodies == 1)
213:                 $sHeaders .= $this->_createSection ($this->_aProperties['Bodies'][0]);
214:             else
215:                 $sHeaders .= $this->_createSection ($this->_aProperties['Attachment'][0]);
216: 
217:             $sHeaders .= $this->_sBreakLine.$this->_sBreakLine;
218: 
219:         } elseif ($iCountBodies == 1 && $iCountAttachments > 0) { // Mixed
220:             $sBoundary = $this->_boundaryGenerate ();
221: 
222:             $sHeaders = $this->_createHeaders ();
223: 
224:             $sHeaders .= 'Content-Type: multipart/mixed;'.$this->_sBreakLine."\t".'boundary="'.$sBoundary.'"'.$this->_sBreakLine.$this->_sBreakLine;
225: 
226:             $sHeaders .= $this->_createSection ($this->_aProperties['Bodies'][0], $sBoundary);
227: 
228:             foreach ($this->_aProperties['Attachment'] as $aAttachment) {
229:                 $sHeaders .= $this->_createSection ($aAttachment, $sBoundary);
230:             }
231: 
232:             $sHeaders .= '--'.$sBoundary.'--'.$this->_sBreakLine.$this->_sBreakLine;
233:         } elseif ($iCountBodies > 1 && $iCountAttachments == 0) { // Alternative
234:             $sBoundary = $this->_boundaryGenerate ();
235: 
236:             $sHeaders = $this->_createHeaders ();
237: 
238:             $sHeaders .= 'Content-Type: multipart/alternative;'.$this->_sBreakLine."\t".'boundary="'.$sBoundary.'"'.$this->_sBreakLine.$this->_sBreakLine;
239: 
240:             foreach ($this->_aProperties['Bodies'] as $aBody) {
241:                 $sHeaders .= $this->_createSection ($aBody, $sBoundary);
242:             }
243: 
244:             $sHeaders .= '--'.$sBoundary.'--'.$this->_sBreakLine.$this->_sBreakLine;
245:         } elseif ($iCountBodies > 1 && $iCountAttachments >= 1) { // Mixed + Alternative
246:             $sMixedBoundary = $this->_boundaryGenerate ();
247:             $sAlternativeBoundary = $this->_boundaryGenerate ();
248: 
249:             $sHeaders = $this->_createHeaders ();
250: 
251:             $sAlternativeBody = 'Content-Type: multipart/alternative;'.$this->_sBreakLine."\t".'boundary="'.$sAlternativeBoundary.'"'.$this->_sBreakLine.$this->_sBreakLine;
252: 
253:             foreach ($this->_aProperties['Bodies'] as $aBody) {
254:                 $sAlternativeBody .= $this->_createSection ($aBody, $sAlternativeBoundary);
255:             }
256: 
257:             $sAlternativeBody .= '--'.$sAlternativeBoundary.'--'.$this->_sBreakLine.$this->_sBreakLine;
258: 
259:             $sHeaders .= 'Content-Type: multipart/mixed;'.$this->_sBreakLine."\t".'boundary="'.$sMixedBoundary.'"'.$this->_sBreakLine.$this->_sBreakLine;
260: 
261:             $sHeaders .= '--'.$sMixedBoundary.$this->_sBreakLine;
262:             $sHeaders .= $sAlternativeBody;
263: 
264:             foreach ($this->_aProperties['Attachment'] as $aAttachment) {
265:                 $sHeaders .= $this->_createSection ($aAttachment, $sMixedBoundary);
266:             }
267: 
268:             $sHeaders .= '--'.$sMixedBoundary.'--'.$this->_sBreakLine.$this->_sBreakLine;
269:         } else
270:             throw new Exception ('Invalid Email structure');
271: 
272:         $sSubject = '=?'.$this->_aProperties['Charset'].'?q?'.quoted_printable_encode ($this->_aProperties['Subject']).'?=';
273: 
274:         if (@mail (implode (', ', $this->_aProperties['To']), $sSubject, '', $sHeaders) === false)
275:             throw new Exception ('An error occured while sending the email');
276:     }
277: 
278:     /**
279:      * Modify the src="" element to be joined with the mail as an inline statement
280:      *
281:      * @param Array $aMatches
282:      *
283:      * @return String
284:      */
285:     public function inlineAttachment ($aMatches)
286:     {
287:         $sCID = $this->_cidGenerate ();
288:         try {
289:             $this->addAttachment ($aMatches[1], MimeType::get ($aMatches[1]), null, null, $sCID);
290: 
291:             return 'src="cid:'.$sCID.'"';
292:         } catch (Exception $oE) {
293:             return $aMatches[0];
294:         }
295:     }
296: 
297:     /**
298:      * Create the headers with the values specified in the $_aProperties array
299:      *
300:      * @return String
301:      */
302:     private function _createHeaders ()
303:     {
304:         if (empty ($this->_aProperties['From']))
305:             throw new Exception ('From must be set !');
306: 
307:         if (empty ($this->_aProperties['ReplyTo']))
308:             $this->_aProperties['ReplyTo'] = $this->_aProperties['From'];
309: 
310:         if (empty ($this->_aProperties['ReturnPath']))
311:             $this->_aProperties['ReturnPath'] = $this->_aProperties['From'];
312: 
313:         if (empty ($this->_aProperties['Sender']))
314:             $this->_aProperties['Sender'] = $this->_aProperties['From'];
315: 
316:         $sHeaders = 'X-Priority: '.$this->_aProperties['XPriority'].$this->_sBreakLine;
317:         $sHeaders .= 'X-Mailer: '.$this->_aProperties['XMailer'].$this->_sBreakLine;
318:         $sHeaders .= 'Organisation: '.$this->_aProperties['Organisation'].$this->_sBreakLine;
319:         $sHeaders .= 'Date: '.$this->_aProperties['Date'].$this->_sBreakLine;
320:         $sHeaders .= 'MIME-version: '.$this->_aProperties['MimeVersion'].$this->_sBreakLine;
321:         $sHeaders .= 'From: '.$this->_aProperties['From'].$this->_sBreakLine;
322:         $sHeaders .= 'Reply-To: '.$this->_aProperties['ReplyTo'].$this->_sBreakLine;
323:         $sHeaders .= 'Return-Path: '.$this->_aProperties['ReturnPath'].$this->_sBreakLine;
324:         $sHeaders .= 'Sender: '.$this->_aProperties['Sender'].$this->_sBreakLine;
325:         $sHeaders .= 'X-Sender: '.$this->_aProperties['Sender'].$this->_sBreakLine;
326:         //$sHeaders .= 'Subject: '.$this->_aProperties['Subject'].$this->_sBreakLine;
327: 
328:         if (!empty ($this->_aProperties['DispositionNotificationTo'])) {
329:             $sHeaders .= 'Disposition-Notification-To: '.$this->_aProperties['DispositionNotificationTo'].$this->_sBreakLine;
330:             $sHeaders .= 'X-Confirm-Reading-To: '.$this->_aProperties['DispositionNotificationTo'].$this->_sBreakLine;
331:             $sHeaders .= 'Return-receipt-to: '.$this->_aProperties['DispositionNotificationTo'].$this->_sBreakLine;
332:         }
333: 
334:         if (!empty ($this->_aProperties['AbuseContact'])) {
335:             $sHeaders .= 'X-abuse-contact: '.$this->_aProperties['AbuseContact'].$this->_sBreakLine;
336:         }
337: /*
338:         if (count ($this->_aProperties['To']) > 0)
339:             $sHeaders .= 'To:'.implode (',', $this->_aProperties['To']).$this->_sBreakLine;
340: */
341:         if (count ($this->_aProperties['Cc']) > 0)
342:             $sHeaders .= 'Cc:'.implode (',', $this->_aProperties['Cc']).$this->_sBreakLine;
343: 
344:         if (count ($this->_aProperties['Bcc']) > 0)
345:             $sHeaders .= 'Bcc:'.implode (',', $this->_aProperties['Bcc']).$this->_sBreakLine;
346: 
347:         return $sHeaders;
348:     }
349: 
350:     /**
351:      * Create a section for the email
352:      *
353:      * @param Array  $aElement  : The element informations and content
354:      * @param String $sBoundary (Optionnal) : The boundary to delimite the parts of the email
355:      *
356:      * @return String
357:      */
358:     private function _createSection ($aElement, $sBoundary = null)
359:     {
360:         $sMessage = '';
361:         if (isset ($sBoundary))
362:             $sMessage = '--'.$sBoundary.$this->_sBreakLine;
363: 
364:         $sMessage .= 'Content-Type: '.$aElement['ContentType'];
365: 
366:         if (!empty ($aElement['Charset']))
367:             $sMessage .= '; charset="'.$aElement['Charset'].'"';
368:         else if ($aElement['ContentTransfertEncoding'] == 'base64')
369:             $sMessage .= '; name="'.$aElement['Filename'].'"';
370: 
371:         $sMessage .= $this->_sBreakLine;
372:         $sMessage .= 'Content-Transfer-Encoding: '.$aElement['ContentTransfertEncoding'].$this->_sBreakLine;
373:         $sMessage .= 'Content-Disposition: '.$aElement['ContentDisposition'];
374: 
375:         if (!empty ($aElement['Filename']))
376:             $sMessage .= '; filename="'.$aElement['Filename'].'"';
377: 
378:         $sMessage .= $this->_sBreakLine;
379: 
380:         if (!empty ($aElement['Content-ID']))
381:             $sMessage .= 'Content-ID: <'.$aElement['Content-ID'].'>'.$this->_sBreakLine;
382: 
383: 
384:         $sMessage .= $this->_sBreakLine;
385:         $sMessage .= $aElement['Content'].$this->_sBreakLine.$this->_sBreakLine;
386: 
387:         return $sMessage;
388:     }
389: 
390:     /**
391:      * Generate a Boundary
392:      *
393:      * @return String
394:      */
395:     private function _boundaryGenerate ()
396:     {
397:         return '---=Part_'.md5 (uniqid (mt_rand ()));
398:     }
399: 
400:     /**
401:      * Generate a CID
402:      *
403:      * @return String
404:      */
405:     private function _cidGenerate ()
406:     {
407:         return 'CID_'.md5 (uniqid (mt_rand ()));
408:     }
409: }
410: 
Joostina CMS / CMF v2.* API API documentation generated by ApiGen 2.6.1 – Template adapted by @olvlv and Joostina Team