SuiteCRM-Core/include/export_utils.php
Clemente Raposo 9d484f189a Squashed 'public/legacy/' changes from 60ccef0448..81ce7933fd
81ce7933fd SuiteCRM 7.13.0 Release
595d2bd92b Fix saveDropDown getting called statically
a70c5d1b99 Fix message deletion after auto import
f57b5ede02 Fix Inbound Email allow_outbound_group_usage filtering
9d38016f59 Remove external_oauth_providers config
d5b4f0025c Remove provider field from ExternalOAuthConnection
d457827c7d Change ExternalOAuthProvider to use open visibility by default for group records
3a51437d3a Add null check
b49d6b79a0 Fix Inbound email tests
277f2c91cb Set default on inbound emails
261dae81c1 Add group to OutboundEmailAccounts menu
3e9dbdd5de Fix ExternalOAuthConnection list view pagination and checkboxes
36cbb6a90c Fix ExternalOAuthProvider list view pagination and checkboxes
fe5f0a10d6 Fix OutboundEmailAccounts list view pagination and checkboxes
b9217a36e2 Fix InboundEmail list view pagination and checkboxes
83bd0024a6 Allow selecting group InboundEmails in folder management
f6a9111b25 Fix inbound email relationship definition
07b3110f8a Filter listview email displayed accounts according to preferences
6c49df527a Remove code that auto-selects a group email none is selected
243a0276af Fix preferences mail folder management dropdown
e7838f0bd4 Fix owner field definition in OutboundEmailAccounts
db9a52a27d Fix bounce mailbox type not being properly set
14d43e1efa Fix compose emails not sending
f9e3677db8 Add optional connection string to InboundEmail module
cef8b2bdb6 Allow setting placeholder for varchar on editview
b2d669a022 Fix group_id not being saved properly on InboundEmail
8d25cc19d8 Fix: From not populating
fae3d7b629 Fix folders not clearing subscription
a8e9eba917 Fix signatures not being editable after being created
1762704a28 Fix menu label in ExternalOAuthConnections module
e97ddb6af0 Fix inbound_emails_external_oauth_connections relationship
2cbebdd5a9 Replace External Oauth Provider sugar_config with module
89f2cee005 Add admin menu entry for ExternalOAuthProviders
dbe91ffe26 Add External providers to ExternalOAuthConnector menu
63b944e033 Add ExternalOAuthProvider module
214f0d9008 Rename ExternalOAuthProvider to ExternalOAuthProviderConnector
972356fa90 Add stringmap field
c701e4c6d5 Add json_decode smarty modifier
49024376be Update Travis build to remove php 7.3 test runs
c23f0e57ac Update Minimum php version to php 7.4
b5914d782e Fix #9670 - Disabling the user profile option about notification of assignments does not work
c2f260e477 Clear caches used by Inline Edition
89de5b620f Fix #99568: Ignore int length when comparing vardefs in newer MySQL versions
fb50e2250e ElasticSearch Indexing batch error handling
32af678e4f Fix #9473 - Missing item "Survey" in campainglog_activity_type_dom
a12f4f37be Fix #9638 - Elasticsearch issue with accented characters
d85d72996d Fix #9499 - Add View Survey Responses Menu item
dcd3ea1091 Fix #9574 - Update method to static for module renaming
c56a5b2188 Fix #9646 - Display TinyMCE in step 4 of the campaigns form wizard
d99439aca1 Fix #9717 - Security Suite Record Group selector doesn't appear when duplicating records
ea0b42469a Add new ACL access logic hooks
be0dec47dc Refactor module access query for extendability
8361cceb60 fix #9802 - Diagnostic checkboxes
44e4f47cca SuiteCRM 7.13.0-beta Release
0d6fef782e Fix #9839 - Make Inbound Email not auditable
c0b93a5d2a Fix #9839 - Align Inbound and Outbound email menu labels
3883c2cb7e Fix #9839 - Inbound email assignment fields save and detail display
0a4fbfa2a9 Fix #9839 - Inbound email filters not displaying
6fefdd79a0 Fix #9839 - OutboundEmailAccounts list filtering
3dcab78053 Fix #9839 - Hide sort fields in search modal if none is sortable
95d099d3b4 Fix #9839 - Always sort emails by date received
aff7965abd Fix #9839 - Add showing sort direction when field is not manually sortable
e3f7d02a65 Fix #9839 - Use previously selected email mailbox when using the navigation links
01c96bf15c Fix #9839 - Add Imap2Handler to use imap2 lib
d8dee51d94 Fix #9839 - Move email list retrieval from InboundEmail to ImapHandler
f798b9af4a Fix #9839 - Update InboundEmail calls to mailparser to send 2nd argument
68a8fa97dd Fix #9839 - Move stream validity check to ImapHandlers
fb4f1c81ec Fix #9839 - Fix InboundEmail pagination totals
dc26951a35 Fix #9839 - Use previously selected email mailbox when using the navigation links
cca80e945b Fix #9839 - Move case macro input to Case module settings admin menu
0fb1075aa2 Fix #9839 - Fix undefined error in listview displayEmptyDataMessages
990e98e4bc Fix #9839 - Add support to test oauth connection in InboundEmail
7259c9ce79 Fix #9839 - Allow refreshing ExternalOAuthConnection tokens
49c5c0ee09 Fix #9839 - Make ExternalOAuthConnection sensitive fields db_encrypted
17bbeb3683 Fix #9839 - Allow admins to list Group and personal ExternalOAuthConnection
0f559a6223 Fix #9839 - Allow encrypting fields on db by setting db_encrypted
471792d75f Fix #9839 - Apply acl and group check filtering to OutboundEmailAccounts
093f08f27b Fix #9839 - Apply acl and group check filtering to InboundEmail
decdd27b23 Fix #9839 - Apply acl and group check filtering to ExternalOAuthConnection
584e40cfb3 Fix #9839 - Add user acl group action check
07c5b9f021 Fix #9839 - Show no-data message on empty OutboundEmailAccounts listview
b857e4feab Fix #9839 - Show no-data message on empty ExternalOAuthConnection listview
9b6a7c4fcf Fix #9839 - Validate required fields on InboundEmail folder selection
0755e4bc7e Fix #9839 - Mark fields required when changing authType in InboundEmail
55123f4d70 Fix #9839 - Show no-data message on empty InboundEmail listview
059d112349 Fix #9839 - Fix InboundEmail save
a656abd069 Fix #9839 - Make getUserRoleNames a static method
ae49f130a9 Fix #9839 - Add is-value-set data to password field
2964fcbebc Fix #9839 - Add option to disable listview empty data messages
a5794343cb Fix #9839 - Add ExternalOAuthConnection link to admin menu
215413931c Fix #9839 - Align mail related menu entries
ee9e98741d Fix #9839 - Always keep write-only fields in OutboundEmailAccounts
4e0551e9f0 Fix #9839 - Disable massupdate and export in OutboundEmailAccounts bulk actions
bbf351ee5e Fix #9839 - Disable massupdate and export in InboundEmail bulkactions
6871295c66 Fix #9839 - Allow selecting auth type in InboundEmail module
9befcd0ae6 Fix #9839 - Add ExternalOAuthConnection entrypoints
2cee6f1d67 Fix #9839 - Add ExternalOAuthConnection module
70025d5b66 Fix #9839 - Add write-only display option to text fields
25e2443850 Fix #9839 - Add write-only display option to varchar fields
6be8a334b1 Fix #9839 - Allow creating personal outbound email accounts
8bff1fb237 Fix #9839 - Align Outbound email accounts views with Inbound
e396b7373c Fix #9839 - Allow admin to create personal inbound accounts for users
284d0eca76 Fix #9839 - Align inbound email and outbound email list views
186d8e41e4 Fix #9839 - Add Security Groups subpanel to Outbound email accounts
c07f43decb Fix #9839 - Add Security Groups subpanel to Inbound email accounts
87c9eee413 Fix #9839 - Add access checks to personal outbound email accounts
2f76e6a5f5 Fix #9839 - Add access checks to personal inbound email accounts
88adc8135b Fix #9839 - Remove email account configuration from User Settings
33feb0b1c2 Fix #9839 - Allow setting personal InboundEmail signatures
4cb0fd99aa Fix #9839 - Allow setting personal InboundEmail as default
b8cc31d8dd Fix #9839 - Add security groups to OutboundEmailAccounts
70a0daba51 Fix #9839 - Tidy OutboundEmailAccounts view definitions
ca171a4460 Fix #9839 - Remove email_provider_chooser from OutboundEmailAccounts
f8a6105618 Fix #9839 - Add menu definition to OutboundEmailAccounts
7d6cfd6c6c Fix #9839 - Load InboundEmail stored_options into fields on load
f18ec84b47 Fix #9839 - Adjust InboundEmail save to use new fields
54bfb4f72c Fix #9839 - Remove InboundEmail legacy custom views
69d008671e Fix #9839 - Add new menu entries to InboundEmail
d01a196f3b Fix #9839 - Add js code for inboundEmail
701498d007 Fix #9839 - Add standard view definitions to InboundEmail
b5870531ba Fix #9839 - Add fields for stored_options in InboundEmail
8c57b07591 Fix #9839 - Add inbound and outbound email menu links to Users module
a8bc647662 Fix #9839 - Add combinescripts smarty plugin
e4db0fbfd4 Fix #9839 - Add writeonly display mode for password fields
1cc85c2dbf Fix #9839 - Add readonly display mode for enum fields

git-subtree-dir: public/legacy
git-subtree-split: 81ce7933fd9cecc378154ed4eac7eaab5ec1f139
2022-12-21 11:44:57 +00:00

967 lines
56 KiB
PHP
Executable file

<?php
/**
*
* SugarCRM Community Edition is a customer relationship management program developed by
* SugarCRM, Inc. Copyright (C) 2004-2013 SugarCRM Inc.
*
* SuiteCRM is an extension to SugarCRM Community Edition developed by SalesAgility Ltd.
* Copyright (C) 2011 - 2021 SalesAgility Ltd.
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU Affero General Public License version 3 as published by the
* Free Software Foundation with the addition of the following permission added
* to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
* IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY
* OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
* details.
*
* You should have received a copy of the GNU Affero General Public License along with
* this program; if not, see http://www.gnu.org/licenses or write to the Free
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA.
*
* You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road,
* SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com.
*
* The interactive user interfaces in modified source and object code versions
* of this program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU Affero General Public License version 3.
*
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
* these Appropriate Legal Notices must retain the display of the "Powered by
* SugarCRM" logo and "Supercharged by SuiteCRM" logo. If the display of the logos is not
* reasonably feasible for technical reasons, the Appropriate Legal Notices must
* display the words "Powered by SugarCRM" and "Supercharged by SuiteCRM".
*/
use SuiteCRM\CleanCSV;
if (!defined('sugarEntry') || !sugarEntry) {
die('Not A Valid Entry Point');
}
/**
* gets the system default delimiter or an user-preference based override
* @return string the delimiter
*/
function getDelimiter()
{
global $sugar_config;
global $current_user;
$delimiter = ','; // default to "comma"
$userDelimiter = $current_user->getPreference('export_delimiter');
$delimiter = empty($sugar_config['export_delimiter']) ? $delimiter : $sugar_config['export_delimiter'];
$delimiter = empty($userDelimiter) ? $delimiter : $userDelimiter;
return $delimiter;
}
/**
* Prints the encoded CSV to the output buffer with the right headers for downloading.
*
* @param string $csv The CSV, UTF-8 encoded
* @param string $name The name of the document
*/
function printCSV($csv, $name) {
global $locale, $sugar_config;
// Excel correctly detects the CSV encoding for utf8+bom files. utf16(+bom) only works on Excel for Windows,
// but fails with Excel on macOS.
if (!empty($sugar_config['export_excel_compatible'])) {
$charset = 'UTF-8';
$data = $locale->addBOM($csv, $charset);
} else {
$charset = $locale->getExportCharset();
$data = $locale->translateCharset($csv, 'UTF-8', $charset);
}
header("Pragma: cache");
header("Content-type: text/comma-separated-values; charset=" . $charset);
header("Content-Disposition: attachment; filename=\"{$name}.csv\"");
header("Content-transfer-encoding: binary");
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
header("Last-Modified: " . TimeDate::httpTime());
header("Cache-Control: post-check=0, pre-check=0", false);
header("Content-Length: " . mb_strlen($data, '8bit'));
print $data;
}
/**
* builds up a delimited string for export
* @param string type the bean-type to export
* @param array records an array of records if coming directly from a query
* @return string delimited string for export
*/
function export($type, $records = null, $members = false, $sample=false)
{
global $locale;
global $beanList;
global $beanFiles;
global $current_user;
global $app_strings;
global $app_list_strings;
global $timedate;
global $mod_strings;
global $current_language;
global $log;
$sampleRecordNum = 5;
//Array of fields that should not be exported, and are only used for logic
$remove_from_members = array("ea_deleted", "ear_deleted", "primary_address");
$focus = 0;
$db = DBManagerFactory::getInstance();
if (empty($db)){
$log->fatal('export: not able to get db instance');
throw new RuntimeException('Unexpected error. See logs.');
}
if (empty($beanList[$db->quote($type)])) {
$log->security("export: trying to access an invalid module '" . $db->quote($type) . "'");
throw new RuntimeException('Unexpected error. See logs.');
}
$bean = $beanList[$db->quote($type)];
require_once($beanFiles[$bean]);
$focus = new $bean;
$searchFields = array();
$records = $db->quote($records);
$recordsArray = [];
if (!empty($records)) {
$recordsArray = explode(',', $records);
}
if (!empty($recordsArray)) {
$quotedRecords = [];
foreach ($recordsArray as $record) {
$quotedRecords[] = $db->quote($record);
}
$records = "'" . implode("','", $quotedRecords) . "'";
$where = "{$focus->table_name}.id in ($records)";
} elseif (isset($_REQUEST['all'])) {
$where = '';
} else {
if (!empty($_REQUEST['current_post'])) {
$ret_array = generateSearchWhere($type, $_REQUEST['current_post']);
$where = $ret_array['where'];
$searchFields = $ret_array['searchFields'];
} else {
$where = '';
}
}
$order_by = "";
if ($focus->bean_implements('ACL')) {
if (!ACLController::checkAccess($focus->module_dir, 'export', true)) {
ACLController::displayNoAccess();
sugar_die('');
}
$accessWhere = $focus->buildAccessWhere('export');
if (!empty($accessWhere)) {
$where .= empty($where) ? $accessWhere : ' AND ' . $accessWhere;
}
}
// Export entire list was broken because the where clause already has "where" in it
// and when the query is built, it has a "where" as well, so the query was ill-formed.
// Eliminating the "where" here so that the query can be constructed correctly.
if ($members == true) {
$query = $focus->create_export_members_query($records);
} else {
$beginWhere = substr(trim($where), 0, 5);
if ($beginWhere == "where") {
$where = substr(trim($where), 5, strlen($where));
}
$query = $focus->create_export_query($order_by, $where);
}
$result = '';
$populate = false;
if ($sample) {
$result = $db->limitQuery($query, 0, $sampleRecordNum, true, $app_strings['ERR_EXPORT_TYPE'].$type.": <BR>.".$query);
if ($focus->_get_num_rows_in_query($query)<1) {
$populate = true;
}
} else {
$result = $db->query($query, true, $app_strings['ERR_EXPORT_TYPE'].$type.": <BR>.".$query);
}
$fields_array = $db->getFieldsArray($result, true);
//set up the order on the header row
$fields_array = get_field_order_mapping($focus->module_dir, $fields_array);
//set up labels to be used for the header row
$field_labels = array();
foreach ($fields_array as $key=>$dbname) {
//Remove fields that are only used for logic
if ($members && (in_array($dbname, $remove_from_members))) {
continue;
}
//If labels should not be exportable skip them
if (isset($focus->field_name_map[$key]) && isset($focus->field_name_map[$key]['exportable'])
&& $focus->field_name_map[$key]['exportable'] === false) {
continue;
}
//default to the db name of label does not exist
$field_labels[$key] = translateForExport($dbname, $focus);
}
$content = '';
// setup the "header" line with proper delimiters
$content .= "\"".implode("\"".getDelimiter()."\"", array_values($field_labels))."\"\r\n";
$pre_id = '';
if ($populate) {
//this is a sample request with no data, so create fake datarows
$content .= returnFakeDataRow($focus, $fields_array, $sampleRecordNum);
} else {
$records = array();
//process retrieved record
while ($val = $db->fetchByAssoc($result, false)) {
if ($members) {
$focus = BeanFactory::getBean($val['related_type']);
} else { // field order mapping is not applied for member-exports, as they include multiple modules
//order the values in the record array
$val = get_field_order_mapping($focus->module_dir, $val);
}
$new_arr = array();
if ($members) {
if ($pre_id == $val['id']) {
continue;
}
if ($val['ea_deleted']==1 || $val['ear_deleted']==1) {
$val['primary_email_address'] = '';
}
unset($val['ea_deleted']);
unset($val['ear_deleted']);
unset($val['primary_address']);
}
$pre_id = $val['id'];
foreach ($val as $key => $value) {
//getting content values depending on their types
$fieldNameMapKey = $fields_array[$key];
//Dont export fields that have been explicitly marked not to be exportable
if (isset($focus->field_name_map[$fieldNameMapKey]) && isset($focus->field_name_map[$fieldNameMapKey]['exportable']) &&
$focus->field_name_map[$fieldNameMapKey]['exportable'] === false) {
continue;
}
if (isset($focus->field_name_map[$fieldNameMapKey]) && $focus->field_name_map[$fieldNameMapKey]['type']) {
$fieldType = $focus->field_name_map[$fieldNameMapKey]['type'];
switch ($fieldType) {
//if our value is a currency field, then apply the users locale
case 'currency':
require_once('modules/Currencies/Currency.php');
$value = currency_format_number($value);
break;
//if our value is a datetime field, then apply the users locale
case 'datetime':
case 'datetimecombo':
$value = $timedate->to_display_date_time($db->fromConvert($value, 'datetime'));
$value = preg_replace('/([pm|PM|am|AM]+)/', ' \1', $value);
break;
//kbrill Bug #16296
case 'date':
$value = $timedate->to_display_date($db->fromConvert($value, 'date'), false);
break;
// Bug 32463 - Properly have multienum field translated into something useful for the client
case 'multienum':
$valueArray = unencodeMultiEnum($value);
if (isset($focus->field_name_map[$fields_array[$key]]['options']) && isset($app_list_strings[$focus->field_name_map[$fields_array[$key]]['options']])) {
foreach ($valueArray as $multikey => $multivalue) {
if (isset($app_list_strings[$focus->field_name_map[$fields_array[$key]]['options']][$multivalue])) {
$valueArray[$multikey] = $app_list_strings[$focus->field_name_map[$fields_array[$key]]['options']][$multivalue];
}
}
}
$value = implode(",", $valueArray);
break;
case 'enum':
if (isset($focus->field_name_map[$fields_array[$key]]['options']) &&
isset($app_list_strings[$focus->field_name_map[$fields_array[$key]]['options']]) &&
isset($app_list_strings[$focus->field_name_map[$fields_array[$key]]['options']][$value])
) {
$value = $app_list_strings[$focus->field_name_map[$fields_array[$key]]['options']][$value];
}
break;
}
}
// Keep as $key => $value for post-processing
$cleanCSV = new CleanCSV();
$new_arr[$key] = preg_replace("/\"/", "\"\"", $cleanCSV->escapeField($value));
}
// Use Bean ID as key for records
$records[$pre_id] = $new_arr;
}
// Check if we're going to export non-primary emails
if ($focus->hasEmails() && in_array('email_addresses_non_primary', $fields_array)) {
// $records keys are bean ids
$keys = array_keys($records);
// Split the ids array into chunks of size 100
$chunks = array_chunk($keys, 100);
foreach ($chunks as $chunk) {
// Pick all the non-primary mails for the chunk
$query =
"
SELECT eabr.bean_id, ea.email_address
FROM email_addr_bean_rel eabr
LEFT JOIN email_addresses ea ON ea.id = eabr.email_address_id
WHERE eabr.bean_module = '{$focus->module_dir}'
AND eabr.primary_address = '0'
AND eabr.bean_id IN ('" . implode("', '", $chunk) . "')
AND eabr.deleted != '1'
ORDER BY eabr.bean_id, eabr.reply_to_address, eabr.primary_address DESC
";
$result = $db->query($query, true, $app_strings['ERR_EXPORT_TYPE'] . $type . ": <BR>." . $query);
while ($val = $db->fetchByAssoc($result, false)) {
if (empty($records[$val['bean_id']]['email_addresses_non_primary'])) {
$records[$val['bean_id']]['email_addresses_non_primary'] = $val['email_address'];
} else {
// No custom non-primary mail delimeter yet, use semi-colon
$records[$val['bean_id']]['email_addresses_non_primary'] .= ';' . $val['email_address'];
}
}
}
}
$customRelateFields = array();
$selects = array();
foreach ($records as $record) {
foreach ($record as $recordKey => $recordValue) {
if (preg_match('/{relate\s+from=""([^"]+)""\s+to=""([^"]+)""}/', $recordValue, $matches)) {
$marker = $matches[0];
$relatedValue = '';
$splits = explode('.', $matches[1]);
$currentModule = $splits[0];
$currentField = $splits[1];
$currentBean = BeanFactory::getBean($currentModule);
$currentTable = $currentBean->table_name;
$splits = explode('.', $matches[2]);
$relatedModule = $splits[0];
$relatedField = $splits[1];
$relatedBean = BeanFactory::getBean($relatedModule);
$relatedTable = $relatedBean->table_name;
$relatedLabel = "$relatedTable.name AS related_label, NULL AS related_label1";
if (isset($relatedBean->field_defs['name']['source']) && $relatedBean->field_defs['name']['source'] == 'non-db') {
//$relatedLabel = 'NULL AS related_label, NULL AS related_label1';
if (
!isset($relatedBean->field_defs['first_name']['source']) || $relatedBean->field_defs['first_name']['source'] != 'non-db' &&
!isset($relatedBean->field_defs['last_name']['source']) || $relatedBean->field_defs['last_name']['source'] != 'non-db'
) {
$relatedLabel = "$relatedTable.last_name AS related_label, $relatedTable.first_name AS related_label1";
}
}
$relatedTableCustomJoin = '';
$relatedFieldSelect = "NULL AS related_value";
if (!isset($existsTables["{$relatedTable}_cstm"])) {
$existsTables["{$relatedTable}_cstm"] = $db->tableExists("{$relatedTable}_cstm");
}
if ($existsTables["{$relatedTable}_cstm"]) {
$relatedTableCustomJoin = "
JOIN {$relatedTable}_cstm ON {$relatedTable}_cstm.id_c = {$currentTable}_cstm.$relatedField
";
$relatedFieldSelect = "{$currentTable}_cstm.$relatedField AS related_value";
}
$relatedTableJoin = "LEFT JOIN $relatedTable ON $relatedTable.id = {$currentTable}_cstm.id_c";
if (isset($currentBean->field_defs[$relatedField])) {
$relatedTableJoin = "LEFT JOIN $relatedTable ON $relatedTable.id = {$currentTable}_cstm.$relatedField";
}
//-- $relatedTable.id AS related_id,
//-- {$currentTable}_cstm.id_c AS current_id_c,
//-- {$relatedTable}_cstm.id_c AS related_id_c,
$selects[] = "(SELECT $currentTable.id AS current_id,'$currentModule' AS current_module,'$currentField' AS current_field,'$relatedModule' AS related_module,'$relatedField' AS related_field,$relatedFieldSelect,$relatedLabel FROM $currentTable JOIN {$currentTable}_cstm ON {$currentTable}_cstm.id_c=$currentTable.id $relatedTableCustomJoin $relatedTableJoin WHERE $currentTable.id='{$record['id']}')";
}
}
}
$selects = array_unique($selects);
// grab custom related fields information
// query max length optimization, measured by mssql FreeTDS connection too
$queryMaxLength = 620000;
$query = '';
$i = 0;
$selectsCount = count($selects)-1;
foreach ($selects as $select) {
$queryTemp = $query.($i==0 ? $select : " UNION $select");
if ($i==$selectsCount || strlen($queryTemp) > $queryMaxLength) {
$result = $db->query($query, 'export error on custom related type: '.$query);
while ($val = $db->fetchByAssoc($result, false)) {
$customRelateFields[$val['current_module']][$val['current_id']][$val['related_module']][$val['related_field']] = trim($val['related_label'].' '.$val['related_label1']);
}
$query = $select;
} else {
$query = $queryTemp;
}
$i++;
}
foreach ($records as $record) {
$line = implode("\"" . getDelimiter() . "\"", $record);
$line = "\"" . $line;
$line .= "\"\r\n";
$line = parseRelateFields($line, $record, $customRelateFields);
$content .= $line;
}
}
return $content;
}
/**
* Parse custom related fields
* @param string $line CSV line
* @param array $record of current line
* @return mixed string CSV line
*/
function parseRelateFields($line, $record, $customRelateFields)
{
while (preg_match('/{relate\s+from=""([^"]+)""\s+to=""([^"]+)""}/', $line, $matches)) {
$marker = $matches[0];
$relatedValue = '';
$splits = explode('.', $matches[1]);
$currentModule = $splits[0];
$currentField = $splits[1];
$splits = explode('.', $matches[2]);
$relatedModule = $splits[0];
$relatedField = $splits[1];
if ($currentModule != $record['related_type']) {
$GLOBALS['log']->debug('incorrect related type in export');
} else {
if (isset($customRelateFields[$currentModule][$record['id']][$relatedModule][$relatedField])) {
$relatedValue = $customRelateFields[$currentModule][$record['id']][$relatedModule][$relatedField];
} else {
$relatedValue = '';
}
}
$line = str_replace($marker, $relatedValue, $line);
}
return $line;
}
function generateSearchWhere($module, $query)
{//this function is similar with function prepareSearchForm() in view.list.php
$seed = loadBean($module);
if (file_exists('modules/'.$module.'/SearchForm.html')) {
if (file_exists('modules/' . $module . '/metadata/SearchFields.php')) {
require_once('include/SearchForm/SearchForm.php');
$searchForm = new SearchForm($module, $seed);
} elseif (!empty($_SESSION['export_where'])) { //bug 26026, sometimes some module doesn't have a metadata/SearchFields.php, the searchfrom is generated in the ListView.php.
// Currently, massupdate will not generate the where sql. It will use the sql stored in the SESSION. But this will cause bug 24722, and it cannot be avoided now.
$where = $_SESSION['export_where'];
$whereArr = explode(" ", trim($where));
if ($whereArr[0] == trim('where')) {
$whereClean = array_shift($whereArr);
}
$where = implode(" ", $whereArr);
//rrs bug: 31329 - previously this was just returning $where, but the problem is the caller of this function
//expects the results in an array, not just a string. So rather than fixing the caller, I felt it would be best for
//the function to return the results in a standard format.
$ret_array['where'] = $where;
$ret_array['searchFields'] =array();
return $ret_array;
} else {
return;
}
} else {
require_once('include/SearchForm/SearchForm2.php');
if (file_exists('custom/modules/'.$module.'/metadata/metafiles.php')) {
require('custom/modules/'.$module.'/metadata/metafiles.php');
} elseif (file_exists('modules/'.$module.'/metadata/metafiles.php')) {
require('modules/'.$module.'/metadata/metafiles.php');
}
if (file_exists('custom/modules/'.$module.'/metadata/searchdefs.php')) {
require_once('custom/modules/'.$module.'/metadata/searchdefs.php');
} elseif (!empty($metafiles[$module]['searchdefs'])) {
require_once($metafiles[$module]['searchdefs']);
} elseif (file_exists('modules/'.$module.'/metadata/searchdefs.php')) {
require_once('modules/'.$module.'/metadata/searchdefs.php');
}
//fixing bug #48483: Date Range search on custom date field then export ignores range filter
// first of all custom folder should be checked
if (file_exists('custom/modules/'.$module.'/metadata/SearchFields.php')) {
require_once('custom/modules/'.$module.'/metadata/SearchFields.php');
} elseif (!empty($metafiles[$module]['searchfields'])) {
require_once($metafiles[$module]['searchfields']);
} elseif (file_exists('modules/'.$module.'/metadata/SearchFields.php')) {
require_once('modules/'.$module.'/metadata/SearchFields.php');
}
if (empty($searchdefs) || empty($searchFields)) {
//for some modules, such as iframe, it has massupdate, but it doesn't have search function, the where sql should be empty.
return;
}
$searchForm = new SearchForm($seed, $module);
$searchForm->setup($searchdefs, $searchFields, 'SearchFormGeneric.tpl');
}
$searchForm->populateFromArray(json_decode(html_entity_decode($query), true));
$where_clauses = $searchForm->generateSearchWhere(true, $module);
if (count($where_clauses) > 0) {
$where = '('. implode(' ) AND ( ', $where_clauses) . ')';
}
$GLOBALS['log']->info("Export Where Clause: {$where}");
$ret_array['where'] = $where;
$ret_array['searchFields'] = $searchForm->searchFields;
return $ret_array;
}
/**
* calls export method to build up a delimited string and some sample instructional text on how to use this file
* @param string type the bean-type to export
* @return string delimited string for export with some tutorial text
*/
function exportSample($type)
{
global $app_strings;
//first grab the
$_REQUEST['all']=true;
//retrieve the export content
$content = export($type, null, false, true);
// Add a new row and add details on removing the sample data
// Our Importer will stop after he gets to the new row, ignoring the text below
return $content . "\n" . $app_strings['LBL_IMPORT_SAMPLE_FILE_TEXT'];
}
//this function will take in the bean and field mapping and return a proper value
function returnFakeDataRow($focus, $field_array, $rowsToReturn = 5)
{
if (empty($focus) || empty($field_array)) {
return ;
}
//include the file that defines $sugar_demodata
include('install/demoData.en_us.php');
$person_bean = false;
if (isset($focus->first_name)) {
$person_bean = true;
}
global $timedate;
$returnContent = '';
$counter = 0;
$new_arr = array();
//iterate through the record creation process as many times as defined. Each iteration will create a new row
while ($counter < $rowsToReturn) {
$counter++;
//go through each field and populate with dummy data if possible
foreach ($field_array as $field_name) {
if (empty($focus->field_name_map[$field_name]) || empty($focus->field_name_map[$field_name]['type'])) {
//type is not set, fill in with empty string and continue;
$returnContent .= '"",';
continue;
}
$field = $focus->field_name_map[$field_name];
//fill in value according to type
$type = $field['type'];
switch ($type) {
case "id":
case "assigned_user_name":
//return new guid string
$returnContent .= '"'.create_guid().'",';
break;
case "int":
//return random number`
$returnContent .= '"'.mt_rand(0, 4).'",';
break;
case "name":
//return first, last, user name, or random name string
if ($field['name'] == 'first_name') {
$count = count($sugar_demodata['first_name_array']) - 1;
$returnContent .= '"'.$sugar_demodata['last_name_array'][mt_rand(0, $count)].'",';
} elseif ($field['name'] == 'last_name') {
$count = count($sugar_demodata['last_name_array']) - 1;
$returnContent .= '"'.$sugar_demodata['last_name_array'][mt_rand(0, $count)].'",';
} elseif ($field['name'] == 'user_name') {
$count = count($sugar_demodata['first_name_array']) - 1;
$returnContent .= '"'.$sugar_demodata['last_name_array'][mt_rand(0, $count)].'_'.mt_rand(1, 111).'",';
} else {
//return based on bean
if ($focus->module_dir =='Accounts') {
$count = count($sugar_demodata['company_name_array']) - 1;
$returnContent .= '"'.$sugar_demodata['company_name_array'][mt_rand(0, $count)].'",';
} elseif ($focus->module_dir =='Bugs') {
$count = count($sugar_demodata['bug_seed_names']) - 1;
$returnContent .= '"'.$sugar_demodata['bug_seed_names'][mt_rand(0, $count)].'",';
} elseif ($focus->module_dir =='Notes') {
$count = count($sugar_demodata['note_seed_names_and_Descriptions']) - 1;
$returnContent .= '"'.$sugar_demodata['note_seed_names_and_Descriptions'][mt_rand(0, $count)].'",';
} elseif ($focus->module_dir =='Calls') {
$count = count($sugar_demodata['call_seed_data_names']) - 1;
$returnContent .= '"'.$sugar_demodata['call_seed_data_names'][mt_rand(0, $count)].'",';
} elseif ($focus->module_dir =='Tasks') {
$count = count($sugar_demodata['task_seed_data_names']) - 1;
$returnContent .= '"'.$sugar_demodata['task_seed_data_names'][mt_rand(0, $count)].'",';
} elseif ($focus->module_dir =='Meetings') {
$count = count($sugar_demodata['meeting_seed_data_names']) - 1;
$returnContent .= '"'.$sugar_demodata['meeting_seed_data_names'][mt_rand(0, $count)].'",';
} elseif ($focus->module_dir =='ProductCategories') {
$count = count($sugar_demodata['productcategory_seed_data_names']) - 1;
$returnContent .= '"'.$sugar_demodata['productcategory_seed_data_names'][mt_rand(0, $count)].'",';
} elseif ($focus->module_dir =='ProductTypes') {
$count = count($sugar_demodata['producttype_seed_data_names']) - 1;
$returnContent .= '"'.$sugar_demodata['producttype_seed_data_names'][mt_rand(0, $count)].'",';
} elseif ($focus->module_dir =='ProductTemplates') {
$count = count($sugar_demodata['producttemplate_seed_data']) - 1;
$returnContent .= '"'.$sugar_demodata['producttemplate_seed_data'][mt_rand(0, $count)].'",';
} else {
$returnContent .= '"Default Name for '.$focus->module_dir.'",';
}
}
break;
case "relate":
if ($field['name'] == 'team_name') {
//apply team names and user_name
$teams_count = count($sugar_demodata['teams']) - 1;
$users_count = count($sugar_demodata['users']) - 1;
$returnContent .= '"'.$sugar_demodata['teams'][mt_rand(0, $teams_count)]['name'].','.$sugar_demodata['users'][mt_rand(0, $users_count)]['user_name'].'",';
} else {
//apply GUID
$returnContent .= '"'.create_guid().'",';
}
break;
case "bool":
//return 0 or 1
$returnContent .= '"'.mt_rand(0, 1).'",';
break;
case "text":
//return random text
$returnContent .= '"Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas porttitor congue massa. Fusce posuere, magna sed pulvinar ultricies, purus lectus malesuada libero, sit amet commodo magna eros quis urna",';
break;
case "team_list":
$teams_count = count($sugar_demodata['teams']) - 1;
//give fake team names (East,West,North,South)
$returnContent .= '"'.$sugar_demodata['teams'][mt_rand(0, $teams_count)]['name'].'",';
break;
case "date":
//return formatted date
$timeStamp = strtotime('now');
$value = date($timedate->dbDayFormat, $timeStamp);
$returnContent .= '"'.$timedate->to_display_date_time($value).'",';
break;
case "datetime":
case "datetimecombo":
//return formatted date time
$timeStamp = strtotime('now');
//Start with db date
$value = date($timedate->dbDayFormat.' '.$timedate->dbTimeFormat, $timeStamp);
//use timedate to convert to user display format
$value = $timedate->to_display_date_time($value);
//finally forma the am/pm to have a space so it can be recognized as a date field in excel
$value = preg_replace('/([pm|PM|am|AM]+)/', ' \1', $value);
$returnContent .= '"'.$value.'",';
break;
case "phone":
$value = '('.mt_rand(300, 999).') '.mt_rand(300, 999).'-'.mt_rand(1000, 9999);
$returnContent .= '"'.$value.'",';
break;
case "varchar":
//process varchar for possible values
if ($field['name'] == 'first_name') {
$count = count($sugar_demodata['first_name_array']) - 1;
$returnContent .= '"'.$sugar_demodata['last_name_array'][mt_rand(0, $count)].'",';
} elseif ($field['name'] == 'last_name') {
$count = count($sugar_demodata['last_name_array']) - 1;
$returnContent .= '"'.$sugar_demodata['last_name_array'][mt_rand(0, $count)].'",';
} elseif ($field['name'] == 'user_name') {
$count = count($sugar_demodata['first_name_array']) - 1;
$returnContent .= '"'.$sugar_demodata['last_name_array'][mt_rand(0, $count)].'_'.mt_rand(1, 111).'",';
} elseif ($field['name'] == 'title') {
$count = count($sugar_demodata['titles']) - 1;
$returnContent .= '"'.$sugar_demodata['titles'][mt_rand(0, $count)].'",';
} elseif (strpos($field['name'], 'address_street')>0) {
$count = count($sugar_demodata['street_address_array']) - 1;
$returnContent .= '"'.$sugar_demodata['street_address_array'][mt_rand(0, $count)].'",';
} elseif (strpos($field['name'], 'address_city')>0) {
$count = count($sugar_demodata['city_array']) - 1;
$returnContent .= '"'.$sugar_demodata['city_array'][mt_rand(0, $count)].'",';
} elseif (strpos($field['name'], 'address_state')>0) {
$state_arr = array('CA','NY','CO','TX','NV');
$count = count($state_arr) - 1;
$returnContent .= '"'.$state_arr[mt_rand(0, $count)].'",';
} elseif (strpos($field['name'], 'address_postalcode')>0) {
$returnContent .= '"'.mt_rand(12345, 99999).'",';
} else {
$returnContent .= '"",';
}
break;
case "url":
$returnContent .= '"https://suitecrm.com",';
break;
case "enum":
//get the associated enum if available
global $app_list_strings;
if (isset($focus->field_name_map[$field_name]['type']) && !empty($focus->field_name_map[$field_name]['options'])) {
if (!empty($app_list_strings[$focus->field_name_map[$field_name]['options']])) {
//get the values into an array
$dd_values = $app_list_strings[$focus->field_name_map[$field_name]['options']];
$dd_values = array_values($dd_values);
//grab the count
$count = count($dd_values) - 1;
//choose one at random
$returnContent .= '"'.$dd_values[mt_rand(0, $count)].'",';
} else {
//name of enum options array was found but is empty, return blank
$returnContent .= '"",';
}
} else {
//name of enum options array was not found on field, return blank
$returnContent .= '"",';
}
break;
default:
//type is not matched, fill in with empty string and continue;
$returnContent .= '"",';
}
}
$returnContent .= "\r\n";
}
return $returnContent;
}
//expects the field name to translate and a bean of the type being translated (to access field map and mod_strings)
function translateForExport($field_db_name, $focus)
{
global $mod_strings,$app_strings;
if (empty($field_db_name) || empty($focus)) {
return false;
}
//grab the focus module strings
$temp_mod_strings = $mod_strings;
global $current_language;
$mod_strings = return_module_language($current_language, $focus->module_dir);
$fieldLabel = '';
//!! first check to see if we are overriding the label for export.
if (!empty($mod_strings['LBL_EXPORT_'.strtoupper($field_db_name)])) {
//entry exists which means we are overriding this value for exporting, use this label
$fieldLabel = $mod_strings['LBL_EXPORT_'.strtoupper($field_db_name)];
}
//!! next check to see if we are overriding the label for export on app_strings.
elseif (!empty($app_strings['LBL_EXPORT_'.strtoupper($field_db_name)])) {
//entry exists which means we are overriding this value for exporting, use this label
$fieldLabel = $app_strings['LBL_EXPORT_'.strtoupper($field_db_name)];
}//check to see if label exists in mapping and in mod strings
elseif (!empty($focus->field_name_map[$field_db_name]['vname']) && !empty($mod_strings[$focus->field_name_map[$field_db_name]['vname']])) {
$fieldLabel = $mod_strings[$focus->field_name_map[$field_db_name]['vname']];
}//check to see if label exists in mapping and in app strings
elseif (!empty($focus->field_name_map[$field_db_name]['vname']) && !empty($app_strings[$focus->field_name_map[$field_db_name]['vname']])) {
$fieldLabel = $app_strings[$focus->field_name_map[$field_db_name]['vname']];
}//field is not in mapping, so check to see if db can be uppercased and found in mod strings
elseif (!empty($mod_strings['LBL_'.strtoupper($field_db_name)])) {
$fieldLabel = $mod_strings['LBL_'.strtoupper($field_db_name)];
}//check to see if db can be uppercased and found in app strings
elseif (!empty($app_strings['LBL_'.strtoupper($field_db_name)])) {
$fieldLabel = $app_strings['LBL_'.strtoupper($field_db_name)];
} else {
//we could not find the label in mod_strings or app_strings based on either a mapping entry
//or on the db_name itself or being overwritten, so default to the db name as a last resort
$fieldLabel = $field_db_name;
}
//strip the label of any columns
$fieldLabel= preg_replace("/([:]|\xEF\xBC\x9A)[\\s]*$/", '', trim($fieldLabel));
//reset the bean mod_strings back to original import strings
$mod_strings = $temp_mod_strings;
return $fieldLabel;
}
//call this function to return the desired order to display columns for export in.
//if you pass in an array, it will reorder the array and send back to you. It expects the array
//to have the db names as key values, or as labels
function get_field_order_mapping($name='', $reorderArr = '', $exclude = true)
{
//define the ordering of fields, note that the key value is what is important, and should be the db field name
$field_order_array = array();
$field_order_array['accounts'] = array( 'name'=>'Name', 'id'=>'ID', 'website'=>'Website', 'email_address' =>'Email Address', 'email_addresses_non_primary' => 'Non Primary E-mails', 'phone_office' =>'Office Phone', 'phone_alternate' => 'Alternate Phone', 'phone_fax' => 'Fax', 'billing_address_street' => 'Billing Street', 'billing_address_city' => 'Billing City', 'billing_address_state' => 'Billing State', 'billing_address_postalcode' => 'Billing Postal Code', 'billing_address_country' => 'Billing Country', 'shipping_address_street' => 'Shipping Street', 'shipping_address_city' => 'Shipping City', 'shipping_address_state' => 'Shipping State', 'shipping_address_postalcode' => 'Shipping Postal Code', 'shipping_address_country' => 'Shipping Country', 'description' => 'Description', 'account_type' => 'Type', 'industry' =>'Industry', 'annual_revenue' => 'Annual Revenue', 'employees' => 'Employees', 'sic_code' => 'SIC Code', 'ticker_symbol' => 'Ticker Symbol', 'parent_id' => 'Parent Account ID', 'ownership' =>'Ownership', 'campaign_id' =>'Campaign ID', 'rating' =>'Rating', 'assigned_user_name' =>'Assigned to', 'assigned_user_id' =>'Assigned User ID', 'team_id' =>'Team Id', 'team_name' =>'Teams', 'team_set_id' =>'Team Set ID', 'date_entered' =>'Date Created', 'date_modified' =>'Date Modified', 'modified_user_id' =>'Modified By', 'created_by' =>'Created By', 'deleted' =>'Deleted');
$field_order_array['contacts'] = array( 'first_name' => 'First Name', 'last_name' => 'Last Name', 'id'=>'ID', 'salutation' => 'Salutation', 'title' => 'Title', 'department' => 'Department', 'account_name' => 'Account Name', 'email_address' => 'Email Address', 'email_addresses_non_primary' => 'Non Primary E-mails for Import', 'phone_mobile' => 'Phone Mobile','phone_work' => 'Phone Work', 'phone_home' => 'Phone Home', 'phone_other' => 'Phone Other','phone_fax' => 'Phone Fax', 'primary_address_street' => 'Primary Address Street', 'primary_address_city' => 'Primary Address City', 'primary_address_state' => 'Primary Address State', 'primary_address_postalcode' => 'Primary Address Postal Code', 'primary_address_country' => 'Primary Address Country', 'alt_address_street' => 'Alternate Address Street', 'alt_address_city' => 'Alternate Address City', 'alt_address_state' => 'Alternate Address State', 'alt_address_postalcode' => 'Alternate Address Postal Code', 'alt_address_country' => 'Alternate Address Country', 'description' => 'Description', 'birthdate' => 'Birthdate', 'lead_source' => 'Lead Source', 'campaign_id' => 'campaign_id', 'do_not_call' => 'Do Not Call', 'portal_name' => 'Portal Name', 'portal_active' => 'Portal Active', 'portal_password' => 'Portal Password', 'portal_app' => 'Portal Application', 'reports_to_id' => 'Reports to ID', 'assistant' => 'Assistant', 'assistant_phone' => 'Assistant Phone', 'picture' => 'Picture', 'assigned_user_name' => 'Assigned User Name', 'assigned_user_id' => 'Assigned User ID', 'team_name' => 'Teams', 'team_id' => 'Team id', 'team_set_id' => 'Team Set ID', 'date_entered' =>'Date Created', 'date_modified' =>'Date Modified', 'modified_user_id' =>'Modified By', 'created_by' =>'Created By', 'deleted' =>'Deleted');
$field_order_array['leads'] = array( 'first_name' => 'First Name', 'last_name' => 'Last Name', 'id'=>'ID', 'salutation' => 'Salutation', 'title' => 'Title', 'department' => 'Department', 'account_name' => 'Account Name', 'account_description' => 'Account Description', 'website' => 'Website', 'email_address' => 'Email Address', 'email_addresses_non_primary' => 'Non Primary E-mails for Import', 'phone_mobile' => 'Phone Mobile', 'phone_work' => 'Phone Work', 'phone_home' => 'Phone Home', 'phone_other' => 'Phone Other', 'phone_fax' => 'Phone Fax', 'primary_address_street' => 'Primary Address Street', 'primary_address_city' => 'Primary Address City', 'primary_address_state' => 'Primary Address State', 'primary_address_postalcode' => 'Primary Address Postal Code', 'primary_address_country' => 'Primary Address Country', 'alt_address_street' => 'Alt Address Street', 'alt_address_city' => 'Alt Address City', 'alt_address_state' => 'Alt Address State', 'alt_address_postalcode' => 'Alt Address Postalcode', 'alt_address_country' => 'Alt Address Country', 'status' => 'Status', 'status_description' => 'Status Description', 'lead_source' => 'Lead Source', 'lead_source_description' => 'Lead Source Description', 'description'=>'Description', 'converted' => 'Converted', 'opportunity_name' => 'Opportunity Name', 'opportunity_amount' => 'Opportunity Amount', 'refered_by' => 'Referred By', 'campaign_id' => 'campaign_id', 'do_not_call' => 'Do Not Call', 'portal_name' => 'Portal Name', 'portal_app' => 'Portal Application', 'reports_to_id' => 'Reports To ID', 'assistant' => 'Assistant', 'assistant_phone' => 'Assistant Phone', 'birthdate'=>'Birthdate', 'contact_id' => 'Contact ID', 'account_id' => 'Account ID', 'opportunity_id' => 'Opportunity ID', 'assigned_user_name' => 'Assigned User Name', 'assigned_user_id' => 'Assigned User ID', 'team_name' => 'Teams', 'team_id' => 'Team id', 'team_set_id' => 'Team Set ID', 'date_entered' => 'Date Created', 'date_modified' => 'Date Modified', 'created_by' => 'Created By ID', 'modified_user_id' => 'Modified By ID', 'deleted' => 'Deleted');
$field_order_array['opportunities'] = array( 'name' => 'Opportunity Name', 'id'=>'ID', 'amount' => 'Opportunity Amount', 'currency_id' => 'Currency', 'date_closed' => 'Expected Close Date', 'sales_stage' => 'Sales Stage', 'probability' => 'Probability (%)', 'next_step' => 'Next Step', 'opportunity_type' => 'Opportunity Type', 'account_name' => 'Account Name', 'description' => 'Description', 'amount_usdollar' => 'Amount', 'lead_source' => 'Lead Source', 'campaign_id' => 'campaign_id', 'assigned_user_name' => 'Assigned User Name', 'assigned_user_id' => 'Assigned User ID', 'team_name' => 'Teams', 'team_id' => 'Team id', 'team_set_id' => 'Team Set ID', 'date_entered' => 'Date Created', 'date_modified' => 'Date Modified', 'created_by' => 'Created By ID', 'modified_user_id' => 'Modified By ID', 'deleted' => 'Deleted');
$field_order_array['notes'] = array( 'name' => 'Name', 'id'=>'ID', 'description' => 'Description', 'filename' => 'Attachment', 'parent_type' => 'Parent Type', 'parent_id' => 'Parent ID', 'contact_id' => 'Contact ID', 'portal_flag' => 'Display in Portal?', 'assigned_user_name' =>'Assigned to', 'assigned_user_id' => 'assigned_user_id', 'team_id' => 'Team id', 'team_set_id' => 'Team Set ID', 'date_entered' => 'Date Created', 'date_modified' => 'Date Modified', 'created_by' => 'Created By ID', 'modified_user_id' => 'Modified By ID', 'deleted' => 'Deleted' );
$field_order_array['bugs'] = array('bug_number' => 'Bug Number', 'id'=>'ID', 'name' => 'Subject', 'description' => 'Description', 'status' => 'Status', 'type' => 'Type', 'priority' => 'Priority', 'resolution' => 'Resolution', 'work_log' => 'Work Log', 'found_in_release' => 'Found In Release', 'fixed_in_release' => 'Fixed In Release', 'found_in_release_name' => 'Found In Release Name', 'fixed_in_release_name' => 'Fixed In Release', 'product_category' => 'Category', 'source' => 'Source', 'portal_viewable' => 'Portal Viewable', 'system_id' => 'System ID', 'assigned_user_id' => 'Assigned User ID', 'assigned_user_name' => 'Assigned User Name', 'team_name'=>'Teams', 'team_id' => 'Team id', 'team_set_id' => 'Team Set ID', 'date_entered' =>'Date Created', 'date_modified' =>'Date Modified', 'modified_user_id' =>'Modified By', 'created_by' =>'Created By', 'deleted' =>'Deleted');
$field_order_array['tasks'] = array( 'name'=>'Subject', 'id'=>'ID', 'description'=>'Description', 'status'=>'Status', 'date_start'=>'Date Start', 'date_due'=>'Date Due','priority'=>'Priority', 'parent_type'=>'Parent Type', 'parent_id'=>'Parent ID', 'contact_id'=>'Contact ID', 'assigned_user_name' =>'Assigned to', 'assigned_user_id'=>'Assigned User ID', 'team_name'=>'Teams', 'team_id'=>'Team id', 'team_set_id'=>'Team Set ID', 'date_entered'=>'Date Created', 'date_modified'=>'Date Modified', 'created_by'=>'Created By ID', 'modified_user_id'=>'Modified By ID', 'deleted'=>'Deleted');
$field_order_array['calls'] = array( 'name'=>'Subject', 'id'=>'ID', 'description'=>'Description', 'status'=>'Status', 'direction'=>'Direction', 'date_start'=>'Date', 'date_end'=>'Date End', 'duration_hours'=>'Duration Hours', 'duration_minutes'=>'Duration Minutes', 'reminder_time'=>'Reminder Time', 'parent_type'=>'Parent Type', 'parent_id'=>'Parent ID', 'outlook_id'=>'Outlook ID', 'assigned_user_name' =>'Assigned to', 'assigned_user_id'=>'Assigned User ID', 'team_name'=>'Teams', 'team_id'=>'Team id', 'team_set_id'=>'Team Set ID', 'date_entered'=>'Date Created', 'date_modified'=>'Date Modified', 'created_by'=>'Created By ID', 'modified_user_id'=>'Modified By ID', 'deleted'=>'Deleted');
$field_order_array['meetings'] =array( 'name'=>'Subject', 'id'=>'ID', 'description'=>'Description', 'status'=>'Status', 'location'=>'Location', 'date_start'=>'Date', 'date_end'=>'Date End', 'duration_hours'=>'Duration Hours', 'duration_minutes'=>'Duration Minutes', 'reminder_time'=>'Reminder Time', 'type'=>'Meeting Type', 'external_id'=>'External ID', 'password'=>'Meeting Password', 'join_url'=>'Join Url', 'host_url'=>'Host Url', 'displayed_url'=>'Displayed Url', 'creator'=>'Meeting Creator', 'parent_type'=>'Related to', 'parent_id'=>'Related to', 'outlook_id'=>'Outlook ID','assigned_user_name' =>'Assigned to','assigned_user_id' => 'Assigned User ID', 'team_name' => 'Teams', 'team_id' => 'Team id', 'team_set_id' => 'Team Set ID', 'date_entered' => 'Date Created', 'date_modified' => 'Date Modified', 'created_by' => 'Created By ID', 'modified_user_id' => 'Modified By ID', 'deleted' => 'Deleted');
$field_order_array['cases'] =array( 'case_number'=>'Case Number', 'id'=>'ID', 'name'=>'Subject', 'description'=>'Description', 'status'=>'Status', 'type'=>'Type', 'priority'=>'Priority', 'resolution'=>'Resolution', 'work_log'=>'Work Log', 'portal_viewable'=>'Portal Viewable', 'account_name'=>'Account Name', 'account_id'=>'Account ID', 'assigned_user_id'=>'Assigned User ID', 'team_name'=>'Teams', 'team_id'=>'Team id', 'team_set_id'=>'Team Set ID', 'date_entered'=>'Date Created', 'date_modified'=>'Date Modified', 'created_by'=>'Created By ID', 'modified_user_id'=>'Modified By ID', 'deleted'=>'Deleted');
$field_order_array['prospects'] =array( 'first_name'=>'First Name', 'last_name'=>'Last Name', 'id'=>'ID', 'salutation'=>'Salutation', 'title'=>'Title', 'department'=>'Department', 'account_name'=>'Account Name', 'email_address'=>'Email Address', 'email_addresses_non_primary' => 'Non Primary E-mails for Import', 'phone_mobile' => 'Phone Mobile', 'phone_work' => 'Phone Work', 'phone_home' => 'Phone Home', 'phone_other' => 'Phone Other', 'phone_fax' => 'Phone Fax', 'primary_address_street' => 'Primary Address Street', 'primary_address_city' => 'Primary Address City', 'primary_address_state' => 'Primary Address State', 'primary_address_postalcode' => 'Primary Address Postal Code', 'primary_address_country' => 'Primary Address Country', 'alt_address_street' => 'Alternate Address Street', 'alt_address_city' => 'Alternate Address City', 'alt_address_state' => 'Alternate Address State', 'alt_address_postalcode' => 'Alternate Address Postal Code', 'alt_address_country' => 'Alternate Address Country', 'description' => 'Description', 'birthdate' => 'Birthdate', 'assistant'=>'Assistant', 'assistant_phone'=>'Assistant Phone', 'campaign_id'=>'campaign_id', 'tracker_key'=>'Tracker Key', 'do_not_call'=>'Do Not Call', 'lead_id'=>'Lead Id', 'assigned_user_name'=>'Assigned User Name', 'assigned_user_id'=>'Assigned User ID', 'team_id' =>'Team Id', 'team_name' =>'Teams', 'team_set_id' =>'Team Set ID', 'date_entered' =>'Date Created', 'date_modified' =>'Date Modified', 'modified_user_id' =>'Modified By', 'created_by' =>'Created By', 'deleted' =>'Deleted');
$fields_to_exclude = array();
$fields_to_exclude['accounts'] = array('account_name');
$fields_to_exclude['bugs'] = array('system_id');
$fields_to_exclude['cases'] = array('system_id', 'modified_by_name', 'modified_by_name_owner', 'modified_by_name_mod', 'created_by_name', 'created_by_name_owner', 'created_by_name_mod', 'assigned_user_name', 'assigned_user_name_owner', 'assigned_user_name_mod', 'team_count', 'team_count_owner', 'team_count_mod', 'team_name_owner', 'team_name_mod', 'account_name_owner', 'account_name_mod', 'modified_user_name', 'modified_user_name_owner', 'modified_user_name_mod');
$fields_to_exclude['notes'] = array('first_name','last_name', 'file_mime_type','embed_flag');
$fields_to_exclude['tasks'] = array('date_start_flag', 'date_due_flag');
//of array is passed in for reordering, process array
if (!empty($name) && !empty($reorderArr) && is_array($reorderArr)) {
//make sure reorderArr has values as keys, if not then iterate through and assign the value as the key
$newReorder = array();
foreach ($reorderArr as $rk=> $rv) {
if (is_int($rk)) {
$newReorder[$rv]=$rv;
} else {
$newReorder[$rk]=$rv;
}
}
//if module is not defined, lets default the order to another module of the same type
//this would apply mostly to custom modules
if (!isset($field_order_array[strtolower($name)]) && isset($_REQUEST['module'])) {
$exemptModuleList = array('ProspectLists');
if (in_array($name, $exemptModuleList)) {
return $newReorder;
}
//get an instance of the bean
global $beanList;
global $beanFiles;
$bean = $beanList[$_REQUEST['module']];
require_once($beanFiles[$bean]);
$focus = new $bean;
//if module is of type person
if ($focus instanceof Person) {
$name = 'contacts';
}
//if module is of type company
else {
if ($focus instanceof Company) {
$name = 'accounts';
}
//if module is of type Sale
else {
if ($focus instanceof Sale) {
$name = 'opportunities';
}//if module is of type File
else {
if ($focus instanceof Issue) {
$name = 'bugs';
}//all others including type File can use basic
else {
$name = 'Notes';
}
}
}
}
}
//lets iterate through and create a reordered temporary array using
//the newly formatted copy of passed in array
$temp_result_arr = array();
$lname = strtolower($name);
if (!empty($field_order_array[$lname])) {
foreach ($field_order_array[$lname] as $fk=> $fv) {
//if the value exists as a key in the passed in array, add to temp array and remove from reorder array.
//Do not force into the temp array as we don't want to violate acl's
if (array_key_exists($fk, $newReorder)) {
$temp_result_arr[$fk] = $newReorder[$fk];
unset($newReorder[$fk]);
}
}
}
//add in all the left over values that were not in our ordered list
//array_splice($temp_result_arr, count($temp_result_arr), 0, $newReorder);
foreach ($newReorder as $nrk=>$nrv) {
$temp_result_arr[$nrk] = $nrv;
}
if ($exclude) {
//Some arrays have values we wish to exclude
if (isset($fields_to_exclude[$lname])) {
foreach ($fields_to_exclude[$lname] as $exclude_field) {
unset($temp_result_arr[$exclude_field]);
}
}
}
//return temp ordered list
return $temp_result_arr;
}
//if no array was passed in, pass back either the list of ordered columns by module, or the entireorder array
if (empty($name)) {
return $field_order_array;
} else {
return $field_order_array[strtolower($name)];
}
}