Page Menu
Home
In-Portal Phabricator
Search
Configure Global Search
Log In
Files
F1168232
email_events_event_handler.php
No One
Temporary
Actions
Download 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
Wed, Sep 24, 8:57 AM
Size
16 KB
Mime Type
text/x-php
Expires
Fri, Sep 26, 8:57 AM (1 d, 43 m)
Engine
blob
Format
Raw Data
Handle
756796
Attached To
rINP In-Portal
email_events_event_handler.php
View Options
<?php
/**
* @version $Id: email_events_event_handler.php 13013 2010-01-05 09:53:20Z alex $
* @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 standart permission mapping
*
*/
function
mapPermissions
()
{
parent
::
mapPermissions
();
$permissions
=
Array
(
'OnFrontOnly'
=>
Array
(
'self'
=>
'edit'
),
'OnSaveSelected'
=>
Array
(
'self'
=>
'view'
),
'OnProcessEmailQueue'
=>
Array
(
'self'
=>
'add|edit'
),
);
$this
->
permMapping
=
array_merge
(
$this
->
permMapping
,
$permissions
);
}
/**
* Changes permission section to one from REQUEST, not from config
*
* @param kEvent $event
*/
function
CheckPermission
(&
$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
* @access protected
* @see OnListBuild
*/
function
SetCustomQuery
(&
$event
)
{
if
(
$event
->
Special
==
'module'
)
{
$object
=&
$event
->
getObject
();
$module
=
$this
->
Application
->
GetVar
(
'module'
);
$object
->
addFilter
(
'module_filter'
,
'%1$s.Module = '
.
$this
->
Conn
->
qstr
(
$module
));
}
}
/**
* 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
=
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
*/
function
OnSelectUser
(&
$event
)
{
if
(
$event
->
Special
!=
'module'
)
{
parent
::
OnSelectUser
(
$event
);
return
;
}
if
(
$this
->
Application
->
CheckPermission
(
'SYSTEM_ACCESS.READONLY'
,
1
))
{
$event
->
status
=
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
);
}
/**
* Returns sender & recipients ids plus event_id (as parameter by reference)
*
* @param kEvent $event
* @param int $event_id id of email event used
*
* @return mixed
*/
function
GetMessageRecipients
(&
$event
,
&
$event_id
)
{
$email_event
=&
$event
->
getObject
(
Array
(
'skip_autoload'
=>
true
)
);
/* @var $email_event kDBItem */
// get event parameters by name & type
$load_keys
=
Array
(
'Event'
=>
$event
->
getEventParam
(
'EmailEventName'
),
'Type'
=>
$event
->
getEventParam
(
'EmailEventType'
),
);
$email_event
->
Load
(
$load_keys
);
if
(!
$email_event
->
isLoaded
())
{
// event record not found
return
false
;
}
if
(
$email_event
->
GetDBField
(
'Enabled'
)
==
STATUS_DISABLED
)
{
return
false
;
}
if
(
$email_event
->
GetDBField
(
'FrontEndOnly'
)
&&
$this
->
Application
->
isAdmin
)
{
return
false
;
}
// initial values
$to_user_id
=
$event
->
getEventParam
(
'EmailEventToUserId'
);
if
(
!
is_numeric
(
$to_user_id
)
)
{
$to_user_id
=
-
1
;
// when not specified, then send to "root"
}
$from_user_id
=
$email_event
->
GetDBField
(
'FromUserId'
);
if
(
$email_event
->
GetDBField
(
'Type'
)
==
EVENT_TYPE_ADMIN
)
{
// For type "Admin" recipient is a user from field FromUserId which means From/To user in Email events list
if
(
$to_user_id
==
-
1
)
{
$to_user_id
=
$from_user_id
;
}
$from_user_id
=
-
1
;
}
$event_id
=
$email_event
->
GetDBField
(
'EventId'
);
return
Array
(
$from_user_id
,
$to_user_id
);
}
/**
* Returns user name, email by id, or ones, that specified in $direct_params
*
* @param int $user_id
* @param string $user_type type of user = {to,from}
* @param Array $direct_params
* @return Array
*/
function
GetRecipientInfo
(
$user_id
,
$user_type
,
$direct_params
=
null
)
{
// load user, because it can be addressed from email template tags
$user
=&
$this
->
Application
->
recallObject
(
'u.email-'
.
$user_type
,
null
,
Array
(
'skip_autoload'
=>
true
));
/* @var $user UsersItem */
$email
=
$name
=
''
;
$result
=
$user_id
>
0
?
$user
->
Load
(
(
int
)
$user_id
)
:
$user
->
Clear
();
if
(
$user
->
IsLoaded
())
{
$email
=
$user
->
GetDBField
(
'Email'
);
$name
=
trim
(
$user
->
GetDBField
(
'FirstName'
).
' '
.
$user
->
GetDBField
(
'LastName'
));
}
if
(
is_array
(
$direct_params
))
{
if
(
isset
(
$direct_params
[
$user_type
.
'_email'
]))
{
$email
=
$direct_params
[
$user_type
.
'_email'
];
}
if
(
isset
(
$direct_params
[
$user_type
.
'_name'
]))
{
$name
=
$direct_params
[
$user_type
.
'_name'
];
}
}
if
(!
$email
)
{
// if email is empty, then use admins email
$email
=
$this
->
Application
->
ConfigValue
(
'Smtp_AdminMailFrom'
);
}
if
(!
$name
)
{
$name
=
$user_type
==
'from'
?
strip_tags
(
$this
->
Application
->
ConfigValue
(
'Site_Name'
))
:
$email
;
}
return
Array
(
$email
,
$name
);
}
/**
* Returns email event message by ID (headers & body in one piece)
*
* @param int $event_id
* @param string $message_type contains message type = {text,html}
* @param int $language_id
*/
function
GetMessageBody
(
$event_id
,
&
$message_type
,
$language_id
=
null
)
{
if
(!
isset
(
$language_id
))
{
$language_id
=
$this
->
Application
->
GetVar
(
'm_lang'
);
}
$message
=&
$this
->
Application
->
recallObject
(
'emailmessages'
,
null
,
Array
(
'skip_autoload'
=>
true
));
/* @var $message kDBItem */
$message
->
Load
(
Array
(
'EventId'
=>
$event_id
,
'LanguageId'
=>
$language_id
)
);
if
(!
$message
->
isLoaded
())
{
// event translation on required language not found
return
false
;
}
$message_type
=
$message
->
GetDBField
(
'MessageType'
);
// 1. get message body
$message_body
=
$message
->
GetDBField
(
'Template'
);
// 2. add footer
$sql
=
'SELECT em.Template
FROM '
.
$message
->
TableName
.
' em
LEFT JOIN '
.
TABLE_PREFIX
.
'Events e ON e.EventId = em.EventId
WHERE em.LanguageId = '
.
$language_id
.
' AND e.Event = "COMMON.FOOTER"'
;
list
(,
$footer
)
=
explode
(
"
\n\n
"
,
$this
->
Conn
->
GetOne
(
$sql
));
if
(
$message_type
==
'text'
)
{
$esender
=&
$this
->
Application
->
recallObject
(
'EmailSender'
);
/* @var $esender kEmailSendingHelper */
$footer
=
$esender
->
ConvertToText
(
$footer
);
}
if
(
$footer
)
{
$message_body
.=
"
\r\n
"
.
$footer
;
}
// 3. replace tags if needed
$default_replacement_tags
=
Array
(
'<inp:touser _Field="password"'
=>
'<inp2:u_Field name="Password_plain"'
,
'<inp:touser _Field="UserName"'
=>
'<inp2:u_Field name="Login"'
,
'<inp:touser _Field'
=>
'<inp2:u_Field name'
,
);
$replacement_tags
=
$message
->
GetDBField
(
'ReplacementTags'
);
$replacement_tags
=
$replacement_tags
?
unserialize
(
$replacement_tags
)
:
Array
();
$replacement_tags
=
array_merge_recursive2
(
$default_replacement_tags
,
$replacement_tags
);
foreach
(
$replacement_tags
as
$replace_from
=>
$replace_to
)
{
$message_body
=
str_replace
(
$replace_from
,
$replace_to
,
$message_body
);
}
return
$message_body
;
}
/**
* Parse message template and return headers (as array) and message body part
*
* @param string $message
* @param Array $direct_params
* @return Array
*/
function
ParseMessageBody
(
$message
,
$direct_params
=
null
)
{
$message_language
=
$this
->
_getSendLanguage
(
$direct_params
);
$this
->
_changeLanguage
(
$message_language
);
$direct_params
[
'message_text'
]
=
isset
(
$direct_params
[
'message'
])
?
$direct_params
[
'message'
]
:
''
;
// parameter alias
// 1. parse template
$this
->
Application
->
InitParser
();
$parser_params
=
$this
->
Application
->
Parser
->
Params
;
// backup parser params
$this
->
Application
->
Parser
->
SetParams
(
array_merge_recursive2
(
$parser_params
,
$direct_params
)
);
$message
=
implode
(
'&|&'
,
explode
(
"
\n\n
"
,
$message
,
2
));
// preserves double \n in case when tag is located in subject field
$message
=
$this
->
Application
->
Parser
->
Parse
(
$message
,
'email_template'
,
0
);
$this
->
Application
->
Parser
->
SetParams
(
$parser_params
);
// restore parser params
// 2. replace line endings, that are send with data submitted via request
$message
=
str_replace
(
"
\r\n
"
,
"
\n
"
,
$message
);
// possible case
$message
=
str_replace
(
"
\r
"
,
"
\n
"
,
$message
);
// impossible case, but just in case replace this too
// 3. separate headers from body
$message_headers
=
Array
();
list
(
$headers
,
$message_body
)
=
explode
(
'&|&'
,
$message
,
2
);
$category_helper
=&
$this
->
Application
->
recallObject
(
'CategoryHelper'
);
/* @var $category_helper CategoryHelper */
$message_body
=
$category_helper
->
replacePageIds
(
$message_body
);
$headers
=
explode
(
"
\n
"
,
$headers
);
foreach
(
$headers
as
$header
)
{
$header
=
explode
(
':'
,
$header
,
2
);
$message_headers
[
trim
(
$header
[
0
])
]
=
trim
(
$header
[
1
]);
}
$this
->
_changeLanguage
();
return
Array
(
$message_headers
,
$message_body
);
}
/**
* Raised when email message shoul be sent
*
* @param kEvent $event
*/
function
OnEmailEvent
(&
$event
)
{
$email_event_name
=
$event
->
getEventParam
(
'EmailEventName'
);
if
(
strpos
(
$email_event_name
,
'_'
)
!==
false
)
{
trigger_error
(
'<span class="debug_error">Invalid email event name</span> <b>'
.
$email_event_name
.
'</b>. Use only <b>UPPERCASE characters</b> and <b>dots</b> as email event names'
,
E_USER_ERROR
);
}
// additional parameters from kApplication->EmailEvent
$send_params
=
$event
->
getEventParam
(
'DirectSendParams'
);
// 1. get information about message sender and recipient
$recipients
=
$this
->
GetMessageRecipients
(
$event
,
$event_id
);
if
(
$recipients
===
false
)
{
// if not valid recipients found, then don't send event
return
false
;
}
list
(
$from_id
,
$to_id
)
=
$recipients
;
list
(
$from_email
,
$from_name
)
=
$this
->
GetRecipientInfo
(
$from_id
,
'from'
,
$send_params
);
list
(
$to_email
,
$to_name
)
=
$this
->
GetRecipientInfo
(
$to_id
,
'to'
,
$send_params
);
// 2. prepare message to be sent
$message_language
=
$this
->
_getSendLanguage
(
$send_params
);
$message_template
=
$this
->
GetMessageBody
(
$event_id
,
$message_type
,
$message_language
);
if
(!
trim
(
$message_template
))
{
trigger_error
(
'Message template is empty'
,
E_USER_WARNING
);
return
false
;
}
list
(
$message_headers
,
$message_body
)
=
$this
->
ParseMessageBody
(
$message_template
,
$send_params
);
if
(!
trim
(
$message_body
))
{
trigger_error
(
'Message template is empty after parsing'
,
E_USER_WARNING
);
return
false
;
}
// 3. set headers & send message
$esender
=&
$this
->
Application
->
recallObject
(
'EmailSender'
);
/* @var $esender kEmailSendingHelper */
$esender
->
SetFrom
(
$from_email
,
$from_name
);
$esender
->
AddTo
(
$to_email
,
$to_name
);
$message_subject
=
isset
(
$message_headers
[
'Subject'
])
?
$message_headers
[
'Subject'
]
:
'Mail message'
;
$esender
->
SetSubject
(
$message_subject
);
if
(
$this
->
Application
->
isDebugMode
())
{
// set special header with event name, so it will be easier to determite what's actually was received
$message_headers
[
'X-Event-Name'
]
=
$email_event_name
.
' - '
.
(
$event
->
getEventParam
(
'EmailEventType'
)
==
1
?
'ADMIN'
:
'USER'
);
}
foreach
(
$message_headers
as
$header_name
=>
$header_value
)
{
$esender
->
SetEncodedHeader
(
$header_name
,
$header_value
);
}
$esender
->
CreateTextHtmlPart
(
$message_body
,
$message_type
==
'html'
);
$event
->
status
=
$esender
->
Deliver
()
?
erSUCCESS
:
erFAIL
;
if
(
$event
->
status
==
erSUCCESS
){
// all keys, that are not used in email sending are written to log record
$send_keys
=
Array
(
'from_email'
,
'from_name'
,
'to_email'
,
'to_name'
,
'message'
);
foreach
(
$send_keys
as
$send_key
)
{
unset
(
$send_params
[
$send_key
]);
}
$fields_hash
=
Array
(
'fromuser'
=>
$from_name
.
' ('
.
$from_email
.
')'
,
'addressto'
=>
$to_name
.
' ('
.
$to_email
.
')'
,
'subject'
=>
$message_subject
,
'timestamp'
=>
adodb_mktime
(),
'event'
=>
$email_event_name
,
'EventParams'
=>
serialize
(
$send_params
),
);
$this
->
Conn
->
doInsert
(
$fields_hash
,
TABLE_PREFIX
.
'EmailLog'
);
}
$this
->
Application
->
removeObject
(
'u.email-from'
);
$this
->
Application
->
removeObject
(
'u.email-to'
);
}
function
_getSendLanguage
(
$send_params
)
{
if
(
$send_params
&&
array_key_exists
(
'language_id'
,
$send_params
))
{
return
$send_params
[
'language_id'
];
}
return
$this
->
Application
->
GetVar
(
'm_lang'
);
}
function
_changeLanguage
(
$language_id
=
null
)
{
static
$prev_language_id
=
null
;
if
(!
isset
(
$language_id
))
{
// restore language
$language_id
=
$prev_language_id
;
}
$this
->
Application
->
SetVar
(
'm_lang'
,
$language_id
);
$language
=&
$this
->
Application
->
recallObject
(
'lang.current'
);
/* @var $lang_object kDBItem */
$language
->
Load
(
$language_id
);
$this
->
Application
->
Phrases
->
LanguageId
=
$language_id
;
$this
->
Application
->
Phrases
->
Phrases
=
Array
();
$prev_language_id
=
$language_id
;
// for restoring it later
}
/**
* 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
=
erSTOP
;
echo
(
$emails_sent
/
$total_emails
)
*
100
;
}
}
}
Event Timeline
Log In to Comment