diff --git a/CRM/Certificate/Entity/AbstractEntity.php b/CRM/Certificate/Entity/AbstractEntity.php
index 0388642..4660045 100644
--- a/CRM/Certificate/Entity/AbstractEntity.php
+++ b/CRM/Certificate/Entity/AbstractEntity.php
@@ -101,21 +101,28 @@ public function getCertificateConfigurationById($certificateId) {
* Id of the entity to get a configured certificate for
* @param int $contactId
* Id of the contact the entity belongs to
+ * @param bool $multiple
+ * If multiple certificate should be returned
*
- * @return \CRM_Certificate_BAO_CompuCertificate|bool
+ * @return \CRM_Certificate_BAO_CompuCertificate|array|bool
*/
- public function getCertificateConfiguration($entityId, $contactId) {
+ public function getCertificateConfiguration($entityId, $contactId, $multiple = FALSE) {
try {
$certificateBAO = new CRM_Certificate_BAO_CompuCertificate();
$this->addEntityConditionals($certificateBAO, $entityId, $contactId);
$certificateBAO->whereDateIsValid();
$certificateBAO->orderBy(CRM_Certificate_DAO_CompuCertificate::$_tableName . '.id Desc');
$certificateBAO->selectAdd(CRM_Certificate_DAO_CompuCertificate::$_tableName . '.id');
- $certificateBAO->find(TRUE);
+ $certificateBAO->find();
- if (!empty($certificateBAO->id) && $this->isCertificateValidForAnEntity($certificateBAO, $contactId)) {
- return $certificateBAO;
+ $results = [];
+ while ($certificateBAO->fetch()) {
+ if (!empty($certificateBAO->id) && $this->isCertificateValidForAnEntity($certificateBAO, $contactId)) {
+ $results[] = clone $certificateBAO;
+ }
}
+
+ return $multiple ? $results : ($results[0] ?? FALSE);
}
catch (\Exception $e) {
}
diff --git a/CRM/Certificate/Entity/Membership.php b/CRM/Certificate/Entity/Membership.php
index 97093ff..4a3ad73 100644
--- a/CRM/Certificate/Entity/Membership.php
+++ b/CRM/Certificate/Entity/Membership.php
@@ -169,6 +169,7 @@ public function formatConfiguredCertificatesForContact(array $configuredCertific
'start_date' => $configuredCertificate['start_date'],
'linked_to' => $membership['membership_name'],
'download_link' => $this->getCertificateDownloadUrl($membership['id'], $contactId, TRUE),
+ 'configuration_id' => $configuredCertificate['certificate_id'],
];
array_push($certificates, $certificate);
});
diff --git a/CRM/Certificate/Hook/PageRun/EventPageTab.php b/CRM/Certificate/Hook/PageRun/EventPageTab.php
index b680464..d7f5175 100644
--- a/CRM/Certificate/Hook/PageRun/EventPageTab.php
+++ b/CRM/Certificate/Hook/PageRun/EventPageTab.php
@@ -32,7 +32,7 @@ public function addDownloadButton() {
$downloadUrl = htmlspecialchars_decode(CRM_Utils_System::url('civicrm/certificates/event', $query));
CRM_Core_Resources::singleton()
->addScriptFile("uk.co.compucorp.certificate", "./js/eventDownloadButton.js");
- Civi::resources()->addVars(E::SHORT_NAME, ['download_url' => $downloadUrl]);
+ Civi::resources()->addVars(E::SHORT_NAME, ['download_url' => [$downloadUrl]]);
}
}
diff --git a/CRM/Certificate/Hook/PageRun/MemberPageTab.php b/CRM/Certificate/Hook/PageRun/MemberPageTab.php
index 95555a4..b52d1b2 100644
--- a/CRM/Certificate/Hook/PageRun/MemberPageTab.php
+++ b/CRM/Certificate/Hook/PageRun/MemberPageTab.php
@@ -21,12 +21,14 @@ public function addDownloadButton() {
$certificateType = CRM_Certificate_Enum_CertificateType::MEMBERSHIPS;
$entity = CRM_Certificate_Entity_EntityFactory::create($certificateType);
- $configuredCertificate = $entity->getCertificateConfiguration($id, $contactId);
+ $configuredCertificates = $entity->getCertificateConfiguration($id, $contactId, TRUE);
- if ($configuredCertificate) {
- $downloadUrl = $entity->getCertificateDownloadUrl($id, $contactId);
+ if (!empty($configuredCertificates)) {
+ foreach ($configuredCertificates as $certificate) {
+ $downloadUrls[] = sprintf("%s&ccid=%s", $entity->getCertificateDownloadUrl($id, $contactId), $certificate->id);
+ }
- Civi::resources()->addVars(E::SHORT_NAME, ['download_url' => $downloadUrl]);
+ Civi::resources()->addVars(E::SHORT_NAME, ['download_url' => $downloadUrls]);
Civi::resources()->addScriptFile(E::LONG_NAME, "/js/compucertificate.js", 0);
Civi::resources()->addScriptFile(E::LONG_NAME, "./js/memberDownloadButton.js", 1);
}
diff --git a/CRM/Certificate/Page/CertificateDownload.php b/CRM/Certificate/Page/CertificateDownload.php
index 303712d..51ac349 100755
--- a/CRM/Certificate/Page/CertificateDownload.php
+++ b/CRM/Certificate/Page/CertificateDownload.php
@@ -44,7 +44,8 @@ public static function downloadMembershipCertificate() {
*/
private static function downloadCertificate($contactId, $entityId, $certificateType) {
try {
- $certificate = self::checkIfCertificateAvailable($contactId, $entityId, $certificateType);
+ $configurationId = CRM_Utils_Request::retrieve('ccid', 'Positive');
+ $certificate = self::checkIfCertificateAvailable($contactId, $entityId, $certificateType, $configurationId);
}
catch (CRM_Core_Exception $e) {
CRM_Core_Session::setStatus($e->getMessage(), 'Error', 'error');
@@ -67,22 +68,34 @@ private static function downloadCertificate($contactId, $entityId, $certificateT
* @param int $contactId
* @param int $entityId
* @param int $certificateType
+ * @param int|bool $certificateId
*
* @return \CRM_Certificate_BAO_CompuCertificate
*
* @throws \CRM_Core_exception
*/
- public static function checkIfCertificateAvailable($contactId, $entityId, $certificateType) {
+ public static function checkIfCertificateAvailable($contactId, $entityId, $certificateType, $certificateId = NULL) {
if (empty($contactId) || empty($entityId)) {
throw new CRM_Core_Exception('You do not have permission to access this contact.', 403);
}
- $certificate = self::validateCertificate($contactId, $entityId, $certificateType);
- $accessChecker = new CRM_Certificate_Service_CertificateAccessChecker($contactId, $certificate);
- $hasAccess = $accessChecker->check();
+ $certificates = self::validateCertificate($contactId, $entityId, $certificateType);
+ $certificateWithAccess = [];
+ foreach ($certificates as $certificate) {
+ if (!empty($certificateId) && $certificate->id != $certificateId) {
+ continue;
+ }
- if ($hasAccess) {
- return $certificate;
+ $accessChecker = new CRM_Certificate_Service_CertificateAccessChecker($contactId, $certificate);
+ $hasAccess = $accessChecker->check();
+
+ if ($hasAccess) {
+ $certificateWithAccess[$certificate->id] = $certificate;
+ }
+ }
+
+ if (!empty($certificateWithAccess)) {
+ return end($certificateWithAccess);
}
throw new CRM_Core_Exception('You do not have permission to access this contact.', 403);
@@ -96,19 +109,19 @@ public static function checkIfCertificateAvailable($contactId, $entityId, $certi
* @param $entityId
* @param int $certificateType
*
- * @return \CRM_Certificate_BAO_CompuCertificate
+ * @return \CRM_Certificate_BAO_CompuCertificate[]
*
* @throws CRM_Core_Exception;
*/
private static function validateCertificate(int $contactId, int $entityId, int $certificateType) {
$entity = CRM_Certificate_Entity_EntityFactory::create($certificateType);
- $configuredCertificate = $entity->getCertificateConfiguration($entityId, $contactId);
+ $configuredCertificates = $entity->getCertificateConfiguration($entityId, $contactId, TRUE);
- if (!$configuredCertificate) {
+ if (empty($configuredCertificates)) {
throw new CRM_Core_Exception(ts('Certificate not available for contact'));
}
- return $configuredCertificate;
+ return $configuredCertificates;
}
}
diff --git a/CRM/Certificate/Service/Certificate.php b/CRM/Certificate/Service/Certificate.php
index 928479b..ec1554e 100644
--- a/CRM/Certificate/Service/Certificate.php
+++ b/CRM/Certificate/Service/Certificate.php
@@ -17,7 +17,8 @@ class CRM_Certificate_Service_Certificate {
public function store($values) {
$result = NULL;
- if ($this->configurationExist($values)) {
+ $duplicateSupportEntity = [CRM_Certificate_Enum_CertificateType::MEMBERSHIPS];
+ if (!in_array($values['type'], $duplicateSupportEntity) && $this->configurationExist($values)) {
throw new CRM_Certificate_Exception_ConfigurationExistException();
}
diff --git a/js/compucertificate.js b/js/compucertificate.js
index 34c451d..0377612 100644
--- a/js/compucertificate.js
+++ b/js/compucertificate.js
@@ -15,8 +15,15 @@ window.downloadLink = function () {
`
Print Certificate`
);
+
+ let url = '';
+ let count = 0;
+ CRM.vars.certificate.download_url.forEach(downloadUrl => {
+ url += " setTimeout(function(){ window.open('" + downloadUrl + "'); }, " + (500 * count++) + "); ";
+ });
+
btn.setAttribute('type', 'button');
- btn.setAttribute('onclick', "window.open('" + CRM.vars.certificate.download_url + "')");
+ btn.setAttribute('onclick', url);
btn.setAttribute('target', '_blank');
btn.classList.add('ui-button', 'ui-corner-all', 'ui-widget');
btn.style.marginRight = '5px';
diff --git a/tests/phpunit/CRM/Certificate/Service/CertificateMembershipTest.php b/tests/phpunit/CRM/Certificate/Service/CertificateMembershipTest.php
index 41e5006..64e4434 100644
--- a/tests/phpunit/CRM/Certificate/Service/CertificateMembershipTest.php
+++ b/tests/phpunit/CRM/Certificate/Service/CertificateMembershipTest.php
@@ -58,8 +58,7 @@ public function testCreateEventCertificateConfigurationForEmptyStatusAndType() {
* Test that duplicate certifiacte configuration
* cannot be created for the same entity.
*/
- public function testExceptionThrownForDuplicateCertificateMembershipConfiguration() {
- $this->expectException(CRM_Certificate_Exception_ConfigurationExistException::class);
+ public function testExceptionNotThrownForDuplicateCertificateMembershipConfiguration() {
$statuses = CRM_Certificate_Test_Fabricator_MembershipStatus::fabricate()['id'];
$types = CRM_Certificate_Test_Fabricator_MembershipType::fabricate()['id'];
@@ -72,8 +71,11 @@ public function testExceptionThrownForDuplicateCertificateMembershipConfiguratio
'end_date' => date('Y-m-d'),
];
- $this->createCertificate($values);
- $this->createCertificate($values);
+ $cert1 = $this->createCertificate($values);
+ $cert2 = $this->createCertificate($values);
+
+ $this->assertNotEmpty($cert1);
+ $this->assertNotEmpty($cert2);
}
/**