Webylon 3.2 API Docs
  • Package
  • Function
  • Tree
  • Deprecated
  • Download
Version: current
  • 3.2
  • 3.1

Packages

  • 1c
    • exchange
      • catalog
  • auth
  • Booking
  • building
    • company
  • cart
    • shipping
    • steppedcheckout
  • Catalog
    • monument
  • cms
    • assets
    • batchaction
    • batchactions
    • bulkloading
    • comments
    • content
    • core
    • export
    • newsletter
    • publishers
    • reports
    • security
    • tasks
  • Dashboard
  • DataObjectManager
  • event
  • faq
  • forms
    • actions
    • core
    • fields-basic
    • fields-dataless
    • fields-datetime
    • fields-files
    • fields-formatted
    • fields-formattedinput
    • fields-relational
    • fields-structural
    • transformations
    • validators
  • googlesitemaps
  • guestbook
  • installer
  • newsletter
  • None
  • photo
    • gallery
  • PHP
  • polls
  • recaptcha
  • sapphire
    • api
    • bulkloading
    • control
    • core
    • cron
    • dev
    • email
    • fields-formattedinput
    • filesystem
    • formatters
    • forms
    • i18n
    • integration
    • misc
    • model
    • parsers
    • search
    • security
    • tasks
    • testing
    • tools
    • validation
    • view
    • widgets
  • seo
    • open
      • graph
  • sfDateTimePlugin
  • spamprotection
  • stealth
    • captha
  • subsites
  • userform
    • pagetypes
  • userforms
  • webylon
  • widgets

Classes

  • Address
  • AddSubsiteTask
  • Announcement
  • AnnouncementDecorator
  • AnnouncementHolder
  • AssociatedFolderDecorator
  • AttachedFiles
  • AudioPhpCaptcha
  • AutoCompleteField
  • Base1CExchanger
  • BookingOrder_StatusLog
  • CalendarUtil
  • CalendarWidgetExtention
  • CatalogCatalogLinkedDecorator
  • CatalogOldFieldsDecorator
  • CatalogProductLinkedDecorator
  • CheckoutStep_ShippingMethod
  • ChequePayment
  • ClearHistoryTask
  • ClientEmailOrderNotification_SiteConfig
  • ClientVKOrderNotification_SiteConfig
  • CommentsSiteConfig
  • ContactsPage
  • CookieExtention
  • CostTableShippingRate
  • CustomMenu
  • CustomMenuAdmin
  • CustomMenuDecorator
  • CustomMenuHolder
  • CustomMenuItem
  • CustomPayment
  • DataObjectLoggerExtension
  • DataObjectSubsites
  • DefaultCMSActionDecorator
  • DocPage
  • DocumentDirection
  • DocumentHaving
  • DocumentSearchForm
  • DocumentSiteConfig
  • DocumentsPage
  • DocumentType
  • DOMUtil
  • ExtendPageAnnouncement
  • ExtendPagePoll
  • FavoriteExtention
  • FavoritePage
  • FavoriteProductMemberExtention
  • FavoriteProducts
  • FileOversizeDecorator
  • FindCyrillicSiteConfig
  • FolderRenameTask
  • GDMergeAlpha
  • HomePage
  • ImageAutoResize
  • ImageResizeTask
  • ImportCatalog1C_Importer
  • ImportCatalogSiteConfig
  • ImportSiteConfig
  • LoggerAdmin
  • LogItem
  • ManagerEmailOrderNotification_SiteConfig
  • MapObject
  • MapObjectGroup
  • MapPage
  • MediawebForm
  • MemberLoggerExtension
  • MonumentsSiteConfig
  • MultiUploadConfig
  • NearestEventExtention
  • NewDocumentsAdmin
  • NewsArchive
  • NewsEntry
  • NewsHolder
  • NewsSiteConfig
  • Order_StatusLog
  • Orders1CExchange_Exporter
  • PageHideFieldsExtension
  • PageInformerRates
  • PageInformerWeather
  • Payment_Failure
  • Payment_Processing
  • Payment_Result
  • Payment_Success
  • PaymentMethod
  • PaymentSiteConfig
  • PayPalPayment
  • PayPalPayment_Handler
  • PhoneField
  • PhotoAlbumExtentions
  • PhpCaptcha
  • PhpCaptchaColour
  • PhpCaptchaField
  • phpMorphy
  • phpMorphy_AncodesResolver_AsIs
  • phpMorphy_AncodesResolver_Proxy
  • phpMorphy_AncodesResolver_ToDialingAncodes
  • phpMorphy_AncodesResolver_ToText
  • phpMorphy_AnnotDecoder_Base
  • phpMorphy_AnnotDecoder_Common
  • phpMorphy_AnnotDecoder_Factory
  • phpMorphy_AnnotDecoder_Predict
  • phpMorphy_FilesBundle
  • phpMorphy_Fsa
  • phpMorphy_Fsa_Decorator
  • phpMorphy_Fsa_Proxy
  • phpMorphy_Fsa_Sparse_File
  • phpMorphy_Fsa_Sparse_Mem
  • phpMorphy_Fsa_Sparse_Shm
  • phpMorphy_Fsa_Tree_File
  • phpMorphy_Fsa_Tree_Mem
  • phpMorphy_Fsa_Tree_Shm
  • phpMorphy_Fsa_WordsCollector
  • phpMorphy_GramInfo
  • phpMorphy_GramInfo_AncodeCache
  • phpMorphy_GramInfo_Decorator
  • phpMorphy_Graminfo_File
  • phpMorphy_Graminfo_Mem
  • phpMorphy_GramInfo_Proxy
  • phpMorphy_GramInfo_Proxy_WithHeader
  • phpMorphy_GramInfo_RuntimeCaching
  • phpMorphy_Graminfo_Shm
  • phpMorphy_GrammemsProvider_Base
  • phpMorphy_GrammemsProvider_Decorator
  • phpMorphy_GrammemsProvider_Empty
  • phpMorphy_GrammemsProvider_Factory
  • phpMorphy_GrammemsProvider_ForFactory
  • phpMorphy_GrammemsProvider_ru_RU
  • phpMorphy_GramTab
  • phpMorphy_GramTab_Empty
  • phpMorphy_GramTab_Proxy
  • phpMorphy_Link
  • phpMorphy_Link_Annot
  • phpMorphy_Link_Base
  • phpMorphy_Morphier_Base
  • phpMorphy_Morphier_Bulk
  • phpMorphy_Morphier_Common
  • phpMorphy_Morphier_Empty
  • phpMorphy_Morphier_Finder_Base
  • phpMorphy_Morphier_Finder_Common
  • phpMorphy_Morphier_Finder_Predict_Databse
  • phpMorphy_Morphier_Finder_Predict_Suffix
  • phpMorphy_Morphier_Helper
  • phpMorphy_Morphier_Predict_Database
  • phpMorphy_Morphier_Predict_Suffix
  • phpMorphy_Morphier_PredictCollector
  • phpMorphy_Semaphore
  • phpMorphy_Semaphore_Empty
  • phpMorphy_Semaphore_Nix
  • phpMorphy_Semaphore_Win
  • phpMorphy_Shm_Cache
  • phpMorphy_Shm_Cache_FileDescriptor
  • phpMorphy_Shm_Header
  • phpMorphy_Source_Dba
  • phpMorphy_Source_Fsa
  • phpMorphy_State
  • phpMorphy_Storage
  • phpMorphy_Storage_Factory
  • phpMorphy_Storage_File
  • phpMorphy_Storage_Mem
  • phpMorphy_Storage_Proxy
  • phpMorphy_Storage_Shm
  • phpMorphy_UnicodeHelper
  • phpMorphy_UnicodeHelper_Base
  • phpMorphy_UnicodeHelper_MultiByteFixed
  • phpMorphy_UnicodeHelper_singlebyte
  • phpMorphy_UnicodeHelper_ucs_2be
  • phpMorphy_UnicodeHelper_ucs_2le
  • phpMorphy_UnicodeHelper_ucs_4be
  • phpMorphy_UnicodeHelper_ucs_4le
  • phpMorphy_UnicodeHelper_utf_16_Base
  • phpMorphy_UnicodeHelper_utf_16be
  • phpMorphy_UnicodeHelper_utf_16le
  • phpMorphy_UnicodeHelper_utf_32_Base
  • phpMorphy_UnicodeHelper_utf_32be
  • phpMorphy_UnicodeHelper_utf_32le
  • phpMorphy_UnicodeHelper_utf_8
  • phpMorphy_WordDescriptor
  • phpMorphy_WordDescriptor_Collection
  • phpMorphy_WordDescriptor_Collection_Serializer
  • phpMorphy_WordForm
  • ProductCatalogImportTask
  • ProductOldFieldsDecorator
  • ProductParamValue_BoolValueField
  • ProductParamValue_MultiValueField
  • ProductParamValue_MultiValueSetField
  • ProductParamValue_ValueField
  • ProductProductLinkedDecorator
  • PublHolder
  • Publication
  • PublicationSiteTree
  • RatingDataObject
  • RatingExtension
  • RealtySiteConfigDecorator
  • RecentComments
  • RecentFiles
  • RecentPages
  • RelatedPageLink
  • RoomRate_PriceField
  • RussianUpLower
  • SberbankPayment
  • SberbankPayment_Handler
  • SetMainSiteHomePageTypeTask
  • ShippingEstimator
  • ShippingPackage
  • ShowUserFromExtension
  • ShowViewedProductExtention
  • SiteConfigDecorator
  • SiteConfigSubsites
  • SiteTreeSubsites
  • SMSCOrderNotification_SiteConfig
  • SMSOrderNotification_SiteConfig
  • Socle
  • SocleSize
  • SortCMSActionDecorator
  • SS_Report_FakeQuery
  • SSMorphy
  • SSNController
  • SteppedCheckout_PageMessages
  • SubpageListField
  • SubscribeFormAllPagesExtension
  • SubsiteDropdownField
  • SubsiteReportWrapper
  • TableShippingRate
  • UnitellerPayment
  • UnitellerPayment_Handler
  • UnmoderatedComments
  • VAT
  • VideoManager
  • VideoSiteConfig
  • ViewedProductExtention
  • WatermarkImage
  • WatermarkSiteConfig
  • WeightTableShippingRate
  • XMLValidate
  • YaMoneyPayment
  • YaMoneyPayment_Handler
  • YMLExporter
  • YMLSiteConfig

Interfaces

  • PaymentObjectInterface
  • phpMorphy_AncodesResolver_Interface
  • phpMorphy_AnnotDecoder_Interface
  • phpMorphy_Fsa_Interface
  • phpMorphy_GramInfo_Interace
  • phpMorphy_GrammemsProvider_Interface
  • phpMorphy_GramTab_Interface
  • phpMorphy_Morphier_Finder_Interface
  • phpMorphy_Morphier_Interface
  • phpMorphy_Shm_Cache_Interface
  • phpMorphy_Source_Interface

Exceptions

  • phpMorphy_Exception

Functions

  • column_sort
  • column_sort_callback_basic
  • encodeFileForEmail
  • encodeMultipart
  • getMimeType
  • htmlEmail
  • loadMimeTypes
  • phpmorphy_overload_mb_funcs
  • plaintextEmail
  • processHeaders
  • QuotedPrintable_encode
  • supressOutput
  • validEmailAddr
  • wrapImagesInline
  • wrapImagesInline_rewriter
  1 <?php
  2 /**
  3  * Mailer objects are responsible for actually sending emails.
  4  * The default Mailer class will use PHP's mail() function.
  5  * 
  6  * @package sapphire
  7  * @subpackage email
  8  */
  9 class Mailer extends Object {
 10         
 11     /**
 12      * Отправитель для тех случаев когда пиьсмо не принимается
 13      */
 14     protected static $fallback_sender = 'trash@mediaweb.ru';
 15     
 16     static function set_fallback_sender($value) {
 17         self::$fallback_sender = validEmailAddr($value);
 18     }
 19     
 20     static function get_fallback_sender() {
 21         return self::$fallback_sender;
 22     }
 23 
 24     /**
 25      * Mail encoding
 26      */
 27     protected static $encoding ='base64';
 28 
 29     static function set_encoding($val) {
 30         if ($val == 'base64' || $val == '8bit' || $val == '') {
 31             self::$encoding = $val;
 32         }
 33         else {
 34             die("Unsupported mail encoding: '$val'");
 35         }
 36     }
 37 
 38     static function get_encoding() {
 39         return self::$encoding;
 40     }
 41     
 42     /**
 43      * Send a plain-text email.
 44      *  
 45      * @param string $to
 46      * @param string $from
 47      * @param string §subject
 48      * @param string $plainContent
 49      * @param bool $attachedFiles
 50      * @param array $customheaders
 51      * @return bool
 52      */
 53     function sendPlain($to, $from, $subject, $plainContent, $attachedFiles = false, $customheaders = false) {
 54         return plaintextEmail($to, $from, $subject, $plainContent, $attachedFiles, $customheaders);
 55     }
 56     
 57     /**
 58      * Send a multi-part HTML email.
 59      * 
 60      * @return bool
 61      */
 62     function sendHTML($to, $from, $subject, $htmlContent, $attachedFiles = false, $customheaders = false, $plainContent = false, $inlineImages = false) {
 63         return htmlEmail($to, $from, $subject, $htmlContent, $attachedFiles, $customheaders, $plainContent, $inlineImages);
 64     }
 65 
 66     /**
 67      * Заменяет отправителя в заголовках письма
 68      * 
 69      * @param mixed $headers    строка или массив с заголовками письма
 70      * @param string $sender    новый отправитель (по-умолчанию @link Mailer::get_fallback_sender())
 71      * 
 72      * @return mixed    обновленные заголовки
 73      */
 74     static function replace_sender($headers, $sender = false) {
 75         if (!$sender) 
 76             $sender = self::get_fallback_sender();
 77         
 78         // $sender may be a just email like 'user@domain.com' or have human name like '"User Name" <user@domain.com>'
 79         // Add hostname if not human name in $sender
 80         if (isset($_SERVER['HTTP_HOST']) && strpos($sender, '<') === false)
 81             $sender = sprintf('"%s" <%s>', $_SERVER['HTTP_HOST'], $sender);
 82         
 83         return preg_replace('/(From|Sender): .*/i', '$1: ' . validEmailAddr($sender), $headers);
 84     }
 85 }
 86 
 87 // TO DO: Clean this code up, make it more OO.
 88 // For now, we've just put a clean interface around this dirty code :)
 89 
 90 /*
 91  * Sends an email as a both HTML and plaintext
 92  *   $attachedFiles should be an array of file names
 93  *    - if you pass the entire $_FILES entry, the user-uploaded filename will be preserved
 94  *   use $plainContent to override default plain-content generation
 95  * 
 96  * @return bool
 97  */
 98 function htmlEmail($to, $from, $subject, $htmlContent, $attachedFiles = false, $customheaders = false, $plainContent = false, $inlineImages = false) {
 99     if ($customheaders && is_array($customheaders) == false) {
100         echo "htmlEmail($to, $from, $subject, ...) could not send mail: improper \$customheaders passed:<BR>";
101         dieprintr($headers);
102     }
103 
104     $from = validEmailAddr($from);
105     $to = validEmailAddr($to);
106     
107     $subjectIsUnicode = true;
108     $bodyIsUnicode = true;
109     $plainEncoding = Mailer::get_encoding();
110     
111     // We generate plaintext content by default, but you can pass custom stuff
112     if(!$plainContent) {
113         $plainContent = Convert::xml2raw($htmlContent);
114     }
115 
116 
117     // If the subject line contains extended characters, we must encode the 
118     $subject = Convert::xml2raw($subject);
119     if(isset($subjectIsUnicode) && $subjectIsUnicode)
120         $subject = "=?UTF-8?B?" . base64_encode($subject) . "?=";
121 
122 
123     // Make the plain text part
124     $headers["Content-Type"] = "text/plain; charset=\"utf-8\"";
125     $headers["Content-Transfer-Encoding"] = $plainEncoding ? $plainEncoding : "8bit";
126 
127     $plainPart = processHeaders($headers, ($plainEncoding == "base64") ? chunk_split(base64_encode($plainContent),60) : wordwrap($plainContent,120));
128 
129     // Make the HTML part
130     $headers["Content-Type"] = "text/html; charset=\"utf-8\"";
131         
132     
133     // Add basic wrapper tags if the body tag hasn't been given
134     if(stripos($htmlContent, '<body') === false) {
135         $htmlContent =
136             "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\">\n" .
137             "<HTML><HEAD>\n" .
138             "<META http-equiv=Content-Type content=\"text/html; charset=utf-8\">\n" .
139             "<STYLE type=3Dtext/css></STYLE>\n\n".
140             "</HEAD>\n" .
141             "<BODY bgColor=#ffffff>\n" .
142                 $htmlContent .
143             "\n</BODY>\n" .
144             "</HTML>";
145     }
146 
147     if($inlineImages) {
148         $htmlPart = wrapImagesInline($htmlContent);
149     } else {
150         $headers["Content-Transfer-Encoding"] = $plainEncoding ? $plainEncoding : "8bit";
151         $htmlPart = processHeaders($headers, ($plainEncoding == "base64") ? chunk_split(base64_encode($htmlContent),120) : wordwrap($htmlContent,120));
152 //      $headers["Content-Transfer-Encoding"] = "base64";
153 //      $htmlPart = processHeaders($headers, chunk_split(base64_encode($htmlContent),120));
154     }
155     
156     list($messageBody, $messageHeaders) = encodeMultipart(array($plainPart,$htmlPart), "multipart/alternative");
157 
158     // Messages with attachments are handled differently
159     if($attachedFiles && is_array($attachedFiles)) {
160         
161         // The first part is the message itself
162         $fullMessage = processHeaders($messageHeaders, $messageBody);
163         $messageParts = array($fullMessage);
164 
165         // Include any specified attachments as additional parts
166         foreach($attachedFiles as $file) {
167             if(isset($file['tmp_name']) && isset($file['name'])) {
168                 $messageParts[] = encodeFileForEmail($file['tmp_name'], $file['name']);
169             } else {
170                 $messageParts[] = encodeFileForEmail($file);
171             }
172         }
173             
174         // We further wrap all of this into another multipart block
175         list($fullBody, $headers) = encodeMultipart($messageParts, "multipart/mixed");
176 
177     // Messages without attachments do not require such treatment
178     } else {
179         $headers = $messageHeaders;
180         $fullBody = $messageBody;
181     }
182 
183     // Email headers
184     $headers["From"] = $from;
185     $headers["Reply-To"] = $from;
186 
187     // Messages with the X-SilverStripeMessageID header can be tracked
188     if(isset($customheaders["X-SilverStripeMessageID"]) && defined('BOUNCE_EMAIL')) {
189             $bounceAddress = BOUNCE_EMAIL;
190     } else {
191             $bounceAddress = $from;
192     }
193 
194     // Strip the human name from the bounce address
195     if(ereg('^([^<>]*)<([^<>]+)> *$', $bounceAddress, $parts)) $bounceAddress = $parts[2];  
196     
197     // $headers["Sender"]       = $from;
198     $headers["X-Mailer"]    = X_MAILER;
199     if (!isset($customheaders["X-Priority"])) $headers["X-Priority"]    = 3;
200     
201     $headers = array_merge((array)$headers, (array)$customheaders);
202 
203     // the carbon copy header has to be 'Cc', not 'CC' or 'cc' -- ensure this.
204     if (isset($headers['CC'])) { $headers['Cc'] = $headers['CC']; unset($headers['CC']); }
205     if (isset($headers['cc'])) { $headers['Cc'] = $headers['cc']; unset($headers['cc']); }
206     
207     // the carbon copy header has to be 'Bcc', not 'BCC' or 'bcc' -- ensure this.
208     if (isset($headers['BCC'])) {$headers['Bcc']=$headers['BCC']; unset($headers['BCC']); }
209     if (isset($headers['bcc'])) {$headers['Bcc']=$headers['bcc']; unset($headers['bcc']); }
210         
211     // Send the email
212     $headers = processHeaders($headers);
213     
214     // Try it without the -f option if it fails
215     if (!($result = @mail($to, $subject, $fullBody, $headers, "-f$bounceAddress"))) {
216         $result = mail($to, $subject, $fullBody, Mailer::replace_sender($headers));
217     }
218     
219     return $result;
220 }
221 
222 /*
223  * Send a plain text e-mail
224  */
225 function plaintextEmail($to, $from, $subject, $plainContent, $attachedFiles, $customheaders = false) {
226     $subjectIsUnicode = false;
227     $plainEncoding = Mailer::get_encoding();
228 
229     if ($customheaders && is_array($customheaders) == false) {
230         echo "htmlEmail($to, $from, $subject, ...) could not send mail: improper \$customheaders passed:<BR>";
231         dieprintr($headers);
232     }
233 
234     $from = validEmailAddr($from);
235     $to = validEmailAddr($to);
236     
237     if(strpos($subject,"&#") !== false) $subjectIsUnicode = true;
238 
239     // If the subject line contains extended characters, we must encode it
240     $subject = Convert::xml2raw($subject);
241     if($subjectIsUnicode)
242         $subject = "=?UTF-8?B?" . base64_encode($subject) . "?=";
243 
244 
245     // Make the plain text part
246     $headers["Content-Type"] = "text/plain; charset=\"utf-8\"";
247     $headers["Content-Transfer-Encoding"] = $plainEncoding ? $plainEncoding : '8bit';
248 
249     $plainContent = ($plainEncoding == "base64") ? chunk_split(base64_encode($plainContent),60) : wordwrap($plainContent, 120);
250 
251     // Messages with attachments are handled differently
252     if(is_array($attachedFiles)) {
253         // The first part is the message itself
254         $fullMessage = processHeaders($headers, $plainContent);
255         $messageParts = array($fullMessage);
256 
257         // Include any specified attachments as additional parts
258         foreach($attachedFiles as $file) {
259             if(isset($file['tmp_name']) && isset($file['name'])) {
260                 $messageParts[] = encodeFileForEmail($file['tmp_name'], $file['name']);
261             } else {
262                 $messageParts[] = encodeFileForEmail($file);
263             }
264         }
265         
266 
267         // We further wrap all of this into another multipart block
268         list($fullBody, $headers) = encodeMultipart($messageParts, "multipart/mixed");
269 
270     // Messages without attachments do not require such treatment
271     } else {
272         $fullBody = $plainContent;
273     }
274 
275     // Email headers
276     $headers["From"] = $from;
277     $headers["Reply-To"] = $from;
278 
279     // Messages with the X-SilverStripeMessageID header can be tracked
280     if(isset($customheaders["X-SilverStripeMessageID"]) && defined('BOUNCE_EMAIL')) {       
281         $bounceAddress = BOUNCE_EMAIL;
282         // Get the human name from the from address, if there is one
283         if(ereg('^([^<>]+)<([^<>])> *$', $from, $parts))
284             $bounceAddress = "$parts[1]<$bounceAddress>";
285     } else {
286         $bounceAddress = $from;
287     }
288     
289     // $headers["Sender"]       = $from;
290     $headers["X-Mailer"]    = X_MAILER;
291     if(!isset($customheaders["X-Priority"])) {
292         $headers["X-Priority"]  = 3;
293     }
294     
295     $headers = array_merge((array)$headers, (array)$customheaders);
296 
297     // the carbon copy header has to be 'Cc', not 'CC' or 'cc' -- ensure this.
298     if (isset($headers['CC'])) { $headers['Cc'] = $headers['CC']; unset($headers['CC']); }
299     if (isset($headers['cc'])) { $headers['Cc'] = $headers['cc']; unset($headers['cc']); }
300         
301     // Send the email
302     $headers = processHeaders($headers);
303 
304     // Try it without the -f option if it fails
305     if(!$result = @mail($to, $subject, $fullBody, $headers, "-f$bounceAddress")) {
306         $result = mail($to, $subject, $fullBody, Mailer::replace_sender($headers));
307     }
308     
309     return $result;
310 }
311 
312 
313 function encodeMultipart($parts, $contentType, $headers = false) {
314     $separator = "----=_NextPart_" . ereg_replace('[^0-9]','',rand() * 10000000000);
315 
316 
317     $headers["MIME-Version"] = "1.0";
318     $headers["Content-Type"] = "$contentType; boundary=\"$separator\"";
319     $headers["Content-Transfer-Encoding"] = "8bit";
320 
321     if($contentType == "multipart/alternative") {
322         //$baseMessage = "This is an encoded HTML message.  There are two parts: a plain text and an HTML message, open whatever suits you better.";
323         $baseMessage = "\nThis is a multi-part message in MIME format.";
324     } else {
325         //$baseMessage = "This is a message containing attachments.  The e-mail body is contained in the first attachment";
326         $baseMessage = "\nThis is a multi-part message in MIME format.";
327     }
328 
329 
330     $separator = "\n--$separator\n";
331     $body = "$baseMessage\n" .
332         $separator . implode("\n".$separator, $parts) . "\n" . trim($separator) . "--";
333 
334     return array($body, $headers);
335 }
336 
337 /*
338  * Return a multipart/related e-mail chunk for the given HTML message and its linked images
339  * Decodes absolute URLs, accessing the appropriate local images
340  */
341 function wrapImagesInline($htmlContent) {
342     global $_INLINED_IMAGES;
343     $_INLINED_IMAGES = null;
344     
345     $replacedContent = imageRewriter($htmlContent, 'wrapImagesInline_rewriter($URL)');
346     
347     
348     // Make the HTML part
349     $headers["Content-Type"] = "text/html; charset=\"utf-8\"";
350     $headers["Content-Transfer-Encoding"] = "quoted-printable";
351     $multiparts[] = processHeaders($headers, QuotedPrintable_encode($replacedContent));
352     
353     // Make all the image parts     
354     global $_INLINED_IMAGES;
355     foreach($_INLINED_IMAGES as $url => $cid) {
356         $multiparts[] = encodeFileForEmail($url, false, "inline", "Content-ID: <$cid>\n");      
357     }
358 
359     // Merge together in a multipart
360     list($body, $headers) = encodeMultipart($multiparts, "multipart/related");
361     return processHeaders($headers, $body);
362 }
363 function wrapImagesInline_rewriter($url) {
364     $url = relativiseURL($url);
365     
366     global $_INLINED_IMAGES;
367     if(!$_INLINED_IMAGES[$url]) {
368         $identifier = "automatedmessage." . rand(1000,1000000000) . "@silverstripe.com";
369         $_INLINED_IMAGES[$url] = $identifier;
370     }
371     return "cid:" . $_INLINED_IMAGES[$url];
372     
373 }
374 
375 /*
376  * Combine headers w/ the body into a single string.
377  */
378 function processHeaders($headers, $body = false) {
379     $res = '';
380     if(is_array($headers)) while(list($k, $v) = each($headers))
381         $res .= "$k: $v\n";
382     if($body) $res .= "\n$body";
383     return $res;
384 }
385 
386 /**
387  * Encode the contents of a file for emailing, including headers
388  * 
389  * $file can be an array, in which case it expects these members:
390  *   'filename'        - the filename of the file
391  *   'contents'        - the raw binary contents of the file as a string
392  *  and can optionally include these members:
393  *   'mimetype'        - the mimetype of the file (calculated from filename if missing)
394  *   'contentLocation' - the 'Content-Location' header value for the file
395  *   
396  * $file can also be a string, in which case it is assumed to be the filename
397  * 
398  * h5. contentLocation
399  * 
400  * Content Location is one of the two methods allowed for embedding images into an html email. It's also the simplest, and best supported
401  * 
402  * Assume we have an email with this in the body:
403  * 
404  *   <img src="http://example.com/image.gif" />
405  * 
406  * To display the image, an email viewer would have to download the image from the web every time it is displayed. Due to privacy issues, most
407  * viewers will not display any images unless the user clicks 'Show images in this email'. Not optimal.
408  * 
409  * However, we can also include a copy of this image as an attached file in the email. By giving it a contentLocation of "http://example.com/image.gif"
410  * most email viewers will use this attached copy instead of downloading it. Better, most viewers will show it without a 'Show images in this email'
411  * conformation.
412  * 
413  * Here is an example of passing this information through Email.php:
414  * 
415  *   $email = new Email();
416  *   $email->attachments[] = array(
417  *     'filename' => BASE_PATH . "/themes/mytheme/images/header.gif",
418  *     'contents' => file_get_contents(BASE_PATH . "/themes/mytheme/images/header.gif"),
419  *     'mimetype' => 'image/gif',
420  *     'contentLocation' => Director::absoluteBaseURL() . "/themes/mytheme/images/header.gif"
421  *   );
422  * 
423  */
424 function encodeFileForEmail($file, $destFileName = false, $disposition = NULL, $extraHeaders = "") {    
425     if(!$file) {
426         user_error("encodeFileForEmail: not passed a filename and/or data", E_USER_WARNING);
427         return;
428     }
429     
430     if (is_string($file)) {
431         $file = array('filename' => $file);
432         $fh = fopen($file['filename'], "rb");
433         if ($fh) {
434             while(!feof($fh)) $file['contents'] .= fread($fh, 10000);   
435             fclose($fh);
436         }
437     }
438 
439     // Build headers, including content type
440     if(!$destFileName) $base = basename($file['filename']);
441     else $base = $destFileName;
442 
443     $mimeType = $file['mimetype'] ? $file['mimetype'] : getMimeType($file['filename']);
444     if(!$mimeType) $mimeType = "application/unknown";
445         
446     if (empty($disposition)) $disposition = isset($file['contentLocation']) ? 'inline' : 'attachment';
447     
448     // Encode for emailing
449     if (substr($file['mimetype'], 0, 4) != 'text') {
450         $encoding = "base64";
451         $file['contents'] = chunk_split(base64_encode($file['contents']));
452     } else {
453         // This mime type is needed, otherwise some clients will show it as an inline attachment
454         $mimeType = 'application/octet-stream';
455         $encoding = "quoted-printable";     
456         $file['contents'] = QuotedPrintable_encode($file['contents']);      
457     }
458 
459     $headers = "Content-type: $mimeType;\n\tname=\"$base\"\n".
460                "Content-Transfer-Encoding: $encoding\n".
461                "Content-Disposition: $disposition;\n\tfilename=\"$base\"\n" ;
462     
463     if ( isset($file['contentLocation']) ) $headers .= 'Content-Location: ' . $file['contentLocation'] . "\n" ;
464     
465     $headers .= $extraHeaders . "\n";
466 
467     // Return completed packet
468     return $headers . $file['contents'];
469 }
470 
471 function QuotedPrintable_encode($quotprint) {       
472         $quotprint = (string) str_replace('\r\n',chr(13).chr(10),$quotprint);
473         $quotprint = (string) str_replace('\n',  chr(13).chr(10),$quotprint);
474         $quotprint = (string) preg_replace("~([\x01-\x1F\x3D\x7F-\xFF])~e", "sprintf('=%02X', ord('\\1'))", $quotprint);
475         //$quotprint = (string) str_replace('\=0D=0A',"=0D=0A",$quotprint);
476         $quotprint = (string) str_replace('=0D=0A',"\n",$quotprint);    
477         $quotprint = (string) str_replace('=0A=0D',"\n",$quotprint);    
478         $quotprint = (string) str_replace('=0D',"\n",$quotprint);   
479         $quotprint = (string) str_replace('=0A',"\n",$quotprint);   
480         return (string) $quotprint;
481 }
482 
483 function validEmailAddr($emailAddress) {
484     $emailAddress = trim($emailAddress);
485     $angBrack = strpos($emailAddress, '<');
486     
487     if($angBrack === 0) {
488         $emailAddress = substr($emailAddress, 1, strpos($emailAddress,'>')-1);
489         
490     } else if($angBrack) {      
491         $emailAddress = str_replace('@', '', substr($emailAddress, 0, $angBrack))
492                             .substr($emailAddress, $angBrack);
493     }
494     
495     return $emailAddress;
496 }
497 
498 /*
499  * Get mime type based on extension
500  */
501 function getMimeType($filename) {
502     global $global_mimetypes;
503     if(!$global_mimetypes) loadMimeTypes();
504     $ext = strtolower(substr($filename,strrpos($filename,'.')+1));
505     return isset($global_mimetypes[$ext]) ? $global_mimetypes[$ext] : 'application/octet-stream';
506 }
507 
508 /*
509  * Load the mime-type data from the system file
510  */
511 function loadMimeTypes() {
512     $mimetypePathCustom = '/etc/mime.types';
513     $mimetypePathGeneric = Director::baseFolder() . '/sapphire/email/mime.types';
514     $mimeTypes = file_exists($mimetypePathGeneric) ?  file($mimetypePathGeneric) : file($mimetypePathCustom);
515     foreach($mimeTypes as $typeSpec) {
516         if(($typeSpec = trim($typeSpec)) && substr($typeSpec,0,1) != "#") {
517             $parts = preg_split("/[ \t\r\n]+/", $typeSpec);
518             if(sizeof($parts) > 1) {
519                 $mimeType = array_shift($parts);
520                 foreach($parts as $ext) {
521                     $ext = strtolower($ext);
522                     $mimeData[$ext] = $mimeType;
523                 }
524             }
525         }
526     }
527 
528     global $global_mimetypes;
529     $global_mimetypes = $mimeData;
530     return $mimeData;
531 }
532 
533 
[Raise a SilverStripe Framework issue/bug](https://github.com/silverstripe/silverstripe-framework/issues/new)
- [Raise a SilverStripe CMS issue/bug](https://github.com/silverstripe/silverstripe-cms/issues/new)
- Please use the Silverstripe Forums to ask development related questions. -
Webylon 3.2 API Docs API documentation generated by ApiGen 2.8.0