mirror of
https://github.com/SuiteCRM/SuiteCRM-Core.git
synced 2025-08-29 04:21:06 +08:00
SuiteCRM 8.6.1 Release
This commit is contained in:
parent
1a39227980
commit
f483bec4cf
25 changed files with 1713 additions and 1498 deletions
|
@ -2,7 +2,7 @@
|
|||
<img width="180px" height="41px" src="https://suitecrm.com/wp-content/uploads/2017/12/logo.png" align="right" />
|
||||
</a>
|
||||
|
||||
# SuiteCRM 8.6.0
|
||||
# SuiteCRM 8.6.1
|
||||
|
||||
[](https://github.com/salesagility/suitecrm/blob/hotfix/LICENSE.txt)
|
||||
[](https://github.com/salesagility/SuiteCRM-Core/issues)
|
||||
|
|
2
VERSION
2
VERSION
|
@ -1 +1 @@
|
|||
8.6.0
|
||||
8.6.1
|
||||
|
|
|
@ -87,7 +87,6 @@
|
|||
"tecnickcom/tcpdf": "^6.4",
|
||||
"tedivm/jshrink": "^1.3",
|
||||
"tinymce/tinymce": "^5.10",
|
||||
"tuupola/slim-jwt-auth": "^2.0",
|
||||
"vlucas/phpdotenv": "^3.5",
|
||||
"voku/anti-xss": "^4.1",
|
||||
"webonyx/graphql-php": "^0.13.8",
|
||||
|
|
140
composer.lock
generated
140
composer.lock
generated
|
@ -4,7 +4,7 @@
|
|||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "e576320852b29ba5bbaeb161fdb3904f",
|
||||
"content-hash": "0013c270369ae4573daa9e6c29448bc5",
|
||||
"packages": [
|
||||
{
|
||||
"name": "api-platform/core",
|
||||
|
@ -1955,25 +1955,31 @@
|
|||
},
|
||||
{
|
||||
"name": "firebase/php-jwt",
|
||||
"version": "v5.5.1",
|
||||
"version": "v6.10.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/firebase/php-jwt.git",
|
||||
"reference": "83b609028194aa042ea33b5af2d41a7427de80e6"
|
||||
"reference": "a49db6f0a5033aef5143295342f1c95521b075ff"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/firebase/php-jwt/zipball/83b609028194aa042ea33b5af2d41a7427de80e6",
|
||||
"reference": "83b609028194aa042ea33b5af2d41a7427de80e6",
|
||||
"url": "https://api.github.com/repos/firebase/php-jwt/zipball/a49db6f0a5033aef5143295342f1c95521b075ff",
|
||||
"reference": "a49db6f0a5033aef5143295342f1c95521b075ff",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.0"
|
||||
"php": "^7.4||^8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": ">=4.8 <=9"
|
||||
"guzzlehttp/guzzle": "^6.5||^7.4",
|
||||
"phpspec/prophecy-phpunit": "^2.0",
|
||||
"phpunit/phpunit": "^9.5",
|
||||
"psr/cache": "^1.0||^2.0",
|
||||
"psr/http-client": "^1.0",
|
||||
"psr/http-factory": "^1.0"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-sodium": "Support EdDSA (Ed25519) signatures",
|
||||
"paragonie/sodium_compat": "Support EdDSA (Ed25519) signatures when libsodium is not present"
|
||||
},
|
||||
"type": "library",
|
||||
|
@ -2004,7 +2010,11 @@
|
|||
"jwt",
|
||||
"php"
|
||||
],
|
||||
"time": "2021-11-08T20:18:51+00:00"
|
||||
"support": {
|
||||
"issues": "https://github.com/firebase/php-jwt/issues",
|
||||
"source": "https://github.com/firebase/php-jwt/tree/v6.10.0"
|
||||
},
|
||||
"time": "2023-12-01T16:26:39+00:00"
|
||||
},
|
||||
{
|
||||
"name": "friendsofphp/proxy-manager-lts",
|
||||
|
@ -3199,16 +3209,16 @@
|
|||
},
|
||||
{
|
||||
"name": "league/oauth2-server",
|
||||
"version": "8.4.1",
|
||||
"version": "8.4.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/thephpleague/oauth2-server.git",
|
||||
"reference": "eed31d86d8cc8e6e9c9f58fbb2113494f8b41e24"
|
||||
"reference": "007dc5f6c0151a73b133fec36c9686cc956209d3"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/thephpleague/oauth2-server/zipball/eed31d86d8cc8e6e9c9f58fbb2113494f8b41e24",
|
||||
"reference": "eed31d86d8cc8e6e9c9f58fbb2113494f8b41e24",
|
||||
"url": "https://api.github.com/repos/thephpleague/oauth2-server/zipball/007dc5f6c0151a73b133fec36c9686cc956209d3",
|
||||
"reference": "007dc5f6c0151a73b133fec36c9686cc956209d3",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -3273,13 +3283,17 @@
|
|||
"secure",
|
||||
"server"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/thephpleague/oauth2-server/issues",
|
||||
"source": "https://github.com/thephpleague/oauth2-server/tree/8.4.2"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://github.com/sephster",
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2023-03-22T11:47:53+00:00"
|
||||
"time": "2023-08-02T22:54:39+00:00"
|
||||
},
|
||||
{
|
||||
"name": "league/uri",
|
||||
|
@ -4243,16 +4257,16 @@
|
|||
},
|
||||
{
|
||||
"name": "phpseclib/phpseclib",
|
||||
"version": "3.0.19",
|
||||
"version": "3.0.37",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/phpseclib/phpseclib.git",
|
||||
"reference": "cc181005cf548bfd8a4896383bb825d859259f95"
|
||||
"reference": "cfa2013d0f68c062055180dd4328cc8b9d1f30b8"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/cc181005cf548bfd8a4896383bb825d859259f95",
|
||||
"reference": "cc181005cf548bfd8a4896383bb825d859259f95",
|
||||
"url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/cfa2013d0f68c062055180dd4328cc8b9d1f30b8",
|
||||
"reference": "cfa2013d0f68c062055180dd4328cc8b9d1f30b8",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -4331,6 +4345,10 @@
|
|||
"x.509",
|
||||
"x509"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/phpseclib/phpseclib/issues",
|
||||
"source": "https://github.com/phpseclib/phpseclib/tree/3.0.37"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://github.com/terrafrost",
|
||||
|
@ -4345,7 +4363,7 @@
|
|||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2023-03-05T17:13:09+00:00"
|
||||
"time": "2024-03-03T02:14:58+00:00"
|
||||
},
|
||||
{
|
||||
"name": "pimple/pimple",
|
||||
|
@ -9802,20 +9820,20 @@
|
|||
},
|
||||
{
|
||||
"name": "tecnickcom/tcpdf",
|
||||
"version": "6.6.2",
|
||||
"version": "6.7.5",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/tecnickcom/TCPDF.git",
|
||||
"reference": "e3cffc9bcbc76e89e167e9eb0bbda0cab7518459"
|
||||
"reference": "951eabf0338ec2522bd0d5d9c79b08a3a3d36b36"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/tecnickcom/TCPDF/zipball/e3cffc9bcbc76e89e167e9eb0bbda0cab7518459",
|
||||
"reference": "e3cffc9bcbc76e89e167e9eb0bbda0cab7518459",
|
||||
"url": "https://api.github.com/repos/tecnickcom/TCPDF/zipball/951eabf0338ec2522bd0d5d9c79b08a3a3d36b36",
|
||||
"reference": "951eabf0338ec2522bd0d5d9c79b08a3a3d36b36",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.0"
|
||||
"php": ">=5.5.0"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
|
@ -9840,7 +9858,7 @@
|
|||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"LGPL-3.0-only"
|
||||
"LGPL-3.0-or-later"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
|
@ -9860,13 +9878,17 @@
|
|||
"pdf417",
|
||||
"qrcode"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/tecnickcom/TCPDF/issues",
|
||||
"source": "https://github.com/tecnickcom/TCPDF/tree/6.7.5"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://www.paypal.com/cgi-bin/webscr?cmd=_donations¤cy_code=GBP&business=paypal@tecnick.com&item_name=donation%20for%20tcpdf%20project",
|
||||
"type": "custom"
|
||||
}
|
||||
],
|
||||
"time": "2022-12-17T10:28:59+00:00"
|
||||
"time": "2024-04-20T17:25:10+00:00"
|
||||
},
|
||||
{
|
||||
"name": "tedivm/jshrink",
|
||||
|
@ -9926,16 +9948,16 @@
|
|||
},
|
||||
{
|
||||
"name": "tinymce/tinymce",
|
||||
"version": "5.10.7",
|
||||
"version": "5.10.9",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/tinymce/tinymce-dist.git",
|
||||
"reference": "f078d8eb7de81f20d34b2ae4326870d20e22d4ff"
|
||||
"reference": "e5650a256f8941a0593ec0b9d3c435f20f1d4245"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/tinymce/tinymce-dist/zipball/f078d8eb7de81f20d34b2ae4326870d20e22d4ff",
|
||||
"reference": "f078d8eb7de81f20d34b2ae4326870d20e22d4ff",
|
||||
"url": "https://api.github.com/repos/tinymce/tinymce-dist/zipball/e5650a256f8941a0593ec0b9d3c435f20f1d4245",
|
||||
"reference": "e5650a256f8941a0593ec0b9d3c435f20f1d4245",
|
||||
"shasum": ""
|
||||
},
|
||||
"type": "component",
|
||||
|
@ -9976,62 +9998,10 @@
|
|||
"tinymce",
|
||||
"wysiwyg"
|
||||
],
|
||||
"time": "2022-12-07T03:50:54+00:00"
|
||||
},
|
||||
{
|
||||
"name": "tuupola/slim-jwt-auth",
|
||||
"version": "2.4.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/tuupola/slim-jwt-auth.git",
|
||||
"reference": "bca54de41a8207d4d67faf3601a06a96cb7ed48f"
|
||||
"support": {
|
||||
"source": "https://github.com/tinymce/tinymce-dist/tree/5.10.9"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/tuupola/slim-jwt-auth/zipball/bca54de41a8207d4d67faf3601a06a96cb7ed48f",
|
||||
"reference": "bca54de41a8207d4d67faf3601a06a96cb7ed48f",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"firebase/php-jwt": "^3.0 || ^4.0 || ^5.0",
|
||||
"php": "^5.5 || ^7.0",
|
||||
"psr/http-message": "^1.0",
|
||||
"psr/log": "^1.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"overtrue/phplint": "^0.2.4",
|
||||
"phpunit/phpunit": "^4.6",
|
||||
"squizlabs/php_codesniffer": "^2.3",
|
||||
"zendframework/zend-diactoros": "^1.3"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Slim\\Middleware\\": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Mika Tuupola",
|
||||
"email": "tuupola@appelsiini.net",
|
||||
"homepage": "http://www.appelsiini.net/",
|
||||
"role": "Developer"
|
||||
}
|
||||
],
|
||||
"description": "PSR-7 JWT Authentication Middleware",
|
||||
"homepage": "https://github.com/tuupola/slim-jwt-auth",
|
||||
"keywords": [
|
||||
"auth",
|
||||
"json",
|
||||
"jwt",
|
||||
"middleware",
|
||||
"psr-7"
|
||||
],
|
||||
"time": "2018-04-03T06:12:18+00:00"
|
||||
"time": "2023-11-15T00:42:08+00:00"
|
||||
},
|
||||
{
|
||||
"name": "twig/twig",
|
||||
|
@ -16320,5 +16290,5 @@
|
|||
"platform-overrides": {
|
||||
"php": "7.4.0"
|
||||
},
|
||||
"plugin-api-version": "1.1.0"
|
||||
"plugin-api-version": "2.6.0"
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "common",
|
||||
"version": "8.6.0",
|
||||
"version": "8.6.1",
|
||||
"peerDependencies": {
|
||||
"@angular/common": "^12.1.0",
|
||||
"@angular/core": "^12.1.0",
|
||||
|
|
|
@ -46,6 +46,8 @@ export interface ViewFieldDefinition {
|
|||
metadata?: FieldMetadata;
|
||||
logic?: FieldLogicMap;
|
||||
displayLogic?: FieldLogicMap;
|
||||
|
||||
[key: string]: any;
|
||||
}
|
||||
|
||||
export interface Panel {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "core",
|
||||
"version": "8.6.0",
|
||||
"version": "8.6.1",
|
||||
"peerDependencies": {
|
||||
"@angular/common": "^12.1.0",
|
||||
"@angular/core": "^12.1.0",
|
||||
|
|
|
@ -43,7 +43,7 @@ import {
|
|||
import {AsyncValidatorFn, UntypedFormArray, UntypedFormControl, ValidatorFn} from '@angular/forms';
|
||||
import {LanguageStore} from '../../../store/language/language.store';
|
||||
import get from 'lodash-es/get';
|
||||
import {merge} from 'lodash-es';
|
||||
import {isEmpty, merge} from 'lodash-es';
|
||||
import {FieldObjectRegistry} from "./field-object-type.registry";
|
||||
|
||||
|
||||
|
@ -69,7 +69,15 @@ export class FieldBuilder {
|
|||
*/
|
||||
public buildField(record: Record, viewField: ViewFieldDefinition, language: LanguageStore = null): Field {
|
||||
|
||||
const definition = (viewField && viewField.fieldDefinition) || {} as FieldDefinition;
|
||||
const module = record?.module ?? '';
|
||||
let definition = viewField?.fieldDefinition ?? {} as FieldDefinition;
|
||||
const multiModuleDefinitions = viewField?.multiModuleDefinitions ?? {} as ObjectMap;
|
||||
const currentModuleDefinitions = multiModuleDefinitions[module] ?? {} as FieldDefinition;
|
||||
|
||||
if (!isEmpty(currentModuleDefinitions)){
|
||||
definition = currentModuleDefinitions;
|
||||
}
|
||||
|
||||
const {value, valueList, valueObject} = this.parseValue(viewField, definition, record);
|
||||
const {validators, asyncValidators} = this.getSaveValidators(record, viewField);
|
||||
|
||||
|
|
|
@ -221,7 +221,7 @@ class InstallHandler extends LegacyHandler
|
|||
|
||||
$checkFile = __DIR__ . '/../../../../.curl_check_main_page';
|
||||
|
||||
require_once "core/backend/Install/Service/InstallPreChecks.php";
|
||||
require_once __DIR__ . "/../../../../core/backend/Install/Service/InstallPreChecks.php";
|
||||
$installChecks = new InstallPreChecks($log);
|
||||
|
||||
try {
|
||||
|
|
|
@ -71,11 +71,16 @@ trait InstallationUtilsTrait
|
|||
public function getLegacyConfig($legacyDir): ?array
|
||||
{
|
||||
$sugarConfigFile = $legacyDir . '/config.php';
|
||||
$sugarOverrideConfigFile = $legacyDir . '/config_override.php';
|
||||
|
||||
if (is_file($sugarConfigFile)) {
|
||||
$sugar_config = [];
|
||||
include $sugarConfigFile;
|
||||
|
||||
if (is_file($sugarOverrideConfigFile)) {
|
||||
include $sugarOverrideConfigFile;
|
||||
}
|
||||
|
||||
return $sugar_config;
|
||||
}
|
||||
|
||||
|
|
|
@ -114,15 +114,22 @@ class Kernel extends BaseKernel
|
|||
$routes->import($confDir . '/{routes}' . self::CONFIG_EXTS, '/', 'glob');
|
||||
}
|
||||
|
||||
/**
|
||||
* Init bundles and container
|
||||
* @return void
|
||||
*/
|
||||
public function init(): void
|
||||
{
|
||||
$this->initializeBundles();
|
||||
$this->initializeContainer();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @return array
|
||||
*/
|
||||
public function getLegacyRoute(Request $request): array
|
||||
{
|
||||
$this->initializeBundles();
|
||||
$this->initializeContainer();
|
||||
|
||||
if ($this->container->has('legacy.route.handler')) {
|
||||
return $this->container->get('legacy.route.handler')->getLegacyRoute($request);
|
||||
}
|
||||
|
|
|
@ -112,7 +112,7 @@ class LegacyApiRedirectHandler extends LegacyRedirectHandler
|
|||
|
||||
return [
|
||||
'dir' => '',
|
||||
'file' => 'index.php',
|
||||
'file' => './index.php',
|
||||
'access' => true
|
||||
];
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
|
||||
namespace App\Routes\Service;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
|
||||
class LegacyRedirectHandler
|
||||
|
@ -88,6 +89,10 @@ class LegacyRedirectHandler
|
|||
|
||||
$baseUrl = substr($baseUrl, 1);
|
||||
|
||||
if (strpos($baseUrl, '../') !== false) {
|
||||
throw new InvalidArgumentException('invalid path');
|
||||
}
|
||||
|
||||
if (strpos($baseUrl, '.php') === false) {
|
||||
$baseUrl .= 'index.php';
|
||||
}
|
||||
|
|
|
@ -62,8 +62,7 @@ trait FieldDefinitionsInjectorTrait
|
|||
return $field;
|
||||
}
|
||||
|
||||
$alias = $fieldAliasMapper->map($vardefs[$name]);
|
||||
$aliasDefs = $vardefs[$alias] ?? $vardefs[$name];
|
||||
$aliasDefs = $this->getAliasDefinitions($fieldAliasMapper, $vardefs, $name);
|
||||
|
||||
$field['fieldDefinition'] = $aliasDefs;
|
||||
$field['name'] = $aliasDefs['name'] ?? $field['name'];
|
||||
|
@ -112,4 +111,20 @@ trait FieldDefinitionsInjectorTrait
|
|||
|
||||
return $field;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param FieldAliasMapper $fieldAliasMapper
|
||||
* @param array $vardefs
|
||||
* @param string $name
|
||||
* @return mixed
|
||||
*/
|
||||
protected function getAliasDefinitions(FieldAliasMapper $fieldAliasMapper, array $vardefs, string $name)
|
||||
{
|
||||
if (empty($vardefs[$name])) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$alias = $fieldAliasMapper->map($vardefs[$name]);
|
||||
return $vardefs[$alias] ?? $vardefs[$name];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -198,9 +198,11 @@ class SubPanelDefinitionHandler extends LegacyHandler implements SubPanelDefinit
|
|||
}
|
||||
|
||||
$columnSubpanel = $subpanel;
|
||||
$extraModuleVardefs = [];
|
||||
if (!empty($tab['collection_list'])) {
|
||||
$columnSubpanel = $subpanel->get_header_panel_def();
|
||||
$headerModule = $this->moduleNameMapper->toFrontEnd($columnSubpanel->get_module_name());
|
||||
$extraModuleVardefs = $this->getCollectionListVardefs($tab['collection_list']);
|
||||
} else {
|
||||
$headerModule = $this->getHeaderModule($tab);
|
||||
}
|
||||
|
@ -223,7 +225,7 @@ class SubPanelDefinitionHandler extends LegacyHandler implements SubPanelDefinit
|
|||
|
||||
$resultingTabs[$key] = $tabs[$key];
|
||||
|
||||
$mapColumns = $this->mapColumns($columnSubpanel, $vardefs);
|
||||
$mapColumns = $this->mapColumns($columnSubpanel, $vardefs, $extraModuleVardefs);
|
||||
|
||||
if (!empty($tab['collection_list'])) {
|
||||
$iconColumn = $this->buildIconColumn($tab['module']);
|
||||
|
@ -292,9 +294,9 @@ class SubPanelDefinitionHandler extends LegacyHandler implements SubPanelDefinit
|
|||
|
||||
$topButtonDefinitions = $this->getButtonDefinitions($subpanel);
|
||||
|
||||
foreach($topButtonDefinitions as $key => $value){
|
||||
if (stripos($value['widget_class'], 'topfilter')){
|
||||
if (!$this->getSearchdefs($subpanel) && !$searchDefs['searchdefs']){
|
||||
foreach ($topButtonDefinitions as $key => $value) {
|
||||
if (stripos($value['widget_class'], 'topfilter')) {
|
||||
if (!$this->getSearchdefs($subpanel) && !$searchDefs['searchdefs']) {
|
||||
unset($topButtonDefinitions[$key]);
|
||||
break;
|
||||
}
|
||||
|
@ -321,7 +323,7 @@ class SubPanelDefinitionHandler extends LegacyHandler implements SubPanelDefinit
|
|||
protected function getSearchdefs(aSubPanel $subpanel) {
|
||||
$searchDefs = $subpanel->_instance_properties['searchdefs'] ?? '';
|
||||
|
||||
if (!empty($searchDefs)){
|
||||
if (!empty($searchDefs)) {
|
||||
foreach ($searchDefs as &$field) {
|
||||
$fieldDefinition = [
|
||||
'name' => $field['name'],
|
||||
|
@ -354,7 +356,7 @@ class SubPanelDefinitionHandler extends LegacyHandler implements SubPanelDefinit
|
|||
* @param array $vardefs
|
||||
* @return array
|
||||
*/
|
||||
protected function mapColumns(aSubPanel $subpanel, array $vardefs): array
|
||||
protected function mapColumns(aSubPanel $subpanel, array $vardefs, array $extraModuleVardefs): array
|
||||
{
|
||||
$panelDefinition = $subpanel->panel_definition ?? [];
|
||||
$listFields = $panelDefinition['list_fields'] ?? [];
|
||||
|
@ -377,7 +379,13 @@ class SubPanelDefinitionHandler extends LegacyHandler implements SubPanelDefinit
|
|||
continue;
|
||||
}
|
||||
|
||||
$definitions[] = $this->buildColumn($column, $key, $vardefs);
|
||||
$definition = $this->buildColumn($column, $key, $vardefs);
|
||||
|
||||
if (!empty($extraModuleVardefs)) {
|
||||
$definition = $this->addMultiModuleVardefs($extraModuleVardefs, $key, $definition);
|
||||
}
|
||||
|
||||
$definitions[] = $definition;
|
||||
}
|
||||
|
||||
return $definitions;
|
||||
|
@ -597,4 +605,70 @@ class SubPanelDefinitionHandler extends LegacyHandler implements SubPanelDefinit
|
|||
|
||||
return $lineActions;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $collection_list
|
||||
* @return array
|
||||
*/
|
||||
protected function getCollectionListVardefs($collection_list): array
|
||||
{
|
||||
$extraModuleVardefs = [];
|
||||
if (!is_array($collection_list)) {
|
||||
return $extraModuleVardefs;
|
||||
}
|
||||
|
||||
foreach ($collection_list as $item) {
|
||||
$itemLegacyModuleName = $item['module'] ?? '';
|
||||
if (empty($itemLegacyModuleName)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$itemModule = $this->moduleNameMapper->toFrontEnd($itemLegacyModuleName);
|
||||
if (empty($itemModule)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$itemVardefs = $this->getSubpanelModuleVardefs($itemModule);
|
||||
if (empty($itemVardefs)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$extraModuleVardefs[$itemModule] = $itemVardefs;
|
||||
}
|
||||
|
||||
return $extraModuleVardefs;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $extraModuleVardefs
|
||||
* @param int|string $key
|
||||
* @param array $definition
|
||||
* @return array
|
||||
*/
|
||||
protected function addMultiModuleVardefs(array $extraModuleVardefs, $key, array $definition): array
|
||||
{
|
||||
|
||||
|
||||
$multiModuleFieldVardefs = [];
|
||||
foreach ($extraModuleVardefs as $module => $extraModuleVardef) {
|
||||
$alias = $definition['alias'] ?? '';
|
||||
|
||||
if (empty($extraModuleVardef[$alias])) {
|
||||
$alias = $key;
|
||||
}
|
||||
|
||||
$fieldDefs = $this->getAliasDefinitions($this->fieldAliasMapper, $extraModuleVardef, $alias);
|
||||
|
||||
if (!empty($fieldDefs)) {
|
||||
|
||||
$fieldDefs['name'] = $definition['name'];
|
||||
$fieldDefs['alias'] = $alias;
|
||||
|
||||
$multiModuleFieldVardefs[$module] = $fieldDefs;
|
||||
}
|
||||
}
|
||||
|
||||
$definition['multiModuleDefinitions'] = $multiModuleFieldVardefs;
|
||||
return $definition;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,5 @@
|
|||
{
|
||||
"extends": "tslint:recommended",
|
||||
"rulesDirectory": [
|
||||
"codelyzer"
|
||||
],
|
||||
"rules": {
|
||||
"align": {
|
||||
"options": [
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "suitecrm",
|
||||
"version": "8.6.0",
|
||||
"version": "8.6.1",
|
||||
"scripts": {
|
||||
"ng": "ng",
|
||||
"start": "npm run start:shell",
|
||||
|
@ -89,7 +89,6 @@
|
|||
"@typescript-eslint/eslint-plugin": "^2.34.0",
|
||||
"@typescript-eslint/parser": "^2.34.0",
|
||||
"barrelsby": "^2.2.0",
|
||||
"codelyzer": "^6.0.0",
|
||||
"eslint": "^6.8.0",
|
||||
"eslint-import-resolver-alias": "^1.1.2",
|
||||
"eslint-import-resolver-typescript": "^2.3.0",
|
||||
|
|
|
@ -34,6 +34,8 @@ require __DIR__ . '/../vendor/autoload.php';
|
|||
$kernel = new Kernel($_SERVER['APP_ENV'], (bool)$_SERVER['APP_DEBUG']);
|
||||
$request = Request::createFromGlobals();
|
||||
|
||||
$kernel->init();
|
||||
|
||||
global $legacyRoute;
|
||||
|
||||
$legacyRoute = $kernel->getLegacyRoute($request);
|
||||
|
@ -56,7 +58,7 @@ if (!empty($legacyRoute)) {
|
|||
if (file_exists($legacyRoute['file'])) {
|
||||
|
||||
/* @noinspection PhpIncludeInspection */
|
||||
require $legacyRoute['file'];
|
||||
require './' . $legacyRoute['file'];
|
||||
} else {
|
||||
|
||||
http_response_code(404);
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
<?php
|
||||
/**
|
||||
* SuiteCRM is a customer relationship management program developed by SalesAgility Ltd.
|
||||
* Copyright (C) 2024 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 SALESAGILITY, SALESAGILITY 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.
|
||||
*
|
||||
* 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
|
||||
* "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 "Supercharged by SuiteCRM".
|
||||
*/
|
||||
|
||||
trait HtmlFieldPurify
|
||||
{
|
||||
|
||||
/**
|
||||
* @param SugarBean $bean
|
||||
* @param string $field
|
||||
* @param mixed $value
|
||||
* @return string
|
||||
*/
|
||||
protected function purify(SugarBean $bean, string $field, mixed $value): string
|
||||
{
|
||||
$fieldDef = $bean->field_defs[$field] ?? [];
|
||||
|
||||
$purifyHtml = $fieldDef['metadata']['purifyHtml'] ?? true;
|
||||
|
||||
if ($purifyHtml === false || !is_string($value)) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
$extra = ['HTML.ForbiddenElements' => ['iframe' => true]];
|
||||
$allowIframe = $fieldDef['metadata']['allowIframe'] ?? false;
|
||||
if (isTrue($allowIframe)) {
|
||||
$extra = [];
|
||||
}
|
||||
|
||||
return purify_html(securexss($value), $extra);
|
||||
}
|
||||
}
|
|
@ -27,9 +27,12 @@
|
|||
|
||||
require_once __DIR__ . '/../../../ApiBeanMapper/FieldMappers/FieldMapperInterface.php';
|
||||
require_once __DIR__ . '/../../../ModuleNameMapper.php';
|
||||
require_once __DIR__ . '/../../Helpers/HtmlFieldPurify.php';
|
||||
|
||||
class CaseUpdatesDescriptionMapper implements FieldMapperInterface
|
||||
{
|
||||
use HtmlFieldPurify;
|
||||
|
||||
public const FIELD_NAME = 'description';
|
||||
|
||||
/**
|
||||
|
@ -51,7 +54,9 @@ class CaseUpdatesDescriptionMapper implements FieldMapperInterface
|
|||
public function toApi(SugarBean $bean, array &$container, string $alternativeName = ''): void
|
||||
{
|
||||
$name = self::FIELD_NAME;
|
||||
$container[$name] = html_entity_decode($bean->$name ?? '', ENT_QUOTES);
|
||||
$value = html_entity_decode($bean->$name ?? '', ENT_QUOTES);
|
||||
|
||||
$container[$name] = html_entity_decode($this->purify($bean, $name, $value));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -59,8 +64,10 @@ class CaseUpdatesDescriptionMapper implements FieldMapperInterface
|
|||
*/
|
||||
public function toBean(SugarBean $bean, array &$container, string $alternativeName = ''): void
|
||||
{
|
||||
$contents = $container[self::getField()] ?? [];
|
||||
$container[self::getField()] = nl2br($contents);
|
||||
$field = self::getField();
|
||||
$value = nl2br($container[$field] ?? '');
|
||||
|
||||
$container[$field] = $this->purify($bean, $field,$value);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -26,9 +26,12 @@
|
|||
*/
|
||||
|
||||
require_once __DIR__ . '/TypeMapperInterface.php';
|
||||
require_once __DIR__ . '/../Helpers/HtmlFieldPurify.php';
|
||||
|
||||
class HtmlMapper implements TypeMapperInterface
|
||||
{
|
||||
use HtmlFieldPurify;
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
|
@ -54,7 +57,9 @@ class HtmlMapper implements TypeMapperInterface
|
|||
return;
|
||||
}
|
||||
|
||||
$container[$newName] = $bean->$name;
|
||||
$value = html_entity_decode($bean->$name);
|
||||
|
||||
$container[$newName] = $this->purify($bean, $name, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -68,15 +73,12 @@ class HtmlMapper implements TypeMapperInterface
|
|||
$newName = $alternativeName;
|
||||
}
|
||||
|
||||
$fieldDef = $bean->field_defs[$newName] ?? [];
|
||||
|
||||
$purifyHtml = $fieldDef['metadata']['purifyHtml'] ?? true;
|
||||
$value = $container[$newName] ?? '';
|
||||
|
||||
if ($purifyHtml === false || empty($value) || !is_string($value)) {
|
||||
if (empty($value)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$container[$newName] = purify_html(securexss($value));
|
||||
$container[$newName] = $this->purify($bean, $name, $value);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,9 +26,12 @@
|
|||
*/
|
||||
|
||||
require_once __DIR__ . '/TypeMapperInterface.php';
|
||||
require_once __DIR__ . '/../Helpers/HtmlFieldPurify.php';
|
||||
|
||||
class TextMapper implements TypeMapperInterface
|
||||
{
|
||||
use HtmlFieldPurify;
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
|
@ -54,7 +57,12 @@ class TextMapper implements TypeMapperInterface
|
|||
return;
|
||||
}
|
||||
|
||||
$container[$newName] = $bean->$name;
|
||||
$value = $bean->$name;
|
||||
if (is_string($value) ) {
|
||||
$value = html_entity_decode($value);
|
||||
}
|
||||
|
||||
$container[$newName] = $this->purify($bean, $name, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -68,15 +76,15 @@ class TextMapper implements TypeMapperInterface
|
|||
$newName = $alternativeName;
|
||||
}
|
||||
|
||||
$value = $container[$newName] ?? '';
|
||||
|
||||
$fieldDef = $bean->field_defs[$newName] ?? [];
|
||||
|
||||
$editor = $fieldDef['editor'] ?? '';
|
||||
$purifyHtml = $fieldDef['metadata']['purifyHtml'] ?? true;
|
||||
|
||||
if (empty($editor) || $editor !== 'html' || $purifyHtml === false || !is_string($container[$newName] ?? '')) {
|
||||
if (empty($editor) || $editor !== 'html' || !is_string($value)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$container[$newName] = purify_html(securexss($container[$newName] ?? ''));
|
||||
$container[$newName] = $this->purify($bean, $name, $value);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,5 +7,5 @@ function survey_url_display(Surveys $survey)
|
|||
global $sugar_config;
|
||||
$url = $sugar_config['site_url'] . "/index.php?entryPoint=survey&id=" . $survey->id;
|
||||
|
||||
return "<a href='$url'>$url</a>";
|
||||
return "<a href='$url' target='_blank'>$url</a>";
|
||||
}
|
||||
|
|
|
@ -891,9 +891,6 @@
|
|||
"tinymce/tinymce": {
|
||||
"version": "4.9.11"
|
||||
},
|
||||
"tuupola/slim-jwt-auth": {
|
||||
"version": "2.4.0"
|
||||
},
|
||||
"twig/twig": {
|
||||
"version": "v2.12.3"
|
||||
},
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue