<?php
/**
 * ExecuteService File
 *
 * @category Admin
 * @package  ClientExec
 * @author   Alberto Vasquez <alberto@clientexec.com>
 * @license  ClientExec License
 * @version  [someversion]
 * @link     http://www.clientexec.com
 */

require_once 'newedge/classes/NE_PluginCollection.php';

/**
 * ExecuteService Action Class
 *
 * @category Admin
 * @package  ClientExec
 * @author   Alberto Vasquez <alberto@clientexec.com>
 * @license  ClientExec License
 * @version  [someversion]
 * @link     http://www.clientexec.com
 */
class ExecuteService extends NE_Action
{
    var $permission     = '';

    // user authentication and permission validation done inside dispatch()

    /**
     * Action's dispatch method
     *
     * @return redirect
     */
    function dispatch()
    {
        if (defined('RUNNING_SERVICE_SCRIPT')) {
            // *************************
            // Running from outside CE
            // *************************
            if (isset($_GET['service']) && $this->settings->get('Allow run services from URL')) {
                $runService = $_GET['service'];
                $manuallyExecuted = 2;
                $this->logger->log(3, "** OUTSIDE SERVICE REQUEST **: services.php called for service '$runService'");
            } elseif ($runService = @$_SERVER['argv'][1]) {
                $this->logger->log(3, "** CRON REQUEST **: services.php called for service '$runService'");
                $manuallyExecuted = 0;
            } else {
                die('Service not defined or services not set up to run from the URL.');
            }

            if ($this->settings->get("plugin_{$runService}_Enabled") != 1) {
                die("Service $runService is not Enabled.");
            }
        } else {
            // ************************
            // Running from inside CE
            // ************************
            if (!isset($_SESSION['userId'])) {
                NE_Lib::redirectPage('index.php?fuse=admin&amp;view=Login');
            }
            if (!$this->user->hasPermission('admin_manage_plugins')) {
                trigger_error("You don't have enough permissions to trigger this action", E_USER_ERROR);
                exit;
            }

            if (!isset($_GET['service'])) {
                die('Service not defined.');
            }
            $manuallyExecuted = 1;
            $runService = $_GET['service'];
        }
		// service execution can take a while
		@set_time_limit(0);
		
		// Grab an array of plugin information
		$info = @unserialize($this->settings->get('services_meta_info'));
    
		// ServicePlugin required for service status defines.
        require_once 'modules/admin/models/ServicePlugin.php';
		include_once ("modules/admin/models/PluginGateway.php");
		$gateway = new PluginGateway($this->user);
		$plugin = $gateway->getServicePluginByName($runService);

		// Ensure we have data for the plugin before trying to use it.
		if ( is_array($info) && array_key_exists($plugin->getInternalName(), $info) ) {
            $tmpInfo = $info[$plugin->getInternalName()];
            $oldInfo = $tmpInfo;
        } else {
            $oldInfo = "";
        }
        $time = array();
		if(isset($tmpInfo['time'])){
			$time = NE_Lib::date_diff_hrs($tmpInfo['time'], date('Y-m-d H:i:s'));
		}

		// AVOID CALLING THE SERVICE TWICE IF IT IS ALREADY RUNNING AND IT HAS BEEN RUNNING FOR LESS THAN 30 MINUTES
		if(isset($tmpInfo['status'])
		  && $tmpInfo['status'] == SERVICE_STATUS_IN_PROCESS
		  && isset($tmpInfo['time'])
		  && $time['h'] == 0
		  && $time['m'] < 30){
			$this->logger->log(3, "Service '$runService' is already running. Service request ignored.");
			return;
		}

		// Update to be in status.
		$tmpInfo['time'] = date('Y-m-d H:i:s');
		$tmpInfo['manually_executed'] = $manuallyExecuted;
		$tmpInfo['results'] = '';
		$tmpInfo['errors'] = '';
		$tmpInfo['status'] = SERVICE_STATUS_IN_PROCESS;
		$tmpInfo['extra_info'] = @$info[$plugin->getInternalName()]['extra_info'];
		$info[$plugin->getInternalName()] = $tmpInfo;
		$this->settings->updateValue('services_meta_info', serialize($info));

		$messages = $plugin->execute($oldInfo);
		$errors = '';
		$results = '';
		if (is_array($messages)) {
			foreach ($messages as $message) {
				if (is_a($message, 'NE_Error')) {
					$errors .= $message->getMessage()."\n";
				} else {
					$results .= "$message\n";
				}
			}
		}
		
		// Grab an array of plugin information, since it could have been changed in the plugin
		$info = @unserialize($this->settings->get('services_meta_info'));
		
		// Update to be finished
		$tmpInfo['time'] = date('Y-m-d H:i:s');
		$tmpInfo['manually_executed'] = $manuallyExecuted;

		$tmpInfo['results'] = $results;
		$tmpInfo['errors'] = $errors;
		$tmpInfo['status'] = SERVICE_STATUS_FINISHED;
		$tmpInfo['extra_info'] = @$info[$plugin->getInternalName()]['extra_info'];
		$info[$plugin->getInternalName()] = $tmpInfo;
		$this->settings->updateValue('services_meta_info', serialize($info));

		if (defined('RUNNING_SERVICE_SCRIPT') && $errors) {
			echo "Errors calling plugin ".$plugin->getInternalName().":\n$errors\n";
			if ($recipients = $this->settings->get('Application Error Notification')) {
				include_once 'newedge/classes/NE_MailGateway.php';
				$mailGateway = new NE_MailGateway();
				$body = "ClientExec automated error notification\n\nThe service plugin ".$this->settings->get("plugin_".$plugin->getInternalName()."_Plugin Name")
						." generated the following error(s):\n$errors\n";

				$recipients = explode("\r\n", $recipients);
				foreach ($recipients as $recipient) {
					// bypass mail queue, because it could be it the one failing, creating thus an infinite loop
					$mailSend = $mailGateway->mailMessageEmail(
						array('HTML' => null, 'plainText' => $body),
						$this->settings->get('Support E-mail'),
						$this->settings->get('Support E-mail'),
						$recipient,
						'',
						'ClientExec Service Plugin Error Notification',
						1
					);
					if (is_a($mailSend, 'NE_Error')) {
						echo $mailSend->getMessage();
					}
				}
			}
		}

		if (!defined('RUNNING_SERVICE_SCRIPT') && $errors) {
			NE_Lib::addMessage(nl2br($errors));
			NE_Lib::addMessage(nl2br($results));
		}

		if (!defined('RUNNING_SERVICE_SCRIPT') && !$errors) {
			NE_Lib::addMessage($this->lang('Service executed successfully'));
			NE_Lib::addMessage(nl2br($results));
		}
		
        if (!defined('RUNNING_SERVICE_SCRIPT')) {
            NE_Lib::redirectPage("index.php?setting=".$_REQUEST['service']."&amp;fuse=admin&amp;view=Services");
        }

    }


}
?>