Seditio Source
Root |
./othercms/b2evolution_7.2.3/inc/automations/model/_automationstep.class.php
<?php
/**
 * This file implements the automation step class.
 *
 * This file is part of the b2evolution/evocms project - {@link http://b2evolution.net/}.
 * See also {@link https://github.com/b2evolution/b2evolution}.
 *
 * @license GNU GPL v2 - {@link http://b2evolution.net/about/gnu-gpl-license}
 *
 * @copyright (c)2003-2020 by Francois Planque - {@link http://fplanque.com/}.
*
 * @license http://b2evolution.net/about/license.html GNU General Public License (GPL)
 *
 * @package evocore
 */
if( !defined('EVO_MAIN_INIT') ) die( 'Please, do not access this page directly.' );

load_class( '_core/model/dataobjects/_dataobject.class.php', 'DataObject' );
load_funcs( 'automations/model/_automation.funcs.php' );


/**
 * AutomationStep Class
 *
 * @package evocore
 */
class AutomationStep extends DataObject
{
    var
$autm_ID;
    var
$order;
    var
$label;
    var
$type;
    var
$info;
    var
$yes_next_step_ID;
    var
$yes_next_step_delay;
    var
$no_next_step_ID;
    var
$no_next_step_delay;
    var
$error_next_step_ID;
    var
$error_next_step_delay;
    var
$diagram;

    var
$Automation = NULL;

    var
$yes_next_AutomationStep = NULL;
    var
$no_next_AutomationStep = NULL;
    var
$error_next_AutomationStep = NULL;

   
/**
     * Constructor
     *
     * @param object table Database row
     */
   
function __construct( $db_row = NULL )
    {
       
// Call parent constructor:
       
parent::__construct( 'T_automation__step', 'step_', 'step_ID' );

        if(
$db_row !== NULL )
        {
           
$this->ID = $db_row->step_ID;
           
$this->autm_ID = $db_row->step_autm_ID;
           
$this->order = $db_row->step_order;
           
$this->label = $db_row->step_label;
           
$this->type = $db_row->step_type;
           
$this->info = $db_row->step_info;
           
$this->yes_next_step_ID = $db_row->step_yes_next_step_ID;
           
$this->yes_next_step_delay = $db_row->step_yes_next_step_delay;
           
$this->no_next_step_ID = $db_row->step_no_next_step_ID;
           
$this->no_next_step_delay = $db_row->step_no_next_step_delay;
           
$this->error_next_step_ID = $db_row->step_error_next_step_ID;
           
$this->error_next_step_delay = $db_row->step_error_next_step_delay;
           
$this->diagram = $db_row->step_diagram;
        }
    }


   
/**
     * Get delete restriction settings
     *
     * @return array
     */
   
static function get_delete_restrictions()
    {
        return array(
                array(
'table' => 'T_automation__user_state', 'fk' => 'aust_next_step_ID', 'msg' => TB_('%d states of User in Automation') ),
                array(
'table' => 'T_automation__step', 'fk' => 'step_yes_next_step_ID', 'and_condition' => 'step_yes_next_step_ID != step_ID', 'msg' => TB_('Step is used as Next Step %d times').' '.TB_('("YES" column)') ),
                array(
'table' => 'T_automation__step', 'fk' => 'step_no_next_step_ID', 'and_condition' => 'step_no_next_step_ID != step_ID', 'msg' => TB_('Step is used as Next Step %d times').' '.TB_('("NO" column)') ),
                array(
'table' => 'T_automation__step', 'fk' => 'step_error_next_step_ID', 'and_condition' => 'step_error_next_step_ID != step_ID', 'msg' => TB_('Step is used as Next Step %d times').' '.TB_('("ERROR" column)') ),
            );
    }


   
/**
     * Insert object into DB based on previously recorded changes.
     *
     * @param boolean TRUE to check if step can be inserted e.g. when automation is not paused
     * @return boolean true on success
     */
   
function dbinsert( $check_restriction = true )
    {
        if(
$check_restriction && ! $this->can_be_modified() )
        {    
// If this step cannnot be modified
           
return false;
        }

        if(
$r = parent::dbinsert() )
        {
           
// Update next steps with selected option "Loop" to ID of this new inserted Step:
           
$next_steps = array(
               
'yes_next_step_ID',
               
'no_next_step_ID',
               
'error_next_step_ID',
            );
            foreach(
$next_steps as $next_step_ID_name )
            {
                if(
get_param( 'step_'.$next_step_ID_name ) == 'loop' )
                {
                   
$this->set( $next_step_ID_name, $this->ID ); // Loop
               
}
            }
           
$this->dbupdate();
        }

        return
$r;
    }


   
/**
     * Update the DB based on previously recorded changes
     *
     * @return boolean true on success, false on failure to update, NULL if no update necessary
     */
   
function dbupdate()
    {
        if( !
$this->can_be_modified() )
        {    
// If this step cannnot be modified
           
return false;
        }

        return
parent::dbupdate();
    }


   
/**
     * Get a member param by its name
     *
     * @param mixed Name of parameter
     * @return mixed Value of parameter
     */
   
function get( $parname )
    {
        switch(
$parname )
        {
            case
'if_condition_js_object':
               
// Format values(like dates) of the field "IF Condition" from MySQL DB format to current locale format:
               
return param_format_condition( $this->get( 'info' ), 'js' );
        }

        return
parent::get( $parname );
    }


   
/**
     * Load data from Request form fields.
     *
     * @return boolean true if loaded data seems valid.
     */
   
function load_from_Request()
    {
        global
$DB, $admin_url;

        if( empty(
$this->ID ) )
        {    
// Set Automation only for new creating Step:
           
param( 'autm_ID', 'integer', true );
           
$this->set_from_Request( 'autm_ID', 'autm_ID' );
        }

        if( !
$this->can_be_modified() && ! param( 'confirm_pause', 'integer' ) )
        {    
// Don't allow to edit step of active automation without confirmation:
           
global $Messages;
           
$Messages->add( empty( $this->ID )
                ?
TB_('You must pause the automation before creating new step.')
                :
TB_('You must pause the automation before changing step.'), 'error' );
        }

       
// Order:
       
$step_order = param( 'step_order', 'integer', NULL );
        if(
$this->ID > 0 )
        {    
// Order is required for edited step:
           
param_string_not_empty( 'step_order', TB_('Please enter a step order number.') );
        }
        elseif(
$step_order === NULL )
        {    
// Set order for new creating step automatically:
           
$max_order_SQL = new SQL( 'Get max step order for Automation #'.$this->get( 'autm_ID' ) );
           
$max_order_SQL->SELECT( 'MAX( step_order )' );
           
$max_order_SQL->FROM( 'T_automation__step' );
           
$max_order_SQL->WHERE( 'step_autm_ID = '.$this->get( 'autm_ID' ) );
           
set_param( 'step_order', $DB->get_var( $max_order_SQL ) + 1 );
        }
       
$this->set_from_Request( 'order' );
        if(
$this->get( 'order' ) > 0 )
        {    
// Check for unique order per Automation:
           
$check_order_SQL = new SQL( 'Check unique step order for Automation #'.$this->get( 'autm_ID' ) );
           
$check_order_SQL->SELECT( 'step_ID' );
           
$check_order_SQL->FROM( 'T_automation__step' );
           
$check_order_SQL->WHERE( 'step_autm_ID = '.$this->get( 'autm_ID' ) );
           
$check_order_SQL->WHERE_and( 'step_order = '.$this->get( 'order' ) );
            if(
$this->ID > 0 )
            {    
// Exclude this Step:
               
$check_order_SQL->WHERE_and( 'step_ID != '.$this->ID );
            }
            if(
$existing_step_ID = $DB->get_var( $check_order_SQL ) )
            {    
// Display error because of duplicated order in the same Automation:
               
global $admin_url;
               
param_error( 'step_order',
                   
sprintf( TB_('Another step with the same order number already exists in the current automation. Do you want to <a %s>edit that step</a>?'),
                       
'href="'.$admin_url.'?ctrl=automations&amp;action=edit_step&amp;step_ID='.$existing_step_ID.'"' ) );
            }
        }
       
param_check_range( 'step_order', -2147483646, 2147483647, sprintf( TB_('Step order must be numeric (%d - %d).'), -2147483646, 2147483647 ) );

       
// Type:
       
param_string_not_empty( 'step_type', 'Please select a step type.' );
       
$this->set_from_Request( 'type' );
       
// Save additional info depending on step type:
       
switch( $this->get( 'type' ) )
        {
            case
'if_condition':
               
// IF Condition:
               
param_condition( 'step_if_condition' );
               
param_string_not_empty( 'step_if_condition', TB_('Please set a condition.') );
               
$this->set( 'info', get_param( 'step_if_condition' ) );
                break;

            case
'send_campaign':
               
// Email campaign:
               
param( 'step_email_campaign', 'integer', NULL );
               
param_check_number( 'step_email_campaign', TB_('Please select an email campaign.'), true );
               
$this->set( 'info', get_param( 'step_email_campaign' ) );
                break;

            case
'notify_owner':
               
// Notify owner:
               
param( 'step_notification_message', 'text' );
               
param_check_not_empty( 'step_notification_message', TB_('Please enter a notification message.') );
               
$this->set( 'info', get_param( 'step_notification_message' ) );
                break;

            case
'add_usertag':
            case
'remove_usertag':
               
// Add/Remove usertag:
               
param_string_not_empty( 'step_usertag', TB_('Please enter an user tag.') );
                if(
preg_match( '/(^-|[;,])/', get_param( 'step_usertag' ) ) )
                {    
// If usertag has a not allowed char:
                   
param_error( 'step_usertag', sprintf( TB_('Usertag cannot start with %s and contain chars %s'), '<code>-</code>', '<code>;,</code>' ) );
                }
               
$this->set( 'info', get_param( 'step_usertag' ) );
                break;

            case
'subscribe':
            case
'unsubscribe':
               
// Subscribe/Unsubscribe:
               
param( 'step_newsletter', 'integer', true );
               
param_check_not_empty( 'step_newsletter', TB_('Please select a list.') );
               
$this->set( 'info', get_param( 'step_newsletter' ) );
                break;

            case
'start_automation':
               
// Start new automation:
               
param( 'step_automation', 'integer', true );
               
param_check_not_empty( 'step_automation', TB_('Please select an automation.') );
               
$this->set( 'info', get_param( 'step_automation' ) );
                break;

            case
'user_status':
               
// Change user account status:
               
param( 'user_status', 'string', true );
               
param_check_not_empty( 'user_status', /* Do NOT translate because this error is impossible for normal form */'Please select an account status.' );
               
$this->set( 'info', get_param( 'user_status' ) );
                break;

            default:
               
$this->set( 'info', NULL, true );
        }

       
// Next steps:
       
$next_steps = array(
               
'yes_next_step_ID'   => 'yes_next_step_delay',
               
'no_next_step_ID'    => 'no_next_step_delay',
               
'error_next_step_ID' => 'error_next_step_delay',
            );
        foreach(
$next_steps as $next_step_ID_name => $next_step_delay_name )
        {
            if( (
$this->get( 'type' ) == 'notify_owner' && $next_step_ID_name == 'no_next_step_ID' ) ||
                (
in_array( $this->get( 'type' ), array( 'add_usertag', 'remove_usertag' ) ) && $next_step_ID_name == 'error_next_step_ID' ) )
            {    
// Some next steps are not used depending on step type:
               
$this->set( $next_step_ID_name, NULL, true );
               
$this->set( $next_step_delay_name, NULL, true );
            }
            else
            {
               
$this->set( $next_step_ID_name, intval( param( 'step_'.$next_step_ID_name, 'string' ) ) );
               
$this->set( $next_step_delay_name, param_duration( 'step_'.$next_step_delay_name ) );
            }
        }

       
// Label:
       
$this->set_label();

        return !
param_errors_detected();
    }


   
/**
     * Get Automation object of this step
     *
     * @return object Automation
     */
   
function & get_Automation()
    {
        if(
$this->Automation === NULL )
        {    
// Initialize Automation object only first time and store in cache:
           
$AutomationCache = & get_AutomationCache();
           
$this->Automation = & $AutomationCache->get_by_ID( $this->get( 'autm_ID' ), false, false );
        }

        return
$this->Automation;
    }


   
/**
     * Get next Step object of this Step by step ID
     *
     * @param integer Step type: 'yes', 'no', 'error'
     * @return object|boolean Next Automation Step OR
     *                        FALSE - if automation should be stopped after this Step
     *                                because either it is configured for STOP action
     *                                            or it is the latest step of the automation
     */
   
function & get_next_AutomationStep_by_type( $next_step_type )
    {
        switch(
$next_step_type )
        {
            case
'YES':
               
$next_step_ID = $this->get( 'yes_next_step_ID' );
                break;
            case
'NO':
               
$next_step_ID = $this->get( 'no_next_step_ID' );
                break;
            case
'ERROR':
               
$next_step_ID = $this->get( 'error_next_step_ID' );
                break;
            default:
               
debug_die( 'Invalid automation next step type "'.$next_step_type.'"' );
        }

       
$next_AutomationStep = false;

       
$possible_step_type_results = step_get_result_labels();
        if( empty(
$possible_step_type_results[ $this->get( 'type' ) ][ $next_step_type ] ) )
        {    
// If the requested result(YES, NO or ERROR) is not supported by current step type:
           
return $next_AutomationStep;
        }

       
$next_step_ID = intval( $next_step_ID );

       
$AutomationStepCache = & get_AutomationStepCache();
        if(
$next_step_ID > 0 )
        {    
// Get a next Step by defined ID:
           
$next_AutomationStep = & $AutomationStepCache->get_by_ID( $next_step_ID, false, false );
        }

        if(
$next_step_ID == -1 )
        {    
// Stop workflow when option is selected to "STOP":
           
$next_AutomationStep = false;
        }
        elseif(
$next_step_ID == 0 || ! $next_AutomationStep )
        {    
// Get next ordered Step when option is selected to "Continue" OR Step cannot be found by ID in DB:
           
$next_AutomationStep = & $AutomationStepCache->get_by_ID( $this->get_next_ordered_step_ID(), false, false );
            if( empty(
$next_AutomationStep ) )
            {    
// If it is the latest Step of the Automation:
               
$next_AutomationStep = false;
            }
        }

        return
$next_AutomationStep;
    }


   
/**
     * Get ID of the next ordered Step after this Step
     *
     * @return integer|NULL Step ID or NULL if this is the latest
     */
   
function get_next_ordered_step_ID()
    {
        if( empty(
$this->ID ) )
        {    
// New creating step is the latest by default:
           
return NULL;
        }

        global
$DB;

       
$next_ordered_step_SQL = new SQL( 'Get next ordered Step after current Step #'.$this->ID );
       
$next_ordered_step_SQL->SELECT( 'step_ID' );
       
$next_ordered_step_SQL->FROM( 'T_automation__step' );
       
$next_ordered_step_SQL->WHERE( 'step_autm_ID = '.$DB->quote( $this->get( 'autm_ID' ) ) );
       
$next_ordered_step_SQL->WHERE_and( 'step_order > '.$DB->quote( $this->get( 'order' ) ) );
       
$next_ordered_step_SQL->ORDER_BY( 'step_order ASC' );
       
$next_ordered_step_SQL->LIMIT( 1 );

        return
$DB->get_var( $next_ordered_step_SQL );
    }


   
/**
     * Get YES next Step object of this Step
     *
     * @return object|boolean Next Automation Step OR
     *                        FALSE - if automation should be stopped after this Step
     *                                because either it is configured for STOP action
     *                                            or it is the latest step of the automation
     */
   
function & get_yes_next_AutomationStep()
    {
        if(
$this->yes_next_AutomationStep === NULL )
        {    
// Load next Step into cache object:
           
$this->yes_next_AutomationStep = & $this->get_next_AutomationStep_by_type( 'YES' );
        }

        return
$this->yes_next_AutomationStep;
    }


   
/**
     * Get NO next Step object of this Step
     *
     * @return object|boolean Next Automation Step OR
     *                        FALSE - if automation should be stopped after this Step
     *                                because either it is configured for STOP action
     *                                            or it is the latest step of the automation
     */
   
function & get_no_next_AutomationStep()
    {
        if(
$this->no_next_AutomationStep === NULL )
        {    
// Load next Step into cache object:
           
$this->no_next_AutomationStep = & $this->get_next_AutomationStep_by_type( 'NO' );
        }

        return
$this->no_next_AutomationStep;
    }


   
/**
     * Get ERROR next Step object of this Step
     *
     * @return object|boolean Next Automation Step OR
     *                        FALSE - if automation should be stopped after this Step
     *                                because either it is configured for STOP action
     *                                            or it is the latest step of the automation
     */
   
function & get_error_next_AutomationStep()
    {
        if(
$this->error_next_AutomationStep === NULL )
        {    
// Load next Step into cache object:
           
$this->error_next_AutomationStep = & $this->get_next_AutomationStep_by_type( 'ERROR' );
        }

        return
$this->error_next_AutomationStep;
    }


   
/**
     * Execute action for this step
     *
     * @param integer User ID
     * @return string A process log
     */
   
function execute_action( $user_ID )
    {
        global
$DB, $servertimenow, $mail_log_message, $executed_automation_steps;

       
// Initialize array to store executed steps per user in order to avoid infinite loops:
       
if( ! isset( $executed_automation_steps ) )
        {
           
$executed_automation_steps = array();
        }
        if( ! isset(
$executed_automation_steps[ $user_ID ] ) )
        {
           
$executed_automation_steps[ $user_ID ] = array();
        }

       
$Automation = & $this->get_Automation();

       
$log_nl = "\n";
       
$log_point = ' - ';
       
$log_bold_start = '<b>';
       
$log_bold_end = '</b>';

       
$UserCache = & get_UserCache();
       
$step_User = & $UserCache->get_by_ID( $user_ID, false, false );

       
// Log:
       
$process_log = 'Executing '.$log_bold_start.'Step #'.$this->get( 'order' ).$log_bold_end
           
.'('.step_get_type_title( $this->get( 'type' ) ).': '.$this->get( 'label' ).')'
           
.' of '.$log_bold_start.'Automation: #'.$Automation->ID.$log_bold_end.'('.$Automation->get( 'name' ).')'
           
.' for '.$log_bold_start.'User #'.$user_ID.$log_bold_end.( $step_User ? '('.$step_User->get( 'login' ).')' : '' ).'...'.$log_nl;

       
// Retrun ERROR result by default for all unknown cases:
       
$step_result = 'ERROR';
       
$additional_result_message = '';

        if(
$step_User )
        {    
// Allow to execute action only if User is detected in DB:
           
switch( $this->get( 'type' ) )
            {
                case
'if_condition':
                    if(
$this->check_if_condition( $step_User, $if_condition_log ) )
                    {    
// The user is matched to condition of this step:
                       
$step_result = 'YES';
                    }
                    else
                    {    
// The user is NOT matched to condition of this step:
                       
$step_result = 'NO';
                    }
                   
// Log:
                   
$process_log .= $log_point.'Log: '.$if_condition_log.$log_nl;
                    break;

                case
'send_campaign':
                   
// Send email campaign
                   
$EmailCampaignCache = & get_EmailCampaignCache();
                    if(
$step_EmailCampaign = & $EmailCampaignCache->get_by_ID( $this->get( 'info' ), false, false ) )
                    {
                        if(
in_array( $user_ID, $step_EmailCampaign->get_recipients( 'full_receive' ) ) )
                        {    
// If user already received this email:
                           
$step_result = 'NO';
                           
$additional_result_message = 'Email was ALREADY sent';
                        }
                        elseif(
in_array( $user_ID, $step_EmailCampaign->get_recipients( 'full_skipped' ) ) )
                        {    
// If user is marked to be manually skipped:
                           
$step_result = 'NO';
                           
$additional_result_message = 'Manually skipped';
                        }
                        elseif(
in_array( $user_ID, $step_EmailCampaign->get_recipients( 'full_skipped_tag' ) ) )
                        {    
// If user has user tag that should be skipped:
                           
$step_result = 'NO';
                           
$additional_result_message = 'User has skipped user tag';
                        }
                        elseif( (
$user_subscribed_newsletter_ID = $Automation->is_user_subscribed( $user_ID ) ) &&
                               
$step_EmailCampaign->send_email( $user_ID, '', '', 'auto', $user_subscribed_newsletter_ID, $Automation->ID ) )
                        {    
// If user is subscribed to at least one newsletter of this Automation AND email has been sent to user successfully now:
                           
$step_result = 'YES';
                        }
                        else
                        {    
// Some error on sending of email to user:
                            // - problem with php mail function;
                            // - user cannot receive such email because of day limit;
                            // - user is not activated yet.
                           
$step_result = 'ERROR';
                            if(
$user_subscribed_newsletter_ID )
                            {    
// If user is subscribed but some error on email sending:
                               
$additional_result_message = empty( $mail_log_message ) ? 'Unknown error' : $mail_log_message;
                            }
                            else
                            {    
// If user just doesn't wait this email:
                               
$additional_result_message = 'User #'.$step_User->ID.'('.$step_User->get( 'login' ).') is not subscribed to email lists of the Automation';
                            }
                        }
                    }
                    else
                    {    
// Wrong stored email campaign for this step:
                       
$step_result = 'ERROR';
                       
$additional_result_message = 'Email Campaign #'.$this->get( 'info' ).' is not found in DB.';
                    }
                    break;

                case
'notify_owner':
                   
// Notify owner of automation:
                   
if( ! ( $owner_User = & $Automation->get_owner_User() ) )
                    {    
// If owner User is not detected in DB:
                       
$step_result = 'ERROR';
                       
$additional_result_message = 'Owner User #'.$this->get( 'owner_user_ID' ).' is not found in DB.';
                        break;
                    }

                   
$notification_message = str_replace( array(
                           
'$step_number$',
                           
'$step_ID$',
                           
'$automation_name$',
                           
'$automation_ID$',
                        ),
                        array(
                           
$this->get( 'order' ),
                           
$this->ID,
                           
'"'.$Automation->get( 'name' ).'"',
                           
$Automation->ID,
                        ),
                       
$this->get( 'info' ) );

                   
$step_user_login_html = $step_User->get_colored_login( array(
                           
'mask'      => '$avatar$ $login$',
                           
'use_style' => true,
                           
'protocol'  => 'http:',
                        ) );

                   
$email_template_params = array(
                       
'message_html' => nl2br( str_replace( '$login$', $step_user_login_html, $notification_message ) ),
                       
'message_text' => str_replace( '$login$', $step_User->get( 'login' ), $notification_message ),
                    );

                    if(
send_mail_to_User( $owner_User->ID, sprintf( TB_('Notification of automation %s'), '"'.$Automation->get( 'name' ).'"' ), 'automation_owner_notification', $email_template_params ) )
                    {    
// If email has been sent to user successfully now:
                       
$step_result = 'YES';
                    }
                    else
                    {    
// Some error on sending of email to user:
                        // - problem with php mail function;
                        // - user cannot receive such email because of day limit;
                        // - user is not activated yet.
                       
$step_result = 'ERROR';
                       
$additional_result_message = empty( $mail_log_message ) ? 'Unknown error' : $mail_log_message;
                    }
                    break;

                case
'add_usertag':
                   
// Add usertag:
                   
$usertags = $step_User->get_usertags();
                   
$new_usertag = $this->get( 'info' );
                    if(
in_array( $new_usertag, $usertags ) )
                    {    
// If step User was already tagged:
                       
$step_result = 'NO';
                    }
                    else
                    {    
// Add new usertag:
                       
$step_User->add_usertags( $new_usertag );
                       
$step_User->dbupdate();
                       
$step_result = 'YES';
                    }
                   
// Display tag name in log:
                   
$additional_result_message = $new_usertag;
                    break;

                case
'remove_usertag':
                   
// Remove usertag:
                   
$usertags = $step_User->get_usertags();
                   
$del_usertag = $this->get( 'info' );
                    if( !
in_array( $del_usertag, $usertags ) )
                    {    
// if step User didn't have that tag:
                       
$step_result = 'NO';
                    }
                    else
                    {    
// Remove usertag:
                       
$step_result = 'YES';
                       
$step_User->remove_usertags( $del_usertag );
                       
$step_User->dbupdate();
                    }
                   
// Display tag name in log:
                   
$additional_result_message = $del_usertag;
                    break;

                case
'subscribe':
                case
'unsubscribe':
                   
// Subscribe/Unsubscribe User to List:
                   
$NewsletterCache = & get_NewsletterCache();
                    if(
$Newsletter = & $NewsletterCache->get_by_ID( $this->get( 'info' ), false, false ) )
                    {    
// If List/Newsletter exists:
                       
if( $this->get( 'type' ) == 'subscribe' )
                        {    
// Subscribe:
                           
$affected_subscriprions_num = $step_User->subscribe( $Newsletter->ID );

                           
// Send notification to owners of lists where user was subscribed:
                           
$step_User->send_list_owner_notifications( 'subscribe' );
                        }
                        else
                        {    
// Unsubscribe:
                           
$affected_subscriprions_num = $step_User->unsubscribe( $Newsletter->ID );

                           
// Send notification to owners of lists where user was unsubscribed:
                           
$step_User->send_list_owner_notifications( 'unsubscribe' );
                        }
                       
$step_result = ( $affected_subscriprions_num ? 'YES' : 'NO' );
                       
// Display newsletter name in log:
                       
$additional_result_message = $Newsletter->get( 'name' );
                    }
                    else
                    {    
// If List/Newsletter does not exist:
                       
$step_result = 'ERROR';
                       
$additional_result_message = 'List #'.$this->get( 'info' ).' is not found in DB.';
                    }
                    break;

                case
'start_automation':
                   
// Start new Automation:
                   
$AutomationCache = & get_AutomationCache();
                    if(
$new_Automation = & $AutomationCache->get_by_ID( $this->get( 'info' ), false, false ) )
                    {    
// If Automation exists:
                       
$added_users_num = $new_Automation->add_users( array( $step_User->ID ), array(
                               
'users_no_subs'   => 'add',    // Add anyway users who are not subscribed to Newsletter of the Automation
                               
'users_automated' => 'ignore', // Ignore users who are already in the Automation
                               
'users_new'       => 'add',    // Add new users
                           
) );
                       
$step_result = ( $added_users_num ? 'YES' : 'NO' );
                       
// Display newsletter name in log:
                       
$additional_result_message = $new_Automation->get( 'name' );
                    }
                    else
                    {    
// If List/Newsletter does not exist:
                       
$step_result = 'ERROR';
                       
$additional_result_message = 'Automation #'.$this->get( 'info' ).' is not found in DB.';
                    }
                    break;

                case
'user_status':
                   
// Change user account status:
                   
$current_status = $step_User->get( 'status' );
                   
$new_status = $this->get( 'info' );
                    if(
$step_User->ID == 1 )
                    {    
// Don't allow to change status of the Admin user:
                       
$step_result = 'ERROR';
                       
$additional_result_message = 'Status of admin user account cannot be changed';
                    }
                    elseif(
$current_status == $new_status )
                    {    
// If step User's account is already in the desired status:
                       
$step_result = 'NO';
                       
// Display status title in log:
                       
$user_statuses = get_user_statuses();
                       
$additional_result_message = ( isset( $user_statuses[ $new_status ] ) ? $user_statuses[ $new_status ] : $new_status );
                    }
                    elseif(
$current_status == 'closed' )
                    {    
// Don't allow to change a closed status:
                       
$step_result = 'ERROR';
                       
$additional_result_message = 'The closed user account cannot be changed to any other status';
                    }
                    else
                    {    
// Change user account to another status:
                       
$step_User->set( 'status', $new_status );
                        if(
$step_User->dbupdate() )
                        {    
// Successful user updating:
                           
$step_result = 'YES';
                           
// Display status title in log:
                           
$user_statuses = get_user_statuses();
                           
$additional_result_message = ( isset( $user_statuses[ $new_status ] ) ? $user_statuses[ $new_status ] : $new_status );
                        }
                        else
                        {    
// Unknown error on user updating:
                           
$step_result = 'ERROR';
                        }
                    }
                    break;

                default:
                   
// Log:
                   
$process_log .= $log_point.'No implemented action'.$log_nl;
                    break;
            }
        }
        else
        {    
// Wrong user:
           
$additional_result_message = $log_bold_start.'User #'.$user_ID.$log_bold_end.' is not found in DB.';
        }

       
// Log:
       
if( $step_result == 'ERROR' && empty( $additional_result_message ) )
        {    
// Set default additional error message:
           
$additional_result_message = 'Unknown error';
        }
       
$process_log .= $log_point.'Result: '.$this->get_result_title( $step_result, $additional_result_message ).'.'.$log_nl;

       
// Get data for next step:
       
switch( $step_result )
        {
            case
'YES':
               
$next_AutomationStep = & $this->get_yes_next_AutomationStep();
               
$next_delay = $this->get( 'yes_next_step_delay' );
                break;

            case
'NO':
               
$next_AutomationStep = & $this->get_no_next_AutomationStep();
               
$next_delay = $this->get( 'no_next_step_delay' );
                break;

            case
'ERROR':
               
$next_AutomationStep = & $this->get_error_next_AutomationStep();
               
$next_delay = $this->get( 'error_next_step_delay' );
                break;
        }

        if(
$next_AutomationStep )
        {    
// Use data for next step if it is defined:
           
$next_step_ID = $next_AutomationStep->ID;
            if(
$next_delay == 0 && in_array( $next_AutomationStep->ID, $executed_automation_steps[ $user_ID ] ) )
            {    
// Force a delay of infinite loop to 4 hour:
               
$next_exec_ts = date2mysql( $servertimenow + ( 3600 * 4 ) );
            }
            else
            {    
// Use normal delay of next step:
               
$next_exec_ts = date2mysql( $servertimenow + $next_delay );
            }
        }
        else
        {    
// This was the end Step of the Automation:
           
$next_step_ID = NULL;
           
$next_exec_ts = NULL;
        }
       
// Update data for next step or finish it:
       
$DB->query( 'UPDATE T_automation__user_state
              SET aust_next_step_ID = '
.$DB->quote( $next_step_ID ).',
                  aust_next_exec_ts = '
.$DB->quote( $next_exec_ts ).'
            WHERE aust_autm_ID = '
.$DB->quote( $Automation->ID ).'
              AND aust_user_ID = '
.$DB->quote( $user_ID ),
           
'Update data for next Step after executing Step #'.$this->ID );

       
// Log:
       
$process_log .= ( $next_AutomationStep
               
? $log_point.'Next step: #'.$next_AutomationStep->get( 'order' )
                    .
'('.step_get_type_title( $next_AutomationStep->get( 'type' ) ).( $next_AutomationStep->get( 'label' ) == '' ? '' : ' "'.$next_AutomationStep->get( 'label' ).'"' ).')'
                   
.' delay: '.seconds_to_period( $next_delay ).', '.$next_exec_ts
               
: $log_point.'There is no next step configured.' );

        if(
$next_delay == 0 && $next_AutomationStep )
        {    
// If delay for next step is 0 seconds then we must execute such step right now:
           
if( in_array( $next_AutomationStep->ID, $executed_automation_steps[ $user_ID ] ) )
            {    
// Don't run this next step because it was already executed for the user:
               
$process_log .= $log_point.$log_bold_start.'Next step rescheduled with a 4 hour delay to avoid infinite loop!'.$log_bold_end.$log_nl;
            }
            else
            {    
// Run next step because it is not executed yet for the user:
               
$executed_automation_steps[ $user_ID ][] = $this->ID;
               
$process_log .= $log_nl.$log_point.$log_bold_start.'Run next step immediately:'.$log_nl.$log_bold_end;
               
$process_log .= $next_AutomationStep->execute_action( $user_ID );
            }
        }

        return
$process_log;
    }


   
/**
     * Get name of automation step, it is used for `<select>` with $AutomationStepCache
     *
     * @return string
     */
   
function get_name()
    {
       
$step_label = utf8_substr( utf8_trim( $this->get( 'label' ) ), 0, 100 );
        return
'#'.$this->get( 'order' ).' - '
           
.( step_get_type_title( $this->get( 'type' ) ).': '.$step_label );
    }


   
/**
     * Get result title depending on step type
     *
     * @param string Result: YES, NO, ERROR
     * @param string Additional message, for example: some error message
     * @return string Result title
     */
   
function get_result_title( $result, $additional_message = '' )
    {
       
$result_titles = step_get_result_titles();

       
$result_title = isset( $result_titles[ $this->get( 'type' ) ][ $result ] ) ? $result_titles[ $this->get( 'type' ) ][ $result ] : $result;

        if(
strpos( $result_title, '%s' ) !== false )
        {    
// Replace mask with additional message like error:
           
$result_title = sprintf( $result_title, '"'.$additional_message.'"' );
        }

        return
$result_title;
    }


   
/**
     * Check result of "IF Condition"
     *
     * @param object|NULL User, NULL to get only log as scheme of current condition without checking
     * @param string Log process into this param
     * @return boolean TRUE if condition is matched for given user, otherwise FALSE
     */
   
function check_if_condition( $step_User, & $process_log )
    {
        if(
$this->get( 'type' ) != 'if_condition' )
        {    
// This is allowed only for step type "IF Condition":
           
return false;
        }

       
$json_object = json_decode( $this->get( 'info' ) );

        if(
$json_object === NULL || ! isset( $json_object->valid ) || $json_object->valid !== true )
        {    
// Wrong object, Return false:
           
return false;
        }

        return
$this->check_if_condition_object( $json_object, $step_User, $process_log );
    }


   
/**
     * Check result of "IF Condition" object(one group of rules)
     * Used recursively to find all sub grouped conditions
     *
     * @param object JSON object of step type "IF Condition"
     * @param object|NULL User, NULL to get only log as scheme of current condition without checking
     * @param string Log process into this param
     * @return boolean TRUE if condition is matched for given user, otherwise FALSE
     */
   
function check_if_condition_object( $json_object, $step_User, & $process_log )
    {
        if( ! isset(
$json_object->condition ) || ! in_array( $json_object->condition, array( 'AND', 'OR' ) ) || empty( $json_object->rules ) )
        {    
// Wrong json object params, Skip it:
           
return false;
        }

       
// If user is not given we cannot do a checking,
        // Used to autogenerate step label:
       
$check_result = ( $step_User !== NULL );

       
// Log:
       
$process_log .= ' ('.( $check_result ? $json_object->condition : ' ' );
       
// Array to convert operator names to log format:
       
$log_operators = array(
               
'equal'            => '=',
               
'not_equal'        => '&#8800;',
               
'less'             => '<',
               
'less_or_equal'    => '&#8804;',
               
'greater'          => '>',
               
'greater_or_equal' => '&#8805;',
               
'between'          => array( '&#8805;', 'AND &#8804;' ),
               
'not_between'      => array( '<', 'OR >' ),
            );
       
$log_fields = array(
               
'user_tag'    => 'User tag',
               
'user_status' => 'User Account status',
               
'date'        => 'Current date',
               
'time'        => 'Current time',
               
'day'         => 'Current day of the week',
               
'month'       => 'Current month',
               
'days_before_birthday'          => 'Days before birthday',
               
'listsend_last_sent_to_user'    => 'Last sent list to user',
               
'listsend_last_opened_by_user'  => 'Last opened list by user',
               
'listsend_last_clicked_by_user' => 'Last clicked list by user',
            );
       
$log_values = array(
               
'day' => array(
                   
1 => 'Monday',
                   
2 => 'Tuesday',
                   
3 => 'Wednesday',
                   
4 => 'Thursday',
                   
5 => 'Friday',
                   
6 => 'Saturday',
                   
7 => 'Sunday'
               
),
               
'month' => array(
                   
1 => 'January',
                   
2 => 'February',
                   
3 => 'March',
                   
4 => 'April',
                   
5 => 'May',
                   
6 => 'June',
                   
7 => 'July',
                   
8 => 'August',
                   
9 => 'September',
                   
10 => 'October',
                   
11 => 'November',
                   
12 => 'December'
               
),
               
'user_status' => get_user_statuses(),
            );
       
$log_bold_start = '<b>';
       
$log_bold_end = '</b>';
       
$log_rule_separator = ', ';

        if(
$json_object->condition == 'AND' )
        {    
// Default result for group with operator 'AND':
           
$conditions_result = true;
           
$stop_result = false;
        }
        else
        {    
// Default result for group with operator 'OR':
           
$conditions_result = false;
           
$stop_result = true;
        }

        foreach(
$json_object->rules as $r => $rule )
        {
            if( !
$check_result )
            {
               
$log_rule_separator = $r > 0 ? ' '.$json_object->condition.' ' : '';
            }

            if(
$check_result && $conditions_result == $stop_result )
            {    
// Skip this rule because previous rules already returned the end result for current condition(AND|OR):
               
$process_log .= $log_rule_separator.$log_bold_start.'ignored'.$log_bold_end;
                continue;
            }

            if( isset(
$rule->rules ) && is_array( $rule->rules ) )
            {    
// This is a group of conditions, Run this function recursively:
               
$process_log .= $log_rule_separator;
               
$rule_result = $this->check_if_condition_object( $rule, $step_User, $process_log );
            }
            else
            {    
// This is a single field:
               
if( $check_result )
                {
                   
$rule_result = $this->check_if_condition_rule( $rule, $step_User, $process_log );
                }
               
// Log:
               
$process_log .= $log_rule_separator.( isset( $log_fields[ $rule->field ] ) ? $log_fields[ $rule->field ] : $rule->field );
                if(
in_array( $rule->field, array( 'listsend_last_sent_to_user', 'listsend_last_opened_by_user', 'listsend_last_clicked_by_user' ) ) )
                {    
// Special value for list send fields:
                   
$value = explode( ':', $rule->value );
                   
$period = ( isset( $value[0] ) ? intval( $value[0] ) : '0' )
                        .( isset(
$value[1] ) ? ' '.$value[1].'s' : '' ).' ago';
                   
$rule_newsletter_ID = isset( $value[2] ) ? intval( $value[2] ) : 0;
                   
$newsletter = ' for ';
                    if(
$rule_newsletter_ID > 0 )
                    {    
// Specific newsletter is selected:
                       
$NewsletterCache = & get_NewsletterCache();
                        if(
$rule_Newsletter = & $NewsletterCache->get_by_ID( $rule_newsletter_ID, false, false ) )
                        {    
// Display a name of the selected newsletter:
                           
$newsletter .= 'List: '.$rule_Newsletter->get( 'name' ).'';
                        }
                        else
                        {    
// If newsletter was deleted from DB:
                           
$newsletter .= 'List: Error: NOT FOUND IN DB!';
                        }
                    }
                    elseif(
$rule_newsletter_ID == -1 )
                    {    
// Any newsletter should be used for this condition rule:
                       
$newsletter .= 'any list';
                    }
                    else
                    {    
// Any tied newsletter should be used for this condition rule:
                       
$newsletter .= 'any list tied to step automation';
                    }
                   
$process_log .= ' '.$log_operators[ $rule->operator ].' "'.$period.$newsletter.'"';
                }
                elseif(
is_array( $log_operators[ $rule->operator ] ) )
                {    
// Multiple operator and values:
                   
foreach( $log_operators[ $rule->operator ] as $o => $operator )
                    {
                       
$process_log .= ' '.$operator.' "'.( isset( $log_values[ $rule->field ][ $rule->value[ $o ] ] ) ? $log_values[ $rule->field ][ $rule->value[ $o ] ] : $rule->value[ $o ] ).'"';
                    }
                }
                else
                {    
// Single operator and value:
                   
$process_log .= ' '.$log_operators[ $rule->operator ].' "'.( isset( $log_values[ $rule->field ][ $rule->value ] ) ? $log_values[ $rule->field ][ $rule->value ] : $rule->value ).'"';
                }
                if(
$check_result )
                {
                   
$process_log .= ': '.$log_bold_start.( $rule_result ? 'TRUE' : 'FALSE' ).$log_bold_end;
                }
            }

           
// Append current result with previous results:
           
if( $json_object->condition == 'AND' )
            {    
// AND condition:
               
$conditions_result = $check_result ? ( $conditions_result && $rule_result ) : true;
            }
            else
            {    
// OR condition:
               
$conditions_result = $check_result ? ( $conditions_result || $rule_result ) : false;
            }
        }

       
// Log:
       
$process_log .= ( $check_result ? '' : ' ' ).')';
        if(
$check_result )
        {
           
$process_log .= ' : '.$log_bold_start.( $conditions_result ? 'TRUE' : 'FALSE' ).$log_bold_end;
        }

        return
$conditions_result;
    }


   
/**
     * Check rule of "IF Condition" for given User
     *
     * @param object Rule, object with properties: field, value, operator
     * @param object User
     * @return boolean TRUE if condition is matched for given user, otherwise FALSE
     */
   
function check_if_condition_rule( $rule, $step_User )
    {
        switch(
$rule->field )
        {
            case
'user_tag':
               
// Check if User has a tag:
               
$user_tags = $step_User->get_usertags();
                switch(
$rule->operator )
                {
                    case
'equal':
                        return
in_array( $rule->value, $user_tags );
                    case
'not_equal':
                        return !
in_array( $rule->value, $user_tags );
                }
                break;

            case
'user_status':
               
// Check User status:
               
switch( $rule->operator )
                {
                    case
'equal':
                        return
$step_User->get( 'status' ) == $rule->value;
                    case
'not_equal':
                        return
$step_User->get( 'status' ) != $rule->value;
                }
                break;

            case
'date':
               
// Check current date:
               
return $this->check_if_condition_rule_date_value( $rule, 'Y-m-d' );

            case
'time':
               
// Check current time:
               
return $this->check_if_condition_rule_date_value( $rule, 'H:i' );

            case
'day':
               
// Check current day of week:
               
return $this->check_if_condition_rule_date_value( $rule, 'w' );

            case
'month':
               
// Check current month:
               
return $this->check_if_condition_rule_date_value( $rule, 'm' );

            case
'days_before_birthday':
               
// Check number of days before birthday:
               
global $localtimenow;

               
$localdatenow   = strtotime( date( 'Y-m-d', $localtimenow ) );
               
$birthday_month = $step_User->get( 'birthday_month' );
               
$birthday_day   = $step_User->get( 'birthday_day' );

                if(
$birthday_month && $birthday_day )
                {
                   
$birthday = strtotime( date( 'Y', $localtimenow ).'-'.$birthday_month.'-'.$birthday_day );
                    if(
$birthday < $localdatenow )
                    {    
// Birthday for current year has already passed, use birthday next year:
                       
$birthday = strtotime( ( (int) date( 'Y', $localtimenow ) + 1 ).'-'.$birthday_month.'-'.$birthday_day );
                    }
                   
$datediff = $birthday - $localdatenow;
                   
$days     = (int) round( $datediff / ( 60 * 60 * 24 ) );

                    switch(
$rule->operator )
                    {
                        case
'equal':
                            return
$days == $rule->value;
                        case
'not_equal':
                            return
$days != $rule->value;
                        case
'less':
                            return
$days < $rule->value;
                        case
'less_or_equal':
                            return
$days <= $rule->value;
                        case
'greater':
                            return
$days > $rule->value;
                        case
'greater_or_equal':
                            return
$days >= $rule->value;
                        case
'between':
                            return
$days >= $rule->value[0] && $days <= $rule->value[1];
                        case
'not_between':
                            return
$days < $rule->value[0] || $days > $rule->value[1];
                    }
                }
               
                return
false;

            case
'listsend_last_sent_to_user':
               
// Check last sent list to user:
               
return $this->check_if_condition_rule_listsend_value( $rule, $step_User->ID, 'enls_last_sent_manual_ts' ) ||
                             
$this->check_if_condition_rule_listsend_value( $rule, $step_User->ID, 'enls_last_sent_auto_ts' );

            case
'listsend_last_opened_by_user':
               
// Check last opened list by user:
               
return $this->check_if_condition_rule_listsend_value( $rule, $step_User->ID, 'enls_last_open_ts' );

            case
'listsend_last_clicked_by_user':
               
// Check last clicked list by user:
               
return $this->check_if_condition_rule_listsend_value( $rule, $step_User->ID, 'enls_last_click_ts' );
        }

       
// Unknown field or operator:
       
return false;
    }


   
/**
     * Check rule of "IF Condition" for date value
     *
     * @param object Rule, object with properties: field, value, operator
     * @param string Date format like Y-m-d, H:i, w, m
     * @return boolean TRUE if condition is matched for current date, otherwise FALSE
     */
   
function check_if_condition_rule_date_value( $rule, $date_format )
    {
        global
$localtimenow;

       
$date_value = date( $date_format, $localtimenow );
        if(
$date_format == 'w' && $date_value === '0' )
        {    
// Use 7 for Sunday:
           
$date_value = '7';
        }

        switch(
$rule->operator )
        {
            case
'equal':
                return
$date_value == $rule->value;
            case
'not_equal':
                return
$date_value != $rule->value;
            case
'less':
                return
$date_value < $rule->value;
            case
'less_or_equal':
                return
$date_value <= $rule->value;
            case
'greater':
                return
$date_value > $rule->value;
            case
'greater_or_equal':
                return
$date_value >= $rule->value;
            case
'between':
                return
$date_value >= $rule->value[0] && $date_value <= $rule->value[1];
            case
'not_between':
                return
$date_value < $rule->value[0] || $date_value > $rule->value[1];
        }

        return
false;
    }


   
/**
     * Check rule of "IF Condition" for list send value
     *
     * @param object Rule, object with properties: field, value, operator
     * @param integer Step User ID
     * @param string DB field name for checking: 'enls_last_sent_manual_ts', 'enls_last_open_ts', 'enls_last_click_ts'
     * @return boolean TRUE if condition is matched for current date, otherwise FALSE
     */
   
function check_if_condition_rule_listsend_value( $rule, $step_user_ID, $check_db_field_name )
    {
       
$value = explode( ':', $rule->value );
       
$period_value = ( isset( $value[0] ) ? intval( $value[0] ) : 0 );

        if(
$period_value > 0 )
        {    
// Check this condition only if period > 0 seconds:
           
global $DB, $servertimenow;

           
// Calculate a time ago depending on period:
           
$periods = array(
               
'second' => 1,        // 1 second
               
'minute' => 60,       // 60 seconds
               
'hour'   => 3600,     // 60 minutes
               
'day'    => 86400,    // 24 hours
               
'month'  => 2592000,  // 30 days
               
'year'   => 31536000, // 365 days
           
);
           
$period_name = ( isset( $value[1] ) ? $value[1] : false );
            if(
$period_name && isset( $periods[ $period_name ] ) )
            {
               
$period_value *= $periods[ $period_name ];
            }
           
$rule_value_time = $servertimenow - $period_value;

           
$rule_newsletter_ID = ( isset( $value[2] ) ? intval( $value[2] ) : 0 );
            if(
$rule_newsletter_ID > 0 )
            {    
// Check for a selected list:
               
$NewsletterCache = & get_NewsletterCache();
                if(
$rule_Newsletter = & $NewsletterCache->get_by_ID( $rule_newsletter_ID, false, false ) )
                {    
// Check only for a selected list:
                   
$rule_newsletters = $rule_Newsletter->ID;
                }
                else
                {    
// If a selected list has been removed from DB:
                   
$rule_newsletters = -1;
                }
            }
            elseif(
$rule_newsletter_ID == -1 )
            {    
// Check for ALL lists:
               
$rule_newsletters = false;
            }
            else
            {    
// Check any list tied to step automation:
               
$step_Automation = & $this->get_Automation();
               
$rule_newsletters = $step_Automation->get_newsletter_IDs();
            }

           
$SQL = new SQL( 'Get last time for IF Condition "Last sent/opened/clicked list" ('.$check_db_field_name.')' );
           
$SQL->SELECT( $check_db_field_name );
           
$SQL->FROM( 'T_email__newsletter_subscription' );
           
$SQL->WHERE( 'enls_user_ID = '.$DB->quote( $step_user_ID ) );
            if(
$rule_newsletters !== false )
            {    
// Check only for the selected rule lists:
               
$SQL->WHERE_and( 'enls_enlt_ID IN ( '.$DB->quote( $rule_newsletters ).' )' );
            }
           
$SQL->ORDER_BY( $check_db_field_name );
           
$SQL->LIMIT( 1 );
           
$last_time = strtotime( $DB->get_var( $SQL ) );

            switch(
$rule->operator )
            {
                case
'less':
                    return
$rule_value_time < $last_time;
                case
'less_or_equal':
                    return
$rule_value_time <= $last_time;
                case
'greater':
                    return
$rule_value_time > $last_time;
                case
'greater_or_equal':
                    return
$rule_value_time >= $last_time;
            }
        }
        else
        {    
// No reason to check if period is 0 seconds:
           
return true;
        }
    }


   
/**
     * Set label generated automatically
     *
     * @param string Label
     */
   
function set_label()
    {
       
$label = '';

        switch(
$this->get( 'type' ) )
        {
            case
'if_condition':
               
// Get log of conditions without results:
               
$this->check_if_condition( NULL, $label );
                break;

            case
'send_campaign':
               
$EmailCampaignCache = & get_EmailCampaignCache();
                if(
$EmailCampaign = & $EmailCampaignCache->get_by_ID( $this->get( 'info' ), false, false ) )
                {    
// Use name of Email Campaign:
                   
$label = $EmailCampaign->get( 'name' );
                }
                break;

            case
'notify_owner':
                if( (
$step_Automation = & $this->get_Automation() ) &&
                    (
$automation_owner_User = & $step_Automation->get_owner_User() ) )
                {    
// User login of owner:
                   
$label = $automation_owner_User->get( 'login' );
                }
                break;

            case
'subscribe':
            case
'unsubscribe':
               
$NewsletterCache = & get_NewsletterCache();
                if(
$Newsletter = & $NewsletterCache->get_by_ID( $this->get( 'info' ), false, false ) )
                {    
// Use name of Newsletter/List:
                   
$label = $Newsletter->get( 'name' );
                }
                break;

            case
'start_automation':
               
$AutomationCache = & get_AutomationCache();
                if(
$Automation = & $AutomationCache->get_by_ID( $this->get( 'info' ), false, false ) )
                {    
// Use name of Automation:
                   
$label = $Automation->get( 'name' );
                }
                break;

            case
'user_status':
               
$user_statuses = get_user_statuses();
                if( isset(
$user_statuses[ $this->get( 'info' ) ] ) )
                {    
// Get status title from status key:
                   
$label = $user_statuses[ $this->get( 'info' ) ];
                }
                break;

            case
'add_usertag':
            case
'remove_usertag':
            default:
               
$label = $this->get( 'info' );
                break;
        }

       
$this->set( 'label', utf8_substr( utf8_trim( $label ), 0, 500 ) );
    }


   
/**
     * Check if this automation step can be modified(added/edited/deleted) currently
     *
     * @param boolean
     */
   
function can_be_modified()
    {
        if( (
$step_Automation = & $this->get_Automation() ) &&
           
$step_Automation->get( 'status' ) == 'paused' )
        {    
// Automation of this step must be paused in order to edit steps:
           
return true;
        }

        return
false;
    }


   
/**
     * Pause automation by confirmation from request
     *
     * @return boolean
     */
   
function pause_automation()
    {
        if(
$this->can_be_modified() )
        {    
// If step automation is already paused
           
return true;
        }

        if( !
param( 'confirm_pause', 'integer' ) )
        {    
// If action is not confirmed
           
return false;
        }

       
// Try to pause the step's automation:
       
$step_Automation = & $this->get_Automation();
       
$step_Automation->set( 'status', 'paused' );

        if(
$step_Automation->dbupdate() )
        {    
// Display a message if automation has been paused:
           
global $Messages;
           
$Messages->add( TB_('Automation has been paused.'), 'success' );
            return
true;
        }
        else
        {    
// If automation could not paused
           
return false;
        }
    }
}

?>