- Added comprehensive AI Assistant system (aiassist/ directory): * Vector search and embedding capabilities * Typebot proxy integration * Elastic search functionality * Message classification and chat history * MCP proxy for external integrations - Implemented Court Status API (GetCourtStatus.php): * Real-time court document status checking * Integration with external court systems * Comprehensive error handling and logging - Enhanced S3 integration: * Improved file backup system with metadata * Batch processing capabilities * Enhanced error logging and recovery * Copy operations with URL fixing - Added Telegram contact creation API - Improved error logging across all modules - Enhanced callback system for AI responses - Extensive backup file storage with timestamps - Updated documentation and README files - File storage improvements: * Thousands of backup files with proper metadata * Fix operations for broken file references * Project-specific backup and recovery systems * Comprehensive file integrity checking Total: 26,461+ files added/modified including AWS SDK, vendor dependencies, and extensive backup system.
743 lines
19 KiB
PHP
743 lines
19 KiB
PHP
<?php
|
|
/* * *******************************************************************************
|
|
* The content of this file is subject to the ITS4YouEmailMarketing license.
|
|
* ("License"); You may not use this file except in compliance with the License
|
|
* The Initial Developer of the Original Code is IT-Solutions4You s.r.o.
|
|
* Portions created by IT-Solutions4You s.r.o. are Copyright(C) IT-Solutions4You s.r.o.
|
|
* All Rights Reserved.
|
|
* ****************************************************************************** */
|
|
|
|
abstract class ITS4YouEmailMarketing_Content_Template extends Vtiger_Base_Model
|
|
{
|
|
|
|
/**
|
|
* @var object
|
|
*/
|
|
protected $contactRecord;
|
|
|
|
/**
|
|
* @var $recordModel Vtiger_Record_Model
|
|
*/
|
|
protected $recordModel;
|
|
/**
|
|
* @var object
|
|
*/
|
|
protected $marketingRecord;
|
|
/**
|
|
* @var string
|
|
*/
|
|
protected $moduleName;
|
|
/**
|
|
* @var object
|
|
*/
|
|
protected $moduleModel;
|
|
/**
|
|
* @var string
|
|
*/
|
|
protected $subject;
|
|
/**
|
|
* @var string
|
|
*/
|
|
protected $body;
|
|
/**
|
|
* @var int
|
|
*/
|
|
protected $templateId;
|
|
/**
|
|
* @var string
|
|
*/
|
|
protected $templateSource;
|
|
|
|
/**
|
|
* @var array
|
|
*/
|
|
protected $images = [];
|
|
|
|
/**
|
|
* @var int
|
|
*/
|
|
protected $contactId;
|
|
|
|
/**
|
|
* @var string
|
|
*/
|
|
protected $contactModule;
|
|
|
|
/**
|
|
* @param int $value
|
|
*/
|
|
public function setContactId($value)
|
|
{
|
|
$this->contactId = $value;
|
|
}
|
|
|
|
/**
|
|
* @param string $value
|
|
*/
|
|
public function setContactModule($value)
|
|
{
|
|
$this->contactModule = $value;
|
|
}
|
|
|
|
/**
|
|
* @return int
|
|
*/
|
|
public function getContactId()
|
|
{
|
|
return $this->contactId;
|
|
}
|
|
|
|
/**
|
|
* @return string
|
|
*/
|
|
public function getContactModule()
|
|
{
|
|
return $this->contactModule;
|
|
}
|
|
|
|
/**
|
|
* @param array $images
|
|
*/
|
|
public function setImages($images) {
|
|
$this->images = $images;
|
|
}
|
|
|
|
/**
|
|
* @return array
|
|
*/
|
|
public function getImages() {
|
|
return $this->images;
|
|
}
|
|
|
|
/**
|
|
* @param int|object $record
|
|
* @return bool|object
|
|
*/
|
|
public static function getInstanceFromMarketing($record)
|
|
{
|
|
if (!empty($record) && is_numeric($record)) {
|
|
$record = Vtiger_Record_Model::getInstanceById($record);
|
|
}
|
|
|
|
if (!empty($record)) {
|
|
$instance = self::getInstanceById($record->get('template'), $record->get('templatesource'));
|
|
|
|
if ($instance) {
|
|
$instance->setMarketing($record);
|
|
}
|
|
|
|
return $instance;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* @param int $record
|
|
* @param string $source
|
|
* @return bool|object
|
|
*/
|
|
public static function getInstanceById($record, $source)
|
|
{
|
|
/** @var $instance ITS4YouEmailMarketing_Content_Template */
|
|
$instance = self::getInstance($source);
|
|
|
|
if ($instance && $record) {
|
|
$instance->templateId = $record;
|
|
$instance->setContent();
|
|
}
|
|
|
|
return $instance;
|
|
}
|
|
|
|
/**
|
|
* @param string $source
|
|
* @return bool|object
|
|
*/
|
|
public static function getInstance($source)
|
|
{
|
|
$class = 'ITS4YouEmailMarketing_' . $source . '_Template';
|
|
|
|
if (class_exists($class)) {
|
|
$instance = new $class();
|
|
$instance->templateSource = $source;
|
|
|
|
if (vtlib_isModuleActive($instance->moduleName)) {
|
|
return $instance;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* @return mixed
|
|
*/
|
|
abstract protected function setContent();
|
|
|
|
/**
|
|
* @param $recordModel
|
|
*/
|
|
public function setMarketing($recordModel)
|
|
{
|
|
$this->marketingRecord = $recordModel;
|
|
}
|
|
|
|
/**
|
|
* @return mixed
|
|
*/
|
|
public function getSource()
|
|
{
|
|
return $this->templateSource;
|
|
}
|
|
|
|
/**
|
|
* @return string
|
|
*/
|
|
public function getName()
|
|
{
|
|
if ($this->recordModel) {
|
|
return $this->recordModel->getDisplayName();
|
|
}
|
|
|
|
return 'Empty Display Name';
|
|
}
|
|
|
|
/**
|
|
* @return string
|
|
*/
|
|
public function getSubject()
|
|
{
|
|
return $this->subject;
|
|
}
|
|
|
|
/**
|
|
* @param $value
|
|
*/
|
|
public function setSubject($value)
|
|
{
|
|
$this->subject = $value;
|
|
}
|
|
|
|
/**
|
|
* @return string
|
|
*/
|
|
public function getBody()
|
|
{
|
|
return $this->body;
|
|
}
|
|
|
|
/**
|
|
* @param $value
|
|
*/
|
|
public function setBody($value)
|
|
{
|
|
$this->body = $value;
|
|
}
|
|
|
|
/**
|
|
* @return bool|Vtiger_Module|Vtiger_Module_Model
|
|
*/
|
|
public function getModuleModel()
|
|
{
|
|
if (!$this->moduleModel) {
|
|
$this->moduleModel = Vtiger_Module_Model::getInstance($this->moduleName);
|
|
}
|
|
|
|
return $this->moduleModel;
|
|
}
|
|
|
|
/**
|
|
* @return array
|
|
*/
|
|
public function getPickListValues()
|
|
{
|
|
$modules = false;
|
|
|
|
if ($this->marketingRecord) {
|
|
$modules = $this->marketingRecord->getRelatedRecordsModules();
|
|
}
|
|
|
|
$query = $this->getPickListQuery($modules, true);
|
|
$values = [];
|
|
|
|
if ($query) {
|
|
$adb = PearDatabase::getInstance();
|
|
$result = $adb->pquery($query, $modules);
|
|
|
|
while ($row = $adb->fetchByAssoc($result)) {
|
|
$values[$row['id']] = $row['name'];
|
|
}
|
|
}
|
|
|
|
return (array)$values;
|
|
}
|
|
|
|
/**
|
|
* @param array|bool $modules
|
|
* @param bool $globalTemplates
|
|
* @return array
|
|
*/
|
|
abstract protected function getPickListQuery($modules = false, $globalTemplates = false);
|
|
|
|
/**
|
|
* @return string
|
|
*/
|
|
public function getModuleName()
|
|
{
|
|
return $this->moduleName;
|
|
}
|
|
|
|
/**
|
|
* @return string
|
|
*/
|
|
public function getLanguage()
|
|
{
|
|
global $default_language;
|
|
|
|
if ($this->marketingRecord) {
|
|
return $this->marketingRecord->get('templatelanguage', $default_language);
|
|
}
|
|
|
|
return $default_language;
|
|
}
|
|
|
|
public function getCreateLink()
|
|
{
|
|
return 'index.php?module=' . $this->moduleName . '&view=Edit';
|
|
}
|
|
|
|
public function getEditLink()
|
|
{
|
|
$link = 'index.php?module=' . $this->moduleName . '&view=Edit';
|
|
|
|
if ($this->recordModel) {
|
|
$link .= '&record=' . $this->recordModel->getId();
|
|
}
|
|
|
|
return $link;
|
|
}
|
|
|
|
/**
|
|
* @param string $blockName
|
|
* @return string
|
|
*/
|
|
public function getBlocksPattern($blockName)
|
|
{
|
|
return '/<' . $blockName . '(?<blockData>[^>]*)>(?<block>[\s\S]*?)<\/' . $blockName . '>/m';
|
|
}
|
|
|
|
/**
|
|
* @param string $blockName
|
|
* @return array
|
|
*/
|
|
public function getBlocksInfo($blockName)
|
|
{
|
|
$pattern = $this->getBlocksPattern($blockName);
|
|
$content = html_entity_decode($this->getBody());
|
|
preg_match_all($pattern, $content,$matches_all, PREG_SET_ORDER, 0);
|
|
$blocks = [];
|
|
|
|
foreach ($matches_all as $matches) {
|
|
$blockData = str_replace('\'', '"', $matches['blockData']);
|
|
preg_match_all('/(?<key>[\S]+?)\=\"(?<value>[\s\S]+?)\"|\"\ /', $blockData, $matches);
|
|
$data = [];
|
|
|
|
foreach ($matches['key'] as $keyNum => $key) {
|
|
$data[$key] = $matches['value'][$keyNum];
|
|
}
|
|
|
|
array_push($blocks, $data);
|
|
}
|
|
|
|
return $blocks;
|
|
}
|
|
|
|
/**
|
|
* @var string $name
|
|
*/
|
|
public function retrieveBlockData($name)
|
|
{
|
|
$this->setBlockData($name, $this->getBlocksInfo($name));
|
|
}
|
|
|
|
/**
|
|
* @var array
|
|
*/
|
|
public $blockData = array();
|
|
|
|
/**
|
|
* @param string $name
|
|
* @param array $value
|
|
*/
|
|
public function setBlockData($name, $value)
|
|
{
|
|
$this->blockData[$name] = $value;
|
|
}
|
|
|
|
public function getBlockData($name)
|
|
{
|
|
if (empty($this->blockData[$name])) {
|
|
$this->retrieveBlockData($name);
|
|
}
|
|
|
|
return $this->blockData[$name];
|
|
}
|
|
|
|
/**
|
|
* @return bool
|
|
*/
|
|
public function isAllowedRecordsBlock()
|
|
{
|
|
return !empty($this->getBlockData('recordsblock'));
|
|
}
|
|
|
|
/**
|
|
* @throws Exception
|
|
*/
|
|
public function replaceRecordsBlock()
|
|
{
|
|
$type = 'recordsblock';
|
|
$content = html_entity_decode($this->getBody());
|
|
$recordId = $this->marketingRecord->getId();
|
|
$templateRecords = ITS4YouEmailMarketing_TemplateRecords_Model::getRecords($recordId);
|
|
|
|
foreach ($this->getBlockData($type) as $block) {
|
|
if (!empty($block) && preg_match($this->getBlocksPattern($type), $content, $matches)) {
|
|
$templateModule = $block['data-module'];
|
|
$newContent = '';
|
|
|
|
foreach ($templateRecords[$templateModule] as $templateRecord) {
|
|
$sourceRecord = $templateRecord->getSourceRecord();
|
|
$block = '<div ' . $matches['blockData'] . '>' . $matches['block'] . '</div>';
|
|
|
|
if ($sourceRecord) {
|
|
foreach ($this->getVariableFields($templateModule) as $variable => $field) {
|
|
$block = str_replace('$' . $variable . '$', $this->getDisplayValue($field, $sourceRecord), $block);
|
|
}
|
|
|
|
$block = str_replace(sprintf('$%s-ID$', strtoupper($sourceRecord->getModuleName())), $sourceRecord->getId(), $block);
|
|
|
|
$newContent .= $block;
|
|
}
|
|
}
|
|
|
|
$content = preg_replace($this->getBlocksPattern($type), $newContent, $content, 1);
|
|
}
|
|
}
|
|
|
|
$this->setBody($content);
|
|
}
|
|
|
|
/**
|
|
* @param object $field
|
|
* @param object $record
|
|
* @return mixed|string
|
|
*/
|
|
public function getDisplayValue($field, $record)
|
|
{
|
|
/** @var $field Vtiger_Field_Model */
|
|
$fieldName = $field->getName();
|
|
$fieldValue = strip_tags($record->getDisplayValue($fieldName));
|
|
|
|
if ($field->getFieldDataType() === 'image') {
|
|
foreach ($record->getImageDetails() as $imageDetail) {
|
|
if(isset($imageDetail['url'])) {
|
|
$fieldValue = $imageDetail['url'];
|
|
} else {
|
|
$fieldValue = vglobal('site_URL') . $imageDetail['path'] . '_' . $imageDetail['name'];
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
return $fieldValue;
|
|
}
|
|
|
|
/**
|
|
* @param object|bool $recipientRecord
|
|
* @return string
|
|
* @throws Exception
|
|
*/
|
|
public function getContent($recipientRecord = false)
|
|
{
|
|
if ($recipientRecord) {
|
|
$this->setContactData($recipientRecord->getId(), $recipientRecord->getModuleName());
|
|
$this->setContactRecord($recipientRecord);
|
|
|
|
if (vtlib_isModuleActive('ITS4YouMultiCompany')) {
|
|
$this->replaceCompanyVariables();
|
|
}
|
|
|
|
$this->replaceEmailsVariables();
|
|
$this->replaceCustomVariables();
|
|
}
|
|
|
|
if ($this->marketingRecord) {
|
|
$this->replaceTemplateVariables();
|
|
$this->replaceRecordsBlock();
|
|
$this->replaceCustomFunctions();
|
|
}
|
|
|
|
$this->convertBase64Images();
|
|
|
|
return $this->getBody();
|
|
}
|
|
|
|
|
|
/**
|
|
* @param object $value
|
|
*/
|
|
public function setContactRecord($value)
|
|
{
|
|
$this->contactRecord = $value;
|
|
}
|
|
|
|
/**
|
|
* @return object
|
|
*/
|
|
public function getContactRecord()
|
|
{
|
|
return $this->contactRecord;
|
|
}
|
|
|
|
public function replaceCompanyVariables() {
|
|
$userId = $this->getContactRecord()->get('assigned_user_id');
|
|
$content = $this->getBody();
|
|
|
|
if(method_exists('ITS4YouMultiCompany_Record_Model', 'getCompanyInstance')) {
|
|
$siteUrl = ITS4YouEmailMarketing_Module_Model::getSiteUrl();
|
|
$recordModel = ITS4YouMultiCompany_Record_Model::getCompanyInstance($userId);
|
|
$moduleModel = Vtiger_Module_Model::getInstance('ITS4YouMultiCompany');
|
|
$var = '$companydetails-%s$';
|
|
|
|
foreach ($moduleModel->getFields() as $field) {
|
|
if($this->isVariableField($field)) {
|
|
if('image' === $field->getFieldDataType()) {
|
|
$imageDetails = $recordModel->getImageDetails($field)[0];
|
|
$value = '';
|
|
|
|
if(!empty($imageDetails['name'])) {
|
|
$value = sprintf('%s%s_%s', $siteUrl, $imageDetails['path'], $imageDetails['name']);
|
|
$value = sprintf('<img src="%s">', $value);
|
|
}
|
|
} else {
|
|
$value = strip_tags($recordModel->getDisplayValue($field->name));
|
|
}
|
|
|
|
$content = str_replace(sprintf($var, $field->name), $value, $content);
|
|
|
|
if ('logo' === $field->name) {
|
|
$content = str_replace(sprintf($var, 'logoname'), $value, $content);
|
|
$content = str_replace('$logo$', $value, $content);
|
|
}
|
|
|
|
if ('street' === $field->name) {
|
|
$content = str_replace(sprintf($var, 'address'), $value, $content);
|
|
}
|
|
|
|
if ('companyname' === $field->name) {
|
|
$content = str_replace(sprintf($var, 'organizationname'), $value, $content);
|
|
}
|
|
}
|
|
}
|
|
|
|
$content = str_replace(sprintf($var, 'id'), $recordModel->getId(), $content);
|
|
}
|
|
|
|
$this->setBody($content);
|
|
}
|
|
|
|
/**
|
|
* @param Vtiger_Field $field
|
|
* @return bool
|
|
*/
|
|
public function isVariableField($field)
|
|
{
|
|
return in_array($field->displaytype, ['1', '2']);
|
|
}
|
|
|
|
public function replaceCustomFunctions()
|
|
{
|
|
$content = $this->getBody();
|
|
$cfModel = ITS4YouEmailMarketing_CustomFunctions_Model::getInstance($content);
|
|
$cfModel->replaceCustomFunctions('');
|
|
$cfModel->replaceCustomFunctions('_after');
|
|
|
|
|
|
$this->setBody($cfModel->getContent());
|
|
}
|
|
|
|
public function replaceEmailsVariables()
|
|
{
|
|
$content = $this->getBody();
|
|
$content = getMergedDescription($content, $this->getContactId(), $this->getContactModule());
|
|
|
|
$this->setBody($content);
|
|
}
|
|
|
|
public function replaceCustomVariables()
|
|
{
|
|
$content = $this->getBody();
|
|
$content = ITS4YouEmailMarketing_Module_Model::convertCustomVariables($content, $this->getContactId());
|
|
|
|
$this->setBody($content);
|
|
}
|
|
|
|
public function replaceTemplateVariables()
|
|
{
|
|
/** @var $module ITS4YouEmailMarketing_Module_Model */
|
|
$module = $this->marketingRecord->getModule();
|
|
$body = $module->replaceTemplateFields($this->marketingRecord, $this->getBody());
|
|
|
|
$this->setBody($body);
|
|
}
|
|
|
|
/**
|
|
* @param string|object $module
|
|
* @return array
|
|
* @throws Exception
|
|
*/
|
|
public function getVariableFields($module)
|
|
{
|
|
if (is_string($module)) {
|
|
$module = Vtiger_Module_Model::getInstance($module);
|
|
}
|
|
|
|
$moduleName = $module->getName();
|
|
$fieldsResult = [];
|
|
|
|
foreach ($module->getFields() as $field) {
|
|
if ($field) {
|
|
/** @var $field Vtiger_Field_Model */
|
|
$fieldVar = str_replace('_', '-', strtoupper($moduleName . '-' . $field->getName()));
|
|
$fieldsResult[$fieldVar] = $field;
|
|
}
|
|
}
|
|
|
|
return $fieldsResult;
|
|
}
|
|
|
|
public function convertBase64Images()
|
|
{
|
|
$content = $this->getBody();
|
|
$re = '/<img.*?src="(.*?)"[^\>]+>/';
|
|
preg_match_all($re, $content, $matches, PREG_SET_ORDER, 0);
|
|
$num = count($this->getImages());
|
|
|
|
foreach ($matches as $match) {
|
|
$image = $match[0];
|
|
$url = $match[1];
|
|
$replaceUrl = $url;
|
|
$num++;
|
|
|
|
if ($this->isEmptyImage($replaceUrl)) {
|
|
$replaceUrl = $this->getDefaultImage();
|
|
}
|
|
|
|
if ($this->isImageToBase64($image)) {
|
|
$cid = 'EmailMarketingImage' . $num;
|
|
$this->setImage($cid, $replaceUrl, basename($replaceUrl));
|
|
$content = str_replace($image, $this->replaceImageSrc($image, $url, 'cid:' . $cid), $content);
|
|
}
|
|
}
|
|
|
|
$this->setBody($content);
|
|
}
|
|
|
|
/**
|
|
* @param string $content
|
|
* @param string $fromUrl
|
|
* @param string $toUrl
|
|
* @return string|string[]
|
|
*/
|
|
public function replaceImageSrc($content, $fromUrl, $toUrl)
|
|
{
|
|
$content = str_replace('src="' . $fromUrl . '"', 'src="' . $toUrl . '"', $content);
|
|
$content = str_replace("src='" . $fromUrl . "'", 'src="' . $toUrl . '"', $content);
|
|
|
|
return $content;
|
|
}
|
|
|
|
/**
|
|
* @param string $cid
|
|
* @param string $path
|
|
* @param string $name
|
|
*/
|
|
public function setImage($cid, $path, $name)
|
|
{
|
|
$this->images[$cid] = array(
|
|
'cid' => $cid,
|
|
'path' => $this->clearImageUrl($path),
|
|
'name' => $name,
|
|
);
|
|
}
|
|
|
|
/**
|
|
* @param string $path
|
|
* @return string
|
|
*/
|
|
public function clearImageUrl($path)
|
|
{
|
|
global $site_URL;
|
|
|
|
$site = trim($site_URL, '/');
|
|
|
|
return trim(str_replace($site, '', $path), '/');
|
|
}
|
|
|
|
/**
|
|
* @param string $value
|
|
* @return bool
|
|
*/
|
|
public function isImageToBase64($value)
|
|
{
|
|
$re = '/image\-convert/';
|
|
preg_match_all($re, $value, $matches, PREG_SET_ORDER, 0);
|
|
|
|
return !empty($matches);
|
|
}
|
|
|
|
/**
|
|
* @param string $url
|
|
* @return string
|
|
*/
|
|
public function convertImageToBase64($url)
|
|
{
|
|
$type = pathinfo($url, PATHINFO_EXTENSION);
|
|
|
|
if (!empty($type)) {
|
|
$data = file_get_contents($url);
|
|
}
|
|
|
|
if (empty($data)) {
|
|
$url = ITS4YouEmailMarketing_Module_Model::getSiteUrl() . 'storage/images/nophoto.png';
|
|
$type = pathinfo($url, PATHINFO_EXTENSION);
|
|
$data = file_get_contents($url);
|
|
}
|
|
|
|
return sprintf('data:image/%s;base64,%s', $type, base64_encode($data));
|
|
}
|
|
|
|
/**
|
|
* @param string $url
|
|
* @return bool
|
|
*/
|
|
public function isEmptyImage($url)
|
|
{
|
|
return empty(pathinfo($url, PATHINFO_EXTENSION)) || empty(file_get_contents($url));
|
|
}
|
|
|
|
/**
|
|
* @return string
|
|
*/
|
|
public function getDefaultImage()
|
|
{
|
|
return ITS4YouEmailMarketing_Module_Model::getSiteUrl() . 'storage/images/nophoto.png';
|
|
}
|
|
|
|
public function getDocumentsIds()
|
|
{
|
|
return [];
|
|
}
|
|
} |