Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
bd41820
Add missing business hours calculation to reports
mattlorimer Mar 6, 2020
54fb11c
Remove deprecated sudo from .travis.yml
Dillon-Brown Dec 24, 2019
b41018f
Fixed #3911 - LDAPAutheticate warnings in log
Dillon-Brown Mar 14, 2019
c4d162f
Update the index on the target list - targets middle table to include
Feb 5, 2020
6decebe
Fix usage of deprecated Redis::delete() function
tsitle Mar 7, 2020
ba68160
Fixed #8450 - Minor bug in GridLayoutMetaDataParser::addField()
tsitle Jan 25, 2020
aa8f423
Fix issue for non based on Emails Campaigns
QuickCRM Feb 28, 2020
c5f38fe
fix string_format
QuickCRM Mar 22, 2020
0fc4f27
Remove maxLength from user name in DB config
pgorod Jan 31, 2020
90a320b
Increase drive timeouts to be a little more lenient
Jason-Dang Jan 30, 2020
422bd2e
Fix #8549 - Cannot resize case updates text area
JackBuchanan Feb 14, 2020
2180e28
Add option to filter by email on V8 API
cameronblaikie Mar 6, 2020
6249863
Fix #6489 - Report pagination display
mattlorimer Apr 7, 2020
44270bb
Fix Username alignment in all screen widths
mattlorimer Mar 30, 2020
45792ea
Fix #8643 - Reports do not work related module custom fields
mattlorimer Apr 8, 2020
90dce7f
Fix #5487 - Report groups repeat for each record
mattlorimer Apr 7, 2020
82483d1
Fix #8499 - API V8 issues for password grants
serfreeman1337 Jan 29, 2020
7073858
Fix warnings when running upgrade via cli
mattlorimer Apr 7, 2020
92930a6
Remove duplicate call in Reports csv export
QuickCRM Apr 8, 2020
b6f9f30
Fix PHP notice in Subpanel
Mar 9, 2020
1ebd9c1
Fix PHP notice in TemplateHandler
Mar 9, 2020
ba89555
Avoid a PHP notice by calling session_start when a session already
Mar 9, 2020
e77522d
Add AOR_Reports to special_query_modules
QuickCRM Apr 8, 2020
1ec6135
Fix - Maps display data table fail to load correct language file
QuickCRM Apr 1, 2020
0e25bff
Fix #8484 - No validation when using header save button in Products
Mar 27, 2020
004909c
Move OAuth2 Encryption Key into config.php
tsitle Mar 15, 2020
cff2513
Fix missing query offset in SugarBean::get_linked_beans()
tsitle Mar 12, 2020
9b41c33
Fix indentation of multi-line function call
tsitle Mar 17, 2020
7d10b3c
Improved logging, squashed
pgorod Apr 23, 2020
09405d2
Updates for PHP 7.4 and greater
pgorod Mar 3, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
language: php
os: linux
sudo: required

matrix:
fast_finish: true
Expand Down
1 change: 0 additions & 1 deletion Api/Core/Config/ApiConfig.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ class ApiConfig

const OAUTH2_PRIVATE_KEY = 'Api/V8/OAuth2/private.key';
const OAUTH2_PUBLIC_KEY = 'Api/V8/OAuth2/public.key';
const OAUTH2_ENCRYPTION_KEY = '';

/**
*
Expand Down
24 changes: 8 additions & 16 deletions Api/V8/Config/services/middlewares.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,24 +35,16 @@
sprintf('file://%s/%s', $baseDir, ApiConfig::OAUTH2_PUBLIC_KEY)
);

if (empty(ApiConfig::OAUTH2_ENCRYPTION_KEY)) {
$oldKey = "OAUTH2_ENCRYPTION_KEY = '" . ApiConfig::OAUTH2_ENCRYPTION_KEY;
$key = "OAUTH2_ENCRYPTION_KEY = '" . base64_encode(random_bytes(32));
$apiConfig = file_get_contents('Api/Core/Config/ApiConfig.php');

$configFileContents = str_replace(
$oldKey,
$key,
$apiConfig
);
file_put_contents(
'Api/Core/Config/ApiConfig.php',
$configFileContents,
LOCK_EX
);
$oauth2EncKey = isset($GLOBALS['sugar_config']['oauth2_encryption_key'])
? $GLOBALS['sugar_config']['oauth2_encryption_key'] : '';
if (empty($oauth2EncKey)) {
$oauth2EncKey = 'SCRM-DEFK';
if (isset($GLOBALS['log'])) {
$GLOBALS['log']->fatal('WARNING: `oauth2_encryption_key` not set in config.php');
}
}

$server->setEncryptionKey(ApiConfig::OAUTH2_ENCRYPTION_KEY);
$server->setEncryptionKey($oauth2EncKey);

// Client credentials grant
$server->enableGrantType(
Expand Down
16 changes: 14 additions & 2 deletions Api/V8/OAuth2/Entity/UserEntity.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,24 @@

class UserEntity implements UserEntityInterface
{
/**
* @var $userId
*/
private $userId;

/**
* @param string $userId
*/
public function __construct($userId)
{
$this->userId = $userId;
}

/**
* @inheritdoc
*/
public function getIdentifier()
{
// we skip this right now, since we are not using scopes atm
return true;
return $this->userId;
}
}
14 changes: 1 addition & 13 deletions Api/V8/OAuth2/Repository/AccessTokenRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -62,19 +62,9 @@ public function persistNewAccessToken(AccessTokenEntityInterface $accessTokenEnt
/** @var User $user */
$client = $this->beanManager->getBeanSafe('OAuth2Clients', $clientId);

/** @var User $user */
$user = $this->beanManager->newBeanSafe('Users');

switch ($client->allowed_grant_type) {
case 'password':
if (!empty($_POST['username'])) {
/** @var User $user */
$user = $this->beanManager->newBeanSafe('Users');
$user->retrieve_by_string_fields(
['user_name' => $_POST['username']]
);
$userId = $user->id;
}
$userId = $accessTokenEntity->getUserIdentifier();
break;
case 'client_credentials':
$userId = $client->assigned_user_id;
Expand All @@ -85,8 +75,6 @@ public function persistNewAccessToken(AccessTokenEntityInterface $accessTokenEnt
throw new InvalidArgumentException('No user found');
}

$userId = !empty($user->id) ? $user->id : $client->assigned_user_id;

/** @var OAuth2Tokens $token */
$token = $this->beanManager->newBeanSafe(OAuth2Tokens::class);

Expand Down
2 changes: 1 addition & 1 deletion Api/V8/OAuth2/Repository/UserRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,6 @@ public function getUserEntityByUserCredentials(
throw new \InvalidArgumentException('The password is invalid: ' . $password);
}

return new UserEntity();
return new UserEntity($user->id);
}
}
79 changes: 70 additions & 9 deletions Api/V8/Service/ModuleService.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace Api\V8\Service;

use Api\V8\BeanDecorator\BeanListResponse;
use Api\V8\BeanDecorator\BeanManager;
use Api\V8\JsonApi\Helper\AttributeObjectHelper;
use Api\V8\JsonApi\Helper\PaginationObjectHelper;
Expand Down Expand Up @@ -91,6 +92,7 @@ public function getRecord(GetModuleParams $params, $path)
*/
public function getRecords(GetModulesParams $params, Request $request)
{
global $db;
// this whole method should split into separated classes later
$module = $params->getModuleName();
$orderBy = $params->getSort();
Expand Down Expand Up @@ -118,16 +120,75 @@ public function getRecords(GetModulesParams $params, Request $request)
$fields = $this->beanManager->getDefaultFields($bean);
}

$beanListResponse = $this->beanManager->getList($module)
->orderBy($orderBy)
->where($where)
->offset($offset)
->limit($limit)
->max($size)
->deleted($deleted)
->fields($this->beanManager->filterAcceptanceFields($bean, $fields))
->fetch();
// Detect if bean has email field
if ((property_exists($bean, 'email1')
&& strpos($where, 'email1') !== false)
|| (property_exists($bean, 'email2')
&& strpos($where, 'email2') !== false)
) {

$selectedModule = strtolower($module);

// Selects Module or COUNT(*) and will add one to the query.
$idSelect = 'SELECT ' . $selectedModule . '.id ';
$countSelect = 'SELECT COUNT(*) AS cnt ';

$quotedCountSelect = $db->quote($countSelect);

// Email where clause
$fromQuery
= 'FROM email_addresses JOIN email_addr_bean_rel ON email_addresses.id = email_addr_bean_rel.email_address_id JOIN '
. $selectedModule . ' ON ' . $selectedModule
. '.id = email_addr_bean_rel.bean_id ';
$modifiedWhere = str_replace('accounts.email1',
'email_addresses.email_address', $where);
$where = $modifiedWhere;

// Sets and adds deleted to the query
if ($deleted == 0) {
$whereAuto = '' . $bean->table_name . ' .deleted=0';
} elseif ($deleted == 1) {
$whereAuto = '' . $bean->table_name . ' .deleted=1';
}
if ($where != '') {
$where = ' where (' . $where . ') AND ' . $whereAuto . '';
} else {
$where = ' where ' . $whereAuto . '';
}

// Joins parts together to form query
$query = $idSelect . $fromQuery . $where;
$countQuery = $quotedCountSelect . $fromQuery . $where;
$realRowCount = (int)$db->fetchRow($db->query($countQuery, true, ''))['cnt'];

// Sets order by into the query
$order_by = $bean->process_order_by($orderBy);
if (!empty($orderBy)) {
$query .= ' ORDER BY ' . $order_by;
}

$result = $bean->process_list_query($query, $offset, $limit, -1, $where);
$beanResult['row_count'] = $result['row_count'];
$beanList = [];

foreach ($result['list'] as $resultBean) {
$queryModuleBean = \BeanFactory::newBean($module);
$queryModuleBean->id = $resultBean->id;
$beanList[] = $queryModuleBean;
}
$beanResult['list'] = $beanList;
$beanListResponse = new BeanListResponse($beanResult);
} else {
$beanListResponse = $this->beanManager->getList($module)
->orderBy($orderBy)
->where($where)
->offset($offset)
->limit($limit)
->max($size)
->deleted($deleted)
->fields($this->beanManager->filterAcceptanceFields($bean, $fields))
->fetch();
}

$beanArray = [];
foreach ($beanListResponse->getBeans() as $bean) {
Expand Down
13 changes: 7 additions & 6 deletions data/SugarBean.php
Original file line number Diff line number Diff line change
Expand Up @@ -2065,13 +2065,14 @@ public function get_linked_beans(
));
}
// Link2 style
if ($end_index != -1 || !empty($deleted) || !empty($optional_where) || !empty($order_by)) {
if ($begin_index != 0 || $end_index != -1 || !empty($deleted) || !empty($optional_where) || !empty($order_by)) {
return array_values($this->$field_name->getBeans(array(
'where' => $optional_where,
'deleted' => $deleted,
'limit' => ($end_index - $begin_index),
'order_by' => $order_by
)));
'where' => $optional_where,
'deleted' => $deleted,
'offset' => $begin_index,
'limit' => ($end_index - $begin_index),
'order_by' => $order_by
)));
}
return array_values($this->$field_name->getBeans());
}
Expand Down
34 changes: 27 additions & 7 deletions include/MVC/Controller/SugarController.php
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,12 @@ class SugarController
'listview' => 'ListView'
);

public $breadcrumbs = Array(
'entryPointFile' => '',
'processTasksHistory' => '',
'handleActionTasksHistory' => '',
);

/**
* Constructor. This ie meant to load up the module, action, record as well
* as the mapping arrays.
Expand Down Expand Up @@ -453,6 +459,7 @@ public function process()
{
$GLOBALS['action'] = $this->action;
$GLOBALS['module'] = $this->module;
$this->breadcrumbs['processTasksHistory'] = '';

//check to ensure we have access to the module.
if ($this->hasAccess) {
Expand All @@ -465,7 +472,9 @@ public function process()
$processed = false;
if (!$this->_processed) {
foreach ($this->process_tasks as $process) {
$this->breadcrumbs['processTasksHistory'] .= $process . '…';
$this->$process();
$this->breadcrumbs['processTasksHistory'] .= 'ok. ';
if ($this->_processed) {
break;
}
Expand All @@ -474,6 +483,7 @@ public function process()

$this->redirect();
} else {
$this->breadcrumbs['processTasksHistory'] .= 'no access!';
$this->no_access();
}
}
Expand All @@ -489,22 +499,27 @@ public function process()
*/
protected function handle_action()
{
$this->breadcrumbs['handleActionTasksHistory'] = '';

$processed = false;
foreach ($this->tasks as $task) {
$this->breadcrumbs['handleActionTasksHistory'] .= $task . '…';
$processed = ($this->$task() || $processed);
$this->breadcrumbs['handleActionTasksHistory'] .= 'ok. ';
}
$this->_processed = $processed;
}

/**
* Perform an action prior to the specified action.
* This can be overridde in a sub-class
* This can be overridden in a sub-class
*/
private function pre_action()
{
$function = $this->getPreActionMethodName();
if ($this->hasFunction($function)) {
$GLOBALS['log']->debug('Performing pre_action');
$this->breadcrumbs['handleActionTasksHistory'] .= $function. ' ';
$GLOBALS['log']->debug('Performing pre_action' . $function . ' MODULE: ' . $this->module);
$this->$function();

return true;
Expand All @@ -515,13 +530,14 @@ private function pre_action()

/**
* Perform the specified action.
* This can be overridde in a sub-class
* This can be overridden in a sub-class
*/
private function do_action()
{
$function = $this->getActionMethodName();
if ($this->hasFunction($function)) {
$GLOBALS['log']->debug('Performing action: ' . $function . ' MODULE: ' . $this->module);
$this->breadcrumbs['handleActionTasksHistory'] .= $function. ' ';
$GLOBALS['log']->debug('Performing do_action: ' . $function . ' MODULE: ' . $this->module);
$this->$function();

return true;
Expand All @@ -532,13 +548,14 @@ private function do_action()

/**
* Perform an action after to the specified action has occurred.
* This can be overridde in a sub-class
* This can be overridden in a sub-class
*/
private function post_action()
{
$function = $this->getPostActionMethodName();
if ($this->hasFunction($function)) {
$GLOBALS['log']->debug('Performing post_action');
$this->breadcrumbs['handleActionTasksHistory'] .= $function. ' ';
$GLOBALS['log']->debug('Performing post_action' . $function . ' MODULE: ' . $this->module);
$this->$function();

return true;
Expand Down Expand Up @@ -621,6 +638,7 @@ protected function set_redirect($url)
protected function redirect()
{
if (!empty($this->redirect_url)) {
$this->breadcrumbs['processTasksHistory'] .= 'redirect…';
SugarApplication::redirect($this->redirect_url);
}
}
Expand Down Expand Up @@ -1012,12 +1030,14 @@ private function blockFileAccess()
*/
private function handleEntryPoint()
{
$this->breadcrumbs['entryPointFile'] = '';
if (!empty($_REQUEST['entryPoint'])) {
$this->loadMapping('entry_point_registry');
$entryPoint = $_REQUEST['entryPoint'];

if (!empty($this->entry_point_registry[$entryPoint])) {
require_once($this->entry_point_registry[$entryPoint]['file']);
$this->breadcrumbs['entryPointFile'] = $this->entry_point_registry[$entryPoint]['file'];
require_once($this->breadcrumbs['entryPointFile']);
$this->_processed = true;
$this->view = '';
}
Expand Down
3 changes: 3 additions & 0 deletions include/SubPanel/SubPanelTiles.php
Original file line number Diff line number Diff line change
Expand Up @@ -383,6 +383,9 @@ public function display($showContainer = true, $forceTabless = false)

$tab_names = '["' . implode('","', $tab_names) . '"]';

if (!isset($module_sub_panels)) {
$module_sub_panels = [];
}
$module_sub_panels = array_map('array_keys', $module_sub_panels);
$module_sub_panels = json_encode($module_sub_panels);

Expand Down
2 changes: 1 addition & 1 deletion include/SugarCache/SugarCacheRedis.php
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ protected function _clearExternal(
$key
) {
$key = $this->_fixKeyName($key);
$this->_getRedisObject()->delete($key);
$this->_getRedisObject()->del($key);
}

/**
Expand Down
4 changes: 3 additions & 1 deletion include/SugarLogger/LoggerManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,8 @@ class LoggerManager
'debug' => 100,
'info' => 70,
'warn' => 50,
'PHP E' => 45,
'PHP S' => 44,
'deprecated' => 40,
'error' => 25,
'fatal' => 10,
Expand Down Expand Up @@ -228,7 +230,7 @@ protected function _findAvailableLoggers()
}
require_once("$location/$file");
$loggerClass = basename($file, '.php');
if (class_exists($loggerClass) && class_implements($loggerClass, 'LoggerTemplate')) {
if (class_exists($loggerClass) && in_array('LoggerTemplate', class_implements($loggerClass))) {
self::$_loggers[$loggerClass] = new $loggerClass();
}
}
Expand Down
Loading