Overview
  • Package
  • Class
  • Tree
  • Todo

Packages

  • AddonValue
    • Interfaces
  • ApiV2Controllers
  • Category
    • Collections
    • Entities
    • Factories
    • Interfaces
    • Providers
    • Repositories
    • Storages
  • Customer
    • Address
    • Country
    • CountryZone
    • Interfaces
    • Validation
    • ValueObjects
  • Email
    • Collections
    • Entities
    • Exceptions
    • Interfaces
    • Repository
    • ValueObjects
  • Http
    • Collections
    • Exceptions
    • Factories
    • Interfaces
    • ValueObjects
  • Loaders
    • CrossCuttingLoader
    • GXCoreLoader
    • Interfaces
  • None
  • Order
    • Collections
    • Entities
    • Factories
    • Interfaces
    • Repositories
    • Storages
    • ValueObjects
  • Product
    • Collections
    • Entities
    • Factories
    • Interfaces
    • Providers
    • Repositories
    • Storages
  • ProductModule
    • Collections
    • Deleter
    • Entities
    • Factories
    • Interface
    • Interfaces
    • Reader
    • Repositories
    • Writer
  • Shared
    • Exceptions
    • FileSystem
    • Interfaces
    • Storage
    • Types
  • Statistics
    • Interfaces
  • UserConfiguration
    • Interfaces
    • Repository

Classes

  • AbstractAddonValueServiceFactory
  • AbstractAddonValueStorage
  • AbstractApiV2Controller
  • AbstractCategoryServiceFactory
  • AbstractCollection
  • AbstractCustomerFactory
  • AbstractCustomerServiceFactory
  • AbstractFileStorage
  • AbstractHttpContextFactory
  • AbstractHttpViewControllerRegistryFactory
  • AbstractImagesApiV2Controller
  • AbstractOrderServiceFactory
  • AbstractProductAttributeServiceFactory
  • AbstractProductServiceFactory
  • AddonValueService
  • AddonValueServiceFactory
  • AddonValueStorageFactory
  • AddressBlock
  • AddressBookService
  • AddressClass
  • AddressesApiV2Controller
  • AddressFormatProvider
  • AdminHttpViewController
  • AdminPageHttpControllerResponse
  • Asset
  • AssetCollection
  • AttachmentCollection
  • AttachmentName
  • AttachmentPath
  • AttachmentsApiV2Controller
  • AttachmentsHandler
  • BoolType
  • CategoriesApiV2Controller
  • Category
  • CategoryAddonValueStorage
  • CategoryFactory
  • CategoryIconsApiV2Controller
  • CategoryImagesApiV2Controller
  • CategoryListItem
  • CategoryListItemCollection
  • CategoryListProvider
  • CategoryListProviderFactory
  • CategoryObjectService
  • CategoryReadService
  • CategoryRepository
  • CategoryRepositoryDeleter
  • CategoryRepositoryReader
  • CategoryRepositoryWriter
  • CategoryServiceFactory
  • CategorySettings
  • CategorySettingsRepository
  • CategorySettingsRepositoryReader
  • CategorySettingsRepositoryWriter
  • CategoryWriteService
  • ContactCollection
  • ContactName
  • ContactType
  • CountriesApiV2Controller
  • CountryService
  • CrossCuttingLoader
  • CurrencyCode
  • Customer
  • CustomerAccountInputValidator
  • CustomerAddress
  • CustomerAddressDeleter
  • CustomerAddressInputValidator
  • CustomerAddressReader
  • CustomerAddressRepository
  • CustomerAddressWriter
  • CustomerB2BStatus
  • CustomerCallNumber
  • CustomerCity
  • CustomerCompany
  • CustomerCountry
  • CustomerCountryIso2
  • CustomerCountryIso3
  • CustomerCountryName
  • CustomerCountryReader
  • CustomerCountryRepository
  • CustomerCountryZone
  • CustomerCountryZoneIsoCode
  • CustomerCountryZoneName
  • CustomerCountryZoneReader
  • CustomerCountryZoneRepository
  • CustomerDateOfBirth
  • CustomerDeleter
  • CustomerEmail
  • CustomerFactory
  • CustomerFirstname
  • CustomerGender
  • CustomerInputValidator
  • CustomerInputValidatorSettings
  • CustomerLastname
  • CustomerNumber
  • CustomerPassword
  • CustomerPostcode
  • CustomerReader
  • CustomerReadService
  • CustomerRegistrationInputValidatorService
  • CustomerRepository
  • CustomersApiV2Controller
  • CustomerService
  • CustomerServiceFactory
  • CustomerServiceSettings
  • CustomerStatusInformation
  • CustomerStatusProvider
  • CustomerStreet
  • CustomerSuburb
  • CustomerVatNumber
  • CustomerWriter
  • CustomerWriteService
  • DecimalType
  • DefaultApiV2Controller
  • EditableCollection
  • EditableKeyValueCollection
  • Email
  • EmailAddress
  • EmailAttachment
  • EmailCollection
  • EmailContact
  • EmailContent
  • EmailDeleter
  • EmailFactory
  • EmailReader
  • EmailRepository
  • EmailsApiV2Controller
  • EmailService
  • EmailStringType
  • EmailSubject
  • EmailWriter
  • EmptyCurrencyCode
  • EmptyDateTime
  • EmptyLanguageCode
  • EmptyOrderItemDownloadInformation
  • EmptyProductImage
  • EnvCategoryServiceSettings
  • EnvironmentHttpContextFactory
  • EnvironmentHttpViewControllerRegistryFactory
  • EnvProductImageFileStorageSettings
  • ExistingDirectory
  • ExistingFile
  • FilenameStringType
  • GXCoreLoader
  • GXCoreLoaderSettings
  • GXEngineOrder
  • GXEngineProduct
  • HttpApiV2Controller
  • HttpContext
  • HttpContextReader
  • HttpControllerResponse
  • HttpDispatcher
  • HttpResponseProcessor
  • HttpService
  • HttpServiceFactory
  • HttpViewController
  • HttpViewControllerFactory
  • HttpViewControllerRegistry
  • IdCollection
  • IdType
  • ImageFileStorage
  • IntType
  • JsonHttpControllerResponse
  • KeyValueCollection
  • LanguageCode
  • LegacyProductImageProcessing
  • MailerAdapter
  • NonEmptyStringType
  • OrderAddonValueStorage
  • OrderFactory
  • OrderItem
  • OrderItemAddonValueStorage
  • OrderItemAttribute
  • OrderItemAttributeCollection
  • OrderItemAttributeFactory
  • OrderItemAttributeRepository
  • OrderItemAttributeRepositoryDeleter
  • OrderItemAttributeRepositoryFactory
  • OrderItemAttributeRepositoryReader
  • OrderItemAttributeRepositoryWriter
  • OrderItemCollection
  • OrderItemDownloadInformation
  • OrderItemFactory
  • OrderItemProperty
  • OrderItemPropertyFactory
  • OrderItemPropertyRepository
  • OrderItemPropertyRepositoryDeleter
  • OrderItemPropertyRepositoryReader
  • OrderItemPropertyRepositoryWriter
  • OrderItemRepository
  • OrderItemRepositoryDeleter
  • OrderItemRepositoryReader
  • OrderItemRepositoryWriter
  • OrderListGenerator
  • OrderListItem
  • OrderListItemCollection
  • OrderObjectService
  • OrderPaymentType
  • OrderReadService
  • OrderRepository
  • OrderRepositoryDeleter
  • OrderRepositoryReader
  • OrderRepositoryWriter
  • OrdersApiV2Controller
  • OrderServiceFactory
  • OrderServiceSettings
  • OrderShippingType
  • OrdersHistoryApiV2Controller
  • OrdersItemsApiV2Controller
  • OrdersItemsAttributesApiV2Controller
  • OrderStatusHistoryListItem
  • OrderStatusHistoryListItemCollection
  • OrderStatusHistoryStorage
  • OrdersTotalsApiV2Controller
  • OrderTotal
  • OrderTotalCollection
  • OrderTotalFactory
  • OrderTotalRepository
  • OrderTotalRepositoryDeleter
  • OrderTotalRepositoryReader
  • OrderTotalRepositoryWriter
  • OrderWriteService
  • ProductAddonValueStorage
  • ProductAttribute
  • ProductAttributeCollection
  • ProductAttributeFactory
  • ProductAttributeObjectService
  • ProductAttributeRepository
  • ProductAttributeRepositoryDeleter
  • ProductAttributeRepositoryReader
  • ProductAttributeRepositoryWriter
  • ProductAttributeService
  • ProductAttributeServiceFactory
  • ProductCategoryLinker
  • ProductFactory
  • ProductImage
  • ProductImageCollection
  • ProductImageContainer
  • ProductImageContainerRepository
  • ProductImageFileStorage
  • ProductImagesApiV2Controller
  • ProductListItem
  • ProductListItemCollection
  • ProductListProvider
  • ProductListProviderFactory
  • ProductObjectService
  • ProductPermissionSetter
  • ProductReadService
  • ProductRepository
  • ProductRepositoryDeleter
  • ProductRepositoryReader
  • ProductRepositoryWriter
  • ProductsApiV2Controller
  • ProductServiceFactory
  • ProductSettings
  • ProductSettingsRepository
  • ProductSettingsRepositoryReader
  • ProductSettingsRepositoryWriter
  • ProductsLinksApiV2Controller
  • ProductWriteService
  • RedirectHttpControllerResponse
  • StaticCrossCuttingLoader
  • StaticGXCoreLoader
  • StatisticsService
  • StoredCategory
  • StoredOrderItem
  • StoredOrderItemAttribute
  • StoredOrderItemAttributeCollection
  • StoredOrderItemCollection
  • StoredOrderItemProperty
  • StoredOrderTotal
  • StoredOrderTotalCollection
  • StoredProduct
  • StoredProductAttribute
  • StoredProductAttributeCollection
  • StringCollection
  • StringType
  • UserConfigurationReader
  • UserConfigurationService
  • UserConfigurationWriter
  • VatNumberValidator
  • WritableDirectory
  • WritableFile
  • YetAnotherLanguageProvider
  • ZonesApiV2Controller

Interfaces

  • AddonValueContainerInterface
  • AddonValueServiceInterface
  • AddonValueStorageFactoryInterface
  • AddressBlockInterface
  • AddressBookServiceInterface
  • AddressClassInterface
  • AddressFormatProviderInterface
  • AssetCollectionInterface
  • AssetInterface
  • AttachmentCollectionInterface
  • AttachmentNameInterface
  • AttachmentPathInterface
  • AttachmentsHandlerInterface
  • CategoryFactoryInterface
  • CategoryInterface
  • CategoryListProviderFactoryInterface
  • CategoryListProviderInterface
  • CategoryObjectServiceInterface
  • CategoryReadServiceInterface
  • CategoryRepositoryDeleterInterface
  • CategoryRepositoryInterface
  • CategoryRepositoryReaderInterface
  • CategoryRepositoryWriterInterface
  • CategoryServiceSettingsInterface
  • CategorySettingsInterface
  • CategorySettingsRepositoryInterface
  • CategorySettingsRepositoryReaderInterface
  • CategorySettingsRepositoryWriterInterface
  • CategoryWriteServiceInterface
  • ContactCollectionInterface
  • ContactNameInterface
  • ContactTypeInterface
  • ContentViewInterface
  • CountryServiceInterface
  • CrossCuttingLoaderInterface
  • CrossCuttingObjectInterface
  • CustomerAccountInputValidatorInterface
  • CustomerAddressDeleterInterface
  • CustomerAddressInputValidatorInterface
  • CustomerAddressInterface
  • CustomerAddressReaderInterface
  • CustomerAddressRepositoryInterface
  • CustomerAddressWriterInterface
  • CustomerB2BStatusInterface
  • CustomerCallNumberInterface
  • CustomerCityInterface
  • CustomerCompanyInterface
  • CustomerCountryInterface
  • CustomerCountryIso2Interface
  • CustomerCountryIso3Interface
  • CustomerCountryNameInterface
  • CustomerCountryReaderInterface
  • CustomerCountryRepositoryInterface
  • CustomerCountryZoneInterface
  • CustomerCountryZoneIsoCodeInterface
  • CustomerCountryZoneNameInterface
  • CustomerCountryZoneReaderInterface
  • CustomerCountryZoneRepositoryInterface
  • CustomerDeleterInterface
  • CustomerEmailInterface
  • CustomerFirstnameInterface
  • CustomerGenderInterface
  • CustomerInputValidatorInterface
  • CustomerInputValidatorSettingsInterface
  • CustomerInterface
  • CustomerLastnameInterface
  • CustomerNumberInterface
  • CustomerPasswordInterface
  • CustomerPostcodeInterface
  • CustomerReaderInterface
  • CustomerReadServiceInterface
  • CustomerRegistrationInputValidatorServiceInterface
  • CustomerRepositoryInterface
  • CustomerServiceInterface
  • CustomerServiceSettingsInterface
  • CustomerStatusProviderInterface
  • CustomerStreetInterface
  • CustomerSuburbInterface
  • CustomerVatNumberInterface
  • CustomerWriterInterface
  • CustomerWriteServiceInterface
  • EmailAddressInterface
  • EmailAttachmentInterface
  • EmailCollectionInterface
  • EmailContactInterface
  • EmailContentInterface
  • EmailDeleterInterface
  • EmailFactoryInterface
  • EmailInterface
  • EmailReaderInterface
  • EmailRepositoryInterface
  • EmailServiceInterface
  • EmailSubjectInterface
  • EmailWriterInterface
  • GXCoreLoaderInterface
  • GXCoreLoaderSettingsInterface
  • HttpContextInterface
  • HttpContextReaderInterface
  • HttpControllerResponseInterface
  • HttpDispatcherInterface
  • HttpResponseProcessorInterface
  • HttpServiceFactoryInterface
  • HttpServiceInterface
  • HttpViewControllerFactoryInterface
  • HttpViewControllerInterface
  • HttpViewControllerRegistryInterface
  • IdInterface
  • LanguageProviderInterface
  • MailerAdapterInterface
  • OrderFactoryInterface
  • OrderInterface
  • OrderItemAttributeFactoryInterface
  • OrderItemAttributeInterface
  • OrderItemAttributeRepositoryDeleterInterface
  • OrderItemAttributeRepositoryFactoryInterface
  • OrderItemAttributeRepositoryInterface
  • OrderItemAttributeRepositoryReaderInterface
  • OrderItemAttributeRepositoryWriterInterface
  • OrderItemFactoryInterface
  • OrderItemInterface
  • OrderItemPropertyFactoryInterface
  • OrderItemPropertyRepositoryDeleterInterface
  • OrderItemPropertyRepositoryReaderInterface
  • OrderItemPropertyRepositoryWriterInterface
  • OrderItemRepositoryDeleterInterface
  • OrderItemRepositoryInterface
  • OrderItemRepositoryReaderInterface
  • OrderItemRepositoryWriterInterface
  • OrderListGeneratorInterface
  • OrderObjectServiceInterface
  • OrderPaymentTypeInterface
  • OrderReadServiceInterface
  • OrderRepositoryDeleterInterface
  • OrderRepositoryInterface
  • OrderRepositoryReaderInterface
  • OrderRepositoryWriterInterface
  • OrderServiceSettingsInterface
  • OrderShippingTypeInterface
  • OrderStatusHistoryReaderInterface
  • OrderStatusHistoryWriterInterface
  • OrderTotalFactoryInterface
  • OrderTotalInterface
  • OrderTotalRepositoryDeleterInterface
  • OrderTotalRepositoryInterface
  • OrderTotalRepositoryReaderInterface
  • OrderTotalRepositoryWriterInterface
  • OrderWriteServiceInterface
  • ProductAttributeFactoryInterface
  • ProductAttributeInterface
  • ProductAttributeObjectServiceInterface
  • ProductAttributeRepositoryDeleterInterface
  • ProductAttributeRepositoryInterface
  • ProductAttributeRepositoryReaderInterface
  • ProductAttributeRepositoryWriterInterface
  • ProductAttributeServiceInterface
  • ProductCategoryLinkerInterface
  • ProductFactoryInterface
  • ProductImageContainerInterface
  • ProductImageContainerRepositoryInterface
  • ProductImageInterface
  • ProductImagePathsSettingsInterface
  • ProductImageProcessingInterface
  • ProductInterface
  • ProductListProviderFactoryInterface
  • ProductListProviderInterface
  • ProductObjectServiceInterface
  • ProductPermissionSetterInterface
  • ProductReadServiceInterface
  • ProductRepositoryDeleterInterface
  • ProductRepositoryInterface
  • ProductRepositoryReaderInterface
  • ProductRepositoryWriterInterface
  • ProductSettingsInterface
  • ProductSettingsRepositoryInterface
  • ProductSettingsRepositoryReaderInterface
  • ProductSettingsRepositoryWriterInterface
  • ProductWriteServiceInterface
  • StatisticsServiceInterface
  • StoredCategoryInterface
  • StoredOrderItemAttributeInterface
  • StoredOrderItemInterface
  • StoredOrderTotalInterface
  • StoredProductAttributeInterface
  • StoredProductInterface
  • UserConfigurationReaderInterface
  • UserConfigurationServiceInterface
  • UserConfigurationWriterInterface
  • VatNumberValidatorInterface

Exceptions

  • AjaxException
  • AttachmentNotFoundException
  • FileNotFoundException
  • HttpApiV2Exception
  • MissingControllerNameException
  • UnknownEnvironmentException
  1 <?php
  2 /* --------------------------------------------------------------
  3    AttachmentsHandler.inc.php 2015-07-22 gm
  4    Gambio GmbH
  5    http://www.gambio.de
  6    Copyright (c) 2015 Gambio GmbH
  7    Released under the GNU General Public License (Version 2)
  8    [http://www.gnu.org/licenses/gpl-2.0.html]
  9    --------------------------------------------------------------
 10 */
 11 
 12 MainFactory::load_class('AttachmentsHandlerInterface');
 13 
 14 /**
 15  * Class AttachmentsHandler
 16  *
 17  * This class will handle the email attachments organization. Every email must have
 18  * its own attachments directory so that we can avoid file issues between emails.
 19  *
 20  * @category   System
 21  * @package    Email
 22  */
 23 class AttachmentsHandler implements AttachmentsHandlerInterface
 24 {
 25     /**
 26      * Full server path to "uploads" directory.
 27      *
 28      * @var string
 29      */
 30     protected $uploadsDirPath;
 31 
 32 
 33     /**
 34      * Class Constructor
 35      *
 36      * @throws InvalidArgumentException If the provided argument is not valid.
 37      *
 38      * @param string $p_uploadsDirPath Path to the server's "uploads" directory. The uploads directory
 39      *                                 must already contain a "tmp" and an "attachments" directory created
 40      *                                 by an FTP client (resolves permission problems).
 41      */
 42     public function __construct($p_uploadsDirPath)
 43     {
 44         if(empty($p_uploadsDirPath) || !is_string($p_uploadsDirPath))
 45         {
 46             throw new InvalidArgumentException('Invalid uploads path argument provided (existing path as string expected): '
 47                                                . gettype($p_uploadsDirPath));
 48         }
 49 
 50         if(!file_exists($p_uploadsDirPath))
 51         {
 52             throw new InvalidArgumentException('Provided uploads directory path does not exist in the server: '
 53                                                . $p_uploadsDirPath);
 54         }
 55         
 56         if(!file_exists($p_uploadsDirPath . '/tmp') || !file_exists($p_uploadsDirPath . '/attachments'))
 57         {
 58             throw new InvalidArgumentException('Uploads directory path must contain a "tmp" and an "attachments" directory: '
 59                                                . $p_uploadsDirPath);
 60         }
 61 
 62         $this->uploadsDirPath = rtrim((string)$p_uploadsDirPath,
 63                                       '/\t\n\r\0\x0B'); // Remove trailing slash and other chars
 64     }
 65 
 66 
 67     /**
 68      * Upload an attachment to "uploads/tmp" directory.
 69      *
 70      * This method takes the uploaded file information and places it in the "uploads/tmp" directory
 71      * as a temporary place, until the "uploadEmailCollection" moves it to the final destination.
 72      *
 73      * @param EmailAttachmentInterface $attachment Contains the file information (path is required).
 74      *
 75      * @return EmailAttachment Returns an EmailAttachment instance with the new attachment path.
 76      *
 77      * @throws Exception If method cannot copy the file from the PHP temp dir to the destination path.
 78      */
 79     public function uploadAttachment(EmailAttachmentInterface $attachment)
 80     {
 81         $name         = ($attachment->getName()
 82                          !== null) ? (string)$attachment->getName() : basename((string)$attachment->getPath());
 83         $originalName = $name;
 84         $path         = $this->uploadsDirPath . '/tmp/';
 85 
 86         // Validate uploaded file. 
 87         if(file_exists($path . $name))
 88         {
 89             // Add a counter prefix in the file name.
 90             $postfixCounter = 1;
 91             do
 92             {
 93                 if(strpos($name, '.') > -1)
 94                 {
 95                     $name = preg_replace('/\.(?=[^.]*$)/', '-' . $postfixCounter . '.', $originalName);
 96                 }
 97                 else
 98                 {
 99                     $name = $originalName . '-' . $postfixCounter;
100                 }
101                 $postfixCounter++;
102             }
103             while(file_exists($path . $name));
104         }
105 
106         // Copy file to uploads directory.
107         if(!@copy((string)$attachment->getPath(false), $path . $name))
108         {
109             throw new Exception('Could not store uploaded file: ' . (string)$attachment->getPath());
110         }
111 
112         // Return new email attachment instance.
113         $newFilePath        = $this->uploadsDirPath . '/tmp/' . $name;
114         $newAttachmentPath  = MainFactory::create('AttachmentPath', $newFilePath);
115         $newEmailAttachment = MainFactory::create('EmailAttachment', $newAttachmentPath);
116 
117         return $newEmailAttachment;
118     }
119 
120 
121     /**
122      * Removes a single email attachment.
123      *
124      * @param EmailAttachmentInterface $attachment E-Mail attachment.
125      */
126     public function deleteAttachment(EmailAttachmentInterface $attachment)
127     {
128         @unlink((string)$attachment->getPath());
129     }
130 
131 
132     /**
133      * Process attachments for each email in collection.
134      *
135      * Important! Use this method after you save the emails into the database. The reason is that
136      * this property separates each attachment file by its email ID, a value that is only accessible
137      * after the email is already saved.
138      *
139      * @param EmailCollectionInterface $collection Passed by reference, contains emails of which the
140      *                                             attachments must be processed.
141      *
142      * @deprecated Since v2.3.3.0 this method is marked as deprecated and will be removed from the class.
143      *
144      * @codeCoverageIgnore
145      */
146     public function uploadEmailCollection(EmailCollectionInterface $collection)
147     {
148         $modifiedEmailCollection = MainFactory::create('EmailCollection'); // need to return the new collection with the changed data
149 
150         foreach($collection->getArray() as $email)
151         {
152             if($email->getAttachments() !== null && count($email->getAttachments()->getArray()) > 0)
153             {
154                 if($email->getId() === null)
155                 {
156                     throw new UnexpectedValueException('Cannot process attachments without an id.');
157                 }
158 
159                 $attachmentsDirectory = $this->uploadsDirPath . '/attachments';
160 
161                 // Copy all attachments to "uploads/attachments" directory. 
162                 $modifiedAttachmentCollection = MainFactory::create('AttachmentCollection');
163 
164                 foreach($email->getAttachments()->getArray() as $attachment)
165                 {
166                     $oldAttachmentPath = (string)$attachment->getPath();
167                     $attachmentName    = (string)$attachment->getName();
168                     $newAttachmentName = (!empty($attachmentName)) ? $attachmentName : basename((string)$attachment->getPath());
169                     $newAttachmentPath = $attachmentsDirectory . '/email_id_' . (string)$email->getId() . '-'
170                                          . $newAttachmentName;
171 
172                     @copy($oldAttachmentPath, $newAttachmentPath);
173 
174                     $attachment->setPath(MainFactory::create('AttachmentPath', $newAttachmentPath));
175 
176                     // If attachment resides in the "tmp" directory remove it from the sever. 
177                     if(basename(dirname($oldAttachmentPath)) === 'tmp')
178                     {
179                         @unlink($oldAttachmentPath);
180                     }
181 
182                     $modifiedAttachmentCollection->add($attachment);
183                 }
184 
185                 $email->setAttachments($modifiedAttachmentCollection); // Replace the old attachments collection.
186                 $modifiedEmailCollection->add($email); // Add the modified email instance to the emails collection. 
187             }
188             $collection = $modifiedEmailCollection;
189         }
190     }
191 
192 
193     /**
194      * Delete attachments for each email in collection.
195      *
196      * Every email has its own attachments directory. When emails are deleted we need
197      * to remove their respective attachments.
198      *
199      * @param EmailCollectionInterface $collection Contains email records to be deleted.
200      *
201      * @deprecated Since v2.3.3.0 this method is marked as deprecated and will be removed from the class.
202      *
203      * @codeCoverageIgnore
204      */
205     public function deleteEmailCollection(EmailCollectionInterface $collection)
206     {
207         foreach($collection->getArray() as $email)
208         {
209             if($email->getAttachments() !== null)
210             {
211                 foreach($email->getAttachments()->getArray() as $attachment)
212                 {
213                     $this->deleteAttachment((string)$attachment->getPath());
214                 }
215 
216                 // Remove attachment directory for the email record. 
217                 $attachmentDirectory = $this->uploadsDirPath . '/attachments/' . (string)$email->getCreationDate()
218                                                                                                ->getTimestamp();
219                 if(file_exists($attachmentDirectory))
220                 {
221                     @rmdir($attachmentDirectory);
222                 }
223             }
224         }
225     }
226 
227 
228     /**
229      * Get attachments directory file size in bytes.
230      *
231      * @link http://stackoverflow.com/a/21409562
232      *
233      * @return int Returns the size in bytes.
234      */
235     public function getAttachmentsSize()
236     {
237         $path = realpath($this->uploadsDirPath . '/attachments');
238         $size = 0;
239 
240         if($path !== false)
241         {
242             $recursiveIterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path,
243                                                                                               FilesystemIterator::SKIP_DOTS));
244             foreach($recursiveIterator as $file)
245             {
246                 $size += $file->getSize();
247             }
248         }
249 
250         return $size;
251     }
252 
253 
254     /**
255      * Delete old attachments prior to removal date.
256      *
257      * This method will remove all the files and directories that are prior to the given date.
258      * It will return removal information so that user can see how much disc spaces was set free.
259      *
260      * @param DateTime $removalDate From this date and before the attachment files will be removed.
261      *
262      * @return array Returns an array which contains the "count" and "size" values or the operation.
263      */
264     public function deleteOldAttachments(DateTime $removalDate)
265     {
266         $removedAttachmentsCount = 0;
267         $removedAttachmentsSize  = 0; // in bytes 
268 
269         if($handle = opendir($this->uploadsDirPath . '/attachments'))
270         {
271             $directoryPath = $this->uploadsDirPath . '/attachments/*';
272             $files         = glob($directoryPath) ? : array();
273             foreach($files as $file)
274             {
275                 if(is_file($file) && $file !== 'index.html')
276                 {
277                     $lastModified = filemtime($file);
278                     if($lastModified <= $removalDate->getTimestamp())
279                     {
280                         $removedAttachmentsSize += filesize($file); // in bytes
281                         unlink($file);
282                         $removedAttachmentsCount++;
283                     }
284                 }
285             }
286 
287             closedir($handle);
288         }
289 
290         return array(
291             'count' => $removedAttachmentsCount,
292             'size'  => $removedAttachmentsSize,
293         );
294     }
295 
296 
297     /**
298      * Process email attachments.
299      *
300      * This method will move all the email attachments to the "uploads/attachments" directory
301      * and store them there for future reference and history navigation purposes. The email needs
302      * to be saved first because the email ID will be used to distinguish the emails.
303      *
304      * @param EmailInterface $email Passed by reference, contains the email data.
305      */
306     public function backupEmailAttachments(EmailInterface &$email)
307     {
308         if($email->getId() === null)
309         {
310             throw new UnexpectedValueException('Cannot process attachments without an ID value. '
311                                                . 'You should first save the email to the database and then backup '
312                                                . 'its\' attachments.');
313         }
314 
315         $modifiedAttachmentCollection = MainFactory::create('AttachmentCollection');
316 
317         foreach($email->getAttachments()->getArray() as $attachment)
318         {
319             $oldAttachmentPath = (string)$attachment->getPath();
320             $attachmentName    = (string)$attachment->getName();
321             
322             $newAttachmentName = (!empty($attachmentName)) ? $attachmentName : basename($oldAttachmentPath);
323 
324             // Remove existing "email_id_#" prefix from the email.
325             if(strpos($newAttachmentName, 'email_id_') !== false)
326             {
327                 $sanitizedAttachmentName = preg_replace('/^.*?-/', '', $newAttachmentName);
328                 if($sanitizedAttachmentName !== null)
329                 {
330                     $newAttachmentName = $sanitizedAttachmentName;
331                 }
332             }
333             
334             $newAttachmentPath = $this->uploadsDirPath . '/attachments/email_id_' . (string)$email->getId() . '-'
335                                  . $newAttachmentName;
336 
337             @copy($oldAttachmentPath, $newAttachmentPath);
338 
339             $attachment->setPath(MainFactory::create('AttachmentPath', $newAttachmentPath));
340 
341             // If attachment resides in the "tmp" directory remove it from the sever. 
342             if(basename(dirname($oldAttachmentPath)) === 'tmp')
343             {
344                 @unlink($oldAttachmentPath);
345             }
346 
347             $modifiedAttachmentCollection->add($attachment);
348         }
349     }
350 
351 
352     /**
353      * Deletes email attachments.
354      *
355      * This method will remove all the email attachments from the server.
356      *
357      * @param EmailInterface $email Contains the email information.
358      */
359     public function deleteEmailAttachments(EmailInterface $email)
360     {
361         foreach($email->getAttachments()->getArray() as $attachment)
362         {
363             if(file_exists((string)$attachment->getPath()))
364             {
365                 @unlink((string)$attachment->getPath());
366             }
367         }
368     }
369 
370 
371     /**
372      * Removes all files within the "uploads/tmp" directory.
373      *
374      * There might be cases where old unused files are left within the "tmp" directory and they
375      * need to be deleted. This function will remove all these files.
376      */
377     public function emptyTempDirectory()
378     {
379         foreach(scandir($this->uploadsDirPath . '/tmp') as $filename)
380         {
381             if($filename === '.' || $filename === '..' || $filename === 'index.html')
382             {
383                 continue;
384             }
385             
386             @unlink($this->uploadsDirPath . '/tmp/' . $filename);
387         }
388     }
389 }
API documentation generated by ApiGen