Verified Commit 1035212e authored by Kevin Cristiano's avatar Kevin Cristiano 🌎
Browse files

civicrm release-5.52.1

parent 94344a93
......@@ -2,7 +2,7 @@
/**
* Plugin Name: CiviCRM
* Description: CiviCRM - Growing and Sustaining Relationships
* Version: 5.52.0
* Version: 5.52.1
* Requires at least: 4.9
* Requires PHP: 7.2
* Author: CiviCRM LLC
......@@ -36,7 +36,7 @@ if (!defined('ABSPATH')) {
}
// Set version here: changing it forces Javascript and CSS to reload.
define('CIVICRM_PLUGIN_VERSION', '5.52.0');
define('CIVICRM_PLUGIN_VERSION', '5.52.1');
// Store reference to this file.
if (!defined('CIVICRM_PLUGIN_FILE')) {
......
......@@ -58,8 +58,9 @@ class CRM_Api4_Page_AJAX extends CRM_Core_Page {
CRM_Utils_System::civiExit();
}
try {
// Call multiple
// Two call formats. Which one was used? Note: CRM_Api4_Permission::check() and CRM_Api4_Page_AJAX::run() should have matching conditionals.
if (empty($this->urlPath[3])) {
// Received multi-call format
$calls = CRM_Utils_Request::retrieve('calls', 'String', CRM_Core_DAO::$_nullObject, TRUE, NULL, 'POST');
$calls = json_decode($calls, TRUE);
$response = [];
......@@ -67,8 +68,8 @@ class CRM_Api4_Page_AJAX extends CRM_Core_Page {
$response[$index] = call_user_func_array([$this, 'execute'], $call);
}
}
// Call single
else {
// Received single-call format
$entity = $this->urlPath[3];
$action = $this->urlPath[4];
$params = CRM_Utils_Request::retrieve('params', 'String');
......
......@@ -22,17 +22,32 @@
class CRM_Api4_Permission {
public static function check() {
$config = CRM_Core_Config::singleton();
$urlPath = explode('/', $_GET[$config->userFrameworkURLVar]);
$permissions = [
$urlPath = explode('/', CRM_Utils_System::currentPath());
$defaultPermissions = [
['access CiviCRM', 'access AJAX API'],
];
// Two call formats. Which one was used? Note: CRM_Api4_Permission::check() and CRM_Api4_Page_AJAX::run() should have matching conditionals.
if (!empty($urlPath[3])) {
// Received single-call format
$entity = $urlPath[3];
$action = $urlPath[4];
$permissions = $defaultPermissions;
CRM_Utils_Hook::alterApiRoutePermissions($permissions, $entity, $action);
return CRM_Core_Permission::check($permissions);
}
else {
// Received multi-call format
$calls = CRM_Utils_Request::retrieve('calls', 'String', CRM_Core_DAO::$_nullObject, TRUE, NULL, 'POST');
$calls = json_decode($calls, TRUE);
foreach ($calls as $call) {
$permissions = $defaultPermissions;
CRM_Utils_Hook::alterApiRoutePermissions($permissions, $call[0], $call[1]);
if (!CRM_Core_Permission::check($permissions)) {
return FALSE;
}
}
return TRUE;
}
return CRM_Core_Permission::check($permissions);
}
}
......@@ -417,7 +417,7 @@ class CRM_Contribute_Import_Parser_Contribution extends CRM_Import_Parser {
$error = $this->checkContactDuplicate($paramValues);
if (CRM_Core_Error::isAPIError($error, CRM_Core_ERROR::DUPLICATE_CONTACT)) {
$matchedIDs = explode(',', $error['error_message']['params'][0]);
$matchedIDs = (array) $error['error_message']['params'];
if (count($matchedIDs) > 1) {
throw new CRM_Core_Exception('Multiple matching contact records detected for this row. The contribution was not imported', CRM_Import_Parser::ERROR);
}
......@@ -776,7 +776,7 @@ class CRM_Contribute_Import_Parser_Contribution extends CRM_Import_Parser {
$error = $this->checkContactDuplicate($params);
if (isset($error['error_message']['params'][0])) {
$matchedIDs = explode(',', $error['error_message']['params'][0]);
$matchedIDs = (array) $error['error_message']['params'];
// check if only one contact is found
if (count($matchedIDs) > 1) {
......
......@@ -236,7 +236,7 @@ class CRM_Event_Import_Parser_Participant extends CRM_Import_Parser {
$error = $this->checkContactDuplicate($formatValues);
if (CRM_Core_Error::isAPIError($error, CRM_Core_ERROR::DUPLICATE_CONTACT)) {
$matchedIDs = explode(',', $error['error_message']['params'][0]);
$matchedIDs = (array) $error['error_message']['params'];
if (count($matchedIDs) >= 1) {
foreach ($matchedIDs as $contactId) {
$formatted['contact_id'] = $contactId;
......
......@@ -215,7 +215,7 @@ class CRM_Member_Import_Parser_Membership extends CRM_Import_Parser {
$error = $this->checkContactDuplicate($formatValues);
if (CRM_Core_Error::isAPIError($error, CRM_Core_ERROR::DUPLICATE_CONTACT)) {
$matchedIDs = explode(',', $error['error_message']['params'][0]);
$matchedIDs = (array) $error['error_message']['params'];
if (count($matchedIDs) > 1) {
throw new CRM_Core_Exception('Multiple matching contact records detected for this row. The membership was not imported', CRM_Import_Parser::ERROR);
}
......
......@@ -48,7 +48,7 @@ function _civicrm_api3_deprecated_duplicate_formatted_contact($params) {
'is_error' => 1,
'error_message' => [
'code' => CRM_Core_Error::DUPLICATE_CONTACT,
'params' => $contact->id,
'params' => [$contact->id],
'level' => 'Fatal',
'message' => "Found matching contacts: $contact->id",
],
......
......@@ -265,7 +265,7 @@ class FormattingUtil {
}
// Fallback for option lists that exist in the api but not the BAO
if (!isset($options) || $options === FALSE) {
$options = civicrm_api4($field['entity'], 'getFields', ['action' => $action, 'loadOptions' => ['id', $valueType], 'where' => [['name', '=', $field['name']]]])[0]['options'] ?? NULL;
$options = civicrm_api4($field['entity'], 'getFields', ['checkPermissions' => FALSE, 'action' => $action, 'loadOptions' => ['id', $valueType], 'where' => [['name', '=', $field['name']]]])[0]['options'] ?? NULL;
$options = $options ? array_column($options, $valueType, 'id') : $options;
}
if (is_array($options)) {
......
......@@ -759,7 +759,7 @@
restrict: 'EA',
scope: {
crmUiTabSet: '@',
tabSetOptions: '@'
tabSetOptions: '<'
},
templateUrl: '~/crmUi/tabset.html',
transclude: true,
......
<?php
/** @deprecated */
function civicrmVersion( ) {
return array( 'version' => '5.52.0',
return array( 'version' => '5.52.1',
'cms' => 'Wordpress',
'revision' => '' );
}
......
......@@ -59,6 +59,7 @@
"symfony/filesystem": "~4.4",
"symfony/process": "~4.4",
"symfony/var-dumper": "~3.0 || ~4.4 || ~5.1",
"symfony/service-contracts": "~2.2",
"psr/log": "~1.0 || ~2.0 || ~3.0",
"symfony/finder": "~4.4",
"tecnickcom/tcpdf" : "6.4.*",
......@@ -94,7 +95,8 @@
"ezyang/htmlpurifier": "^4.13",
"phpoffice/phpspreadsheet": "^1.18",
"symfony/polyfill-php73": "^1.23",
"html2text/html2text": "^4.3.1"
"html2text/html2text": "^4.3.1",
"psr/container": "~1.0"
},
"scripts": {
"post-install-cmd": [
......
......@@ -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": "9808720dbc97471b1d5cc71fdc6b6897",
"content-hash": "0fc116de60e32605258ea574d897653b",
"packages": [
{
"name": "adrienrn/php-mimetyper",
......@@ -3055,22 +3055,27 @@
},
{
"name": "psr/container",
"version": "1.1.1",
"version": "1.0.0",
"source": {
"type": "git",
"url": "https://github.com/php-fig/container.git",
"reference": "8622567409010282b7aeebe4bb841fe98b58dcaf"
"reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-fig/container/zipball/8622567409010282b7aeebe4bb841fe98b58dcaf",
"reference": "8622567409010282b7aeebe4bb841fe98b58dcaf",
"url": "https://api.github.com/repos/php-fig/container/zipball/b7ce3b176482dbbc1245ebf52b181af44c2cf55f",
"reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f",
"shasum": ""
},
"require": {
"php": ">=7.2.0"
"php": ">=5.3.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0.x-dev"
}
},
"autoload": {
"psr-4": {
"Psr\\Container\\": "src/"
......@@ -3083,7 +3088,7 @@
"authors": [
{
"name": "PHP-FIG",
"homepage": "https://www.php-fig.org/"
"homepage": "http://www.php-fig.org/"
}
],
"description": "Common Container Interface (PHP FIG PSR-11)",
......@@ -3097,9 +3102,9 @@
],
"support": {
"issues": "https://github.com/php-fig/container/issues",
"source": "https://github.com/php-fig/container/tree/1.1.1"
"source": "https://github.com/php-fig/container/tree/master"
},
"time": "2021-03-05T17:36:06+00:00"
"time": "2017-02-14T16:28:37+00:00"
},
{
"name": "psr/http-client",
......@@ -3736,73 +3741,6 @@
],
"time": "2022-06-22T15:01:38+00:00"
},
{
"name": "symfony/deprecation-contracts",
"version": "v2.5.2",
"source": {
"type": "git",
"url": "https://github.com/symfony/deprecation-contracts.git",
"reference": "e8b495ea28c1d97b5e0c121748d6f9b53d075c66"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/e8b495ea28c1d97b5e0c121748d6f9b53d075c66",
"reference": "e8b495ea28c1d97b5e0c121748d6f9b53d075c66",
"shasum": ""
},
"require": {
"php": ">=7.1"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "2.5-dev"
},
"thanks": {
"name": "symfony/contracts",
"url": "https://github.com/symfony/contracts"
}
},
"autoload": {
"files": [
"function.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Nicolas Grekas",
"email": "p@tchwork.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "A generic function and convention to trigger deprecation notices",
"homepage": "https://symfony.com",
"support": {
"source": "https://github.com/symfony/deprecation-contracts/tree/v2.5.2"
},
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2022-01-02T09:53:40+00:00"
},
{
"name": "symfony/event-dispatcher",
"version": "v4.4.42",
......@@ -4884,25 +4822,21 @@
},
{
"name": "symfony/service-contracts",
"version": "v2.5.2",
"version": "v2.2.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/service-contracts.git",
"reference": "4b426aac47d6427cc1a1d0f7e2ac724627f5966c"
"reference": "d15da7ba4957ffb8f1747218be9e1a121fd298a1"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/service-contracts/zipball/4b426aac47d6427cc1a1d0f7e2ac724627f5966c",
"reference": "4b426aac47d6427cc1a1d0f7e2ac724627f5966c",
"url": "https://api.github.com/repos/symfony/service-contracts/zipball/d15da7ba4957ffb8f1747218be9e1a121fd298a1",
"reference": "d15da7ba4957ffb8f1747218be9e1a121fd298a1",
"shasum": ""
},
"require": {
"php": ">=7.2.5",
"psr/container": "^1.1",
"symfony/deprecation-contracts": "^2.1|^3"
},
"conflict": {
"ext-psr": "<1.1|>=2"
"psr/container": "^1.0"
},
"suggest": {
"symfony/service-implementation": ""
......@@ -4910,7 +4844,7 @@
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "2.5-dev"
"dev-master": "2.2-dev"
},
"thanks": {
"name": "symfony/contracts",
......@@ -4947,7 +4881,7 @@
"standards"
],
"support": {
"source": "https://github.com/symfony/service-contracts/tree/v2.5.2"
"source": "https://github.com/symfony/service-contracts/tree/master"
},
"funding": [
{
......@@ -4963,7 +4897,7 @@
"type": "tidelift"
}
],
"time": "2022-05-30T19:17:29+00:00"
"time": "2020-09-07T11:33:47+00:00"
},
{
"name": "symfony/var-dumper",
......
......@@ -13,7 +13,7 @@
<url desc="Licensing">http://www.gnu.org/licenses/agpl-3.0.html</url>
</urls>
<releaseDate>2020-01-09</releaseDate>
<version>5.52.0</version>
<version>5.52.1</version>
<develStage>beta</develStage>
<compatibility>
<ver>5.52</ver>
......
......@@ -103,7 +103,7 @@ abstract class AbstractProcessor extends \Civi\Api4\Generic\AbstractAction {
$data = ['fields' => $result[$id]];
foreach ($entity['joins'] ?? [] as $joinEntity => $join) {
$data['joins'][$joinEntity] = (array) $api4($joinEntity, 'get', [
'where' => self::getJoinWhereClause($entity['type'], $joinEntity, $id),
'where' => self::getJoinWhereClause($this->_formDataModel, $entity['name'], $joinEntity, $id),
'limit' => !empty($join['af-repeat']) ? $join['max'] ?? 0 : 1,
'select' => array_keys($join['fields']),
'orderBy' => self::getEntityField($joinEntity, 'is_primary') ? ['is_primary' => 'DESC'] : [],
......@@ -139,22 +139,32 @@ abstract class AbstractProcessor extends \Civi\Api4\Generic\AbstractAction {
abstract protected function processForm();
/**
* @param $mainEntityName
* @param $joinEntityName
* @param $mainEntityId
* @param \Civi\Afform\FormDataModel $formDataModel
* @param string $mainEntityName
* @param string $joinEntityType
* @param int|string $mainEntityId
* @return array
* @throws \API_Exception
*/
protected static function getJoinWhereClause($mainEntityName, $joinEntityName, $mainEntityId) {
protected static function getJoinWhereClause(FormDataModel $formDataModel, string $mainEntityName, string $joinEntityType, $mainEntityId) {
$entity = $formDataModel->getEntity($mainEntityName);
$mainEntityType = $entity['type'];
$params = [];
if (self::getEntityField($joinEntityName, 'entity_id')) {
// Add data as clauses e.g. `is_primary: true`
foreach ($entity['joins'][$joinEntityType]['data'] ?? [] as $key => $val) {
$params[] = [$key, '=', $val];
}
// Figure out the FK field between the join entity and the main entity
if (self::getEntityField($joinEntityType, 'entity_id')) {
$params[] = ['entity_id', '=', $mainEntityId];
if (self::getEntityField($joinEntityName, 'entity_table')) {
$params[] = ['entity_table', '=', CoreUtil::getTableName($mainEntityName)];
if (self::getEntityField($joinEntityType, 'entity_table')) {
$params[] = ['entity_table', '=', CoreUtil::getTableName($mainEntityType)];
}
}
else {
$mainEntityField = \CRM_Core_DAO_AllCoreTables::convertEntityNameToLower($mainEntityName) . '_id';
$mainEntityField = \CRM_Core_DAO_AllCoreTables::convertEntityNameToLower($mainEntityType) . '_id';
$params[] = [$mainEntityField, '=', $mainEntityId];
}
return $params;
......
......@@ -244,7 +244,7 @@ class Submit extends AbstractProcessor {
$result = civicrm_api4($joinEntityName, 'replace', [
// Disable permission checks because the main entity has already been vetted
'checkPermissions' => FALSE,
'where' => self::getJoinWhereClause($event->getEntityType(), $joinEntityName, $entityId),
'where' => self::getJoinWhereClause($event->getFormDataModel(), $event->getEntityName(), $joinEntityName, $entityId),
'records' => $values,
], ['id']);
$indexedResult = array_combine(array_keys($values), (array) $result);
......@@ -256,7 +256,7 @@ class Submit extends AbstractProcessor {
civicrm_api4($joinEntityName, 'delete', [
// Disable permission checks because the main entity has already been vetted
'checkPermissions' => FALSE,
'where' => self::getJoinWhereClause($event->getEntityType(), $joinEntityName, $entityId),
'where' => self::getJoinWhereClause($event->getFormDataModel(), $event->getEntityName(), $joinEntityName, $entityId),
]);
}
catch (\API_Exception $e) {
......
......@@ -13,7 +13,7 @@
<url desc="Licensing">http://www.gnu.org/licenses/agpl-3.0.html</url>
</urls>
<releaseDate>2020-01-09</releaseDate>
<version>5.52.0</version>
<version>5.52.1</version>
<develStage>beta</develStage>
<compatibility>
<ver>5.52</ver>
......
......@@ -13,7 +13,7 @@
<url desc="Licensing">http://www.gnu.org/licenses/agpl-3.0.html</url>
</urls>
<releaseDate>2020-01-09</releaseDate>
<version>5.52.0</version>
<version>5.52.1</version>
<develStage>alpha</develStage>
<compatibility>
<ver>5.52</ver>
......
......@@ -12,7 +12,7 @@
<url desc="Licensing">http://www.gnu.org/licenses/agpl-3.0.html</url>
</urls>
<releaseDate>2020-01-09</releaseDate>
<version>5.52.0</version>
<version>5.52.1</version>
<tags>
<tag>mgmt:hidden</tag>
</tags>
......
......@@ -15,7 +15,7 @@
<url desc="Licensing">http://www.gnu.org/licenses/agpl-3.0.html</url>
</urls>
<releaseDate>2021-02-11</releaseDate>
<version>5.52.0</version>
<version>5.52.1</version>
<develStage>stable</develStage>
<compatibility>
<ver>5.52</ver>
......
......@@ -15,7 +15,7 @@
<url desc="Licensing">http://www.gnu.org/licenses/agpl-3.0.html</url>
</urls>
<releaseDate>2022-01-02</releaseDate>
<version>5.52.0</version>
<version>5.52.1</version>
<develStage>alpha</develStage>
<compatibility>
<ver>5.52</ver>
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment