API CHANGE Moving newsletter functionality to its own module

git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/cms/trunk@52939 467b73ca-7a2a-4603-9d3b-597d59a354a9
This commit is contained in:
Ingo Schommer 2008-04-17 10:34:37 +00:00
parent e607848e9b
commit b1920529f8
29 changed files with 0 additions and 4115 deletions

View File

@ -10,7 +10,6 @@ Director::addRules(50, array(
'cms' => '->admin',
'admin/security/$Action/$ID/$OtherID' => 'SecurityAdmin',
'admin/help/$Action/$ID' => 'CMSHelp',
'admin/newsletter/$Action/$ID' => 'NewsletterAdmin',
'admin/reports/$Action/$ID' => 'ReportAdmin',
'admin/assets/$Action/$ID' => 'AssetAdmin',
'admin/comments/$Action' => 'CommentAdmin',
@ -18,7 +17,6 @@ Director::addRules(50, array(
'admin/bulkload/$Action/$ID/$OtherID' => 'BulkLoaderAdmin',
'admin/ImageEditor/$Action' => 'ImageEditor',
'admin/$Action/$ID/$OtherID' => 'CMSMain',
'unsubscribe/$Email/$MailingList' => 'Unsubscribe_Controller'
));
// Built-in modules

View File

@ -853,12 +853,6 @@ JS;
"admin/assets/",
"AssetAdmin"
);
self::add_menu_item(
"newsletter",
_t('LeftAndMain.NEWSLETTERS',"Newsletters",PR_HIGH,"Menu title"),
"admin/newsletter/",
"NewsletterAdmin"
);
if(ReportAdmin::has_reports()) {
self::add_menu_item(
"report",

View File

@ -1,106 +0,0 @@
<?php
/**
* @package cms
* @subpackage newsletter
*/
/**
* Create a process in session which is incremented to calls from the client
* @package cms
* @subpackage newsletter
*/
class BatchProcess extends Object {
protected $objects;
protected $current;
protected $id;
protected $scriptOutput = true;
function __construct( $collection ) {
$this->current = 0;
if( $collection ) {
if( is_array( $collection ) )
$this->objects = $collection;
elseif( is_a( $collection, 'DataObjectSet' ) ) {
$this->objects = $collection->toArray();
} else
$this->objects = array( $collection );
}
}
function runToCompletion() {
$this->scriptOutput = false;
$this->current = 0;
$ignore = $this->next( count( $this->objects ) );
$this->complete();
}
function getID() {
return $this->id;
}
function next() {
self::addProcess( $this );
return $this->id.':'.$this->current.'/'.count( $this->objects );
}
function start() {
$this->current = 0;
$this->id = self::generateID();
if( !$this->objects || count( $this->objects ) === 0 )
return $this->complete();
return $this->next();
}
function complete() {
self::removeProcess( $this );
}
static function generateID() {
return count(Session::get('BatchProcesses')) + 1;
}
static function addProcess( $process ) {
Session::set('BatchProcesses.' . ($process->getID() - 1), serialize($process));
}
static function removeProcess( $process ) {
Session::clear('BatchProcesses.' . ($process->getID() - 1));
}
}
/**
* Controller for calling the batch processes via Ajax.
* @package cms
* @subpackage newsletter
*/
class BatchProcess_Controller extends Controller {
function next() {
$processID = $this->urlParams['ID'];
if( !$processID ) {
return _t('BatchProcess_Controller.ERROR', 'ERROR: Could not continue process');
}
$process = unserialize(Session::get('BatchProcesses.' . ($this->urlParams['ID'] - 1)));
if( !$process ) {
return _t('BatchProcess_Controller.ERROR', 'ERROR:Could not continue process');
}
if( $this->urlParams['Batch'] )
return $process->next( $this->urlParams['Batch'] );
else
return $process->next();
}
}
?>

View File

@ -1,58 +0,0 @@
<?php
/**
* @package cms
* @subpackage newsletter
*/
/**
* Form field showing a list of bounced addresses
* @package cms
* @subpackage newsletter
*/
class BouncedList extends FormField {
protected $nlType;
function __construct( $name, $newsletterType ) {
parent::__construct( $name, '', null );
if( is_object( $newsletterType ) )
$this->nlType = $newsletterType;
else
$this->nlType = DataObject::get_by_id( 'NewsletterType', $newsletterType );
}
function setController($controller) {
$this->controller = $controller;
}
function FieldHolder() {
return $this->renderWith( 'NewsletterAdmin_BouncedList' );
}
function Entries() {
$id = $this->nlType->GroupID;
$bounceRecords = DataObject::get( 'Email_BounceRecord', "`GroupID`='$id'", null, "INNER JOIN `Group_Members` USING(`MemberID`)" );
//user_error($id, E_USER_ERROR );
if( !$bounceRecords )
return null;
foreach( $bounceRecords as $bounceRecord ) {
if( $bounceRecord ) {
$bouncedUsers[] = new ArrayData( array(
'Record' => $bounceRecord,
'GroupID' => $id,
'Member' => DataObject::get_by_id( 'Member', $bounceRecord->MemberID )
));
}
}
return new DataObjectSet( $bouncedUsers );
}
}
?>

View File

@ -1,192 +0,0 @@
<?php
/**
* @package cms
* @subpackage newsletter
*/
/**
* Single newsletter instance. Each Newsletter belongs to a NewsletterType.
* @package cms
* @subpackage newsletter
*/
class Newsletter extends DataObject {
/**
* Returns a FieldSet with which to create the CMS editing form.
* You can use the extend() method of FieldSet to create customised forms for your other
* data objects.
*/
function getCMSFields($controller = null) {
require_once("forms/Form.php");
$group = DataObject::get_by_id("Group", $this->Parent()->GroupID);
$sent_status_report = $this->renderWith("Newsletter_SentStatusReport");
$ret = new FieldSet(
new TabSet("Root",
$mailTab = new Tab(_t('Newsletter.NEWSLETTER', 'Newsletter'),
new TextField("Subject", _t('Newsletter.SUBJECT', 'Subject'), $this->Subject),
new HtmlEditorField("Content", _t('Newsletter.CONTENT', 'Content'))
),
$sentToTab = new Tab(_t('Newsletter.SENTREPORT', 'Sent Status Report'),
new LiteralField("Sent Status Report", $sent_status_report)
)
)
);
if( $this->Status != 'Draft' ) {
$mailTab->push( new ReadonlyField("SendDate", _t('Newsletter.SENTAT', 'Sent at'), $this->SendDate) );
}
return $ret;
}
/**
* Returns a DataObject listing the recipients for the given status for this newsletter
*
* @param string $result 3 possible values: "Sent", (mail() returned TRUE), "Failed" (mail() returned FALSE), or "Bounced" ({@see $email_bouncehandler}).
*/
function SentRecipients($result) {
$SQL_result = Convert::raw2sql($result);
return DataObject::get("Newsletter_SentRecipient",array("ParentID='".$this->ID."'", "Result='".$SQL_result."'"));
}
/**
* Returns a DataObjectSet containing the subscribers who have never been sent this Newsletter
*
*/
function UnsentSubscribers() {
// Get a list of everyone who has been sent this newsletter
$sent_recipients = DataObject::get("Newsletter_SentRecipient","ParentID='".$this->ID."'");
// If this Newsletter has not been sent to anyone yet, $sent_recipients will be null
if ($sent_recipients != null) {
$sent_recipients_array = $sent_recipients->toNestedArray('MemberID');
} else {
$sent_recipients_array = array();
}
// Get a list of all the subscribers to this newsletter
$subscribers = DataObject::get( 'Member', "`GroupID`='".$this->Parent()->GroupID."'", null, "INNER JOIN `Group_Members` ON `MemberID`=`Member`.`ID`" );
// If this Newsletter has no subscribers, $subscribers will be null
if ($subscribers != null) {
$subscribers_array = $subscribers->toNestedArray();
} else {
$subscribers_array = array();
}
// Get list of subscribers who have not been sent this newsletter:
$unsent_subscribers_array = array_diff_key($subscribers_array, $sent_recipients_array);
// Create new data object set containing the subscribers who have not been sent this newsletter:
$unsent_subscribers = new DataObjectSet();
foreach($unsent_subscribers_array as $key => $data) {
$unsent_subscribers->push(new ArrayData($data));
}
return $unsent_subscribers;
}
function getTitle() {
return $this->getField('Subject');
}
function getNewsletterType() {
return DataObject::get_by_id('NewsletterType', $this->ParentID);
}
static $db = array(
"Status" => "Enum('Draft, Send', 'Draft')",
"Content" => "HTMLText",
"Subject" => "Varchar(255)",
"SentDate" => "Datetime",
);
static $has_one = array(
"Parent" => "NewsletterType",
);
static $has_many = array(
"Recipients" => "Newsletter_Recipient",
"SentRecipients" => "Newsletter_SentRecipient",
);
static function newDraft( $parentID, $subject, $content ) {
if( is_numeric( $parentID ) ) {
$newsletter = new Newsletter();
$newsletter->Status = 'Draft';
$newsletter->Title = $newsletter->Subject = $subject;
$newsletter->ParentID = $parentID;
$newsletter->Content = $content;
$newsletter->write();
} else {
user_error( $parentID, E_USER_ERROR );
}
return $newsletter;
}
}
/**
* Database record for recipients that have had the newsletter sent to them.
* @package cms
* @subpackage newsletter
*/
class Newsletter_SentRecipient extends DataObject {
/**
* The DB schema for Newsletter_SentRecipient.
*
* ParentID is the the Newsletter
* Email and MemberID keep track of the recpients information
* Result has 4 possible values: "Sent", (mail() returned TRUE), "Failed" (mail() returned FALSE),
* "Bounced" ({@see $email_bouncehandler}), or "BlackListed" (sending to is disabled).
*/
static $db = array(
"ParentID" => "Int",
"Email" => "Varchar(255)",
"Result" => "Enum('Sent, Failed, Bounced, BlackListed', 'Sent')",
);
static $has_one = array(
"Member" => "Member",
);
}
/**
* Single recipient of the newsletter
* @package cms
* @subpackage newsletter
*/
class Newsletter_Recipient extends DataObject {
static $db = array(
"ParentID" => "Int",
);
static $has_one = array(
"Member" => "Member",
);
}
/**
* Email object for sending newsletters.
* @package cms
* @subpackage newsletter
*/
class Newsletter_Email extends Email_Template {
protected $nlType;
function __construct($nlType) {
$this->nlType = $nlType;
parent::__construct();
}
function setTemplate( $template ) {
$this->ss_template = $template;
}
function UnsubscribeLink(){
$emailAddr = $this->To();
$nlTypeID = $this->nlType->ID;
return Director::absoluteBaseURL()."unsubscribe/$emailAddr/$nlTypeID";
}
}
?>

View File

@ -1,143 +0,0 @@
<?php
/**
* @package cms
* @subpackage newsletter
*/
/**
* Batch process for sending newsletters.
* @package cms
* @subpackage newsletter
*/
class NewsletterEmailProcess extends BatchProcess {
protected $subject;
protected $body;
protected $from;
protected $newsletter;
protected $nlType;
protected $messageID;
/**
* Set up a Newsletter Email Process
*
* @param $recipients DataObjectSet The recipients of this newsletter
*/
function __construct( $subject, $body, $from, $newsletter, $nlType, $messageID = null, $recipients) {
$this->subject = $subject;
$this->body = $body;
$this->from = $from;
$this->newsletter = $newsletter;
$this->nlType = $nlType;
$this->messageID = $messageID;
parent::__construct( $recipients );
}
function next( $count = 10 ) {
$max = $this->current + $count;
$max = $max < count( $this->objects ) ? $max : count( $this->objects );
while($this->current < $max) {
$index = $this->current++;
$member = $this->objects[$index];
// check to see if the user has unsubscribed from the mailing list
// TODO Join in the above query first
$unsubscribeRecord = DataObject::get_one('Member_UnsubscribeRecord', "`MemberID`='{$member->ID}' AND `NewsletterTypeID`='{$this->nlType->ID}'");
if( !$unsubscribeRecord ) {
$address = $member->Email;
/**
* Email Blacklisting Support
*/
if($member->BlacklistedEmail && Email_BlackList::isBlocked($address)){
$bounceRecord = new Email_BounceRecord();
$bounceRecord->BounceEmail = $member->Email;
$bounceRecord->BounceTime = date("Y-m-d H:i:s",time());
$bounceRecord->BounceMessage = "BlackListed Email";
$bounceRecord->MemberID = $member->ID;
$bounceRecord->write();
// Log the blacklist for this specific Newsletter
$newsletter = new Newsletter_SentRecipient();
$newsletter->Email = $address;
$newsletter->MemberID = $member->ID;
$newsletter->Result = 'BlackListed';
$newsletter->ParentID = $this->newsletter->ID;
$newsletter->write();
} else {
$e = new Newsletter_Email($this->nlType);
$e->setBody( $this->body );
$e->setSubject( $this->subject );
$e->setFrom( $this->from );
$e->setTemplate( $this->nlType->Template );
if(method_exists($member, "getNameForEmail"))
$nameForEmail = $member->getNameForEmail();
$e->populateTemplate( array( 'Member' => $member, 'FirstName' => $member->FirstName, 'NameForEmail'=>$nameForEmail ) );
$this->sendToAddress( $e, $address, $this->messageID, $member);
}
}
}
if( $this->current >= count( $this->objects ) )
return $this->complete();
else
return parent::next();
}
/*
* Sends a Newsletter email to the specified address
*
* @param $member The object containing information about the member being emailed
*/
private function sendToAddress( $email, $address, $messageID = null, $member) {
$email->setTo( $address );
$result = $email->send( $messageID );
// Log result of the send
$newsletter = new Newsletter_SentRecipient();
$newsletter->Email = $address;
$newsletter->MemberID = $member->ID;
// If Sending is successful
if ($result == true) {
$newsletter->Result = 'Sent';
} else {
$newsletter->Result = 'Failed';
}
$newsletter->ParentID = $this->newsletter->ID;
$newsletter->write();
// Adding a pause between email sending can be useful for debugging purposes
// sleep(10);
}
function complete() {
parent::complete();
if( $this->newsletter->SentDate ) {
$resent = true;
} else {
$resent = false;
}
$this->newsletter->SentDate = 'now';
$this->newsletter->Status = 'Send';
$this->newsletter->write();
// Call the success message JS function with the Newsletter information
if( $resent ) {
return "resent_ok( '{$this->nlType->ID}', '{$this->newsletter->ID}', '".count( $this->objects )."' )";
} else {
return "draft_sent_ok( '{$this->nlType->ID}', '{$this->newsletter->ID}', '".count( $this->objects )."' )";
}
}
}
?>

View File

@ -1,55 +0,0 @@
<?php
/**
* @package cms
* @subpackage newsletter
*/
/**
* Simple form field shown when the NewsletterAdmin first loads.
* @package cms
* @subpackage newsletter
*/
class NewsletterList extends FormField {
function __construct($name, $mailtype, $status = "Draft") {
if(is_object($mailtype)) $this->mailType = $mailtype;
else $this->mailType = DataObject::get_by_id('NewsletterType',$mailtype);
$this->status = $status;
parent::__construct(null);
}
function FieldHolder() {
return $this->renderWith("NewsletterList");
}
function setMailType($mailtype) {
$this->mailType = $mailtype;
}
function setController($controller) {
$this->controller = $controller;
}
/* No longer used
function Newsletters() {
return DataObject::get( 'Newsletter', "`ParentID`='{$this->mailType->ID}' AND `Status`='{$this->status}'" );
}
*/
function DraftNewsletters() {
return $this->mailType->DraftNewsletters();
}
function SentNewsletters() {
return $this->mailType->SentNewsletters();
}
function Status() {
return $this->status;
}
function mailTypeID() {
return $this->mailType->ID;
}
}
?>

View File

@ -1,137 +0,0 @@
<?php
/**
* @package cms
* @subpackage newsletter
*/
/**
* Represents a type of newsletter, for example the weekly products update.
* The NewsletterType is associated with a recipient list and a bunch of Newsletter objects, which are each either Sent or Draft.
* @package cms
* @subpackage newsletter
*/
class NewsletterType extends DataObject {
static $db = array(
"Title" => "Varchar",
"Template" => "Varchar",
"FromEmail" => "Varchar",
"Sent" => "Datetime"
);
static $has_one = array(
"Parent" => "SiteTree",
"Group" => "Group",
);
static $has_many = array(
"Newsletters" => "Newsletter",
);
function DraftNewsletters() {
return DataObject::get("Newsletter","ParentID={$this->ID} AND Status ='Draft'");
}
function SentNewsletters() {
return DataObject::get("Newsletter","ParentID={$this->ID} AND Status ='Send'");
}
function Recipients() {
return DataObject::get("Member", "Group_Members.GroupID = {$this->GroupID}", "", "JOIN Group_Members on Group_Members.MemberID = Member.ID");
}
function delete() {
foreach( $this->Newsletters() as $newsletter )
$newsletter->delete();
parent::delete();
}
/**
* Updates the group so the security section is also in sync with
* the curent newsletters.
*/
function onBeforeWrite(){
if($this->ID){
$group = $this->Group();
if($group->Title != "$this->Title"){
$group->Title = _t('NewsletterType.MAILINGLIST', 'Mailing List:').' '. $this->Title;
// Otherwise the code would have mailing list in it too :-(
$group->Code = SiteTree::generateURLSegment($this->Title);
$group->write();
}
}
parent::onBeforeWrite();
}
/**
* Get the fieldset to display in the administration section
*/
function getCMSFields() {
$group = null;
if($this->GroupID) {
$group = DataObject::get_one("Group", "ID = $this->GroupID");
}
$fields = new FieldSet(
new TextField("Title", _t('NewsletterType.NEWSLETTERTYPE', 'Newsletter Type')),
new TextField("FromEmail", _t('NewsletterType.SENDFROM', 'Send newsletters from')),
new TabSet("Root",
new Tab(_t('NewsletterType.DRAFTS', 'Drafts'),
$draftList = new NewsletterList("Draft", $this, _t('NewsletterType.DRAFT', 'Draft'))
),
new TabSet('Sent',
new Tab(_t('NewsletterType.SENT', 'Sent'),
$sendList = new NewsletterList("Send", $this, _t('NewsletterType.SEND', 'Send'))
),
new Tab(_t('NewsletterType.UNSUBSCRIBED', 'Unsubscribed'),
$unsubscribedList = new UnsubscribedList("Unsubscribed", $this)
),
new Tab(_t('NewsletterType.BOUNCED', 'Bounced'),
$bouncedList = new BouncedList("Bounced", $this )
)
)
)
);
if($this->GroupID) {
$fields->addFieldToTab('Root',
new TabSet("Recipients",
new Tab( _t('NewsletterType.RECIPIENTS', 'Recipients'),
$recipients = new MemberTableField(
$this,
"Recipients",
$group
)
),
new Tab( _t('NewsletterType.IMPORT', 'Import'),
$importField = new RecipientImportField("ImportFile", _t('NewsletterType.IMPORTFROM', 'Import from file'), $group )
)
)
);
$recipients->setController($this);
$importField->setController($this);
$importField->setTypeID( $this->ID );
}
$fields->addFieldToTab('Root',
new Tab(_t('NewsletterType.TEMPLATE', 'Template'),
$templates = new TemplateList("Template","Template", $this->Template, NewsletterAdmin::template_path())
)
);
$draftList->setController($this);
$sendList->setController($this);
$templates->setController($this);
$unsubscribedList->setController($this);
$bouncedList->setController($this);
$fields->push($idField = new HiddenField("ID"));
$fields->push( new HiddenField( "executeForm", "", "TypeEditForm" ) );
$idField->setValue($this->ID);
return $fields;
}
}
?>

View File

@ -1,391 +0,0 @@
<?php
/**
* @package cms
* @subpackage newsletter
*/
/**
* Displays a field for importing recipients.
* @package cms
* @subpackage newsletter
*/
class RecipientImportField extends FormField {
protected $memberGroup;
protected $memberClass;
protected $tableColumns;
protected $table;
protected $clientFileName;
protected $typeID;
static $column_types = array(
'Salutation' => array( 'title', 'salutation' ),
'FirstName' => array( 'firstname', 'christianname', 'givenname' ),
'Surname' => array( 'lastname','surname', 'familyname' ),
'Email' => array( 'email', 'emailaddress' ),
'Address' => array( 'address' ),
'PhoneNumber' => array('phone','phonenumber'),
'JobTitle' => array( 'jobtitle' ),
'Organisation' => array( 'organisation', 'organization' ),
'EmailType' => array( 'htmlorplaintext', 'emailtype' )
);
static $custom_set_fields = array();
public static function setCustomField( $getMapCode, $fieldName ) {
self::$custom_set_fields[] = array(
'Code' => $getMapCode,
'Field' => $fieldName
);
}
function __construct( $name, $title, $memberGroup, $memberClass = 'Member', $form = null ) {
$this->memberGroup = $memberGroup;
$this->memberClass = $memberClass;
parent::__construct( $name, $title, null, $form );
}
function Field() {
$frameURL = Director::absoluteBaseURL() . 'admin/newsletter/displayfilefield/' . $this->typeID;
return "<iframe name=\"{$this->Name}\" frameborder=\"0\" class=\"RecipientImportField\" src=\"$frameURL\"></iframe>";
}
function setTypeID( $id ) {
$this->typeID = $id;
}
function CustomSetFields() {
$fields = new FieldSet();
foreach( self::$custom_set_fields as $customField ) {
eval( '$map = ' . $customField['Code'] .';' );
$noneMap = array( 0 => '(Not set)' );
$map = $noneMap + $map;
$fields->push( new DropdownField( 'Set['.$customField['Field'].']', $customField['Field'], $map ) );
}
return $fields;
}
/**
* Returns HTML to be displayed inside the IFrame
*/
static function fileupload() {
}
/**
* Returns the table of results to be displayed in the table of
* details loaded from the file
*/
function displaytable() {
// Check that a file was uploaded
$tempFile = fopen( $_FILES['ImportFile']['tmp_name'], 'r' );
// display some error if the file cannot be opened
$this->clientFileName = $_FILES['ImportFile']['name'];
while( ( $row = fgetcsv( $tempFile ) ) !== false ) {
if( !$this->tableColumns ) {
$this->parseTableHeader( $row );
} else {
$newRow = array();
$newSessionTableRow = array();
foreach( $row as $cell ) {
$newRow[] = $this->parseCSVCell( $cell );
$newSessionTableRow[] = $cell;
}
$cells = new DataObjectSet( $newRow );
$table[] = $cells->customise( array( 'Cells' => $cells ) );
$sessionTable[] = $newSessionTableRow;
}
}
fclose( $tempFile );
$this->table = new DataObjectSet( $table );
Session::set("ImportFile.{$_REQUEST['ID']}", $sessionTable);
return $this->renderWith( 'Newsletter_RecipientImportField_Table' );
}
/**
* Determines what type each column is
*/
function parseTableHeader( $columns ) {
$columnSource = array_combine(
array_keys( self::$column_types ),
array_keys( self::$column_types )
);
$columnSource = array_merge( array( 'Unknown' => 'Unknown' ), $columnSource );
$colCount = 0;
foreach( $columns as $cell ) {
$columnType = $this->getColumnType( $this->parseCSVCell( $cell )->Value() );
$this->tableColumns[] = new DropdownField( 'ImportFileColumns[' . (string)( $colCount++ ) . ']', '', $columnSource, $columnType );
}
}
function parseCSVCell( $cell ) {
return new RecipientImportField_Cell( $cell );
}
function getColumnType( $cell ) {
$cell = strtolower( $cell );
$escapedValue = preg_replace( '/[^a-z]/', '', $cell );
foreach( self::$column_types as $type => $aliases ) {
if( in_array( $escapedValue, $aliases ) )
return $type;
}
return 'Unknown';
}
function setController( $controller ) {
$this->controller = $controller;
}
/**
* Set of table column headers
*/
function ColumnHeaders() {
return new DataObjectSet( $this->tableColumns );
}
function Rows() {
return $this->table;
}
function FileName() {
return $this->clientFileName;
}
function TypeID() {
return $this->typeID;
}
}
/**
* Single cell of the recipient import field
* @package cms
* @subpackage newsletter
*/
class RecipientImportField_Cell extends ViewableData {
protected $value;
function __construct( $value ) {
$this->value = $value;
}
function Value() {
return $this->value;
}
}
/**
* Upload form that appears in the iframe
* @package cms
* @subpackage newsletter
*/
class RecipientImportField_UploadForm extends Form {
function import( $data, $form ) {
$id = $data['ID'];
$mailType = DataObject::get_one("NewsletterType", "ID = $id");
if($mailType->GroupID)
$group = DataObject::get_one("Group", "ID = $mailType->GroupID");
$recipientField = new RecipientImportField("ImportFile","Import from file", $group );
$recipientField->setTypeID( $id );
// if the file is not valid, then return an error
if( empty( $_FILES ) || empty( $_FILES['ImportFile'] ) || $_FILES['ImportFile']['size'] == 0 )
return $this->customise( array( 'ID' => $id, "UploadForm" => $this->controller->UploadForm( $id ), 'ErrorMessage' => 'Please choose a CSV file to import' ) )->renderWith('Newsletter_RecipientImportField');
elseif( !$this->isValidCSV( $_FILES['ImportFile'] ) ) {
/*if( file_exists( $_FILES['ImportFile']['tmp_name'] ) ) unlink( $_FILES['ImportFile']['tmp_name'] );
unset( $_FILES['ImportFile'] );*/
return $this->customise( array( 'ID' => $id, "UploadForm" => $this->controller->UploadForm( $id ), 'ErrorMessage' => 'The selected file was not a CSV file' ) )->renderWith('Newsletter_RecipientImportField');
} else
return $recipientField->displaytable();
}
function isValidCSV( $file ) {
return preg_match( '/.*\.csv$/i', $file['name'] ) > 0;
}
function confirm( $data, $form ) {
$id = $data['ID'];
$mailType = DataObject::get_one("NewsletterType", "ID = $id");
if($mailType->GroupID)
$group = DataObject::get_one("Group", "ID = $mailType->GroupID");
// @TODO Look into seeing if $data['Set'] should be removed since it seems to be undefined
return $this->importMembers( $id, $group, $data['ImportFileColumns'], $data['Set'] );
}
function cancel( $data, $form ) {
$newForm = $this->controller->UploadForm( $data['ID'] );
return $newForm->forTemplate();
}
function action_import( $data, $form ) {
return $this->import( $data, $form );
}
function action_confirm( $data, $form ) {
return $this->confirm( $data, $form );
}
function action_cancel( $data, $form ) {
return $this->cancel( $data, $form );
}
/**
* Import members from the uploaded file
*/
protected function importMembers( $id, $group, $cols, $setFields, $primaryColType = 'Email' ) {
$startTime = time();
$importData = Session::get("ImportFile.{$id}");
$validColumns = array_keys( RecipientImportField::$column_types );
$columnMap = array_flip( $cols );
// Debug::show($columnMap);
// locate the primary column's index
$primaryColumn = /*array_search( $primaryColType, $validColumns );*/ $columnMap[$primaryColType];
// changed fields
$changedFields = array();
// intersect the list of valid columns with the column map to find the columns we need
$importColumns = array_intersect( $validColumns, $cols );
// statistics
$newMembers = 0;
$changedMembers = 0;
$skippedMembers = 0;
// the class that the imported members will become
$newMemberClass = Object::getCustomClass( 'Member' );
// for each row, add a new member or overwrite an existing member
foreach( $importData as $newMemberRow ) {
// skip rows with an empty value for the primary column
if( empty( $newMemberRow[$primaryColumn] ) ) {
$skippedMembers++;
continue;
}
// remember to check if the user has unsubscribed
$trackChanges = true;
// TODO: Write DataObject::update
$member = $this->findMember( $newMemberRow[$primaryColumn] );
if( !$member ) {
$newMembers++;
$trackChanges = false;
$member = Object::create("Member");
} else {
// skip this member if the are unsubscribed
if( $member->Unsubscribed ) {
$skippedMembers++;
continue;
}
if( $member->class != $newMemberClass )
$member->setClassName( $newMemberClass );
$changedMembers++;
}
// add each of the valid columns
foreach( $importColumns as $datum ) {
// perform any required conversions
$newValue = trim( $newMemberRow[$columnMap[$datum]] );
$oldValue = trim( $member->$datum );
// Debug::message( "$datum@{$columnMap[$datum]}" );
// track the modifications to the member data
if( $trackChanges && $newValue != $oldValue && $datum != $primaryColumn ) {
$changedFields[] = array(
$newMemberRow[$primaryColumn],
"$datum:\n$oldValue",
"$datum:\n$newValue"
);
$numChangedFields++;
}
$member->$datum = $newValue;
}
// set any set fields
if( $setFields )
foreach( $setFields as $fieldName => $fieldValue )
$member->$fieldName = $fieldValue;
// add member to group
$member->write();
$member->Groups()->add( $group->ID );
}
$numChangedFields = count( $changedFields );
$this->notifyChanges( $changedFields );
// TODO Refresh window
$customData = array(
'ID' => $id,
"UploadForm" => $this->controller->UploadForm( $id ),
'ImportMessage' => 'Imported new members',
'NewMembers' => (string)$newMembers,
'ChangedMembers' => (string)$changedMembers,
'ChangedFields' => (string)$numChangedFields,
'SkippedRecords' => (string)$skippedMembers,
'Time' => time() - $startTime
);
return $this->customise( $customData )->renderWith('Newsletter_RecipientImportField');
}
function findMember( $email ) {
$email = addslashes( $email );
return DataObject::get_one( 'Member', "`Email`='$email'" );
}
function notifyChanges( $changes ) {
$email = new Email( Email::getAdminEmail(), Email::getAdminEmail(), 'Changed Fields' );
$body = "";
foreach( $changes as $change ) {
$body .= "-------------------------------\n";
$body .= implode( ' ', $change ) . "\n";
}
$email->setBody( $body );
$email->send();
}
}
?>

View File

@ -1,278 +0,0 @@
<?php
/**
* @package cms
* @subpackage newsletter
*/
/**
* Page type for creating a page that contains a form that visitors can use to subscript to a newsletter.
* @package cms
* @subpackage newsletter
*/
class SubscribeForm extends UserDefinedForm {
static $add_action = "a newsletter subscription form";
static $required_fields = array(
'Email address' => 'EditableEmailField(CustomParameter=Email,CanDelete=0)',
'First name' => 'EditableTextField(CustomParameter=FirstName)',
'Last name' => 'EditableTextField(CustomParameter=Surname)',
'Address' => 'EditableTextField(Rows=3,CustomParameter=Address)',
'Job title' => 'EditableTextField(CustomParameter=JobTitle)',
'Organisation' => 'EditableTextField(CustomParameter=Organisation)',
'Mail format' => 'EditableRadioField(Options=1:HTML,Options=0:Text__only,CustomParameter=HTMLEmail)'
);
static $db = array(
'Subscribe' => 'Boolean',
'AllNewsletters' => 'Boolean',
'Subject' => 'Varchar'
);
static $defaults = array(
"OnCompleteMessage" => "<p>Thanks, you have been added to our mailing list.</p>",
);
static $has_many = array(
'Newsletters' => 'NewsletterType'
);
function __construct( $data = null, $isSingleton = false ) {
parent::__construct( $data, $isSingleton );
if( $data || $isSingleton )
return;
$this->addDefaultFields();
}
private function addDefaultFields() {
$f = $this->Fields();
// check that the required fields exist
$count = 1;
foreach( self::$required_fields as $defaultName => $typeString ) {
list( $type, $typeValue ) = $this->parseType( $typeString );
$newField = new $type();
$newField->Name = "Field" . (string)$count;
$newField->Title = $defaultName;
// TODO Map the field to a particular action
if( !empty( $typeValue ) ) {
$newField->prepopulate( $typeValue );
}
$newField->ParentID = $this->ID;
$newField->Sort = $count;
$newField->write();
$count++;
}
}
public function write($showDebug = false, $forceInsert = false, $forceWrite = false) {
$isNew = (!$this->ID);
parent::write($showDebug, $forceInsert, $forceWrite);
if($isNew) $this->addDefaultFields();
}
public function Newsletters() {
$components = $this->getComponents('Newsletters');
return $components;
}
public function customFormActions( $isReadonly = false ) {
$fields = parent::customFormActions( $isReadonly );
// get the newsletters in the system
$newsletterTypes = DataObject::get( 'NewsletterType' );
$availableNewsletters = array();
$nlCheckboxes = array();
foreach( $this->Newsletters() as $subscribeTo )
$availableNewsletters[] = $subscribeTo->ID;
// create a checkbox for each newsletter
if($newsletterTypes && is_object($newsletterTypes)) {
foreach( $newsletterTypes as $newsletterType )
$nlCheckboxes[] = new CheckboxField( "CustomNewsletters[{$newsletterType->ID}]", $newsletterType->Title, in_array( $newsletterType->ID, $availableNewsletters ) );
}
$fields->push( new OptionsetField( 'AllNewsletters', '', array(
1 => 'All newsletters',
0 => 'Specific newsletters'
),
$this->AllNewsletters
));
$fields->push( new CompositeField( $nlCheckboxes ));
$fields->push( new TextField( 'Subject', 'Subject line on confirmation', $this->Subject ) );
return $fields;
}
function parseType( $typeString ) {
if( preg_match('/^([A-Za-z_]+)\(([^)]+)\)$/', $typeString, $match ) )
return array( $match[1], $match[2] );
return array( $typeString, null );
}
/**
*
*/
public function processNewFormFields() {
}
/**
* Saves data related to any custom actions this form performs when submitted
*/
public function customFormSave( $data, $form ) {
$newsletters = $this->Newsletters();
$this->Subscribe = !empty( $data['Subscribe'] );
$this->AllNewsletters = !empty( $data['AllNewsletters'] );
$this->Subject = $data['Subject'];
// Note: $data['CustomNewsletters'] was changed to $_REQUEST['CustomNewsletters'] in order to fix
// to fix "'Specific newsletters' option in 'newsletter subscription form' page type does not work" bug
// See: http://www.silverstripe.com/bugs/flat/1675
if( !empty( $_REQUEST['CustomNewsletters'] ) ) {
/*foreach( $newsletters as $newsletter ) {
if( $data['CustomNewsletters'][$newsletter->ID] == 'on' ) {
$newsletters->add( $newsletter->ID );
} else {
$newsletters->remove( $newsletter->ID );
}
}*/
if( isset($_REQUEST['CustomNewsletters'][0]) )
unset( $_REQUEST['CustomNewsletters'][0] );
$newsletters->setByIDList( array_keys( $_REQUEST['CustomNewsletters'] ) );
} else {
$this->AllNewsletters = true;
$newsletters->removeAll();
}
}
}
/**
* Email for sending subscribe form submissions.
* @package cms
* @subpackage newsletter
*/
class SubscribeForm_SubscribeEmail extends Email_Template {
protected $to = '$Email';
protected $subject = '$Subject';
protected $ss_template = 'SubscribeEmail';
protected $from = '';
}
/**
* Controller for the SubscribeForm page
* @package cms
* @subpackage newsletter
*/
class SubscribeForm_Controller extends UserDefinedForm_Controller {
function process( $data, $form ) {
// Add the user to the mailing list
$member = Object::create("Member");
// $_REQUEST['showqueries'] = 1;
// map the editables to the data
foreach( $this->Fields() as $editable ) {
$field = $editable->CustomParameter;
if( !$field )
continue;
// Debug::message( $editable->Name . '->' . $field );
// if( $member->hasField( $field ) )
$member->$field = $data[$editable->Name];
}
// need to write the member record before adding the user to groups
$member->write();
$newsletters = array();
// Add member to the selected newsletters
if( isset($data['Newsletters'])) foreach( $data['Newsletters'] as $listID ) {
if( !is_numeric( $listID ) )
continue;
// get the newsletter
$newsletter = DataObject::get_by_id( 'NewsletterType', $listID );
if( !$newsletter )
continue;
$newsletters[] = $newsletter;
// Debug::show( $newsletter->GroupID );
$member->Groups()->add( $newsletter->GroupID );
}
// email the user with their details
$templateData = array(
'Email' => $member->Email,
'FirstName' => $member->FirstName,
'Newsletters' => new DataObjectSet( $newsletters ),
'UnsubscribeLink' => Director::baseURL() . 'unsubscribe/' . $member->Email
);
$email = new SubscribeForm_SubscribeEmail();
$email->setFrom( Email::getAdminEmail() );
$email->setSubject( $this->Subject );
$email->populateTemplate( $templateData );
$email->send();
$parentHTML = parent::process( $data, $form );
$templateData['Link'] = $data['Referrer'];
$templateData['UnsubscribeLink'] = Director::baseURL() . 'unsubscribe';
$custom = $this->customise(array(
"Content" => $this->customise( $templateData )->renderWith('SubscribeSubmission')
));
return $custom->renderWith('Page');
}
function Form() {
$form = parent::Form();
if( $this->AllNewsletters )
$newsletterList = DataObject::get('NewsletterType');
else
$newsletterList = $this->Newsletters();
$newsletters = array();
// get the newsletter types to display on the form
foreach( $newsletterList as $newsletter )
$newsletters[$newsletter->ID] = $newsletter->Title;
$form->Fields()->push( new CheckboxSetField( 'Newsletters', 'Subscribe to lists', $newsletters ) );
$validator = $form->getValidator();
$validator->addRequiredField( 'Newsletters' );
$form->setValidator( $validator );
return $form;
}
}
?>

View File

@ -1,48 +0,0 @@
<?php
/**
* @package cms
* @subpackage newsletter
*/
/**
* Subclass of DropdownField for showing a list of the newsletter templates available.
* @package cms
* @subpackage newsletter
*/
class TemplateList extends DropdownField {
protected $templatePath;
function __construct( $name, $title, $value, $path, $form = null ) {
$this->templatePath = $path;
parent::__construct( $name, $title, $this->getTemplates(), $value, $form );
}
private function getTemplates() {
$templates = array( "" => _t('TemplateList.NONE', 'None') );
$absPath = Director::baseFolder();
if( $absPath{strlen($absPath)-1} != "/" )
$absPath .= "/";
$absPath .= $this->templatePath;
if(is_dir($absPath)) {
$templateDir = opendir( $absPath );
// read all files in the directory
while( ( $templateFile = readdir( $templateDir ) ) !== false ) {
// *.ss files are templates
if( preg_match( '/(.*)\.ss$/', $templateFile, $match ) )
$templates[$match[1]] = $match[1];
}
}
return $templates;
}
function setController( $controller ) {
$this->controller = $controller;
}
}
?>

View File

@ -1,206 +0,0 @@
<?php
/**
* @package cms
* @subpackage newsletter
*/
/**
* Create a form that a user can use to unsubscribe from a mailing list
* @package cms
* @subpackage newsletter
*/
class Unsubscribe_Controller extends Page_Controller {
function __construct($data = null) {
}
function RelativeLink($action = null) {
return "unsubscribe/$action";
}
function index() {
Session::clear("loggedInAs");
Requirements::themedCSS("form");
// if the email address is given
$emailAddress = addslashes( $this->urlParams['Email'] );
$mailingListID = addslashes( $this->urlParams['MailingList'] );
if(is_numeric($mailingListID)) {
$mailingList = DataObject::get_by_id("NewsletterType", $mailingListID);
}
// try to find the user
if($emailAddress)
$member = DataObject::get_one( 'Member', "`Email`='$emailAddress'" );
// if the email address and mailing list is given in the URL and both are valid,
// then unsubscribe the user
if( $member && $mailingList && $member->inGroup( $mailingList->GroupID ) ) {
$this->unsubscribeFromList( $member, $mailingList );
$url = "unsubscribe"."/done/".$member->Email."/".$mailingList->Title;
Director::redirect($url);
} elseif( $member ) {
$listForm = $this->MailingListForm( $member );
} else {
$listForm = $this->EmailAddressForm();
}
if($this->urlParams['Email'] == "done")
$listForm->sessionMessage(_t('Unsubscribe.SUCCESS', 'Thank you. You have been removed from the selected groups'), "good");
return $this->customise( array( 'Content' => $listForm->forTemplate() ) )->renderWith('Page');
}
/**
* Display a form with all the mailing lists that the user is subscribed to
*/
function MailingListForm( $member = null ) {
$email = $this->urlParams['Email'];
return new Unsubscribe_MailingListForm($this, 'MailingListForm', $member, $email);
}
/**
* Display a form allowing the user to input their email address
*/
function EmailAddressForm() {
return new Unsubscribe_EmailAddressForm( $this, 'EmailAddressForm' );
}
/**
* Show the lists for the user with the given email address
*/
function showlists( $data, $form ) {
$member = DataObject::get_one( 'Member', "`Email`='{$data['Email']}'" );
$mailingListForm = new Unsubscribe_MailingListForm( $this, 'MailingListForm', $member, $data['Email']);
return $this->customise( array( 'Content' => $mailingListForm->forTemplate() ) )->renderWith('Page');
}
/**
* Unsubscribe the user from the given lists.
*/
function unsubscribe($data, $form) {
$email = $this->urlParams['Email'];
$member = DataObject::get_one( 'Member', "`Email`='$email'" );
if(!$member){
$member = DataObject::get_one('Member', "`EmailAddress` = '$email'");
}
if( $data['MailingLists'] ) {
foreach( array_keys( $data['MailingLists'] ) as $listID ){
$nlType = DataObject::get_by_id( 'NewsletterType', $listID );
$nlTypeTitles[]= $nlType->Title;
$this->unsubscribeFromList( $member, DataObject::get_by_id( 'NewsletterType', $listID ) );
}
$sORp = (sizeof($nlTypeTitles)>1)?"newsletters ":"newsletter ";
//means single or plural
$nlTypeTitles = $sORp.implode(", ", $nlTypeTitles);
$url = "unsubscribe/done/".$member->Email."/".$nlTypeTitles;
Director::redirect($url);
} else {
$form->addErrorMessage('MailingLists', _t('Unsubscribe.NOMLSELECTED', 'You need to select at least one mailing list to unsubscribe from.'), 'bad');
Director::redirectBack();
}
}
protected function unsubscribeFromList( $member, $list ) {
// track unsubscriptions
$member->Groups()->remove( $list->GroupID );
$unsubscribeRecord = new Member_UnsubscribeRecord();
$unsubscribeRecord->unsubscribe($member, $list);
}
}
/**
* 2nd step form for the Unsubcribe page.
* The form will list all the mailing lists that the user is subscribed to.
* @package cms
* @subpackage newsletter
*/
class Unsubscribe_MailingListForm extends Form {
protected $memberEmail;
function __construct( $controller, $name, $member, $email ) {
$this->memberEmail = $member->Email;
$fields = new FieldSet();
$actions = new FieldSet();
// get all the mailing lists for this user
$lists = $this->getMailingLists( $member );
if( $lists ) {
$fields->push( new LabelField( _t('Unsubcribe.SUBSCRIBEDTO', 'You are subscribed to the following lists:')) );
foreach( $lists as $list ) {
$fields->push( new CheckboxField( "MailingLists[{$list->ID}]", $list->Title ) );
}
$actions->push( new FormAction('unsubscribe', _t('Unsubscribe.UNSUBSCRIBE', 'Unsubscribe') ) );
} else {
$fields->push( new LabelField(sprintf(_t('Unsubscribe.NOTSUBSCRIBED', 'I\'m sorry, but %s doesn\'t appear to be in any of our mailing lists.'), $email) ) );
}
parent::__construct( $controller, $name, $fields, $actions );
}
function FormAction() {
return $this->controller->Link() . "{$this->memberEmail}?executeForm=" . $this->name;
}
protected function getMailingLists( $member ) {
// get all the newsletter types that the member is subscribed to
return DataObject::get( 'NewsletterType', "`MemberID`='{$member->ID}'", null, "LEFT JOIN `Group_Members` USING(`GroupID`)" );
}
}
/**
* 1st step form for the Unsubcribe page.
* The form will let people enter an email address and press a button to continue.
* @package cms
* @subpackage newsletter
*/
class Unsubscribe_EmailAddressForm extends Form {
function __construct( $controller, $name ) {
$fields = new FieldSet(
new EmailField( 'Email', _t('Unsubscribe.EMAILADDR', 'Email address') )
);
$actions = new FieldSet(
new FormAction( 'showlists', _t('Unsubscribe.SHOWLISTS', 'Show lists') )
);
parent::__construct( $controller, $name, $fields, $actions );
}
function FormAction() {
return parent::FormAction() . ( $_REQUEST['showqueries'] ? '&showqueries=1' : '' );
}
}
/**
* Final stage form for the Unsubcribe page.
* The form just gives you a success message.
* @package cms
* @subpackage newsletter
*/
class Unsubscribe_Successful extends Form {
function __construct($controller, $name){
$fields = new FieldSet();
$actions = new FieldSet();
parent::__construct($controller, $name, $fields, $actions);
}
function setSuccessfulMessage($email, $newsletterTypes) {
Requirements::themedCSS("form");
$this->setMessage(sprintf(_t('Unsubscribe.REMOVESUCCESS', 'Thank you. %s will no longer receive the %s.'), $email, $newsletterTypes), "good");
}
}
?>

View File

@ -1,57 +0,0 @@
<?php
/**
* @package cms
* @subpackage newsletter
*/
/**
* Displays a list of all members that have unsubscribed from the list
* @package cms
* @subpackage newsletter
*/
class UnsubscribedList extends FormField {
protected $nlType;
function __construct( $name, $newsletterType ) {
parent::__construct( $name, '', null );
if( is_object( $newsletterType ) )
$this->nlType = $newsletterType;
else
$this->nlType = DataObject::get_by_id( 'NewsletterType', $newsletterType );
}
function FieldHolder() {
return $this->renderWith( 'NewsletterAdmin_UnsubscribedList' );
}
function Entries() {
$id = $this->nlType->ID;
$unsubscribeRecords = DataObject::get( 'Member_UnsubscribeRecord', "`NewsletterTypeID`='$id'" );
// user_error($id, E_USER_ERROR );
if( !$unsubscribeRecords )
return null;
foreach( $unsubscribeRecords as $unsubscribeRecord ) {
if( $unsubscribeRecord ) {
$unsubscribedUsers[] = new ArrayData( array(
'Record' => $unsubscribeRecord,
'Member' => DataObject::get_by_id( 'Member', $unsubscribeRecord->MemberID )
));
}
}
return new DataObjectSet( $unsubscribedUsers );
}
function setController($controller) {
$this->controller = $controller;
}
}
?>

View File

@ -1,801 +0,0 @@
<?php
/**
* @package cms
* @subpackage newsletter
*/
/**
* Newsletter administration section
* @package cms
* @subpackage newsletter
*/
class NewsletterAdmin extends LeftAndMain {
static $subitem_class = "Member";
static $template_path = null; // defaults to (project)/templates/email
static $allowed_actions = array(
'adddraft',
'addgroup',
'addtype',
'autocomplete',
'displayfilefield',
'getformcontent',
'getsentstatusreport',
'getsitetree',
'memberblacklisttoggle',
'newmember',
'remove',
'removebouncedmember',
'removenewsletter',
'save',
'savemember',
'savenewsletter',
'sendnewsletter',
'showdrafts',
'showmailtype',
'shownewsletter',
'showrecipients',
'showsent',
);
public function init() {
// Check permissions
// if(!Member::currentUser() || !Member::currentUser()->isAdmin()) Security::permissionFailure($this);
parent::init();
/*
if(!$this->can('AdminCMS')) {
$messageSet = array(
'default' => "Please choose an authentication method and enter your credentials to access the CMS.",
'alreadyLoggedIn' => "I'm sorry, but you can't access that part of the CMS. If you want to log in as someone else, do so below",
'logInAgain' => "You have been logged out of the CMS. If you would like to log in again, enter a username and password below.",
);
Security::permissionFailure($this, $messageSet);
return;
}*/
Requirements::javascript(MCE_ROOT . "tiny_mce_src.js");
Requirements::javascript("jsparty/tiny_mce_improvements.js");
Requirements::javascript("jsparty/hover.js");
Requirements::javascript("jsparty/scriptaculous/controls.js");
Requirements::javascript("cms/javascript/SecurityAdmin.js");
Requirements::javascript("cms/javascript/LeftAndMain_left.js");
Requirements::javascript("cms/javascript/LeftAndMain_right.js");
Requirements::javascript("cms/javascript/CMSMain_left.js");
Requirements::javascript("cms/javascript/NewsletterAdmin_left.js");
Requirements::javascript("cms/javascript/NewsletterAdmin_right.js");
Requirements::javascript("sapphire/javascript/ProgressBar.js");
// We don't want this showing up in every ajax-response, it should always be present in a CMS-environment
if(!Director::is_ajax()) {
Requirements::javascriptTemplate("cms/javascript/tinymce.template.js", array(
"ContentCSS" => project() . "/css/editor.css",
"BaseURL" => Director::absoluteBaseURL(),
"Lang" => i18n::get_tinymce_lang()
));
}
// needed for MemberTableField (Requirements not determined before Ajax-Call)
Requirements::javascript("cms/javascript/MemberTableField.js");
Requirements::css("cms/css/NewsletterAdmin.css");
}
public function remove() {
$ids = explode( ',', $_REQUEST['csvIDs'] );
$count = 0;
foreach( $ids as $id ) {
if( preg_match( '/^mailtype_(\d+)$/', $id, $matches ) )
$record = DataObject::get_by_id( 'NewsletterType', $matches[1] );
else if( preg_match( '/^[a-z]+_\d+_(\d+)$/', $id, $matches ) )
$record = DataObject::get_by_id( 'Newsletter', $matches[1] );
if($record) {
$record->delete();
}
FormResponse::add("removeTreeNodeByIdx(\$('sitetree'), '$id' );");
// Don't allow a deleted draft to be edited
FormResponse::add("$('Form_EditForm').closeIfSetTo('$matches[1]');");
$count++;
}
FormResponse::status_message('Deleted '.$count.' items','good');
return FormResponse::respond();
}
public function getformcontent(){
Session::set('currentPage', $_REQUEST['ID']);
Session::set('currentType', $_REQUEST['type']);
if($_REQUEST['otherID'])
Session::set('currentOtherID', $_REQUEST['otherID']);
SSViewer::setOption('rewriteHashlinks', false);
$result = $this->renderWith($this->class . "_right");
return $this->getLastFormIn($result);
}
/**
* Called when a mailing list is clicked on the left menu
*/
public function showrecipients($params) {
return $this->showWithEditForm( $params, $this->getMailingListEditForm( $params['ID'] ) );
}
/**
* Called when a draft or sent newsletter is clicked on the left menu and when a new one is added
*/
public function shownewsletter($params) {
return $this->showWithEditForm( $params, $this->getNewsletterEditForm( $params['ID'] ) );
}
/**
* Called when a newsletter type is clicked on the left menu
*/
public function showmailtype($params) {
return $this->showWithEditForm( $params, $this->getNewsletterTypeEditForm( $params['ID'] ) );
}
/**
* Called when a 'Drafts' folder is clicked on the left menu
*/
public function showdrafts($params) {
return $this->ShowNewsletterFolder($params, 'Draft');
}
/**
* Called when a 'Sent Items' folder is clicked on the left menu
*/
public function showsent($params) {
return $this->ShowNewsletterFolder($params, 'Sent');
}
/**
* Shows either the 'Sent' or 'Drafts' folder using the NewsletterList template
*/
public function ShowNewsletterFolder($params, $type) {
$id = $params['ID'];
if(!is_numeric($id)) {
$id = Session::get('currentPage');
}
if( is_a( $id, 'NewsletterType' ) ) {
$mailType = $id;
$id = $mailType->ID;
} else {
if($id && is_numeric($id)) {
$mailType = DataObject::get_by_id( 'NewsletterType', $id );
}
}
$draftList = new NewsletterList($type, $mailType, $type);
return $draftList->renderWith("NewsletterList");
}
public function removenewsletter($params) {
if( !is_numeric( $params['ID'] ) )
return '';
$newsletter = DataObject::get_by_id( 'Newsletter', $params['ID'] );
$newsletter->delete();
return 'letter-' . $params['ID'];
}
private function showWithEditForm( $params, $editForm ) {
if(isset($params['ID'])) {
Session::set('currentPage', $params['ID']);
}
if(isset($params['OtherID'])) {
Session::set('currentMember', $params['OtherID']);
}
if(Director::is_ajax()) {
SSViewer::setOption('rewriteHashlinks', false);
return $editForm->formHtmlContent();
} else {
return array();
}
}
public function getEditForm( $id ) {
return $this->getNewsletterTypeEditForm( $id );
}
/**
* Get the EditForm
*/
public function EditForm() {
if((isset($_REQUEST['ID']) && isset($_REQUEST['Type']) && $_REQUEST['Type'] == 'Newsletter') || isset($_REQUEST['action_savenewsletter'])) {
return $this->NewsletterEditForm();
} else {
// If a mailing list member is being added to a group, then call the Recipient form
if (isset($_REQUEST['fieldName']) && 'Recipients' == $_REQUEST['fieldName']) {
return $this->MailingListEditForm();
} else {
return $this->TypeEditForm();
}
}
}
public function NewsletterEditForm() {
$id = $_REQUEST['ID'] ? $_REQUEST['ID'] : $this->currentPageID();
if(!is_numeric($id)) {
$id = 0;
}
return $this->getNewsletterEditForm($id);
}
public function TypeEditForm() {
$id = isset($_REQUEST['ID']) ? $_REQUEST['ID'] : $this->currentPageID();
if(!is_numeric($id)) {
$id = 0;
}
return $this->getNewsletterTypeEditForm($id);
}
public function MailingListEditForm() {
$id = isset($_REQUEST['ID']) ? $_REQUEST['ID'] : $this->currentPageID();
return $this->getMailingListEditForm($id);
}
public function getNewsletterTypeEditForm($id) {
if(!is_numeric($id)) {
$id = Session::get('currentPage');
}
if( is_a( $id, 'NewsletterType' ) ) {
$mailType = $id;
$id = $mailType->ID;
} else {
if($id && is_numeric($id)) {
$mailType = DataObject::get_by_id( 'NewsletterType', $id );
}
}
if(isset($mailType) && is_object($mailType) && $mailType->GroupID) {
$group = DataObject::get_one("Group", "ID = $mailType->GroupID");
}
if(isset($mailType)&&$mailType) {
$fields = new FieldSet(
new TabSet("Root",
new Tab(_t('NewsletterAdmin.NLSETTINGS', 'Newsletter Settings'),
new TextField("Title", _t('NewsletterAdmin.NEWSLTYPE','Newsletter Type')),
new TextField("FromEmail", _t('NewsletterAdmin.FROMEM','From email address')),
$templates = new TemplateList("Template", _t('NewsletterAdmin.TEMPLATE', 'Template'), $mailType->Template, self::template_path())
)
)
);
$templates->setController($this);
$fields->push($idField = new HiddenField("ID"));
$fields->push( new HiddenField( "executeForm", "", "TypeEditForm" ) );
$idField->setValue($id);
$actions = new FieldSet(new FormAction('save', _t('NewsletterAdmin.SAVE', 'Save')));
$form = new Form($this, "EditForm", $fields, $actions);
$form->loadDataFrom(array(
'Title' => $mailType->Title,
'FromEmail' => $mailType->FromEmail
));
} else {
$form = false;
}
return $form;
}
public function getMailingListEditForm($id) {
if(!is_numeric($id)) {
$id = Session::get('currentPage');
}
if( is_a( $id, 'NewsletterType' ) ) {
$mailType = $id;
$id = $mailType->ID;
} else {
if($id && is_numeric($id)) {
$mailType = DataObject::get_by_id( 'NewsletterType', $id );
}
}
if(isset($mailType) && is_object($mailType) && $mailType->GroupID) {
$group = DataObject::get_one("Group", "ID = $mailType->GroupID");
}
if(isset($mailType) && is_object($mailType)) {
$fields = new FieldSet(
new TabSet("Root",
new Tab(_t('NewsletterAdmin.RECIPIENTS', 'Recipients'),
$recipients = new MemberTableField(
$this,
"Recipients",
$group
)
),
new Tab(_t('NewsletterAdmin.IMPORT', 'Import'),
$importField = new RecipientImportField("ImportFile",_t('NewsletterAdmin.IMPORTFROM', 'Import from file'), $group )
),
new Tab(_t('NewsletterAdmin.UNSUBSCRIBERS', 'Unsubscribers'),
$unsubscribedList = new UnsubscribedList("Unsubscribed", $mailType)
),
new Tab(_t('NewsletterAdmin.BOUNCED','Bounced'), $bouncedList = new BouncedList("Bounced", $mailType )
)
)
);
$recipients->setController($this);
$importField->setController($this);
$unsubscribedList->setController($this);
$bouncedList->setController($this);
$importField->setTypeID( $id );
$fields->push($idField = new HiddenField("ID"));
$fields->push( new HiddenField( "executeForm", "", "MailingListEditForm" ) );
$idField->setValue($id);
// Save button is not used in Mailing List section
$actions = new FieldSet(new HiddenField("save"));
$form = new Form($this, "EditForm", $fields, $actions);
$form->loadDataFrom(array(
'Title' => $mailType->Title,
'FromEmail' => $mailType->FromEmail
));
} else {
$form = false;
}
return $form;
}
/**
* Removes a bounced member from the mailing list
*
* @return String
*/
function removebouncedmember($urlParams) {
// First remove the Bounce entry
$id = Convert::raw2sql($urlParams['ID']);
if (is_numeric($id)) {
$bounceObject = DataObject::get_by_id('Email_BounceRecord', $id);
if($bounceObject) {
// Remove this bounce record
$bounceObject->delete();
$memberObject = DataObject::get_by_id('Member', $bounceObject->MemberID);
$groupID = Convert::raw2sql($_REQUEST['GroupID']);
if(is_numeric($groupID) && is_object($memberObject)) {
// Remove the member from the mailing list
$memberObject->Groups()->remove($groupID);
} else {
user_error("NewsletterAdmin::removebouncedmember: Bad parameters: Group=$groupID, Member=".$bounceObject->MemberID, E_USER_ERROR);
}
FormResponse::status_message($memberObject->Email.' '._t('NewsletterAdmin.REMOVEDSUCCESS', 'was removed from the mailing list'), 'good');
FormResponse::add("$('Form_EditForm').getPageFromServer($('Form_EditForm_ID').value, 'recipients');");
return FormResponse::respond();
}
} else {
user_error("NewsletterAdmin::removebouncedmember: Bad parameters: Group=$groupID, Member=".$bounceObject->MemberID, E_USER_ERROR);
}
}
/**
* Reloads the "Sent Status Report" tab via ajax
*/
function getsentstatusreport($params) {
if(Director::is_ajax()) {
$newsletter = DataObject::get_by_id( 'Newsletter', $params['ID'] );
$sent_status_report = $newsletter->renderWith("Newsletter_SentStatusReport");
return $sent_status_report;
}
}
public static function template_path() {
if(self::$template_path) return self::$template_path;
else return self::$template_path = project() . '/templates/email';
}
/* Does not seem to be used
public function showdraft( $params ) {
return $this->showWithEditForm( $params, $this->getNewsletterEditForm( $params['ID'] ) );
}
*/
public function getNewsletterEditForm($myId){
$email = DataObject::get_by_id("Newsletter", $myId);
if($email) {
$fields = $email->getCMSFields($this);
$fields->push($idField = new HiddenField("ID"));
$idField->setValue($myId);
$fields->push($ParentidField = new HiddenField("ParentID"));
$ParentidField->setValue($email->ParentID);
$fields->push($typeField = new HiddenField("Type"));
$typeField->setValue('Newsletter');
//$fields->push(new HiddenField("executeForm", "", "EditForm") );
$actions = new FieldSet();
if( $email->SentDate )
$actions->push(new FormAction('send',_t('NewsletterAdmin.RESEND','Resend')));
else
$actions->push(new FormAction('send',_t('NewsletterAdmin.SEND','Send...')));
$actions->push(new FormAction('save',_t('NewsletterAdmin.SAVE','Save')));
$form = new Form($this, "EditForm", $fields, $actions);
$form->loadDataFrom($email);
if($email->Status != 'Draft') {
$form->makeReadonly();
}
// user_error( $form->FormAction(), E_USER_ERROR );
return $form;
} else {
user_error( 'Unknown Email ID: ' . $myId, E_USER_ERROR );
}
}
public function SendProgressBar() {
$progressBar = new ProgressBar( 'SendProgressBar', _t('NewsletterAdmin.SENDING','Sending emails...') );
return $progressBar->FieldHolder();
}
public function sendnewsletter( /*$data, $form = null*/ ) {
$id = isset($_REQUEST['ID']) ? $_REQUEST['ID'] : $_REQUEST['NewsletterID'];
if( !$id ) {
FormResponse::status_message(_t('NewsletterAdmin.NONLSPECIFIED', 'No newsletter specified'),'bad');
return FormResponse::respond();
}
$newsletter = DataObject::get_by_id("Newsletter", $id);
$nlType = $newsletter->getNewsletterType();
$e = new Newsletter_Email($nlType);
$e->Body = $body = $newsletter->Content;
$e->Subject = $subject = $newsletter->Subject;
// TODO Make this dynamic
if( $nlType && $nlType->FromEmail )
$e->From = $from = $nlType->FromEmail;
else
$e->From = $from = Email::getAdminEmail();
if(isset($_REQUEST['TestEmail'])) $e->To = $_REQUEST['TestEmail'];
$e->setTemplate( $nlType->Template );
$messageID = base64_encode( $newsletter->ID . '_' . date( 'd-m-Y H:i:s' ) );
switch($_REQUEST['SendType']) {
case "Test":
if($_REQUEST['TestEmail']) {
$e->To = $_REQUEST['TestEmail'];
$e->setTemplate( $nlType->Template );
self::sendToAddress( $e, $_REQUEST['TestEmail'], $messageID );
FormResponse::status_message(_t('NewsletterAdmin.SENTTESTTO','Sent test to ') . $_REQUEST['TestEmail'],'good');
} else {
FormResponse::status_message(_t('NewsletterAdmin.PLEASEENTERMAIL','Please enter an email address'),'bad');
}
break;
case "List":
// Send to the entire mailing list.
$groupID = $nlType->GroupID;
echo self::sendToList( $subject, $body, $from, $newsletter, $nlType, $messageID,
DataObject::get( 'Member', "`GroupID`='$groupID'", null, "INNER JOIN `Group_Members` ON `MemberID`=`Member`.`ID`" )
);
break;
case "Unsent":
// Send to only those who have not already been sent this newsletter.
$only_to_unsent = 1;
echo self::sendToList( $subject, $body, $from, $newsletter, $nlType, $messageID, $newsletter->UnsentSubscribers());
break;
}
return FormResponse::respond();
}
static function sendToAddress( $email, $address, $messageID = null ) {
$email->To = $address;
$email->send();
}
static function sendToList( $subject, $body, $from, $newsletter, $nlType, $messageID = null, $recipients) {
$emailProcess = new NewsletterEmailProcess( $subject, $body, $from, $newsletter, $nlType, $messageID, $recipients);
return $emailProcess->start();
}
public function save($urlParams, $form) {
// Both the Newsletter type and the Newsletter draft call save() when "Save" button is clicked
if( isset($_REQUEST['Type']) && $_REQUEST['Type'] == 'Newsletter' )
return $this->savenewsletter( $urlParams, $form );
$id = $_REQUEST['ID'];
$className = 'NewsletterType';
$record = DataObject::get_one($className, "`$className`.ID = $id");
// Is the template attached to the type, or the newsletter itself?
$record->Template = addslashes( $_REQUEST['Template'] );
$form->saveInto($record);
$record->write();
FormResponse::set_node_title("mailtype_$id", $record->Title);
FormResponse::status_message(_t('NewsletterAdmin.SAVED','Saved'), 'good');
$result = $this->getActionUpdateJS($record);
return FormResponse::respond();
}
public function savenewsletter($urlParams, $form) {
$id = $_REQUEST['ID'];
$className = 'Newsletter';
$record = DataObject::get_one($className, "`$className`.ID = $id");
// Is the template attached to the type, or the newsletter itself?
$type = $record->getNewsletterType();
$record->Subject = $urlParams['Subject'];
$record->Content = $urlParams['Content'];
$record->write();
$id = 'draft_'.$record->ParentID.'_'.$record->ID;
FormResponse::set_node_title($id, $record->Title);
FormResponse::status_message('Saved', 'good');
// Get the new action buttons
$actionList = '';
foreach($form->Actions() as $action) {
$actionList .= $action->Field() . ' ';
}
FormResponse::add("$('Form_EditForm').loadActionsFromString('" . Convert::raw2js($actionList) . "');");
return FormResponse::respond();
}
/*
* Saves the settings on the 'Bounced' tab of the 'Mailing List' allowing members to be added to Email_BlackList
*
*/
public function memberblacklisttoggle($urlParams) {
$id = $urlParams['ID'];
$bounceObject = DataObject::get_by_id('Email_BounceRecord', $id);
$memberObject = DataObject::get_by_id('Member', $bounceObject->MemberID);
// If the email is currently not blocked, block it
if (FALSE == $memberObject->BlacklistedEmail) {
$memberObject->setBlacklistedEmail(TRUE);
FormResponse::status_message($memberObject->Email.' '._t('NewsletterAdmin.ADDEDTOBL', 'was added to blacklist'), 'good');
} else {
// Unblock the email
$memberObject->setBlacklistedEmail(FALSE);
FormResponse::status_message($memberObject->Email.' '._t('NewsletterAdmin.REMOVEDFROMBL','was removed from blacklist'), 'good');
}
return FormResponse::respond();
}
function NewsletterAdminSiteTree() {
return $this->getsitetree();
}
function getsitetree() {
return $this->renderWith('NewsletterAdmin_SiteTree');
}
public function AddRecordForm() {
$m = new MemberTableField($this,"Members", $this->currentPageID());
return $m->AddRecordForm();
}
/**
* Ajax autocompletion
*/
public function autocomplete() {
$fieldName = $this->urlParams['ID'];
$fieldVal = $_REQUEST[$fieldName];
$matches = DataObject::get("Member","$fieldName LIKE '" . addslashes($fieldVal) . "%'");
if($matches) {
echo "<ul>";
foreach($matches as $match) {
$data = $match->FirstName;
$data .= ",$match->Surname";
$data .= ",$match->Email";
$data .= ",$match->Password";
echo "<li>" . $match->$fieldName . "<span class=\"informal\">($match->FirstName $match->Surname, $match->Email)</span><span class=\"informal data\">$data</li>";
}
echo "</ul>";
}
}
function savemember() {
$data = $_REQUEST;
$className = $this->stat('subitem_class');
$id = $_REQUEST['ID'];
if($id == 'new') $id = null;
if($id) {
$record = DataObject::get_one($className, "`$className`.ID = $id");
} else {
// send out an email to notify the user that they have been subscribed
$record = new $className();
}
$record->update($data);
$record->ID = $id;
$record->write();
$record->Groups()->add($data['GroupID']);
$FirstName = Convert::raw2js($record->FirstName);
$Surname = Convert::raw2js($record->Surname);
$Email = Convert::raw2js($record->Email);
$Password = Convert::raw2js($record->Password);
$response = <<<JS
$('MemberList').setRecordDetails($record->ID, {
FirstName : "$FirstName",
Surname : "$Surname",
Email : "$Email"
});
$('MemberList').clearAddForm();
JS;
FormResponse::add($response);
FormResponse::status_message(_t('NewsletterAdmin.SAVED'), 'good');
return FormResponse::respond();
}
public function NewsletterTypes() {
return DataObject::get("NewsletterType","");
}
public function addgroup() {
$parent = $_REQUEST['ParentID'] ? $_REQUEST['ParentID'] : 0;
$p = new Group();
$p->Title = "New Group";
$p->Code = "new-group";
$p->ParentID = $parent;
$p->write();
$this->returnItemToUser($p);
}
/**
* Called by AJAX to create a new newsletter type
*
*/
public function addtype( $params ) {
$form = $this->getNewsletterTypeEditForm( $this->newNewsletterType() );
return $this->showWithEditForm( $_REQUEST, $form );
}
/**
* Called by AJAX to create a new newsletter draft
*
*/
public function adddraft( $data) {
$draftID = $this->newDraft( $_REQUEST['ParentID'] );
// Needed for shownewsletter() to work
$_REQUEST['ID'] = $draftID;
return $this->shownewsletter($_REQUEST);
}
/**
* Create a new newsletter type
*/
private function newNewsletterType() {
// create a new group for the newsletter
$newGroup = new Group();
$newGroup->Title = _t('NewsletterAdmin.NEWLIST','New mailing list');
$newGroup->Code = "new-mailing-list";
$newGroup->write();
// create the new type
$newsletterType = new NewsletterType();
$newsletterType->Title = _t('NewsletterAdmin.NEWNEWSLTYPE','New newsletter type');
$newsletterType->GroupID = $newGroup->ID;
$newsletterType->write();
// BUGFIX: Return only the ID of the new newsletter type
return $newsletterType->ID;
}
private function newDraft( $parentID ) {
if(!$parentID || !is_numeric( $parentID)) {
$parent = DataObject::get_one("NewsletterType");
if ($parent) {
$parentID = $parent->ID;
} else {
// BUGFIX: It could be that no Newsletter types have been created, if so add one to prevent errors.
$parentID = $this->newNewsletterType();
}
}
if( $parentID && is_numeric( $parentID ) ) {
$parent = DataObject::get_by_id("NewsletterType", $parentID);
// BUGFIX: It could be that no Newsletter types have been created, if so add one to prevent errors.
if(!$parent) {
$parentID = $this->newNewsletterType();
}
$newsletter = new Newsletter();
$newsletter->Status = 'Draft';
$newsletter->Title = $newsletter->Subject = _t('NewsletterAdmin.MEWDRAFTMEWSL','New draft newsletter');
$newsletter->ParentID = $parentID;
$newsletter->write();
} else {
user_error( "You must first create a newsletter type before creating a draft", E_USER_ERROR );
}
return $newsletter->ID;
}
public function newmember() {
Session::clear('currentMember');
$newMemberForm = array(
"MemberForm" => $this->getMemberForm('new'),
);
if(Director::is_ajax()) {
SSViewer::setOption('rewriteHashlinks', false);
$customised = $this->customise($newMemberForm);
$result = $customised->renderWith($this->class . "_rightbottom");
$parts = split('</?form[^>]*>', $result);
echo $parts[1];
} else {
return $newMemberForm;
}
}
public function EditedMember() {
if(Session::get('currentMember'))
return DataObject::get_by_id("Member", Session::get('currentMember'));
}
public function Link($action = null) {
if(!$action) $action = "index";
return "admin/newsletter/$action/" . $this->currentPageID();
}
public function displayfilefield() {
$id = $this->urlParams['ID'];
return $this->customise( array( 'ID' => $id, "UploadForm" => $this->UploadForm() ) )->renderWith('Newsletter_RecipientImportField');
}
function UploadForm( $id = null ) {
if( !$id )
$id = $this->urlParams['ID'];
$fields = new FieldSet(
new FileField( "ImportFile", "" ),
//new HiddenField( "action_import", "", "1" ),
new HiddenField( "ID", "", $id )
);
$actions = new FieldSet(
new FormAction( "action_import", _t('NewsletterAdmin.SHOWCONTENTS','Show contents') )
);
return new RecipientImportField_UploadForm( $this, "UploadForm", $fields, $actions );
}
}
?>

View File

@ -1,40 +0,0 @@
/**
* SiteTree
*/
ul.tree span.a.MailType,
ul.tree span.a.last.MailType,
ul.tree span.a.children.MailType {
background-image: none;
}
ul.tree span.a.MailType span.c,
ul.tree span.a.last.MailType span.c,
ul.tree span.a.children.MailType span.c {
margin: 0;
}
/**
* Form
*/
div#ImportFile iframe {
width: 80%;
height: auto;
border: none;
}
table.ReportField {
position: relative;
border: solid 1px #82C0FF;
border-collapse: collapse;
}
table.ReportField thead th {
background-color: #82C0FF;
}
table.ReportField td, table.ReportField {
border: solid 1px #82C0FF;
}
table.ReportField tr {
border-bottom: solid 1px #82C0FF;
}

View File

@ -1,409 +0,0 @@
if(typeof SiteTreeHandlers == 'undefined') SiteTreeHandlers = {};
SiteTreeHandlers.showNLDraft_url = 'admin/newsletter/shownewsletter/';
SiteTreeHandlers.showNLType_url = 'admin/newsletter/showtype/';
SiteTreeHandlers.controller_url = 'admin/newsletter';
SiteTree.prototype = {
castAsTreeNode: function(li) {
behaveAs(li, SiteTreeNode, this.options);
},
getIdxOf : function(treeNode) {
if(treeNode && treeNode.id)
return treeNode.id;
},
getTreeNodeByIdx : function(idx) {
if(!idx) idx = "0";
return document.getElementById(idx);
},
initialise: function() {
this.observeMethod('SelectionChanged', this.changeCurrentTo);
},
createTreeNode : function(idx, title, pageType, secondIdx) {
var i;
var node = document.createElement('li');
node.className = pageType;
var aTag = document.createElement('a');
node.id = idx;
if( pageType == 'Draft' ) {
aTag.href = SiteTreeHandlers.showNLDraft_url + idx;
} else {
aTag.href = SiteTreeHandlers.showNLType_url + idx;
}
aTag.innerHTML = title;
node.appendChild(aTag);
SiteTreeNode.create(node, this.options);
return node;
},
addDraftNode: function( title, parentID, draftID ) {
var st = $('sitetree');
// BUGFIX: If there is nothing in the left tree we need to add a Newsletter type first to prevent errors
if(typeof st.lastTreeNode() == 'undefined') {
$('sitetree').addTypeNode('New newsletter type', $('Form_EditForm_ID').value );
}
// BUGFIX: If no selection is made in the left tree, and a draft is added, parentID won't be set,
// so we need to use the value from the Draft edit form.
parentID = $('Form_EditForm_ParentID').value;
var draftNode = this.createTreeNode( 'draft_' + parentID + '_' + draftID, title, 'Draft', parentID );
this.getTreeNodeByIdx('drafts_' + parentID).appendTreeNode( draftNode );
this.changeCurrentTo( draftNode );
},
addTypeNode: function( title, parentID ) {
var typeNode = this.createTreeNode( 'mailtype_' + parentID, title, 'MailType' );
var draftsNode = this.createTreeNode( 'drafts_' + parentID, 'Drafts', 'DraftFolder' );
var sentItemsNode = this.createTreeNode( 'sent_' + parentID, 'Sent Items', 'SentFolder' );
var mailingListNode = this.createTreeNode( 'recipients_' + parentID, 'Mailing List', 'Recipients' );
typeNode.appendTreeNode( draftsNode );
Element.addClassName( draftsNode, 'nodelete');
typeNode.appendTreeNode( sentItemsNode );
Element.addClassName(sentItemsNode,'nodelete');
typeNode.appendTreeNode( mailingListNode );
Element.addClassName(mailingListNode,'nodelete');
this.appendTreeNode( typeNode );
this.changeCurrentTo( typeNode );
// Change the 'Create...' drop-down to 'Add a draft' since this will be the logical next action after a Newsletter type is created
$('add_type').value = 'draft';
}
}
/**
* Delete pages action
*/
deletedraft = {
button_onclick : function() {
if(treeactions.toggleSelection(this)) {
deletedraft.o1 = $('sitetree').observeMethod('SelectionChanged', deletedraft.treeSelectionChanged);
deletedraft.o2 = $('deletedrafts_options').observeMethod('Close', deletedraft.popupClosed);
addClass($('sitetree'),'multiselect');
var sel = $('sitetree').firstSelected();
if(sel) {
var selIdx = $('sitetree').getIdxOf(sel);
deletedraft.selectedNodes = { };
deletedraft.selectedNodes[selIdx] = true;
sel.removeNodeClass('current');
sel.addNodeClass('selected');
}
}
return false;
},
treeSelectionChanged : function(selectedNode) {
var idx = $('sitetree').getIdxOf(selectedNode);
if(selectedNode.selected) {
selectedNode.removeNodeClass('selected');
selectedNode.selected = false;
deletedraft.selectedNodes[idx] = false;
} else {
selectedNode.addNodeClass('selected');
selectedNode.selected = true;
deletedraft.selectedNodes[idx] = true;
}
return false;
},
popupClosed : function() {
removeClass($('sitetree'),'multiselect');
$('sitetree').stopObserving(deletedraft.o1);
$('deletedrafts_options').stopObserving(deletedraft.o2);
for(var idx in deletedraft.selectedNodes) {
if(deletedraft.selectedNodes[idx]) {
node = $('sitetree').getTreeNodeByIdx(idx);
if(node) {
node.removeNodeClass('selected');
node.selected = false;
}
}
}
},
form_submit : function() {
var csvIDs = "";
for(var idx in deletedraft.selectedNodes) {
if(deletedraft.selectedNodes[idx]) csvIDs += (csvIDs ? "," : "") + idx;
}
if(csvIDs) {
if(confirm("Do you really want to these Newsletter items?")) {
$('deletedrafts_options').elements.csvIDs.value = csvIDs;
Ajax.SubmitForm('deletedrafts_options', null, {
onSuccess : function(response) {
Ajax.Evaluator(response);
var sel;
if((sel = $('sitetree').selected) && sel.parentNode) sel.addNodeClass('current');
// else $('Form_EditForm').innerHTML = "";
treeactions.closeSelection($('deletedrafts'));
},
onFailure : function(response) {
errorMessage('Error deleting drafts', response);
}
});
$('deletedrafts').getElementsByTagName('button')[0].onclick();
}
} else {
alert("Please select at least 1 Newsletter item.");
}
return false;
},
treeSelectionChanged : function(selectedNode) {
var idx = $('sitetree').getIdxOf(selectedNode);
if( !deletedraft.selectedNodes )
deletedraft.selectedNodes = {};
if(selectedNode.className.indexOf('nodelete') == -1) {
if(selectedNode.selected) {
selectedNode.removeNodeClass('selected');
selectedNode.selected = false;
deletedraft.selectedNodes[idx] = false;
} else {
selectedNode.addNodeClass('selected');
selectedNode.selected = true;
deletedraft.selectedNodes[idx] = true;
}
}
return false;
}
}
SiteTreeNode.prototype.onselect = function() {
// Change the 'Create...' drop-down to 'Add a draft' whenever a selection is made in the left tree
$('add_type').value = 'draft';
$('sitetree').changeCurrentTo(this);
if($('sitetree').notify('SelectionChanged', this)) {
autoSave(true, this.getPageFromServer.bind(this));
}
return false;
};
SiteTreeNode.prototype.getPageFromServer = function() {
var match = this.id.match(/(mailtype|drafts|draft|sent|recipients)_([\d]+)$/);
var openTabName = null;
var currentPageID = null;
if( $('Form_EditForm_ID') )
currentPageID = $('Form_EditForm_ID').value;
var newPageID = null;
var otherID = null;
var type = null;
if( match ) {
newPageID = match[2];
type = match[1];
} else if(this.id.match(/(mailtype|drafts|draft|sent|recipients)_([\d]+)_([\d]+)$/)) {
newPageID = RegExp.$2;
type = RegExp.$1;
otherID = RegExp.$3;
}
$('Form_EditForm').getPageFromServer(newPageID, type, otherID, openTabName);
};
function draft_sent_ok( newsletterID, draftID, numEmails ) {
var draftsListNode = $('drafts_' + newsletterID);
var sentListNode = $('sent_' + newsletterID);
var draftNode = $('draft_' + newsletterID + '_' + draftID );
draftsListNode.removeTreeNode( draftNode );
draftNode.id = 'sent_' + newsletterID + '_' + draftID;
sentListNode.appendTreeNode( draftNode, null );
statusMessage('Sent newsletter to mailing list. Sent ' + numEmails + ' emails successfully.', 'good');
}
function resent_ok( newsletterID, sentID, numEmails ) {
statusMessage('Resent newsletter to mailing list. Sent ' + numEmails + ' emails successfully.', 'good');
}
function reloadSiteTree() {
new Ajax.Request( 'admin/newsletter/getsitetree', {
method: get,
onSuccess: function( response ) {
$('sitetree_holder').innerHTML = response.responseText;
},
onFailure: function( response ) {
}
});
}
_HANDLER_FORMS['addtype'] = 'addtype_options';
_HANDLER_FORMS['deletedrafts'] = 'deletedrafts_options';
AddForm = Class.extend('addpage');
AddForm.applyTo('#addtype');
AddForm.prototype = {
initialize: function () {
Observable.applyTo($(_HANDLER_FORMS[this.id]));
this.getElementsByTagName('button')[0].onclick = function() {
var st = $('sitetree');
if (st) {
// Select 'Add new draft' if the left tree is not empty,
// because, most likely, the user will want to add a new draft if they already have a newsletter type
if (typeof st.lastTreeNode() != 'undefined') {
$('add_type').value = 'draft';
} else {
$('add_type').value = 'type';
}
} else {
$('add_type').value = 'type';
}
}
$(_HANDLER_FORMS[this.id]).onsubmit = this.form_submit;
},
form_submit : function() {
var st = $('sitetree');
if (st) {
if( st.selected && st.selected.length ) {
selectedNode = st.selected[0];
} else {
selectedNode = st.selected;
}
} else {
var selectedNode = null;
}
var parentID = null;
while( selectedNode && !parentID ) {
if( selectedNode && selectedNode.id && selectedNode.id.match(/mailtype_([0-9a-z\-]+)$/) )
parentID = RegExp.$1;
else
selectedNode = selectedNode.parentNode;
}
if(parentID && parentID.substr(0,3) == 'new') {
alert("You have to save a page before adding children underneath it");
} else {
if (this.elements) {
this.elements.ParentID.value = parentID;
}
var type = 'draft';
var selectIDPrefix = 'draft_' + parentID + '_';
if( $('add_type').value == 'type' ) {
type = 'type';
selectIDPrefix = 'mailtype_';
}
// Call either addtype or adddraft
var request = new Ajax.Request( this.action + type + '?ajax=1' + '&ParentID=' + parentID, {
method: 'get',
asynchronous: true,
onSuccess : function( response ) {
$('Form_EditForm').loadNewPage(response.responseText);
// create a new node and add it to the site tree
if( type == 'draft' ) {
$('sitetree').addDraftNode('New draft newsletter', parentID, $('Form_EditForm_ID').value );
} else {
$('sitetree').addTypeNode('New newsletter type', $('Form_EditForm_ID').value );
}
statusMessage('Added new ' + type);
},
onFailure : function(response) {
alert(response.responseText);
statusMessage('Could not add new ' + type );
}
});
}
return false;
},
reloadSiteTree: function( response ) {
statusMessage('Added new newsletter type', 'good' );
$('sitetree_holder').innerHTML = response.responseText;
Behaviour.apply( $('sitetree_holder') );
},
button_onclick : function() {
if(treeactions.toggleSelection(this)) {
var selectedNode = $('sitetree').firstSelected();
if(selectedNode) {
while(selectedNode.parentTreeNode && !selectedNode.hints.defaultChild) {
$('sitetree').changeCurrentTo(selectedNode.parentTreeNode);
selectedNode = selectedNode.parentTreeNode;
}
}
this.o1 = $('sitetree').observeMethod('SelectionChanged', this.treeSelectionChanged.bind(this));
this.o2 = $(_HANDLER_FORMS[this.id]).observeMethod('Close', this.popupClosed.bind(this));
}
return false;
},
treeSelectionChanged: function( treeNode ) {
this.selected = treeNode;
},
popupClosed: function() {
$('sitetree').stopObserving(this.o1);
$(_HANDLER_FORMS.addtype).stopObserving(this.o2);
}
}
function removeTreeNodeByIdx( tree, nodeID ) {
var node = tree.getTreeNodeByIdx( nodeID );
if( node )
if( node.parentTreeNode )
node.parentTreeNode.removeTreeNode( node );
else
$('sitetree').removeTreeNode( node );
}
/**
* Initialisation function to set everything up
*/
Behaviour.addLoader(function () {
// Set up add draft
Observable.applyTo($('addtype_options'));
if( $('addtype') ) {
if( AddForm.button_click )
$('addtype').getElementsByTagName('a')[0].onclick = function() {return false;};
if( AddForm.button_click )
$('addtype_options').onsubmit = AddForm.form_submit;
}
// Set up delete drafts
Observable.applyTo($('deletedrafts_options'));
var deleteDrafts = $('deletedrafts');
if( deleteDrafts ) {
deleteDrafts.onclick = deletedraft.button_onclick;
deleteDrafts.getElementsByTagName('button')[0].onclick = function() {return false;};
$('deletedrafts_options').onsubmit = deletedraft.form_submit;
}
});

View File

@ -1,568 +0,0 @@
function action_send_right() {
$('action_send_options').toggle();
}
/**
* Hides the drop-down Send newsletter form if Cancel button is clicked
*/
Behaviour.register( {
'#action_send_cancel': {
onclick : function() {
$('action_send_options').toggle();
return false;
}
}
});
// Called when checkbox on Bounced tab of Mailing List is clicked
Behaviour.register( {
'#BouncedListTable tr td.markingcheckbox input': {
onclick : function(e) {
new Ajax.Request(
'admin/newsletter/memberblacklisttoggle/' + this.value,
{
method: 'post',
postBody: 'forceajax=1',
onComplete: function(response){
Ajax.Evaluator(response);
}.bind(this),
onFailure: ajaxErrorHandler
}
);
}
}
});
// Don't show unsaved changes confirm() for changes to Bounced tab checkboxes
Behaviour.register({
'#Form_EditForm' : {
changeDetection_fieldsToIgnore : {
'BouncedList[]' : true
}
}
});
// Called when X link on Bounced tab of Mailing List is clicked (adapted from TableListField.js)
Behaviour.register( {
'#BouncedListTable a.deletelink': {
onclick : function(e) {
var img = Event.element(e);
var link = Event.findElement(e,"a");
var row = Event.findElement(e,"tr");
var confirmed = confirm("Are you sure you want to remove this recipient from your mailing list?");
if(confirmed)
{
img.setAttribute("src",'cms/images/network-save.gif');
new Ajax.Request(
link.getAttribute("href"),
{
method: 'post',
postBody: 'forceajax=1',
onComplete: function(response){
Effect.Fade(row);
Ajax.Evaluator(response);
}.bind(this),
onFailure: ajaxErrorHandler
}
);
}
Event.stop(e);
}
}
});
CMSForm.applyTo('#Form_MemberForm','rightbottom');
Behaviour.register({
'#Form_EditForm' : {
initialise : function() {
this.openTab = null;
this.prepareForm();
},
/**
* Processing called whenever a page is loaded in the right - including the initial one
*/
prepareForm : function() {
ajaxActionsAtTop('Form_EditForm', 'form_actions_right', 'right');
},
/**
* Request a page from the server via Ajax
*/
getPageFromServer : function(id, type, otherid,openTabName) {
this.openTab = openTabName;
if(id && parseInt(id) == id) {
this.receivingID = id;
// Treenode might not exist if that part of the tree is closed
var treeNode = $('sitetree').getTreeNodeByIdx(id);
if(treeNode) treeNode.addNodeClass('loading');
statusMessage("loading...");
var requestURL = 'admin/newsletter/show' + type + '/' + id;
if( otherid ) {
requestURL = 'admin/newsletter/shownewsletter/' + otherid;
}
new Ajax.Request(baseHref() + requestURL, {
asynchronous : true,
method : 'post',
postBody : /*'ID=' + id + 'type=' + type + */'ajax=1'+ (otherid?('&otherid='+otherid):''),
onSuccess : this.successfullyReceivedPage.bind(this),
onFailure : function(response) {
errorMessage('error loading page',response);
}
});
// Hide the action buttons if 'Drafts' or 'Sent Items' is clicked on
if ('drafts' == type || 'sent' == type)
{
Element.hide('form_actions');
Element.hide('form_actions_right');
}
} else {
throw("getPageFromServer: Bad page ID: " + id);
}
},
successfullyReceivedPage : function(response) {
this.loadNewPage(response.responseText);
// Treenode might not exist if that part of the tree is closed
var treeNode = $('sitetree').getTreeNodeByIdx(this.receivingID);
if(treeNode) {
$('sitetree').changeCurrentTo(treeNode);
treeNode.removeNodeClass('loading');
}
statusMessage('');
onload_init_tabstrip();
if( this.openTab ) {
openTab( this.openTab );
this.openTab = null;
}
},
didntReceivePage : function(response) {
errorMessage('error loading page', response);
$('sitetree').getTreeNodeByIdx(this.elements.ID.value).removeNodeClass('loading');
},
/**
* Load a new page into the right-hand form
*/
loadNewPage : function(formContent) {
rightHTML = formContent;
rightHTML = rightHTML.replace(/href *= *"#/g, 'href="' + window.location.href.replace(/#.*$/,'') + '#');
// Prepare iframes for removal, otherwise we get loading bugs
var i, allIframes = this.getElementsByTagName('iframe');
if(allIframes) for(i=0;i<allIframes.length;i++) {
allIframes[i].contentWindow.location.href = 'about:blank';
allIframes[i].parentNode.removeChild(allIframes[i]);
}
this.innerHTML = rightHTML;
allIframes = this.getElementsByTagName('iframe');
if(allIframes) for(i=0;i<allIframes.length;i++) {
try {
allIframes[i].contentWindow.location.href = allIframes[i].src;
} catch(er) {alert('Error in NewsletterAdmin_right.js #Form_EditForm::loadNewPage(): ' + er.message);}
}
_TAB_DIVS_ON_PAGE = [];
try {
var tabs = document.getElementsBySelector('#Form_EditForm ul.tabstrip');
} catch(er) {/* alert('a: '+ er.message + '\n' + er.line);*/ }
try {
for(var i=0;i<tabs.length;i++) if(tabs[i].tagName) initTabstrip(tabs[i]);
} catch(er) { /*alert('b: '+ er.message + '\n' + er.line); */}
if((typeof tinyMCE != 'undefined') && tinyMCE.instances) {
tinyMCE.instances = [];
tinyMCE.isLoaded = false;
tinyMCE.onLoad();
}
onload_init_tabstrip();
// if(this.prepareForm) this.prepareForm();
Behaviour.apply($('Form_EditForm'));
if(this.prepareForm)
this.prepareForm();
this.resetElements();
window.ontabschanged();
},
/**
* Save the contens of the form, by submitting it and resetting is changed checker
* on success.
*/
save: function(ifChanged, callAfter) {
_AJAX_LOADING = true;
if(typeof tinyMCE != 'undefined') tinyMCE.triggerSave();
var __callAfter = callAfter;
var __form = this;
if(__form.notify) __form.notify('BeforeSave', __form.elements.ID.value);
var success = function(response) {
Ajax.Evaluator(response);
__form.resetElements();
if(__callAfter) __callAfter();
if(__form.notify) __form.notify('PageSaved', __form.elements.ID.value);
_AJAX_LOADING = false;
}
var action = 'action_save';
if(ifChanged) {
var data = this.serializeChangedFields('ID') + '&ajax=1&' + action + '=1';
} else {
var data = this.serializeAllFields() + '&ajax=1&' + action + '=1';
}
// alert(this.action + '\n\n' + data);
new Ajax.Request(this.action, {
method : this.method,
postBody: data,
onSuccess : success,
onFailure : function(response) {
alert(response.responseText);
errorMessage('Error saving content', response);
_AJAX_LOADING = false;
}
});
}
}
});
Behaviour.register({
'#action_send_options' : {
/**
* Open the form
*/
open : function() {
this.elements.NewsletterID.value = $('Form_EditForm').elements.ID.value;
var allInputs = this.getElementsByTagName('input');
this.submitButton = allInputs[allInputs.length-1];
this.submitButton.onclick = this.send.bind(this);
this.style.display = '';
},
close : function() {
this.style.display = 'none';
},
toggle : function() {
if(this.style.display == '') this.close();
else this.open();
},
send_test: function() {
// Show a "submitting..." box
if(!this.sendingText) {
this.sendingText = document.createElement('div');
this.sendingText.innerHTML = 'Sending newsletter...';
this.sendingText.className = 'sendingText';
Element.setOpacity(this.sendingText, 0.9);
this.appendChild(this.sendingText);
}
this.sendingText.style.display = '';
// Save always because change detection doesn't work for IE on newly created drafts.
// Use onclick instead of form.save() to make things work in IE.
$('Form_EditForm_action_save').onclick();
// Send the request
ajaxSubmitForm(false, this.onCompleteTest.bind(this), this, '', 'sendnewsletter')
return false;
},
/**
* Called by AJAX when 'Send newsletter' button is clicked
*
*/
send: function() {
// If 'Send to the entire mailing list' option is chosen
if( $('SendTypeList').checked) {
return this.send_to_list('List');
// If 'Send to only people not previously sent to' option is chosen
} else if ($('SendTypeUnsent').checked) {
return this.send_to_list('Unsent');
} else {
return this.send_test();
}
},
/**
* Submit the option form and carry out the action
*
* @param sendType string 'List' if sending to entire list and 'Unsent' if only sending to people not previously sent to
*/
send_to_list : function(sendType) {
// Show a "submitting..." box
/*if(!this.sendingText) {
this.sendingText = document.createElement('div');
this.sendingText.innerHTML = 'Sending newsletter...';
this.sendingText.className = 'sendingText';
Element.setOpacity(this.sendingText, 0.9);
this.appendChild(this.sendingText);
}
this.sendingText.style.display = '';*/
// Save always because change detection doesn't work for IE on newly created drafts.
// Use onclick instead of form.save() to make things work in IE.
$('Form_EditForm_action_save').onclick();
if( $('SendProgressBar') )
$('SendProgressBar').start();
// Send the request
Ajax.SubmitForm( $('Form_EditForm'), 'action_sendnewsletter', {
extraData: '&SendType=' + sendType,
onSuccess: this.incrementProcess.bind(this),
onFailure: function(response) {
statusMessage(response.responseText);
}
});
/*var form = $('Form_EditForm');
var data = form.serializeChangedFields('ID','type') + '&ajax=1&action_savenewsletter=1&SendType=List';
new Ajax.Request(form.action, {
method : form.method,
postBody: data,
onSuccess : this.incrementProcess.bind(this),
onFailure : function(response) {
errorMessage('Error sending to mailing list', response);
}
});*/
return false;
},
incrementProcess: function( response ) {
var processParts = response.responseText.match( /(\d+):(\d+)\/(\d+)/ );
if( !processParts || parseInt( processParts[2] ) >= parseInt( processParts[3] ) ) {
this.onComplete( response );
return;
}
// update the progress bar
$('SendProgressBar').setProgress( ( parseInt( processParts[2] ) / parseInt( processParts[3] ) ) * 100 );
var estimate = $('SendProgressBar').estimateTime();
$('SendProgressBar').setText( 'Sent ' + processParts[2] + ' of ' + processParts[3] + '. ' + estimate + ' remaining...' );
// set the action to the batch process controller
var updateRequest = baseHref() + 'processes/next/' + processParts[1] + '/10?ajax=1';
var request = new Ajax.Request( updateRequest, {
onSuccess: this.incrementProcess.bind(this),
onFailure: function( response ) {
errorMessage( response.responseText );
}
});
},
/**
* Process the action's Ajax response
*/
onComplete: function( response ) {
// $('SendProgressBar').setProgress( 100 );
// $('SendProgressBar').setText( 'Done!' );
$('SendProgressBar').reset();
// this.elements.Message.value = '';
// Reload the "Sent Status Report" tab after a Newsletter is sent
var id = this.elements.NewsletterID.value;
var request = new Ajax.Request(baseHref() + 'admin/newsletter/getsentstatusreport/' + id + '?ajax=1', {
onSuccess: function( response ) {
$('Root_SentStatusReport').innerHTML = response.responseText;
},
onFailure: function(response) {
statusMessage('Could not automatically refresh Sent Status Report tab', 'bad');
}
});
this.close();
if( response )
Ajax.Evaluator(response);
},
onCompleteTest: function( response ) {
// this.sendingText.innerHTML = '';
if( this.sendingText.parentNode == this )
this.removeChild( this.sendingText );
this.close();
if( response )
Ajax.Evaluator(response);
}
}
});
Behaviour.register({
/**
* When the iframe has loaded, apply the listeners
*/
'div#ImportFile' : {
frameLoaded: function( doc ) {
this.showTable = true;
var fileField = doc.getElementsByTagName('input')[0];
var idField = doc.getElementsByTagName('input')[1];
idField.value = $('Form_EditForm_ID').value;
fileField.onchange = this.selectedFile.bind(this);
},
loadTable: function( doc ) {
this.innerHTML = doc.getElementsByTagName('body')[0].innerHTML;
}
}
});
// @TODO: Check if this code is used anymore now that NewsletterList was removed.
NewsletterList = Class.create();
NewsletterList.applyTo('table.NewsletterList');
NewsletterList.prototype = {
initialize: function() {
this.tableBody = this.getElementsByTagName('tbody')[0];
this.deleteLinks = this.getElementsByTagName('a');
for( var i = 0; i < this.deleteLinks.length; i++ ) {
this.deleteLinks[i].onclick = this.deleteNewsletter.bindAsEventListener(this);
}
},
deleteNewsletter: function( event ) {
var link = event.target;
if( event.srcElement )
link = event.srcElement;
var rowNode = link.parentNode.parentNode;
new Ajax.Request( link.href, {
onSuccess: this.removeRow,
onFailure: function( response ) {
alert('The newsletter could not be deleted');
}
});
},
removeRow: function( response ) {
this.tableBody.removeChild( $(response.responseText) );
}
}
/**
* Handle auto-saving. Detects if changes have been made, and if so save everything on the page.
* If confirmation is true it will ask for confirmation.
*/
function autoSave(confirmation, callAfter) {
if(typeof tinyMCE != 'undefined') tinyMCE.triggerSave();
var __forms = []
if($('Form_EditForm')) __forms.push($('Form_EditForm'));
if($('Form_SubForm')) __forms.push($('Form_SubForm'));
if($('Form_MemberForm')) __forms.push($('Form_MemberForm'));
var __somethingHasChanged = false;
var __callAfter = callAfter;
__forms.each(function(form) {
if(form.isChanged && form.isChanged()) {
__somethingHasChanged = true;
}
});
if(__somethingHasChanged) {
// Note: discard and cancel options are no longer used since switching to confirm dialog.
// save is still used if confirmation = false
var options = {
save: function() {
statusMessage('saving...', '', true);
var i;
for(i=0;i<__forms.length;i++) {
if(__forms[i].isChanged && __forms[i].isChanged()) {
if(i == 0) __forms[i].save(true, __callAfter);
else __forms[i].save(true);
}
}
},
discard: function() {
__forms.each(function(form) { form.resetElements(false); });
if(__callAfter) __callAfter();
},
cancel: function() {
}
}
if(confirmation ) {
if(confirm("Are you sure you want to navigate away from this page?\n\nWARNING: Your changes have not been saved.\n\nPress OK to continue, or Cancel to stay on the current page."))
{
// OK was pressed, call function for what was clicked on
if(__callAfter) __callAfter();
} else {
// Cancel was pressed, stay on the current page
return false;
}
} else {
options.save();
}
} else {
if(__callAfter) __callAfter();
}
}
function reloadRecipientsList() {
$('Form_EditForm').getPageFromServer($('Form_EditForm_ID').value, 'recipients', 0, 'Root_Recipients');
}
/*RecipientImportField = Class.create();
RecipientImportField.applyTo('iframe.RecipientImportField');
RecipientImportField.prototype = {
initialize: function() {
this.src = document.getElementsByTagName('base')[0].href + this.src;
}
}*/
/**
* We don't want hitting the enter key in the subject field
* to submit the form.
*/
Behaviour.register({
'#Form_EditForm_Subject' : {
onkeypress : function(event) {
event = (event) ? event : window.event;
var kc = event.keyCode ? event.keyCode : event.charCode;
if(kc == 13) {
return false;
}
}
}
});
/**
* Handle 'add one' link action. Adds a new draft to the site tree and loads it up to edit.
*/
function addNewDraft(parentID) {
$('add_type').value = 'draft';
$('addtype_options').onsubmit();
}

View File

@ -1,172 +0,0 @@
/**
* Auto-lookup on ajax fields
*/
AjaxMemberLookup = {
initialise : function() {
var div = document.createElement('div');
div.id = this.id + '_ac';
div.className = 'autocomplete';
this.parentNode.appendChild(div);
new Ajax.Autocompleter(this.id, div.id, 'admin/security/autocomplete/' + this.name, {
afterUpdateElement : this.afterAutocomplete.bind(this)
});
},
afterAutocomplete : function(field, selectedItem) {
var data = selectedItem.getElementsByTagName('span')[1].innerHTML;
var items = data.split(",");
form = Element.ancestorOfType(field, 'form');
form.elements.FirstName.value = items[0];
form.elements.Surname.value = items[1];
form.elements.Email.value = items[2];
form.elements.Password.value = items[3];
var fieldSet = field.parentNode.parentNode.getElementsByTagName('input');
ajaxSubmitFieldSet('admin/newsletter/savemember', fieldSet);
}
}
/**
* Member list behaviour
*/
Behaviour.register({
'#MemberList tr' : {
onmouseover : hover_over,
onmouseout : hover_out,
onclick : function() {
if(this.className.indexOf('addrow') == -1) {
Element.addClassName(this, 'loading');
new Ajax.Request('admin/newsletter/getmember', {
method : 'post',
postBody : 'ID=' + this.id.replace('member-','') + '&ajax=1',
onSuccess : this.select_success.bind(this)
});
} else {
$('Form_MemberForm').innerHTML = "<p>Choose a member from above.</p>";
}
},
select_success : function(response) {
Element.removeClassName(this, 'loading');
$('Form_MemberForm').loadNewPage(response.responseText);
statusMessage('loaded','good');
// for (var n in tinyMCE.instances) tinyMCE.removeMCEControl(n);
}
},
'#MemberList thead tr' : {
onmouseover : null,
onmouseout : null,
onclick : null
},
'#MemberList' : {
initialise : function() {
this.headerMap = [];
var i, item, headers = this.getElementsByTagName('thead')[0].getElementsByTagName('tr')[0].getElementsByTagName('td');
for(i=0;item=headers[i];i++) {
this.headerMap[i] = item.className;
}
},
setRecordDetails : function(id, details, groupID) {
var row = document.getElementById('member-' + id);
if(row) {
var i, item, cells = row.getElementsByTagName('td');
for(i=0;item=cells[i];i++) {
if(details[this.headerMap[i]]) {
item.innerHTML = details[this.headerMap[i]];
}
}
} else {
this.createRecord(id, details, groupID);
}
},
createRecord : function (id, details, groupId) {
var row = document.createElement('tr');
row.id = 'member-' + id;
var i, cell, cellField;
for(i=0;cellField=this.headerMap[i];i++) {
cell = document.createElement('td')
if(details[cellField]) {
cell.innerHTML = details[cellField];
}
row.appendChild(cell);
}
// Add the delete icon
if(typeof groupId == 'undefined')
var groupId = $('Form_EditForm').elements.ID.value;
cell = document.createElement('td')
cell.innerHTML = '<a class="deletelink" href="admin/security/removememberfromgroup/' + groupId + '/' + id + '"><img src="cms/images/delete.gif" alt="delete" /></a>';
cell.getElementsByTagName('0');
row.appendChild(cell);
var tbody = this.getElementsByTagName('tbody')[0];
var addRow = document.getElementsByClassName('addrow',tbody)[0];
if(addRow) tbody.insertBefore(row, addRow);
else tbody.appendChild(row);
Behaviour.apply(row, true);
},
clearAddForm : function() {
var tbody = this.getElementsByTagName('tbody')[0];
var addRow = document.getElementsByClassName('addrow',tbody)[0];
if(addRow) {
var i,field,fields = addRow.getElementsByTagName('input');
for(i=0;field=fields[i];i++) {
if(field.type != 'hidden' && field.type != 'submit') field.value = '';
}
}
},
removeMember : function(memberID) {
var record;
if(record = $('member-' + memberID)) {
record.parentNode.removeChild(record);
}
}
},
'#MemberList input' : AjaxMemberLookup,
'#MemberList a.deletelink' : {
onclick : function(event) {
if(confirm("Do you want to remove this member from the group?")) {
this.getElementsByTagName('img')[0].src = 'cms/images/network-save.gif';
ajaxLink(this.href);
}
Event.stop(event);
return false;
}
},
'#MemberList tr.addrow' : {
onmouseover : null,
onmouseout : null,
onclick : null
},
'#MemberList tr.addrow td.actions input' : {
onclick : function(event) {
data = this.parentNode.parentNode.getElementsByTagName('input');
var i,item,error = [];
for(i=0;item=data[i];i++) {
if(item.name == 'Email' && !item.value) error[error.length] = "Email";
if(item.name == 'Password' && !item.value) error[error.length] = "Password";
}
if(error.length > 0) {
alert('Please enter a ' + error.join(' and a ') + ' to add a member.');
} else {
ajaxSubmitFieldSet('admin/newsletter/addmember', data);
}
return false;
}
}
});

View File

@ -1,13 +0,0 @@
Behaviour.register({
'body' : {
onload: function() {
top.getElementById('ImportFile').frameLoaded( document );
}
},
'form input[type=file]' : {
onchange: function() {
this.form.submit();
}
}
});

View File

@ -1,39 +0,0 @@
<% if Entries %>
<p><b><% _t('INSTRUCTIONS', 'Instructions:') %></b></p>
<ul>
<li><% _t('INSTRUCTIONS1', 'Uncheck the box to enable sending to a blacklisted email address.') %></li>
<li><% _t('INSTRUCTIONS2', 'To remove a recipients\'s email address from your mailing list, click the icon') %> <img src="cms/images/delete.gif" alt="delete" /></li>
</ul>
<table id="BouncedListTable" class="CMSList BouncedList" summary="<% _t('HAVEBOUNCED','Emails that have bounced') %>">
<thead>
<tr>
<th width="18"><% _t('BLACKLISTED', 'Blacklisted') %></th>
<th><% _t('UNAME','User name') %></th>
<th><% _t('EMADD','Email address') %></th>
<th><% _t('RESON', 'Reason:') %></th>
<th><% _t('DATE', 'Date') %></th>
<th width="18">&nbsp;</th>
</tr>
</thead>
<tbody>
<% control Entries %>
<tr>
<td class="markingcheckbox">
<% if Member.BlacklistedEmail %>
<input class="checkbox" type="checkbox" checked="checked" name="BouncedList[]" value="$Record.ID" />
<% else %>
<input class="checkbox" type="checkbox" name="BouncedList[]" value="$Record.ID" />
<% end_if %>
</td>
<td>$Member.FirstName $Member.Surname</td>
<td>$Member.Email</td>
<td>$Record.BounceMessage</td>
<td>$Record.Created.Long</td>
<td width="16"><a class="deletelink" href="admin/newsletter/removebouncedmember/$Record.ID/?GroupID=$GroupID"><img src="cms/images/delete.gif" alt="delete" /></a></td>
</tr>
<% end_control %>
</tbody>
</table>
<% else %>
<p><% _t('NOBOUNCED','No emails sent have bounced.') %></p>
<% end_if %>

View File

@ -1,33 +0,0 @@
<% if NewsletterTypes %>
<ul id="sitetree" class="tree unformatted">
<% control NewsletterTypes %>
<li id="mailtype_$ID" class="MailType">
<a href="#">$Title</a>
<ul>
<li id="drafts_$ID" class="DraftFolder nodelete"><a href="$baseURL/admin/showtype/$ID"><% _t('DRAFTS','Drafts') %></a>
<% if DraftNewsletters %>
<ul>
<% control DraftNewsletters %>
<li class="Draft" id="draft_{$ParentID}_{$ID}"><a href="$baseURL/admin/newsletter/shownewsletter/$ID">$Title</a></li>
<% end_control %>
</ul>
<% end_if %>
</li>
<li id="sent_$ID" class="SentFolder nodelete"><a href="$baseURL/admin/showtype/$ID"><% _t('SENT','Sent Items') %></a>
<% if SentNewsletters %>
<ul>
<% control SentNewsletters %>
<li class="Sent" id="sent_{$ParentID}_{$ID}"><a href="$baseURL/admin/newsletter/shownewsletter/$ID">$Title</a></li>
<% end_control %>
</ul>
<% end_if %>
</li>
<li id="recipients_$ID" class="Recipients nodelete"><a href="$baseURL/admin/newsletter/showtype/$ID"><% _t('MAILLIST','Mailing List') %></a></li>
</ul>
</li>
<% end_control %>
</ul>
<% else %>
<ul id="sitetree" class="tree unformatted">
</ul>
<% end_if %>

View File

@ -1,21 +0,0 @@
<% if Entries %>
<table class="CMSList UnsubscribedList" summary="Unsubscribed users">
<tbody>
<tr>
<td><% _t('UNAME','User name') %></td>
<td><% _t('UNSUBON','Unsubscribed on') %></td>
</tr>
<% control Entries %>
<tr>
<td>$Member.FirstName $Member.Surname</td>
<td>$Record.Created.Long</td>
</tr>
<% end_control %>
</tbody>
</table>
<% else %>
<p>
<% _t('NOUNSUB','No users have unsubscribed from this newsletter.') %>
</p>
<% end_if %>

View File

@ -1,48 +0,0 @@
<style>
ul.tree li.MailType span.MailType a {
background-image: url(cms/images/treeicons/sent-folder.png);
font-weight: bold;
}
ul.tree li.MailType span.Recipients a {
background-image: url(cms/images/treeicons/multi-user.png);
}
ul.tree li.MailType span.Recipients a {
background-image: url(cms/images/treeicons/multi-user.png);
}
ul.tree li.MailType span.SentFolder a, ul.tree span.SentFolder.children a {
background-image: url(cms/images/treeicons/sent-folder.png);
}
ul.tree li.MailType span.DraftFolder a, ul.tree span.DraftFolder.children a {
background-image: url(cms/images/treeicons/draft-folder.png);
}
ul.tree li.MailType span.Draft a {
background-image: url(cms/images/treeicons/draft-file.png);
}
ul.tree li.MailType span.Sent a {
background-image: url(cms/images/treeicons/sent-file.gif);
}
</style>
<h2><% _t('NEWSLETTERS','Newsletters') %></h2>
<div id="treepanes" style="overflow-y: auto;">
<ul id="TreeActions">
<li class="action" id="addtype"><button><% _t('CREATE','Create') %></button></li>
<li class="action" id="deletedrafts"><button><% _t('DEL','Delete') %></button></li>
</ul>
<div style="clear:both;"></div>
<form class="actionparams" id="addtype_options" style="display: none" action="admin/newsletter/add">
<input type="hidden" name="ParentID" value="" />
<select name="PageType" id="add_type">
<option value="type"><% _t('ADDTYPE','Add new type') %></option>
<option value="draft"><% _t('ADDDRAFT','Add new draft') %></option>
</select>
<input class="action" type="submit" value="<% _t('GO','Go') %>" />
</form>
<form class="actionparams" id="deletedrafts_options" style="display: none" action="admin/newsletter/remove">
<p><% _t('SELECTDRAFTS','Select the drafts that you want to delete and then click the button below') %></p>
<input type="hidden" name="csvIDs" />
<input type="submit" value="<% _t('DELETEDRAFTS','Delete the selected drafts') %>" />
</form>
<% include NewsletterAdmin_SiteTree %>
</div>

View File

@ -1,33 +0,0 @@
<% include Editor_toolbar %>
<div id="form_actions_right" class="ajaxActions">
</div>
<form class="actionparams" id="action_send_options" style="display:none" action="admin/newsletter/sendnewsletter">
<fieldset>
<input type="hidden" name="NewsletterID" />
<ul class="optionset">
<li><input name="SendType" id="SendTypeTest" value="Test" checked="checked" type="radio" /> <label for="SendTypeTest"><% _t('SENDTEST','Send test to') %></label> <input name="TestEmail" type="text" /></li>
<li><input name="SendType" id="SendTypeList" value="List" type="radio" /> <label for="SendTypeList"><% _t('ENTIRE','Send to the entire mailing list') %></label></li>
<li><input name="SendType" id="SendTypeUnsent" value="Unsent" type="radio" /> <label for="SendTypeUnsent"><% _t('ONLYNOT','Send to only people not previously sent to') %></label></li>
</ul>
$SendProgressBar
</fieldset>
<p class="actions">
<ul class="optionset">
<li class="cancel"><button id="action_send_cancel"><% _t('CANCEL','Cancel') %></button></li>
<li class="submit"><input type="submit" value="<% _t('SEND','Send newsletter') %>" /></li>
</ul>
</p>
</form>
<% if EditForm %>
$EditForm
<% else %>
<form id="Form_EditForm" action="admin/newsletter?executeForm=EditForm" method="post" enctype="multipart/form-data">
<p><% _t('WELCOME1','Welcome to the',50,'Followed by application name') %> $ApplicationName <% _t('WELCOME2','newsletter admininistration section. Please choose a folder from the left.',50) %></p>
</form>
<% end_if %>
<p id="statusMessage" style="visibility:hidden"></p>

View File

@ -1,6 +0,0 @@
<% if Status = Draft %>
<p><% _t('CHOOSEDRAFT1','Please choose a draft on the left, or') %> <a href="javascript:addNewDraft({$mailTypeID})"><% _t('CHOOSEDRAFT2','add one') %></a>.</p>
<% end_if %>
<% if Status = Sent %>
<p><% _t('CHOOSESENT','Please choose a sent item on the left.') %></p>
<% end_if %>

View File

@ -1,51 +0,0 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<% base_tag %>
$MetaTags
<style type="text/css" media="screen">
@import "mot/css/css.css";
@import "mot/css/typography.css";
</style>
<style type="text/css" media="print">
@import "mot/css/print.css";
</style>
<style type="text/css">
body {
padding-top: 1em;
padding-bottom: 2em;
overflow: scroll !important;
}
</style>
<script src="jsparty/prototype.js" type="text/javascript"></script>
<script src="jsparty/behaviour.js" type="text/javascript"></script>
<script src="cms/javascript/Newsletter_UploadForm.js" type="text/javascript"></script>
<% if ImportMessage %>
<script type="text/javascript">
top.statusMessage('<% _t('IMPORTNEW','Imported new members') %>','good');
top.reloadRecipientsList();
</script>
<% end_if %>
</head>
<body onload="">
<% if ImportMessage %>
<p>
$ImportMessage
<p><b>Note:</b><% _t('MLRELOAD1', 'To see the new members on the Recipients tab, you need to') %> <a href="#" onclick="javascript:top.reloadRecipientsList()"><% _t('MLRELOAD2', 'reload the Mailing List') %></a>.</p>
<ul>
<li><label><% _t('IMPORTED','New members imported:') %></label>$NewMembers</li>
<li><label><% _t('UPDATED','Members updated:') %></label>$ChangedMembers</li>
<li><label><% _t('CHANGED','Number of details changed:') %></label>$ChangedFields</li>
<li><label><% _t('SKIPPED','Records skipped:') %></label>$SkippedRecords</li>
<li><label><% _t('TIME','Time taken:') %> </label>$Time <% _t('SEC','seconds') %></li>
</ul>
</p>
<% end_if %>
<% if ErrorMessage %>
<p class="message bad">
$ErrorMessage
</p>
<% end_if %>
$UploadForm
</body>
</html>

View File

@ -1,46 +0,0 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<% base_tag %>
$MetaTags
<style type="text/css" media="screen">
@import "mot/css/css.css";
@import "mot/css/typography.css";
</style>
<style type="text/css" media="print">
@import "mot/css/print.css";
</style>
<script src="jsparty/prototype.js" type="text/javascript"></script>
<script src="jsparty/behaviour.js" type="text/javascript"></script>
<script src="cms/javascript/Newsletter_UploadForm.js" type="text/javascript"></script>
</head>
<body onload="">
<h1><% _t('CONTENTSOF','Contents of') %> $FileName</h1>
<form method="post" action="admin/newsletter/?executeForm=UploadForm" name="UploadForm">
<% control CustomSetFields %>
$FieldHolder
<% end_control %>
<input type="submit" name="action_confirm" value="<% _t('YES','Confirm') %>" />
<input type="submit" name="action_cancel" value="<% _t('NO','Cancel') %>" />
<input type="hidden" name="ID" value="$TypeID" />
<table summary="<% _t('RECIMPORTED','Recipients imported from') %> $FileName">
<tbody>
<tr>
<% control ColumnHeaders %>
<th>
$Field
</th>
<% end_control %>
</tr>
<% control Rows %>
<tr>
<% control Cells %>
<td>$Value</td>
<% end_control %>
</tr>
<% end_control %>
</tbody>
</table>
</form>
</body>
</html>

View File

@ -1,120 +0,0 @@
<% if SentRecipients(Failed) %>
<h2 class="error" style="width:auto;"><% _t('SENDFAIL','Sending to the Following Recipients Failed') %></h2>
<table class="CMSList">
<thead>
<tr>
<th class="Email" style="width:33%"><% _t('EMAIL','Email') %></th>
<th><% _t('DATE','Date') %></th>
<th><% _t('RES','Result') %></th>
</tr>
</thead>
<tbody>
<% control SentRecipients(Failed) %>
<tr>
<td>$Email</td>
<td>$LastEdited</td>
<td>$Result</td>
</tr>
<% end_control %>
</tbody>
</table>
<% end_if %>
<% if SentRecipients(Bounced) %>
<h2 class="error" style="width:auto;"><% _t('SENDBOUNCED','Sending to the Following Recipients Bounced') %></h2>
<table class="CMSList">
<thead>
<tr>
<th class="Email" style="width:33%"><% _t('EMAIL') %></th>
<th><% _t('DATE') %></th>
<th><% _t('RES') %></th>
</tr>
</thead>
<tbody>
<% control SentRecipients(Bounced) %>
<tr>
<td>$Email</td>
<td>$LastEdited</td>
<td>$Result</td>
</tr>
<% end_control %>
</tbody>
</table>
<% end_if %>
<% if SentRecipients(BlackListed) %>
<h2 class="error" style="width:auto;"><% _t('FAILEDBL', 'Sending to the Following Recipients Did Not Occur Because They Are BlackListed') %></h2>
<table class="CMSList">
<thead>
<tr>
<th class="Email" style="width:33%"><% _t('EMAIL') %></th>
<th><% _t('DATE') %></th>
<th><% _t('RES') %></th>
</tr>
</thead>
<tbody>
<% control SentRecipients(BlackListed) %>
<tr>
<td>$Email</td>
<td>$LastEdited</td>
<td>$Result</td>
</tr>
<% end_control %>
</tbody>
</table>
<% end_if %>
<% if UnsentSubscribers %>
<h2><% _t('NEWSNEVERSENT','The Newsletter has Never Been Sent to Following Subscribers') %></h2>
<table class="CMSList">
<thead>
<tr>
<th class="Email" style="width:33%"><% _t('EMAIL') %></th>
<th class="FirstName"><% _t('FN','Firstname') %></th>
<th class="Surname"><% _t('SN','Surname') %></th>
</tr>
</thead>
<tbody>
<% control UnsentSubscribers %>
<tr id="unsent-member-$ID">
<td>$Email</td>
<td>$FirstName</td>
<td>$Surname</td>
</tr>
<% end_control %>
</tbody>
</table>
<% end_if %>
<% if SentRecipients(Sent) %>
<h2><% _t('SENTOK','Sending to the Following Recipients was Successful') %></h2>
<table class="CMSList">
<thead>
<tr>
<th class="Email" style="width:33%"><% _t('EMAIL') %></th>
<th><% _t('DATE') %></th>
<th><% _t('RES') %></th>
</tr>
</thead>
<tbody>
<% control SentRecipients(Sent) %>
<tr id="sent-member-$ID">
<td>$Email</td>
<td>$LastEdited</td>
<td>$Result</td>
</tr>
<% end_control %>
</tbody>
</table>
<% end_if %>

View File

@ -1,36 +0,0 @@
<html>
<head>
<style type="text/css">
div.data span {
width: 50%;
}
div.data span.left {
text-align: right;
font-weight: bold;
}
div.data a {
overflow: visible;
}
</style>
</head>
<body>
<h1>$Subject</h1>
<p>Dear $FirstName,</p>
<p>Thanks for signing up to our mailing list. The following data was submitted:</p>
<p>First name: $FirstName</p>
<p>Email: $Email</p>
<p>Password: $Password (we've generated this password for you)</p>
<% if Newsletters %>
<p>You're subscribed to the following mailing lists:</p>
<ul>
<% control Newsletters %>
<li>$Title</li>
<% end_control %>
</ul>
<% end_if %>
</body>
</html>