3424 lines
147 KiB
PHP
3424 lines
147 KiB
PHP
<?php
|
||
/*********************************************************************************
|
||
* The contents of this file are subject to the SugarCRM Public License Version 1.1.2
|
||
* ("License"); You may not use this file except in compliance with the
|
||
* License. You may obtain a copy of the License at http://www.sugarcrm.com/SPL
|
||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
|
||
* the specific language governing rights and limitations under the License.
|
||
* The Original Code is: SugarCRM Open Source
|
||
* The Initial Developer of the Original Code is SugarCRM, Inc.
|
||
* Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.;
|
||
* All Rights Reserved.
|
||
* Contributor(s): ______________________________________.
|
||
********************************************************************************/
|
||
/*********************************************************************************
|
||
* $Header: /advent/projects/wesat/vtiger_crm/vtigercrm/data/CRMEntity.php,v 1.16 2005/04/29 04:21:31 mickie Exp $
|
||
* Description: Defines the base class for all data entities used throughout the
|
||
* application. The base class including its methods and variables is designed to
|
||
* be overloaded with module-specific methods and variables particular to the
|
||
* module's base entity class.
|
||
********************************************************************************/
|
||
|
||
include_once('config.php');
|
||
require_once('include/logging.php');
|
||
require_once('data/Tracker.php');
|
||
require_once('include/utils/utils.php');
|
||
require_once('include/utils/UserInfoUtil.php');
|
||
require_once("include/Zend/Json.php");
|
||
require_once 'include/RelatedListView.php';
|
||
|
||
class CRMEntity {
|
||
|
||
var $ownedby;
|
||
var $recordSource = 'CRM';
|
||
|
||
/**
|
||
* Detect if we are in bulk save mode, where some features can be turned-off
|
||
* to improve performance.
|
||
*/
|
||
static function isBulkSaveMode() {
|
||
global $VTIGER_BULK_SAVE_MODE;
|
||
if (isset($VTIGER_BULK_SAVE_MODE) && $VTIGER_BULK_SAVE_MODE) {
|
||
return true;
|
||
}
|
||
return false;
|
||
}
|
||
|
||
static function getInstance($module) {
|
||
$modName = $module;
|
||
if ($module == 'Calendar' || $module == 'Events') {
|
||
$module = 'Calendar';
|
||
$modName = 'Activity';
|
||
}
|
||
// File access security check
|
||
if (!class_exists($modName)) {
|
||
checkFileAccessForInclusion("modules/$module/$modName.php");
|
||
require_once("modules/$module/$modName.php");
|
||
}
|
||
$focus = new $modName();
|
||
$focus->moduleName = $module;
|
||
$focus->column_fields = new TrackableObject();
|
||
$focus->column_fields = getColumnFields($module);
|
||
if (method_exists($focus, 'initialize')) $focus->initialize();
|
||
return $focus;
|
||
}
|
||
|
||
/**
|
||
* Function which indicates whether to chagne the modified time or not while saving
|
||
*/
|
||
static function isTimeStampNoChangeMode(){
|
||
global $VTIGER_TIMESTAMP_NO_CHANGE_MODE;
|
||
if (isset($VTIGER_TIMESTAMP_NO_CHANGE_MODE) && $VTIGER_TIMESTAMP_NO_CHANGE_MODE) {
|
||
return true;
|
||
}
|
||
return false;
|
||
}
|
||
|
||
/**
|
||
* Function which will used to initialize object properties
|
||
*/
|
||
function initialize() {
|
||
$moduleName = $this->moduleName;
|
||
$moduleModel = Vtiger_Module_Model::getInstance($moduleName);
|
||
if($moduleModel && !$moduleModel->isEntityModule()) {
|
||
return;
|
||
}
|
||
|
||
//SalesPlatform.ru begin
|
||
//$userSpecificTableIgnoredModules = array('SMSNotifier', 'PBXManager', 'ModComments');
|
||
$userSpecificTableIgnoredModules = array('SMSNotifier', 'ModComments');
|
||
//SalesPlatform.ru end
|
||
if(in_array($moduleName, $userSpecificTableIgnoredModules)) return;
|
||
|
||
$userSpecificTable = Vtiger_Functions::getUserSpecificTableName($moduleName);
|
||
if(!in_array($userSpecificTable, $this->tab_name)) {
|
||
$this->tab_name[] = $userSpecificTable;
|
||
$this->tab_name_index [$userSpecificTable] = 'recordid';
|
||
}
|
||
}
|
||
|
||
function saveentity($module, $fileid = '') {
|
||
global $current_user, $adb; //$adb added by raju for mass mailing
|
||
$insertion_mode = $this->mode;
|
||
|
||
$columnFields = $this->column_fields;
|
||
$anyValue = false;
|
||
foreach ($columnFields as $value) {
|
||
if(!empty($value)) {
|
||
$anyValue = true;
|
||
break;
|
||
}
|
||
}
|
||
if(!$anyValue) {
|
||
die("<center>" .getTranslatedString('LBL_MANDATORY_FIELD_MISSING')."</center>");
|
||
}
|
||
|
||
// added to support files transformation for file upload fields like uitype 69,
|
||
if(count($_FILES)) {
|
||
$_FILES = Vtiger_Util_Helper::transformUploadedFiles($_FILES, true);
|
||
}
|
||
|
||
$this->db->startTransaction();
|
||
|
||
//SalesPlatform.ru begin
|
||
$saveError = null;
|
||
//SalesPlatform.ru end
|
||
|
||
foreach ($this->tab_name as $table_name) {
|
||
if ($table_name == "vtiger_crmentity") {
|
||
$this->insertIntoCrmEntity($module, $fileid);
|
||
} else {
|
||
$this->insertIntoEntityTable($table_name, $module, $fileid);
|
||
}
|
||
|
||
//SalesPlatform.ru begin
|
||
if($this->db->database->ErrorMsg() != false && $saveError === null) {
|
||
$saveError = vtranslate('LBL_ERROR_CODE') . ": " . $this->db->database->ErrorNo() . " " .
|
||
vtranslate('LBL_ERROR_MESSAGE') . ": " . $this->db->database->ErrorMsg();
|
||
}
|
||
//SalesPlatform.ru end
|
||
}
|
||
//SalesPlatform.ru begin
|
||
if($this->db->hasFailedTransaction()) {
|
||
throw new Exception($saveError);
|
||
}
|
||
//SalesPlatform.ru end
|
||
|
||
$columnFields->restartTracking();
|
||
//Calling the Module specific save code
|
||
$this->save_module($module);
|
||
|
||
$this->db->completeTransaction();
|
||
|
||
// vtlib customization: Hook provide to enable generic module relation.
|
||
if ($_REQUEST['createmode'] == 'link' && !$_REQUEST['__linkcreated']) {
|
||
$_REQUEST['__linkcreated'] = true;
|
||
$for_module = vtlib_purify($_REQUEST['return_module']);
|
||
$for_crmid = vtlib_purify($_REQUEST['return_id']);
|
||
$with_module = $module;
|
||
$with_crmid = $this->id;
|
||
|
||
$on_focus = CRMEntity::getInstance($for_module);
|
||
|
||
if ($for_module && $for_crmid && $with_module && $with_crmid) {
|
||
relateEntities($on_focus, $for_module, $for_crmid, $with_module, $with_crmid);
|
||
}
|
||
}
|
||
// END
|
||
}
|
||
|
||
/**
|
||
* This function is used to upload the attachment in the server and save that attachment information in db.
|
||
* @param int $id - entity id to which the file to be uploaded
|
||
* @param string $module - the current module name
|
||
* @param array $file_details - array which contains the file information(name, type, size, tmp_name and error)
|
||
* return void
|
||
*/
|
||
function uploadAndSaveFile($id, $module, $file_details, $attachmentType='Attachment') {
|
||
global $log;
|
||
$log->debug("Entering into uploadAndSaveFile($id,$module,$file_details) method.");
|
||
|
||
// Debug logging for ModComments
|
||
file_put_contents('logs/debug.log', '[' . date('Y-m-d H:i:s') . '] UPLOAD_AND_SAVE_FILE: module=' . $module . ', id=' . $id . ', attachmentType=' . $attachmentType . PHP_EOL, FILE_APPEND);
|
||
|
||
global $adb, $current_user;
|
||
global $upload_badext;
|
||
|
||
$date_var = date("Y-m-d H:i:s");
|
||
|
||
//to get the owner id
|
||
$ownerid = $this->column_fields['assigned_user_id'];
|
||
if (!isset($ownerid) || $ownerid == '')
|
||
$ownerid = $current_user->id;
|
||
|
||
if (isset($file_details['original_name']) && $file_details['original_name'] != null) {
|
||
$file_name = $file_details['original_name'];
|
||
} else {
|
||
$file_name = $file_details['name'];
|
||
}
|
||
|
||
// Check 1
|
||
$save_file = 'true';
|
||
//only images are allowed for Image Attachmenttype
|
||
$mimeType = vtlib_mime_content_type($file_details['tmp_name']);
|
||
$mimeTypeContents = explode('/', $mimeType);
|
||
// For contacts and products we are sending attachmentType as value
|
||
if ($attachmentType == 'Image' || ($file_details['size'] && $mimeTypeContents[0] == 'image')) {
|
||
$save_file = validateImageFile($file_details);
|
||
}
|
||
if ($save_file == 'false') {
|
||
return false;
|
||
}
|
||
|
||
// Check 2
|
||
$save_file = 'true';
|
||
//only images are allowed for these modules
|
||
if ($module == 'Contacts' || $module == 'Products') {
|
||
$save_file = validateImageFile($file_details);
|
||
}
|
||
|
||
$binFile = sanitizeUploadFileName($file_name, $upload_badext);
|
||
|
||
// Generate new ID for file attachment (always create new file record)
|
||
$current_id = $adb->getUniqueID("vtiger_crmentity");
|
||
file_put_contents('logs/debug.log', '[' . date('Y-m-d H:i:s') . '] FILE ID: Generated new file ID ' . $current_id . ' for comment ID ' . $id . PHP_EOL, FILE_APPEND);
|
||
|
||
$filename = ltrim(basename(" " . $binFile)); //allowed filename like UTF-8 characters
|
||
$filetype = $file_details['type'];
|
||
$filetmp_name = $file_details['tmp_name'];
|
||
|
||
// S3 Integration: Upload file directly to S3 instead of local storage
|
||
$upload_status = false;
|
||
$s3_metadata = null;
|
||
|
||
// Check if S3 upload is enabled
|
||
global $UPLOAD_TO_S3;
|
||
|
||
$log->debug("S3 upload check: save_file=$save_file, UPLOAD_TO_S3=" . ($UPLOAD_TO_S3 ? 'true' : 'false'));
|
||
file_put_contents('logs/debug.log', '[' . date('Y-m-d H:i:s') . '] S3 DEBUG: save_file=' . $save_file . ', UPLOAD_TO_S3=' . ($UPLOAD_TO_S3 ? 'true' : 'false') . PHP_EOL, FILE_APPEND);
|
||
|
||
$s3_metadata = null; // Initialize S3 metadata variable
|
||
|
||
// Check if S3 upload is enabled
|
||
global $UPLOAD_TO_S3;
|
||
|
||
if ($save_file == 'true' && $UPLOAD_TO_S3) {
|
||
file_put_contents('logs/debug.log', '[' . date('Y-m-d H:i:s') . '] S3 UPLOAD STARTING: current_id=' . $current_id . ', filename=' . $filename . ', tmp_file=' . $filetmp_name . PHP_EOL, FILE_APPEND);
|
||
$log->debug("Starting file upload process for record $current_id, filename: $filename, tmp_file: $filetmp_name");
|
||
|
||
// Проверяем, что временный файл существует
|
||
if (!file_exists($filetmp_name)) {
|
||
$log->error("Temporary file not found: $filetmp_name");
|
||
$upload_status = false;
|
||
} else {
|
||
try {
|
||
file_put_contents('logs/debug.log', '[' . date('Y-m-d H:i:s') . '] S3: Temporary file exists, creating S3Service' . PHP_EOL, FILE_APPEND);
|
||
// Load S3 Storage Service
|
||
require_once __DIR__ . '/../include/Storage/S3StorageService.php';
|
||
$s3Service = new S3StorageService();
|
||
|
||
file_put_contents('logs/debug.log', '[' . date('Y-m-d H:i:s') . '] S3: Calling put() method' . PHP_EOL, FILE_APPEND);
|
||
$log->debug("S3Service loaded, attempting upload to S3");
|
||
|
||
// Upload to S3
|
||
$s3Result = $s3Service->put($filetmp_name, $current_id, $filename);
|
||
$upload_status = true;
|
||
$s3_metadata = $s3Result;
|
||
|
||
file_put_contents('logs/debug.log', '[' . date('Y-m-d H:i:s') . '] S3 SUCCESS: Upload completed, metadata=' . json_encode($s3_metadata) . PHP_EOL, FILE_APPEND);
|
||
$log->debug("S3 upload successful for record $current_id, key: " . $s3Result['key']);
|
||
|
||
} catch (Exception $e) {
|
||
file_put_contents('logs/debug.log', '[' . date('Y-m-d H:i:s') . '] S3 EXCEPTION: ' . $e->getMessage() . PHP_EOL, FILE_APPEND);
|
||
$log->error("S3 upload failed for record $current_id: " . $e->getMessage());
|
||
$upload_status = false;
|
||
$s3_metadata = null; // Clear S3 metadata on failure
|
||
|
||
// Fallback to local storage if S3 fails
|
||
$upload_file_path = decideFilePath();
|
||
$encryptFileName = Vtiger_Util_Helper::getEncryptedFileName($binFile);
|
||
$upload_status = copy($filetmp_name, $upload_file_path . $current_id . "_" . $encryptFileName);
|
||
|
||
if ($upload_status) {
|
||
$log->debug("Fallback to local storage successful for record $current_id");
|
||
} else {
|
||
$log->error("Both S3 and local storage failed for record $current_id");
|
||
}
|
||
}
|
||
}
|
||
} else if ($save_file == 'true' && !$UPLOAD_TO_S3) {
|
||
// S3 is disabled, use local storage
|
||
// file_put_contents('logs/debug.log', '[' . date('Y-m-d H:i:s') . '] LOCAL STORAGE: S3 disabled, using local storage' . PHP_EOL, FILE_APPEND);
|
||
file_put_contents('logs/debug.log', '[' . date('Y-m-d H:i:s') . '] LOCAL STORAGE: module=' . $module . ', save_file=' . $save_file . ', S3 disabled, using local storage' . PHP_EOL, FILE_APPEND);
|
||
|
||
file_put_contents('logs/debug.log', '[' . date('Y-m-d H:i:s') . '] LOCAL STORAGE: Calling decideFilePath()' . PHP_EOL, FILE_APPEND);
|
||
$upload_file_path = decideFilePath();
|
||
file_put_contents('logs/debug.log', '[' . date('Y-m-d H:i:s') . '] LOCAL STORAGE: upload_file_path=' . $upload_file_path . PHP_EOL, FILE_APPEND);
|
||
|
||
file_put_contents('logs/debug.log', '[' . date('Y-m-d H:i:s') . '] LOCAL STORAGE: Calling getEncryptedFileName()' . PHP_EOL, FILE_APPEND);
|
||
$encryptFileName = Vtiger_Util_Helper::getEncryptedFileName($binFile);
|
||
file_put_contents('logs/debug.log', '[' . date('Y-m-d H:i:s') . '] LOCAL STORAGE: encryptFileName=' . $encryptFileName . PHP_EOL, FILE_APPEND);
|
||
|
||
file_put_contents('logs/debug.log', '[' . date('Y-m-d H:i:s') . '] LOCAL STORAGE: Calling copy() from ' . $filetmp_name . ' to ' . $upload_file_path . $current_id . "_" . $encryptFileName . PHP_EOL, FILE_APPEND);
|
||
$upload_status = copy($filetmp_name, $upload_file_path . $current_id . "_" . $encryptFileName);
|
||
file_put_contents('logs/debug.log', '[' . date('Y-m-d H:i:s') . '] LOCAL STORAGE: copy() result=' . ($upload_status ? 'true' : 'false') . PHP_EOL, FILE_APPEND);
|
||
|
||
if ($upload_status) {
|
||
$log->debug("Local storage upload successful for record $current_id");
|
||
file_put_contents('logs/debug.log', '[' . date('Y-m-d H:i:s') . '] LOCAL STORAGE: Upload successful, continuing...' . PHP_EOL, FILE_APPEND);
|
||
} else {
|
||
$log->error("Local storage upload failed for record $current_id");
|
||
file_put_contents('logs/debug.log', '[' . date('Y-m-d H:i:s') . '] LOCAL STORAGE: Upload failed!' . PHP_EOL, FILE_APPEND);
|
||
}
|
||
} else {
|
||
file_put_contents('logs/debug.log', '[' . date('Y-m-d H:i:s') . '] NO UPLOAD: save_file=' . $save_file . ', UPLOAD_TO_S3=' . ($UPLOAD_TO_S3 ? 'true' : 'false') . PHP_EOL, FILE_APPEND);
|
||
}
|
||
|
||
file_put_contents('logs/debug.log', '[' . date('Y-m-d H:i:s') . '] CHECKING FINAL CONDITION: save_file=' . $save_file . ', upload_status=' . ($upload_status ? 'true' : 'false') . PHP_EOL, FILE_APPEND);
|
||
if ($save_file == 'true' && $upload_status === true) {
|
||
file_put_contents('logs/debug.log', '[' . date('Y-m-d H:i:s') . '] ENTERING FILE PROCESSING BLOCK: attachmentType=' . $attachmentType . ', mode=' . $this->mode . PHP_EOL, FILE_APPEND);
|
||
if($attachmentType != 'Image' && $this->mode == 'edit') {
|
||
//Only one Attachment per entity delete previous attachments
|
||
$res = $adb->pquery('SELECT vtiger_seattachmentsrel.attachmentsid FROM vtiger_seattachmentsrel
|
||
INNER JOIN vtiger_crmentity ON vtiger_crmentity.crmid = vtiger_seattachmentsrel.attachmentsid AND vtiger_crmentity.setype = ?
|
||
WHERE vtiger_seattachmentsrel.crmid = ?',array($module.' Attachment',$id));
|
||
$oldAttachmentIds = array();
|
||
for($attachItr = 0;$attachItr < $adb->num_rows($res);$attachItr++) {
|
||
$oldAttachmentIds[] = $adb->query_result($res,$attachItr,'attachmentsid');
|
||
}
|
||
if(count($oldAttachmentIds)) {
|
||
$adb->pquery('DELETE FROM vtiger_seattachmentsrel WHERE attachmentsid IN ('.generateQuestionMarks($oldAttachmentIds).')',$oldAttachmentIds);
|
||
//TODO : revisit to delete actual file and attachment entry,as we need to see the deleted file in the history when its changed
|
||
//$adb->pquery('DELETE FROM vtiger_attachments WHERE attachmentsid IN ('.generateQuestionMarks($oldAttachmentIds).')',$oldAttachmentIds);
|
||
//$adb->pquery('DELETE FROM vtiger_crmentity WHERE crmid IN ('.generateQuestionMarks($oldAttachmentIds).')',$oldAttachmentIds);
|
||
}
|
||
}
|
||
file_put_contents('logs/debug.log', '[' . date('Y-m-d H:i:s') . '] DATABASE: Finished deleting old attachments, proceeding to add new entry' . PHP_EOL, FILE_APPEND);
|
||
//Add entry to crmentity
|
||
file_put_contents('logs/debug.log', '[' . date('Y-m-d H:i:s') . '] DATABASE: Adding entry to vtiger_crmentity for record ' . $current_id . PHP_EOL, FILE_APPEND);
|
||
file_put_contents('logs/debug.log', '[' . date('Y-m-d H:i:s') . '] DATABASE: setype will be: "' . $module . ' ' . $attachmentType . '"' . PHP_EOL, FILE_APPEND);
|
||
$sql1 = "INSERT INTO vtiger_crmentity (crmid,smcreatorid,smownerid,setype,description,createdtime,modifiedtime) VALUES (?, ?, ?, ?, ?, ?, ?)";
|
||
$params1 = array($current_id, $current_user->id, $ownerid, $module." ".$attachmentType, $this->column_fields['description'], $adb->formatDate($date_var, true), $adb->formatDate($date_var, true));
|
||
$adb->pquery($sql1, $params1);
|
||
file_put_contents('logs/debug.log', '[' . date('Y-m-d H:i:s') . '] DATABASE: vtiger_crmentity entry added successfully' . PHP_EOL, FILE_APPEND);
|
||
//Add entry to attachments
|
||
if ($s3_metadata) {
|
||
file_put_contents('logs/debug.log', '[' . date('Y-m-d H:i:s') . '] DATABASE: Saving S3 metadata to database for record ' . $current_id . PHP_EOL, FILE_APPEND);
|
||
file_put_contents('logs/debug.log', '[' . date('Y-m-d H:i:s') . '] DATABASE: filename=' . $filename . ', filetype=' . $filetype . PHP_EOL, FILE_APPEND);
|
||
file_put_contents('logs/debug.log', '[' . date('Y-m-d H:i:s') . '] DATABASE: S3 URL=' . $s3_metadata['url'] . ', size=' . $s3_metadata['size'] . PHP_EOL, FILE_APPEND);
|
||
|
||
// S3 storage - save S3 metadata
|
||
$sql2 = "INSERT INTO vtiger_attachments(attachmentsid, name, description, type, path, storedname) values(?, ?, ?, ?, ?, ?)";
|
||
// Используем S3 URL в поле name для корректного отображения в UI
|
||
$s3_url_for_attachments = isset($s3_metadata['url']) && $s3_metadata['url']
|
||
? $s3_metadata['url']
|
||
: ('https://'.$s3_metadata['bucket'].'/'.$s3_metadata['key']);
|
||
$params2 = array($current_id, $s3_url_for_attachments, $this->column_fields['description'], $filetype, 's3://' . $s3_metadata['bucket'], $s3_metadata['key']);
|
||
$result2 = $adb->pquery($sql2, $params2);
|
||
|
||
file_put_contents('logs/debug.log', '[' . date('Y-m-d H:i:s') . '] DATABASE: vtiger_attachments INSERT result=' . ($result2 ? 'SUCCESS' : 'FAILED') . PHP_EOL, FILE_APPEND);
|
||
|
||
// Update vtiger_notes with S3 metadata and set as external file
|
||
// Берём готовый публичный URL, который вернул клиент (полный https://...)
|
||
$s3_url = isset($s3_metadata['url']) && $s3_metadata['url']
|
||
? $s3_metadata['url']
|
||
: ('https://'.$s3_metadata['bucket'].'/'.$s3_metadata['key']);
|
||
// Исправляем nc_path - добавляем дублирование crm2 для Nextcloud
|
||
$nc_path = '/crm2/' . $s3_metadata['key'];
|
||
|
||
// Используем INSERT ... ON DUPLICATE KEY UPDATE для корректной работы с vtiger_notes
|
||
// Старый вариант (не работал, так как записи не было):
|
||
// $sql4 = "UPDATE vtiger_notes SET filename=?, filelocationtype='E', filesize=?, s3_bucket=?, s3_key=?, s3_etag=?, nc_path=? WHERE notesid=?";
|
||
// $params4 = array($s3_url, $s3_metadata['size'], $s3_metadata['bucket'], $s3_metadata['key'], $s3_metadata['etag'], $nc_path, $current_id);
|
||
|
||
$sql4 = "INSERT INTO vtiger_notes (notesid, filename, filelocationtype, filesize, s3_bucket, s3_key, s3_etag, nc_path) VALUES (?, ?, 'E', ?, ?, ?, ?, ?) ON DUPLICATE KEY UPDATE filename=VALUES(filename), filelocationtype=VALUES(filelocationtype), filesize=VALUES(filesize), s3_bucket=VALUES(s3_bucket), s3_key=VALUES(s3_key), s3_etag=VALUES(s3_etag), nc_path=VALUES(nc_path)";
|
||
$params4 = array($current_id, $s3_url, $s3_metadata['size'], $s3_metadata['bucket'], $s3_metadata['key'], $s3_metadata['etag'], $nc_path);
|
||
$result4 = $adb->pquery($sql4, $params4);
|
||
|
||
file_put_contents('logs/debug.log', '[' . date('Y-m-d H:i:s') . '] DATABASE: vtiger_notes INSERT/UPDATE result=' . ($result4 ? 'SUCCESS' : 'FAILED') . PHP_EOL, FILE_APPEND);
|
||
|
||
// Force commit the transaction
|
||
$adb->query("COMMIT");
|
||
file_put_contents('logs/debug.log', '[' . date('Y-m-d H:i:s') . '] DATABASE: Transaction committed for record ' . $current_id . PHP_EOL, FILE_APPEND);
|
||
|
||
file_put_contents('logs/debug.log', '[' . date('Y-m-d H:i:s') . '] DATABASE: S3 metadata saved successfully for record ' . $current_id . PHP_EOL, FILE_APPEND);
|
||
$log->debug("S3 metadata saved for record $current_id: bucket=" . $s3_metadata['bucket'] . ", key=" . $s3_metadata['key']);
|
||
} else {
|
||
// Local storage fallback - save traditional metadata
|
||
file_put_contents('logs/debug.log', '[' . date('Y-m-d H:i:s') . '] DATABASE: Using local storage fallback for record ' . $current_id . PHP_EOL, FILE_APPEND);
|
||
$upload_file_path = decideFilePath();
|
||
$encryptFileName = Vtiger_Util_Helper::getEncryptedFileName($binFile);
|
||
$sql2 = "INSERT INTO vtiger_attachments(attachmentsid, name, description, type, path, storedname) values(?, ?, ?, ?, ?, ?)";
|
||
$params2 = array($current_id, $filename, $this->column_fields['description'], $filetype, $upload_file_path, $encryptFileName);
|
||
$result2 = $adb->pquery($sql2, $params2);
|
||
file_put_contents('logs/debug.log', '[' . date('Y-m-d H:i:s') . '] DATABASE: vtiger_attachments INSERT result=' . ($result2 ? 'SUCCESS' : 'FAILED') . PHP_EOL, FILE_APPEND);
|
||
|
||
|
||
$log->debug("Local storage metadata saved for record $id");
|
||
}
|
||
|
||
//Add relation
|
||
file_put_contents('logs/debug.log', '[' . date('Y-m-d H:i:s') . '] DATABASE: Adding relation between record ' . $id . ' and attachment ' . $current_id . PHP_EOL, FILE_APPEND);
|
||
$sql3 = 'INSERT INTO vtiger_seattachmentsrel VALUES(?,?)';
|
||
$params3 = array($id, $current_id);
|
||
$result3 = $adb->pquery($sql3, $params3);
|
||
file_put_contents('logs/debug.log', '[' . date('Y-m-d H:i:s') . '] DATABASE: vtiger_seattachmentsrel INSERT result=' . ($result3 ? 'SUCCESS' : 'FAILED') . PHP_EOL, FILE_APPEND);
|
||
|
||
// Commit transaction after all operations
|
||
$adb->query("COMMIT");
|
||
file_put_contents('logs/debug.log', '[' . date('Y-m-d H:i:s') . '] DATABASE: Transaction committed after all operations for record ' . $current_id . PHP_EOL, FILE_APPEND);
|
||
|
||
file_put_contents('logs/debug.log', '[' . date('Y-m-d H:i:s') . '] DATABASE: File upload process completed successfully for record ' . $current_id . PHP_EOL, FILE_APPEND);
|
||
return $current_id;
|
||
} else {
|
||
//failed to upload file
|
||
return false;
|
||
}
|
||
}
|
||
|
||
/** Function to insert values in the vtiger_crmentity for the specified module
|
||
* @param $module -- module:: Type varchar
|
||
*/
|
||
function insertIntoCrmEntity($module, $fileid = '') {
|
||
global $adb;
|
||
global $current_user;
|
||
global $log;
|
||
|
||
if ($fileid != '') {
|
||
$this->id = $fileid;
|
||
$this->mode = 'edit';
|
||
}
|
||
|
||
$date_var = date("Y-m-d H:i:s");
|
||
|
||
$ownerid = $this->column_fields['assigned_user_id'];
|
||
$groupid = $this->column_fields['group_id'];
|
||
|
||
if (empty($groupid))
|
||
$groupid = 0;
|
||
|
||
|
||
if (empty($ownerid)) {
|
||
$ownerid = $current_user->id;
|
||
}
|
||
|
||
if ($module == 'Events') {
|
||
$module = 'Calendar';
|
||
}
|
||
|
||
// SalesPlatform.ru begin Fix owner for outgoing calls
|
||
if($module == 'PBXManager') {
|
||
$currentUser = Users_Record_Model::getCurrentUserModel();
|
||
$current_user->id = $currentUser->getId();
|
||
}
|
||
// SalesPlatform.ru end
|
||
|
||
if ($this->mode == 'edit') {
|
||
$description_val = from_html($this->column_fields['description'], ($insertion_mode == 'edit') ? true : false);
|
||
|
||
$tabid = getTabid($module);
|
||
$modified_date_var = $adb->formatDate($date_var, true);
|
||
if(self::isTimeStampNoChangeMode()) {
|
||
if(!empty($this->column_fields['modifiedtime'])) {
|
||
$modified_date_var = $adb->formatDate($this->column_fields['modifiedtime'], true);
|
||
}
|
||
}
|
||
|
||
$acl = Vtiger_AccessControl::loadUserPrivileges($current_user->id);
|
||
if ($acl->is_admin == true || $acl->profileGlobalPermission[1] == 0 || $acl->profileGlobalPermission[2] == 0 || $this->isWorkFlowFieldUpdate) {
|
||
$sql = "update vtiger_crmentity set smownerid=?, smgroupid=?,modifiedby=?,description=?, modifiedtime=? where crmid=?";
|
||
$params = array($ownerid, $groupid, $current_user->id, $description_val, $adb->formatDate($date_var, true), $this->id);
|
||
} else {
|
||
$profileList = getCurrentUserProfileList();
|
||
$perm_qry = "SELECT columnname FROM vtiger_field INNER JOIN vtiger_profile2field ON vtiger_profile2field.fieldid = vtiger_field.fieldid INNER JOIN vtiger_def_org_field ON vtiger_def_org_field.fieldid = vtiger_field.fieldid WHERE vtiger_field.tabid = ? AND vtiger_profile2field.visible = 0 AND vtiger_profile2field.readonly = 0 AND vtiger_profile2field.profileid IN (" . generateQuestionMarks($profileList) . ") AND vtiger_def_org_field.visible = 0 and vtiger_field.tablename='vtiger_crmentity' and vtiger_field.displaytype in (1,3) and vtiger_field.presence in (0,2);";
|
||
$perm_result = $adb->pquery($perm_qry, array($tabid, $profileList));
|
||
$perm_rows = $adb->num_rows($perm_result);
|
||
for ($i = 0; $i < $perm_rows; $i++) {
|
||
$columname[] = $adb->query_result($perm_result, $i, "columnname");
|
||
}
|
||
if (is_array($columname) && in_array("description", $columname)) {
|
||
$sql = "update vtiger_crmentity set smownerid=?, smgroupid=?, modifiedby=?,description=?, modifiedtime=? where crmid=?";
|
||
$params = array($ownerid, $groupid, $current_user->id, $description_val, $adb->formatDate($date_var, true), $this->id);
|
||
} else {
|
||
$sql = "update vtiger_crmentity set smownerid=?, smgroupid=?,modifiedby=?, modifiedtime=? where crmid=?";
|
||
$params = array($ownerid, $groupid, $current_user->id, $adb->formatDate($date_var, true), $this->id);
|
||
}
|
||
}
|
||
$adb->pquery($sql, $params);
|
||
$this->column_fields['modifiedtime'] = $modified_date_var;
|
||
$this->column_fields['modifiedby'] = $current_user->id;
|
||
} else {
|
||
//if this is the create mode and the group allocation is chosen, then do the following
|
||
$current_id = $adb->getUniqueID("vtiger_crmentity");
|
||
$_REQUEST['currentid'] = $current_id;
|
||
if ($current_user->id == '')
|
||
$current_user->id = 0;
|
||
|
||
|
||
// Customization
|
||
$created_date_var = $adb->formatDate($date_var, true);
|
||
$modified_date_var = $adb->formatDate($date_var, true);
|
||
|
||
// Preserve the timestamp
|
||
if (self::isBulkSaveMode()) {
|
||
if (!empty($this->column_fields['createdtime']))
|
||
$created_date_var = $adb->formatDate($this->column_fields['createdtime'], true);
|
||
//NOTE : modifiedtime ignored to support vtws_sync API track changes.
|
||
}
|
||
// END
|
||
|
||
if ($this->column_fields['source'] != null && $this->column_fields['source'] != " ") {
|
||
$source = strtoupper($this->column_fields['source']);
|
||
} else {
|
||
$source = strtoupper($this->recordSource);
|
||
}
|
||
|
||
$description_val = from_html($this->column_fields['description'], ($insertion_mode == 'edit') ? true : false);
|
||
$sql = "insert into vtiger_crmentity (crmid,smcreatorid,smownerid,smgroupid,setype,description,modifiedby,createdtime,modifiedtime,source) values(?,?,?,?,?,?,?,?,?,?)";
|
||
$params = array($current_id, $current_user->id, $ownerid, $groupid, $module, $description_val, $current_user->id, $created_date_var, $modified_date_var,$source);
|
||
$adb->pquery($sql, $params);
|
||
|
||
$this->column_fields['createdtime'] = $created_date_var;
|
||
$this->column_fields['modifiedtime'] = $modified_date_var;
|
||
$this->column_fields['modifiedby'] = $current_user->id;
|
||
//$this->column_fields['created_user_id'] = $current_user->id;
|
||
$this->id = $current_id;
|
||
}
|
||
}
|
||
|
||
// Function which returns the value based on result type (array / ADODB ResultSet)
|
||
private function resolve_query_result_value($result, $index, $columnname) {
|
||
global $adb;
|
||
if (is_array($result))
|
||
return $result[$index][$columnname];
|
||
else
|
||
return $adb->query_result($result, $index, $columnname);
|
||
}
|
||
|
||
/** Function to insert values in the specifed table for the specified module
|
||
* @param $table_name -- table name:: Type varchar
|
||
* @param $module -- module:: Type varchar
|
||
*/
|
||
function insertIntoEntityTable($table_name, $module, $fileid = '') {
|
||
global $log;
|
||
global $current_user, $app_strings;
|
||
$log->info("function insertIntoEntityTable " . $module . ' vtiger_table name ' . $table_name);
|
||
global $adb;
|
||
$insertion_mode = $this->mode;
|
||
$table_name = Vtiger_Util_Helper::validateStringForSql($table_name);
|
||
|
||
//Checkin whether an entry is already is present in the vtiger_table to update
|
||
if ($insertion_mode == 'edit') {
|
||
$tablekey = $this->tab_name_index[$table_name];
|
||
// Make selection on the primary key of the module table to check.
|
||
$check_query = "select $tablekey from $table_name where $tablekey=?";
|
||
$check_params = array($this->id);
|
||
if (Vtiger_Functions::isUserSpecificFieldTable($table_name, $module)) {
|
||
$check_query .= ' AND userid=?';
|
||
array_push($check_params, $current_user->id);
|
||
}
|
||
$check_result = $adb->pquery($check_query, $check_params);
|
||
|
||
$num_rows = $adb->num_rows($check_result);
|
||
|
||
if ($num_rows <= 0) {
|
||
$insertion_mode = '';
|
||
}
|
||
}
|
||
|
||
$tabid = getTabid($module);
|
||
if ($module == 'Calendar' && $this->column_fields["activitytype"] != null && $this->column_fields["activitytype"] != 'Task') {
|
||
$tabid = getTabid('Events');
|
||
}
|
||
if ($insertion_mode == 'edit') {
|
||
$update = array();
|
||
$update_params = array();
|
||
$updateColumnNames = array();
|
||
$updateFieldNameColumnNameMap = array();
|
||
$acl = Vtiger_AccessControl::loadUserPrivileges($current_user->id);
|
||
if ($acl->is_admin == true || $acl->profileGlobalPermission[1] == 0 || $acl->profileGlobalPermission[2] == 0 || $this->isWorkFlowFieldUpdate) {
|
||
$sql = "select fieldname,columnname,uitype,generatedtype,
|
||
typeofdata from vtiger_field where tabid in (" . generateQuestionMarks($tabid) . ") and tablename=? and displaytype in (1,3,6) and presence in (0,2) group by columnname";
|
||
$params = array($tabid, $table_name);
|
||
} else {
|
||
$profileList = getCurrentUserProfileList();
|
||
|
||
if (count($profileList) > 0) {
|
||
$sql = "SELECT vtiger_field.fieldname,vtiger_field.columnname,vtiger_field.uitype,vtiger_field.generatedtype,vtiger_field.typeofdata FROM vtiger_field
|
||
INNER JOIN vtiger_profile2field
|
||
ON vtiger_profile2field.fieldid = vtiger_field.fieldid
|
||
INNER JOIN vtiger_def_org_field
|
||
ON vtiger_def_org_field.fieldid = vtiger_field.fieldid
|
||
WHERE vtiger_field.tabid = ?
|
||
AND vtiger_profile2field.visible = 0 AND vtiger_profile2field.readonly = 0
|
||
AND vtiger_profile2field.profileid IN (" . generateQuestionMarks($profileList) . ")
|
||
AND vtiger_def_org_field.visible = 0 and vtiger_field.tablename=? and vtiger_field.displaytype in (1,3,6) and vtiger_field.presence in (0,2) group by columnname";
|
||
|
||
$params = array($tabid, $profileList, $table_name);
|
||
} else {
|
||
$sql = "SELECT vtiger_field.fieldname,vtiger_field.columnname,vtiger_field.uitype,vtiger_field.generatedtype,vtiger_field.typeofdata FROM vtiger_field
|
||
INNER JOIN vtiger_profile2field
|
||
ON vtiger_profile2field.fieldid = vtiger_field.fieldid
|
||
INNER JOIN vtiger_def_org_field
|
||
ON vtiger_def_org_field.fieldid = vtiger_field.fieldid
|
||
WHERE vtiger_field.tabid = ?
|
||
AND vtiger_profile2field.visible = 0 AND vtiger_profile2field.readonly = 0
|
||
AND vtiger_def_org_field.visible = 0 and vtiger_field.tablename=? and vtiger_field.displaytype in (1,3,6) and vtiger_field.presence in (0,2) group by columnname";
|
||
|
||
$params = array($tabid, $table_name);
|
||
}
|
||
}
|
||
} else {
|
||
$table_index_column = $this->tab_name_index[$table_name];
|
||
if ($table_index_column == 'id' && $table_name == 'vtiger_users') {
|
||
$currentuser_id = $adb->getUniqueID("vtiger_users");
|
||
$this->id = $currentuser_id;
|
||
}
|
||
$column = array($table_index_column);
|
||
$value = array($this->id);
|
||
if (Vtiger_Functions::isUserSpecificFieldTable($table_name, $module)) {
|
||
array_push($column, 'userid');
|
||
array_push($value, $current_user->id);
|
||
}
|
||
$sql = "select fieldname,columnname,uitype,generatedtype,typeofdata from vtiger_field where tabid=? and tablename=? and displaytype in (1,3,4,6) and vtiger_field.presence in (0,2)";
|
||
$params = array($tabid, $table_name);
|
||
}
|
||
|
||
// Attempt to re-use the quer-result to avoid reading for every save operation
|
||
// TODO Need careful analysis on impact ... MEMORY requirement might be more
|
||
static $_privatecache = array();
|
||
|
||
$cachekey = "{$insertion_mode}-" . implode(',', $params);
|
||
|
||
if (!isset($_privatecache[$cachekey])) {
|
||
$result = $adb->pquery($sql, $params);
|
||
$noofrows = $adb->num_rows($result);
|
||
|
||
if (CRMEntity::isBulkSaveMode()) {
|
||
$cacheresult = array();
|
||
for ($i = 0; $i < $noofrows; ++$i) {
|
||
$cacheresult[] = $adb->fetch_array($result);
|
||
}
|
||
$_privatecache[$cachekey] = $cacheresult;
|
||
}
|
||
} else { // Useful when doing bulk save
|
||
$result = $_privatecache[$cachekey];
|
||
$noofrows = count($result);
|
||
}
|
||
|
||
for ($i = 0; $i < $noofrows; $i++) {
|
||
|
||
$fieldname = $this->resolve_query_result_value($result, $i, "fieldname");
|
||
$columname = $this->resolve_query_result_value($result, $i, "columnname");
|
||
$uitype = $this->resolve_query_result_value($result, $i, "uitype");
|
||
$generatedtype = $this->resolve_query_result_value($result, $i, "generatedtype");
|
||
$typeofdata = $this->resolve_query_result_value($result, $i, "typeofdata");
|
||
$skipUpdateForField = false;
|
||
$typeofdata_array = explode("~", $typeofdata);
|
||
$datatype = $typeofdata_array[0];
|
||
|
||
$ajaxSave = false;
|
||
if (($_REQUEST['file'] == 'DetailViewAjax' && $_REQUEST['ajxaction'] == 'DETAILVIEW'
|
||
&& isset($_REQUEST["fldName"]) && $_REQUEST["fldName"] != $fieldname)
|
||
|| ($_REQUEST['action'] == 'MassEditSave' && !isset($_REQUEST[$fieldname."_mass_edit_check"]))) {
|
||
$ajaxSave = true;
|
||
}
|
||
|
||
if ($uitype == 4 && $insertion_mode != 'edit') {
|
||
$fldvalue = '';
|
||
// Bulk Save Mode: Avoid generation of module sequence number, take care later.
|
||
// SalesPlatform.ru begin: Added separate numbering for self organizations
|
||
if (!CRMEntity::isBulkSaveMode()) {
|
||
$modules = array('Invoice', 'Act', 'Consignment');
|
||
if (in_array($module, $modules) && isset($this->column_fields['spcompany'])) {
|
||
$fldvalue = $this->setModuleSeqNumber("increment", $module, '', '', $this->column_fields['spcompany']);
|
||
} else {
|
||
$fldvalue = $this->setModuleSeqNumber("increment", $module);
|
||
}
|
||
//$fldvalue = $this->setModuleSeqNumber("increment", $module);
|
||
}
|
||
// SalesPlatform.ru end
|
||
$this->column_fields[$fieldname] = $fldvalue;
|
||
}
|
||
if (isset($this->column_fields[$fieldname])) {
|
||
if ($uitype == 56) {
|
||
if ($this->column_fields[$fieldname] === 'on' || $this->column_fields[$fieldname] == 1) {
|
||
$fldvalue = '1';
|
||
} else {
|
||
$fldvalue = '0';
|
||
}
|
||
} elseif ($uitype == 15 || $uitype == 16) {
|
||
|
||
if ($this->column_fields[$fieldname] == $app_strings['LBL_NOT_ACCESSIBLE']) {
|
||
|
||
//If the value in the request is Not Accessible for a picklist, the existing value will be replaced instead of Not Accessible value.
|
||
$sql = "select $columname from $table_name where " . $this->tab_name_index[$table_name] . "=?";
|
||
$res = $adb->pquery($sql, array($this->id));
|
||
$pick_val = $adb->query_result($res, 0, $columname);
|
||
$fldvalue = $pick_val;
|
||
} else {
|
||
$fldvalue = $this->column_fields[$fieldname];
|
||
}
|
||
} elseif ($uitype == 33) {
|
||
if (is_array($this->column_fields[$fieldname])) {
|
||
$field_list = implode(' |##| ', $this->column_fields[$fieldname]);
|
||
} else {
|
||
$field_list = $this->column_fields[$fieldname];
|
||
}
|
||
$fldvalue = $field_list;
|
||
} elseif ($uitype == 5 || $uitype == 6 || $uitype == 23) {
|
||
//Added to avoid function call getDBInsertDateValue in ajax save
|
||
if (isset($current_user->date_format) && !$ajaxSave) {
|
||
$fldvalue = getValidDBInsertDateValue($this->column_fields[$fieldname]);
|
||
} else {
|
||
$fldvalue = $this->column_fields[$fieldname];
|
||
}
|
||
} elseif ($uitype == 7) {
|
||
//strip out the spaces and commas in numbers if given ie., in amounts there may be ,
|
||
$fldvalue = str_replace(",", "", $this->column_fields[$fieldname]); //trim($this->column_fields[$fieldname],",");
|
||
if (in_array($datatype, array('N', 'NN'))) {
|
||
$fldvalue = CurrencyField::convertToDBFormat($this->column_fields[$fieldname], $current_user, true);
|
||
}
|
||
} elseif ($uitype == 1 && in_array($datatype, array('N', 'NN')) && in_array($fieldname, array('qty_per_unit','qtyinstock','salescommission','exciseduty'))) {
|
||
$fldvalue = CurrencyField::convertToDBFormat($this->column_fields[$fieldname], $current_user, true);
|
||
} elseif ($uitype == 26) {
|
||
if (empty($this->column_fields[$fieldname])) {
|
||
$fldvalue = 1; //the documents will stored in default folder
|
||
} else {
|
||
$fldvalue = $this->column_fields[$fieldname];
|
||
}
|
||
} elseif ($uitype == 28) {
|
||
if ($this->column_fields[$fieldname] == null) {
|
||
$fileQuery = $adb->pquery("SELECT filename from vtiger_notes WHERE notesid = ?", array($this->id));
|
||
$fldvalue = null;
|
||
if (isset($fileQuery)) {
|
||
$rowCount = $adb->num_rows($fileQuery);
|
||
if ($rowCount > 0) {
|
||
$fldvalue = decode_html($adb->query_result($fileQuery, 0, 'filename'));
|
||
}
|
||
}
|
||
} else {
|
||
$fldvalue = decode_html($this->column_fields[$fieldname]);
|
||
}
|
||
} elseif ($uitype == 8) {
|
||
$this->column_fields[$fieldname] = rtrim($this->column_fields[$fieldname], ',');
|
||
$ids = explode(',', $this->column_fields[$fieldname]);
|
||
$json = new Zend_Json();
|
||
$fldvalue = $json->encode($ids);
|
||
} elseif ($uitype == 12) {
|
||
|
||
// Bulk Sae Mode: Consider the FROM email address as specified, if not lookup
|
||
$fldvalue = $this->column_fields[$fieldname];
|
||
|
||
if (empty($fldvalue)) {
|
||
$query = "SELECT email1 FROM vtiger_users WHERE id = ?";
|
||
$res = $adb->pquery($query, array($current_user->id));
|
||
$rows = $adb->num_rows($res);
|
||
if ($rows > 0) {
|
||
$fldvalue = $adb->query_result($res, 0, 'email1');
|
||
}
|
||
}
|
||
// END
|
||
} elseif ($uitype == 72 && !$ajaxSave) {
|
||
// Some of the currency fields like Unit Price, Totoal , Sub-total - doesn't need currency conversion during save
|
||
$fldvalue = CurrencyField::convertToDBFormat($this->column_fields[$fieldname], null, true);
|
||
} elseif ($uitype == 71 && !$ajaxSave) {
|
||
$fldvalue = CurrencyField::convertToDBFormat($this->column_fields[$fieldname]);
|
||
} elseif ($uitype == 69) {
|
||
$fldvalue = $this->column_fields[$fieldname];
|
||
if(count($_FILES)) {
|
||
$IMG_FILES = $_FILES[$fieldname];
|
||
if($_REQUEST['action'] == 'MassSave' || $_REQUEST['action'] == 'MassEditSave') {
|
||
if($IMG_FILES[0]['error'] == 0) {
|
||
$oldImageAttachmentIds = array();
|
||
$oldAttachmentsRes = $adb->pquery('SELECT vtiger_seattachmentsrel.attachmentsid FROM vtiger_seattachmentsrel
|
||
INNER JOIN vtiger_attachments ON vtiger_seattachmentsrel.attachmentsid = vtiger_attachments.attachmentsid
|
||
INNER JOIN vtiger_crmentity ON vtiger_crmentity.crmid = vtiger_attachments.attachmentsid AND setype = ?
|
||
WHERE vtiger_seattachmentsrel.crmid = ?',array($module.' Image',$this->id));
|
||
for($itr = 0;$itr < $adb->num_rows($oldAttachmentsRes);$itr++) {
|
||
$oldImageAttachmentIds[] = $adb->query_result($oldAttachmentsRes,$itr,'attachmentsid');
|
||
}
|
||
if(count($oldImageAttachmentIds)) {
|
||
$adb->pquery('DELETE FROM vtiger_seattachmentsrel WHERE attachmentsid IN ('.generateQuestionMarks($oldImageAttachmentIds).')',$oldImageAttachmentIds);
|
||
$adb->pquery('DELETE FROM vtiger_attachments WHERE attachmentsid IN ('.generateQuestionMarks($oldImageAttachmentIds).')',$oldImageAttachmentIds);
|
||
$adb->pquery('DELETE FROM vtiger_crmentity WHERE crmid IN ('.generateQuestionMarks($oldImageAttachmentIds).')',$oldImageAttachmentIds);
|
||
}
|
||
}
|
||
}
|
||
$uploadedFileNames = array();
|
||
if(count($IMG_FILES)){
|
||
foreach($IMG_FILES as $fileIndex => $file) {
|
||
if($file['error'] == 0 && $file['name'] != '' && $file['size'] > 0) {
|
||
if($_REQUEST[$fileIndex.'_hidden'] != '')
|
||
$file['original_name'] = vtlib_purify($_REQUEST[$fileindex.'_hidden']);
|
||
else {
|
||
$file['original_name'] = stripslashes($file['name']);
|
||
}
|
||
$file['original_name'] = str_replace('"','',$file['original_name']);
|
||
$attachmentId = $this->uploadAndSaveFile($this->id,$module,$file,'Image');
|
||
if($attachmentId) {
|
||
$uploadedFileNames[] = $file['name'];
|
||
}
|
||
}
|
||
}
|
||
}
|
||
if(count($uploadedFileNames)) {
|
||
$fldvalue = implode(',',$uploadedFileNames);
|
||
} else {
|
||
$skipUpdateForField = true;
|
||
}
|
||
}
|
||
if (($insertion_mode == 'edit' && $skipUpdateForField == false) || $_REQUEST['imgDeleted']) {
|
||
$skipUpdateForField = false;
|
||
$uploadedFileNames = array();
|
||
$getImageNamesSql = 'SELECT name FROM vtiger_seattachmentsrel INNER JOIN vtiger_attachments ON
|
||
vtiger_seattachmentsrel.attachmentsid = vtiger_attachments.attachmentsid LEFT JOIN '.$table_name.' ON '.
|
||
$table_name.'.'.$tablekey.' = vtiger_seattachmentsrel.crmid WHERE vtiger_seattachmentsrel.crmid = ?';
|
||
$imageNamesRes = $adb->pquery($getImageNamesSql,array($this->id));
|
||
$numOfRows = $adb->num_rows($imageNamesRes);
|
||
for($imgItr = 0;$imgItr < $numOfRows;$imgItr++) {
|
||
$imageName = $adb->query_result($imageNamesRes,$imgItr,'name');
|
||
array_push($uploadedFileNames, decode_html($imageName));
|
||
}
|
||
$fldvalue = implode(',',$uploadedFileNames);
|
||
}
|
||
}elseif ($uitype == 61 && count($_FILES)) {
|
||
if($module == "ModComments") {
|
||
$UPLOADED_FILES = $_FILES[$fieldname];
|
||
foreach($UPLOADED_FILES as $fileIndex => $file) {
|
||
if($file['error'] == 0 && $file['name'] != '' && $file['size'] > 0) {
|
||
if($_REQUEST[$fileindex.'_hidden'] != '') {
|
||
$file['original_name'] = vtlib_purify($_REQUEST[$fileindex.'_hidden']);
|
||
} else {
|
||
$file['original_name'] = stripslashes($file['name']);
|
||
}
|
||
$file['original_name'] = str_replace('"','',$file['original_name']);
|
||
$attachmentId = $this->uploadAndSaveFile($this->id,$module,$file);
|
||
if($attachmentId) {
|
||
$uploadedFileNames[] = $attachmentId;
|
||
}
|
||
}
|
||
}
|
||
if(count($uploadedFileNames)) {
|
||
$fldvalue = implode(',',$uploadedFileNames);
|
||
} else {
|
||
$skipUpdateForField = true;
|
||
}
|
||
} else {
|
||
$file = $_FILES[$fieldname];
|
||
if($file['error'] == 0 && $file['name'] != '' && $file['size'] > 0) {
|
||
$attachmentId = $this->uploadAndSaveFile($this->id,$module,$file);
|
||
if($attachmentId) $fldvalue = $attachmentId;
|
||
} else {
|
||
$skipUpdateForField = true;
|
||
}
|
||
}
|
||
} else {
|
||
$fldvalue = $this->column_fields[$fieldname];
|
||
}
|
||
if ($uitype != 33 && $uitype != 8)
|
||
$fldvalue = from_html($fldvalue, ($insertion_mode == 'edit') ? true : false);
|
||
} else {
|
||
$fldvalue = '';
|
||
}
|
||
if ($fldvalue == '') {
|
||
$fldvalue = $this->get_column_value($columname, $fldvalue, $fieldname, $uitype, $datatype);
|
||
}
|
||
|
||
if ($insertion_mode == 'edit') {
|
||
if ($uitype != 4 && !$skipUpdateForField) {
|
||
array_push($update, $columname . "=?");
|
||
array_push($update_params, $fldvalue);
|
||
array_push($updateColumnNames, $columname);
|
||
$updateFieldNameColumnNameMap[$fieldname]=$columname;
|
||
}
|
||
} else {
|
||
array_push($column, $columname);
|
||
array_push($value, $fldvalue);
|
||
}
|
||
}
|
||
|
||
if ($insertion_mode == 'edit') {
|
||
//Track the update and update only when needed - vikas
|
||
$updateFieldValues = @array_combine($updateColumnNames, $update_params);
|
||
$changedFields = $this->column_fields->getChanged();
|
||
if(count($changedFields) > 0) {
|
||
$update = array();
|
||
$update_params = array();
|
||
foreach($changedFields as $field) {
|
||
$fieldColumn = $updateFieldNameColumnNameMap[$field];
|
||
if(@array_key_exists($fieldColumn, $updateFieldValues)) {
|
||
array_push($update, $fieldColumn.'=?');
|
||
array_push($update_params, $updateFieldValues[$fieldColumn]);
|
||
}
|
||
}
|
||
}
|
||
// SalesPlatform.ru begin
|
||
if ($module == 'Potentials') {
|
||
$dbquery = 'select sales_stage from vtiger_potential where potentialid = ?';
|
||
$sales_stage = $adb->query_result($adb->pquery($dbquery, array($this->id)), 0, 'sales_stage');
|
||
if ($sales_stage != $_REQUEST['sales_stage'] && $_REQUEST['sales_stage'] != '') {
|
||
$date_var = date("Y-m-d H:i:s");
|
||
$closingDateField = new DateTimeField($this->column_fields['closingdate']);
|
||
$closingdate = ($_REQUEST['ajxaction'] == 'DETAILVIEW') ? $this->column_fields['closingdate'] : $closingDateField->getDBInsertDateValue();
|
||
$sql = "insert into vtiger_potstagehistory values(?,?,?,?,?,?,?,?)";
|
||
$params = array('', $this->id, $this->column_fields['amount'], decode_html($sales_stage), $this->column_fields['probability'], 0, $adb->formatDate($closingdate, true), $adb->formatDate($date_var, true));
|
||
$adb->pquery($sql, $params);
|
||
}
|
||
}
|
||
// SalesPlatform.ru begin Added Acts and Consignments
|
||
elseif ($module == 'PurchaseOrder' || $module == 'SalesOrder' || $module == 'Quotes' || $module == 'Invoice' || $module == 'Act' || $module == 'Consignment') {
|
||
//elseif ($module == 'PurchaseOrder' || $module == 'SalesOrder' || $module == 'Quotes' || $module == 'Invoice') {
|
||
// SalesPlatform.ru end
|
||
//added to update the history for PO, SO, Quotes and Invoice
|
||
$history_field_array = Array(
|
||
// SalesPlatform.ru begin: Added acts and consignments
|
||
"Act" => "sp_actstatus",
|
||
"Consignment" => "sp_consignmentstatus",
|
||
// SalesPlatform.ru end
|
||
"PurchaseOrder" => "postatus",
|
||
"SalesOrder" => "sostatus",
|
||
"Quotes" => "quotestage",
|
||
"Invoice" => "invoicestatus"
|
||
);
|
||
|
||
$inventory_module = $module;
|
||
|
||
if ($_REQUEST['ajxaction'] == 'DETAILVIEW') {//if we use ajax edit
|
||
if ($inventory_module == "PurchaseOrder")
|
||
$relatedname = getVendorName($this->column_fields['vendor_id']);
|
||
else
|
||
$relatedname = getAccountName($this->column_fields['account_id']);
|
||
|
||
$total = $this->column_fields['hdnGrandTotal'];
|
||
}
|
||
else {//using edit button and save
|
||
if ($inventory_module == "PurchaseOrder")
|
||
$relatedname = $_REQUEST["vendor_name"];
|
||
else
|
||
$relatedname = $_REQUEST["account_name"];
|
||
|
||
$total = $_REQUEST['total'];
|
||
}
|
||
|
||
if ($this->column_fields["$history_field_array[$inventory_module]"] == $app_strings['LBL_NOT_ACCESSIBLE']) {
|
||
|
||
//If the value in the request is Not Accessible for a picklist, the existing value will be replaced instead of Not Accessible value.
|
||
$his_col = $history_field_array[$inventory_module];
|
||
$his_sql = "select $his_col from $this->table_name where " . $this->table_index . "=?";
|
||
$his_res = $adb->pquery($his_sql, array($this->id));
|
||
$status_value = $adb->query_result($his_res, 0, $his_col);
|
||
$stat_value = $status_value;
|
||
} else {
|
||
$stat_value = $this->column_fields["$history_field_array[$inventory_module]"];
|
||
}
|
||
$oldvalue = getSingleFieldValue($this->table_name, $history_field_array[$inventory_module], $this->table_index, $this->id);
|
||
if ($this->column_fields["$history_field_array[$inventory_module]"] != '' && $oldvalue != $stat_value) {
|
||
addInventoryHistory($inventory_module, $this->id, $relatedname, $total, $stat_value);
|
||
}
|
||
}
|
||
// SalesPlatform.ru end
|
||
if (count($update) > 0) {
|
||
$sql1 = "UPDATE $table_name SET " . implode(",", $update) . " WHERE " . $this->tab_name_index[$table_name] . "=?";
|
||
array_push($update_params, $this->id);
|
||
if (Vtiger_Functions::isUserSpecificFieldTable($table_name, $module)) {
|
||
$sql1 .= ' AND userid = ?';
|
||
array_push($update_params, $current_user->id);
|
||
}
|
||
$adb->pquery($sql1, $update_params);
|
||
}
|
||
} else {
|
||
$sql1 = "insert into $table_name(" . implode(",", $column) . ") values(" . generateQuestionMarks($value) . ")";
|
||
$adb->pquery($sql1, $value);
|
||
}
|
||
}
|
||
|
||
/** Function to delete a record in the specifed table
|
||
* @param $table_name -- table name:: Type varchar
|
||
* The function will delete a record .The id is obtained from the class variable $this->id and the columnname got from $this->tab_name_index[$table_name]
|
||
*/
|
||
function deleteRelation($table_name) {
|
||
global $adb;
|
||
$table_name = Vtiger_Util_Helper::validateStringForSql($table_name);
|
||
$check_query = "select * from $table_name where " . $this->tab_name_index[$table_name] . "=?";
|
||
$check_result = $adb->pquery($check_query, array($this->id));
|
||
$num_rows = $adb->num_rows($check_result);
|
||
|
||
if ($num_rows == 1) {
|
||
$del_query = "DELETE from $table_name where " . $this->tab_name_index[$table_name] . "=?";
|
||
$adb->pquery($del_query, array($this->id));
|
||
}
|
||
}
|
||
|
||
/** Function to attachment filename of the given entity
|
||
* @param $notesid -- crmid:: Type Integer
|
||
* The function will get the attachmentsid for the given entityid from vtiger_seattachmentsrel table and get the attachmentsname from vtiger_attachments table
|
||
* returns the 'filename'
|
||
*/
|
||
function getOldFileName($notesid) {
|
||
global $log;
|
||
$log->info("in getOldFileName " . $notesid);
|
||
global $adb;
|
||
$query1 = "select * from vtiger_seattachmentsrel where crmid=?";
|
||
$result = $adb->pquery($query1, array($notesid));
|
||
$noofrows = $adb->num_rows($result);
|
||
if ($noofrows != 0)
|
||
$attachmentid = $adb->query_result($result, 0, 'attachmentsid');
|
||
if ($attachmentid != '') {
|
||
$query2 = "select * from vtiger_attachments where attachmentsid=?";
|
||
$filename = $adb->query_result($adb->pquery($query2, array($attachmentid)), 0, 'name');
|
||
}
|
||
return $filename;
|
||
}
|
||
|
||
/**
|
||
* Function returns the column alias for a field
|
||
* @param <Array> $fieldinfo - field information
|
||
* @return <String> field value
|
||
*/
|
||
protected function createColumnAliasForField($fieldinfo) {
|
||
return strtolower($fieldinfo['tablename'] . $fieldinfo['fieldname']);
|
||
}
|
||
|
||
/**
|
||
* Retrieve record information of the module
|
||
* @param <Integer> $record - crmid of record
|
||
* @param <String> $module - module name
|
||
*/
|
||
function retrieve_entity_info($record, $module, $allowDeleted = false) {
|
||
global $adb, $log, $app_strings, $current_user;
|
||
|
||
// INNER JOIN is desirable if all dependent table has entries for the record.
|
||
// LEFT JOIN is desired if the dependent tables does not have entry.
|
||
$join_type = 'LEFT JOIN';
|
||
|
||
// Tables which has multiple rows for the same record
|
||
// will be skipped in record retrieve - need to be taken care separately.
|
||
$multirow_tables = NULL;
|
||
if (isset($this->multirow_tables)) {
|
||
$multirow_tables = $this->multirow_tables;
|
||
} else {
|
||
$multirow_tables = array(
|
||
'vtiger_campaignrelstatus',
|
||
'vtiger_attachments',
|
||
//'vtiger_inventoryproductrel',
|
||
//'vtiger_cntactivityrel',
|
||
'vtiger_email_track'
|
||
);
|
||
}
|
||
|
||
// Lookup module field cache
|
||
if($module == 'Calendar' || $module == 'Events') {
|
||
getColumnFields('Calendar');
|
||
$cachedEventsFields = VTCacheUtils::lookupFieldInfo_Module('Events');
|
||
$cachedCalendarFields = VTCacheUtils::lookupFieldInfo_Module('Calendar');
|
||
$cachedModuleFields = array_merge($cachedEventsFields, $cachedCalendarFields);
|
||
} else {
|
||
$cachedModuleFields = VTCacheUtils::lookupFieldInfo_Module($module);
|
||
}
|
||
if ($cachedModuleFields === false) {
|
||
// Pull fields and cache for further use
|
||
$tabid = getTabid($module);
|
||
|
||
$sql0 = "SELECT fieldname, fieldid, fieldlabel, columnname, tablename, uitype, typeofdata,presence FROM vtiger_field WHERE tabid=?";
|
||
// NOTE: Need to skip in-active fields which we will be done later.
|
||
$result0 = $adb->pquery($sql0, array($tabid));
|
||
if ($adb->num_rows($result0)) {
|
||
while ($resultrow = $adb->fetch_array($result0)) {
|
||
// Update cache
|
||
VTCacheUtils::updateFieldInfo(
|
||
$tabid, $resultrow['fieldname'], $resultrow['fieldid'], $resultrow['fieldlabel'], $resultrow['columnname'], $resultrow['tablename'], $resultrow['uitype'], $resultrow['typeofdata'], $resultrow['presence']
|
||
);
|
||
}
|
||
// Get only active field information
|
||
$cachedModuleFields = VTCacheUtils::lookupFieldInfo_Module($module);
|
||
}
|
||
}
|
||
|
||
if ($cachedModuleFields) {
|
||
$column_clause = '';
|
||
$from_clause = '';
|
||
$where_clause = '';
|
||
$limit_clause = ' LIMIT 1'; // to eliminate multi-records due to table joins.
|
||
|
||
$params = array();
|
||
$required_tables = $this->tab_name_index; // copies-on-write
|
||
|
||
foreach ($cachedModuleFields as $fieldinfo) {
|
||
if (in_array($fieldinfo['tablename'], $multirow_tables)) {
|
||
continue;
|
||
}
|
||
// Added to avoid picking shipping tax fields for Inventory modules, the shipping tax detail are stored in vtiger_inventoryshippingrel
|
||
// table, but in vtiger_field table we have set tablename as vtiger_inventoryproductrel.
|
||
// SalesPlatform.ru begin Added Acts and Consignments
|
||
if ($fieldinfo['tablename'] == 'vtiger_contacts_user_field') {
|
||
continue;
|
||
}
|
||
// SalesPlatform.ru begin #5342
|
||
// if ($fieldinfo['tablename'] == 'vtiger_invoice_user_field') {
|
||
// $required_tables[$fieldinfo['tablename']] = 'recordid';
|
||
// }
|
||
// SalesPlatform.ru end #5342
|
||
if(($module == 'Invoice' || $module == 'Quotes' || $module == 'SalesOrder' || $module == 'PurchaseOrder' || $module == 'Act' || $module == 'Consignment')
|
||
//if(($module == 'Invoice' || $module == 'Quotes' || $module == 'SalesOrder' || $module == 'PurchaseOrder')
|
||
// SalesPlatform.ru end
|
||
&& stripos($fieldinfo['columnname'], 'shtax') !== false) {
|
||
continue;
|
||
}
|
||
|
||
// Alias prefixed with tablename+fieldname to avoid duplicate column name across tables
|
||
// fieldname are always assumed to be unique for a module
|
||
$column_clause .= $fieldinfo['tablename'].'.'.$fieldinfo['columnname'].' AS '.$this->createColumnAliasForField($fieldinfo).',';
|
||
}
|
||
$column_clause .= 'vtiger_crmentity.deleted, vtiger_crmentity.label';
|
||
|
||
if (isset($required_tables['vtiger_crmentity'])) {
|
||
$from_clause = ' vtiger_crmentity';
|
||
unset($required_tables['vtiger_crmentity']);
|
||
foreach ($required_tables as $tablename => $tableindex) {
|
||
if (in_array($tablename, $multirow_tables)) {
|
||
// Avoid multirow table joins.
|
||
continue;
|
||
}
|
||
$joinCondition = "($tablename.$tableindex = vtiger_crmentity.crmid ";
|
||
if($current_user && Vtiger_Functions::isUserSpecificFieldTable($tablename, $module)) {
|
||
$joinCondition .= " AND $tablename.userid = ".$current_user->id;
|
||
}
|
||
$joinCondition .= " )";
|
||
$from_clause .= sprintf(' %s %s ON %s', $join_type,
|
||
$tablename, $joinCondition);
|
||
}
|
||
}
|
||
|
||
$where_clause .= ' vtiger_crmentity.crmid=?';
|
||
$params[] = $record;
|
||
|
||
$sql = sprintf('SELECT %s FROM %s WHERE %s %s', $column_clause, $from_clause, $where_clause, $limit_clause);
|
||
|
||
$result = $adb->pquery($sql, $params);
|
||
// initialize the object
|
||
$this->column_fields = new TrackableObject();
|
||
|
||
if (!$result || $adb->num_rows($result) < 1) {
|
||
throw new Exception($app_strings['LBL_RECORD_NOT_FOUND'], -1);
|
||
} else {
|
||
$resultrow = $adb->query_result_rowdata($result);
|
||
if (!$allowDeleted) {
|
||
if (!empty($resultrow['deleted'])) {
|
||
throw new Exception($app_strings['LBL_RECORD_DELETE'], 1);
|
||
}
|
||
}
|
||
if(!empty($resultrow['label'])){
|
||
$this->column_fields['label'] = $resultrow['label'];
|
||
} else {
|
||
// added to compute label needed in event handlers
|
||
$entityFields = Vtiger_Functions::getEntityModuleInfo($module);
|
||
if(!empty($entityFields['fieldname'])) {
|
||
$entityFieldNames = explode(',', $entityFields['fieldname']);
|
||
if(count($entityFieldNames) > 1) {
|
||
$this->column_fields['label'] = $resultrow[$entityFields['tablename'].$entityFieldNames[0]].' '.$resultrow[$entityFields['tablename'].$entityFieldNames[1]];
|
||
} else {
|
||
$this->column_fields['label'] = $resultrow[$entityFields['tablename'].$entityFieldNames[0]];
|
||
}
|
||
}
|
||
}
|
||
foreach ($cachedModuleFields as $fieldinfo) {
|
||
$fieldvalue = '';
|
||
$fieldkey = $this->createColumnAliasForField($fieldinfo);
|
||
//Note : value is retrieved with a tablename+fieldname as we are using alias while building query
|
||
if (isset($resultrow[$fieldkey])) {
|
||
$fieldvalue = $resultrow[$fieldkey];
|
||
}
|
||
$this->column_fields[$fieldinfo['fieldname']] = $fieldvalue;
|
||
}
|
||
}
|
||
}
|
||
|
||
//adding tags for vtws_retieve
|
||
$tagsList = Vtiger_Tag_Model::getAllAccessible($current_user->id, $module, $record);
|
||
$tags = array();
|
||
foreach($tagsList as $tag) {
|
||
$tags[] = $tag->getName();
|
||
}
|
||
$this->column_fields['tags'] = (count($tags) > 0) ? implode(',',$tags) : '';
|
||
|
||
$this->column_fields['record_id'] = $record;
|
||
$this->id = $record;
|
||
$this->column_fields['record_module'] = $module;
|
||
$this->column_fields->startTracking();
|
||
}
|
||
|
||
/** Function to saves the values in all the tables mentioned in the class variable $tab_name for the specified module
|
||
* @param $module -- module:: Type varchar
|
||
*/
|
||
function save($module_name, $fileid = '') {
|
||
global $log,$adb;
|
||
$log->debug("module name is " . $module_name);
|
||
|
||
//Event triggering code
|
||
require_once("include/events/include.inc");
|
||
|
||
//In Bulk mode stop triggering events
|
||
if(!self::isBulkSaveMode()) {
|
||
$em = new VTEventsManager($adb);
|
||
// Initialize Event trigger cache
|
||
$em->initTriggerCache();
|
||
$entityData = VTEntityData::fromCRMEntity($this);
|
||
|
||
$em->triggerEvent("vtiger.entity.beforesave.modifiable", $entityData);
|
||
$em->triggerEvent("vtiger.entity.beforesave", $entityData);
|
||
$em->triggerEvent("vtiger.entity.beforesave.final", $entityData);
|
||
}
|
||
//Event triggering code ends
|
||
|
||
//GS Save entity being called with the modulename as parameter
|
||
$this->saveentity($module_name, $fileid);
|
||
|
||
if($em) {
|
||
//Event triggering code
|
||
$em->triggerEvent("vtiger.entity.aftersave", $entityData);
|
||
$em->triggerEvent("vtiger.entity.aftersave.final", $entityData);
|
||
//Event triggering code ends
|
||
}
|
||
}
|
||
|
||
function process_list_query($query, $row_offset, $limit = -1, $max_per_page = -1) {
|
||
global $list_max_entries_per_page;
|
||
$this->log->debug("process_list_query: " . $query);
|
||
if (!empty($limit) && $limit != -1) {
|
||
$result = & $this->db->limitQuery($query, $row_offset + 0, $limit, true, "Error retrieving $this->object_name list: ");
|
||
} else {
|
||
$result = & $this->db->query($query, true, "Error retrieving $this->object_name list: ");
|
||
}
|
||
|
||
$list = Array();
|
||
if ($max_per_page == -1) {
|
||
$max_per_page = $list_max_entries_per_page;
|
||
}
|
||
$rows_found = $this->db->getRowCount($result);
|
||
|
||
$this->log->debug("Found $rows_found " . $this->object_name . "s");
|
||
|
||
$previous_offset = $row_offset - $max_per_page;
|
||
$next_offset = $row_offset + $max_per_page;
|
||
|
||
if ($rows_found != 0) {
|
||
|
||
// We have some data.
|
||
|
||
for ($index = $row_offset, $row = $this->db->fetchByAssoc($result, $index); $row && ($index < $row_offset + $max_per_page || $max_per_page == -99); $index++, $row = $this->db->fetchByAssoc($result, $index)) {
|
||
|
||
|
||
foreach ($this->list_fields as $entry) {
|
||
|
||
foreach ($entry as $key => $field) { // this will be cycled only once
|
||
if (isset($row[$field])) {
|
||
$this->column_fields[$this->list_fields_names[$key]] = $row[$field];
|
||
|
||
|
||
$this->log->debug("$this->object_name({$row['id']}): " . $field . " = " . $this->$field);
|
||
} else {
|
||
$this->column_fields[$this->list_fields_names[$key]] = "";
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
//$this->db->println("here is the bug");
|
||
|
||
|
||
$list[] = clone($this); //added by Richie to support PHP5
|
||
}
|
||
}
|
||
|
||
$response = Array();
|
||
$response['list'] = $list;
|
||
$response['row_count'] = $rows_found;
|
||
$response['next_offset'] = $next_offset;
|
||
$response['previous_offset'] = $previous_offset;
|
||
|
||
return $response;
|
||
}
|
||
|
||
function process_full_list_query($query) {
|
||
$this->log->debug("CRMEntity:process_full_list_query");
|
||
$result = & $this->db->query($query, false);
|
||
//$this->log->debug("CRMEntity:process_full_list_query: result is ".$result);
|
||
|
||
|
||
if ($this->db->getRowCount($result) > 0) {
|
||
|
||
// $this->db->println("process_full mid=".$this->table_index." mname=".$this->module_name);
|
||
// We have some data.
|
||
while ($row = $this->db->fetchByAssoc($result)) {
|
||
$rowid = $row[$this->table_index];
|
||
|
||
if (isset($rowid))
|
||
$this->retrieve_entity_info($rowid, $this->module_name);
|
||
else
|
||
$this->db->println("rowid not set unable to retrieve");
|
||
|
||
|
||
|
||
//clone function added to resolvoe PHP5 compatibility issue in Dashboards
|
||
//If we do not use clone, while using PHP5, the memory address remains fixed but the
|
||
//data gets overridden hence all the rows that come in bear the same value. This in turn
|
||
//provides a wrong display of the Dashboard graphs. The data is erroneously shown for a specific month alone
|
||
//Added by Richie
|
||
$list[] = clone($this); //added by Richie to support PHP5
|
||
}
|
||
}
|
||
|
||
if (isset($list))
|
||
return $list;
|
||
else
|
||
return null;
|
||
}
|
||
|
||
/** This function should be overridden in each module. It marks an item as deleted.
|
||
* If it is not overridden, then marking this type of item is not allowed
|
||
* Portions created by SugarCRM are Copyright (C) SugarCRM, Inc..
|
||
* All Rights Reserved..
|
||
* Contributor(s): ______________________________________..
|
||
*/
|
||
function mark_deleted($id) {
|
||
global $current_user;
|
||
$date_var = date("Y-m-d H:i:s");
|
||
$query = "UPDATE vtiger_crmentity set deleted=1,modifiedtime=?,modifiedby=? where crmid=?";
|
||
$this->db->pquery($query, array($this->db->formatDate($date_var, true), $current_user->id, $id), true, "Error marking record deleted: ");
|
||
}
|
||
|
||
function retrieve_by_string_fields($fields_array, $encode = true) {
|
||
$where_clause = $this->get_where($fields_array);
|
||
|
||
$query = "SELECT * FROM $this->table_name $where_clause";
|
||
$this->log->debug("Retrieve $this->object_name: " . $query);
|
||
$result = & $this->db->requireSingleResult($query, true, "Retrieving record $where_clause:");
|
||
if (empty($result)) {
|
||
return null;
|
||
}
|
||
|
||
$row = $this->db->fetchByAssoc($result, -1, $encode);
|
||
|
||
foreach ($this->column_fields as $field) {
|
||
if (isset($row[$field])) {
|
||
$this->$field = $row[$field];
|
||
}
|
||
}
|
||
return $this;
|
||
}
|
||
|
||
// this method is called during an import before inserting a bean
|
||
// define an associative array called $special_fields
|
||
// the keys are user defined, and don't directly map to the bean's vtiger_fields
|
||
// the value is the method name within that bean that will do extra
|
||
// processing for that vtiger_field. example: 'full_name'=>'get_names_from_full_name'
|
||
|
||
function process_special_fields() {
|
||
foreach ($this->special_functions as $func_name) {
|
||
if (method_exists($this, $func_name)) {
|
||
$this->$func_name();
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Function to check if the custom vtiger_field vtiger_table exists
|
||
* return true or false
|
||
*/
|
||
function checkIfCustomTableExists($tablename) {
|
||
global $adb;
|
||
$query = "select * from " . $adb->sql_escape_string($tablename);
|
||
$result = $this->db->pquery($query, array());
|
||
$testrow = $this->db->num_fields($result);
|
||
if ($testrow > 1) {
|
||
$exists = true;
|
||
} else {
|
||
$exists = false;
|
||
}
|
||
return $exists;
|
||
}
|
||
|
||
/**
|
||
* function to construct the query to fetch the custom vtiger_fields
|
||
* return the query to fetch the custom vtiger_fields
|
||
*/
|
||
function constructCustomQueryAddendum($tablename, $module) {
|
||
global $adb;
|
||
$tabid = getTabid($module);
|
||
$sql1 = "select columnname,fieldlabel from vtiger_field where generatedtype=2 and tabid=? and vtiger_field.presence in (0,2)";
|
||
$result = $adb->pquery($sql1, array($tabid));
|
||
$numRows = $adb->num_rows($result);
|
||
$sql3 = "select ";
|
||
for ($i = 0; $i < $numRows; $i++) {
|
||
$columnName = $adb->query_result($result, $i, "columnname");
|
||
$fieldlabel = $adb->query_result($result, $i, "fieldlabel");
|
||
//construct query as below
|
||
if ($i == 0) {
|
||
$sql3 .= $tablename . "." . $columnName . " '" . $fieldlabel . "'";
|
||
} else {
|
||
$sql3 .= ", " . $tablename . "." . $columnName . " '" . $fieldlabel . "'";
|
||
}
|
||
}
|
||
if ($numRows > 0) {
|
||
$sql3 = $sql3 . ',';
|
||
}
|
||
return $sql3;
|
||
}
|
||
|
||
/**
|
||
* This function returns a full (ie non-paged) list of the current object type.
|
||
* Portions created by SugarCRM are Copyright (C) SugarCRM, Inc..
|
||
* All Rights Reserved..
|
||
* Contributor(s): ______________________________________..
|
||
*/
|
||
function get_full_list($order_by = "", $where = "") {
|
||
$this->log->debug("get_full_list: order_by = '$order_by' and where = '$where'");
|
||
$query = $this->create_list_query($order_by, $where);
|
||
return $this->process_full_list_query($query);
|
||
}
|
||
|
||
/**
|
||
* Track the viewing of a detail record. This leverages get_summary_text() which is object specific
|
||
* params $user_id - The user that is viewing the record.
|
||
* Portions created by SugarCRM are Copyright (C) SugarCRM, Inc..
|
||
* All Rights Reserved..
|
||
* Contributor(s): ______________________________________..
|
||
*/
|
||
function track_view($user_id, $current_module, $id = '') {
|
||
$this->log->debug("About to call vtiger_tracker (user_id, module_name, item_id)($user_id, $current_module, $this->id)");
|
||
|
||
$tracker = new Tracker();
|
||
$tracker->track_view($user_id, $current_module, $id, '');
|
||
}
|
||
|
||
/**
|
||
* Function to get the column value of a field when the field value is empty ''
|
||
* @param $columnname -- Column name for the field
|
||
* @param $fldvalue -- Input value for the field taken from the User
|
||
* @param $fieldname -- Name of the Field
|
||
* @param $uitype -- UI type of the field
|
||
* @return Column value of the field.
|
||
*/
|
||
function get_column_value($columnname, $fldvalue, $fieldname, $uitype, $datatype = '') {
|
||
global $log;
|
||
$log->debug("Entering function get_column_value ($columnname, $fldvalue, $fieldname, $uitype, $datatype='')");
|
||
|
||
// Added for the fields of uitype '57' which has datatype mismatch in crmentity table and particular entity table
|
||
if ($uitype == 57 && $fldvalue == '') {
|
||
return 0;
|
||
}
|
||
if (is_uitype($uitype, "_date_") && $fldvalue == '' || $uitype == '14') {
|
||
return null;
|
||
}
|
||
if ($datatype == 'I' || $datatype == 'N' || $datatype == 'NN') {
|
||
return 0;
|
||
}
|
||
$log->debug("Exiting function get_column_value");
|
||
return $fldvalue;
|
||
}
|
||
|
||
/**
|
||
* Function to make change to column fields, depending on the current user's accessibility for the fields
|
||
*/
|
||
function apply_field_security($moduleName = '') {
|
||
global $current_user, $currentModule;
|
||
|
||
if($moduleName == '') {
|
||
$moduleName = $currentModule;
|
||
}
|
||
require_once('include/utils/UserInfoUtil.php');
|
||
foreach ($this->column_fields as $fieldname => $fieldvalue) {
|
||
$reset_value = false;
|
||
if (getFieldVisibilityPermission($moduleName, $current_user->id, $fieldname) != '0')
|
||
$reset_value = true;
|
||
|
||
if ($fieldname == "record_id" || $fieldname == "record_module")
|
||
$reset_value = false;
|
||
|
||
/*
|
||
if (isset($this->additional_column_fields) && in_array($fieldname, $this->additional_column_fields) == true)
|
||
$reset_value = false;
|
||
*/
|
||
|
||
if ($reset_value == true)
|
||
$this->column_fields[$fieldname] = "";
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Function invoked during export of module record value.
|
||
*/
|
||
function transform_export_value($key, $value) {
|
||
// NOTE: The sub-class can override this function as required.
|
||
return $value;
|
||
}
|
||
|
||
/**
|
||
* Function to initialize the importable fields array, based on the User's accessibility to the fields
|
||
*/
|
||
function initImportableFields($module) {
|
||
global $current_user, $adb;
|
||
require_once('include/utils/UserInfoUtil.php');
|
||
|
||
$skip_uitypes = array('4'); // uitype 4 is for Mod numbers
|
||
// Look at cache if the fields information is available.
|
||
$cachedModuleFields = VTCacheUtils::lookupFieldInfo_Module($module);
|
||
|
||
if ($cachedModuleFields === false) {
|
||
getColumnFields($module); // This API will initialize the cache as well
|
||
// We will succeed now due to above function call
|
||
$cachedModuleFields = VTCacheUtils::lookupFieldInfo_Module($module);
|
||
}
|
||
|
||
$colf = Array();
|
||
|
||
if ($cachedModuleFields) {
|
||
foreach ($cachedModuleFields as $fieldinfo) {
|
||
// Skip non-supported fields
|
||
if (in_array($fieldinfo['uitype'], $skip_uitypes)) {
|
||
continue;
|
||
} else {
|
||
$colf[$fieldinfo['fieldname']] = $fieldinfo['uitype'];
|
||
}
|
||
}
|
||
}
|
||
|
||
foreach ($colf as $key => $value) {
|
||
if (getFieldVisibilityPermission($module, $current_user->id, $key, 'readwrite') == '0')
|
||
$this->importable_fields[$key] = $value;
|
||
}
|
||
}
|
||
|
||
/** Function to initialize the required fields array for that particular module */
|
||
function initRequiredFields($module) {
|
||
global $adb;
|
||
|
||
$tabid = getTabId($module);
|
||
$sql = "select * from vtiger_field where tabid= ? and typeofdata like '%M%' and uitype not in ('53','70') and vtiger_field.presence in (0,2)";
|
||
$result = $adb->pquery($sql, array($tabid));
|
||
$numRows = $adb->num_rows($result);
|
||
for ($i = 0; $i < $numRows; $i++) {
|
||
$fieldName = $adb->query_result($result, $i, "fieldname");
|
||
$this->required_fields[$fieldName] = 1;
|
||
}
|
||
}
|
||
|
||
/** Function to delete an entity with given Id */
|
||
function trash($module, $id) {
|
||
global $log, $current_user, $adb;
|
||
|
||
if(!self::isBulkSaveMode()) {
|
||
require_once("include/events/include.inc");
|
||
$em = new VTEventsManager($adb);
|
||
|
||
// Initialize Event trigger cache
|
||
$em->initTriggerCache();
|
||
|
||
$entityData = VTEntityData::fromEntityId($adb, $id);
|
||
|
||
$em->triggerEvent("vtiger.entity.beforedelete", $entityData);
|
||
}
|
||
$this->mark_deleted($id);
|
||
$this->unlinkDependencies($module, $id);
|
||
|
||
require_once('libraries/freetag/freetag.class.php');
|
||
$freetag = new freetag();
|
||
$freetag->delete_all_object_tags_for_user($current_user->id, $id);
|
||
|
||
$sql_recentviewed = 'DELETE FROM vtiger_tracker WHERE user_id = ? AND item_id = ?';
|
||
$this->db->pquery($sql_recentviewed, array($current_user->id, $id));
|
||
|
||
if($em){
|
||
$em->triggerEvent("vtiger.entity.afterdelete", $entityData);
|
||
}
|
||
}
|
||
|
||
/** Function to unlink all the dependent entities of the given Entity by Id */
|
||
function unlinkDependencies($module, $id) {
|
||
global $log;
|
||
|
||
$fieldRes = $this->db->pquery('SELECT tabid, tablename, columnname FROM vtiger_field WHERE fieldid IN (
|
||
SELECT fieldid FROM vtiger_fieldmodulerel WHERE relmodule=?)', array($module));
|
||
$numOfFields = $this->db->num_rows($fieldRes);
|
||
for ($i = 0; $i < $numOfFields; $i++) {
|
||
$tabId = $this->db->query_result($fieldRes, $i, 'tabid');
|
||
$tableName = $this->db->query_result($fieldRes, $i, 'tablename');
|
||
$columnName = $this->db->query_result($fieldRes, $i, 'columnname');
|
||
|
||
$relatedModule = vtlib_getModuleNameById($tabId);
|
||
$focusObj = CRMEntity::getInstance($relatedModule);
|
||
|
||
//Backup Field Relations for the deleted entity
|
||
$targetTableColumn = $focusObj->tab_name_index[$tableName];
|
||
|
||
$relQuery = "SELECT $targetTableColumn FROM $tableName WHERE $columnName=?";
|
||
$relResult = $this->db->pquery($relQuery, array($id));
|
||
$numOfRelRecords = $this->db->num_rows($relResult);
|
||
if ($numOfRelRecords > 0) {
|
||
$recordIdsList = array();
|
||
for ($k = 0; $k < $numOfRelRecords; $k++) {
|
||
$recordIdsList[] = $this->db->query_result($relResult, $k, $focusObj->table_index);
|
||
}
|
||
if(count($recordIdsList) > 0) {
|
||
$params = array($id, RB_RECORD_UPDATED, $tableName, $columnName, $focusObj->table_index, implode(",", $recordIdsList));
|
||
$this->db->pquery('INSERT INTO vtiger_relatedlists_rb VALUES (?,?,?,?,?,?)', $params);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
/** Function to unlink an entity with given Id from another entity */
|
||
function unlinkRelationship($id, $return_module, $return_id) {
|
||
global $log, $currentModule;
|
||
if($return_module == 'Documents') {
|
||
$sql = 'DELETE FROM vtiger_senotesrel WHERE crmid=? AND notesid=?';
|
||
$this->db->pquery($sql, array($id, $return_id));
|
||
} else {
|
||
$query = 'DELETE FROM vtiger_crmentityrel WHERE (crmid=? AND relmodule=? AND relcrmid=?) OR (relcrmid=? AND module=? AND crmid=?)';
|
||
$params = array($id, $return_module, $return_id, $id, $return_module, $return_id);
|
||
$this->db->pquery($query, $params);
|
||
|
||
$fieldRes = $this->db->pquery('SELECT tabid, tablename, columnname FROM vtiger_field WHERE fieldid IN (SELECT fieldid FROM vtiger_fieldmodulerel WHERE module=? AND relmodule=?)', array($currentModule, $return_module));
|
||
$numOfFields = $this->db->num_rows($fieldRes);
|
||
for ($i = 0; $i < $numOfFields; $i++) {
|
||
$tabId = $this->db->query_result($fieldRes, $i, 'tabid');
|
||
$tableName = $this->db->query_result($fieldRes, $i, 'tablename');
|
||
$columnName = $this->db->query_result($fieldRes, $i, 'columnname');
|
||
|
||
$relatedModule = vtlib_getModuleNameById($tabId);
|
||
$focusObj = CRMEntity::getInstance($relatedModule);
|
||
|
||
$updateQuery = "UPDATE $tableName SET $columnName=? WHERE $columnName=? AND $focusObj->table_index=?";
|
||
$updateParams = array(null, $return_id, $id);
|
||
$this->db->pquery($updateQuery, $updateParams);
|
||
}
|
||
}
|
||
}
|
||
|
||
/** Function to restore a deleted record of specified module with given crmid
|
||
* @param $module -- module name:: Type varchar
|
||
* @param $entity_ids -- list of crmids :: Array
|
||
*/
|
||
function restore($module, $id) {
|
||
global $current_user, $adb;
|
||
|
||
$this->db->println("TRANS restore starts $module");
|
||
$this->db->startTransaction();
|
||
|
||
//Event triggering code
|
||
require_once("include/events/include.inc");
|
||
global $adb;
|
||
$em = new VTEventsManager($adb);
|
||
|
||
// Initialize Event trigger cache
|
||
$em->initTriggerCache();
|
||
|
||
$this->id = $id;
|
||
$entityData = VTEntityData::getInstanceByDeletedEntityId($adb, $id, $module);
|
||
$em->triggerEvent("vtiger.entity.beforerestore", $entityData);
|
||
|
||
$date_var = date("Y-m-d H:i:s");
|
||
$query = 'UPDATE vtiger_crmentity SET deleted=0,modifiedtime=?,modifiedby=? WHERE crmid = ?';
|
||
$this->db->pquery($query, array($this->db->formatDate($date_var, true), $current_user->id, $id), true, "Error restoring records :");
|
||
//Restore related entities/records
|
||
$this->restoreRelatedRecords($module, $id);
|
||
|
||
//Event triggering code
|
||
$em->triggerEvent("vtiger.entity.afterrestore", $entityData);
|
||
//Event triggering code ends
|
||
|
||
$this->db->completeTransaction();
|
||
$this->db->println("TRANS restore ends");
|
||
}
|
||
|
||
/** Function to restore all the related records of a given record by id */
|
||
function restoreRelatedRecords($module, $record) {
|
||
|
||
$result = $this->db->pquery('SELECT * FROM vtiger_relatedlists_rb WHERE entityid = ?', array($record));
|
||
$numRows = $this->db->num_rows($result);
|
||
for ($i = 0; $i < $numRows; $i++) {
|
||
$action = $this->db->query_result($result, $i, "action");
|
||
$rel_table = $this->db->query_result($result, $i, "rel_table");
|
||
$rel_column = $this->db->query_result($result, $i, "rel_column");
|
||
$ref_column = $this->db->query_result($result, $i, "ref_column");
|
||
$related_crm_ids = $this->db->query_result($result, $i, "related_crm_ids");
|
||
|
||
if (strtoupper($action) == RB_RECORD_UPDATED) {
|
||
$related_ids = explode(",", $related_crm_ids);
|
||
if ($rel_table == 'vtiger_crmentity' && $rel_column == 'deleted') {
|
||
$sql = "UPDATE $rel_table set $rel_column = 0 WHERE $ref_column IN (" . generateQuestionMarks($related_ids) . ")";
|
||
$this->db->pquery($sql, array($related_ids));
|
||
} else {
|
||
$sql = "UPDATE $rel_table set $rel_column = ? WHERE $rel_column = 0 AND $ref_column IN (" . generateQuestionMarks($related_ids) . ")";
|
||
$this->db->pquery($sql, array($record, $related_ids));
|
||
}
|
||
} elseif (strtoupper($action) == RB_RECORD_DELETED) {
|
||
if ($rel_table == 'vtiger_seproductsrel') {
|
||
$sql = "INSERT INTO $rel_table($rel_column, $ref_column, 'setype') VALUES (?,?,?)";
|
||
$this->db->pquery($sql, array($record, $related_crm_ids, getSalesEntityType($related_crm_ids)));
|
||
} else {
|
||
$sql = "INSERT INTO $rel_table($rel_column, $ref_column) VALUES (?,?)";
|
||
$this->db->pquery($sql, array($record, $related_crm_ids));
|
||
}
|
||
}
|
||
}
|
||
|
||
//Clean up the the backup data also after restoring
|
||
$this->db->pquery('DELETE FROM vtiger_relatedlists_rb WHERE entityid = ?', array($record));
|
||
}
|
||
|
||
/**
|
||
* Function to initialize the sortby fields array
|
||
*/
|
||
function initSortByField($module) {
|
||
global $adb, $log;
|
||
$log->debug("Entering function initSortByField ($module)");
|
||
// Define the columnname's and uitype's which needs to be excluded
|
||
$exclude_columns = Array('parent_id', 'quoteid', 'vendorid', 'access_count');
|
||
$exclude_uitypes = Array();
|
||
|
||
$tabid = getTabId($module);
|
||
if ($module == 'Calendar') {
|
||
$tabid = array('9', '16');
|
||
}
|
||
$sql = "SELECT columnname FROM vtiger_field " .
|
||
" WHERE (fieldname not like '%\_id' OR fieldname in ('assigned_user_id'))" .
|
||
" AND tabid in (" . generateQuestionMarks($tabid) . ") and vtiger_field.presence in (0,2)";
|
||
$params = array($tabid);
|
||
if (count($exclude_columns) > 0) {
|
||
$sql .= " AND columnname NOT IN (" . generateQuestionMarks($exclude_columns) . ")";
|
||
array_push($params, $exclude_columns);
|
||
}
|
||
if (count($exclude_uitypes) > 0) {
|
||
$sql .= " AND uitype NOT IN (" . generateQuestionMarks($exclude_uitypes) . ")";
|
||
array_push($params, $exclude_uitypes);
|
||
}
|
||
$result = $adb->pquery($sql, $params);
|
||
$num_rows = $adb->num_rows($result);
|
||
for ($i = 0; $i < $num_rows; $i++) {
|
||
$columnname = $adb->query_result($result, $i, 'columnname');
|
||
if (in_array($columnname, $this->sortby_fields))
|
||
continue;
|
||
else
|
||
$this->sortby_fields[] = $columnname;
|
||
}
|
||
if ($tabid == 21 or $tabid == 22)
|
||
$this->sortby_fields[] = 'crmid';
|
||
$log->debug("Exiting initSortByField");
|
||
}
|
||
|
||
/* Function to set the Sequence string and sequence number starting value */
|
||
// SalesPlatform.ru begin: Added separate numbering for self organizations
|
||
function setModuleSeqNumber($mode, $module, $req_str = '', $req_no = '', $spCompany = '') {
|
||
if($spCompany == 'Default') {
|
||
$spCompany = '';
|
||
}
|
||
//function setModuleSeqNumber($mode, $module, $req_str = '', $req_no = '') {
|
||
// SalesPlatform.ru end
|
||
global $adb;
|
||
//when we configure the invoice number in Settings this will be used
|
||
if ($mode == "configure" && $req_no != '') {
|
||
// SalesPlatform.ru begin: Added separate numbering for self organizations
|
||
$adb->pquery("ALTER TABLE vtiger_modentity_num ADD spcompany varchar(200) COLLATE utf8_unicode_ci DEFAULT ''", array());
|
||
$check = $adb->pquery("select cur_id from vtiger_modentity_num where semodule=? and prefix = ? and spcompany=?", array($module, $req_str, $spCompany));
|
||
//$check = $adb->pquery("select cur_id from vtiger_modentity_num where semodule=? and prefix = ?", array($module, $req_str));
|
||
// SalesPlatform.ru end
|
||
if ($adb->num_rows($check) == 0) {
|
||
$numid = $adb->getUniqueId("vtiger_modentity_num");
|
||
// SalesPlatform.ru begin: Added separate numbering for self organizations
|
||
$active = $adb->pquery("select num_id from vtiger_modentity_num where semodule=? and active=1 and spcompany=?", array($module, $spCompany));
|
||
//$active = $adb->pquery("select num_id from vtiger_modentity_num where semodule=? and active=1", array($module));
|
||
// SalesPlatform.ru end
|
||
$adb->pquery("UPDATE vtiger_modentity_num SET active=0 where num_id=?", array($adb->query_result($active, 0, 'num_id')));
|
||
|
||
// SalesPlatform.ru begin: Added separate numbering for self organizations
|
||
$adb->pquery("INSERT into vtiger_modentity_num values(?,?,?,?,?,?,?)", array($numid, $module, $req_str, $req_no, $req_no, 1, $spCompany));
|
||
//$adb->pquery("INSERT into vtiger_modentity_num values(?,?,?,?,?,?)", array($numid, $module, $req_str, $req_no, $req_no, 1));
|
||
// SalesPlatform.ru end
|
||
return true;
|
||
} else if ($adb->num_rows($check) != 0) {
|
||
// SalesPlatform.ru begin Added separate numbering for self organizations
|
||
//$num_check = $adb->query_result($check, 0, 'cur_id');
|
||
//if ($req_no < $num_check) {
|
||
// return false;
|
||
//} else {
|
||
// $adb->pquery("UPDATE vtiger_modentity_num SET active=0 where active=1 and semodule=?", array($module));
|
||
// $adb->pquery("UPDATE vtiger_modentity_num SET cur_id=?, active = 1 where prefix=? and semodule=?", array($req_no, $req_str, $module));
|
||
// return true;
|
||
//}
|
||
$adb->pquery("UPDATE vtiger_modentity_num SET active=0 where active=1 and semodule=? and spcompany=?", array($module, $spCompany));
|
||
$adb->pquery("UPDATE vtiger_modentity_num SET cur_id=?, active = 1 where prefix=? and semodule=? and spcompany=?", array($req_no, $req_str, $module, $spCompany));
|
||
return true;
|
||
// SalesPlatform.ru end
|
||
}
|
||
} else if ($mode == "increment") {
|
||
//when we save new invoice we will increment the invoice id and write
|
||
// SalesPlatform.ru begin: Added separate numbering for self organizations
|
||
$check = $adb->pquery("select cur_id,prefix from vtiger_modentity_num where semodule=? and active = 1 and spcompany=?", array($module, $spCompany));
|
||
//$check = $adb->pquery("select cur_id,prefix from vtiger_modentity_num where semodule=? and active = 1", array($module));
|
||
// SalesPlatform.ru end
|
||
$prefix = $adb->query_result($check, 0, 'prefix');
|
||
$curid = $adb->query_result($check, 0, 'cur_id');
|
||
$prev_inv_no = $prefix . $curid;
|
||
$strip = strlen($curid) - strlen($curid + 1);
|
||
if ($strip < 0)
|
||
$strip = 0;
|
||
$temp = str_repeat("0", $strip);
|
||
$req_no.= $temp . ($curid + 1);
|
||
// SalesPlatform.ru begin: Added separate numbering for self organizations
|
||
$adb->pquery("UPDATE vtiger_modentity_num SET cur_id=? where cur_id=? and active=1 AND semodule=? and spcompany=?", array($req_no, $curid, $module, $spCompany));
|
||
//$adb->pquery("UPDATE vtiger_modentity_num SET cur_id=? where cur_id=? and active=1 AND semodule=?", array($req_no, $curid, $module));
|
||
// SalesPlatform.ru end
|
||
return decode_html($prev_inv_no);
|
||
}
|
||
}
|
||
|
||
// END
|
||
|
||
/* Function to check if module sequence numbering is configured for the given module or not */
|
||
// SalesPlatform.ru begin: Added separate numbering for self organizations
|
||
function isModuleSequenceConfigured($module, $spCompany = '') {
|
||
if($spCompany == 'Default') {
|
||
$spCompany = '';
|
||
}
|
||
//function isModuleSequenceConfigured($module) {
|
||
// SalesPlatform.ru end
|
||
$adb = PearDatabase::getInstance();
|
||
// SalesPlatform.ru begin: Added separate numbering for self organizations
|
||
$result = $adb->pquery('SELECT 1 FROM vtiger_modentity_num WHERE semodule = ? AND active = 1 and spcompany=?', array($module, $spCompany));
|
||
//$result = $adb->pquery('SELECT 1 FROM vtiger_modentity_num WHERE semodule = ? AND active = 1', array($module));
|
||
// SalesPlatform.ru end
|
||
if ($result && $adb->num_rows($result) > 0) {
|
||
return true;
|
||
}
|
||
return false;
|
||
}
|
||
|
||
/* Function to get the next module sequence number for a given module */
|
||
// SalesPlatform.ru begin: Added separate numbering for self organizations
|
||
function getModuleSeqInfo($module, $spCompany = '') {
|
||
if($spCompany == 'Default') {
|
||
$spCompany = '';
|
||
}
|
||
//function getModuleSeqInfo($module) {
|
||
// SalesPlatform.ru end
|
||
global $adb;
|
||
// SalesPlatform.ru begin: Added separate numbering for self organizations
|
||
$check = $adb->pquery("select cur_id,prefix from vtiger_modentity_num where semodule=? and active = 1 and spcompany=?", array($module, $spCompany));
|
||
//$check = $adb->pquery("select cur_id,prefix from vtiger_modentity_num where semodule=? and active = 1", array($module));
|
||
// SalesPlatform.ru end
|
||
$prefix = $adb->query_result($check, 0, 'prefix');
|
||
$curid = $adb->query_result($check, 0, 'cur_id');
|
||
return array($prefix, $curid);
|
||
}
|
||
|
||
// END
|
||
|
||
/* Function to check if the mod number already exits */
|
||
function checkModuleSeqNumber($table, $column, $no) {
|
||
global $adb;
|
||
$table = Vtiger_Util_Helper::validateStringForSql($table);
|
||
$column = Vtiger_Util_Helper::validateStringForSql($column);
|
||
$result = $adb->pquery("select " . $adb->sql_escape_string($column) .
|
||
" from " . $adb->sql_escape_string($table) .
|
||
" where " . $adb->sql_escape_string($column) . " = ?", array($no));
|
||
|
||
$num_rows = $adb->num_rows($result);
|
||
|
||
if ($num_rows > 0)
|
||
return true;
|
||
else
|
||
return false;
|
||
}
|
||
|
||
// END
|
||
|
||
// SalesPlatform.ru begin: Added separate numbering for self organizations
|
||
function updateMissingSeqNumber($module, $spCompany = '') {
|
||
if($spCompany == 'Default') {
|
||
$spCompany = '';
|
||
}
|
||
//function updateMissingSeqNumber($module) {
|
||
// SalesPlatform.ru end
|
||
global $log, $adb;
|
||
$log->debug("Entered updateMissingSeqNumber function");
|
||
|
||
vtlib_setup_modulevars($module, $this);
|
||
|
||
// SalesPlatform.ru begin: Added separate numbering for self organizations
|
||
if (!$this->isModuleSequenceConfigured($module, $spCompany))
|
||
//if (!$this->isModuleSequenceConfigured($module))
|
||
// SalesPlatform.ru end
|
||
return;
|
||
|
||
$tabid = getTabid($module);
|
||
$fieldinfo = $adb->pquery("SELECT tablename, columnname FROM vtiger_field WHERE tabid = ? AND uitype = 4", Array($tabid));
|
||
|
||
$returninfo = Array();
|
||
|
||
if ($fieldinfo && $adb->num_rows($fieldinfo)) {
|
||
// TODO: We assume the following for module sequencing field
|
||
// 1. There will be only field per module
|
||
// 2. This field is linked to module base table column
|
||
$fld_table = $adb->query_result($fieldinfo, 0, 'tablename');
|
||
$fld_column = $adb->query_result($fieldinfo, 0, 'columnname');
|
||
|
||
if ($fld_table == $this->table_name) {
|
||
$records = $adb->pquery("SELECT $this->table_index AS recordid FROM $this->table_name " .
|
||
"WHERE $fld_column = '' OR $fld_column is NULL", array());
|
||
|
||
if ($records && $adb->num_rows($records)) {
|
||
$returninfo['totalrecords'] = $adb->num_rows($records);
|
||
$returninfo['updatedrecords'] = 0;
|
||
|
||
// SalesPlatform.ru begin: Added separate numbering for self organizations
|
||
$modseqinfo = $this->getModuleSeqInfo($module, $spCompany);
|
||
//$modseqinfo = $this->getModuleSeqInfo($module);
|
||
// SalesPlatform.ru end
|
||
$prefix = $modseqinfo[0];
|
||
$cur_id = $modseqinfo[1];
|
||
|
||
$old_cur_id = $cur_id;
|
||
while ($recordinfo = $adb->fetch_array($records)) {
|
||
$value = "$prefix" . "$cur_id";
|
||
$adb->pquery("UPDATE $fld_table SET $fld_column = ? WHERE $this->table_index = ?", Array($value, $recordinfo['recordid']));
|
||
$cur_id += 1;
|
||
$returninfo['updatedrecords'] = $returninfo['updatedrecords'] + 1;
|
||
}
|
||
if ($old_cur_id != $cur_id) {
|
||
// SalesPlatform.ru begin: Added separate numbering for self organizations
|
||
$adb->pquery("UPDATE vtiger_modentity_num set cur_id=? where semodule=? and active=1 and spcompany=?", Array($cur_id, $module, $spCompany));
|
||
//$adb->pquery("UPDATE vtiger_modentity_num set cur_id=? where semodule=? and active=1", Array($cur_id, $module));
|
||
// SalesPlatform.ru end
|
||
}
|
||
}
|
||
} else {
|
||
$log->fatal("Updating Missing Sequence Number FAILED! REASON: Field table and module table mismatching.");
|
||
}
|
||
}
|
||
return $returninfo;
|
||
}
|
||
|
||
/* Generic function to get attachments in the related list of a given module */
|
||
|
||
function get_attachments($id, $cur_tab_id, $rel_tab_id, $actions = false) {
|
||
|
||
global $currentModule, $app_strings, $singlepane_view;
|
||
$this_module = $currentModule;
|
||
$parenttab = getParentTab();
|
||
|
||
$related_module = vtlib_getModuleNameById($rel_tab_id);
|
||
$other = CRMEntity::getInstance($related_module);
|
||
|
||
// Some standard module class doesn't have required variables
|
||
// that are used in the query, they are defined in this generic API
|
||
vtlib_setup_modulevars($related_module, $other);
|
||
|
||
$singular_modname = vtlib_toSingular($related_module);
|
||
$button = '';
|
||
if ($actions) {
|
||
if (is_string($actions))
|
||
$actions = explode(',', strtoupper($actions));
|
||
if (in_array('SELECT', $actions) && isPermitted($related_module, 4, '') == 'yes') {
|
||
$button .= "<input title='" . getTranslatedString('LBL_SELECT') . " " . getTranslatedString($related_module) . "' class='crmbutton small edit' type='button' onclick=\"return window.open('index.php?module=$related_module&return_module=$currentModule&action=Popup&popuptype=detailview&select=enable&form=EditView&form_submit=false&recordid=$id&parenttab=$parenttab','test','width=640,height=602,resizable=0,scrollbars=0');\" value='" . getTranslatedString('LBL_SELECT') . " " . getTranslatedString($related_module) . "'> ";
|
||
}
|
||
if (in_array('ADD', $actions) && isPermitted($related_module, 1, '') == 'yes') {
|
||
$button .= "<input type='hidden' name='createmode' id='createmode' value='link' />" .
|
||
"<input title='" . getTranslatedString('LBL_ADD_NEW') . " " . getTranslatedString($singular_modname) . "' class='crmbutton small create'" .
|
||
" onclick='this.form.action.value=\"EditView\";this.form.module.value=\"$related_module\"' type='submit' name='button'" .
|
||
" value='" . getTranslatedString('LBL_ADD_NEW') . " " . getTranslatedString($singular_modname) . "'> ";
|
||
}
|
||
}
|
||
|
||
// To make the edit or del link actions to return back to same view.
|
||
if ($singlepane_view == 'true')
|
||
$returnset = "&return_module=$this_module&return_action=DetailView&return_id=$id";
|
||
else
|
||
$returnset = "&return_module=$this_module&return_action=CallRelatedList&return_id=$id";
|
||
|
||
$userNameSql = getSqlForNameInDisplayFormat(array('first_name'=>'vtiger_users.first_name',
|
||
'last_name' => 'vtiger_users.last_name'), 'Users');
|
||
$query = "select case when (vtiger_users.user_name not like '') then $userNameSql else vtiger_groups.groupname end as user_name," .
|
||
"'Documents' ActivityType,vtiger_attachments.type FileType,crm2.modifiedtime lastmodified,vtiger_crmentity.modifiedtime,
|
||
vtiger_seattachmentsrel.attachmentsid attachmentsid, vtiger_crmentity.smownerid smownerid, vtiger_notes.notesid crmid,
|
||
vtiger_notes.notecontent description,vtiger_notes.*
|
||
from vtiger_notes
|
||
inner join vtiger_senotesrel on vtiger_senotesrel.notesid= vtiger_notes.notesid
|
||
left join vtiger_notescf ON vtiger_notescf.notesid= vtiger_notes.notesid
|
||
inner join vtiger_crmentity on vtiger_crmentity.crmid= vtiger_notes.notesid and vtiger_crmentity.deleted=0
|
||
inner join vtiger_crmentity crm2 on crm2.crmid=vtiger_senotesrel.crmid
|
||
LEFT JOIN vtiger_groups
|
||
ON vtiger_groups.groupid = vtiger_crmentity.smownerid
|
||
left join vtiger_seattachmentsrel on vtiger_seattachmentsrel.crmid =vtiger_notes.notesid
|
||
left join vtiger_attachments on vtiger_seattachmentsrel.attachmentsid = vtiger_attachments.attachmentsid
|
||
left join vtiger_users on vtiger_crmentity.smownerid= vtiger_users.id
|
||
where crm2.crmid=" . $id;
|
||
|
||
$return_value = GetRelatedList($this_module, $related_module, $other, $query, $button, $returnset);
|
||
|
||
if ($return_value == null)
|
||
$return_value = Array();
|
||
$return_value['CUSTOM_BUTTON'] = $button;
|
||
return $return_value;
|
||
}
|
||
|
||
/**
|
||
* For Record View Notification
|
||
*/
|
||
function isViewed($crmid = false) {
|
||
if (!$crmid) {
|
||
$crmid = $this->id;
|
||
}
|
||
if ($crmid) {
|
||
global $adb;
|
||
$result = $adb->pquery("SELECT viewedtime,modifiedtime,smcreatorid,smownerid,modifiedby FROM vtiger_crmentity WHERE crmid=?", Array($crmid));
|
||
$resinfo = $adb->fetch_array($result);
|
||
|
||
$lastviewed = $resinfo['viewedtime'];
|
||
$modifiedon = $resinfo['modifiedtime'];
|
||
$smownerid = $resinfo['smownerid'];
|
||
$smcreatorid = $resinfo['smcreatorid'];
|
||
$modifiedby = $resinfo['modifiedby'];
|
||
|
||
if ($modifiedby == '0' && ($smownerid == $smcreatorid)) {
|
||
/** When module record is created * */
|
||
return true;
|
||
} else if ($smownerid == $modifiedby) {
|
||
/** Owner and Modifier as same. * */
|
||
return true;
|
||
} else if ($lastviewed && $modifiedon) {
|
||
/** Lastviewed and Modified time is available. */
|
||
if ($this->__timediff($modifiedon, $lastviewed) > 0)
|
||
return true;
|
||
}
|
||
}
|
||
return false;
|
||
}
|
||
|
||
function __timediff($d1, $d2) {
|
||
list($t1_1, $t1_2) = explode(' ', $d1);
|
||
list($t1_y, $t1_m, $t1_d) = explode('-', $t1_1);
|
||
list($t1_h, $t1_i, $t1_s) = explode(':', $t1_2);
|
||
|
||
$t1 = mktime($t1_h, $t1_i, $t1_s, $t1_m, $t1_d, $t1_y);
|
||
|
||
list($t2_1, $t2_2) = explode(' ', $d2);
|
||
list($t2_y, $t2_m, $t2_d) = explode('-', $t2_1);
|
||
list($t2_h, $t2_i, $t2_s) = explode(':', $t2_2);
|
||
|
||
$t2 = mktime($t2_h, $t2_i, $t2_s, $t2_m, $t2_d, $t2_y);
|
||
|
||
if ($t1 == $t2)
|
||
return 0;
|
||
return $t2 - $t1;
|
||
}
|
||
|
||
function markAsViewed($userid) {
|
||
global $adb;
|
||
$adb->pquery("UPDATE vtiger_crmentity set viewedtime=? WHERE crmid=? AND smownerid=?", Array(date('Y-m-d H:i:s', time()), $this->id, $userid));
|
||
}
|
||
|
||
/**
|
||
* Save the related module record information. Triggered from CRMEntity->saveentity method or updateRelations.php
|
||
* @param String This module name
|
||
* @param Integer This module record number
|
||
* @param String Related module name
|
||
* @param mixed Integer or Array of related module record number
|
||
*/
|
||
function save_related_module($module, $crmid, $with_module, $with_crmid) {
|
||
global $adb;
|
||
if (!is_array($with_crmid))
|
||
$with_crmid = Array($with_crmid);
|
||
foreach ($with_crmid as $relcrmid) {
|
||
|
||
if ($with_module == 'Documents') {
|
||
$checkpresence = $adb->pquery("SELECT crmid FROM vtiger_senotesrel WHERE crmid = ? AND notesid = ?", Array($crmid, $relcrmid));
|
||
// Relation already exists? No need to add again
|
||
if ($checkpresence && $adb->num_rows($checkpresence))
|
||
continue;
|
||
|
||
$adb->pquery("INSERT INTO vtiger_senotesrel(crmid, notesid) VALUES(?,?)", array($crmid, $relcrmid));
|
||
} else {
|
||
$checkpresence = $adb->pquery("SELECT crmid FROM vtiger_crmentityrel WHERE
|
||
crmid = ? AND module = ? AND relcrmid = ? AND relmodule = ?", Array($crmid, $module, $relcrmid, $with_module));
|
||
// Relation already exists? No need to add again
|
||
if ($checkpresence && $adb->num_rows($checkpresence))
|
||
continue;
|
||
|
||
$adb->pquery("INSERT INTO vtiger_crmentityrel(crmid, module, relcrmid, relmodule) VALUES(?,?,?,?)", Array($crmid, $module, $relcrmid, $with_module));
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Delete the related module record information. Triggered from updateRelations.php
|
||
* @param String This module name
|
||
* @param Integer This module record number
|
||
* @param String Related module name
|
||
* @param mixed Integer or Array of related module record number
|
||
*/
|
||
function delete_related_module($module, $crmid, $with_module, $with_crmid) {
|
||
global $adb;
|
||
if (!is_array($with_crmid))
|
||
$with_crmid = Array($with_crmid);
|
||
foreach ($with_crmid as $relcrmid) {
|
||
|
||
if ($with_module == 'Documents') {
|
||
$adb->pquery("DELETE FROM vtiger_senotesrel WHERE crmid=? AND notesid=?", Array($crmid, $relcrmid));
|
||
} else {
|
||
$adb->pquery("DELETE FROM vtiger_crmentityrel WHERE (crmid=? AND module=? AND relcrmid=? AND relmodule=?) OR (relcrmid=? AND relmodule=? AND crmid=? AND module=?)",
|
||
Array($crmid, $module, $relcrmid, $with_module,$crmid, $module, $relcrmid, $with_module));
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Default (generic) function to handle the related list for the module.
|
||
* NOTE: Vtiger_Module::setRelatedList sets reference to this function in vtiger_relatedlists table
|
||
* if function name is not explicitly specified.
|
||
*/
|
||
function get_related_list($id, $cur_tab_id, $rel_tab_id, $actions = false) {
|
||
|
||
global $currentModule, $app_strings, $singlepane_view;
|
||
|
||
$parenttab = getParentTab();
|
||
|
||
$related_module = vtlib_getModuleNameById($rel_tab_id);
|
||
$other = CRMEntity::getInstance($related_module);
|
||
|
||
// Some standard module class doesn't have required variables
|
||
// that are used in the query, they are defined in this generic API
|
||
vtlib_setup_modulevars($currentModule, $this);
|
||
vtlib_setup_modulevars($related_module, $other);
|
||
|
||
$singular_modname = 'SINGLE_' . $related_module;
|
||
|
||
$button = '';
|
||
if ($actions) {
|
||
if (is_string($actions))
|
||
$actions = explode(',', strtoupper($actions));
|
||
if (in_array('SELECT', $actions) && isPermitted($related_module, 4, '') == 'yes') {
|
||
$button .= "<input title='" . getTranslatedString('LBL_SELECT') . " " . getTranslatedString($related_module) . "' class='crmbutton small edit' " .
|
||
" type='button' onclick=\"return window.open('index.php?module=$related_module&return_module=$currentModule&action=Popup&popuptype=detailview&select=enable&form=EditView&form_submit=false&recordid=$id&parenttab=$parenttab','test','width=640,height=602,resizable=0,scrollbars=0');\"" .
|
||
" value='" . getTranslatedString('LBL_SELECT') . " " . getTranslatedString($related_module, $related_module) . "'> ";
|
||
}
|
||
if (in_array('ADD', $actions) && isPermitted($related_module, 1, '') == 'yes') {
|
||
$button .= "<input type='hidden' name='createmode' id='createmode' value='link' />" .
|
||
"<input title='" . getTranslatedString('LBL_ADD_NEW') . " " . getTranslatedString($singular_modname) . "' class='crmbutton small create'" .
|
||
" onclick='this.form.action.value=\"EditView\";this.form.module.value=\"$related_module\"' type='submit' name='button'" .
|
||
" value='" . getTranslatedString('LBL_ADD_NEW') . " " . getTranslatedString($singular_modname, $related_module) . "'> ";
|
||
}
|
||
}
|
||
|
||
// To make the edit or del link actions to return back to same view.
|
||
if ($singlepane_view == 'true')
|
||
$returnset = "&return_module=$currentModule&return_action=DetailView&return_id=$id";
|
||
else
|
||
$returnset = "&return_module=$currentModule&return_action=CallRelatedList&return_id=$id";
|
||
|
||
$query = "SELECT vtiger_crmentity.*, $other->table_name.*";
|
||
|
||
$userNameSql = getSqlForNameInDisplayFormat(array('first_name'=>'vtiger_users.first_name',
|
||
'last_name' => 'vtiger_users.last_name'), 'Users');
|
||
$query .= ", CASE WHEN (vtiger_users.user_name NOT LIKE '') THEN $userNameSql ELSE vtiger_groups.groupname END AS user_name";
|
||
|
||
$more_relation = '';
|
||
if (!empty($other->related_tables)) {
|
||
foreach ($other->related_tables as $tname => $relmap) {
|
||
$query .= ", $tname.*";
|
||
|
||
// Setup the default JOIN conditions if not specified
|
||
if (empty($relmap[1]))
|
||
$relmap[1] = $other->table_name;
|
||
if (empty($relmap[2]))
|
||
$relmap[2] = $relmap[0];
|
||
$more_relation .= " LEFT JOIN $tname ON $tname.$relmap[0] = $relmap[1].$relmap[2]";
|
||
}
|
||
}
|
||
|
||
$query .= " FROM $other->table_name";
|
||
$query .= " INNER JOIN vtiger_crmentity ON vtiger_crmentity.crmid = $other->table_name.$other->table_index";
|
||
$query .= " INNER JOIN vtiger_crmentityrel ON (vtiger_crmentityrel.relcrmid = vtiger_crmentity.crmid OR vtiger_crmentityrel.crmid = vtiger_crmentity.crmid)";
|
||
$query .= $more_relation;
|
||
$query .= " LEFT JOIN vtiger_users ON vtiger_users.id = vtiger_crmentity.smownerid";
|
||
$query .= " LEFT JOIN vtiger_groups ON vtiger_groups.groupid = vtiger_crmentity.smownerid";
|
||
$query .= " WHERE vtiger_crmentity.deleted = 0 AND (vtiger_crmentityrel.crmid = $id OR vtiger_crmentityrel.relcrmid = $id)";
|
||
if($related_module == 'Leads') {
|
||
$query .= " AND vtiger_leaddetails.converted=0 ";
|
||
}
|
||
|
||
$return_value = GetRelatedList($currentModule, $related_module, $other, $query, $button, $returnset);
|
||
|
||
if ($return_value == null)
|
||
$return_value = Array();
|
||
$return_value['CUSTOM_BUTTON'] = $button;
|
||
|
||
return $return_value;
|
||
}
|
||
|
||
/**
|
||
* Default (generic) function to handle the dependents list for the module.
|
||
* NOTE: UI type '10' is used to stored the references to other modules for a given record.
|
||
* These dependent records can be retrieved through this function.
|
||
* For eg: A trouble ticket can be related to an Account or a Contact.
|
||
* From a given Contact/Account if we need to fetch all such dependent trouble tickets, get_dependents_list function can be used.
|
||
*/
|
||
function get_dependents_list($id, $cur_tab_id, $rel_tab_id, $relationId) {
|
||
global $currentModule, $app_strings, $singlepane_view, $current_user;
|
||
|
||
$parenttab = getParentTab();
|
||
|
||
$related_module = vtlib_getModuleNameById($rel_tab_id);
|
||
$other = CRMEntity::getInstance($related_module);
|
||
|
||
// Some standard module class doesn't have required variables
|
||
// that are used in the query, they are defined in this generic API
|
||
vtlib_setup_modulevars($currentModule, $this);
|
||
vtlib_setup_modulevars($related_module, $other);
|
||
|
||
$singular_modname = 'SINGLE_' . $related_module;
|
||
|
||
$button = '';
|
||
|
||
// To make the edit or del link actions to return back to same view.
|
||
if ($singlepane_view == 'true')
|
||
$returnset = "&return_module=$currentModule&return_action=DetailView&return_id=$id";
|
||
else
|
||
$returnset = "&return_module=$currentModule&return_action=CallRelatedList&return_id=$id";
|
||
|
||
$return_value = null;
|
||
$relationFieldSql = "SELECT relationfieldid FROM vtiger_relatedlists WHERE relation_id=?";
|
||
$result = $this->db->pquery($relationFieldSql,array($relationId));
|
||
$num_rows = $this->db->num_rows($result);
|
||
$relationFieldId = null;
|
||
if($num_rows > 0) {
|
||
$relationFieldId = $this->db->query_result($result,0,'relationfieldid');
|
||
}
|
||
if(empty($relationFieldId)) {
|
||
$dependentFieldSql = $this->db->pquery("SELECT tabid, fieldname, columnname,tablename FROM vtiger_field WHERE uitype='10' AND" .
|
||
" fieldid IN (SELECT fieldid FROM vtiger_fieldmodulerel WHERE relmodule=? AND module=?)", array($currentModule, $related_module));
|
||
} else {
|
||
$dependentFieldSql = $this->db->pquery("SELECT tabid, fieldname, columnname,tablename FROM vtiger_field WHERE uitype='10' AND" .
|
||
" fieldid IN (SELECT relationfieldid FROM vtiger_relatedlists WHERE relation_id=?)", array($relationId));
|
||
}
|
||
$numOfFields = $this->db->num_rows($dependentFieldSql);
|
||
|
||
if ($numOfFields > 0) {
|
||
$dependentColumn = $this->db->query_result($dependentFieldSql, 0, 'columnname');
|
||
$dependentField = $this->db->query_result($dependentFieldSql, 0, 'fieldname');
|
||
$dependentTableName = $this->db->query_result($dependentFieldSql, 0, 'tablename');
|
||
|
||
$button .= '<input type="hidden" name="' . $dependentColumn . '" id="' . $dependentColumn . '" value="' . $id . '">';
|
||
$button .= '<input type="hidden" name="' . $dependentColumn . '_type" id="' . $dependentColumn . '_type" value="' . $currentModule . '">';
|
||
|
||
$query = "SELECT vtiger_crmentity.*, $other->table_name.*";
|
||
|
||
$userNameSql = getSqlForNameInDisplayFormat(array('first_name'=>'vtiger_users.first_name',
|
||
'last_name' => 'vtiger_users.last_name'), 'Users');
|
||
$query .= ", CASE WHEN (vtiger_users.user_name NOT LIKE '') THEN $userNameSql ELSE vtiger_groups.groupname END AS user_name";
|
||
|
||
$more_relation = '';
|
||
if (!empty($other->related_tables)) {
|
||
foreach ($other->related_tables as $tname => $relmap) {
|
||
$query .= ", $tname.*";
|
||
|
||
// Setup the default JOIN conditions if not specified
|
||
if (empty($relmap[1]))
|
||
$relmap[1] = $other->table_name;
|
||
if (empty($relmap[2]))
|
||
$relmap[2] = $relmap[0];
|
||
$more_relation .= " LEFT JOIN $tname ON $tname.$relmap[0] = $relmap[1].$relmap[2]";
|
||
}
|
||
}
|
||
|
||
$query .= " FROM $other->table_name";
|
||
$query .= " INNER JOIN vtiger_crmentity ON vtiger_crmentity.crmid = $other->table_name.$other->table_index";
|
||
$query .= $more_relation;
|
||
$query .= " INNER JOIN $this->table_name AS $this->table_name$this->moduleName ON $this->table_name$this->moduleName.$this->table_index = $dependentTableName.$dependentColumn";
|
||
$query .= " LEFT JOIN vtiger_users ON vtiger_users.id = vtiger_crmentity.smownerid";
|
||
$query .= " LEFT JOIN vtiger_groups ON vtiger_groups.groupid = vtiger_crmentity.smownerid";
|
||
|
||
$query .= " WHERE vtiger_crmentity.deleted = 0 AND $this->table_name$this->moduleName.$this->table_index = $id";
|
||
if($related_module == 'Leads') {
|
||
$query .= " AND vtiger_leaddetails.converted=0 ";
|
||
}
|
||
$return_value = GetRelatedList($currentModule, $related_module, $other, $query, $button, $returnset);
|
||
}
|
||
if ($return_value == null)
|
||
$return_value = Array();
|
||
$return_value['CUSTOM_BUTTON'] = $button;
|
||
|
||
return $return_value;
|
||
}
|
||
|
||
/**
|
||
* Move the related records of the specified list of id's to the given record.
|
||
* @param String This module name
|
||
* @param Array List of Entity Id's from which related records need to be transfered
|
||
* @param Integer Id of the the Record to which the related records are to be moved
|
||
*/
|
||
function transferRelatedRecords($module, $transferEntityIds, $entityId) {
|
||
global $adb, $log;
|
||
$log->debug("Entering function transferRelatedRecords ($module, $transferEntityIds, $entityId)");
|
||
foreach ($transferEntityIds as $transferId) {
|
||
|
||
// Pick the records related to the entity to be transfered, but do not pick the once which are already related to the current entity.
|
||
$relatedRecords = $adb->pquery("SELECT relcrmid, relmodule FROM vtiger_crmentityrel WHERE crmid=? AND module=?" .
|
||
" AND relcrmid NOT IN (SELECT relcrmid FROM vtiger_crmentityrel WHERE crmid=? AND module=?)", array($transferId, $module, $entityId, $module));
|
||
$numOfRecords = $adb->num_rows($relatedRecords);
|
||
for ($i = 0; $i < $numOfRecords; $i++) {
|
||
$relcrmid = $adb->query_result($relatedRecords, $i, 'relcrmid');
|
||
$relmodule = $adb->query_result($relatedRecords, $i, 'relmodule');
|
||
$adb->pquery("UPDATE vtiger_crmentityrel SET crmid=? WHERE relcrmid=? AND relmodule=? AND crmid=? AND module=?", array($entityId, $relcrmid, $relmodule, $transferId, $module));
|
||
}
|
||
|
||
// Pick the records to which the entity to be transfered is related, but do not pick the once to which current entity is already related.
|
||
$parentRecords = $adb->pquery("SELECT crmid, module FROM vtiger_crmentityrel WHERE relcrmid=? AND relmodule=?" .
|
||
" AND crmid NOT IN (SELECT crmid FROM vtiger_crmentityrel WHERE relcrmid=? AND relmodule=?)", array($transferId, $module, $entityId, $module));
|
||
$numOfRecords = $adb->num_rows($parentRecords);
|
||
for ($i = 0; $i < $numOfRecords; $i++) {
|
||
$parcrmid = $adb->query_result($parentRecords, $i, 'crmid');
|
||
$parmodule = $adb->query_result($parentRecords, $i, 'module');
|
||
$adb->pquery("UPDATE vtiger_crmentityrel SET relcrmid=? WHERE crmid=? AND module=? AND relcrmid=? AND relmodule=?", array($entityId, $parcrmid, $parmodule, $transferId, $module));
|
||
}
|
||
$adb->pquery("UPDATE vtiger_modcomments SET related_to = ? WHERE related_to = ?", array($entityId, $transferId));
|
||
}
|
||
$log->debug("Exiting transferRelatedRecords...");
|
||
}
|
||
|
||
/*
|
||
* Function to get the primary query part of a report for which generateReportsQuery Doesnt exist in module
|
||
* @param - $module Primary module name
|
||
* returns the query string formed on fetching the related data for report for primary module
|
||
*/
|
||
|
||
function generateReportsQuery($module, $queryPlanner) {
|
||
global $adb;
|
||
$primary = CRMEntity::getInstance($module);
|
||
|
||
vtlib_setup_modulevars($module, $primary);
|
||
$moduletable = $primary->table_name;
|
||
$moduleindex = $primary->table_index;
|
||
$modulecftable = $primary->customFieldTable[0];
|
||
$modulecfindex = $primary->customFieldTable[1];
|
||
|
||
if (isset($modulecftable) && $queryPlanner->requireTable($modulecftable)) {
|
||
$cfquery = "inner join $modulecftable as $modulecftable on $modulecftable.$modulecfindex=$moduletable.$moduleindex";
|
||
} else {
|
||
$cfquery = '';
|
||
}
|
||
|
||
$relquery = '';
|
||
$matrix = $queryPlanner->newDependencyMatrix();
|
||
|
||
$fields_query = $adb->pquery("SELECT vtiger_field.fieldname,vtiger_field.tablename,vtiger_field.fieldid from vtiger_field INNER JOIN vtiger_tab on vtiger_tab.name = ? WHERE vtiger_tab.tabid=vtiger_field.tabid AND vtiger_field.uitype IN (10) and vtiger_field.presence in (0,2)", array($module));
|
||
|
||
if ($adb->num_rows($fields_query) > 0) {
|
||
for ($i = 0; $i < $adb->num_rows($fields_query); $i++) {
|
||
$field_name = $adb->query_result($fields_query, $i, 'fieldname');
|
||
$field_id = $adb->query_result($fields_query, $i, 'fieldid');
|
||
$tab_name = $adb->query_result($fields_query, $i, 'tablename');
|
||
$ui10_modules_query = $adb->pquery("SELECT relmodule FROM vtiger_fieldmodulerel WHERE fieldid=?", array($field_id));
|
||
|
||
if ($adb->num_rows($ui10_modules_query) > 0) {
|
||
|
||
// Capture the forward table dependencies due to dynamic related-field
|
||
$crmentityRelModuleFieldTable = "vtiger_crmentityRel$module$field_id";
|
||
|
||
$crmentityRelModuleFieldTableDeps = array();
|
||
for ($j = 0; $j < $adb->num_rows($ui10_modules_query); $j++) {
|
||
$rel_mod = $adb->query_result($ui10_modules_query, $j, 'relmodule');
|
||
$rel_obj = CRMEntity::getInstance($rel_mod);
|
||
vtlib_setup_modulevars($rel_mod, $rel_obj);
|
||
|
||
$rel_tab_name = $rel_obj->table_name;
|
||
$rel_tab_index = $rel_obj->table_index;
|
||
$crmentityRelModuleFieldTableDeps[] = $rel_tab_name . "Rel$module$field_id";
|
||
}
|
||
|
||
$matrix->setDependency($crmentityRelModuleFieldTable, $crmentityRelModuleFieldTableDeps);
|
||
$matrix->addDependency($tab_name, $crmentityRelModuleFieldTable);
|
||
|
||
if ($queryPlanner->requireTable($crmentityRelModuleFieldTable, $matrix)) {
|
||
$relquery.= " left join vtiger_crmentity as $crmentityRelModuleFieldTable on $crmentityRelModuleFieldTable.crmid = $tab_name.$field_name and vtiger_crmentityRel$module$field_id.deleted=0";
|
||
}
|
||
|
||
for ($j = 0; $j < $adb->num_rows($ui10_modules_query); $j++) {
|
||
$rel_mod = $adb->query_result($ui10_modules_query, $j, 'relmodule');
|
||
$rel_obj = CRMEntity::getInstance($rel_mod);
|
||
vtlib_setup_modulevars($rel_mod, $rel_obj);
|
||
|
||
$rel_tab_name = $rel_obj->table_name;
|
||
$rel_tab_index = $rel_obj->table_index;
|
||
|
||
$rel_tab_name_rel_module_table_alias = $rel_tab_name . "Rel$module$field_id";
|
||
|
||
if ($queryPlanner->requireTable($rel_tab_name_rel_module_table_alias)) {
|
||
$relquery.= " left join $rel_tab_name as $rel_tab_name_rel_module_table_alias on $rel_tab_name_rel_module_table_alias.$rel_tab_index = $crmentityRelModuleFieldTable.crmid";
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
$query = "from $moduletable inner join vtiger_crmentity on vtiger_crmentity.crmid=$moduletable.$moduleindex";
|
||
|
||
// Add the pre-joined custom table query
|
||
$query .= " "."$cfquery";
|
||
|
||
if ($queryPlanner->requireTable('vtiger_groups'.$module)) {
|
||
$query .= " left join vtiger_groups as vtiger_groups" . $module . " on vtiger_groups" . $module . ".groupid = vtiger_crmentity.smownerid";
|
||
}
|
||
|
||
if ($queryPlanner->requireTable('vtiger_users'.$module)) {
|
||
$query .= " left join vtiger_users as vtiger_users" . $module . " on vtiger_users" . $module . ".id = vtiger_crmentity.smownerid";
|
||
}
|
||
if ($queryPlanner->requireTable('vtiger_lastModifiedBy'.$module)) {
|
||
$query .= " left join vtiger_users as vtiger_lastModifiedBy" . $module . " on vtiger_lastModifiedBy" . $module . ".id = vtiger_crmentity.modifiedby";
|
||
}
|
||
if ($queryPlanner->requireTable('vtiger_createdby'.$module)) {
|
||
$query .= " LEFT JOIN vtiger_users AS vtiger_createdby$module ON vtiger_createdby$module.id=vtiger_crmentity.smcreatorid";
|
||
}
|
||
// TODO Optimize the tables below based on requirement
|
||
$query .= " left join vtiger_groups on vtiger_groups.groupid = vtiger_crmentity.smownerid";
|
||
$query .= " left join vtiger_users on vtiger_users.id = vtiger_crmentity.smownerid";
|
||
|
||
// Add the pre-joined relation table query
|
||
$query .= " " . $relquery;
|
||
|
||
return $query;
|
||
}
|
||
|
||
/*
|
||
* Function to get the secondary query part of a report for which generateReportsSecQuery Doesnt exist in module
|
||
* @param - $module primary module name
|
||
* @param - $secmodule secondary module name
|
||
* returns the query string formed on fetching the related data for report for secondary module
|
||
*/
|
||
|
||
function generateReportsSecQuery($module, $secmodule,$queryPlanner) {
|
||
global $adb;
|
||
$secondary = CRMEntity::getInstance($secmodule);
|
||
|
||
vtlib_setup_modulevars($secmodule, $secondary);
|
||
|
||
$tablename = $secondary->table_name;
|
||
$tableindex = $secondary->table_index;
|
||
$modulecftable = $secondary->customFieldTable[0];
|
||
$modulecfindex = $secondary->customFieldTable[1];
|
||
|
||
if (isset($modulecftable) && $queryPlanner->requireTable($modulecftable)) {
|
||
$cfquery = "left join $modulecftable as $modulecftable on $modulecftable.$modulecfindex=$tablename.$tableindex";
|
||
} else {
|
||
$cfquery = '';
|
||
}
|
||
|
||
$relquery = '';
|
||
$matrix = $queryPlanner->newDependencyMatrix();
|
||
|
||
$fields_query = $adb->pquery("SELECT vtiger_field.fieldname,vtiger_field.tablename,vtiger_field.fieldid from vtiger_field INNER JOIN vtiger_tab on vtiger_tab.name = ? WHERE vtiger_tab.tabid=vtiger_field.tabid AND vtiger_field.uitype IN (10) and vtiger_field.presence in (0,2)", array($secmodule));
|
||
|
||
if ($adb->num_rows($fields_query) > 0) {
|
||
for ($i = 0; $i < $adb->num_rows($fields_query); $i++) {
|
||
$field_name = $adb->query_result($fields_query, $i, 'fieldname');
|
||
$field_id = $adb->query_result($fields_query, $i, 'fieldid');
|
||
$tab_name = $adb->query_result($fields_query, $i, 'tablename');
|
||
$ui10_modules_query = $adb->pquery("SELECT relmodule FROM vtiger_fieldmodulerel WHERE fieldid=?", array($field_id));
|
||
|
||
if ($adb->num_rows($ui10_modules_query) > 0) {
|
||
// Capture the forward table dependencies due to dynamic related-field
|
||
$crmentityRelSecModuleTable = "vtiger_crmentityRel$secmodule$field_id";
|
||
|
||
$crmentityRelSecModuleTableDeps = array();
|
||
for ($j = 0; $j < $adb->num_rows($ui10_modules_query); $j++) {
|
||
$rel_mod = $adb->query_result($ui10_modules_query, $j, 'relmodule');
|
||
$rel_obj = CRMEntity::getInstance($rel_mod);
|
||
vtlib_setup_modulevars($rel_mod, $rel_obj);
|
||
|
||
$rel_tab_name = $rel_obj->table_name;
|
||
$rel_tab_index = $rel_obj->table_index;
|
||
$crmentityRelSecModuleTableDeps[] = $rel_tab_name . "Rel$secmodule";
|
||
}
|
||
|
||
$matrix->setDependency($crmentityRelSecModuleTable, $crmentityRelSecModuleTableDeps);
|
||
$matrix->addDependency($tab_name, $crmentityRelSecModuleTable);
|
||
|
||
if ($queryPlanner->requireTable($crmentityRelSecModuleTable, $matrix)) {
|
||
$relquery .= " left join vtiger_crmentity as $crmentityRelSecModuleTable on $crmentityRelSecModuleTable.crmid = $tab_name.$field_name and $crmentityRelSecModuleTable.deleted=0";
|
||
}
|
||
for ($j = 0; $j < $adb->num_rows($ui10_modules_query); $j++) {
|
||
$rel_mod = $adb->query_result($ui10_modules_query, $j, 'relmodule');
|
||
$rel_obj = CRMEntity::getInstance($rel_mod);
|
||
vtlib_setup_modulevars($rel_mod, $rel_obj);
|
||
|
||
$rel_tab_name = $rel_obj->table_name;
|
||
$rel_tab_index = $rel_obj->table_index;
|
||
|
||
$rel_tab_name_rel_secmodule_table_alias = $rel_tab_name . "Rel$secmodule$field_id";
|
||
if ($queryPlanner->requireTable($rel_tab_name_rel_secmodule_table_alias)) {
|
||
$relquery .= " left join $rel_tab_name as $rel_tab_name_rel_secmodule_table_alias on $rel_tab_name_rel_secmodule_table_alias.$rel_tab_index = $crmentityRelSecModuleTable.crmid";
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// Update forward table dependencies
|
||
$matrix->setDependency("vtiger_crmentity$secmodule", array("vtiger_groups$secmodule", "vtiger_users$secmodule", "vtiger_lastModifiedBy$secmodule"));
|
||
$matrix->addDependency($tablename, "vtiger_crmentity$secmodule");
|
||
|
||
if (!$queryPlanner->requireTable($tablename, $matrix) && !$queryPlanner->requireTable($modulecftable)) {
|
||
return '';
|
||
}
|
||
|
||
$query = $this->getRelationQuery($module, $secmodule, "$tablename", "$tableindex", $queryPlanner);
|
||
|
||
if ($queryPlanner->requireTable("vtiger_crmentity$secmodule", $matrix)) {
|
||
$query .= " left join vtiger_crmentity as vtiger_crmentity$secmodule on vtiger_crmentity$secmodule.crmid = $tablename.$tableindex AND vtiger_crmentity$secmodule.deleted=0";
|
||
}
|
||
|
||
// Add the pre-joined custom table query
|
||
$query .= " ".$cfquery;
|
||
|
||
if ($queryPlanner->requireTable("vtiger_groups$secmodule")) {
|
||
$query .= " left join vtiger_groups as vtiger_groups" . $secmodule . " on vtiger_groups" . $secmodule . ".groupid = vtiger_crmentity$secmodule.smownerid";
|
||
}
|
||
if ($queryPlanner->requireTable("vtiger_users$secmodule")) {
|
||
$query .= " left join vtiger_users as vtiger_users" . $secmodule . " on vtiger_users" . $secmodule . ".id = vtiger_crmentity$secmodule.smownerid";
|
||
}
|
||
if ($queryPlanner->requireTable("vtiger_lastModifiedBy$secmodule")) {
|
||
$query .= " left join vtiger_users as vtiger_lastModifiedBy" . $secmodule . " on vtiger_lastModifiedBy" . $secmodule . ".id = vtiger_crmentity" . $secmodule . ".modifiedby";
|
||
}
|
||
if ($queryPlanner->requireTable('vtiger_createdby'.$secmodule)) {
|
||
$query .= " LEFT JOIN vtiger_users AS vtiger_createdby$secmodule ON vtiger_createdby$secmodule.id=vtiger_crmentity.smcreatorid";
|
||
}
|
||
// Add the pre-joined relation table query
|
||
$query .= " " . $relquery;
|
||
|
||
return $query;
|
||
}
|
||
|
||
function getReportsUiType10Query($module, $queryPlanner){
|
||
$adb = PearDatabase::getInstance();
|
||
$relquery = '';
|
||
$matrix = $queryPlanner->newDependencyMatrix();
|
||
|
||
$params = array($module);
|
||
if($module == "Calendar") {
|
||
array_push($params,"Events");
|
||
}
|
||
|
||
$fields_query = $adb->pquery("SELECT vtiger_field.fieldname,vtiger_field.tablename,vtiger_field.fieldid from vtiger_field INNER JOIN vtiger_tab on vtiger_tab.name IN (". generateQuestionMarks($params).") WHERE vtiger_tab.tabid=vtiger_field.tabid AND vtiger_field.uitype IN (10) AND vtiger_field.presence IN (0,2)", $params);
|
||
|
||
if ($adb->num_rows($fields_query) > 0) {
|
||
for ($i = 0; $i < $adb->num_rows($fields_query); $i++) {
|
||
$field_name = $adb->query_result($fields_query, $i, 'fieldname');
|
||
$field_id = $adb->query_result($fields_query, $i, 'fieldid');
|
||
$tab_name = $adb->query_result($fields_query, $i, 'tablename');
|
||
$ui10_modules_query = $adb->pquery("SELECT relmodule FROM vtiger_fieldmodulerel WHERE fieldid=?", array($field_id));
|
||
|
||
if ($adb->num_rows($ui10_modules_query) > 0) {
|
||
|
||
// Capture the forward table dependencies due to dynamic related-field
|
||
$crmentityRelModuleFieldTable = "vtiger_crmentityRel$module$field_id";
|
||
|
||
$crmentityRelModuleFieldTableDeps = array();
|
||
$calendarFlag = false;
|
||
for ($j = 0; $j < $adb->num_rows($ui10_modules_query); $j++) {
|
||
$rel_mod = $adb->query_result($ui10_modules_query, $j, 'relmodule');
|
||
if(vtlib_isModuleActive($rel_mod)) {
|
||
if($rel_mod == 'Calendar') {
|
||
$calendarFlag = true;
|
||
}
|
||
if($calendarFlag && $rel_mod == 'Events') {
|
||
continue;
|
||
}
|
||
$rel_obj = CRMEntity::getInstance($rel_mod);
|
||
vtlib_setup_modulevars($rel_mod, $rel_obj);
|
||
|
||
$rel_tab_name = $rel_obj->table_name;
|
||
$rel_tab_index = $rel_obj->table_index;
|
||
$crmentityRelModuleFieldTableDeps[] = $rel_tab_name . "Rel$module$field_id";
|
||
}
|
||
}
|
||
|
||
$matrix->setDependency($crmentityRelModuleFieldTable, $crmentityRelModuleFieldTableDeps);
|
||
$matrix->addDependency($tab_name, $crmentityRelModuleFieldTable);
|
||
|
||
if ($queryPlanner->requireTable($crmentityRelModuleFieldTable, $matrix)) {
|
||
$relquery.= " LEFT JOIN vtiger_crmentity AS $crmentityRelModuleFieldTable ON $crmentityRelModuleFieldTable.crmid = $tab_name.$field_name AND vtiger_crmentityRel$module$field_id.deleted=0";
|
||
}
|
||
|
||
$calendarFlag = false;
|
||
for ($j = 0; $j < $adb->num_rows($ui10_modules_query); $j++) {
|
||
$rel_mod = $adb->query_result($ui10_modules_query, $j, 'relmodule');
|
||
if(vtlib_isModuleActive($rel_mod)) {
|
||
if($rel_mod == 'Calendar') {
|
||
$calendarFlag = true;
|
||
}
|
||
if($calendarFlag && $rel_mod == 'Events') {
|
||
continue;
|
||
}
|
||
$rel_obj = CRMEntity::getInstance($rel_mod);
|
||
vtlib_setup_modulevars($rel_mod, $rel_obj);
|
||
|
||
$rel_tab_name = $rel_obj->table_name;
|
||
$rel_tab_index = $rel_obj->table_index;
|
||
|
||
$rel_tab_name_rel_module_table_alias = $rel_tab_name . "Rel$module$field_id";
|
||
|
||
if ($queryPlanner->requireTable($rel_tab_name_rel_module_table_alias)) {
|
||
$relquery.= " LEFT JOIN $rel_tab_name AS $rel_tab_name_rel_module_table_alias ON $rel_tab_name_rel_module_table_alias.$rel_tab_index = $crmentityRelModuleFieldTable.crmid";
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
return $relquery;
|
||
}
|
||
|
||
/*
|
||
* Function to get the security query part of a report
|
||
* @param - $module primary module name
|
||
* returns the query string formed on fetching the related data for report for security of the module
|
||
*/
|
||
|
||
function getListViewSecurityParameter($module) {
|
||
$tabid = getTabid($module);
|
||
global $current_user;
|
||
if ($current_user) {
|
||
require('user_privileges/user_privileges_' . $current_user->id . '.php');
|
||
require('user_privileges/sharing_privileges_' . $current_user->id . '.php');
|
||
}
|
||
$sec_query = '';
|
||
if($is_admin==false && $profileGlobalPermission[1] == 1 && $profileGlobalPermission[2] == 1
|
||
&& $defaultOrgSharingPermission[$tabid] == 3) {
|
||
$sec_query .= " and (vtiger_crmentity.smownerid in($current_user->id) or vtiger_crmentity.smownerid
|
||
in (select vtiger_user2role.userid from vtiger_user2role
|
||
inner join vtiger_users on vtiger_users.id=vtiger_user2role.userid
|
||
inner join vtiger_role on vtiger_role.roleid=vtiger_user2role.roleid
|
||
where vtiger_role.parentrole like '" . $current_user_parent_role_seq . "::%') or vtiger_crmentity.smownerid
|
||
in(select shareduserid from vtiger_tmp_read_user_sharing_per
|
||
where userid=" . $current_user->id . " and tabid=" . $tabid . ") or (";
|
||
if (sizeof($current_user_groups) > 0) {
|
||
$sec_query .= " vtiger_crmentity.smownerid in (" . implode(",", $current_user_groups) . ") or ";
|
||
}
|
||
$sec_query .= " vtiger_crmentity.smownerid in(select vtiger_tmp_read_group_sharing_per.sharedgroupid
|
||
from vtiger_tmp_read_group_sharing_per where userid=" . $current_user->id . " and tabid=" . $tabid . "))) ";
|
||
}
|
||
return $sec_query;
|
||
}
|
||
|
||
/*
|
||
* Function to get the relation query part of a report
|
||
* @param - $module primary module name
|
||
* @param - $secmodule secondary module name
|
||
* returns the query string formed on relating the primary module and secondary module
|
||
*/
|
||
|
||
function getRelationQuery($module, $secmodule, $table_name, $column_name, $queryPlanner) {
|
||
$tab = getRelationTables($module, $secmodule);
|
||
|
||
foreach ($tab as $key => $value) {
|
||
$tables[] = $key;
|
||
$fields[] = $value;
|
||
}
|
||
$pritablename = $tables[0];
|
||
$sectablename = $tables[1];
|
||
$prifieldname = $fields[0][0];
|
||
$secfieldname = $fields[0][1];
|
||
$tmpname = $pritablename . 'tmp' . $secmodule;
|
||
$condition = "";
|
||
if (!empty($tables[1]) && !empty($fields[1])) {
|
||
$condvalue = $tables[1] . "." . $fields[1];
|
||
$condition = "$table_name.$prifieldname=$condvalue";
|
||
} else {
|
||
$condvalue = $table_name . "." . $column_name;
|
||
$condition = "$pritablename.$secfieldname=$condvalue";
|
||
}
|
||
|
||
$selectColumns = "$table_name.*";
|
||
|
||
// Look forward for temporary table usage as defined by the QueryPlanner
|
||
$secQueryFrom = " FROM $table_name INNER JOIN vtiger_crmentity ON " .
|
||
"vtiger_crmentity.crmid=$table_name.$column_name AND vtiger_crmentity.deleted=0 ";
|
||
|
||
//The relation field exists in custom field . relation field added from layout editor
|
||
if($pritablename != $table_name) {
|
||
$modulecftable = $this->customFieldTable[0];
|
||
$modulecfindex = $this->customFieldTable[1];
|
||
|
||
if (isset($modulecftable)) {
|
||
$columns = $this->db->getColumnNames($modulecftable);
|
||
//remove the primary key since it will conflict with base table column name or else creating temporary table will fails for duplicate columns
|
||
//eg : vtiger_potential has potentialid and vtiger_potentialscf has same potentialid
|
||
unset($columns[array_search($modulecfindex,$columns)]);
|
||
if(count($columns) > 0) {
|
||
$cfSelectString = implode(',',$columns);
|
||
$selectColumns .= ','.$cfSelectString;
|
||
}
|
||
$cfquery = "LEFT JOIN $modulecftable ON $modulecftable.$modulecfindex=$table_name.$column_name";
|
||
$secQueryFrom .= $cfquery;
|
||
}
|
||
}
|
||
|
||
$secQuery = 'SELECT '.$selectColumns.' '.$secQueryFrom;
|
||
|
||
$secQueryTempTableQuery = $queryPlanner->registerTempTable($secQuery, array($column_name, $fields[1], $prifieldname),$secmodule);
|
||
|
||
$query = '';
|
||
if ($pritablename == 'vtiger_crmentityrel') {
|
||
$tableName = $table_name;
|
||
if($secmodule == "Emails") {
|
||
$tableName .='Emails';
|
||
}
|
||
$condition = "($tableName.$column_name={$tmpname}.{$secfieldname} " .
|
||
"OR $tableName.$column_name={$tmpname}.{$prifieldname})";
|
||
$query = " left join vtiger_crmentityrel as $tmpname ON (($condvalue={$tmpname}.{$secfieldname} " .
|
||
"OR $condvalue={$tmpname}.{$prifieldname})) AND ({$tmpname}.module='{$secmodule}' OR {$tmpname}.relmodule='{$secmodule}') ";
|
||
} elseif (strripos($pritablename, 'rel') === (strlen($pritablename) - 3)) {
|
||
$instance = self::getInstance($module);
|
||
$sectableindex = $instance->tab_name_index[$sectablename];
|
||
$condition = "$table_name.$column_name=$tmpname.$secfieldname";
|
||
if($secmodule == "Emails"){
|
||
$condition = $table_name.'Emails'.".$column_name=$tmpname.$secfieldname";
|
||
}
|
||
if($pritablename == 'vtiger_seactivityrel') {
|
||
if($module == "Emails" || $secmodule == "Emails"){
|
||
$tmpModule = "Emails";
|
||
}else{
|
||
$tmpModule = "Calendar";
|
||
}
|
||
$query = " left join $pritablename as $tmpname ON ($sectablename.$sectableindex=$tmpname.$prifieldname
|
||
AND $tmpname.activityid IN (SELECT crmid FROM vtiger_crmentity WHERE setype='$tmpModule' AND deleted = 0))";
|
||
} else if($pritablename == 'vtiger_senotesrel') {
|
||
$query = " left join $pritablename as $tmpname ON ($sectablename.$sectableindex=$tmpname.$prifieldname
|
||
AND $tmpname.notesid IN (SELECT crmid FROM vtiger_crmentity WHERE setype='Documents' AND deleted = 0))";
|
||
} else if($pritablename == 'vtiger_inventoryproductrel' && ($module =="Products" || $module =="Services") && ($secmodule == "Invoice" || $secmodule == "SalesOrder" || $secmodule == "PurchaseOrder" || $secmodule == "Quotes")) {
|
||
/** In vtiger_inventoryproductrel table, we'll have same product related to quotes/invoice/salesorder/purchaseorder
|
||
* we need to check whether the product joining is related to secondary module selected or not to eliminate duplicates
|
||
*/
|
||
$query = " left join $pritablename as $tmpname ON ($sectablename.$sectableindex=$tmpname.$prifieldname AND $tmpname.id in
|
||
(select crmid from vtiger_crmentity where setype='$secmodule' and deleted=0))";
|
||
} else if($pritablename == 'vtiger_cntactivityrel') {
|
||
if($queryPlanner->requireTable('vtiger_cntactivityrel') && $secmodule == 'Contacts') {
|
||
$tmpname = 'vtiger_cntactivityrel';
|
||
$condition = "$table_name.$column_name=$tmpname.$secfieldname";
|
||
} else {
|
||
$query = " left join $pritablename as $tmpname ON ($sectablename.$sectableindex=$tmpname.$prifieldname)";
|
||
}
|
||
} else {
|
||
$query = " LEFT JOIN $pritablename AS $tmpname ON ($sectablename.$sectableindex=$tmpname.$prifieldname)";
|
||
}
|
||
if($secmodule == 'Calendar'){
|
||
$condition .= " AND $table_name.activitytype != 'Emails'";
|
||
}else if($secmodule == 'Leads'){
|
||
$condition .= " AND $table_name.converted = 0";
|
||
}
|
||
|
||
}else if($module == "Contacts" && $secmodule == "Potentials"){
|
||
// To get all the Contacts from vtiger_contpotentialrel table
|
||
$condition .= " OR $table_name.potentialid = vtiger_contpotentialrel.potentialid";
|
||
$query .= " left join vtiger_contpotentialrel on vtiger_contpotentialrel.contactid = vtiger_contactdetails.contactid";
|
||
}else if($module == "Potentials" && $secmodule == "Contacts"){
|
||
// To get all the Potentials from vtiger_contpotentialrel table
|
||
$condition .= " OR $table_name.contactid = vtiger_contpotentialrel.contactid";
|
||
$query .= " left join vtiger_contpotentialrel on vtiger_potential.potentialid = vtiger_contpotentialrel.potentialid";
|
||
}
|
||
if ($secmodule == "Emails") {
|
||
$table_name .="Emails";
|
||
}
|
||
$query .= " left join $secQueryTempTableQuery as $table_name on {$condition}";
|
||
return $query;
|
||
}
|
||
|
||
/** END * */
|
||
|
||
/**
|
||
* This function handles the import for uitype 10 fieldtype
|
||
* @param string $module - the current module name
|
||
* @param string fieldname - the related to field name
|
||
*/
|
||
function add_related_to($module, $fieldname) {
|
||
global $adb, $imported_ids, $current_user;
|
||
|
||
$related_to = $this->column_fields[$fieldname];
|
||
|
||
if (empty($related_to)) {
|
||
return false;
|
||
}
|
||
|
||
//check if the field has module information; if not get the first module
|
||
if (!strpos($related_to, "::::")) {
|
||
$module = getFirstModule($module, $fieldname);
|
||
$value = $related_to;
|
||
} else {
|
||
//check the module of the field
|
||
$arr = array();
|
||
$arr = explode("::::", $related_to);
|
||
$module = $arr[0];
|
||
$value = $arr[1];
|
||
}
|
||
|
||
$focus1 = CRMEntity::getInstance($module);
|
||
|
||
$entityNameArr = getEntityField($module);
|
||
$entityName = $entityNameArr['fieldname'];
|
||
$query = "SELECT vtiger_crmentity.deleted, $focus1->table_name.*
|
||
FROM $focus1->table_name
|
||
INNER JOIN vtiger_crmentity ON vtiger_crmentity.crmid=$focus1->table_name.$focus1->table_index
|
||
where $entityName=? and vtiger_crmentity.deleted=0";
|
||
$result = $adb->pquery($query, array($value));
|
||
|
||
if (!isset($this->checkFlagArr[$module])) {
|
||
$this->checkFlagArr[$module] = (isPermitted($module, 'EditView', '') == 'yes');
|
||
}
|
||
|
||
if ($adb->num_rows($result) > 0) {
|
||
//record found
|
||
$focus1->id = $adb->query_result($result, 0, $focus1->table_index);
|
||
} elseif ($this->checkFlagArr[$module]) {
|
||
//record not found; create it
|
||
$focus1->column_fields[$focus1->list_link_field] = $value;
|
||
$focus1->column_fields['assigned_user_id'] = $current_user->id;
|
||
$focus1->column_fields['modified_user_id'] = $current_user->id;
|
||
$focus1->save($module);
|
||
|
||
$last_import = new UsersLastImport();
|
||
$last_import->assigned_user_id = $current_user->id;
|
||
$last_import->bean_type = $module;
|
||
$last_import->bean_id = $focus1->id;
|
||
$last_import->save();
|
||
} else {
|
||
//record not found and cannot create
|
||
$this->column_fields[$fieldname] = "";
|
||
return false;
|
||
}
|
||
if (!empty($focus1->id)) {
|
||
$this->column_fields[$fieldname] = $focus1->id;
|
||
return true;
|
||
} else {
|
||
$this->column_fields[$fieldname] = "";
|
||
return false;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* To keep track of action of field filtering and avoiding doing more than once.
|
||
*
|
||
* @var Array
|
||
*/
|
||
protected $__inactive_fields_filtered = false;
|
||
|
||
/**
|
||
* Filter in-active fields based on type
|
||
*
|
||
* @param String $module
|
||
*/
|
||
function filterInactiveFields($module) {
|
||
if ($this->__inactive_fields_filtered) {
|
||
return;
|
||
}
|
||
|
||
global $adb, $mod_strings;
|
||
|
||
// Look for fields that has presence value NOT IN (0,2)
|
||
$cachedModuleFields = VTCacheUtils::lookupFieldInfo_Module($module, array('1'));
|
||
if ($cachedModuleFields === false) {
|
||
// Initialize the fields calling suitable API
|
||
getColumnFields($module);
|
||
$cachedModuleFields = VTCacheUtils::lookupFieldInfo_Module($module, array('1'));
|
||
}
|
||
|
||
$hiddenFields = array();
|
||
|
||
if ($cachedModuleFields) {
|
||
foreach ($cachedModuleFields as $fieldinfo) {
|
||
$fieldLabel = $fieldinfo['fieldlabel'];
|
||
// NOTE: We should not translate the label to enable field diff based on it down
|
||
$fieldName = $fieldinfo['fieldname'];
|
||
$tableName = str_replace("vtiger_", "", $fieldinfo['tablename']);
|
||
$hiddenFields[$fieldLabel] = array($tableName => $fieldName);
|
||
}
|
||
}
|
||
|
||
if (isset($this->list_fields)) {
|
||
$this->list_fields = array_diff_assoc($this->list_fields, $hiddenFields);
|
||
}
|
||
|
||
if (isset($this->search_fields)) {
|
||
$this->search_fields = array_diff_assoc($this->search_fields, $hiddenFields);
|
||
}
|
||
|
||
// To avoid re-initializing everytime.
|
||
$this->__inactive_fields_filtered = true;
|
||
}
|
||
|
||
/** END * */
|
||
function buildSearchQueryForFieldTypes($uitypes, $value=false) {
|
||
global $adb;
|
||
|
||
if (!is_array($uitypes))
|
||
$uitypes = array($uitypes);
|
||
$module = $this->moduleName;
|
||
|
||
$cachedModuleFields = VTCacheUtils::lookupFieldInfo_Module($module);
|
||
if ($cachedModuleFields === false) {
|
||
getColumnFields($module); // This API will initialize the cache as well
|
||
// We will succeed now due to above function call
|
||
$cachedModuleFields = VTCacheUtils::lookupFieldInfo_Module($module);
|
||
}
|
||
if($module == 'Calendar' || $module == 'Events') {
|
||
$cachedEventsFields = VTCacheUtils::lookupFieldInfo_Module('Events');
|
||
$cachedCalendarFields = VTCacheUtils::lookupFieldInfo_Module('Calendar');
|
||
$cachedModuleFields = array_merge($cachedEventsFields, $cachedCalendarFields);
|
||
}
|
||
|
||
$lookuptables = array();
|
||
$lookupcolumns = array();
|
||
foreach ($cachedModuleFields as $fieldinfo) {
|
||
if (in_array($fieldinfo['uitype'], $uitypes)) {
|
||
$lookuptables[] = $fieldinfo['tablename'];
|
||
$lookupcolumns[] = $fieldinfo['columnname'];
|
||
}
|
||
}
|
||
|
||
$entityfields = getEntityField($module);
|
||
$querycolumnnames = implode(',', $lookupcolumns);
|
||
$entitycolumnnames = $entityfields['fieldname'];
|
||
$query = "select crmid as id, $querycolumnnames, $entitycolumnnames as name ";
|
||
$query .= " FROM $this->table_name ";
|
||
$query .=" INNER JOIN vtiger_crmentity ON $this->table_name.$this->table_index = vtiger_crmentity.crmid AND deleted = 0 ";
|
||
|
||
//remove the base table
|
||
$LookupTable = array_unique($lookuptables);
|
||
$indexes = array_keys($LookupTable, $this->table_name);
|
||
if (!empty($indexes)) {
|
||
foreach ($indexes as $index) {
|
||
unset($LookupTable[$index]);
|
||
}
|
||
}
|
||
foreach ($LookupTable as $tablename) {
|
||
$query .= " INNER JOIN $tablename
|
||
on $this->table_name.$this->table_index = $tablename." . $this->tab_name_index[$tablename];
|
||
}
|
||
if (!empty($lookupcolumns) && $value !== false) {
|
||
$query .=" WHERE ";
|
||
$i = 0;
|
||
$columnCount = count($lookupcolumns);
|
||
foreach ($lookupcolumns as $columnname) {
|
||
if (!empty($columnname)) {
|
||
if ($i == 0 || $i == ($columnCount))
|
||
$query .= sprintf("%s = '%s'", $columnname, $value);
|
||
else
|
||
$query .= sprintf(" OR %s = '%s'", $columnname, $value);
|
||
$i++;
|
||
}
|
||
}
|
||
}
|
||
return $query;
|
||
}
|
||
|
||
/**
|
||
*
|
||
* @param String $tableName
|
||
* @return String
|
||
*/
|
||
public function getJoinClause($tableName) {
|
||
if (strripos($tableName, 'rel') === (strlen($tableName) - 3)) {
|
||
return 'LEFT JOIN';
|
||
} else if (Vtiger_Functions::isUserSpecificFieldTable($tableName, $this->moduleName)) {
|
||
return 'LEFT JOIN';
|
||
}
|
||
else {
|
||
return 'INNER JOIN';
|
||
}
|
||
}
|
||
|
||
/**
|
||
*
|
||
* @param <type> $module
|
||
* @param <type> $user
|
||
* @param <type> $parentRole
|
||
* @param <type> $userGroups
|
||
*/
|
||
function getNonAdminAccessQuery($module, $user, $parentRole, $userGroups) {
|
||
$query = $this->getNonAdminUserAccessQuery($user, $parentRole, $userGroups);
|
||
if (!empty($module)) {
|
||
$moduleAccessQuery = $this->getNonAdminModuleAccessQuery($module, $user);
|
||
if (!empty($moduleAccessQuery)) {
|
||
$query .= " UNION $moduleAccessQuery";
|
||
}
|
||
}
|
||
return $query;
|
||
}
|
||
|
||
/**
|
||
*
|
||
* @param <type> $user
|
||
* @param <type> $parentRole
|
||
* @param <type> $userGroups
|
||
*/
|
||
function getNonAdminUserAccessQuery($user, $parentRole, $userGroups) {
|
||
$query = "(SELECT $user->id as id) UNION (SELECT vtiger_user2role.userid AS userid FROM " .
|
||
"vtiger_user2role INNER JOIN vtiger_users ON vtiger_users.id=vtiger_user2role.userid " .
|
||
"INNER JOIN vtiger_role ON vtiger_role.roleid=vtiger_user2role.roleid WHERE " .
|
||
"vtiger_role.parentrole like '$parentRole::%')";
|
||
if (count($userGroups) > 0) {
|
||
$query .= $this->getNonAdminUserGroupAccessQuery($userGroups);
|
||
}
|
||
return $query;
|
||
}
|
||
|
||
/**
|
||
*Function to get all the users under groups
|
||
* @param <type> $userGroups
|
||
*/
|
||
function getNonAdminUserGroupAccessQuery($userGroups) {
|
||
$query .= " UNION (SELECT groupid FROM vtiger_groups WHERE groupid IN (".implode(",", $userGroups)."))";
|
||
return $query;
|
||
}
|
||
|
||
/**
|
||
*
|
||
* @param <type> $module
|
||
* @param <type> $user
|
||
*/
|
||
function getNonAdminModuleAccessQuery($module, $user) {
|
||
require('user_privileges/sharing_privileges_' . $user->id . '.php');
|
||
$tabId = getTabid($module);
|
||
$sharingRuleInfoVariable = $module . '_share_read_permission';
|
||
$sharingRuleInfo = $$sharingRuleInfoVariable;
|
||
$sharedTabId = null;
|
||
$query = '';
|
||
if (!empty($sharingRuleInfo) && (count($sharingRuleInfo['ROLE']) > 0 ||
|
||
count($sharingRuleInfo['GROUP']) > 0)) {
|
||
$query = " (SELECT shareduserid FROM vtiger_tmp_read_user_sharing_per " .
|
||
"WHERE userid=$user->id AND tabid=$tabId) UNION (SELECT " .
|
||
"vtiger_tmp_read_group_sharing_per.sharedgroupid FROM " .
|
||
"vtiger_tmp_read_group_sharing_per WHERE userid=$user->id AND tabid=$tabId)";
|
||
}
|
||
return $query;
|
||
}
|
||
|
||
/**
|
||
*
|
||
* @param <type> $module
|
||
* @param <type> $user
|
||
* @param <type> $parentRole
|
||
* @param <type> $userGroups
|
||
*/
|
||
protected function setupTemporaryTable($tableName, $tabId, $user, $parentRole, $userGroups) {
|
||
$module = null;
|
||
if (!empty($tabId)) {
|
||
$module = getTabModuleName($tabId);
|
||
}
|
||
$query = $this->getNonAdminAccessQuery($module, $user, $parentRole, $userGroups);
|
||
$tableName = Vtiger_Util_Helper::validateStringForSql($tableName);
|
||
$query = "create temporary table IF NOT EXISTS $tableName(id int(11) primary key) ignore " .
|
||
$query;
|
||
$db = PearDatabase::getInstance();
|
||
$result = $db->pquery($query, array());
|
||
if (is_object($result)) {
|
||
return true;
|
||
}
|
||
return false;
|
||
}
|
||
|
||
/**
|
||
*
|
||
* @param String $module - module name for which query needs to be generated.
|
||
* @param Users $user - user for which query needs to be generated.
|
||
* @return String Access control Query for the user.
|
||
*/
|
||
function getNonAdminAccessControlQuery($module, $user, $scope = '') {
|
||
require('user_privileges/user_privileges_' . $user->id . '.php');
|
||
require('user_privileges/sharing_privileges_' . $user->id . '.php');
|
||
$query = ' ';
|
||
$tabId = getTabid($module);
|
||
if ($is_admin == false && $profileGlobalPermission[1] == 1 && $profileGlobalPermission[2]
|
||
== 1 && $defaultOrgSharingPermission[$tabId] == 3) {
|
||
$tableName = 'vt_tmp_u' . $user->id;
|
||
$sharingRuleInfoVariable = $module . '_share_read_permission';
|
||
$sharingRuleInfo = $$sharingRuleInfoVariable;
|
||
$sharedTabId = null;
|
||
if (!empty($sharingRuleInfo) && (count($sharingRuleInfo['ROLE']) > 0 ||
|
||
count($sharingRuleInfo['GROUP']) > 0)) {
|
||
$tableName = $tableName . '_t' . $tabId;
|
||
$sharedTabId = $tabId;
|
||
} elseif ($module == 'Calendar' || !empty($scope)) {
|
||
$tableName .= '_t' . $tabId;
|
||
}
|
||
$this->setupTemporaryTable($tableName, $sharedTabId, $user, $current_user_parent_role_seq, $current_user_groups);
|
||
// for secondary module we should join the records even if record is not there(primary module without related record)
|
||
if($scope == ''){
|
||
$query = " INNER JOIN $tableName $tableName$scope ON $tableName$scope.id = " .
|
||
"vtiger_crmentity$scope.smownerid ";
|
||
}else{
|
||
$query = " INNER JOIN $tableName $tableName$scope ON $tableName$scope.id = " .
|
||
"vtiger_crmentity$scope.smownerid OR vtiger_crmentity$scope.smownerid IS NULL";
|
||
}
|
||
}
|
||
return $query;
|
||
}
|
||
|
||
public function listQueryNonAdminChange($query, $scope = '') {
|
||
//make the module base table as left hand side table for the joins,
|
||
//as mysql query optimizer puts crmentity on the left side and considerably slow down
|
||
$query = preg_replace('/\s+/', ' ', $query);
|
||
if (strripos($query, ' WHERE ') !== false) {
|
||
vtlib_setup_modulevars($this->moduleName, $this);
|
||
$query = str_ireplace(' where ', " WHERE $this->table_name.$this->table_index > 0 AND ", $query);
|
||
}
|
||
return $query;
|
||
}
|
||
|
||
/*
|
||
* Function to get the relation tables for related modules
|
||
* @param String $secmodule - $secmodule secondary module name
|
||
* @return Array returns the array with table names and fieldnames storing relations
|
||
* between module and this module
|
||
*/
|
||
|
||
function setRelationTables($secmodule) {
|
||
$rel_tables = array(
|
||
"Documents" => array("vtiger_senotesrel" => array("crmid", "notesid"),
|
||
$this->table_name => $this->table_index),
|
||
);
|
||
return $rel_tables[$secmodule];
|
||
}
|
||
|
||
/**
|
||
* Function to clear the fields which needs to be saved only once during the Save of the record
|
||
* For eg: Comments of HelpDesk should be saved only once during one save of a Trouble Ticket
|
||
*/
|
||
function clearSingletonSaveFields() {
|
||
return;
|
||
}
|
||
|
||
/**
|
||
* Function to track when a new record is linked to a given record
|
||
*/
|
||
function trackLinkedInfo($module, $crmid, $with_module, $with_crmid) {
|
||
global $current_user;
|
||
$adb = PearDatabase::getInstance();
|
||
$currentTime = date('Y-m-d H:i:s');
|
||
|
||
$adb->pquery('UPDATE vtiger_crmentity SET modifiedtime = ?, modifiedby = ? WHERE crmid = ?', array($currentTime, $current_user->id, $crmid));
|
||
|
||
// @Note: We should extend this to event handlers
|
||
if(vtlib_isModuleActive('ModTracker')) {
|
||
// Track the time the relation was added
|
||
require_once 'modules/ModTracker/ModTracker.php';
|
||
ModTracker::linkRelation($module, $crmid, $with_module, $with_crmid);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Function to get sort order
|
||
* return string $sorder - sortorder string either 'ASC' or 'DESC'
|
||
*/
|
||
function getSortOrder() {
|
||
global $log,$currentModule;
|
||
$log->debug("Entering getSortOrder() method ...");
|
||
if (isset($_REQUEST['sorder']))
|
||
$sorder = $this->db->sql_escape_string($_REQUEST['sorder']);
|
||
else
|
||
$sorder = (($_SESSION[$currentModule . '_Sort_Order'] != '') ? ($_SESSION[$currentModule . '_Sort_Order']) : ($this->default_sort_order));
|
||
$log->debug("Exiting getSortOrder() method ...");
|
||
return $sorder;
|
||
}
|
||
|
||
/**
|
||
* Function to get order by
|
||
* return string $order_by - fieldname(eg: 'accountname')
|
||
*/
|
||
function getOrderBy() {
|
||
global $log, $currentModule;
|
||
$log->debug("Entering getOrderBy() method ...");
|
||
|
||
$use_default_order_by = '';
|
||
if (PerformancePrefs::getBoolean('LISTVIEW_DEFAULT_SORTING', true)) {
|
||
$use_default_order_by = $this->default_order_by;
|
||
}
|
||
|
||
if (isset($_REQUEST['order_by']))
|
||
$order_by = $this->db->sql_escape_string($_REQUEST['order_by']);
|
||
else
|
||
$order_by = (($_SESSION[$currentModule.'_Order_By'] != '') ? ($_SESSION[$currentModule.'_Order_By']) : ($use_default_order_by));
|
||
$log->debug("Exiting getOrderBy method ...");
|
||
return $order_by;
|
||
}
|
||
|
||
// Mike Crowe Mod --------------------------------------------------------
|
||
|
||
/**
|
||
* Function to Listview buttons
|
||
* return array $list_buttons - for module (eg: 'Accounts')
|
||
*/
|
||
function getListButtons($app_strings) {
|
||
$list_buttons = Array();
|
||
|
||
if (isPermitted($currentModule, 'Delete', '') == 'yes')
|
||
$list_buttons['del'] = $app_strings[LBL_MASS_DELETE];
|
||
if (isPermitted($currentModule, 'EditView', '') == 'yes') {
|
||
$list_buttons['mass_edit'] = $app_strings[LBL_MASS_EDIT];
|
||
// Mass Edit could be used to change the owner as well!
|
||
//$list_buttons['c_owner'] = $app_strings[LBL_CHANGE_OWNER];
|
||
}
|
||
return $list_buttons;
|
||
}
|
||
|
||
/**
|
||
* Function to track when a record is unlinked to a given record
|
||
*/
|
||
function trackUnLinkedInfo($module, $crmid, $with_module, $with_crmid) {
|
||
global $current_user;
|
||
$adb = PearDatabase::getInstance();
|
||
$currentTime = date('Y-m-d H:i:s');
|
||
|
||
$adb->pquery('UPDATE vtiger_crmentity SET modifiedtime = ?, modifiedby = ? WHERE crmid = ?', array($currentTime, $current_user->id, $crmid));
|
||
|
||
// @Note: We should extend this to event handlers
|
||
if(vtlib_isModuleActive('ModTracker')) {
|
||
//Track the time the relation was deleted
|
||
require_once 'modules/ModTracker/ModTracker.php';
|
||
ModTracker::unLinkRelation($module, $crmid, $with_module, $with_crmid);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Function which will give the basic query to find duplicates
|
||
* @param <String> $module
|
||
* @param <String> $tableColumns
|
||
* @param <String> $selectedColumns
|
||
* @param <Boolean> $ignoreEmpty
|
||
* @param <Array> $requiredTables
|
||
* @return string
|
||
*/
|
||
function getQueryForDuplicates($module, $tableColumns, $selectedColumns = '', $ignoreEmpty = false,$requiredTables = array()) {
|
||
if(is_array($tableColumns)) {
|
||
$tableColumnsString = implode(',', $tableColumns);
|
||
}
|
||
$selectClause = "SELECT " . $this->table_name . "." . $this->table_index . " AS recordid," . $tableColumnsString;
|
||
|
||
// Select Custom Field Table Columns if present
|
||
if (isset($this->customFieldTable))
|
||
$query .= ", " . $this->customFieldTable[0] . ".* ";
|
||
|
||
$fromClause = " FROM $this->table_name";
|
||
|
||
$fromClause .= " INNER JOIN vtiger_crmentity ON vtiger_crmentity.crmid = $this->table_name.$this->table_index";
|
||
|
||
if($this->tab_name) {
|
||
foreach($this->tab_name as $tableName) {
|
||
if($tableName != 'vtiger_crmentity' && $tableName != $this->table_name && $tableName != 'vtiger_inventoryproductrel' && in_array($tableName,$requiredTables)) {
|
||
if($this->tab_name_index[$tableName]) {
|
||
$fromClause .= " INNER JOIN " . $tableName . " ON " . $tableName . '.' . $this->tab_name_index[$tableName] .
|
||
" = $this->table_name.$this->table_index";
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
$whereClause = " WHERE vtiger_crmentity.deleted = 0";
|
||
$whereClause .= $this->getListViewSecurityParameter($module);
|
||
|
||
if($ignoreEmpty) {
|
||
foreach($tableColumns as $tableColumn){
|
||
$whereClause .= " AND ($tableColumn IS NOT NULL AND $tableColumn != '') ";
|
||
}
|
||
}
|
||
|
||
if (isset($selectedColumns) && trim($selectedColumns) != '') {
|
||
$sub_query = "SELECT $selectedColumns FROM $this->table_name AS t " .
|
||
" INNER JOIN vtiger_crmentity AS crm ON crm.crmid = t." . $this->table_index;
|
||
// Consider custom table join as well.
|
||
if (isset($this->customFieldTable)) {
|
||
$sub_query .= " LEFT JOIN " . $this->customFieldTable[0] . " tcf ON tcf." . $this->customFieldTable[1] . " = t.$this->table_index";
|
||
}
|
||
$sub_query .= " WHERE crm.deleted=0 GROUP BY $selectedColumns HAVING COUNT(*)>1";
|
||
} else {
|
||
$sub_query = "SELECT $tableColumnsString $fromClause $whereClause GROUP BY $tableColumnsString HAVING COUNT(*)>1";
|
||
}
|
||
|
||
$i = 1;
|
||
foreach($tableColumns as $tableColumn){
|
||
$tableInfo = explode('.', $tableColumn);
|
||
$duplicateCheckClause .= " ifnull($tableColumn,'null') = ifnull(temp.$tableInfo[1],'null')";
|
||
if (count($tableColumns) != $i++) $duplicateCheckClause .= " AND ";
|
||
}
|
||
|
||
$query = $selectClause . $fromClause .
|
||
" LEFT JOIN vtiger_users_last_import ON vtiger_users_last_import.bean_id=" . $this->table_name . "." . $this->table_index .
|
||
" INNER JOIN (" . $sub_query . ") AS temp ON " . $duplicateCheckClause .
|
||
$whereClause .
|
||
" ORDER BY $tableColumnsString," . $this->table_name . "." . $this->table_index . " ASC";
|
||
return $query;
|
||
}
|
||
|
||
/**
|
||
* Function to get relation query for get_activities
|
||
*/
|
||
function get_activities($id, $cur_tab_id, $rel_tab_id, $actions=false) {
|
||
global $currentModule;
|
||
$this_module = $currentModule;
|
||
|
||
$related_module = vtlib_getModuleNameById($rel_tab_id);
|
||
$userNameSql = getSqlForNameInDisplayFormat(array('first_name' => 'vtiger_users.first_name', 'last_name' => 'vtiger_users.last_name'), 'Users');
|
||
|
||
$query = "SELECT CASE WHEN (vtiger_users.user_name not like '') THEN $userNameSql ELSE vtiger_groups.groupname END AS user_name,
|
||
vtiger_crmentity.*, vtiger_activity.activitytype, vtiger_activity.subject, vtiger_activity.date_start, vtiger_activity.time_start,
|
||
vtiger_activity.recurringtype, vtiger_activity.due_date, vtiger_activity.time_end, vtiger_activity.visibility, vtiger_seactivityrel.crmid AS parent_id,
|
||
CASE WHEN (vtiger_activity.activitytype = 'Task') THEN (vtiger_activity.status) ELSE (vtiger_activity.eventstatus) END AS status
|
||
FROM vtiger_activity
|
||
INNER JOIN vtiger_crmentity ON vtiger_crmentity.crmid = vtiger_activity.activityid
|
||
LEFT JOIN vtiger_seactivityrel ON vtiger_seactivityrel.activityid = vtiger_activity.activityid
|
||
LEFT JOIN vtiger_cntactivityrel ON vtiger_cntactivityrel.activityid = vtiger_activity.activityid
|
||
LEFT JOIN vtiger_users ON vtiger_users.id = vtiger_crmentity.smownerid
|
||
LEFT JOIN vtiger_groups ON vtiger_groups.groupid = vtiger_crmentity.smownerid
|
||
WHERE vtiger_crmentity.deleted = 0 AND vtiger_activity.activitytype <> 'Emails'
|
||
AND vtiger_seactivityrel.crmid = ".$id;
|
||
|
||
$return_value = GetRelatedList($this_module, $related_module, '', $query, '', '');
|
||
if($return_value == null) $return_value = Array();
|
||
return $return_value;
|
||
}
|
||
|
||
function get_comments($relatedRecordId = false) {
|
||
$current_user = vglobal('current_user');
|
||
$moduleName = $this->moduleName;
|
||
if($moduleName != 'ModComments') {
|
||
return false;
|
||
}
|
||
$queryGenerator = new EnhancedQueryGenerator($moduleName, $current_user);
|
||
if(is_object($this->column_fields)) {
|
||
$fields = $this->column_fields->getColumnFieldNames();
|
||
} else if(is_array($this->column_fields)) {
|
||
$fields = array_keys($this->column_fields);
|
||
}
|
||
array_push($fields, 'id');
|
||
$queryGenerator->setFields($fields);
|
||
$query = $queryGenerator->getQuery();
|
||
if($relatedRecordId){
|
||
$query .= " AND related_to = ".$relatedRecordId." ORDER BY vtiger_crmentity.createdtime DESC";
|
||
}
|
||
return $query;
|
||
}
|
||
}
|
||
|
||
class TrackableObject implements ArrayAccess, IteratorAggregate {
|
||
private $storage;
|
||
private $trackingEnabled = true;
|
||
private $tracking;
|
||
|
||
function __construct($value = array()) {
|
||
$this->storage = $value;
|
||
}
|
||
|
||
function offsetExists($key) {
|
||
return isset($this->storage[$key]);
|
||
}
|
||
|
||
function offsetSet($key, $value) {
|
||
if($this->tracking && $this->trackingEnabled) {
|
||
$olderValue = $this->offsetGet($key);
|
||
// decode_html only expects string
|
||
$olderValue = is_string($olderValue) ? decode_html($olderValue) : $olderValue ;
|
||
//same logic is used in vtEntityDelta to check for delta
|
||
if((empty($olderValue) && !empty($value)) || ($olderValue !== $value)) {
|
||
$this->changed[] = $key;
|
||
}
|
||
}
|
||
$this->storage[$key] = $value;
|
||
}
|
||
|
||
public function offsetUnset($key) {
|
||
unset($this->storage[$key]);
|
||
}
|
||
|
||
public function offsetGet($key) {
|
||
return isset($this->storage[$key]) ? $this->storage[$key] : null;
|
||
}
|
||
|
||
public function getIterator() {
|
||
$iterator = new ArrayObject($this->storage);
|
||
return $iterator->getIterator();
|
||
}
|
||
|
||
function getChanged() {
|
||
return $this->changed;
|
||
}
|
||
|
||
function startTracking() {
|
||
if($this->tracking && $this->trackingEnabled) return;
|
||
$this->tracking = true;
|
||
$this->changed = array();
|
||
}
|
||
|
||
function restartTracking() {
|
||
$this->tracking = true;
|
||
$this->startTracking();
|
||
}
|
||
|
||
function pauseTracking() {
|
||
$this->tracking = false;
|
||
}
|
||
|
||
function resumeTracking() {
|
||
if($this->trackingEnabled)
|
||
$this->tracking = true;
|
||
}
|
||
|
||
function getColumnFields() {
|
||
return $this->storage;
|
||
}
|
||
|
||
function getColumnFieldNames(){
|
||
return array_keys($this->storage);
|
||
}
|
||
}
|