It belongs to the Workflow Designer and must not be distributed without complete extension **/ require_once('include/utils/utils.php'); require_once(realpath(dirname(__FILE__).'/autoload_wf.php')); use Workflow\VTEntity; use Workflow\Main; use Workflow\Queue; use Workflow\EntityDelta; class WfEventHandler extends VTEventHandler { /** * @param $handlerType * @param $entityData VTEntityData */ public function handleEvent($handlerType, $entityData) { if(!empty($_COOKIE['IGNORE_WFD'])) return; ob_start(); /*var_dump($_REQUEST,$handlerType, $entityData); exit();*/ if($handlerType == 'vtiger.entity.aftersave.final') { $this->cleanModTracker($entityData); return; } if(isset($_REQUEST['tableblocks'])) { $tableBlocks = $_REQUEST['tableblocks']; unset($_REQUEST['tableblocks']); } $wfManager = new \Workflow\Manager(); EntityDelta::increaseStack(); EntityDelta::refreshDelta($entityData->getModuleName(), $entityData->focus->id); $adb = \PearDatabase::getInstance(); Workflow2::$isAjax = true; if(empty($_SERVER['HTTP_X_REQUESTED_WITH']) || strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) != 'xmlhttprequest') { Workflow2::$isAjax = false; } Workflow2::log($entityData->focus->id, 0, 0, "Start EventHandler"); $restoreEventLogger = false; if(\Workflow\ExecutionLogger::isInitialized()) { $restoreEventLogger = \Workflow\ExecutionLogger::getCurrentInstance(); } if($entityData->getModuleName() == "Documents" && $_REQUEST['action'] == 'SaveAjax' && !empty($_REQUEST['sourceRecord']) && !empty($_REQUEST['sourceModule'])) { $workflows = $wfManager->GetWorkflows($_REQUEST['sourceModule'], Workflow\Main::ADD_DOCUMENT); $parentId = intval($_REQUEST['sourceRecord']); if(count($workflows) > 0) { $context = VTEntity::getForId($parentId); $data = $entityData->getData(); $data['crmid'] = $data['id'] = $entityData->getId(); $context->setEnvironment("document", $data); foreach($workflows as $wf) { if(!$wf->checkExecuteCondition($context)) { continue; } $wf->setExecutionTrigger(Workflow\Main::ADD_DOCUMENT); /** * @var $wf WfMain */ if(!$context->isAvailable()) { break; } #$context->setEnvironment(); $wf->setContext($context); if($wf->checkCondition($entityData)) { $wf->start(); } } } } // Start Workflows with SENDMAIL start condition if($entityData->getModuleName() == "Emails") { $parent_ids = explode("|", $entityData->get("parent_id")); if(!empty($_REQUEST["pmodule"]) && !empty($_REQUEST["sorce_ids"])) { $parent_ids[] = $_REQUEST["sorce_ids"]; } $from_email = $entityData->get("from_email"); $to_email = $entityData->get("saved_toid"); // wenn Versand, dann from_email leer $ToEmailParts = explode(',', $to_email); foreach($parent_ids as $index => $parentId) { $splitted = explode('@', $parentId); $sql = 'SELECT email1, email2, secondaryemail FROM vtiger_users WHERE id = ?'; $result = $adb->pquery($sql, array(intval($splitted[0]))); if($adb->num_rows($result) > 0) { $emails = $adb->fetchByAssoc($result); if(!empty($emails['email1']) && in_array($emails['email1'], $ToEmailParts) !== false) { $parent_ids[$index] = ''; } if(!empty($emails['email2']) && in_array($emails['email2'], $ToEmailParts) !== false) { $parent_ids[$index] = ''; } if(!empty($emails['secondaryemail']) && in_array($emails['secondaryemail'], $ToEmailParts) !== false) { $parent_ids[$index] = ''; } } } if(empty($from_email)) { #echo "
";var_dump($entityData);
                #var_dump($_REQUEST);
                if(!empty($_REQUEST["from_email"])) {
                    // From EmailMAKER Save.php ab Line 120
                    list($type,$email_val) = explode("::",addslashes($_REQUEST["from_email"]),2);

                    if ($email_val != "")
                    {
                        if($type == "a")
                        {
                            $sql_a="select * from vtiger_systems where from_email_field != ? AND server_type = ?";
                            $result_a = $adb->pquery($sql_a, array('','email'));

                            $from_email = $adb->query_result($result_a,0,"from_email_field");
                        }
                        else
                        {
                            $sql_u = "SELECT first_name, last_name, ".$type." AS email  FROM vtiger_users WHERE id = '".$email_val."'";
                            $result_u = $adb->pquery($sql_u, array());

                            $from_email = $adb->query_result($result_u,0,"email");
                        }
                    }

                } else {
                    global $current_user;
                    $from_email = $current_user->column_fields['email1'];
                }
            }

            $maildata = array("subject" => $entityData->get("subject"), "content" => $entityData->get("description"), "from" => $from_email, "to" => $to_email);

            foreach($parent_ids as $recordid) {
                if(empty($recordid)) {
                    continue;
                }
                $context = VTEntity::getForId($recordid);

                if($context !== false) {
                    $workflows = $wfManager->GetWorkflows($context->getModuleName(), Workflow\Main::SENDMAIL_START);
                    if(count($workflows) > 0) {
                        $context->setEnvironment("email", $maildata);
                        foreach($workflows as $wf) {
                            $wf->setExecutionTrigger("WF2_CREATION");
                            /**
                             * @var $wf WfMain
                             */
                            if(!$context->isAvailable()) {
                                break;
                            }
                            #$context->setEnvironment();

                            $wf->setContext($context);

                            if($wf->checkCondition($entityData)) {
                                $wf->start();
                            }
                        }
                    }
                }
            }
        }

        // Start Workflows with CREATE_MAIL start condition
        if($entityData->getModuleName() == "ModComments") {
            $customerId = $entityData->get('customer');

            $envComment = array(
                'commentcontent' => $entityData->get('commentcontent'),
                'assigned_user_id' => $entityData->get('assigned_user_id'),
                'customer' => $customerId,
                'userid' => $entityData->get('userid'),
                'is_private' => $entityData->get('is_private'),
                'source' => empty($customerId)?'crm':'customerportal',
                'comment' => $entityData->getData()
            );

            $parent_ids = array($entityData->get("related_to"));
            foreach($parent_ids as $recordid) {
                $context = VTEntity::getForId($recordid);
                $context->loadEnvironment(array_merge($context->getEnvironment(), $envComment));

                if($context !== false) {
                    $workflows = $wfManager->GetWorkflows($context->getModuleName(), Workflow\Main::COMMENT_START);
                    foreach($workflows as $wf) {
                        $wf->setExecutionTrigger("WF2_CREATION");
                        /**
                         * @var $wf WfMain
                         */
                        if(!$context->isAvailable()) {
                            break;
                        }
                        $wf->setContext($context);

                        if($wf->checkCondition($entityData)) {
                            $wf->start();
                        }
                    }
                }
            }
        }

        if($handlerType == "vtiger.entity.aftersave") {
            global $current_user;
            $context = VTEntity::getForId($entityData->focus->id, $entityData->getModuleName());
            Queue::updateDynamicDate($context);

            $this->doModTrackerFix($entityData);

            /**
             * get workflows, which should be executed
             */
            $workflows = $wfManager->GetWorkflows($entityData->getModuleName(), array(Workflow\Main::ON_FIRST_SAVE, Workflow\Main::ON_EVERY_SAVE));
            $isNew = $entityData->isNew();

            Workflow2::log($entityData->focus->id, 0, 0, "Found Workflows: ".count($workflows));

            foreach($workflows as $wf) {
                $context->setIsNew($isNew);
                if(!$wf->checkExecuteCondition($context)) {
                    continue;
                }

                $wf->setExecutionTrigger($isNew?"WF2_CREATION":"WF2_EVERY_SAVE");

                Workflow2::log($entityData->focus->id, $wf->getId(), 0, "Found WF");
                if(PHP_SAPI === 'cli') {
                    echo "Start of Workflow ".$wf->getId()."\n";
                }
                $context = VTEntity::getForId($entityData->focus->id, $entityData->getModuleName());

                $context->setIsNew($isNew);

                if(!$context->isAvailable()) {
                    break;
                }

                $wf->setContext($context);

                // Checks, If the Workflow should run on this record
                if($wf->checkCondition($entityData)) {
                    $wf->start();

                    if($wf->getSuccessRedirection() !== false && Workflow2::$isAjax === false) {
                        header("Location:".$wf->getSuccessRedirection());
                        exit();
                    }
                } else {
                    Workflow2::log($entityData->focus->id, $wf->getId(), 0, "Skip WF by Cond.");
                }
            }

            //ob_end_clean();
        }

        if($handlerType == "vtiger.entity.beforedelete") {
            /**
             * get workflows, which should be executed
             */
            $workflows = $wfManager->GetWorkflows($entityData->getModuleName(), array(Workflow\Main::BEFOREDELETE_START));

            foreach($workflows as $wf) {
                if(!$wf->checkExecuteCondition($context)) {
                    continue;
                }

                $wf->setExecutionTrigger(Workflow\Main::BEFOREDELETE_START);

                Workflow2::log($entityData->focus->id, $wf->getId(), 0, "Found WF");
                if(PHP_SAPI === 'cli') {
                    echo "Start of Workflow ".$wf->getId()."\n";
                }
                $context = VTEntity::getForId($entityData->focus->id, $entityData->getModuleName());
                $context->setIsNew(false);

                if(!$context->isAvailable()) {
                    break;
                }

                $wf->setContext($context);

                // Checks, If the Workflow should run on this record
                if($wf->checkCondition($entityData)) {
                    $wf->start();

                    if($wf->getSuccessRedirection() !== false) {
                        Workflow2::error_handler(E_NONBREAK_ERROR, 'Redirections do not work on "before delete" triggered Workflows.');
                    }
                }
            }
            //ob_end_clean();
        }

        if($restoreEventLogger !== false) {
            \Workflow\ExecutionLogger::setCurrentInstance($restoreEventLogger);
        }

        if(isset($tableBlocks)) {
            $_REQUEST['tableblocks'] = $tableBlocks;
        }

        EntityDelta::decreaseStack();
        Workflow2::$enableError = false;
    }

    public static $ModTrackerFixCache = array();
    public function doModTrackerFix(VTEntityData $entityData) {
        if($entityData->isNew()) return;
        if(isset(self::$ModTrackerFixCache[$entityData->getId()])) return;

        require_once(realpath(vglobal('root_directory').DIRECTORY_SEPARATOR.'modules'.DIRECTORY_SEPARATOR.'ModTracker'.DIRECTORY_SEPARATOR.'ModTrackerHandler.php'));

        $obj = new ModTrackerHandler();
        $obj->handleEvent('vtiger.entity.aftersave.final', $entityData);

        self::$ModTrackerFixCache[$entityData->getId()] = true;
    }

    public function cleanModTracker(VTEntityData $context) {
        //    if(!isset(\Workflow\VTEntity::$RecordStored[$context->getId()])) return;
        $crmid = $context->getId();
        if(empty($crmid)) return;

        $adb = \PearDatabase::getInstance();

        $modified = strtotime($context->get('modifiedtime'));
        $sql = 'SELECT GROUP_CONCAT(detail.id) as ids, fieldname, postvalue FROM  `vtiger_modtracker_basic` as basic
LEFT JOIN vtiger_modtracker_detail as detail ON (detail.id = basic.id)
WHERE crmid = '.$context->getId().' AND (`changedon` <=  "'.date('Y-m-d H:i:s', $modified+3).'" AND `changedon` >=  "'.date('Y-m-d H:i:s', $modified - 5).'") AND status = 0
GROUP BY fieldname, postvalue  HAVING COUNT(*) > 1';
        $result = $adb->query($sql);

        $total = $adb->num_rows($result);
        $counter = 0;
        while($row = $adb->raw_query_result_rowdata($result, $counter++)) {
            $ids = explode(',', $row['ids']);
            array_shift($ids);
            $sql = 'DELETE FROM vtiger_modtracker_detail WHERE id IN ('.implode(',', $ids).') AND fieldname = ? AND postvalue = ?';
            $adb->pquery($sql, array($row['fieldname'], $row['postvalue']), true);

            foreach($ids as $id) {
                $sql = 'SELECT COUNT(*) FROM vtiger_modtracker_detail WHERE id = '.$id.' HAVING COUNT(*) = 0';
                $result2 = $adb->query($sql);
                while ($row2 = $adb->fetchByAssoc($result2)) {
                    $sql = 'DELETE FROM vtiger_modtracker_basic WHERE id = ' . $id;
                    $adb->query($sql, true);
                }
            }
        }

    }

}