Page Menu
Home
In-Portal Phabricator
Search
Configure Global Search
Log In
Files
F863884
in-portal
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Subscribers
None
File Metadata
Details
File Info
Storage
Attached
Created
Sat, May 3, 11:27 AM
Size
38 KB
Mime Type
text/x-diff
Expires
Mon, May 5, 11:27 AM (8 h, 9 m)
Engine
blob
Format
Raw Data
Handle
613969
Attached To
rINP In-Portal
in-portal
View Options
Index: branches/5.2.x/core/units/helpers/email_message_helper.php
===================================================================
--- branches/5.2.x/core/units/helpers/email_message_helper.php (revision 15464)
+++ branches/5.2.x/core/units/helpers/email_message_helper.php (revision 15465)
@@ -1,91 +1,91 @@
<?php
/**
* @version $Id$
* @package In-Portal
* @copyright Copyright (C) 1997 - 2011 Intechnic. All rights reserved.
* @license GNU/GPL
* In-Portal is Open Source software.
* This means that this software may have been modified pursuant
* the GNU General Public License, and as distributed it includes
* or is derivative of works licensed under the GNU General Public License
* or other free or open source software licenses.
* See http://www.in-portal.org/license for copyright notices and details.
*/
defined('FULL_PATH') or die('restricted access!');
class kEmailMessageHelper extends kHelper {
/**
* Extracts Subject, Headers, Body fields from email message translation
*
* @param string|SimpleXMLElement $text
* @param string $message_type
* @return Array
*/
function parseTemplate($text, $message_type = '')
{
$ret = Array ('Subject' => '', 'Headers' => '', 'HtmlBody' => '', 'PlainTextBody' => '');
if ( $message_type == '' ) {
// this is v5+ e-mail event text as xml node
foreach ($ret as $field => $value) {
$node_name = strtoupper($field);
$ret[$field] = (string)$text->$node_name;
}
return $ret;
}
$line_id = 1;
$headers = Array();
$lines = explode("\n", $text); // "\n" is lost in process
foreach ($lines as $line_id => $line) {
if ( strlen(trim($line)) == 0 || ($line == '.') ) {
break;
}
$parts = explode(':', $line, 2);
if ( strtolower($parts[0]) == 'subject' ) {
$ret['Subject'] = trim($parts[1]);
}
else {
$headers[] = $line;
}
}
$ret['Headers'] = $headers ? implode("\n", $headers) : null; // it's null field
$lines = array_slice($lines, $line_id + 1);
// add "\n", that was lost before
$ret[$message_type == 'html' ? 'HtmlBody' : 'PlainTextBody'] = implode("\n", $lines);
return $ret;
}
/**
* Parses contents of given object field and sets error, when invalid in-portal tags found
* @param kDBItem $object
* @param string $field
* @return void
* @access public
*/
public function parseField($object, $field)
{
$this->Application->InitParser();
try {
$this->Application->Parser->CompileRaw($object->GetField($field), 'email_template');
}
- catch (ParserException $e) {
+ catch (Exception $e) {
if ( $this->Application->isDebugMode() ) {
$this->Application->Debugger->appendHTML('<b style="color: red;">Error in Email Template:</b> ' . $e->getMessage() . ' (line: ' . $e->getLine() . ')');
}
$object->SetError($field, 'parsing_error');
}
}
}
\ No newline at end of file
Index: branches/5.2.x/core/units/phrases/phrases_event_handler.php
===================================================================
--- branches/5.2.x/core/units/phrases/phrases_event_handler.php (revision 15464)
+++ branches/5.2.x/core/units/phrases/phrases_event_handler.php (revision 15465)
@@ -1,503 +1,520 @@
<?php
/**
* @version $Id$
* @package In-Portal
* @copyright Copyright (C) 1997 - 2009 Intechnic. All rights reserved.
* @license GNU/GPL
* In-Portal is Open Source software.
* This means that this software may have been modified pursuant
* the GNU General Public License, and as distributed it includes
* or is derivative of works licensed under the GNU General Public License
* or other free or open source software licenses.
* See http://www.in-portal.org/license for copyright notices and details.
*/
defined('FULL_PATH') or die('restricted access!');
class PhrasesEventHandler extends kDBEventHandler
{
/**
* Allows to override standard permission mapping
*
* @return void
* @access protected
* @see kEventHandler::$permMapping
*/
protected function mapPermissions()
{
parent::mapPermissions();
$permissions = Array (
'OnItemBuild' => Array ('self' => true, 'subitem' => true),
'OnPreparePhrase' => Array ('self' => true, 'subitem' => true),
'OnExportPhrases' => Array ('self' => 'view'),
);
$this->permMapping = array_merge($this->permMapping, $permissions);
}
/**
+ * Hides phrases from disabled modules
+ *
+ * @param kEvent $event
+ * @return void
+ * @access protected
+ */
+ protected function SetCustomQuery(kEvent $event)
+ {
+ parent::SetCustomQuery($event);
+
+ $object = $event->getObject();
+ /* @var $object kDBList */
+
+ $object->addFilter('module_filter', '%1$s.Module IN (SELECT Name FROM ' . TABLE_PREFIX . 'Modules WHERE Loaded = 1)');
+ }
+
+ /**
* Apply some special processing to object being
* recalled before using it in other events that
* call prepareObject
*
* @param kDBItem|kDBList $object
* @param kEvent $event
* @return void
* @access protected
*/
protected function prepareObject(&$object, kEvent $event)
{
// don't call parent
if ( $event->Special == 'import' || $event->Special == 'export' ) {
$this->RemoveRequiredFields($object);
$object->setRequired(Array ('ExportDataTypes', 'LangFile', 'PhraseType', 'Module'));
// allow multiple phrase types to be selected during import/export
$object->SetFieldOption('PhraseType', 'type', 'string');
}
}
/**
* Allow to create phrases from front end in debug mode with DBG_PHRASES constant set
*
* @param kEvent $event
* @return bool
* @access public
*/
public function CheckPermission(kEvent $event)
{
if ( !$this->Application->isAdmin && $this->Application->isDebugMode(false) && kUtil::constOn('DBG_PHRASES') ) {
$allow_events = Array ('OnCreate', 'OnUpdate');
if ( in_array($event->Name, $allow_events) ) {
return true;
}
}
return parent::CheckPermission($event);
}
/**
* Prepares phrase for translation
*
* @param kEvent $event
*/
function OnPreparePhrase($event)
{
$label = $this->Application->GetVar($event->getPrefixSpecial() . '_label');
if (!$label) {
return ;
}
// we got label, try to get it's ID then if any
$phrase_id = $this->_getPhraseId($label);
if ($phrase_id) {
$event->SetRedirectParam($event->getPrefixSpecial(true) . '_id', $phrase_id);
$event->SetRedirectParam('pass', 'm,' . $event->getPrefixSpecial());
$next_template = $this->Application->GetVar('next_template');
if ($next_template) {
$event->SetRedirectParam('next_template', $next_template);
}
}
else {
$event->CallSubEvent('OnNew');
}
if ($this->Application->GetVar('simple_mode')) {
$event->SetRedirectParam('simple_mode', 1);
}
}
function _getPhraseId($phrase)
{
$sql = 'SELECT ' . $this->Application->getUnitOption($this->Prefix, 'IDField') . '
FROM ' . $this->Application->getUnitOption($this->Prefix, 'TableName') . '
WHERE PhraseKey = ' . $this->Conn->qstr( mb_strtoupper($phrase) );
return $this->Conn->GetOne($sql);
}
/**
* Sets phrase type based on place where it's created (to display on form only)
*
* @param kEvent $event
* @return void
* @access protected
*/
protected function OnPreCreate(kEvent $event)
{
parent::OnPreCreate($event);
$object = $event->getObject();
/* @var $object kDBItem */
$this->_setPhraseModule($object);
}
/**
* Forces new label in case if issued from get link
*
* @param kEvent $event
* @return void
* @access protected
*/
protected function OnNew(kEvent $event)
{
parent::OnNew($event);
$object = $event->getObject();
/* @var $object kDBItem */
$label = $this->Application->GetVar($event->getPrefixSpecial() . '_label');
if ( $label ) {
// phrase is created in language, used to display phrases
$object->SetDBField('Phrase', $label);
$object->SetDBField('PhraseType', $this->_getPhraseType($label)); // to show on form
$object->SetDBField('PrimaryTranslation', $this->_getPrimaryTranslation($label));
}
$this->_setPhraseModule($object);
if ( $event->Special == 'export' || $event->Special == 'import' ) {
$object->SetDBField('PhraseType', '|0|1|2|');
$object->SetDBField('Module', '|' . implode('|', array_keys($this->Application->ModuleInfo)) . '|');
$export_mode = $this->Application->GetVar('export_mode');
if ( $export_mode != 'lang' ) {
$object->SetDBField('ExportDataTypes', '|' . $export_mode . '|');
}
}
}
/**
* Returns given phrase translation on primary language
*
* @param string $phrase
* @return string
* @access protected
*/
protected function _getPrimaryTranslation($phrase)
{
$sql = 'SELECT l' . $this->Application->GetDefaultLanguageId() . '_Translation
FROM ' . $this->Application->getUnitOption($this->Prefix, 'TableName') . '
WHERE PhraseKey = ' . $this->Conn->qstr( mb_strtoupper($phrase) );
return $this->Conn->GetOne($sql);
}
/**
* Sets new phrase module
*
* @param kDBItem $object
* @return void
* @access protected
*/
protected function _setPhraseModule(&$object)
{
$last_module = $this->Application->GetVar('last_module');
if ( $last_module ) {
$object->SetDBField('Module', $last_module);
}
}
/**
* Forces create to use live table
*
* @param kEvent $event
* @return void
* @access protected
*/
protected function OnCreate(kEvent $event)
{
if ( $this->Application->GetVar($event->Prefix . '_label') ) {
$object = $event->getObject(Array ('skip_autoload' => true));
/* @var $object kDBItem */
if ( $this->Application->GetVar('m_lang') != $this->Application->GetVar('lang_id') ) {
$object->SwitchToLive();
}
$this->returnToOriginalTemplate($event);
}
parent::OnCreate($event);
}
/**
* Redirects to original template after phrase is being update
*
* @param kEvent $event
* @return void
* @access protected
*/
protected function OnUpdate(kEvent $event)
{
if ( $this->Application->GetVar($event->Prefix . '_label') ) {
$this->returnToOriginalTemplate($event);
}
parent::OnUpdate($event);
}
/**
* Returns to original template after phrase adding/editing
*
* @param kEvent $event
* @return void
* @access protected
*/
protected function returnToOriginalTemplate(kEvent $event)
{
$next_template = $this->Application->GetVar('next_template');
if ( $next_template ) {
$event->redirect = $next_template;
$event->SetRedirectParam('opener', 's');
}
}
/**
* Set last change info, when phrase is created
*
* @param kEvent $event
* @return void
* @access protected
*/
protected function OnBeforeItemCreate(kEvent $event)
{
parent::OnBeforeItemCreate($event);
$object = $event->getObject();
/* @var $object kDBItem */
$primary_language_id = $this->Application->GetDefaultLanguageId();
if ( !$object->GetDBField('l' . $primary_language_id . '_Translation') ) {
// no translation on primary language -> try to copy from other language
$src_languages = Array ('lang_id', 'm_lang'); // editable language, theme language
foreach ($src_languages as $src_language) {
$src_language = $this->Application->GetVar($src_language);
$src_value = $src_language ? $object->GetDBField('l' . $src_language . '_Translation') : false;
if ( $src_value ) {
$object->SetDBField('l' . $primary_language_id . '_Translation', $src_value);
break;
}
}
}
$this->_phraseChanged($event);
}
/**
* Update last change info, when phrase is updated
*
* @param kEvent $event
* @return void
* @access protected
*/
protected function OnBeforeItemUpdate(kEvent $event)
{
parent::OnBeforeItemUpdate($event);
$this->_phraseChanged($event);
}
/**
* Set's phrase key and last change info, used for phrase updating and loading
*
* @param kEvent $event
*/
function _phraseChanged($event)
{
$object = $event->getObject();
/* @var $object kDBItem */
$label = $object->GetDBField('Phrase');
$object->SetDBField('PhraseKey', mb_strtoupper($label));
$object->SetDBField('PhraseType', $this->_getPhraseType($label));
if ( $this->translationChanged($object) ) {
$object->SetDBField('LastChanged_date', adodb_mktime() );
$object->SetDBField('LastChanged_time', adodb_mktime() );
$object->SetDBField('LastChangeIP', $_SERVER['REMOTE_ADDR']);
}
$this->Application->Session->SetCookie('last_module', $object->GetDBField('Module'));
}
/**
* Returns phrase type, that corresponds given phrase label
*
* @param string $label
* @return int
* @access protected
*/
protected function _getPhraseType($label)
{
$phrase_type_map = Array (
'LU' => Language::PHRASE_TYPE_FRONT,
'LA' => Language::PHRASE_TYPE_ADMIN,
'LC' => Language::PHRASE_TYPE_COMMON
);
$label = mb_strtoupper($label);
$label_prefix = substr($label, 0, 2);
return isset($phrase_type_map[$label_prefix]) ? $phrase_type_map[$label_prefix] : Language::PHRASE_TYPE_COMMON;
}
/**
* Checks, that at least one of phrase's translations was changed
*
* @param kDBItem $object
* @return bool
*/
function translationChanged(&$object)
{
$changed_fields = array_keys( $object->GetChangedFields() );
$translation_fields = Array ('Translation', 'HintTranslation', 'ColumnTranslation');
foreach ($changed_fields as $changed_field) {
$changed_field = preg_replace('/^l[\d]+_/', '', $changed_field);
if ( in_array($changed_field, $translation_fields) ) {
return true;
}
}
return false;
}
/**
* Changes default module to custom (when available)
*
* @param kEvent $event
* @return void
* @access protected
*/
protected function OnAfterConfigRead(kEvent $event)
{
parent::OnAfterConfigRead($event);
if ($this->Application->findModule('Name', 'Custom')) {
$fields = $this->Application->getUnitOption($event->Prefix, 'Fields');
$fields['Module']['default'] = 'Custom';
$this->Application->setUnitOption($event->Prefix, 'Fields', $fields);
}
// make sure, that PrimaryTranslation column always refrers to primary language column
$language_id = $this->Application->GetVar('lang_id');
if (!$language_id) {
$language_id = $this->Application->GetVar('m_lang');
}
$primary_language_id = $this->Application->GetDefaultLanguageId();
$calculated_fields = $this->Application->getUnitOption($event->Prefix, 'CalculatedFields');
foreach ($calculated_fields[''] as $field_name => $field_expression) {
$field_expression = str_replace('%5$s', $language_id, $field_expression);
$field_expression = str_replace('%4$s', $primary_language_id, $field_expression);
$calculated_fields[''][$field_name] = $field_expression;
}
$this->Application->setUnitOption($event->Prefix, 'CalculatedFields', $calculated_fields);
if ($this->Application->GetVar('regional')) {
$this->Application->setUnitOption($event->Prefix, 'PopulateMlFields', true);
}
}
/**
* Saves changes & changes language
*
* @param kEvent $event
* @return void
* @access protected
*/
protected function OnPreSaveAndChangeLanguage(kEvent $event)
{
$label = $this->Application->GetVar($event->getPrefixSpecial() . '_label');
if ( $label && !$this->UseTempTables($event) ) {
$phrase_id = $this->_getPhraseId($label);
if ( $phrase_id ) {
$event->CallSubEvent('OnUpdate');
$event->SetRedirectParam('opener', 's');
}
else {
$event->CallSubEvent('OnCreate');
$event->SetRedirectParam('opener', 's');
}
if ( $event->status != kEvent::erSUCCESS ) {
return;
}
$event->SetRedirectParam($event->getPrefixSpecial() . '_event', 'OnPreparePhrase');
$event->SetRedirectParam('pass_events', true);
}
if ( $this->Application->GetVar('simple_mode') ) {
$event->SetRedirectParam('simple_mode', 1);
}
parent::OnPreSaveAndChangeLanguage($event);
}
/**
* Prepare temp tables and populate it
* with items selected in the grid
*
* @param kEvent $event
* @return void
* @access protected
*/
protected function OnEdit(kEvent $event)
{
parent::OnEdit($event);
// use language from grid, instead of primary language used by default
$event->SetRedirectParam('m_lang', $this->Application->GetVar('m_lang'));
}
/**
* Stores ids of selected phrases and redirects to export language step 1
*
* @param kEvent $event
* @return void
* @access protected
*/
protected function OnExportPhrases(kEvent $event)
{
if ( $this->Application->CheckPermission('SYSTEM_ACCESS.READONLY', 1) ) {
$event->status = kEvent::erFAIL;
return;
}
$this->Application->setUnitOption('phrases', 'AutoLoad', false);
$this->StoreSelectedIDs($event);
$this->Application->StoreVar('export_language_ids', $this->Application->GetVar('m_lang'));
$event->setRedirectParams(
Array (
'phrases.export_event' => 'OnNew',
'pass' => 'all,phrases.export',
'export_mode' => $event->Prefix,
)
);
}
}
\ No newline at end of file
Index: branches/5.2.x/core/units/email_events/email_events_event_handler.php
===================================================================
--- branches/5.2.x/core/units/email_events/email_events_event_handler.php (revision 15464)
+++ branches/5.2.x/core/units/email_events/email_events_event_handler.php (revision 15465)
@@ -1,726 +1,729 @@
<?php
/**
* @version $Id$
* @package In-Portal
* @copyright Copyright (C) 1997 - 2009 Intechnic. All rights reserved.
* @license GNU/GPL
* In-Portal is Open Source software.
* This means that this software may have been modified pursuant
* the GNU General Public License, and as distributed it includes
* or is derivative of works licensed under the GNU General Public License
* or other free or open source software licenses.
* See http://www.in-portal.org/license for copyright notices and details.
*/
defined('FULL_PATH') or die('restricted access!');
class EmailEventsEventsHandler extends kDBEventHandler
{
/**
* Allows to override standard permission mapping
*
* @return void
* @access protected
* @see kEventHandler::$permMapping
*/
protected function mapPermissions()
{
parent::mapPermissions();
$permissions = Array (
'OnFrontOnly' => Array ('self' => 'edit'),
'OnSaveSelected' => Array ('self' => 'view'),
'OnProcessEmailQueue' => Array ('self' => 'add|edit'),
'OnExportEmailEvents' => Array ('self' => 'view'),
'OnSuggestAddress' => Array ('self' => 'add|edit'),
// events only for developers
'OnPreCreate' => Array ('self' => 'debug'),
'OnDelete' => Array ('self' => 'debug'),
'OnDeleteAll' => Array ('self' => 'debug'),
'OnMassDelete' => Array ('self' => 'debug'),
'OnMassApprove' => Array ('self' => 'debug'),
'OnMassDecline' => Array ('self' => 'debug'),
);
$this->permMapping = array_merge($this->permMapping, $permissions);
}
/**
* Changes permission section to one from REQUEST, not from config
*
* @param kEvent $event
* @return bool
* @access public
*/
public function CheckPermission(kEvent $event)
{
$module = $this->Application->GetVar('module');
if ( strlen($module) > 0 ) {
// checking permission when lising module email events in separate section
$module = explode(':', $module, 2);
if ( count($module) == 1 ) {
$main_prefix = $this->Application->findModule('Name', $module[0], 'Var');
}
else {
$exceptions = Array ('Category' => 'c', 'Users' => 'u');
$main_prefix = $exceptions[$module[1]];
}
$section = $this->Application->getUnitOption($main_prefix . '.email', 'PermSection');
$event->setEventParam('PermSection', $section);
}
// checking permission when listing all email events when editing language
return parent::CheckPermission($event);
}
/**
* Apply any custom changes to list's sql query
*
* @param kEvent $event
* @return void
* @access protected
* @see kDBEventHandler::OnListBuild()
*/
protected function SetCustomQuery(kEvent $event)
{
parent::SetCustomQuery($event);
$object = $event->getObject();
/* @var $object kDBList */
if ( $event->Special == 'module' ) {
$module = $this->Application->GetVar('module');
$object->addFilter('module_filter', '%1$s.Module = ' . $this->Conn->qstr($module));
}
+ else {
+ $object->addFilter('module_filter', '%1$s.Module IN (SELECT Name FROM ' . TABLE_PREFIX . 'Modules WHERE Loaded = 1)');
+ }
if ( !$event->Special && !$this->Application->isDebugMode() ) {
// no special
$object->addFilter('enabled_filter', '%1$s.Enabled <> ' . STATUS_DISABLED);
}
}
/**
* Prepares new kDBItem object
*
* @param kEvent $event
* @return void
* @access protected
*/
protected function OnNew(kEvent $event)
{
parent::OnNew($event);
$mapping = Array ('conf' => 'VariableValue', 'site-domain' => 'DefaultEmailRecipients');
if ( isset($mapping[$event->Special]) ) {
$object = $event->getObject();
/* @var $object kDBItem */
$target_object = $this->Application->recallObject($event->Special);
/* @var $target_object kDBList */
$object->SetDBField('Recipients', $target_object->GetDBField($mapping[$event->Special]));
}
}
/**
* Set default headers
*
* @param kEvent $event
* @return void
* @access protected
*/
protected function OnPreCreate(kEvent $event)
{
parent::OnPreCreate($event);
$object = $event->getObject();
/* @var $object kDBItem */
$object->SetDBField('Headers', $this->Application->ConfigValue('Smtp_DefaultHeaders'));
$this->setRequired($event);
}
/**
* Sets status Front-End Only to selected email events
*
* @param kEvent $event
*/
function OnFrontOnly($event)
{
if ( $this->Application->CheckPermission('SYSTEM_ACCESS.READONLY', 1) ) {
$event->status = kEvent::erFAIL;
return;
}
$ids = implode(',', $this->StoreSelectedIDs($event));
$table_name = $this->Application->getUnitOption($event->Prefix, 'TableName');
$sql = 'UPDATE ' . $table_name . '
SET FrontEndOnly = 1
WHERE EventId IN (' . $ids . ')';
$this->Conn->Query($sql);
$this->clearSelectedIDs($event);
}
/**
* Sets selected user to email events selected
*
* @param kEvent $event
* @return void
* @access protected
*/
protected function OnSelectUser(kEvent $event)
{
if ( $event->Special != 'module' ) {
parent::OnSelectUser($event);
return;
}
if ( $this->Application->CheckPermission('SYSTEM_ACCESS.READONLY', 1) ) {
$event->status = kEvent::erFAIL;
return;
}
$items_info = $this->Application->GetVar('u');
if ( $items_info ) {
$user_id = array_shift(array_keys($items_info));
$selected_ids = $this->getSelectedIDs($event, true);
$ids = $this->Application->RecallVar($event->getPrefixSpecial() . '_selected_ids');
$id_field = $this->Application->getUnitOption($event->Prefix, 'IDField');
$table_name = $this->Application->getUnitOption($event->Prefix, 'TableName');
$sql = 'UPDATE ' . $table_name . '
SET ' . $this->Application->RecallVar('dst_field') . ' = ' . $user_id . '
WHERE ' . $id_field . ' IN (' . $ids . ')';
$this->Conn->Query($sql);
}
$this->finalizePopup($event);
}
/**
* Saves selected ids to session
*
* @param kEvent $event
*/
function OnSaveSelected($event)
{
$this->StoreSelectedIDs($event);
}
/**
* Process emails from queue
*
* @param kEvent $event
* @todo Move to MailingList
*/
function OnProcessEmailQueue($event)
{
$deliver_count = $event->getEventParam('deliver_count');
if ( $deliver_count === false ) {
$deliver_count = $this->Application->ConfigValue('MailingListSendPerStep');
if ( $deliver_count === false ) {
$deliver_count = 10; // 10 emails per script run (if not specified directly)
}
}
$processing_type = $this->Application->GetVar('type');
if ( $processing_type = 'return_progress' ) {
$email_queue_progress = $this->Application->RecallVar('email_queue_progress');
if ( $email_queue_progress === false ) {
$emails_sent = 0;
$sql = 'SELECT COUNT(*)
FROM ' . TABLE_PREFIX . 'EmailQueue
WHERE (SendRetries < 5) AND (LastSendRetry < ' . strtotime('-2 hours') . ')';
$total_emails = $this->Conn->GetOne($sql);
$this->Application->StoreVar('email_queue_progress', $emails_sent . ':' . $total_emails);
}
else {
list ($emails_sent, $total_emails) = explode(':', $email_queue_progress);
}
}
$sql = 'SELECT *
FROM ' . TABLE_PREFIX . 'EmailQueue
WHERE (SendRetries < 5) AND (LastSendRetry < ' . strtotime('-2 hours') . ')
LIMIT 0,' . $deliver_count;
$messages = $this->Conn->Query($sql);
$message_count = count($messages);
if ( !$message_count ) {
// no messages left to send in queue
if ( $processing_type = 'return_progress' ) {
$this->Application->RemoveVar('email_queue_progress');
$this->Application->Redirect($this->Application->GetVar('finish_template'));
}
return;
}
$mailing_list_helper = $this->Application->recallObject('MailingListHelper');
/* @var $mailing_list_helper MailingListHelper */
$mailing_list_helper->processQueue($messages);
if ( $processing_type = 'return_progress' ) {
$emails_sent += $message_count;
if ( $emails_sent >= $total_emails ) {
$this->Application->RemoveVar('email_queue_progress');
$this->Application->Redirect($this->Application->GetVar('finish_template'));
}
$this->Application->StoreVar('email_queue_progress', $emails_sent . ':' . $total_emails);
$event->status = kEvent::erSTOP;
echo ($emails_sent / $total_emails) * 100;
}
}
/**
* Prefills module dropdown
*
* @param kEvent $event
* @return void
* @access protected
*/
protected function OnAfterConfigRead(kEvent $event)
{
parent::OnAfterConfigRead($event);
$options = Array ();
foreach ($this->Application->ModuleInfo as $module_name => $module_info) {
if ( $module_name == 'In-Portal' ) {
continue;
}
$options[$module_name] = $module_name;
}
$fields = $this->Application->getUnitOption($event->Prefix, 'Fields');
$fields['Module']['options'] = $options;
$this->Application->setUnitOption($event->Prefix, 'Fields', $fields);
if ( $this->Application->GetVar('regional') ) {
$this->Application->setUnitOption($event->Prefix, 'PopulateMlFields', true);
}
}
/**
* Prepare temp tables and populate it
* with items selected in the grid
*
* @param kEvent $event
* @return void
* @access protected
*/
protected function OnEdit(kEvent $event)
{
parent::OnEdit($event);
// use language from grid, instead of primary language used by default
$event->SetRedirectParam('m_lang', $this->Application->GetVar('m_lang'));
}
/**
* Fixes default recipient type
*
* @param kEvent $event
* @return void
* @access protected
*/
protected function OnAfterItemLoad(kEvent $event)
{
parent::OnAfterItemLoad($event);
$object = $event->getObject();
/* @var $object kDBItem */
if ( !$this->Application->isDebugMode(false) ) {
if ( $object->GetDBField('AllowChangingRecipient') ) {
$object->SetDBField('RecipientType', EmailEvent::RECIPIENT_TYPE_TO);
}
else {
$object->SetDBField('RecipientType', EmailEvent::RECIPIENT_TYPE_CC);
}
}
// process replacement tags
$records = Array ();
$replacement_tags = $object->GetDBField('ReplacementTags');
$replacement_tags = $replacement_tags ? unserialize($replacement_tags) : Array ();
foreach ($replacement_tags as $tag => $replacement) {
$records[] = Array ('Tag' => $tag, 'Replacement' => $replacement);
}
$minput_helper = $this->Application->recallObject('MInputHelper');
/* @var $minput_helper MInputHelper */
$xml = $minput_helper->prepareMInputXML($records, Array ('Tag', 'Replacement'));
$object->SetDBField('ReplacementTagsXML', $xml);
$this->setRequired($event);
}
/**
* Performs custom validation + keep read-only fields
*
* @param kEvent $event
*/
function _itemChanged($event)
{
$object = $event->getObject();
/* @var $object kDBItem */
if ( !$this->Application->isDebugMode(false) ) {
// only allow to enable/disable event while in debug mode
$to_restore = Array ('Enabled', 'AllowChangingSender', 'AllowChangingRecipient');
if ( !$object->GetOriginalField('AllowChangingSender') ) {
$to_restore = array_merge($to_restore, Array ('CustomSender', 'SenderName', 'SenderAddressType', 'SenderAddress'));
}
if ( !$object->GetOriginalField('AllowChangingRecipient') ) {
$to_restore = array_merge($to_restore, Array ('CustomRecipient' /*, 'Recipients'*/));
}
// prevent specific fields from editing
foreach ($to_restore as $restore_field) {
$original_value = $object->GetOriginalField($restore_field);
if ( $object->GetDBField($restore_field) != $original_value ) {
$object->SetDBField($restore_field, $original_value);
}
}
}
// process replacement tags
if ( $object->GetDBField('ReplacementTagsXML') ) {
$minput_helper = $this->Application->recallObject('MInputHelper');
/* @var $minput_helper MInputHelper */
$replacement_tags = Array ();
$records = $minput_helper->parseMInputXML($object->GetDBField('ReplacementTagsXML'));
foreach ($records as $record) {
$replacement_tags[trim($record['Tag'])] = trim($record['Replacement']);
}
$object->SetDBField('ReplacementTags', $replacement_tags ? serialize($replacement_tags) : NULL);
}
if ( $this->translationChanged($object) ) {
$object->SetDBField('LastChanged_date', TIMENOW);
$object->SetDBField('LastChanged_time', TIMENOW);
}
$this->setRequired($event);
}
/**
* Dynamically changes required fields
*
* @param kEvent $event
* @return void
* @access protected
*/
protected function setRequired(kEvent $event)
{
$object = $event->getObject();
/* @var $object kDBItem */
$language_prefix = 'l' . $this->Application->GetVar('m_lang') . '_';
$object->setRequired($language_prefix . 'HtmlBody', !$object->GetField('PlainTextBody'));
$object->setRequired($language_prefix . 'PlainTextBody', !$object->GetField('HtmlBody'));
}
/**
* Checks, that at least one of phrase's translations was changed
*
* @param kDBItem $object
* @return bool
*/
function translationChanged($object)
{
$changed_fields = array_keys($object->GetChangedFields());
$translation_fields = Array ('Subject', 'HtmlBody', 'PlainTextBody');
foreach ($changed_fields as $changed_field) {
$changed_field = preg_replace('/^l[\d]+_/', '', $changed_field);
if ( in_array($changed_field, $translation_fields) ) {
return true;
}
}
return false;
}
/**
* Don't allow to enable/disable events in non-debug mode
*
* @param kEvent $event
* @return void
* @access protected
*/
protected function OnBeforeItemCreate(kEvent $event)
{
parent::OnBeforeItemCreate($event);
$this->_itemChanged($event);
}
/**
* Don't allow to enable/disable events in non-debug mode
*
* @param kEvent $event
* @return void
* @access protected
*/
protected function OnBeforeItemUpdate(kEvent $event)
{
parent::OnBeforeItemUpdate($event);
$this->_itemChanged($event);
}
/**
* Suggest address based on typed address and selected address type
*
* @param kEvent $event
*/
function OnSuggestAddress($event)
{
$event->status = kEvent::erSTOP;
$address_type = $this->Application->GetVar('type');
$address = $this->Application->GetVar('value');
$limit = $this->Application->GetVar('limit');
if ( !$limit ) {
$limit = 20;
}
switch ($address_type) {
case EmailEvent::ADDRESS_TYPE_EMAIL:
$field = 'Email';
$table_name = TABLE_PREFIX . 'Users';
break;
case EmailEvent::ADDRESS_TYPE_USER:
$field = 'Username';
$table_name = TABLE_PREFIX . 'Users';
break;
case EmailEvent::ADDRESS_TYPE_GROUP:
$field = 'Name';
$table_name = TABLE_PREFIX . 'UserGroups';
break;
default:
$field = $table_name = '';
break;
}
if ( $field ) {
$sql = 'SELECT DISTINCT ' . $field . '
FROM ' . $table_name . '
WHERE ' . $field . ' LIKE ' . $this->Conn->qstr($address . '%') . '
ORDER BY ' . $field . ' ASC
LIMIT 0,' . $limit;
$data = $this->Conn->GetCol($sql);
}
else {
$data = Array ();
}
$this->Application->XMLHeader();
echo '<suggestions>';
foreach ($data as $item) {
echo '<item>' . htmlspecialchars($item) . '</item>';
}
echo '</suggestions>';
}
/**
* Does custom validation
*
* @param kEvent $event
* @return void
* @access protected
*/
protected function OnBeforeItemValidate(kEvent $event)
{
parent::OnBeforeItemValidate($event);
$object = $event->getObject();
/* @var $object kDBItem */
// validate email subject and body for parsing errors
$this->_validateEmailTemplate($object);
// validate sender and recipient addresses
if ( $object->GetDBField('CustomSender') ) {
$this->_validateAddress($event, 'Sender');
}
$this->_validateAddress($event, 'Recipient');
$this->_validateBindEvent($object);
}
/**
* Validates subject and body fields of Email template
*
* @param kDBItem $object
* @return void
* @access protected
*/
protected function _validateEmailTemplate($object)
{
$email_message_helper = $this->Application->recallObject('kEmailMessageHelper');
/* @var $email_message_helper kEmailMessageHelper */
$email_message_helper->parseField($object, 'Subject');
$email_message_helper->parseField($object, 'HtmlBody');
$email_message_helper->parseField($object, 'PlainTextBody');
}
/**
* Validates address using given field prefix
*
* @param kEvent $event
* @param string $field_prefix
* @return void
* @access protected
*/
protected function _validateAddress($event, $field_prefix)
{
$object = $event->getObject();
/* @var $object kDBItem */
$address_type = $object->GetDBField($field_prefix . 'AddressType');
$object->setRequired($field_prefix . 'Address', $address_type > 0);
$address = $object->GetDBField($field_prefix . 'Address');
if ( !$address ) {
// don't validate against empty address
return;
}
switch ($address_type) {
case EmailEvent::ADDRESS_TYPE_EMAIL:
if ( !preg_match('/^(' . REGEX_EMAIL_USER . '@' . REGEX_EMAIL_DOMAIN . ')$/i', $address) ) {
$object->SetError($field_prefix . 'Address', 'invalid_email');
}
break;
case EmailEvent::ADDRESS_TYPE_USER:
$sql = 'SELECT PortalUserId
FROM ' . TABLE_PREFIX . 'Users
WHERE Username = ' . $this->Conn->qstr($address);
if ( !$this->Conn->GetOne($sql) ) {
$object->SetError($field_prefix . 'Address', 'invalid_user');
}
break;
case EmailEvent::ADDRESS_TYPE_GROUP:
$sql = 'SELECT GroupId
FROM ' . TABLE_PREFIX . 'UserGroups
WHERE Name = ' . $this->Conn->qstr($address);
if ( !$this->Conn->GetOne($sql) ) {
$object->SetError($field_prefix . 'Address', 'invalid_group');
}
break;
}
}
/**
* Checks that bind event is specified in correct format and exists
*
* @param kDBItem $object
*/
protected function _validateBindEvent($object)
{
$event_string = $object->GetDBField('BindToSystemEvent');
if ( !$event_string ) {
return;
}
try {
$this->Application->eventImplemented(new kEvent($event_string));
}
catch (Exception $e) {
$object->SetError('BindToSystemEvent', 'invalid_event', '+' . $e->getMessage());
}
}
/**
* Stores ids of selected phrases and redirects to export language step 1
*
* @param kEvent $event
* @return void
* @access protected
*/
protected function OnExportEmailEvents(kEvent $event)
{
if ( $this->Application->CheckPermission('SYSTEM_ACCESS.READONLY', 1) ) {
$event->status = kEvent::erFAIL;
return;
}
$this->Application->setUnitOption('phrases', 'AutoLoad', false);
$this->StoreSelectedIDs($event);
$this->Application->StoreVar('export_language_ids', $this->Application->GetVar('m_lang'));
$event->setRedirectParams(
Array (
'phrases.export_event' => 'OnNew',
'pass' => 'all,phrases.export',
'export_mode' => $event->Prefix,
)
);
}
/**
* Deletes all subscribers to e-mail event after it was deleted
*
* @param kEvent $event
* @return void
* @access protected
*/
protected function OnAfterItemDelete(kEvent $event)
{
parent::OnAfterItemDelete($event);
$object = $event->getObject();
/* @var $object kDBItem */
$sql = 'SELECT SubscriptionId
FROM ' . TABLE_PREFIX . 'SystemEventSubscriptions
WHERE EmailEventId = ' . $object->GetID();
$ids = $this->Conn->GetCol($sql);
if ( !$ids ) {
return;
}
$temp_handler = $this->Application->recallObject('system-event-subscription_TempHandler', 'kTempTablesHandler');
/* @var $temp_handler kTempTablesHandler */
$temp_handler->DeleteItems('system-event-subscription', '', $ids);
}
}
\ No newline at end of file
Event Timeline
Log In to Comment