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

Packages

  • auth
  • Booking
  • cart
    • shipping
    • steppedcheckout
  • Catalog
  • 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

  • BatchProcess
  • BatchProcess_Controller
  • BouncedList
  • Newsletter
  • Newsletter_Email
  • Newsletter_Recipient
  • Newsletter_SentRecipient
  • NewsletterAdmin
  • NewsletterEmailProcess
  • NewsletterList
  • NewsletterRole
  • NewsletterType
  • ProgressBar
  • RecipientExportField
  • RecipientImportField
  • RecipientImportField_Cell
  • SubscribeForm
  • SubscribeForm_Controller
  • Unsubscribe_Controller
  • Unsubscribe_MailingListForm
  • UnsubscribedList
  • UnsubscribeRecord
  1 <?php
  2 
  3 /**
  4  * Displays a field for importing recipients.
  5  *
  6  * @package newsletter
  7  */
  8 class RecipientImportField extends FormField {
  9 
 10     protected $memberGroup;
 11     protected $memberClass;
 12     protected $tableColumns;
 13     protected $table;
 14     protected $clientFileName;
 15     protected $typeID;
 16 
 17     static $column_types = array(
 18         'Salutation' => array( 'title', 'salutation' ),
 19         'FirstName' => array( 'firstname', 'christianname', 'givenname' ),
 20         'Surname' => array( 'lastname','surname', 'familyname' ),
 21         'Email' => array( 'email', 'emailaddress' ),
 22         'Address' => array( 'address' ),
 23         'PhoneNumber' => array('phone','phonenumber'),
 24         'JobTitle' => array( 'jobtitle' ),
 25         'Organisation' => array( 'organisation', 'organization' ),
 26         'EmailType' => array( 'htmlorplaintext', 'emailtype' )
 27     );
 28 
 29     static $custom_set_fields = array();
 30 
 31     public static function setCustomField( $getMapCode, $fieldName ) {
 32         self::$custom_set_fields[] = array(
 33             'Code' => $getMapCode,
 34             'Field' => $fieldName
 35         );
 36     }
 37 
 38     function __construct( $name, $title, $memberGroup, $memberClass = 'Member', $form = null ) {
 39         $this->memberGroup = $memberGroup;
 40         $this->memberClass = $memberClass;
 41         parent::__construct( $name, $title, null, $form );
 42     }
 43 
 44     function Field() {
 45         $frameURL = Director::absoluteBaseURL() . 'admin/newsletter/displayfilefield/' . $this->typeID;
 46 
 47         return "<iframe name=\"{$this->Name}\" frameborder=\"0\" class=\"RecipientImportField\" src=\"$frameURL\"></iframe>";
 48     }
 49 
 50     function setTypeID( $id ) {
 51         $this->typeID = $id;
 52     }
 53 
 54     function CustomSetFields() {
 55         $fields = new FieldSet();
 56 
 57 
 58 
 59         foreach( self::$custom_set_fields as $customField ) {
 60             eval( '$map = ' . $customField['Code'] .';' );
 61 
 62             $noneMap = array( 0 => '(Not set)' );
 63 
 64             $map = $noneMap + $map;
 65 
 66             $fields->push( new DropdownField( 'Set['.$customField['Field'].']', $customField['Field'], $map ) );
 67         }
 68 
 69         return $fields;
 70     }
 71 
 72     /**
 73      * Returns HTML to be displayed inside the IFrame
 74      */
 75     static function fileupload() {
 76 
 77     }
 78 
 79     /**
 80      * Returns the table of results to be displayed in the table of
 81      * details loaded from the file
 82      */
 83     function displaytable() {
 84 
 85         // Check that a file was uploaded
 86         $tempFile = fopen( $_FILES['ImportFile']['tmp_name'], 'r' );
 87 
 88       // display some error if the file cannot be opened
 89         if(!$tempFile) {
 90           return 'The selected file did not arrive at the server';
 91         }
 92 
 93         $this->clientFileName = $_FILES['ImportFile']['name'];
 94 
 95         while( ( $row = fgetcsv( $tempFile ) ) !== false ) {
 96 
 97             if( !$this->tableColumns ) {
 98                 $this->parseTableHeader( $row );
 99             } else {
100                 $newRow = array();
101                 $newSessionTableRow = array();
102 
103                 foreach( $row as $cell ) {
104                     $newRow[] = $this->parseCSVCell( $cell );
105                     $newSessionTableRow[] = $cell;
106                 }
107 
108                 $cells = new DataObjectSet( $newRow );
109                 $table[] = $cells->customise( array( 'Cells' => $cells ) );
110 
111                 $sessionTable[] = $newSessionTableRow;
112             }
113         }
114 
115         fclose( $tempFile );
116 
117         $this->table = new DataObjectSet( $table );
118 
119         Session::set("ImportFile.{$_REQUEST['ID']}", $sessionTable);
120 
121         return $this->renderWith( 'Newsletter_RecipientImportField_Table' );
122     }
123 
124     /**
125      * Determines what type each column is
126      */
127     function parseTableHeader( $columns ) {
128 
129         $columnSource = array_combine(
130             array_keys( self::$column_types ),
131             array_keys( self::$column_types )
132         );
133 
134         $columnSource = array_merge( array( 'Unknown' => 'Unknown' ), $columnSource );
135         $colCount = 0;
136         foreach( $columns as $cell ) {
137             $columnType = $this->getColumnType( $this->parseCSVCell( $cell )->Value() );
138             $this->tableColumns[] = new DropdownField( 'ImportFileColumns[' . (string)( $colCount++ ) . ']', '', $columnSource, $columnType );
139         }
140     }
141 
142     function parseCSVCell( $cell ) {
143         return new RecipientImportField_Cell( $cell );
144     }
145 
146     function getColumnType( $cell ) {
147         $cell = strtolower( $cell );
148         $escapedValue = preg_replace( '/[^a-z]/', '', $cell );
149 
150         foreach( self::$column_types as $type => $aliases ) {
151             if( in_array( $escapedValue, $aliases ) )
152                 return $type;
153         }
154 
155         return 'Unknown';
156     }
157 
158     function setController( $controller ) {
159         $this->controller = $controller;
160     }
161 
162     /**
163      * Set of table column headers
164      */
165     function ColumnHeaders() {
166         return new DataObjectSet( $this->tableColumns );
167     }
168 
169     function Rows() {
170         return $this->table;
171     }
172 
173     function FileName() {
174         return $this->clientFileName;
175     }
176 
177     function TypeID() {
178         return $this->typeID;
179     }
180 }
181 
182 /**
183  * Single cell of the recipient import field
184  *
185  * @package newsletter
186  */
187 class RecipientImportField_Cell extends ViewableData {
188     protected $value;
189 
190     function __construct( $value ) {
191         $this->value = $value;
192         parent::__construct();
193     }
194 
195     function Value() {
196         return $this->value;
197     }
198 }
199 
200 /**
201  * Upload form that appears in the iframe
202  * @package cms
203  * @subpackage newsletter
204  */
205 class RecipientImportField_UploadForm extends Form {
206     function import( $data, $form ) {
207         $id = $data['ID'];
208         $mailType = DataObject::get_one("NewsletterType", "ID = $id");
209         if($mailType->GroupID)
210             $group = DataObject::get_one("Group", "ID = $mailType->GroupID");
211 
212         $recipientField = new RecipientImportField("ImportFile","Import from file", $group );
213         $recipientField->setTypeID( $id );
214 
215         // if the file is not valid, then return an error
216         if( empty( $_FILES ) || empty( $_FILES['ImportFile'] ) || $_FILES['ImportFile']['size'] == 0 )
217             return $this->customise( array( 'ID' => $id, "UploadForm" => $this->controller->UploadForm( $id ), 'ErrorMessage' => 'Please choose a CSV file to import' ) )->renderWith('Newsletter_RecipientImportField');
218         elseif( !$this->isValidCSV( $_FILES['ImportFile'] ) ) {
219             /*if( file_exists( $_FILES['ImportFile']['tmp_name'] ) ) unlink( $_FILES['ImportFile']['tmp_name'] );
220             unset( $_FILES['ImportFile'] );*/
221             return $this->customise( array( 'ID' => $id, "UploadForm" => $this->controller->UploadForm( $id ), 'ErrorMessage' => 'The selected file was not a CSV file' ) )->renderWith('Newsletter_RecipientImportField');
222         } else
223             return $recipientField->displaytable();
224     }
225 
226     function isValidCSV( $file ) {
227         return preg_match( '/.*\.csv$/i', $file['name'] ) > 0;
228     }
229 
230     function confirm( $data, $form ) {
231         $id = $data['ID'];
232         $mailType = DataObject::get_one("NewsletterType", "ID = $id");
233         if($mailType->GroupID)
234             $group = DataObject::get_one("Group", "ID = $mailType->GroupID");
235         // @TODO Look into seeing if $data['Set'] should be removed since it seems to be undefined
236         return $this->importMembers( $id, $group, $data['ImportFileColumns'], (isset($data['Set']) ? $data['Set'] : array()));
237     }
238 
239     function cancel( $data, $form ) {
240         $newForm = $this->controller->UploadForm( $data['ID'] );
241         return $newForm->forTemplate();
242     }
243 
244     function action_import( $data, $form ) {
245         return $this->import( $data, $form );
246     }
247 
248     function action_confirm( $data, $form ) {
249         return $this->confirm( $data, $form );
250     }
251 
252     function action_cancel( $data, $form ) {
253         return $this->cancel( $data, $form );
254     }
255 
256     /**
257      * Import members from the uploaded file
258      */
259     protected function importMembers( $id, $group, $cols, $setFields, $primaryColType = 'Email' ) {
260 
261         $startTime = time();
262 
263         $importData = Session::get("ImportFile.{$id}");
264 
265         $validColumns = array_keys( RecipientImportField::$column_types );
266 
267         $columnMap = array_flip( $cols );
268 
269         // Debug::show($columnMap);
270 
271         // locate the primary column's index
272         $primaryColumn = /*array_search( $primaryColType, $validColumns );*/ $columnMap[$primaryColType];
273 
274         // changed fields
275         $changedFields = array();
276 
277         // intersect the list of valid columns with the column map to find the columns we need
278         $importColumns = array_intersect( $validColumns, $cols );
279 
280         // statistics
281         $newMembers = 0;
282         $changedMembers = 0;
283         $skippedMembers = 0;
284 
285         // the class that the imported members will become
286         $newMemberClass = Object::getCustomClass( 'Member' );
287 
288         // for each row, add a new member or overwrite an existing member
289         foreach( $importData as $newMemberRow ) {
290 
291             // skip rows with an empty value for the primary column
292             if( empty( $newMemberRow[$primaryColumn] ) ) {
293                 $skippedMembers++;
294                 continue;
295             }
296 
297             // remember to check if the user has unsubscribed
298             $trackChanges = true;
299 
300             // TODO: Write DataObject::update
301             $member = $this->findMember( $newMemberRow[$primaryColumn] );
302 
303             if( !$member ) {
304                 $newMembers++;
305                 $trackChanges = false;
306                 $member = Object::create("Member");
307             } else {
308                 // skip this member if the are unsubscribed
309                 if( $member->Unsubscribed ) {
310                     $skippedMembers++;
311                     continue;
312                 }
313 
314                 if( $member->class != $newMemberClass )
315                     $member->setClassName( $newMemberClass );
316 
317                 $changedMembers++;
318             }
319 
320             // add each of the valid columns
321             foreach( $importColumns as $datum ) {
322 
323                 // perform any required conversions
324                 $newValue = trim( $newMemberRow[$columnMap[$datum]] );
325                 $oldValue = trim( $member->$datum );
326 
327                 // Debug::message( "$datum@{$columnMap[$datum]}" );
328 
329                 // track the modifications to the member data
330                 if( $trackChanges && $newValue != $oldValue && $datum != $primaryColumn ) {
331                     $changedFields[] = array(
332                         $newMemberRow[$primaryColumn],
333                         "$datum:\n$oldValue",
334                         "$datum:\n$newValue"
335                     );
336 
337                     $numChangedFields++;
338                 }
339 
340                 $member->$datum = $newValue;
341             }
342 
343             // set any set fields
344             if( $setFields )
345                 foreach( $setFields as $fieldName => $fieldValue )
346                     $member->$fieldName = $fieldValue;
347 
348             // add member to group
349             $member->write();
350             $member->Groups()->add( $group->ID );
351         }
352 
353         $numChangedFields = count( $changedFields );
354         $this->notifyChanges( $changedFields );
355 
356         // TODO Refresh window
357         $customData = array(
358             'ID' => $id,
359             "UploadForm" => $this->controller->UploadForm( $id ),
360             'ImportMessage' => 'Imported new members',
361             'NewMembers' => (string)$newMembers,
362             'ChangedMembers' => (string)$changedMembers,
363             'ChangedFields' => (string)$numChangedFields,
364             'SkippedRecords' => (string)$skippedMembers,
365             'Time' => time() - $startTime
366         );
367         return $this->customise( $customData )->renderWith('Newsletter_RecipientImportField');
368     }
369 
370     function findMember( $email ) {
371         $email = addslashes( $email );
372         if(defined('DB::USE_ANSI_SQL')) {
373             return DataObject::get_one( 'Member', "\"Email\"='$email'" );
374         } else {
375             return DataObject::get_one( 'Member', "`Email`='$email'" );
376         }
377     }
378 
379     function notifyChanges( $changes ) {
380         $email = new Email( Email::getAdminEmail(), Email::getAdminEmail(), 'Changed Fields' );
381 
382         $body = "";
383 
384         foreach( $changes as $change ) {
385             $body .= "-------------------------------\n";
386             $body .= implode( ' ', $change ) . "\n";
387         }
388 
389         $email->setBody( $body );
390         $email->send();
391     }
392 }
393 ?>
[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.1 API Docs API documentation generated by ApiGen 2.8.0