<commit_before><?php

/**
 * Newsletter administration section
 *
 * @package newsletter
 */

class NewsletterAdmin extends LeftAndMain {
	static $subitem_class = 'Member';
	
	/** 
	 * @var which will be used to seperator "send items" into 2 groups, e.g. "most recent number 5", "older". 
	 */
	static $most_recent_seperator = 5; // an int which will be used to seperator "send items" into 2 groups, e.g. "most recent number 5", "older".
	
	/** 
	 * @var array Array of template paths to check 
	 */
	static $template_paths = null; //could be customised in _config 

	static $allowed_actions = array(
		'adddraft',
		'addgroup',
		'addtype',
		'autocomplete',
		'displayfilefield',
		'getformcontent',
		'getsentstatusreport',
		'getsitetree',
		'memberblacklisttoggle',
		'newmember',
		'preview',
		'remove',
		'removebouncedmember',
		'removenewsletter',
		'save',
		'savemember',
		'savenewsletter',
		'sendnewsletter',
		'showdrafts',
		'showmailtype',
		'shownewsletter',
		'showrecipients',
		'showsent',
		'MailingListEditForm',
		'TypeEditForm',
		'UploadForm',
		'NewsletterEditForm',
	);

	static $url_segment = 'newsletter';

	static $url_rule = '/$Action/$ID/$OtherID';

	static $menu_title = 'Newsletter';

	public function init() {
		// In LeftAndMain::init() the current theme is unset.
		// we need to restore the current theme here for make the dropdown of template list.
		$theme = SSViewer::current_theme();
		
		parent::init();
		
		if(isset($theme) && $theme){
			SSViewer::set_theme($theme);
		}
		
		Requirements::javascript(MCE_ROOT . 'tiny_mce_src.js');
		Requirements::javascript(SAPPHIRE_DIR . '/javascript/tiny_mce_improvements.js');

		//TODO what is going on here? where did that hover.js go? can't find it. 
		//TODO We need to reimplement a hover.js?
		Requirements::javascript(CMS_DIR . '/javascript/hover.js');
		Requirements::javascript(THIRDPARTY_DIR . '/scriptaculous/controls.js');

		Requirements::javascript(CMS_DIR . '/javascript/LeftAndMain_left.js');
		Requirements::javascript(CMS_DIR . '/javascript/LeftAndMain_right.js');
		Requirements::javascript(CMS_DIR . '/javascript/CMSMain_left.js');
		
		Requirements::javascript(CMS_DIR . '/javascript/SecurityAdmin.js');

		Requirements::javascript(NEWSLETTER_DIR . '/javascript/NewsletterAdmin_left.js');
		Requirements::javascript(NEWSLETTER_DIR . '/javascript/NewsletterAdmin_right.js');
		Requirements::javascript(NEWSLETTER_DIR . '/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::javascript(MCE_ROOT . 'tiny_mce_src.js');
			HtmlEditorConfig::get('cms')->setOption('ContentCSS', project() . '/css/editor.css');
			HtmlEditorConfig::get('cms')->setOption('Lang', i18n::get_tinymce_lang());
		}

		// Always block the HtmlEditorField.js otherwise it will be sent with an ajax request
		Requirements::block(SAPPHIRE_DIR . '/javascript/HtmlEditorField.js');

		Requirements::css(NEWSLETTER_DIR . '/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);
	}

	/**
	 * Top level call from ajax
	 * Called when a mailing list is clicked on the left menu
	 */
	public function showrecipients($params) {
		$params = $params->allParams();
		return $this->showWithEditForm( $params, $this->getMailingListEditForm( $params['ID'] ) );
	}

	/**
	* Top level call from ajax when click on the left manu
	* Second level call when create a draft
	* Called when a draft or sent newsletter is clicked on the left menu and when a new one is added
	*/
	public function shownewsletter($params) {
		if($params instanceof SS_HTTPRequest){
			$params = $params->allParams();
		}
		return $this->showWithEditForm( $params, $this->getNewsletterEditForm( $params['ID'] ) );
	}

	/**
	 * Preview a {@link Newsletter} draft.
	 *
	 * @param SS_HTTPRequest $request Request parameters
	 */
	public function preview($request) {
		$newsletterID = (int) $request->param('ID');
		$newsletter = DataObject::get_by_id('Newsletter', $newsletterID);
		$templateName = ($newsletter && ($newsletter->Parent()->Template)) ? $newsletter->Parent()->Template : 'GenericEmail';

		// Block stylesheets and JS that are not required (email templates should have inline CSS/JS)
		Requirements::clear();

		$email = new NewsletterEmail($newsletter); 
		
		return HTTP::absoluteURLs($email->getData()->renderWith($templateName));
	}

	/**
	 * Top level call from ajax
	 * Called when a newsletter type is clicked on the left menu
	 */
	public function showmailtype($params) {
		$params = $params->allParams();
		
		return $this->showWithEditForm( $params, $this->getNewsletterTypeEditForm( $params['ID'] ) );
	}

	/**
	* Top level call from ajax
	* Called when a 'Drafts' folder is clicked on the left menu
	*/
	public function showdrafts($params) {
		$params = $params->allParams();
		return $this->ShowNewsletterFolder($params, 'Draft');
	}

	/**
	* Top level call from ajax
	* Called when a 'Sent Items' folder is clicked on the left menu
	*/
	public function showsent($params) {
		$params = $params->allParams();
		return $this->ShowNewsletterFolder($params, 'Sent');
	}

	/**
	* Shows either the 'Sent' or 'Drafts' folder using the NewsletterList template
	* Didn't see anywhere it is called from top level ajax call or from templete,
	* it is only called internally from showdrafts and showsent.
	*/
	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");
	}

	/**
	 * This function is called only internally, so make sure that $params is not a SS_HTTPRequest from caller.
	 */
    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('EditForm' => $editForm);
		}
    }

    public function getEditForm( $id ) {
        $form = $this->getNewsletterTypeEditForm( $id );
		$form->disableDefaultAction();
		return $form;
    }

    /**
     * Get the EditForm
     */
    public function EditForm() {
		// Include JavaScript to ensure HtmlEditorField works.
		HtmlEditorField::include_js();
		
    	if((isset($_REQUEST['ID']) && isset($_REQUEST['Type']) && $_REQUEST['Type'] == 'Newsletter') || isset($_REQUEST['action_savenewsletter'])) {
    		$form = $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']) || (!empty($_REQUEST['MemberSearch']))) {
				$form = $this->MailingListEditForm();
			} else {
				$form = $this->TypeEditForm();
			}
    	}
		if($form) $form->disableDefaultAction();
		return $form;
	}

    public function NewsletterEditForm() {
    	$id = isset($_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 = $mailType->getCMSFields();

			$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, "TypeEditForm", $fields, $actions);
			$form->loadDataFrom($mailType);
			// This saves us from having to change all the JS in response to renaming this form to TypeEditForm
			$form->setHTMLID('Form_EditForm');
			$this->extend('updateEditForm', $form);
		} 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 );
	    	}
	    }
		$group = null;

		if(isset($mailType) && is_object($mailType) && $mailType->GroupID) {
			$group = DataObject::get_one("Group", "\"ID\" = $mailType->GroupID");<commit_msg>BUGFIX: Updated  session handling to use standard leftandmain methods so forms work properly.<commit_after><?php

/**
 * Newsletter administration section
 *
 * @package newsletter
 */

class NewsletterAdmin extends LeftAndMain {
	static $subitem_class = 'Member';
	
	/** 
	 * @var which will be used to seperator "send items" into 2 groups, e.g. "most recent number 5", "older". 
	 */
	static $most_recent_seperator = 5; // an int which will be used to seperator "send items" into 2 groups, e.g. "most recent number 5", "older".
	
	/** 
	 * @var array Array of template paths to check 
	 */
	static $template_paths = null; //could be customised in _config 

	static $allowed_actions = array(
		'adddraft',
		'addgroup',
		'addtype',
		'autocomplete',
		'displayfilefield',
		'getformcontent',
		'getsentstatusreport',
		'getsitetree',
		'memberblacklisttoggle',
		'newmember',
		'preview',
		'remove',
		'removebouncedmember',
		'removenewsletter',
		'save',
		'savemember',
		'savenewsletter',
		'sendnewsletter',
		'showdrafts',
		'showmailtype',
		'shownewsletter',
		'showrecipients',
		'showsent',
		'MailingListEditForm',
		'TypeEditForm',
		'UploadForm',
		'NewsletterEditForm',
	);

	static $url_segment = 'newsletter';

	static $url_rule = '/$Action/$ID/$OtherID';

	static $menu_title = 'Newsletter';

	public function init() {
		// In LeftAndMain::init() the current theme is unset.
		// we need to restore the current theme here for make the dropdown of template list.
		$theme = SSViewer::current_theme();
		
		parent::init();
		
		if(isset($theme) && $theme){
			SSViewer::set_theme($theme);
		}
		
		Requirements::javascript(MCE_ROOT . 'tiny_mce_src.js');
		Requirements::javascript(SAPPHIRE_DIR . '/javascript/tiny_mce_improvements.js');

		//TODO what is going on here? where did that hover.js go? can't find it. 
		//TODO We need to reimplement a hover.js?
		Requirements::javascript(CMS_DIR . '/javascript/hover.js');
		Requirements::javascript(THIRDPARTY_DIR . '/scriptaculous/controls.js');

		Requirements::javascript(CMS_DIR . '/javascript/LeftAndMain_left.js');
		Requirements::javascript(CMS_DIR . '/javascript/LeftAndMain_right.js');
		Requirements::javascript(CMS_DIR . '/javascript/CMSMain_left.js');
		
		Requirements::javascript(CMS_DIR . '/javascript/SecurityAdmin.js');

		Requirements::javascript(NEWSLETTER_DIR . '/javascript/NewsletterAdmin_left.js');
		Requirements::javascript(NEWSLETTER_DIR . '/javascript/NewsletterAdmin_right.js');
		Requirements::javascript(NEWSLETTER_DIR . '/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::javascript(MCE_ROOT . 'tiny_mce_src.js');
			HtmlEditorConfig::get('cms')->setOption('ContentCSS', project() . '/css/editor.css');
			HtmlEditorConfig::get('cms')->setOption('Lang', i18n::get_tinymce_lang());
		}

		// Always block the HtmlEditorField.js otherwise it will be sent with an ajax request
		Requirements::block(SAPPHIRE_DIR . '/javascript/HtmlEditorField.js');

		Requirements::css(NEWSLETTER_DIR . '/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(){
		$this->setCurrentPageID($_REQUEST['id']);

		if($_REQUEST['otherID']) {
			Session::set('currentOtherID', $_REQUEST['otherID']);
		}

		SSViewer::setOption('rewriteHashlinks', false);

		$result = $this->renderWith($this->class . '_right');

		return $this->getLastFormIn($result);
	}

	/**
	 * Top level call from ajax
	 * Called when a mailing list is clicked on the left menu
	 */
	public function showrecipients($params) {
		$params = $params->allParams();
		return $this->showWithEditForm( $params, $this->getMailingListEditForm( $params['ID'] ) );
	}

	/**
	* Top level call from ajax when click on the left manu
	* Second level call when create a draft
	* Called when a draft or sent newsletter is clicked on the left menu and when a new one is added
	*/
	public function shownewsletter($params) {
		if($params instanceof SS_HTTPRequest){
			$params = $params->allParams();
		}
		return $this->showWithEditForm( $params, $this->getNewsletterEditForm( $params['ID'] ) );
	}

	/**
	 * Preview a {@link Newsletter} draft.
	 *
	 * @param SS_HTTPRequest $request Request parameters
	 */
	public function preview($request) {
		$newsletterID = (int) $request->param('ID');
		$newsletter = DataObject::get_by_id('Newsletter', $newsletterID);
		$templateName = ($newsletter && ($newsletter->Parent()->Template)) ? $newsletter->Parent()->Template : 'GenericEmail';

		// Block stylesheets and JS that are not required (email templates should have inline CSS/JS)
		Requirements::clear();

		$email = new NewsletterEmail($newsletter); 
		
		return HTTP::absoluteURLs($email->getData()->renderWith($templateName));
	}

	/**
	 * Top level call from ajax
	 * Called when a newsletter type is clicked on the left menu
	 */
	public function showmailtype($params) {
		$params = $params->allParams();
		
		return $this->showWithEditForm( $params, $this->getNewsletterTypeEditForm( $params['ID'] ) );
	}

	/**
	* Top level call from ajax
	* Called when a 'Drafts' folder is clicked on the left menu
	*/
	public function showdrafts($params) {
		$params = $params->allParams();
		return $this->ShowNewsletterFolder($params, 'Draft');
	}

	/**
	* Top level call from ajax
	* Called when a 'Sent Items' folder is clicked on the left menu
	*/
	public function showsent($params) {
		$params = $params->allParams();
		return $this->ShowNewsletterFolder($params, 'Sent');
	}

	/**
	* Shows either the 'Sent' or 'Drafts' folder using the NewsletterList template
	* Didn't see anywhere it is called from top level ajax call or from templete,
	* it is only called internally from showdrafts and showsent.
	*/
	public function ShowNewsletterFolder($params, $type) {
		$id = $params['ID'];
		if(!is_numeric($id)) {
			$id = $this->currentPageID();
		}
		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");
	}

	/**
	 * This function is called only internally, so make sure that $params is not a SS_HTTPRequest from caller.
	 */
    private function showWithEditForm( $params, $editForm ) {
        if(isset($params['ID'])) {
			$this->setCurrentPageID($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('EditForm' => $editForm);
		}
    }

    public function getEditForm( $id ) {
        $form = $this->getNewsletterTypeEditForm( $id );
		$form->disableDefaultAction();
		return $form;
    }

    /**
     * Get the EditForm
     */
    public function EditForm() {
		// Include JavaScript to ensure HtmlEditorField works.
		HtmlEditorField::include_js();
		
    	if((isset($_REQUEST['ID']) && isset($_REQUEST['Type']) && $_REQUEST['Type'] == 'Newsletter') || isset($_REQUEST['action_savenewsletter'])) {
    		$form = $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']) || (!empty($_REQUEST['MemberSearch']))) {
				$form = $this->MailingListEditForm();
			} else {
				$form = $this->TypeEditForm();
			}
    	}
		if($form) $form->disableDefaultAction();
		return $form;
	}

    public function NewsletterEditForm() {
    	$id = isset($_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 = $this->currentPageID();
        }
	    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 = $mailType->getCMSFields();

			$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, "TypeEditForm", $fields, $actions);
			$form->loadDataFrom($mailType);
			// This saves us from having to change all the JS in response to renaming this form to TypeEditForm
			$form->setHTMLID('Form_EditForm');
			$this->extend('updateEditForm', $form);
		} else {
			$form = false;
		}

		return $form;
	}

	public function getMailingListEditForm($id) {
        if(!is_numeric($id)) {
        	$id = $this->currentPageID();
		}
	    if( is_a( $id, 'NewsletterType' ) ) {
	    		$mailType = $id;
	    		$id = $mailType->ID;
	    } else {
	    	if($id && is_numeric($id)) {
	    		$mailType = DataObject::get_by_id( 'NewsletterType', $id );
	    	}
	    }
		$group = null;

		if(isset($mailType) && is_object($mailType) && $mailType->GroupID) {
			$group = DataObject::get_one("Group", "\"ID\" = $mailType->GroupID");
{'fraction_non_alphanumeric': 0.16571642209552295, 'fraction_numerical': 0.001215066828675577, 'mean_word_length': 4.031507171408418, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 118, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3066307', 'n_tokens_mistral': 7654, 'n_tokens_neox': 6925, 'n_words': 1591}