From 3578246758d9873f977932aeec9edf4fee4db160 Mon Sep 17 00:00:00 2001 From: Kevin Cristiano <kcristiano@kcristiano.com> Date: Thu, 6 Apr 2023 07:28:57 -0400 Subject: [PATCH] civicrm release-5.60.0 --- civicrm.php | 4 +- civicrm/CRM/ACL/BAO/ACL.php | 1 + civicrm/CRM/ACL/BAO/ACLEntityRole.php | 2 + civicrm/CRM/ACL/Form/ACL.php | 2 +- civicrm/CRM/Activity/BAO/Activity.php | 1 + .../CRM/Activity/Import/Form/DataSource.php | 11 - civicrm/CRM/Activity/Selector/Search.php | 14 +- civicrm/CRM/Admin/Form/OptionGroup.php | 2 +- civicrm/CRM/Admin/Form/Options.php | 2 +- civicrm/CRM/Admin/Form/PaymentProcessor.php | 3 +- .../CRM/Admin/Form/Preferences/Mailing.php | 1 + civicrm/CRM/Admin/Form/ScheduleReminders.php | 18 +- civicrm/CRM/Admin/Form/Setting/UF.php | 49 +- civicrm/CRM/Badge/BAO/Layout.php | 1 + civicrm/CRM/Badge/Form/Layout.php | 2 +- civicrm/CRM/Batch/BAO/EntityBatch.php | 1 + civicrm/CRM/Campaign/Form/Survey/Main.php | 2 +- civicrm/CRM/Campaign/Form/SurveyType.php | 2 +- civicrm/CRM/Campaign/Selector/Search.php | 2 +- civicrm/CRM/Case/BAO/Case.php | 4 +- civicrm/CRM/Case/BAO/CaseType.php | 1 + civicrm/CRM/Contact/BAO/Contact.php | 35 +- civicrm/CRM/Contact/BAO/Contact/Location.php | 38 - civicrm/CRM/Contact/BAO/GroupContact.php | 3 +- civicrm/CRM/Contact/DAO/Relationship.php | 3 +- .../CRM/Contact/DAO/SubscriptionHistory.php | 7 +- civicrm/CRM/Contact/Form/DedupeRules.php | 23 +- civicrm/CRM/Contact/Form/Task/Label.php | 3 + civicrm/CRM/Contact/Import/Form/Preview.php | 36 +- civicrm/CRM/Contact/Import/Parser/Contact.php | 40 +- civicrm/CRM/Contact/Page/AJAX.php | 2 +- civicrm/CRM/Contact/Page/Inline/Email.php | 2 +- civicrm/CRM/Contact/Selector.php | 41 +- civicrm/CRM/Contribute/BAO/Contribution.php | 15 +- .../CRM/Contribute/BAO/ContributionPage.php | 2 + .../CRM/Contribute/BAO/ContributionRecur.php | 2 + .../Contribute/Form/AbstractEditPayment.php | 29 - civicrm/CRM/Contribute/Form/Contribution.php | 17 + .../Contribute/Form/Contribution/Confirm.php | 43 +- .../Contribute/Form/Contribution/ThankYou.php | 2 - .../CRM/Contribute/Form/ContributionBase.php | 12 + civicrm/CRM/Contribute/Form/Search.php | 2 + civicrm/CRM/Contribute/Form/Task/PDF.php | 5 +- .../CRM/Contribute/Import/Form/DataSource.php | 4 - .../Contribute/Import/Parser/Contribution.php | 22 +- civicrm/CRM/Contribute/Page/UserDashboard.php | 155 ++-- civicrm/CRM/Core/BAO/ActionSchedule.php | 2 +- civicrm/CRM/Core/BAO/Address.php | 14 +- civicrm/CRM/Core/BAO/Block.php | 6 +- civicrm/CRM/Core/BAO/CustomField.php | 110 ++- civicrm/CRM/Core/BAO/CustomValueTable.php | 5 + civicrm/CRM/Core/BAO/Email.php | 1 + civicrm/CRM/Core/BAO/IM.php | 1 + civicrm/CRM/Core/BAO/Location.php | 38 - civicrm/CRM/Core/BAO/Log.php | 4 +- civicrm/CRM/Core/BAO/OptionGroup.php | 12 +- civicrm/CRM/Core/BAO/Phone.php | 1 + civicrm/CRM/Core/BAO/SchemaHandler.php | 16 +- civicrm/CRM/Core/BAO/UFField.php | 3 + civicrm/CRM/Core/BAO/UFMatch.php | 134 ++- civicrm/CRM/Core/BAO/Website.php | 4 +- civicrm/CRM/Core/ClassLoader.php | 1 + civicrm/CRM/Core/Config.php | 6 +- civicrm/CRM/Core/DAO.php | 54 +- civicrm/CRM/Core/DAO/CustomField.php | 26 +- civicrm/CRM/Core/DAO/JobLog.php | 11 +- civicrm/CRM/Core/Error.php | 12 +- civicrm/CRM/Core/Form.php | 45 +- civicrm/CRM/Core/Form/Search.php | 4 +- civicrm/CRM/Core/InnoDBIndexer.php | 2 +- civicrm/CRM/Core/Lock.php | 28 - civicrm/CRM/Core/OptionGroup.php | 88 -- civicrm/CRM/Core/Payment/PayPalProIPN.php | 2 +- civicrm/CRM/Core/PseudoConstant.php | 4 + civicrm/CRM/Core/SelectValues.php | 5 + civicrm/CRM/Core/Session.php | 6 +- civicrm/CRM/Core/Smarty.php | 26 +- civicrm/CRM/Core/Smarty/plugins/block.ts.php | 4 +- .../Core/Smarty/plugins/function.crmURL.php | 50 + .../Smarty/plugins/modifier.mb_truncate.php | 2 +- .../Smarty/plugins/prefilter.htxtFilter.php | 36 + civicrm/CRM/Custom/Form/Field.php | 14 + civicrm/CRM/Custom/Form/Group.php | 2 +- civicrm/CRM/Custom/Import/Form/DataSource.php | 4 - civicrm/CRM/Dedupe/Merger.php | 86 +- civicrm/CRM/Event/ActionMapping.php | 3 - civicrm/CRM/Event/BAO/Event.php | 1 + civicrm/CRM/Event/BAO/Participant.php | 2 +- civicrm/CRM/Event/Form/ManageEvent/Delete.php | 2 +- civicrm/CRM/Event/Form/Registration.php | 82 +- .../CRM/Event/Form/Registration/Confirm.php | 2 +- .../CRM/Event/Form/Registration/ThankYou.php | 1 + civicrm/CRM/Event/Import/Form/DataSource.php | 4 - .../CRM/Event/Import/Parser/Participant.php | 7 - civicrm/CRM/Event/Page/DashBoard.php | 1 + civicrm/CRM/Event/Page/EventInfo.php | 1 + civicrm/CRM/Event/Page/ManageEvent.php | 1 + civicrm/CRM/Import/DataSource/CSV.php | 2 +- civicrm/CRM/Import/DataSource/SQL.php | 7 +- civicrm/CRM/Import/Form/DataSource.php | 8 +- civicrm/CRM/Mailing/BAO/Mailing.php | 3 +- civicrm/CRM/Mailing/BAO/MailingAB.php | 1 + civicrm/CRM/Mailing/BAO/MailingJob.php | 1 + civicrm/CRM/Mailing/Form/Approve.php | 2 +- civicrm/CRM/Mailing/Form/Browse.php | 2 +- civicrm/CRM/Mailing/Info.php | 16 +- civicrm/CRM/Mailing/Page/Browse.php | 2 +- civicrm/CRM/Member/BAO/MembershipBlock.php | 2 + civicrm/CRM/Member/BAO/MembershipPayment.php | 1 + civicrm/CRM/Member/BAO/MembershipStatus.php | 1 + civicrm/CRM/Member/BAO/MembershipType.php | 31 +- civicrm/CRM/Member/Form/MembershipBlock.php | 2 +- civicrm/CRM/Member/Form/MembershipStatus.php | 2 +- civicrm/CRM/Member/Form/MembershipType.php | 2 +- civicrm/CRM/Member/Import/Form/DataSource.php | 4 - .../CRM/Member/Import/Parser/Membership.php | 6 - civicrm/CRM/Pledge/BAO/Pledge.php | 6 - civicrm/CRM/Pledge/Page/UserDashboard.php | 25 +- civicrm/CRM/Report/Form/Contribute/Detail.php | 15 + .../CRM/Report/Form/Contribute/Summary.php | 15 + civicrm/CRM/Report/Form/Mailing/Summary.php | 6 +- .../CRM/Upgrade/Incremental/php/FiveSixty.php | 75 ++ .../Incremental/sql/5.60.alpha1.mysql.tpl | 1 + civicrm/CRM/Upgrade/Snapshot.php | 7 +- civicrm/CRM/Utils/Address/BatchUpdate.php | 7 +- civicrm/CRM/Utils/Array.php | 4 + civicrm/CRM/Utils/FakeObject.php | 7 +- civicrm/CRM/Utils/Mail/Incoming.php | 2 +- civicrm/CRM/Utils/Mail/Logger.php | 4 +- civicrm/CRM/Utils/REST.php | 3 +- civicrm/CRM/Utils/Request.php | 2 +- civicrm/CRM/Utils/SQL.php | 24 - civicrm/CRM/Utils/String.php | 12 +- civicrm/CRM/Utils/System.php | 17 +- civicrm/CRM/Utils/System/Backdrop.php | 80 ++ civicrm/CRM/Utils/System/Base.php | 171 ++-- civicrm/CRM/Utils/System/Drupal.php | 79 ++ civicrm/CRM/Utils/System/Drupal8.php | 46 + civicrm/CRM/Utils/System/DrupalBase.php | 74 +- civicrm/CRM/Utils/System/Joomla.php | 16 +- civicrm/CRM/Utils/System/Soap.php | 16 + civicrm/CRM/Utils/System/Standalone.php | 16 + civicrm/CRM/Utils/System/UnitTests.php | 16 + civicrm/CRM/Utils/System/WordPress.php | 50 +- civicrm/CRM/Utils/Token.php | 7 + civicrm/Civi/ActionSchedule/Mapping.php | 20 +- civicrm/Civi/Angular/Coder.php | 14 +- .../Api4/Action/Contact/GetDuplicates.php | 1 + civicrm/Civi/Api4/DedupeException.php | 2 +- civicrm/Civi/Api4/Generic/AbstractAction.php | 2 +- .../Civi/Api4/Generic/AbstractSaveAction.php | 2 +- .../Api4/Service/Schema/SchemaMapBuilder.php | 14 +- .../Api4/Service/Spec/CustomFieldSpec.php | 4 + .../Provider/IsCurrentFieldSpecProvider.php | 36 +- .../Civi/Api4/Service/Spec/RequestSpec.php | 2 +- .../Civi/Api4/Service/Spec/SpecFormatter.php | 29 +- .../Civi/Api4/Service/Spec/SpecGatherer.php | 6 +- civicrm/Civi/Api4/Utils/CoreUtil.php | 2 +- civicrm/Civi/Api4/Utils/ReflectionUtils.php | 52 ++ .../Civi/Schema/Traits/DataTypeSpecTrait.php | 2 +- civicrm/Civi/Test/Api3TestTrait.php | 10 +- civicrm/Civi/Token/TokenException.php | 5 + civicrm/ang/api4Explorer/Explorer.js | 3 + civicrm/api/v3/Contribution.php | 54 -- civicrm/api/v3/Event.php | 7 +- civicrm/api/v3/Generic/Getlist.php | 4 +- civicrm/api/v3/MembershipStatus.php | 11 +- civicrm/api/v3/OptionValue.php | 2 +- civicrm/api/v3/Profile.php | 15 +- civicrm/api/v3/utils.php | 19 - civicrm/civicrm-version.php | 2 +- civicrm/composer.json | 19 +- civicrm/composer.lock | 182 +--- civicrm/css/civicrm.css | 1 + .../afform/admin/CRM/AfformAdmin/Upgrader.php | 2 +- .../admin/CRM/AfformAdmin/Upgrader/Base.php | 397 -------- .../ext/afform/admin/afform_admin.civix.php | 106 +-- civicrm/ext/afform/admin/afform_admin.php | 47 - .../elements/afGuiContainer.component.js | 10 +- .../elements/afGuiField.component.js | 4 +- civicrm/ext/afform/admin/info.xml | 8 +- .../Api4/Action/Afform/AbstractProcessor.php | 10 +- .../core/Civi/Api4/Action/Afform/Submit.php | 8 +- .../AfformAutocompleteSubscriber.php | 11 +- civicrm/ext/afform/core/afform.civix.php | 20 - civicrm/ext/afform/core/afform.php | 11 - .../afform/core/ang/af/fields/EntityRef.html | 2 +- civicrm/ext/afform/core/info.xml | 8 +- civicrm/ext/afform/html/info.xml | 4 +- civicrm/ext/afform/mock/info.xml | 4 +- civicrm/ext/authx/authx.civix.php | 106 +-- civicrm/ext/authx/authx.php | 47 - civicrm/ext/authx/info.xml | 6 +- .../civicrm_admin_ui.civix.php | 106 +-- .../ext/civicrm_admin_ui/civicrm_admin_ui.php | 11 - civicrm/ext/civicrm_admin_ui/info.xml | 6 +- civicrm/ext/civigrant/civigrant.civix.php | 101 +- civicrm/ext/civigrant/civigrant.php | 11 - civicrm/ext/civigrant/info.xml | 7 +- .../templates/CRM/Grant/Form/Task/Delete.tpl | 2 +- .../Event/Subscriber/ImportSubscriber.php | 2 +- civicrm/ext/civiimport/civiimport.civix.php | 106 +-- civicrm/ext/civiimport/civiimport.php | 36 - civicrm/ext/civiimport/info.xml | 7 +- .../ext/ckeditor4/CRM/Ckeditor4/Upgrader.php | 2 +- .../ckeditor4/CRM/Ckeditor4/Upgrader/Base.php | 396 -------- civicrm/ext/ckeditor4/ckeditor4.civix.php | 106 +-- civicrm/ext/ckeditor4/ckeditor4.php | 47 - civicrm/ext/ckeditor4/info.xml | 8 +- .../ext/contributioncancelactions/info.xml | 4 +- civicrm/ext/elavon/info.xml | 4 +- civicrm/ext/eventcart/info.xml | 4 +- civicrm/ext/ewaysingle/info.xml | 4 +- .../ext/financialacls/financialacls.civix.php | 106 +-- civicrm/ext/financialacls/financialacls.php | 47 - civicrm/ext/financialacls/info.xml | 6 +- civicrm/ext/flexmailer/flexmailer.civix.php | 14 - civicrm/ext/flexmailer/info.xml | 6 +- .../flexmailer/src/Listener/BounceTracker.php | 3 +- civicrm/ext/greenwich/greenwich.civix.php | 14 - civicrm/ext/greenwich/info.xml | 6 +- .../CRM/Contact/Selector/Custom.php | 104 ++- civicrm/ext/legacycustomsearches/info.xml | 7 +- .../legacycustomsearches.civix.php | 106 +-- .../legacycustomsearches.php | 47 - .../Search/Custom/MultipleValuesCriteria.tpl | 2 +- civicrm/ext/message_admin/info.xml | 7 +- .../ext/message_admin/message_admin.civix.php | 14 - civicrm/ext/message_admin/message_admin.php | 11 - .../Action/OAuthClient/AuthorizationCode.php | 15 +- .../Civi/OAuth/OAuthLeagueFacade.php | 3 +- civicrm/ext/oauth-client/info.xml | 8 +- .../ext/oauth-client/oauth_client.civix.php | 30 - civicrm/ext/oauth-client/oauth_client.php | 11 - civicrm/ext/payflowpro/info.xml | 4 +- civicrm/ext/recaptcha/info.xml | 7 +- civicrm/ext/recaptcha/recaptcha.civix.php | 106 +-- civicrm/ext/recaptcha/recaptcha.php | 47 - .../ext/search_kit/CRM/Search/Upgrader.php | 2 +- .../search_kit/CRM/Search/Upgrader/Base.php | 7 - .../Action/SearchDisplay/GetSearchTasks.php | 18 +- .../SearchDisplayTasksSubscriber.php | 48 + civicrm/ext/search_kit/Civi/Search/Admin.php | 5 +- .../crmSearchAdminLinkGroup.html | 2 +- .../searchAdminTasksConfig.component.js | 58 ++ .../common/searchAdminTasksConfig.html | 26 + .../displays/searchAdminDisplayTable.html | 9 +- .../crmSearchAdmin/resultsTable/debug.html | 5 +- .../crmSearchAdminSearchListing.component.js | 2 +- civicrm/ext/search_kit/info.xml | 6 +- civicrm/ext/search_kit/search_kit.civix.php | 107 +-- civicrm/ext/sequentialcreditnotes/info.xml | 6 +- .../sequentialcreditnotes.civix.php | 106 +-- civicrm/js/Common.js | 3 + civicrm/mixin/smarty-v2@1/mixin.php | 13 +- civicrm/release-notes.md | 41 +- civicrm/release-notes/5.59.1.md | 41 - civicrm/release-notes/5.59.2.md | 39 - civicrm/release-notes/5.59.3.md | 38 - civicrm/release-notes/5.59.4.md | 43 - civicrm/release-notes/5.60.0.md | 696 ++++++++++++++ civicrm/settings/Localization.setting.php | 2 +- civicrm/settings/Mailing.setting.php | 14 + civicrm/sql/civicrm.mysql | 6 +- civicrm/sql/civicrm_data.mysql | 18 +- civicrm/sql/civicrm_generated.mysql | 2 +- .../CRM/Admin/Form/ParticipantStatusType.tpl | 2 +- .../CRM/Admin/Form/PaymentProcessor.tpl | 15 +- .../templates/CRM/Admin/Form/Setting/Smtp.tpl | 2 +- .../templates/CRM/Admin/Form/Setting/UF.tpl | 5 +- civicrm/templates/CRM/Batch/Form/Search.tpl | 2 +- .../CRM/Contact/Form/Inline/Address.tpl | 2 +- .../Form/Inline/CommunicationPreferences.tpl | 2 +- .../CRM/Contact/Form/Inline/ContactInfo.tpl | 2 +- .../CRM/Contact/Form/Inline/ContactName.tpl | 2 +- .../CRM/Contact/Form/Inline/CustomData.tpl | 2 +- .../CRM/Contact/Form/Inline/Demographics.tpl | 2 +- .../CRM/Contact/Form/Inline/Email.tpl | 2 +- .../templates/CRM/Contact/Form/Inline/IM.tpl | 2 +- .../CRM/Contact/Form/Inline/OpenID.tpl | 2 +- .../CRM/Contact/Form/Inline/Phone.tpl | 2 +- .../CRM/Contact/Form/Inline/Website.tpl | 2 +- .../Contact/Form/Task/AddToParentClass.tpl | 2 +- .../CRM/Contact/Form/Task/Delete.tpl | 2 +- .../CRM/Contact/Form/Task/PickProfile.tpl | 2 +- .../CRM/Contact/Form/Task/Unhold.tpl | 2 +- .../CRM/Contact/Import/Form/DataSource.tpl | 4 - .../CRM/Contact/Import/Form/Preview.tpl | 12 +- .../CRM/Contact/Page/Inline/Address.tpl | 3 +- .../CRM/Contact/Page/View/Delete.tpl | 2 +- .../templates/CRM/Contact/Page/View/Note.tpl | 2 +- .../CRM/Contribute/Form/AdditionalPayment.tpl | 4 +- .../CRM/Contribute/Form/Contribution.tpl | 2 +- .../CRM/Contribute/Form/Contribution/Main.tpl | 2 +- .../Form/Contribution/MembershipBlock.tpl | 2 +- .../Form/ContributionPage/AddProduct.tpl | 2 +- .../Form/ContributionPage/Delete.tpl | 2 +- .../Contribute/Form/SearchContribution.tpl | 2 +- .../CRM/Contribute/Page/UserDashboard.tpl | 93 +- .../CRM/Custom/Form/Edit/CustomField.tpl | 4 +- civicrm/templates/CRM/Custom/Form/Field.tpl | 11 +- .../Registration/AdditionalParticipant.tpl | 2 +- civicrm/templates/CRM/Event/Form/Search.tpl | 2 +- .../templates/CRM/Event/Form/SearchEvent.tpl | 2 +- .../templates/CRM/Event/Form/Task/Batch.tpl | 2 +- .../templates/CRM/Event/Form/Task/Print.tpl | 2 +- .../templates/CRM/Event/Form/Task/Result.tpl | 2 +- .../templates/CRM/Event/Page/iCalLinks.tpl | 2 +- civicrm/templates/CRM/Form/body.tpl | 2 +- .../templates/CRM/Mailing/Form/Approve.tpl | 2 +- .../templates/CRM/Mailing/Form/Component.tpl | 2 +- civicrm/templates/CRM/Mailing/MailingUI.hlp | 2 +- civicrm/templates/CRM/Member/Form/Search.tpl | 2 +- .../templates/CRM/Member/Form/Task/Result.tpl | 2 +- .../templates/CRM/Price/Form/DeleteSet.tpl | 4 +- civicrm/templates/CRM/Price/Form/Option.tpl | 2 +- .../templates/CRM/Profile/Form/Dynamic.tpl | 4 +- civicrm/templates/CRM/Profile/Form/Search.tpl | 2 +- civicrm/templates/CRM/SMS/Form/Group.hlp | 4 +- civicrm/templates/CRM/SMS/Form/Group.tpl | 2 +- civicrm/templates/CRM/SMS/Form/Schedule.tpl | 2 +- civicrm/templates/CRM/SMS/Form/Upload.tpl | 2 +- civicrm/templates/CRM/UF/Form/Preview.tpl | 2 +- civicrm/templates/CRM/common/formButtons.tpl | 2 +- civicrm/templates/CRM/common/success.tpl | 4 - civicrm/vendor/autoload.php | 2 +- .../vendor/cache/integration-tests/.gitignore | 3 - .../cache/integration-tests/.travis.yml | 45 - .../vendor/cache/integration-tests/LICENSE | 22 - .../vendor/cache/integration-tests/README.md | 58 -- .../cache/integration-tests/composer.json | 48 - .../cache/integration-tests/phpunit.xml.dist | 63 -- .../integration-tests/src/CachePoolTest.php | 874 ------------------ .../src/HierarchicalCachePoolTest.php | 150 --- .../integration-tests/src/SimpleCacheTest.php | 789 ---------------- .../src/TaggableCachePoolTest.php | 277 ------ .../.github/PULL_REQUEST_TEMPLATE.md | 5 - civicrm/vendor/cache/tag-interop/.gitignore | 2 - civicrm/vendor/cache/tag-interop/.travis.yml | 22 - civicrm/vendor/cache/tag-interop/Changelog.md | 9 - civicrm/vendor/cache/tag-interop/LICENSE | 22 - civicrm/vendor/cache/tag-interop/README.md | 25 - .../TaggableCacheItemInterface.php | 43 - .../TaggableCacheItemPoolInterface.php | 60 -- .../vendor/cache/tag-interop/composer.json | 39 - civicrm/vendor/composer/autoload_psr4.php | 3 - civicrm/vendor/composer/autoload_real.php | 14 +- civicrm/vendor/composer/autoload_static.php | 27 +- civicrm/vendor/composer/installed.json | 189 +--- civicrm/vendor/composer/installed.php | 39 +- civicrm/vendor/psr/cache/CHANGELOG.md | 16 - civicrm/vendor/psr/cache/LICENSE.txt | 19 - civicrm/vendor/psr/cache/README.md | 9 - civicrm/vendor/psr/cache/composer.json | 25 - .../vendor/psr/cache/src/CacheException.php | 10 - .../psr/cache/src/CacheItemInterface.php | 105 --- .../psr/cache/src/CacheItemPoolInterface.php | 138 --- .../cache/src/InvalidArgumentException.php | 13 - civicrm/xml/schema/Contact/Relationship.xml | 1 + .../schema/Contact/SubscriptionHistory.xml | 5 + civicrm/xml/schema/Core/CustomField.xml | 9 + civicrm/xml/schema/Core/JobLog.xml | 12 +- .../contribution_online_receipt_html.tpl | 2 +- .../contribution_online_receipt_text.tpl | 2 +- .../membership_online_receipt_html.tpl | 2 +- .../membership_online_receipt_text.tpl | 2 +- civicrm/xml/version.xml | 2 +- readme.txt | 2 +- 368 files changed, 2966 insertions(+), 7436 deletions(-) create mode 100644 civicrm/CRM/Core/Smarty/plugins/function.crmURL.php create mode 100644 civicrm/CRM/Core/Smarty/plugins/prefilter.htxtFilter.php create mode 100644 civicrm/CRM/Upgrade/Incremental/php/FiveSixty.php create mode 100644 civicrm/CRM/Upgrade/Incremental/sql/5.60.alpha1.mysql.tpl delete mode 100644 civicrm/ext/afform/admin/CRM/AfformAdmin/Upgrader/Base.php delete mode 100644 civicrm/ext/ckeditor4/CRM/Ckeditor4/Upgrader/Base.php delete mode 100644 civicrm/ext/search_kit/CRM/Search/Upgrader/Base.php create mode 100644 civicrm/ext/search_kit/Civi/Api4/Event/Subscriber/SearchDisplayTasksSubscriber.php create mode 100644 civicrm/ext/search_kit/ang/crmSearchAdmin/displays/common/searchAdminTasksConfig.component.js create mode 100644 civicrm/ext/search_kit/ang/crmSearchAdmin/displays/common/searchAdminTasksConfig.html delete mode 100644 civicrm/release-notes/5.59.1.md delete mode 100644 civicrm/release-notes/5.59.2.md delete mode 100644 civicrm/release-notes/5.59.3.md delete mode 100644 civicrm/release-notes/5.59.4.md create mode 100644 civicrm/release-notes/5.60.0.md delete mode 100755 civicrm/vendor/cache/integration-tests/.gitignore delete mode 100644 civicrm/vendor/cache/integration-tests/.travis.yml delete mode 100755 civicrm/vendor/cache/integration-tests/LICENSE delete mode 100644 civicrm/vendor/cache/integration-tests/README.md delete mode 100755 civicrm/vendor/cache/integration-tests/composer.json delete mode 100644 civicrm/vendor/cache/integration-tests/phpunit.xml.dist delete mode 100644 civicrm/vendor/cache/integration-tests/src/CachePoolTest.php delete mode 100644 civicrm/vendor/cache/integration-tests/src/HierarchicalCachePoolTest.php delete mode 100644 civicrm/vendor/cache/integration-tests/src/SimpleCacheTest.php delete mode 100644 civicrm/vendor/cache/integration-tests/src/TaggableCachePoolTest.php delete mode 100644 civicrm/vendor/cache/tag-interop/.github/PULL_REQUEST_TEMPLATE.md delete mode 100644 civicrm/vendor/cache/tag-interop/.gitignore delete mode 100644 civicrm/vendor/cache/tag-interop/.travis.yml delete mode 100644 civicrm/vendor/cache/tag-interop/Changelog.md delete mode 100644 civicrm/vendor/cache/tag-interop/LICENSE delete mode 100644 civicrm/vendor/cache/tag-interop/README.md delete mode 100644 civicrm/vendor/cache/tag-interop/TaggableCacheItemInterface.php delete mode 100644 civicrm/vendor/cache/tag-interop/TaggableCacheItemPoolInterface.php delete mode 100644 civicrm/vendor/cache/tag-interop/composer.json delete mode 100644 civicrm/vendor/psr/cache/CHANGELOG.md delete mode 100644 civicrm/vendor/psr/cache/LICENSE.txt delete mode 100644 civicrm/vendor/psr/cache/README.md delete mode 100644 civicrm/vendor/psr/cache/composer.json delete mode 100644 civicrm/vendor/psr/cache/src/CacheException.php delete mode 100644 civicrm/vendor/psr/cache/src/CacheItemInterface.php delete mode 100644 civicrm/vendor/psr/cache/src/CacheItemPoolInterface.php delete mode 100644 civicrm/vendor/psr/cache/src/InvalidArgumentException.php diff --git a/civicrm.php b/civicrm.php index 23e7cdd85d..7823dd0fb3 100644 --- a/civicrm.php +++ b/civicrm.php @@ -2,7 +2,7 @@ /** * Plugin Name: CiviCRM * Description: CiviCRM - Growing and Sustaining Relationships - * Version: 5.59.4 + * Version: 5.60.0 * Requires at least: 4.9 * Requires PHP: 7.3 * 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.59.4'); +define('CIVICRM_PLUGIN_VERSION', '5.60.0'); // Store reference to this file. if (!defined('CIVICRM_PLUGIN_FILE')) { diff --git a/civicrm/CRM/ACL/BAO/ACL.php b/civicrm/CRM/ACL/BAO/ACL.php index d1166f87ed..89067de60a 100644 --- a/civicrm/CRM/ACL/BAO/ACL.php +++ b/civicrm/CRM/ACL/BAO/ACL.php @@ -447,6 +447,7 @@ SELECT g.* * @deprecated */ public static function del($aclId) { + CRM_Core_Error::deprecatedFunctionWarning('deleteRecord'); self::deleteRecord(['id' => $aclId]); } diff --git a/civicrm/CRM/ACL/BAO/ACLEntityRole.php b/civicrm/CRM/ACL/BAO/ACLEntityRole.php index 1e6899d721..a892cf4ac7 100644 --- a/civicrm/CRM/ACL/BAO/ACLEntityRole.php +++ b/civicrm/CRM/ACL/BAO/ACLEntityRole.php @@ -39,6 +39,7 @@ class CRM_ACL_BAO_ACLEntityRole extends CRM_ACL_DAO_ACLEntityRole { * @return CRM_ACL_BAO_ACLEntityRole */ public static function create(&$params) { + CRM_Core_Error::deprecatedFunctionWarning('writeRecord'); return self::writeRecord($params); } @@ -82,6 +83,7 @@ class CRM_ACL_BAO_ACLEntityRole extends CRM_ACL_DAO_ACLEntityRole { * @deprecated */ public static function del($entityRoleId) { + CRM_Core_Error::deprecatedFunctionWarning('deleteRecord'); return self::deleteRecord(['id' => $entityRoleId]); } diff --git a/civicrm/CRM/ACL/Form/ACL.php b/civicrm/CRM/ACL/Form/ACL.php index bd82aedab0..61138975ce 100644 --- a/civicrm/CRM/ACL/Form/ACL.php +++ b/civicrm/CRM/ACL/Form/ACL.php @@ -247,7 +247,7 @@ class CRM_ACL_Form_ACL extends CRM_Admin_Form { CRM_Core_BAO_Cache::resetCaches(); if ($this->_action & CRM_Core_Action::DELETE) { - CRM_ACL_BAO_ACL::del($this->_id); + CRM_ACL_BAO_ACL::deleteRecord(['id' => $this->_id]); CRM_Core_Session::setStatus(ts('Selected ACL has been deleted.'), ts('Record Deleted'), 'success'); } else { diff --git a/civicrm/CRM/Activity/BAO/Activity.php b/civicrm/CRM/Activity/BAO/Activity.php index cb9d728e2d..69442988d8 100644 --- a/civicrm/CRM/Activity/BAO/Activity.php +++ b/civicrm/CRM/Activity/BAO/Activity.php @@ -1629,6 +1629,7 @@ WHERE activity.id IN ($activityIds)"; //CRM-4027 if ($targetContactID) { $activityParams['target_contact_id'][] = $targetContactID; + $activityParams['target_contact_id'] = array_unique($activityParams['target_contact_id'], SORT_NUMERIC); } // @todo - use api - remove lots of wrangling above. Remove deprecated fatal & let form layer // deal with any exceptions. diff --git a/civicrm/CRM/Activity/Import/Form/DataSource.php b/civicrm/CRM/Activity/Import/Form/DataSource.php index c965cd5fc4..cc27fcd6e9 100644 --- a/civicrm/CRM/Activity/Import/Form/DataSource.php +++ b/civicrm/CRM/Activity/Import/Form/DataSource.php @@ -20,10 +20,6 @@ */ class CRM_Activity_Import_Form_DataSource extends CRM_Import_Form_DataSource { - const PATH = 'civicrm/import/activity'; - - const IMPORT_ENTITY = 'Activity'; - /** * Get the name of the type to be stored in civicrm_user_job.type_id. * @@ -38,13 +34,6 @@ class CRM_Activity_Import_Form_DataSource extends CRM_Import_Form_DataSource { */ public $submitOnce = TRUE; - /** - * Build the form object. - */ - public function buildQuickForm() { - parent::buildQuickForm(); - } - /** * @return CRM_Activity_Import_Parser_Activity */ diff --git a/civicrm/CRM/Activity/Selector/Search.php b/civicrm/CRM/Activity/Selector/Search.php index 14215f6adc..3e73fc2855 100644 --- a/civicrm/CRM/Activity/Selector/Search.php +++ b/civicrm/CRM/Activity/Selector/Search.php @@ -205,7 +205,7 @@ class CRM_Activity_Selector_Search extends CRM_Core_Selector_Base implements CRM * The row number to start from. * @param int $rowCount * The number of rows to return. - * @param string $sort + * @param string|CRM_Utils_Sort $sort * The sql string that describes the sort order. * @param string $output * What should the result set include (web/email/csv). @@ -265,7 +265,7 @@ class CRM_Activity_Selector_Search extends CRM_Core_Selector_Base implements CRM $row['source_contact_name'] = implode(',', array_values($row['source_contact_name'])); $row['source_contact_id'] = implode(',', $row['source_contact_id']); - if ($this->_context == 'search') { + if ($this->_context === 'search') { $row['checkbox'] = CRM_Core_Form::CB_PREFIX . $result->activity_id; } $row['contact_type'] = CRM_Contact_BAO_Contact_Utils::getImage($result->contact_sub_type ? $result->contact_sub_type : $result->contact_type, FALSE, $result->contact_id @@ -291,10 +291,10 @@ class CRM_Activity_Selector_Search extends CRM_Core_Selector_Base implements CRM $accessMailingReport = TRUE; } $activityActions = new CRM_Activity_Selector_Activity($result->contact_id, NULL); - $actionLinks = $activityActions->actionLinks($activityTypeId, - CRM_Utils_Array::value('source_record_id', $row), + $actionLinks = $activityActions::actionLinks($activityTypeId, + $row['source_record_id'] ?? NULL, $accessMailingReport, - CRM_Utils_Array::value('activity_id', $row), + $row['activity_id'] ?? NULL, $this->_key, $this->_compContext ); @@ -303,6 +303,10 @@ class CRM_Activity_Selector_Search extends CRM_Core_Selector_Base implements CRM 'id' => $result->activity_id, 'cid' => $contactId, 'cxt' => $this->_context, + // Parameter for hook locked in by CRM_Activity_Selector_SearchTest + // Any additional parameters added should follow apiv4 style + // and be added to the test. + 'activity_type_id' => $row['activity_type_id'], ], ts('more'), FALSE, diff --git a/civicrm/CRM/Admin/Form/OptionGroup.php b/civicrm/CRM/Admin/Form/OptionGroup.php index 6de152bb9e..fbf87dfb07 100644 --- a/civicrm/CRM/Admin/Form/OptionGroup.php +++ b/civicrm/CRM/Admin/Form/OptionGroup.php @@ -120,7 +120,7 @@ class CRM_Admin_Form_OptionGroup extends CRM_Admin_Form { CRM_Utils_System::flushCache(); if ($this->_action & CRM_Core_Action::DELETE) { - CRM_Core_BAO_OptionGroup::del($this->_id); + CRM_Core_BAO_OptionGroup::deleteRecord(['id' => $this->_id]); CRM_Core_Session::setStatus(ts('Selected option group has been deleted.'), ts('Record Deleted'), 'success'); } else { diff --git a/civicrm/CRM/Admin/Form/Options.php b/civicrm/CRM/Admin/Form/Options.php index 5a36fc49ba..d63a963897 100644 --- a/civicrm/CRM/Admin/Form/Options.php +++ b/civicrm/CRM/Admin/Form/Options.php @@ -459,7 +459,7 @@ class CRM_Admin_Form_Options extends CRM_Admin_Form { $fieldValues = ['option_group_id' => $this->_gid]; CRM_Utils_Weight::delWeight('CRM_Core_DAO_OptionValue', $this->_id, $fieldValues); - if (CRM_Core_BAO_OptionValue::del($this->_id)) { + if (CRM_Core_BAO_OptionValue::deleteRecord(['id' => $this->_id])) { if ($this->_gName == 'phone_type') { CRM_Core_BAO_Phone::setOptionToNull(CRM_Utils_Array::value('value', $this->_defaultValues)); } diff --git a/civicrm/CRM/Admin/Form/PaymentProcessor.php b/civicrm/CRM/Admin/Form/PaymentProcessor.php index 2e6a3b99d1..014727e76b 100644 --- a/civicrm/CRM/Admin/Form/PaymentProcessor.php +++ b/civicrm/CRM/Admin/Form/PaymentProcessor.php @@ -217,8 +217,7 @@ class CRM_Admin_Form_PaymentProcessor extends CRM_Admin_Form { 'payment_processor_type_id', ts('Payment Processor Type'), CRM_Financial_BAO_PaymentProcessor::buildOptions('payment_processor_type_id'), - TRUE, - ['onchange' => "reload(true)"] + TRUE ); // Financial Account of account type asset CRM-11515 diff --git a/civicrm/CRM/Admin/Form/Preferences/Mailing.php b/civicrm/CRM/Admin/Form/Preferences/Mailing.php index 726a31dd4e..23cc19a9b8 100644 --- a/civicrm/CRM/Admin/Form/Preferences/Mailing.php +++ b/civicrm/CRM/Admin/Form/Preferences/Mailing.php @@ -35,6 +35,7 @@ class CRM_Admin_Form_Preferences_Mailing extends CRM_Admin_Form_Preferences { 'auto_recipient_rebuild' => CRM_Core_BAO_Setting::MAILING_PREFERENCES_NAME, 'url_tracking_default' => CRM_Core_BAO_Setting::MAILING_PREFERENCES_NAME, 'open_tracking_default' => CRM_Core_BAO_Setting::MAILING_PREFERENCES_NAME, + 'scheduled_reminder_smarty' => CRM_Core_BAO_Setting::MAILING_PREFERENCES_NAME, ]; public function postProcess() { diff --git a/civicrm/CRM/Admin/Form/ScheduleReminders.php b/civicrm/CRM/Admin/Form/ScheduleReminders.php index 25a8b57bab..67e9bef527 100644 --- a/civicrm/CRM/Admin/Form/ScheduleReminders.php +++ b/civicrm/CRM/Admin/Form/ScheduleReminders.php @@ -15,6 +15,8 @@ * @copyright CiviCRM LLC https://civicrm.org/licensing */ +use Civi\Token\TokenProcessor; + /** * This class generates form components for Scheduling Reminders. */ @@ -696,19 +698,13 @@ class CRM_Admin_Form_ScheduleReminders extends CRM_Admin_Form { * * @return array */ - public function listTokens() { - $tokenProcessor = new \Civi\Token\TokenProcessor(\Civi::dispatcher(), [ - 'controller' => get_class(), + public function listTokens(): array { + $tokenProcessor = new TokenProcessor(\Civi::dispatcher(), [ + 'controller' => __CLASS__, 'smarty' => FALSE, - 'schema' => ['activityId', 'participantId'], + 'schema' => ['activityId', 'participantId', 'membershipId', 'contactId', 'eventId', 'contributionId'], ]); - $tokens = $tokenProcessor->listTokens(); - - $tokens = array_merge(CRM_Core_SelectValues::contactTokens(), $tokens); - $tokens = array_merge(CRM_Core_SelectValues::eventTokens(), $tokens); - $tokens = array_merge(CRM_Core_SelectValues::membershipTokens(), $tokens); - $tokens = array_merge(CRM_Core_SelectValues::contributionTokens(), $tokens); - return $tokens; + return $tokenProcessor->listTokens(); } } diff --git a/civicrm/CRM/Admin/Form/Setting/UF.php b/civicrm/CRM/Admin/Form/Setting/UF.php index f6da3da6de..041a3f5ff9 100644 --- a/civicrm/CRM/Admin/Form/Setting/UF.php +++ b/civicrm/CRM/Admin/Form/Setting/UF.php @@ -34,62 +34,25 @@ class CRM_Admin_Form_Setting_UF extends CRM_Admin_Form_Setting { $this->assign('wpBasePageEnabled', FALSE); $this->assign('userFrameworkUsersTableNameEnabled', FALSE); + $this->assign('viewsIntegration', FALSE); $this->setTitle( ts('Settings - %1 Integration', [1 => $this->_uf]) ); - if ($this->_uf === 'WordPress') { + if ($config->userSystem->canSetBasePage()) { $this->_settings['wpBasePage'] = CRM_Core_BAO_Setting::SYSTEM_PREFERENCES_NAME; $this->assign('wpBasePageEnabled', TRUE); } - if ($config->userSystem->is_drupal) { + if ($config->userSystem->hasUsersTable()) { $this->_settings['userFrameworkUsersTableName'] = CRM_Core_BAO_Setting::SYSTEM_PREFERENCES_NAME; $this->assign('userFrameworkUsersTableNameEnabled', TRUE); } - // find out if drupal has its database prefixed - if ($this->_uf === 'Drupal8') { - $databases['default'] = Drupal\Core\Database\Database::getConnectionInfo('default'); - } - else { - global $databases; - } - - $drupal_prefix = ''; - if (isset($databases['default']['default']['prefix'])) { - if (is_array($databases['default']['default']['prefix'])) { - $drupal_prefix = $databases['default']['default']['prefix']['default']; - } - else { - $drupal_prefix = $databases['default']['default']['prefix']; - } - } - - $this->assign('tablePrefixes', FALSE); - - if ($config->userSystem->viewsExists() && - ( - $config->dsn != $config->userFrameworkDSN || !empty($drupal_prefix) - ) - ) { - - $dsnArray = DB::parseDSN(CRM_Utils_SQL::autoSwitchDSN($config->dsn)); - $tableNames = CRM_Core_DAO::getTableNames(); - asort($tableNames); - $tablePrefixes = '$databases[\'default\'][\'default\'][\'prefix\']= ['; - if ($config->userFramework === 'Backdrop') { - $tablePrefixes = '$database_prefix = ['; - } - // add default prefix: the drupal database prefix - $tablePrefixes .= "\n 'default' => '$drupal_prefix',"; - $prefix = $config->userSystem->getCRMDatabasePrefix(); - foreach ($tableNames as $tableName) { - $tablePrefixes .= "\n '" . str_pad($tableName . "'", 41) . " => '{$prefix}',"; - } - $tablePrefixes .= "\n];"; - $this->assign('tablePrefixes', $tablePrefixes); + $viewsIntegration = $config->userSystem->viewsIntegration(); + if ($viewsIntegration) { + $this->assign('viewsIntegration', $viewsIntegration); } parent::buildQuickForm(); diff --git a/civicrm/CRM/Badge/BAO/Layout.php b/civicrm/CRM/Badge/BAO/Layout.php index a662445166..dd34add77a 100644 --- a/civicrm/CRM/Badge/BAO/Layout.php +++ b/civicrm/CRM/Badge/BAO/Layout.php @@ -92,6 +92,7 @@ class CRM_Badge_BAO_Layout extends CRM_Core_DAO_PrintLabel { * @deprecated */ public static function del($printLabelId) { + CRM_Core_Error::deprecatedFunctionWarning('deleteRecord'); self::deleteRecord(['id' => $printLabelId]); } diff --git a/civicrm/CRM/Badge/Form/Layout.php b/civicrm/CRM/Badge/Form/Layout.php index 90026c7fe3..661fb70ac3 100644 --- a/civicrm/CRM/Badge/Form/Layout.php +++ b/civicrm/CRM/Badge/Form/Layout.php @@ -164,7 +164,7 @@ class CRM_Badge_Form_Layout extends CRM_Admin_Form { */ public function postProcess() { if ($this->_action & CRM_Core_Action::DELETE) { - CRM_Badge_BAO_Layout::del($this->_id); + CRM_Badge_BAO_Layout::deleteRecord(['id' => $this->_id]); CRM_Core_Session::setStatus(ts('Selected badge layout has been deleted.'), ts('Record Deleted'), 'success'); return; } diff --git a/civicrm/CRM/Batch/BAO/EntityBatch.php b/civicrm/CRM/Batch/BAO/EntityBatch.php index 3f64e75b33..18fffa96fa 100644 --- a/civicrm/CRM/Batch/BAO/EntityBatch.php +++ b/civicrm/CRM/Batch/BAO/EntityBatch.php @@ -63,6 +63,7 @@ class CRM_Batch_BAO_EntityBatch extends CRM_Batch_DAO_EntityBatch { * @return CRM_Batch_DAO_EntityBatch */ public static function del($params) { + CRM_Core_Error::deprecatedFunctionWarning('deleteRecord'); if (!is_array($params)) { $params = ['id' => $params]; } diff --git a/civicrm/CRM/Campaign/Form/Survey/Main.php b/civicrm/CRM/Campaign/Form/Survey/Main.php index 44b760763e..72fc38c7c1 100644 --- a/civicrm/CRM/Campaign/Form/Survey/Main.php +++ b/civicrm/CRM/Campaign/Form/Survey/Main.php @@ -187,7 +187,7 @@ class CRM_Campaign_Form_Survey_Main extends CRM_Campaign_Form_Survey { ); // delete option group if no any survey is using it. if (!$countSurvey) { - CRM_Core_BAO_OptionGroup::del($this->_values['result_id']); + CRM_Core_BAO_OptionGroup::deleteRecord(['id' => $this->_values['result_id']]); } } diff --git a/civicrm/CRM/Campaign/Form/SurveyType.php b/civicrm/CRM/Campaign/Form/SurveyType.php index 7138304059..02e8836ef5 100644 --- a/civicrm/CRM/Campaign/Form/SurveyType.php +++ b/civicrm/CRM/Campaign/Form/SurveyType.php @@ -122,7 +122,7 @@ class CRM_Campaign_Form_SurveyType extends CRM_Admin_Form { $fieldValues = ['option_group_id' => $this->_gid]; $wt = CRM_Utils_Weight::delWeight('CRM_Core_DAO_OptionValue', $this->_id, $fieldValues); - if (CRM_Core_BAO_OptionValue::del($this->_id)) { + if (CRM_Core_BAO_OptionValue::deleteRecord(['id' => $this->_id])) { CRM_Core_Session::setStatus(ts('Selected Survey type has been deleted.'), ts('Record Deleted'), 'success'); } } diff --git a/civicrm/CRM/Campaign/Selector/Search.php b/civicrm/CRM/Campaign/Selector/Search.php index 2c3cdd4856..097178b9ba 100644 --- a/civicrm/CRM/Campaign/Selector/Search.php +++ b/civicrm/CRM/Campaign/Selector/Search.php @@ -249,7 +249,7 @@ class CRM_Campaign_Selector_Search extends CRM_Core_Selector_Base implements CRM /** * @param $sort */ - public function buildPrevNextCache($sort) { + private function buildPrevNextCache($sort) { //for prev/next pagination $crmPID = CRM_Utils_Request::retrieve('crmPID', 'Integer'); diff --git a/civicrm/CRM/Case/BAO/Case.php b/civicrm/CRM/Case/BAO/Case.php index ae7ba35fb0..e255c72a38 100644 --- a/civicrm/CRM/Case/BAO/Case.php +++ b/civicrm/CRM/Case/BAO/Case.php @@ -765,7 +765,7 @@ HERESQL; $caseTypes = array_flip($caseTypes); // get statuses as headers for the table - $url = CRM_Utils_System::url('civicrm/case/search', "reset=1&force=1&all=1&status="); + $url = CRM_Utils_System::url('civicrm/case/search', "reset=1&force=1&all=1&case_status_id="); foreach ($caseStatuses as $key => $name) { $caseSummary['headers'][$key]['status'] = $name; $caseSummary['headers'][$key]['url'] = $url . $key; @@ -831,7 +831,7 @@ SELECT civicrm_case.id, case_status.label AS case_status, status_id, civicrm_cas $rows[$res->case_type][$res->case_status] = [ 'count' => 1, 'url' => CRM_Utils_System::url('civicrm/case/search', - "reset=1&force=1&status={$res->status_id}&type={$res->case_type_id}&case_owner={$case_owner}" + "reset=1&force=1&case_status_id={$res->status_id}&case_type_id={$res->case_type_id}&case_owner={$case_owner}" ), ]; } diff --git a/civicrm/CRM/Case/BAO/CaseType.php b/civicrm/CRM/Case/BAO/CaseType.php index c3f7457864..8021fa1ea9 100644 --- a/civicrm/CRM/Case/BAO/CaseType.php +++ b/civicrm/CRM/Case/BAO/CaseType.php @@ -439,6 +439,7 @@ class CRM_Case_BAO_CaseType extends CRM_Case_DAO_CaseType implements \Civi\Core\ * @return CRM_Case_DAO_CaseType */ public static function del($caseTypeId) { + CRM_Core_Error::deprecatedFunctionWarning('deleteRecord'); return static::deleteRecord(['id' => $caseTypeId]); } diff --git a/civicrm/CRM/Contact/BAO/Contact.php b/civicrm/CRM/Contact/BAO/Contact.php index 1e8aa46a23..c9c9dc964c 100644 --- a/civicrm/CRM/Contact/BAO/Contact.php +++ b/civicrm/CRM/Contact/BAO/Contact.php @@ -1147,36 +1147,6 @@ WHERE civicrm_contact.id = " . CRM_Utils_Type::escape($id, 'Integer'); } } - /** - * Function to set is_delete true or restore deleted contact. - * - * @param CRM_Contact_DAO_Contact $contact - * Contact DAO object. - * @param bool $restore - * True to set the is_delete = 1 else false to restore deleted contact, - * i.e. is_delete = 0 - * - * @deprecated - * - * @return bool - * @throws \CRM_Core_Exception - */ - public static function contactTrashRestore($contact, $restore = FALSE) { - CRM_Core_Error::deprecatedFunctionWarning('Use the api'); - - if ($restore) { - CRM_Core_Error::deprecatedFunctionWarning('Use contact.create to restore - this does nothing much'); - // @todo deprecate calling contactDelete with the intention to restore. - $updateParams = [ - 'id' => $contact->id, - 'is_deleted' => FALSE, - ]; - self::create($updateParams); - return TRUE; - } - return self::contactTrash($contact); - } - /** * Get contact type for a contact. * @@ -2579,10 +2549,7 @@ LEFT JOIN civicrm_email ON ( civicrm_contact.id = civicrm_email.contact_id ) $values['preferred_mail_format'] = $preferredMailingFormat[$contact->preferred_mail_format]; } - // get preferred languages - if (!empty($contact->preferred_language)) { - $values['preferred_language'] = CRM_Core_PseudoConstant::getLabel('CRM_Contact_DAO_Contact', 'preferred_language', $contact->preferred_language); - } + $values['preferred_language'] = empty($contact->preferred_language) ? NULL : CRM_Core_PseudoConstant::getLabel('CRM_Contact_DAO_Contact', 'preferred_language', $contact->preferred_language); // Calculating Year difference if ($contact->birth_date) { diff --git a/civicrm/CRM/Contact/BAO/Contact/Location.php b/civicrm/CRM/Contact/BAO/Contact/Location.php index 2e3a0fdb99..13f533ba66 100644 --- a/civicrm/CRM/Contact/BAO/Contact/Location.php +++ b/civicrm/CRM/Contact/BAO/Contact/Location.php @@ -59,44 +59,6 @@ class CRM_Contact_BAO_Contact_Location { return $returnParams; } - /** - * @deprecated Not used anywhere, use the Phone API instead - * Get the sms number and display name of a contact. - * - * @param int $id - * Id of the contact. - * @param string|null $type - * - * @return array - * tuple of display_name and sms if found, or (null,null) - */ - public static function getPhoneDetails($id, $type = NULL) { - CRM_Core_Error::deprecatedFunctionWarning('Phone.get API instead'); - if (!$id) { - return [NULL, NULL]; - } - - $cond = NULL; - if ($type) { - $cond = " AND civicrm_phone.phone_type_id = '$type'"; - } - - $sql = " - SELECT civicrm_contact.display_name, civicrm_phone.phone, civicrm_contact.do_not_sms - FROM civicrm_contact -LEFT JOIN civicrm_phone ON ( civicrm_phone.contact_id = civicrm_contact.id ) - WHERE civicrm_phone.is_primary = 1 - $cond - AND civicrm_contact.id = %1"; - - $params = [1 => [$id, 'Integer']]; - $dao = CRM_Core_DAO::executeQuery($sql, $params); - if ($dao->fetch()) { - return [$dao->display_name, $dao->phone, $dao->do_not_sms]; - } - return [NULL, NULL, NULL]; - } - /** * Get the information to map a contact. * diff --git a/civicrm/CRM/Contact/BAO/GroupContact.php b/civicrm/CRM/Contact/BAO/GroupContact.php index b058686ec8..22d8902d54 100644 --- a/civicrm/CRM/Contact/BAO/GroupContact.php +++ b/civicrm/CRM/Contact/BAO/GroupContact.php @@ -33,6 +33,7 @@ class CRM_Contact_BAO_GroupContact extends CRM_Contact_DAO_GroupContact implemen * @deprecated */ public static function add(array $params): CRM_Contact_DAO_GroupContact { + CRM_Core_Error::deprecatedFunctionWarning('writeRecord'); return self::writeRecord($params); } @@ -503,7 +504,7 @@ SELECT * // As of Aug 2020 it's not called from anywhere so we can remove the below code after some time CRM_Core_Error::deprecatedFunctionWarning('Use the GroupContact API'); - return self::add($params); + return self::writeRecord($params); } /** diff --git a/civicrm/CRM/Contact/DAO/Relationship.php b/civicrm/CRM/Contact/DAO/Relationship.php index 3a676d714c..cdacc83527 100644 --- a/civicrm/CRM/Contact/DAO/Relationship.php +++ b/civicrm/CRM/Contact/DAO/Relationship.php @@ -6,7 +6,7 @@ * * Generated from xml/schema/CRM/Contact/Relationship.xml * DO NOT EDIT. Generated by CRM_Core_CodeGen - * (GenCodeChecksum:53d602cd851fdc4afcfa9f2301e20baa) + * (GenCodeChecksum:ea043ab2b1943a9fe5e86ec6a68fedf4) */ /** @@ -406,6 +406,7 @@ class CRM_Contact_DAO_Relationship extends CRM_Core_DAO { 'FKClassName' => 'CRM_Case_DAO_Case', 'component' => 'CiviCase', 'html' => [ + 'type' => 'EntityRef', 'label' => ts("Case"), ], 'add' => '2.2', diff --git a/civicrm/CRM/Contact/DAO/SubscriptionHistory.php b/civicrm/CRM/Contact/DAO/SubscriptionHistory.php index c1186708f3..18492d6e1e 100644 --- a/civicrm/CRM/Contact/DAO/SubscriptionHistory.php +++ b/civicrm/CRM/Contact/DAO/SubscriptionHistory.php @@ -6,7 +6,7 @@ * * Generated from xml/schema/CRM/Contact/SubscriptionHistory.xml * DO NOT EDIT. Generated by CRM_Core_CodeGen - * (GenCodeChecksum:352df636d72c00072ade0a93fe8ce181) + * (GenCodeChecksum:30b144a6f844fb0fb38b1bdbeee72ecf) */ /** @@ -203,6 +203,11 @@ class CRM_Contact_DAO_SubscriptionHistory extends CRM_Core_DAO { 'entity' => 'SubscriptionHistory', 'bao' => 'CRM_Contact_BAO_SubscriptionHistory', 'localizable' => 0, + 'html' => [ + 'type' => 'Select Date', + 'formatType' => 'activityDateTime', + 'label' => ts("Group Membership Action Date"), + ], 'add' => '1.1', ], 'method' => [ diff --git a/civicrm/CRM/Contact/Form/DedupeRules.php b/civicrm/CRM/Contact/Form/DedupeRules.php index 7c2040631f..1ac21b3510 100644 --- a/civicrm/CRM/Contact/Form/DedupeRules.php +++ b/civicrm/CRM/Contact/Form/DedupeRules.php @@ -27,7 +27,7 @@ class CRM_Contact_Form_DedupeRules extends CRM_Admin_Form { /** * Explicitly declare the entity api name. */ - public function getDefaultEntity() { + public function getDefaultEntity(): string { return 'RuleGroup'; } @@ -192,14 +192,16 @@ class CRM_Contact_Form_DedupeRules extends CRM_Admin_Form { /** * Process the form submission. + * + * @throws \CRM_Core_Exception */ - public function postProcess() { + public function postProcess(): void { $values = $this->exportValues(); //FIXME: Handle logic to replace is_default column by usage // reset used column to General (since there can only // be one 'Supervised' or 'Unsupervised' rule) - if ($values['used'] != 'General') { + if ($values['used'] !== 'General') { $query = " UPDATE civicrm_dedupe_rule_group SET used = 'General' @@ -231,11 +233,10 @@ UPDATE civicrm_dedupe_rule_group $ruleDao = new CRM_Dedupe_DAO_DedupeRule(); $ruleDao->dedupe_rule_group_id = $rgDao->id; $ruleDao->delete(); - $substrLenghts = []; + $substrLengths = []; $tables = []; - $daoObj = new CRM_Core_DAO(); - $database = $daoObj->database(); + for ($count = 0; $count < self::RULES_COUNT; $count++) { if (empty($values["where_$count"])) { continue; @@ -260,13 +261,13 @@ UPDATE civicrm_dedupe_rule_group // CRM-6245: we must pass table/field/length triples to the createIndexes() call below if ($length) { - if (!isset($substrLenghts[$table])) { - $substrLenghts[$table] = []; + if (!isset($substrLengths[$table])) { + $substrLengths[$table] = []; } //CRM-13417 to avoid fatal error "Incorrect prefix key; the used key part isn't a string, the used length is longer than the key part, or the storage engine doesn't support unique prefix keys, 1089" $schemaQuery = "SELECT * FROM INFORMATION_SCHEMA.COLUMNS - WHERE TABLE_SCHEMA = '{$database}' AND + WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = '{$table}' AND COLUMN_NAME = '{$field}';"; $dao = CRM_Core_DAO::executeQuery($schemaQuery); @@ -287,14 +288,14 @@ UPDATE civicrm_dedupe_rule_group $length = $dao->CHARACTER_MAXIMUM_LENGTH; } } - $substrLenghts[$table][$field] = $length; + $substrLengths[$table][$field] = $length; } } // also create an index for this dedupe rule // CRM-3837 CRM_Utils_Hook::dupeQuery($ruleDao, 'dedupeIndexes', $tables); - CRM_Core_BAO_SchemaHandler::createIndexes($tables, 'dedupe_index', $substrLenghts); + CRM_Core_BAO_SchemaHandler::createIndexes($tables, 'dedupe_index', $substrLengths); //need to clear cache of deduped contacts //based on the previous rule diff --git a/civicrm/CRM/Contact/Form/Task/Label.php b/civicrm/CRM/Contact/Form/Task/Label.php index e7a6d164d7..ac91129e22 100644 --- a/civicrm/CRM/Contact/Form/Task/Label.php +++ b/civicrm/CRM/Contact/Form/Task/Label.php @@ -95,6 +95,9 @@ class CRM_Contact_Form_Task_Label extends CRM_Contact_Form_Task { * @param array|null $params */ public function postProcess($params = NULL) { + if (!empty($params)) { + CRM_Core_Error::deprecatedWarning('params parameter is deprecated'); + } $fv = $params ?: $this->controller->exportValues($this->_name); $locName = NULL; diff --git a/civicrm/CRM/Contact/Import/Form/Preview.php b/civicrm/CRM/Contact/Import/Form/Preview.php index c133b99c1c..cfc55e5c03 100644 --- a/civicrm/CRM/Contact/Import/Form/Preview.php +++ b/civicrm/CRM/Contact/Import/Form/Preview.php @@ -26,7 +26,7 @@ class CRM_Contact_Import_Form_Preview extends CRM_Import_Form_Preview { /** * Build the form object. */ - public function buildQuickForm() { + public function buildQuickForm(): void { $this->addElement('text', 'newGroupName', ts('Name for new group'), CRM_Core_DAO::getAttribute('CRM_Contact_DAO_Group', 'title')); $this->addElement('text', 'newGroupDesc', ts('Description of new group')); $groupTypes = CRM_Core_OptionGroup::values('group_type', TRUE); @@ -38,11 +38,11 @@ class CRM_Contact_Import_Form_Preview extends CRM_Import_Form_Preview { ); } - $groups = CRM_Core_PseudoConstant::nestedGroup();; + $groups = CRM_Core_PseudoConstant::nestedGroup(); if (!empty($groups)) { $this->addElement('select', 'groups', ts('Add imported records to existing group(s)'), $groups, [ - 'multiple' => "multiple", + 'multiple' => 'multiple', 'class' => 'crm-select2', ]); } @@ -70,48 +70,32 @@ class CRM_Contact_Import_Form_Preview extends CRM_Import_Form_Preview { * @param array $fields * Posted values of the form. * - * @param $files - * @param self $self - * * @return array|bool * list of errors to be posted back to the form */ - public static function formRule($fields, $files, $self) { + public static function formRule(array $fields) { $errors = []; - $invalidTagName = $invalidGroupName = FALSE; - - if (!empty($fields['newTagName'])) { - if (!CRM_Utils_Rule::objectExists(trim($fields['newTagName']), - ['CRM_Core_DAO_Tag'] - ) - ) { - $errors['newTagName'] = ts('Tag \'%1\' already exists.', - [1 => $fields['newTagName']] - ); - $invalidTagName = TRUE; - } + if (!empty($fields['newTagName']) + && !CRM_Utils_Rule::objectExists(trim($fields['newTagName']), ['CRM_Core_DAO_Tag']) + ) { + $errors['newTagName'] = ts('Tag \'%1\' already exists.', [1 => $fields['newTagName']]); } if (!empty($fields['newGroupName'])) { $title = trim($fields['newGroupName']); $name = CRM_Utils_String::titleToVar($title); $query = 'SELECT COUNT(*) FROM civicrm_group WHERE name LIKE %1 OR title LIKE %2'; - $grpCnt = CRM_Core_DAO::singleValueQuery( + if (CRM_Core_DAO::singleValueQuery( $query, [ 1 => [$name, 'String'], 2 => [$title, 'String'], ] - ); - if ($grpCnt) { - $invalidGroupName = TRUE; + )) { $errors['newGroupName'] = ts('Group \'%1\' already exists.', [1 => $fields['newGroupName']]); } } - $self->assign('invalidTagName', $invalidTagName); - $self->assign('invalidGroupName', $invalidGroupName); - return empty($errors) ? TRUE : $errors; } diff --git a/civicrm/CRM/Contact/Import/Parser/Contact.php b/civicrm/CRM/Contact/Import/Parser/Contact.php index f1b7b92b0e..e86e99c39a 100644 --- a/civicrm/CRM/Contact/Import/Parser/Contact.php +++ b/civicrm/CRM/Contact/Import/Parser/Contact.php @@ -29,7 +29,7 @@ class CRM_Contact_Import_Parser_Contact extends CRM_Import_Parser { use CRM_Contact_Import_MetadataTrait; - protected $_allExternalIdentifiers = []; + private $externalIdentifiers = []; /** * Array of successfully imported contact id's @@ -38,13 +38,6 @@ class CRM_Contact_Import_Parser_Contact extends CRM_Import_Parser { */ protected $_newContacts = []; - /** - * Line count id. - * - * @var int - */ - protected $_lineCount; - protected $_tableName; /** @@ -509,19 +502,7 @@ class CRM_Contact_Import_Parser_Contact extends CRM_Import_Parser { } } } - - //check for duplicate external Identifier - $externalID = $params['external_identifier'] ?? NULL; - if ($externalID) { - /* If it's a dupe,external Identifier */ - - if ($externalDupe = CRM_Utils_Array::value($externalID, $this->_allExternalIdentifiers)) { - $errorMessage = ts('External ID conflicts with record %1', [1 => $externalDupe]); - throw new CRM_Core_Exception($errorMessage); - } - //otherwise, count it and move on - $this->_allExternalIdentifiers[$externalID] = $this->_lineCount; - } + $this->checkForDuplicateExternalIdentifiers($params['external_identifier'] ?? ''); //date-format part ends @@ -1734,4 +1715,21 @@ class CRM_Contact_Import_Parser_Contact extends CRM_Import_Parser { ][$outcome] ?? 'ERROR'; } + /** + * Return an error if the csv has more than one row with the same external identifier. + * + * @param string $externalIdentifier + * + * @throws \CRM_Core_Exception + */ + protected function checkForDuplicateExternalIdentifiers(string $externalIdentifier): void { + if ($externalIdentifier) { + $existingRow = array_search($externalIdentifier, $this->externalIdentifiers, TRUE); + if ($existingRow !== FALSE) { + throw new CRM_Core_Exception(ts('External ID conflicts with record %1', [1 => $existingRow + 1])); + } + $this->externalIdentifiers[] = $externalIdentifier; + } + } + } diff --git a/civicrm/CRM/Contact/Page/AJAX.php b/civicrm/CRM/Contact/Page/AJAX.php index 793e998c60..f09be9d63c 100644 --- a/civicrm/CRM/Contact/Page/AJAX.php +++ b/civicrm/CRM/Contact/Page/AJAX.php @@ -483,7 +483,7 @@ LIMIT {$offset}, {$rowCount} } public static function buildDedupeRules() { - $contactType = CRM_Utils_Request::retrieve('parentId', 'Positive'); + $contactType = CRM_Utils_Request::retrieve('parentId', 'String'); $dedupeRules = CRM_Dedupe_BAO_DedupeRuleGroup::getByType($contactType); CRM_Utils_JSON::output($dedupeRules); diff --git a/civicrm/CRM/Contact/Page/Inline/Email.php b/civicrm/CRM/Contact/Page/Inline/Email.php index 7ca97943c1..6e98a2cc46 100644 --- a/civicrm/CRM/Contact/Page/Inline/Email.php +++ b/civicrm/CRM/Contact/Page/Inline/Email.php @@ -27,7 +27,7 @@ class CRM_Contact_Page_Inline_Email extends CRM_Core_Page { */ public function run() { // get the emails for this contact - $contactId = CRM_Utils_Request::retrieve('cid', 'Positive', CRM_Core_DAO::$_nullObject, TRUE); + $contactId = CRM_Utils_Request::retrieve('cid', 'Positive', NULL, TRUE); $locationTypes = CRM_Core_PseudoConstant::get('CRM_Core_DAO_Address', 'location_type_id', ['labelColumn' => 'display_name']); diff --git a/civicrm/CRM/Contact/Selector.php b/civicrm/CRM/Contact/Selector.php index cb85daa4f2..fa8d2da1f6 100644 --- a/civicrm/CRM/Contact/Selector.php +++ b/civicrm/CRM/Contact/Selector.php @@ -864,7 +864,7 @@ class CRM_Contact_Selector extends CRM_Core_Selector_Base implements CRM_Core_Se * * @return string */ - public function buildPrevNextCache($sort) { + private function buildPrevNextCache($sort) { $cacheKey = 'civicrm search ' . $this->_key; // We should clear the cache in following conditions: @@ -1025,20 +1025,17 @@ class CRM_Contact_Selector extends CRM_Core_Selector_Base implements CRM_Core_Se * @param int $start * @param int $end * + * @todo - use test cover in CRM_Contact_Form_Search_BasicTest to + * to remove the extraneous logging that happens in the tested + * scenario (It does the catch & then write to the log - I was + * going to fix but got stalled on getting https://github.com/civicrm/civicrm-core/pull/25392 + * merged - this comment won't conflict with that PR :-) + * * @throws \CRM_Core_Exception */ - public function fillupPrevNextCache($sort, $cacheKey, $start = 0, $end = self::CACHE_SIZE) { - $coreSearch = TRUE; - // For custom searches, use the contactIDs method - if (is_a($this, 'CRM_Contact_Selector_Custom')) { - $sql = $this->_search->contactIDs($start, $end, $sort, TRUE); - $coreSearch = FALSE; - } - // For core searches use the searchQuery method - else { - $sql = $this->_query->getSearchSQL($start, $end, $sort, FALSE, $this->_query->_includeContactIds, + private function fillupPrevNextCache($sort, $cacheKey, $start = 0, $end = self::CACHE_SIZE) { + $sql = $this->_query->getSearchSQL($start, $end, $sort, FALSE, $this->_query->_includeContactIds, FALSE, TRUE); - } // CRM-9096 // due to limitations in our search query writer, the above query does not work @@ -1049,7 +1046,7 @@ class CRM_Contact_Selector extends CRM_Core_Selector_Base implements CRM_Core_Se // the other alternative of running the FULL query will just be incredibly inefficient // and slow things down way too much on large data sets / complex queries - $selectSQL = CRM_Core_DAO::composeQuery("SELECT DISTINCT %1, contact_a.id, contact_a.sort_name", [1 => [$cacheKey, 'String']]); + $selectSQL = CRM_Core_DAO::composeQuery('SELECT DISTINCT %1, contact_a.id, contact_a.sort_name', [1 => [$cacheKey, 'String']]); $sql = str_ireplace(['SELECT contact_a.id as contact_id', 'SELECT contact_a.id as id'], $selectSQL, $sql); $sql = str_ireplace('ORDER BY `contact_id`', 'ORDER BY `id`', $sql, $sql); @@ -1058,19 +1055,9 @@ class CRM_Contact_Selector extends CRM_Core_Selector_Base implements CRM_Core_Se Civi::service('prevnext')->fillWithSql($cacheKey, $sql); } catch (\Exception $e) { - if ($coreSearch) { - // in the case of error, try rebuilding cache using full sql which is used for search selector display - // this fixes the bugs reported in CRM-13996 & CRM-14438 - $this->rebuildPreNextCache($start, $end, $sort, $cacheKey); - } - else { - CRM_Core_Error::deprecatedFunctionWarning('Custom searches should return sql capable of filling the prevnext cache.'); - // This will always show for CiviRules :-( as a) it orders by 'rule_label' - // which is not available in the query & b) it uses contact not contact_a - // as an alias. - // CRM_Core_Session::setStatus(ts('Query Failed')); - return; - } + // in the case of error, try rebuilding cache using full sql which is used for search selector display + // this fixes the bugs reported in CRM-13996 & CRM-14438 + $this->rebuildPreNextCache($start, $end, $sort, $cacheKey); } if (Civi::service('prevnext') instanceof CRM_Core_PrevNextCache_Sql) { @@ -1091,7 +1078,7 @@ class CRM_Contact_Selector extends CRM_Core_Selector_Base implements CRM_Core_Se * @param string $cacheKey * Cache key. */ - public function rebuildPreNextCache($start, $end, $sort, $cacheKey) { + private function rebuildPreNextCache($start, $end, $sort, $cacheKey): void { // generate full SQL $sql = $this->_query->searchQuery($start, $end, $sort, FALSE, $this->_query->_includeContactIds, FALSE, FALSE, TRUE); diff --git a/civicrm/CRM/Contribute/BAO/Contribution.php b/civicrm/CRM/Contribute/BAO/Contribution.php index ebc8c447f3..d1d7afe877 100644 --- a/civicrm/CRM/Contribute/BAO/Contribution.php +++ b/civicrm/CRM/Contribute/BAO/Contribution.php @@ -11,6 +11,7 @@ use Civi\Api4\Activity; use Civi\Api4\ActivityContact; +use Civi\Api4\Address; use Civi\Api4\Contribution; use Civi\Api4\ContributionRecur; use Civi\Api4\LineItem; @@ -1458,8 +1459,10 @@ GROUP BY p.id * @todo - this is a confusing function called from one place. It has a test. It would be * nice to deprecate it. * + * @deprecated */ public static function getHonorContacts($honorId) { + CRM_Core_Error::deprecatedFunctionWarning('apiv4'); $params = []; $honorDAO = new CRM_Contribute_DAO_ContributionSoft(); $honorDAO->contact_id = $honorId; @@ -1698,8 +1701,7 @@ WHERE $condition $dao = CRM_Core_DAO::executeQuery($query); while ($dao->fetch()) { - $params = ['id' => $dao->id]; - CRM_Core_BAO_Block::blockDelete('Address', $params); + Address::delete(FALSE)->addWhere('id', '=', $dao->id)->execute(); } } @@ -1849,6 +1851,7 @@ LEFT JOIN civicrm_contribution contribution ON ( componentPayment.contribution_ } $contribution->loadRelatedObjects($paymentProcessorID, $ids); + unset($ids); $memberships = $contribution->_relatedObjects['membership'] ?? []; $participant = $contribution->_relatedObjects['participant'] ?? []; @@ -2676,11 +2679,6 @@ INNER JOIN civicrm_activity ON civicrm_activity_contact.activity_id = civicrm_ac // This is a call we want to use less, in favour of loading related objects. $values = $this->addContributionPageValuesToValuesHeavyHandedly($values); if ($this->contribution_page_id) { - // This is precautionary as there are some legacy flows, but it should really be - // loaded by now. - if (!isset($this->_relatedObjects['contributionPage'])) { - $this->loadRelatedEntitiesByID(['contributionPage' => $this->contribution_page_id]); - } CRM_Contribute_BAO_Contribution_Utils::overrideDefaultCurrency($values); } } @@ -4563,9 +4561,6 @@ LIMIT 1;"; $entities = [ 'contact' => 'CRM_Contact_BAO_Contact', 'contributionRecur' => 'CRM_Contribute_BAO_ContributionRecur', - 'contributionType' => 'CRM_Financial_BAO_FinancialType', - 'financialType' => 'CRM_Financial_BAO_FinancialType', - 'contributionPage' => 'CRM_Contribute_BAO_ContributionPage', ]; foreach ($entities as $entity => $bao) { if (!empty($ids[$entity])) { diff --git a/civicrm/CRM/Contribute/BAO/ContributionPage.php b/civicrm/CRM/Contribute/BAO/ContributionPage.php index 43c88cfbbc..9945d10286 100644 --- a/civicrm/CRM/Contribute/BAO/ContributionPage.php +++ b/civicrm/CRM/Contribute/BAO/ContributionPage.php @@ -946,8 +946,10 @@ LEFT JOIN civicrm_premiums ON ( civicrm_premiums.entity_id = civicrm * * @return bool * isSeparateMembershipPayment + * @deprecated */ public static function getIsMembershipPayment($id) { + CRM_Core_Error::deprecatedFunctionWarning('api'); $membershipBlocks = civicrm_api3('membership_block', 'get', [ 'entity_table' => 'civicrm_contribution_page', 'entity_id' => $id, diff --git a/civicrm/CRM/Contribute/BAO/ContributionRecur.php b/civicrm/CRM/Contribute/BAO/ContributionRecur.php index 36f1c5b368..732ce892f5 100644 --- a/civicrm/CRM/Contribute/BAO/ContributionRecur.php +++ b/civicrm/CRM/Contribute/BAO/ContributionRecur.php @@ -230,6 +230,8 @@ class CRM_Contribute_BAO_ContributionRecur extends CRM_Contribute_DAO_Contributi * @param array $ids * (reference ) an array of recurring contribution ids. * + * @deprecated use the api. + * * @return array * an array of recurring ids count */ diff --git a/civicrm/CRM/Contribute/Form/AbstractEditPayment.php b/civicrm/CRM/Contribute/Form/AbstractEditPayment.php index 59c30d96ac..3c687182d1 100644 --- a/civicrm/CRM/Contribute/Form/AbstractEditPayment.php +++ b/civicrm/CRM/Contribute/Form/AbstractEditPayment.php @@ -86,18 +86,6 @@ class CRM_Contribute_Form_AbstractEditPayment extends CRM_Contact_Form_Task { */ protected $entity; - /** - * The id of the premium that we are proceessing. - * - * @var int - */ - public $_premiumID = NULL; - - /** - * @var CRM_Contribute_DAO_ContributionProduct - */ - public $_productDAO = NULL; - /** * The id of the note * @@ -351,23 +339,6 @@ class CRM_Contribute_Form_AbstractEditPayment extends CRM_Contact_Form_Task { CRM_Custom_Form_CustomData::setDefaultValues($this); } - /** - * @param int $id - * @todo - this function is a long way, non standard of saying $dao = new CRM_Contribute_DAO_ContributionProduct(); $dao->id = $id; $dao->find(); - */ - public function assignPremiumProduct($id) { - $sql = " -SELECT * -FROM civicrm_contribution_product -WHERE contribution_id = {$id} -"; - $dao = CRM_Core_DAO::executeQuery($sql); - if ($dao->fetch()) { - $this->_premiumID = $dao->id; - $this->_productDAO = $dao; - } - } - /** * @return array * Array of valid processors. The array resembles the DB table but also has 'object' as a key diff --git a/civicrm/CRM/Contribute/Form/Contribution.php b/civicrm/CRM/Contribute/Form/Contribution.php index 36df356ceb..e1fe1e7aef 100644 --- a/civicrm/CRM/Contribute/Form/Contribution.php +++ b/civicrm/CRM/Contribute/Form/Contribution.php @@ -2134,4 +2134,21 @@ class CRM_Contribute_Form_Contribution extends CRM_Contribute_Form_AbstractEditP return $this->getSubmittedValue('price_set_id'); } + /** + * @param int $id + * @todo - this function is a long way, non standard of saying $dao = new CRM_Contribute_DAO_ContributionProduct(); $dao->id = $id; $dao->find(); + */ + private function assignPremiumProduct($id): void { + $sql = " +SELECT * +FROM civicrm_contribution_product +WHERE contribution_id = {$id} +"; + $dao = CRM_Core_DAO::executeQuery($sql); + if ($dao->fetch()) { + $this->_premiumID = $dao->id; + $this->_productDAO = $dao; + } + } + } diff --git a/civicrm/CRM/Contribute/Form/Contribution/Confirm.php b/civicrm/CRM/Contribute/Form/Contribution/Confirm.php index 891ebcbc5b..e93b6ae706 100644 --- a/civicrm/CRM/Contribute/Form/Contribution/Confirm.php +++ b/civicrm/CRM/Contribute/Form/Contribution/Confirm.php @@ -568,8 +568,8 @@ class CRM_Contribute_Form_Contribution_Confirm extends CRM_Contribute_Form_Contr $this->buildCustom($this->_values['onbehalf_profile_id'], 'onbehalfProfile', TRUE, 'onbehalf', $fieldTypes); } - $this->_separateMembershipPayment = $this->get('separateMembershipPayment'); - $this->assign('is_separate_payment', $this->_separateMembershipPayment); + $this->_separateMembershipPayment = $this->isSeparateMembershipPayment(); + $this->assign('is_separate_payment', $this->isSeparateMembershipPayment()); $this->assign('priceSetID', $this->_priceSetId); @@ -1446,7 +1446,7 @@ class CRM_Contribute_Form_Contribution_Confirm extends CRM_Contribute_Form_Contr //enabled and contribution amount is not selected. fix for CRM-3010 $isPaidMembership = TRUE; } - $isProcessSeparateMembershipTransaction = $this->isSeparateMembershipTransaction($this->_id); + $isProcessSeparateMembershipTransaction = $this->isSeparateMembershipTransaction(); if ($this->isFormSupportsNonMembershipContributions()) { $financialTypeID = $this->_values['financial_type_id']; @@ -1728,8 +1728,8 @@ class CRM_Contribute_Form_Contribution_Confirm extends CRM_Contribute_Form_Contr 'is_transactional' => FALSE, 'fee_amount' => $result['result']['fee_amount'] ?? NULL, 'receive_date' => $result['result']['receive_date'] ?? NULL, - 'card_type_id' => $result['result']['card_type_id'] ?? NULL, - 'pan_truncation' => $result['result']['pan_truncation'] ?? NULL, + 'card_type_id' => $paymentParams['card_type_id'] ?? NULL, + 'pan_truncation' => $paymentParams['pan_truncation'] ?? NULL, ]); } catch (CRM_Core_Exception $e) { @@ -1911,16 +1911,14 @@ class CRM_Contribute_Form_Contribution_Confirm extends CRM_Contribute_Form_Contr * contribution * transaction AND a membership transaction AND the payment processor supports double financial transactions (ie. NOT doTransferCheckout style) * - * @param int $formID + * @todo - this is confusing - does isSeparateMembershipPayment need to + * check both conditions, making this redundant, or are there 2 legit + * variations here? * * @return bool */ - protected function isSeparateMembershipTransaction($formID): bool { - $memBlockDetails = CRM_Member_BAO_Membership::getMembershipBlock($formID); - if (!empty($memBlockDetails['is_separate_payment']) && $this->isFormSupportsNonMembershipContributions()) { - return TRUE; - } - return FALSE; + protected function isSeparateMembershipTransaction(): bool { + return $this->isSeparateMembershipPayment() && $this->isFormSupportsNonMembershipContributions(); } /** @@ -2004,7 +2002,7 @@ class CRM_Contribute_Form_Contribution_Confirm extends CRM_Contribute_Form_Contr $form->_id = $params['id']; CRM_Contribute_BAO_ContributionPage::setValues($form->_id, $form->_values); - $form->_separateMembershipPayment = CRM_Contribute_BAO_ContributionPage::getIsMembershipPayment($form->_id); + $form->_separateMembershipPayment = $form->isSeparateMembershipPayment(); //this way the mocked up controller ignores the session stuff $_SERVER['REQUEST_METHOD'] = 'GET'; $form->controller = new CRM_Contribute_Controller_Contribution(); @@ -2015,12 +2013,12 @@ class CRM_Contribute_Form_Contribution_Confirm extends CRM_Contribute_Form_Contr $order = new CRM_Financial_BAO_Order(); $order->setPriceSetIDByContributionPageID($params['id']); $order->setPriceSelectionFromUnfilteredInput($params); - if (isset($params['amount']) && !CRM_Contribute_BAO_ContributionPage::getIsMembershipPayment($form->_id)) { + if (isset($params['amount']) && !$form->isSeparateMembershipPayment()) { // @todo deprecate receiving amount, calculate on the form. $order->setOverrideTotalAmount((float) $params['amount']); } $amount = $order->getTotalAmount(); - if ($form->_separateMembershipPayment) { + if ($form->isSeparateMembershipPayment()) { $amount -= $order->getMembershipTotalAmount(); } $form->_amount = $params['amount'] = $form->_params['amount'] = $amount; @@ -2409,8 +2407,8 @@ class CRM_Contribute_Form_Contribution_Confirm extends CRM_Contribute_Form_Contr 'is_transactional' => FALSE, 'fee_amount' => $result['fee_amount'] ?? NULL, 'receive_date' => $result['receive_date'] ?? NULL, - 'card_type_id' => $result['card_type_id'] ?? NULL, - 'pan_truncation' => $result['pan_truncation'] ?? NULL, + 'card_type_id' => $paymentParams['card_type_id'] ?? NULL, + 'pan_truncation' => $paymentParams['pan_truncation'] ?? NULL, ]); } catch (CRM_Core_Exception $e) { @@ -2675,20 +2673,17 @@ class CRM_Contribute_Form_Contribution_Confirm extends CRM_Contribute_Form_Contr $isRecur ): array { $form = $this; - CRM_Core_Payment_Form::mapParams($form->_bltID, $form->_params, $paymentParams, TRUE); - $isPaymentTransaction = self::isPaymentTransaction($form); + CRM_Core_Payment_Form::mapParams($this->_bltID, $form->_params, $paymentParams, TRUE); + $isPaymentTransaction = self::isPaymentTransaction($this); $financialType = new CRM_Financial_DAO_FinancialType(); $financialType->id = $financialTypeID; $financialType->find(TRUE); - if ($financialType->is_deductible) { - $form->assign('is_deductible', TRUE); - $form->set('is_deductible', TRUE); - } + $this->assign('is_deductible', $financialType->is_deductible); // add some financial type details to the params list // if folks need to use it - $paymentParams['financial_type_id'] = $paymentParams['financialTypeID'] = $financialType->id; + $paymentParams['financial_type_id'] = $paymentParams['financialTypeID'] = $financialTypeID; //CRM-15297 - contributionType is obsolete - pass financial type as well so people can deprecate it $paymentParams['financialType_name'] = $paymentParams['contributionType_name'] = $form->_params['contributionType_name'] = $financialType->name; //CRM-11456 diff --git a/civicrm/CRM/Contribute/Form/Contribution/ThankYou.php b/civicrm/CRM/Contribute/Form/Contribution/ThankYou.php index 8887d38f7f..c5a510f621 100644 --- a/civicrm/CRM/Contribute/Form/Contribution/ThankYou.php +++ b/civicrm/CRM/Contribute/Form/Contribution/ThankYou.php @@ -41,8 +41,6 @@ class CRM_Contribute_Form_Contribution_ThankYou extends CRM_Contribute_Form_Cont $this->_params = $this->get('params'); $this->_lineItem = $this->get('lineItem'); $this->_useForMember = $this->get('useForMember'); - $is_deductible = $this->get('is_deductible'); - $this->assign('is_deductible', $is_deductible); $this->assign('thankyou_title', CRM_Utils_Array::value('thankyou_title', $this->_values)); $this->assign('thankyou_text', CRM_Utils_Array::value('thankyou_text', $this->_values)); $this->assign('thankyou_footer', CRM_Utils_Array::value('thankyou_footer', $this->_values)); diff --git a/civicrm/CRM/Contribute/Form/ContributionBase.php b/civicrm/CRM/Contribute/Form/ContributionBase.php index 024e262c0b..6b3b3b99f4 100644 --- a/civicrm/CRM/Contribute/Form/ContributionBase.php +++ b/civicrm/CRM/Contribute/Form/ContributionBase.php @@ -68,7 +68,10 @@ class CRM_Contribute_Form_ContributionBase extends CRM_Core_Form { /** * Does this form support a separate membership payment + * * @var bool + * + * @deprecated use $this->isSeparateMembershipPayment() function. */ protected $_separateMembershipPayment; @@ -1259,4 +1262,13 @@ class CRM_Contribute_Form_ContributionBase extends CRM_Core_Form { return $this->_membershipBlock; } + /** + * Is the contribution page configured for 2 payments, one being membership & one not. + * + * @return bool + */ + protected function isSeparateMembershipPayment(): bool { + return $this->getMembershipBlock() && $this->getMembershipBlock()['is_separate_payment']; + } + } diff --git a/civicrm/CRM/Contribute/Form/Search.php b/civicrm/CRM/Contribute/Form/Search.php index 90f7c9787a..c3f65c0c13 100644 --- a/civicrm/CRM/Contribute/Form/Search.php +++ b/civicrm/CRM/Contribute/Form/Search.php @@ -75,6 +75,8 @@ class CRM_Contribute_Form_Search extends CRM_Core_Form_Search { $this->_done = FALSE; parent::preProcess(); + // For contributionTotals.tpl + $this->addExpectedSmartyVariables(['annual']); $this->_queryParams = CRM_Contact_BAO_Query::convertFormValues($this->_formValues); $selector = new CRM_Contribute_Selector_Search($this->_queryParams, diff --git a/civicrm/CRM/Contribute/Form/Task/PDF.php b/civicrm/CRM/Contribute/Form/Task/PDF.php index f2a812cee7..df39acc994 100644 --- a/civicrm/CRM/Contribute/Form/Task/PDF.php +++ b/civicrm/CRM/Contribute/Form/Task/PDF.php @@ -244,14 +244,13 @@ AND {$this->_componentClause}"; $pdfElements = []; $pdfElements['details'] = self::getDetails(implode(',', $contribIds)); $excludeContactIds = []; + $suppressedEmails = 0; if (!$isCreatePDF) { $contactDetails = civicrm_api3('Contact', 'get', [ 'return' => ['email', 'do_not_email', 'is_deceased', 'on_hold'], 'id' => ['IN' => $contactIds], 'options' => ['limit' => 0], ])['values']; - $pdfElements['suppressedEmails'] = 0; - $suppressedEmails = 0; foreach ($contactDetails as $id => $values) { if (empty($values['email']) || (empty($params['override_privacy']) && !empty($values['do_not_email'])) @@ -259,11 +258,11 @@ AND {$this->_componentClause}"; || !empty($values['on_hold']) ) { $suppressedEmails++; - $pdfElements['suppressedEmails'] = $suppressedEmails; $excludeContactIds[] = $values['contact_id']; } } } + $pdfElements['suppressedEmails'] = $suppressedEmails; $pdfElements['excludeContactIds'] = $excludeContactIds; return $pdfElements; diff --git a/civicrm/CRM/Contribute/Import/Form/DataSource.php b/civicrm/CRM/Contribute/Import/Form/DataSource.php index c161cc6529..41d9e8e80e 100644 --- a/civicrm/CRM/Contribute/Import/Form/DataSource.php +++ b/civicrm/CRM/Contribute/Import/Form/DataSource.php @@ -20,10 +20,6 @@ */ class CRM_Contribute_Import_Form_DataSource extends CRM_Import_Form_DataSource { - const PATH = 'civicrm/contribute/import'; - - const IMPORT_ENTITY = 'Contribution'; - /** * Get the name of the type to be stored in civicrm_user_job.type_id. * diff --git a/civicrm/CRM/Contribute/Import/Parser/Contribution.php b/civicrm/CRM/Contribute/Import/Parser/Contribution.php index cd81fe127c..0a4705ff79 100644 --- a/civicrm/CRM/Contribute/Import/Parser/Contribution.php +++ b/civicrm/CRM/Contribute/Import/Parser/Contribution.php @@ -68,12 +68,6 @@ class CRM_Contribute_Import_Parser_Contribution extends CRM_Import_Parser { */ protected $_separator; - /** - * Total number of lines in file - * @var int - */ - protected $_lineCount; - /** * Running total number of valid soft credit rows * @var int @@ -238,7 +232,19 @@ class CRM_Contribute_Import_Parser_Contribution extends CRM_Import_Parser { $params[$entity][$this->getFieldMetadata($mappedField['name'])['name']] = $this->getTransformedFieldValue($mappedField['name'], $fieldValue); } } - return $params; + return $this->removeEmptyValues($params); + } + + protected function removeEmptyValues($array) { + foreach ($array as $key => $value) { + if (is_array($value)) { + $array[$key] = $this->removeEmptyValues($value); + } + elseif ($value === '') { + unset($array[$key]); + } + } + return $array; } /** @@ -465,7 +471,7 @@ class CRM_Contribute_Import_Parser_Contribution extends CRM_Import_Parser { if (!empty($softCreditParams)) { if (empty($contributionParams['total_amount']) || empty($contributionParams['currency'])) { - $contributionParams = Contribution::get()->addSelect('total_amount', 'currency')->addWhere('id', '=', $contributionID)->execute()->first(); + $contributionParams = array_merge($contributionParams, Contribution::get()->addSelect('total_amount', 'currency')->addWhere('id', '=', $contributionID)->execute()->first()); } foreach ($softCreditParams as $softCreditParam) { $softCreditParam['contribution_id'] = $contributionID; diff --git a/civicrm/CRM/Contribute/Page/UserDashboard.php b/civicrm/CRM/Contribute/Page/UserDashboard.php index 0a4c9f0fe1..96b94a18d7 100644 --- a/civicrm/CRM/Contribute/Page/UserDashboard.php +++ b/civicrm/CRM/Contribute/Page/UserDashboard.php @@ -9,6 +9,9 @@ +--------------------------------------------------------------------+ */ +use Civi\Api4\Contribution; +use Civi\Api4\ContributionRecur; + /** * * @package CRM @@ -18,112 +21,84 @@ class CRM_Contribute_Page_UserDashboard extends CRM_Contact_Page_View_UserDashBo /** * called when action is browse. + * + * @throws \CRM_Core_Exception */ - public function listContribution() { - $rows = civicrm_api3('Contribution', 'get', [ - 'options' => [ - 'limit' => 12, - 'sort' => 'receive_date DESC', - ], - 'sequential' => 1, - 'contact_id' => $this->_contactId, - 'return' => [ - 'total_amount', - 'contribution_recur_id', - 'financial_type', - 'receive_date', - 'receipt_date', - 'contribution_status', - 'currency', - 'amount_level', - 'contact_id,', - 'contribution_source', - ], - ])['values']; - - // We want oldest first, just among the most recent contributions - $rows = array_reverse($rows); + public function listContribution(): void { + $contributions = $this->getContributions(); - foreach ($rows as $index => &$row) { + foreach ($contributions as &$row) { // This is required for tpl logic. We should move away from hard-code this to adding an array of actions to the row // which the tpl can iterate through - this should allow us to cope with competing attempts to add new buttons // and allow extensions to assign new ones through the pageRun hook - $row['balance_amount'] = CRM_Contribute_BAO_Contribution::getContributionBalance($row['contribution_id']); - $contributionStatus = CRM_Core_PseudoConstant::getName('CRM_Contribute_BAO_Contribution', 'contribution_status_id', $row['contribution_status_id']); - - if (in_array($contributionStatus, ['Pending', 'Partially paid'])) { + // We could check for balance_amount > 0 here? It feels more correct but this seems to be working. + if (in_array($row['contribution_status_id:name'], ['Pending', 'Partially paid'], TRUE)) { $row['buttons']['pay'] = [ 'class' => 'button', 'label' => ts('Pay Now'), 'url' => CRM_Utils_System::url('civicrm/contribute/transact', [ 'reset' => 1, 'id' => Civi::settings()->get('default_invoice_page'), - 'ccid' => $row['contribution_id'], + 'ccid' => $row['id'], 'cs' => $this->getUserChecksum(), 'cid' => $row['contact_id'], ]), ]; } } + unset($row); - $this->assign('contribute_rows', $rows); + $this->assign('contribute_rows', $contributions); $this->assign('contributionSummary', ['total_amount' => civicrm_api3('Contribution', 'getcount', ['contact_id' => $this->_contactId])]); //add honor block - $params = CRM_Contribute_BAO_Contribution::getHonorContacts($this->_contactId); - - if (!empty($params)) { - // assign vars to templates - $this->assign('honorRows', $params); - $this->assign('honor', TRUE); - } + $softCreditContributions = $this->getContributions(TRUE); + $this->assign('soft_credit_contributions', $softCreditContributions); - $recur = new CRM_Contribute_DAO_ContributionRecur(); - $recur->contact_id = $this->_contactId; - $recur->is_test = 0; - $recur->find(); - - $recurStatus = CRM_Contribute_PseudoConstant::contributionStatus(NULL, 'label'); + $recurringContributions = (array) ContributionRecur::get(FALSE) + ->addWhere('contact_id', '=', $this->_contactId) + ->addWhere('is_test', '=', 0) + ->setSelect([ + '*', + 'contribution_status_id:label', + ])->execute(); $recurRow = []; $recurIDs = []; - while ($recur->fetch()) { - if (empty($recur->payment_processor_id)) { + foreach ($recurringContributions as $recur) { + if (empty($recur['payment_processor_id'])) { // it's not clear why we continue here as any without a processor id would likely // be imported from another system & still seem valid. continue; } - require_once 'api/v3/utils.php'; - //@todo calling api functions directly is not supported - _civicrm_api3_object_to_array($recur, $values); - - $values['recur_status'] = $recurStatus[$values['contribution_status_id']]; - $recurRow[$values['id']] = $values; + // Cast to something Smarty-friendly. + $recur['recur_status'] = $recur['contribution_status_id:label']; + $recurRow[$recur['id']] = $recur; - $action = array_sum(array_keys(CRM_Contribute_Page_Tab::dashboardRecurLinks((int) $recur->id, (int) $recur->contact_id))); + $action = array_sum(array_keys(CRM_Contribute_Page_Tab::dashboardRecurLinks((int) $recur['id'], (int) $recur['contact_id']))); - $details = CRM_Contribute_BAO_ContributionRecur::getSubscriptionDetails($recur->id, 'recur'); + $details = CRM_Contribute_BAO_ContributionRecur::getSubscriptionDetails($recur['id'], 'recur'); $hideUpdate = $details->membership_id & $details->auto_renew; if ($hideUpdate) { $action -= CRM_Core_Action::UPDATE; } - $recurRow[$values['id']]['action'] = CRM_Core_Action::formLink(CRM_Contribute_Page_Tab::dashboardRecurLinks((int) $recur->id, (int) $this->_contactId), + $recurRow[$recur['id']]['action'] = CRM_Core_Action::formLink(CRM_Contribute_Page_Tab::dashboardRecurLinks((int) $recur['id'], (int) $this->_contactId), $action, [ 'cid' => $this->_contactId, - 'crid' => $values['id'], + 'crid' => $recur['id'], 'cxt' => 'contribution', ], ts('more'), FALSE, 'contribution.dashboard.recurring', 'Contribution', - $values['id'] + $recur['id'] ); - $recurIDs[] = $values['id']; + $recurIDs[] = $recur['id']; } if (is_array($recurIDs) && !empty($recurIDs)) { $getCount = CRM_Contribute_BAO_ContributionRecur::getCount($recurIDs); @@ -136,12 +111,7 @@ class CRM_Contribute_Page_UserDashboard extends CRM_Contact_Page_View_UserDashBo } $this->assign('recurRows', $recurRow); - if (!empty($recurRow)) { - $this->assign('recur', TRUE); - } - else { - $this->assign('recur', FALSE); - } + } /** @@ -163,6 +133,8 @@ class CRM_Contribute_Page_UserDashboard extends CRM_Contact_Page_View_UserDashBo /** * the main function that is called when the page * loads, it decides the which action has to be taken for the page. + * + * @throws \CRM_Core_Exception */ public function run() { $this->assign('isIncludeInvoiceLinks', $this->isIncludeInvoiceLinks()); @@ -170,4 +142,59 @@ class CRM_Contribute_Page_UserDashboard extends CRM_Contact_Page_View_UserDashBo $this->listContribution(); } + /** + * Get the contact's contributions. + * + * @param bool $isSoftCredit + * Return contributions for which the contact is the soft credit contact instead. + * + * @return array + * @throws \CRM_Core_Exception + */ + protected function getContributions(bool $isSoftCredit = FALSE): array { + $apiQuery = Contribution::get(FALSE) + ->addOrderBy('receive_date', 'DESC') + ->setLimit(12) + ->setSelect([ + 'total_amount', + 'contribution_recur_id', + 'receive_date', + 'receipt_date', + 'cancel_date', + 'amount_level', + 'contact_id', + 'contact_id.display_name', + 'contribution_status_id:name', + 'contribution_status_id:label', + 'financial_type_id:label', + 'currency', + 'amount_level', + 'contact_id,', + 'source', + 'balance_amount', + 'id', + ]); + + if ($isSoftCredit) { + $apiQuery->addJoin('ContributionSoft AS contribution_soft', 'INNER'); + $apiQuery->addWhere('contribution_soft.contact_id', '=', $this->_contactId); + $apiQuery->addSelect('contribution_soft.soft_credit_type_id:label'); + } + else { + $apiQuery->addWhere('contact_id', '=', $this->_contactId); + } + $contributions = (array) $apiQuery->execute(); + foreach ($contributions as $index => $contribution) { + // QuickForm can't cope with the colons & dots ... cast to a legacy or simplified key. + $contributions[$index]['financial_type'] = $contribution['financial_type_id:label']; + $contributions[$index]['contribution_status'] = $contribution['contribution_status_id:label']; + $contributions[$index]['contribution_status_name'] = $contribution['contribution_status_id:name']; + $contributions[$index]['display_name'] = $contribution['contact_id.display_name']; + $contributions[$index]['soft_credit_type'] = $contribution['contribution_soft.soft_credit_type_id:label'] ?? NULL; + // Add in the api-v3 style naming just in case any extensions are still looking for it. + $contributions[$index]['contribution_id'] = $contribution['id']; + } + return $contributions; + } + } diff --git a/civicrm/CRM/Core/BAO/ActionSchedule.php b/civicrm/CRM/Core/BAO/ActionSchedule.php index 04c08c59a0..8307501bb6 100644 --- a/civicrm/CRM/Core/BAO/ActionSchedule.php +++ b/civicrm/CRM/Core/BAO/ActionSchedule.php @@ -631,7 +631,7 @@ FROM civicrm_action_schedule cas 'controller' => __CLASS__, 'actionSchedule' => $schedule, 'actionMapping' => $mapping, - 'smarty' => TRUE, + 'smarty' => Civi::settings()->get('scheduled_reminder_smarty'), 'schema' => ['contactId'], ]); $tp->addMessage('body_text', $schedule->body_text, 'text/plain'); diff --git a/civicrm/CRM/Core/BAO/Address.php b/civicrm/CRM/Core/BAO/Address.php index e44f9c90d2..004922b0d3 100644 --- a/civicrm/CRM/Core/BAO/Address.php +++ b/civicrm/CRM/Core/BAO/Address.php @@ -15,6 +15,8 @@ * @copyright CiviCRM LLC https://civicrm.org/licensing */ +use Civi\Api4\Address; + /** * This is class to handle address related functions. */ @@ -33,12 +35,8 @@ class CRM_Core_BAO_Address extends CRM_Core_DAO_Address { * @return array|NULL|self * array of created address */ - public static function create(&$params, $fixAddress = TRUE) { - if (!isset($params['address']) || !is_array($params['address'])) { - return self::add($params, $fixAddress); - } - CRM_Core_Error::deprecatedFunctionWarning('Use legacyCreate if not doing a single crud action'); - return self::legacyCreate($params, $fixAddress); + public static function create(array &$params, $fixAddress = TRUE) { + return self::add($params, $fixAddress); } /** @@ -1212,6 +1210,7 @@ SELECT is_primary, * @return bool */ public static function del($id) { + CRM_Core_Error::deprecatedFunctionWarning('deleteRecord'); return (bool) self::deleteRecord(['id' => $id]); } @@ -1362,8 +1361,7 @@ SELECT is_primary, // BUT info is not present at this time, and therefore we should be really careful when deleting the block. // $updateBlankLocInfo will help take appropriate decision. CRM-5969 if (isset($value['id']) && !$addressExists && $updateBlankLocInfo) { - //delete the existing record - CRM_Core_BAO_Block::blockDelete('Address', ['id' => $value['id']]); + Address::delete(FALSE)->addWhere('id', '=', $value['id'])->execute(); continue; } elseif (!$addressExists) { diff --git a/civicrm/CRM/Core/BAO/Block.php b/civicrm/CRM/Core/BAO/Block.php index d508251306..506e951576 100644 --- a/civicrm/CRM/Core/BAO/Block.php +++ b/civicrm/CRM/Core/BAO/Block.php @@ -264,7 +264,7 @@ class CRM_Core_BAO_Block { // $updateBlankLocInfo will help take appropriate decision. CRM-5969 if (!empty($value['id']) && !$dataExists && $updateBlankLocInfo) { //delete the existing record - $baoString::del($value['id']); + $baoString::deleteRecord($value); continue; } elseif (!$dataExists) { @@ -307,7 +307,7 @@ class CRM_Core_BAO_Block { } $baoString = 'CRM_Core_BAO_' . $name; - $baoString::del($params['id']); + $baoString::deleteRecord($params); } /** @@ -457,7 +457,7 @@ class CRM_Core_BAO_Block { * @param array $locations */ public static function sortPrimaryFirst(&$locations) { - uasort($locations, 'self::primaryComparison'); + uasort($locations, [__CLASS__, 'primaryComparison']); } /** diff --git a/civicrm/CRM/Core/BAO/CustomField.php b/civicrm/CRM/Core/BAO/CustomField.php index 7f4aed8d55..cf05c109b2 100644 --- a/civicrm/CRM/Core/BAO/CustomField.php +++ b/civicrm/CRM/Core/BAO/CustomField.php @@ -15,6 +15,9 @@ * @copyright CiviCRM LLC https://civicrm.org/licensing */ +use Civi\Api4\CustomField; +use Civi\Api4\Utils\CoreUtil; + /** * Business objects for managing custom data fields. */ @@ -95,6 +98,11 @@ class CRM_Core_BAO_CustomField extends CRM_Core_DAO_CustomField { 'name' => 'Contact Reference', 'label' => ts('Contact Reference'), ], + [ + 'id' => 'EntityReference', + 'name' => 'Entity Reference', + 'label' => ts('Entity Reference'), + ], ]; } @@ -118,6 +126,7 @@ class CRM_Core_BAO_CustomField extends CRM_Core_DAO_CustomField { 'File' => CRM_Utils_Type::T_STRING, 'Link' => CRM_Utils_Type::T_STRING, 'ContactReference' => CRM_Utils_Type::T_INT, + 'EntityReference' => CRM_Utils_Type::T_INT, 'Country' => CRM_Utils_Type::T_INT, ]; } @@ -610,6 +619,83 @@ class CRM_Core_BAO_CustomField extends CRM_Core_DAO_CustomField { return self::$_importFields[$cacheKey]; } + /** + * Get all active custom fields (cached wrapper). + * + * @param false|int $permissionType + * - Either FALSE (do not check) or CRM_Core_Permission::VIEW or CRM_Core_Permission::EDIT + * + * @return array + * List of customField details keyed by customFieldID + * @throws \CRM_Core_Exception + */ + public static function getAllCustomFields($permissionType): array { + if ($permissionType !== FALSE && !is_int($permissionType)) { + throw new CRM_Core_Exception('permissionCheck must be FALSE or CRM_Core_Permission::VIEW or CRM_Core_Permission::EDIT'); + } + $cacheString = __CLASS__ . __FUNCTION__ . CRM_Core_Config::domainID() . '_' . CRM_Core_I18n::getLocale(); + if ($permissionType) { + $cacheString .= 'check_' . $permissionType . '_user_' . CRM_Core_Session::getLoggedInContactID(); + } + if (!Civi::cache('metadata')->has($cacheString)) { + $apiCall = CustomField::get(FALSE) + ->addOrderBy('custom_group_id.title') + ->addOrderBy('custom_group_id.weight') + ->addOrderBy('weight') + ->addOrderBy('label') + ->addSelect('*') + ->addSelect('custom_group_id.extends') + ->addSelect('custom_group_id.extends_entity_column_id') + ->addSelect('custom_group_id.extends_entity_column_value') + ->addSelect('custom_group_id.is_active') + ->addSelect('custom_group_id.name') + ->addSelect('custom_group_id.table_name') + ->addSelect('custom_group_id.is_public'); + if ($permissionType && !CRM_Core_Permission::customGroupAdmin()) { + $availableGroups = CRM_Core_Permission::customGroup($permissionType); + $apiCall->addWhere('custom_group_id', 'IN', empty($availableGroups) ? [0] : $availableGroups); + } + + $types = (array) $apiCall->execute()->indexBy('id'); + + Civi::cache('metadata')->set($cacheString, $types); + } + return Civi::cache('metadata')->get($cacheString); + } + + /** + * Get all active custom fields for the given contact type. + * + * This is formatted as an apiv4 Style array. + * + * @param string $contactType + * @param bool|int $permissionType + * - Either FALSE (do not check) or CRM_Core_Permission::VIEW or CRM_Core_Permission::EDIT + * @param array $contactSubTypes + * + * @return array $fields + * + * @throws \CRM_Core_Exception + */ + public static function getCustomFieldsForContactType(string $contactType, $permissionType, array $contactSubTypes = []): array { + $fields = []; + foreach (self::getAllCustomFields($permissionType) as $field) { + if ($field['custom_group_id.extends'] === $contactType || $field['custom_group_id.extends'] === 'Contact') { + if (empty($contactSubTypes) || empty($field['custom_group_id.extends_entity_column_value'])) { + $fields[$field['id']] = $field; + } + else { + foreach ($contactSubTypes as $contactSubType) { + if (in_array($contactSubType, $field['custom_group_id.extends_entity_column_value'], TRUE)) { + $fields[$field['id']] = $field; + } + } + } + } + } + return $fields; + } + /** * Return field ids and names (with groups). * @@ -725,7 +811,6 @@ class CRM_Core_BAO_CustomField extends CRM_Core_DAO_CustomField { if (!$field->find(TRUE)) { throw new CRM_Core_Exception('Cannot find Custom Field ' . $fieldID); } - $fieldValues = []; CRM_Core_DAO::storeValues($field, $fieldValues); @@ -983,6 +1068,10 @@ class CRM_Core_BAO_CustomField extends CRM_Core_DAO_CustomField { ); } + elseif ($field->data_type == 'EntityReference') { + $fieldAttributes['entity'] = $field->fk_entity; + $element = $qf->addAutocomplete($elementName, $label, $fieldAttributes, $useRequired && !$search); + } else { // FIXME: This won't work with customFieldOptions hook $fieldAttributes += [ @@ -1162,7 +1251,19 @@ class CRM_Core_BAO_CustomField extends CRM_Core_DAO_CustomField { $display = implode(', ', $displayNames); } } - elseif ($field['data_type'] == 'ContactReference') { + elseif ($field['data_type'] == 'EntityReference' && $value) { + try { + $result = civicrm_api4($field['fk_entity'], 'autocomplete', [ + 'checkPermissions' => FALSE, + 'ids' => [$value], + ]); + $display = $result->single()['label']; + } + catch (CRM_Core_Exception $e) { + $display = ''; + } + } + elseif (in_array($field['data_type'], ['ContactReference', 'EntityReference'])) { $display = $value; } elseif (is_array($value)) { @@ -2384,7 +2485,7 @@ WHERE option_group_id = {$optionGroupId}"; if ($count < 2) { //delete the option group - CRM_Core_BAO_OptionGroup::del($optionGroupId); + CRM_Core_BAO_OptionGroup::deleteRecord(['id' => $optionGroupId]); } } @@ -2693,7 +2794,7 @@ WHERE cf.id = %1 AND cg.is_multiple = 1"; } // Do this before the "Select" string search because date fields have a "Select Date" html_type // and contactRef fields have an "Autocomplete-Select" html_type - contacts are an FK not an option list. - if (in_array($field['data_type'], ['ContactReference', 'Date'])) { + if (in_array($field['data_type'], ['EntityReference', 'ContactReference', 'Date'])) { return FALSE; } if (strpos($field['html_type'], 'Select') !== FALSE) { @@ -2803,6 +2904,7 @@ WHERE cf.id = %1 AND cg.is_multiple = 1"; 'StateProvince' => 'civicrm_state_province', 'ContactReference' => 'civicrm_contact', 'File' => 'civicrm_file', + 'EntityReference' => CoreUtil::getInfoItem((string) $field->fk_entity, 'table_name'), ]; if (isset($fkFields[$field->data_type])) { // Serialized fields store value-separated strings which are incompatible with FK constraints diff --git a/civicrm/CRM/Core/BAO/CustomValueTable.php b/civicrm/CRM/Core/BAO/CustomValueTable.php index 9ba11ab1a0..2312c81847 100644 --- a/civicrm/CRM/Core/BAO/CustomValueTable.php +++ b/civicrm/CRM/Core/BAO/CustomValueTable.php @@ -203,6 +203,10 @@ class CRM_Core_BAO_CustomValueTable { } break; + case 'EntityReference': + $type = 'Integer'; + break; + case 'RichTextEditor': $type = 'String'; break; @@ -315,6 +319,7 @@ class CRM_Core_BAO_CustomValueTable { // the below three are FK's, and have constraints added to them case 'ContactReference': + case 'EntityReference': case 'StateProvince': case 'Country': case 'File': diff --git a/civicrm/CRM/Core/BAO/Email.php b/civicrm/CRM/Core/BAO/Email.php index 0f5ce64671..e7e4eb9a1d 100644 --- a/civicrm/CRM/Core/BAO/Email.php +++ b/civicrm/CRM/Core/BAO/Email.php @@ -355,6 +355,7 @@ AND reset_date IS NULL * @return bool */ public static function del($id) { + CRM_Core_Error::deprecatedFunctionWarning('deleteRecord'); return (bool) self::deleteRecord(['id' => $id]); } diff --git a/civicrm/CRM/Core/BAO/IM.php b/civicrm/CRM/Core/BAO/IM.php index a410e91274..b1a916c374 100644 --- a/civicrm/CRM/Core/BAO/IM.php +++ b/civicrm/CRM/Core/BAO/IM.php @@ -163,6 +163,7 @@ ORDER BY cim.is_primary DESC, im_id ASC "; * @return bool */ public static function del($id) { + CRM_Core_Error::deprecatedFunctionWarning('deleteRecord'); return (bool) self::deleteRecord(['id' => $id]); } diff --git a/civicrm/CRM/Core/BAO/Location.php b/civicrm/CRM/Core/BAO/Location.php index 6ded754996..628551677a 100644 --- a/civicrm/CRM/Core/BAO/Location.php +++ b/civicrm/CRM/Core/BAO/Location.php @@ -222,44 +222,6 @@ WHERE e.id = %1"; ]; } - /** - * Delete all the block associated with the location. - * - * Note a universe search on 1 Oct 2020 found no calls to this function. - * - * @deprecated - * - * @param int $contactId - * Contact id. - * @param int $locationTypeId - * Id of the location to delete. - * @throws CRM_Core_Exception - */ - public static function deleteLocationBlocks($contactId, $locationTypeId) { - CRM_Core_Error::deprecatedFunctionWarning('Use v4 api'); - // ensure that contactId has a value - if (empty($contactId) || - !CRM_Utils_Rule::positiveInteger($contactId) - ) { - throw new CRM_Core_Exception('Incorrect contact id parameter passed to deleteLocationBlocks'); - } - - if (empty($locationTypeId) || - !CRM_Utils_Rule::positiveInteger($locationTypeId) - ) { - // so we only delete the blocks which DO NOT have a location type Id - // CRM-3581 - $locationTypeId = 'null'; - } - - static $blocks = ['Address', 'Phone', 'IM', 'OpenID', 'Email']; - - $params = ['contact_id' => $contactId, 'location_type_id' => $locationTypeId]; - foreach ($blocks as $name) { - CRM_Core_BAO_Block::blockDelete($name, $params); - } - } - /** * Make sure contact should have only one primary block, CRM-5051. * diff --git a/civicrm/CRM/Core/BAO/Log.php b/civicrm/CRM/Core/BAO/Log.php index 3d10a68537..e6e83aac4d 100644 --- a/civicrm/CRM/Core/BAO/Log.php +++ b/civicrm/CRM/Core/BAO/Log.php @@ -89,9 +89,9 @@ class CRM_Core_BAO_Log extends CRM_Core_DAO_Log { } if (!$userID) { - $api_key = CRM_Utils_Request::retrieve('api_key', 'String', $store, FALSE, NULL, 'REQUEST'); + $api_key = CRM_Utils_Request::retrieve('api_key', 'String'); - if ($api_key && strtolower($api_key) != 'null') { + if ($api_key && strtolower($api_key) !== 'null') { $userID = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact', $api_key, 'id', 'api_key'); } } diff --git a/civicrm/CRM/Core/BAO/OptionGroup.php b/civicrm/CRM/Core/BAO/OptionGroup.php index 09e2169423..c7de6d7eea 100644 --- a/civicrm/CRM/Core/BAO/OptionGroup.php +++ b/civicrm/CRM/Core/BAO/OptionGroup.php @@ -52,18 +52,14 @@ class CRM_Core_BAO_OptionGroup extends CRM_Core_DAO_OptionGroup implements \Civi * Add the Option Group. * * @param array $params - * Reference array contains the values submitted by the form. - * @param array $ids - * Reference array contains the id. * * @deprecated * @return CRM_Core_DAO_OptionGroup */ - public static function add(&$params, $ids = []) { - if (empty($params['id']) && !empty($ids['optionGroup'])) { - CRM_Core_Error::deprecatedFunctionWarning('no $ids array'); - $params['id'] = $ids['optionGroup']; - } + public static function add($params) { + // This is very similar to CRM_Core_DAO::makeNameFromLabel which would be + // called automatically via `self::writeRecord()` + // TODO: Check if the differences matter, then deprecate this function and switch to writeRecord. if (empty($params['name']) && empty($params['id'])) { $params['name'] = CRM_Utils_String::titleToVar(strtolower($params['title'])); } diff --git a/civicrm/CRM/Core/BAO/Phone.php b/civicrm/CRM/Core/BAO/Phone.php index 3ed91d733b..cf095fa29a 100644 --- a/civicrm/CRM/Core/BAO/Phone.php +++ b/civicrm/CRM/Core/BAO/Phone.php @@ -236,6 +236,7 @@ ORDER BY ph.is_primary DESC, phone_id ASC "; * @return bool */ public static function del($id) { + CRM_Core_Error::deprecatedFunctionWarning('deleteRecord'); return (bool) self::deleteRecord(['id' => $id]); } diff --git a/civicrm/CRM/Core/BAO/SchemaHandler.php b/civicrm/CRM/Core/BAO/SchemaHandler.php index 0ee0b27c4c..a58dd8c482 100644 --- a/civicrm/CRM/Core/BAO/SchemaHandler.php +++ b/civicrm/CRM/Core/BAO/SchemaHandler.php @@ -547,23 +547,23 @@ MODIFY {$columnName} varchar( $length ) /** * Check if a foreign key Exists + * * @param string $table_name * @param string $constraint_name + * * @return bool TRUE if FK is found */ - public static function checkFKExists($table_name, $constraint_name) { - $dao = new CRM_Core_DAO(); + public static function checkFKExists(string $table_name, string $constraint_name): bool { $query = " SELECT CONSTRAINT_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS - WHERE TABLE_SCHEMA = %1 - AND TABLE_NAME = %2 - AND CONSTRAINT_NAME = %3 + WHERE TABLE_SCHEMA = DATABASE() + AND TABLE_NAME = %1 + AND CONSTRAINT_NAME = %2 AND CONSTRAINT_TYPE = 'FOREIGN KEY' "; $params = [ - 1 => [$dao->_database, 'String'], - 2 => [$table_name, 'String'], - 3 => [$constraint_name, 'String'], + 1 => [$table_name, 'String'], + 2 => [$constraint_name, 'String'], ]; $dao = CRM_Core_DAO::executeQuery($query, $params, TRUE, NULL, FALSE, FALSE); diff --git a/civicrm/CRM/Core/BAO/UFField.php b/civicrm/CRM/Core/BAO/UFField.php index e43bc4a25e..ae8a9dd907 100644 --- a/civicrm/CRM/Core/BAO/UFField.php +++ b/civicrm/CRM/Core/BAO/UFField.php @@ -285,12 +285,15 @@ WHERE cf.id IN (" . $customFieldIds . ") AND is_multiple = 1 LIMIT 0,1"; * Copy existing profile fields to * new profile from the already built profile * + * @deprecated + * * @param int $old_id * From which we need to copy. * @param bool $new_id * In which to copy. */ public static function copy($old_id, $new_id) { + CRM_Core_Error::deprecatedFunctionWarning(''); $ufField = new CRM_Core_DAO_UFField(); $ufField->uf_group_id = $old_id; $ufField->find(); diff --git a/civicrm/CRM/Core/BAO/UFMatch.php b/civicrm/CRM/Core/BAO/UFMatch.php index 831a70ee70..5734a9c239 100644 --- a/civicrm/CRM/Core/BAO/UFMatch.php +++ b/civicrm/CRM/Core/BAO/UFMatch.php @@ -47,10 +47,10 @@ class CRM_Core_BAO_UFMatch extends CRM_Core_DAO_UFMatch { /** * Given a UF user object, make sure there is a contact * object for this user. If the user has new values, we need - * to update the CRM DB with the new values + * to update the CRM DB with the new values. * * @param Object $user - * The drupal user object. + * The user object. * @param bool $update * Has the user object been edited. * @param $uf @@ -71,9 +71,8 @@ class CRM_Core_BAO_UFMatch extends CRM_Core_DAO_UFMatch { $userSystemID = $userSystem->getBestUFID($user); $uniqId = $userSystem->getBestUFUniqueIdentifier($user); - // if the id of the object is zero (true for anon users in drupal) - // have we already processed this user, if so early - // return. + // If the id of the object is zero (true for anon users in Drupal), + // have we already processed this user? If so return early. $userID = $session->get('userID'); $ufID = $session->get('ufID'); @@ -81,14 +80,14 @@ class CRM_Core_BAO_UFMatch extends CRM_Core_DAO_UFMatch { return; } - //check do we have logged in user. + // Check do we have logged in user. $isUserLoggedIn = CRM_Utils_System::isUserLoggedIn(); - // reset the session if we are a different user + // Reset the session if we are a different user. if ($ufID && $ufID != $userSystemID) { $session->reset(); - //get logged in user ids, and set to session. + // Get logged in user ids, and set to session. if ($isUserLoggedIn) { $userIds = self::getUFValues(); $session->set('ufID', CRM_Utils_Array::value('uf_id', $userIds, '')); @@ -96,7 +95,7 @@ class CRM_Core_BAO_UFMatch extends CRM_Core_DAO_UFMatch { } } - // return early + // Return early. if ($userSystemID == 0) { return; } @@ -106,12 +105,12 @@ class CRM_Core_BAO_UFMatch extends CRM_Core_DAO_UFMatch { return; } - //make sure we have session w/ consistent ids. + // Make sure we have session w/ consistent ids. $ufID = $ufmatch->uf_id; $userID = $ufmatch->contact_id; if ($isUserLoggedIn) { $loggedInUserUfID = CRM_Utils_System::getLoggedInUfID(); - //are we processing logged in user. + // Are we processing logged in user. if ($loggedInUserUfID && $loggedInUserUfID != $ufID) { $userIds = self::getUFValues($loggedInUserUfID); $ufID = CRM_Utils_Array::value('uf_id', $userIds, ''); @@ -119,11 +118,11 @@ class CRM_Core_BAO_UFMatch extends CRM_Core_DAO_UFMatch { } } - //set user ids to session. + // Set user ids to session. $session->set('ufID', $ufID); $session->set('userID', $userID); - // add current contact to recently viewed + // Add current contact to recently viewed. if ($ufmatch->contact_id) { [$displayName, $contactImage, $contactType, $contactSubtype, $contactImageUrl] = CRM_Contact_BAO_Contact::getDisplayAndImage($ufmatch->contact_id, TRUE, TRUE); @@ -146,11 +145,10 @@ class CRM_Core_BAO_UFMatch extends CRM_Core_DAO_UFMatch { } /** - * Synchronize the object with the UF Match entry. Can be called stand-alone from - * the drupalUsers script + * Synchronize the object with the UF Match entry. * * @param Object $user - * The drupal user object. + * The user object. * @param string $userKey * The id of the user from the uf object. * @param string $uniqId @@ -169,7 +167,7 @@ class CRM_Core_BAO_UFMatch extends CRM_Core_DAO_UFMatch { $config = CRM_Core_Config::singleton(); $newContact = FALSE; - // make sure that a contact id exists for this user id + // Make sure that a contact id exists for this user id. $ufmatch = new CRM_Core_DAO_UFMatch(); $ufmatch->domain_id = CRM_Core_Config::domainID(); $ufmatch->uf_id = $userKey; @@ -181,9 +179,12 @@ class CRM_Core_BAO_UFMatch extends CRM_Core_DAO_UFMatch { if (!empty($_POST) && !$isLogin) { $dedupeParameters = $_POST; $dedupeParameters['email'] = $uniqId; - // dev/core#1858 Ensure that if we have a contactID parameter which is set in the Create user Record contact task form - // That this contactID value is passed through as the contact_id to the get duplicate contacts function. This is necessary because for Drupal 8 this function gets invoked - // Before the civicrm_uf_match record is added where as in D7 it isn't called until the user tries to actually login. + // dev/core#1858 Ensure that if we have a contactID parameter which is + // set in the Create user Record contact task form. That this contactID + // value is passed through as the contact_id to the get duplicate + // contacts function. This is necessary because for Drupal 8 this + // function gets invoked. Before the civicrm_uf_match record is added + // where as in D7 it isn't called until the user tries to actually login. if (!empty($dedupeParameters['contactID'])) { $dedupeParameters['contact_id'] = $dedupeParameters['contactID']; } @@ -191,14 +192,14 @@ class CRM_Core_BAO_UFMatch extends CRM_Core_DAO_UFMatch { $ids = CRM_Contact_BAO_Contact::getDuplicateContacts($dedupeParameters, 'Individual', 'Unsupervised', [], FALSE); if (!empty($ids) && Civi::settings()->get('uniq_email_per_site')) { - // restrict dupeIds to ones that belong to current domain/site. + // Restrict dupeIds to ones that belong to current domain/site. $siteContacts = CRM_Core_BAO_Domain::getContactList(); foreach ($ids as $index => $dupeId) { if (!in_array($dupeId, $siteContacts)) { unset($ids[$index]); } } - // re-index the array + // Re-index the array. $ids = array_values($ids); } if (!empty($ids)) { @@ -212,9 +213,8 @@ class CRM_Core_BAO_UFMatch extends CRM_Core_DAO_UFMatch { $found = FALSE; if ($dao) { - // ensure there does not exists a contact_id / uf_id pair - // in the DB. This might be due to multiple emails per contact - // CRM-9091 + // Ensure there does not exists a contact_id / uf_id pair in the DB. + // This might be due to multiple emails per contact CRM-9091. $sql = ' SELECT id FROM civicrm_uf_match @@ -235,24 +235,10 @@ AND domain_id = %2 } if (!$found) { - $contactParameters = []; - // Not sure why we're testing for this. Is there ever a case - // in which $user is not an object? - if (is_object($user)) { - if ($config->userSystem->is_drupal) { - $primary_email = $uniqId; - } - elseif ($uf === 'WordPress') { - $primary_email = $user->user_email; - } - else { - $primary_email = $user->email; - } - $contactParameters['email'] = $primary_email; - } - else { - CRM_Core_Error::deprecatedWarning('please log how you hit this...'); - } + $contactParameters = $config->userSystem->getContactDetailsFromUser([ + 'user' => $user, + 'uniqId' => $uniqId, + ]); if ($ctype === 'Organization') { $contactParameters['organization_name'] = $uniqId; @@ -263,30 +249,15 @@ AND domain_id = %2 $contactParameters['contact_type'] = $ctype ?? 'Individual'; - // extract first / middle / last name - // for joomla - if ($uf === 'Joomla' && $user->name) { - CRM_Utils_String::extractName($user->name, $contactParameters); - } - - if ($uf === 'WordPress') { - if ($user->first_name) { - $contactParameters['first_name'] = $user->first_name; - } - - if ($user->last_name) { - $contactParameters['last_name'] = $user->last_name; - } - } - $contactID = civicrm_api3('Contact', 'create', $contactParameters)['id']; $ufmatch->contact_id = $contactID; $ufmatch->uf_name = $uniqId; } - // check that there are not two CMS IDs matching the same CiviCRM contact - this happens when a civicrm - // user has two e-mails and there is a cms match for each of them - // the gets rid of the nasty fata error but still reports the error + // Check that there are not two CMS IDs matching the same CiviCRM contact. + // This happens when a CiviCRM user has two e-mails and there is a cms + // match for each of them the gets rid of the nasty fata error but still + // reports the error. $sql = " SELECT uf_id FROM civicrm_uf_match @@ -340,7 +311,7 @@ AND domain_id = %4 return; } - // 1.do check for contact Id. + // 1. Do check for contact Id. $ufmatch = new CRM_Core_DAO_UFMatch(); $ufmatch->contact_id = $contactId; $ufmatch->domain_id = CRM_Core_Config::domainID(); @@ -362,7 +333,7 @@ AND domain_id = %4 } // CRM-6928 - // 2.do check for duplicate ufName. + // 2. Do check for duplicate ufName. $ufDupeName = new CRM_Core_DAO_UFMatch(); $ufDupeName->uf_name = $ufName; $ufDupeName->domain_id = CRM_Core_Config::domainID(); @@ -376,7 +347,7 @@ AND domain_id = %4 return; } - // save the updated ufmatch object + // Save the updated ufmatch object. $ufmatch->uf_name = $ufName; $ufmatch->save(); $config->userSystem->updateCMSName($ufmatch->uf_id, $ufName); @@ -398,22 +369,23 @@ AND domain_id = %4 $ufmatch->contact_id = $contactId; $ufmatch->domain_id = CRM_Core_Config::domainID(); if ($ufmatch->find(TRUE)) { - // Save the email in UF Match table + // Save the email in UF Match table. $ufmatch->uf_name = $emailAddress; CRM_Core_BAO_UFMatch::create((array) $ufmatch); - // If CMS integration is disabled skip Civi email update if CMS user email is changed + // If CMS integration is disabled skip Civi email update if CMS user email + // is changed. if (Civi::settings()->get('syncCMSEmail') == FALSE) { return; } - //check if the primary email for the contact exists - //$contactDetails[1] - email - //$contactDetails[3] - email id + // Check if the primary email for the contact exists. + // $contactDetails[1] - email + // $contactDetails[3] - email id $contactDetails = CRM_Contact_BAO_Contact_Location::getEmailDetails($contactId); if (trim($contactDetails[1])) { - //update if record is found but different + // Update if record is found but different. $emailID = $contactDetails[3]; if (trim($contactDetails[1]) != $emailAddress) { civicrm_api3('Email', 'create', [ @@ -423,7 +395,7 @@ AND domain_id = %4 } } else { - //else insert a new email record + // Else insert a new email record. $result = civicrm_api3('Email', 'create', [ 'contact_id' => $contactId, 'email' => $emailAddress, @@ -452,7 +424,7 @@ AND domain_id = %4 $ufmatch->domain_id = $domainId = CRM_Core_Config::domainID(); $ufmatch->delete(); - // Flush cache + // Flush cache. Civi::$statics[__CLASS__][$domainId] = []; } @@ -463,7 +435,7 @@ AND domain_id = %4 * Id of UF for which related contact_id is required. * * @return int|null - * contact_id on success, null otherwise + * contact_id on success, null otherwise. */ public static function getContactId($ufID) { if (!$ufID) { @@ -496,7 +468,7 @@ AND domain_id = %4 * ID of the contact for which related uf_id is required. * * @return int|null - * uf_id of the given contact_id on success, null otherwise + * uf_id of the given contact_id on success, null otherwise. */ public static function getUFId($contactID) { if (!$contactID) { @@ -532,7 +504,7 @@ AND domain_id = %4 * * @deprecated * @return int - * contact_id on success, null otherwise + * contact_id on success, null otherwise. */ public static function getContactIDs() { CRM_Core_Error::deprecatedFunctionWarning('unused function to be removed'); @@ -567,11 +539,11 @@ AND domain_id = %4 /** * Get the next unused uf_id value, since the standalone UF doesn't - * have id's (it uses OpenIDs, which go in a different field) + * have id's (it uses OpenIDs, which go in a different field). * * @deprecated * @return int - * next highest unused value for uf_id + * Next highest unused value for uf_id. */ public static function getNextUfIdValue() { CRM_Core_Error::deprecatedFunctionWarning('unused function to be removed'); @@ -588,7 +560,9 @@ AND domain_id = %4 } /** - * @param $email + * Is duplicate user + * + * @param string $email * @deprecated * @return bool */ @@ -644,7 +618,7 @@ AND domain_id = %4 * @inheritDoc */ public function addSelectWhereClause() { - // Prevent default behavior of joining ACLs onto the contact_id field + // Prevent default behavior of joining ACLs onto the contact_id field. $clauses = []; CRM_Utils_Hook::selectWhereClause($this, $clauses); return $clauses; diff --git a/civicrm/CRM/Core/BAO/Website.php b/civicrm/CRM/Core/BAO/Website.php index aafd8e8a51..14c740d694 100644 --- a/civicrm/CRM/Core/BAO/Website.php +++ b/civicrm/CRM/Core/BAO/Website.php @@ -31,6 +31,7 @@ class CRM_Core_BAO_Website extends CRM_Core_DAO_Website { * @throws \CRM_Core_Exception */ public static function create($params) { + CRM_Core_Error::deprecatedFunctionWarning('writeRecord'); return self::writeRecord($params); } @@ -81,7 +82,7 @@ class CRM_Core_BAO_Website extends CRM_Core_DAO_Website { } if (!empty($values['url'])) { $values['contact_id'] = $contactID; - self::create($values); + self::writeRecord($values); } elseif ($skipDelete && !empty($values['id'])) { static::deleteRecord($values); @@ -99,6 +100,7 @@ class CRM_Core_BAO_Website extends CRM_Core_DAO_Website { * @deprecated */ public static function del($id) { + CRM_Core_Error::deprecatedFunctionWarning('deleteRecord'); return (bool) static::deleteRecord(['id' => $id]); } diff --git a/civicrm/CRM/Core/ClassLoader.php b/civicrm/CRM/Core/ClassLoader.php index 0501e6bdac..b92512ad36 100644 --- a/civicrm/CRM/Core/ClassLoader.php +++ b/civicrm/CRM/Core/ClassLoader.php @@ -65,6 +65,7 @@ class CRM_Core_ClassLoader { 'CiviTestSuite', 'CiviUnitTestCase', 'CiviEndToEndTestCase', + 'CiviSimpleCacheTest', 'Contact', 'ContributionPage', 'Custom', diff --git a/civicrm/CRM/Core/Config.php b/civicrm/CRM/Core/Config.php index 795f95576e..415762ce4a 100644 --- a/civicrm/CRM/Core/Config.php +++ b/civicrm/CRM/Core/Config.php @@ -363,12 +363,10 @@ class CRM_Core_Config extends CRM_Core_Config_MagicMerge { * tables created recently from being deleted. */ public static function clearTempTables($timeInterval = FALSE): void { - - $dao = new CRM_Core_DAO(); $query = " SELECT TABLE_NAME as tableName FROM INFORMATION_SCHEMA.TABLES - WHERE TABLE_SCHEMA = %1 + WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME LIKE 'civicrm_tmp_d%' "; @@ -376,7 +374,7 @@ class CRM_Core_Config extends CRM_Core_Config_MagicMerge { $query .= " AND CREATE_TIME < DATE_SUB(NOW(), INTERVAL {$timeInterval})"; } - $tableDAO = CRM_Core_DAO::executeQuery($query, [1 => [$dao->database(), 'String']]); + $tableDAO = CRM_Core_DAO::executeQuery($query); $tables = []; while ($tableDAO->fetch()) { $tables[] = $tableDAO->tableName; diff --git a/civicrm/CRM/Core/DAO.php b/civicrm/CRM/Core/DAO.php index eb84c1651c..f63391c46d 100644 --- a/civicrm/CRM/Core/DAO.php +++ b/civicrm/CRM/Core/DAO.php @@ -1080,25 +1080,6 @@ class CRM_Core_DAO extends DB_DataObject { } } - /** - * Check if there is a given column in a specific table. - * - * @deprecated - * @see CRM_Core_BAO_SchemaHandler::checkIfFieldExists - * - * @param string $tableName - * @param string $columnName - * @param bool $i18nRewrite - * Whether to rewrite the query on multilingual setups. - * - * @return bool - * true if exists, else false - */ - public static function checkFieldExists($tableName, $columnName, $i18nRewrite = TRUE) { - CRM_Core_Error::deprecatedFunctionWarning('CRM_Core_BAO_SchemaHandler::checkIfFieldExists'); - return CRM_Core_BAO_SchemaHandler::checkIfFieldExists($tableName, $columnName, $i18nRewrite); - } - /** * Scans all the tables using a slow query and table name. * @@ -1108,7 +1089,7 @@ class CRM_Core_DAO extends DB_DataObject { $dao = CRM_Core_DAO::executeQuery( "SELECT TABLE_NAME FROM information_schema.TABLES - WHERE TABLE_SCHEMA = '" . CRM_Core_DAO::getDatabaseName() . "' + WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME LIKE 'civicrm_%' AND TABLE_NAME NOT LIKE '%_tmp%' "); @@ -1130,7 +1111,7 @@ class CRM_Core_DAO extends DB_DataObject { "SELECT count(*) FROM information_schema.TABLES WHERE ENGINE = 'MyISAM' - AND TABLE_SCHEMA = '" . CRM_Core_DAO::getDatabaseName() . "' + AND TABLE_SCHEMA = DATABASE() AND TABLE_NAME LIKE 'civicrm_%' AND TABLE_NAME NOT LIKE 'civicrm_tmp_%' "); @@ -1139,11 +1120,12 @@ class CRM_Core_DAO extends DB_DataObject { /** * Get the name of the CiviCRM database. * + * @deprecated use mysql DATABASE() within the query. + * * @return string */ - public static function getDatabaseName() { - $daoObj = new CRM_Core_DAO(); - return $daoObj->database(); + public static function getDatabaseName(): string { + return (new CRM_Core_DAO())->database(); } /** @@ -2440,30 +2422,6 @@ SELECT contact_id } } - /** - * @param string $prefix - * @param bool $addRandomString - * @param null $string - * - * @return string - * @deprecated - * @see CRM_Utils_SQL_TempTable - */ - public static function createTempTableName($prefix = 'civicrm', $addRandomString = TRUE, $string = NULL) { - CRM_Core_Error::deprecatedFunctionWarning('Use CRM_Utils_SQL_TempTable interface to create temporary tables'); - $tableName = $prefix . "_temp"; - - if ($addRandomString) { - if ($string) { - $tableName .= "_" . $string; - } - else { - $tableName .= "_" . md5(uniqid('', TRUE)); - } - } - return $tableName; - } - /** * @param bool $view * @param bool $trigger diff --git a/civicrm/CRM/Core/DAO/CustomField.php b/civicrm/CRM/Core/DAO/CustomField.php index 8faf7f4728..0fd63f551b 100644 --- a/civicrm/CRM/Core/DAO/CustomField.php +++ b/civicrm/CRM/Core/DAO/CustomField.php @@ -6,7 +6,7 @@ * * Generated from xml/schema/CRM/Core/CustomField.xml * DO NOT EDIT. Generated by CRM_Core_CodeGen - * (GenCodeChecksum:f102cd2c666ba101ff0933c9fdac92ce) + * (GenCodeChecksum:74a1b749ab865c09722b5e8904c382a9) */ /** @@ -320,6 +320,15 @@ class CRM_Core_DAO_CustomField extends CRM_Core_DAO { */ public $in_selector; + /** + * Name of entity being referenced. + * + * @var string|null + * (SQL type: varchar(255)) + * Note that values will be retrieved from the database as a string. + */ + public $fk_entity; + /** * Class constructor. */ @@ -812,6 +821,21 @@ class CRM_Core_DAO_CustomField extends CRM_Core_DAO { 'localizable' => 0, 'add' => '4.5', ], + 'fk_entity' => [ + 'name' => 'fk_entity', + 'type' => CRM_Utils_Type::T_STRING, + 'title' => ts('Entity'), + 'description' => ts('Name of entity being referenced.'), + 'maxlength' => 255, + 'size' => CRM_Utils_Type::HUGE, + 'where' => 'civicrm_custom_field.fk_entity', + 'default' => NULL, + 'table_name' => 'civicrm_custom_field', + 'entity' => 'CustomField', + 'bao' => 'CRM_Core_BAO_CustomField', + 'localizable' => 0, + 'add' => '5.60', + ], ]; CRM_Core_DAO_AllCoreTables::invoke(__CLASS__, 'fields_callback', Civi::$statics[__CLASS__]['fields']); } diff --git a/civicrm/CRM/Core/DAO/JobLog.php b/civicrm/CRM/Core/DAO/JobLog.php index 3b0e98bb13..c38d1e7770 100644 --- a/civicrm/CRM/Core/DAO/JobLog.php +++ b/civicrm/CRM/Core/DAO/JobLog.php @@ -6,7 +6,7 @@ * * Generated from xml/schema/CRM/Core/JobLog.xml * DO NOT EDIT. Generated by CRM_Core_CodeGen - * (GenCodeChecksum:258a172d38252619a97c1d74663bdd87) + * (GenCodeChecksum:98cdc7ac1580bf4029404b0e69fa401c) */ /** @@ -58,7 +58,7 @@ class CRM_Core_DAO_JobLog extends CRM_Core_DAO { public $run_time; /** - * Pointer to job id - not a FK though, just for logging purposes + * Pointer to job id * * @var int|string|null * (SQL type: int unsigned) @@ -130,6 +130,7 @@ class CRM_Core_DAO_JobLog extends CRM_Core_DAO { if (!isset(Civi::$statics[__CLASS__]['links'])) { Civi::$statics[__CLASS__]['links'] = static::createReferenceColumns(__CLASS__); Civi::$statics[__CLASS__]['links'][] = new CRM_Core_Reference_Basic(self::getTableName(), 'domain_id', 'civicrm_domain', 'id'); + Civi::$statics[__CLASS__]['links'][] = new CRM_Core_Reference_Basic(self::getTableName(), 'job_id', 'civicrm_job', 'id'); CRM_Core_DAO_AllCoreTables::invoke(__CLASS__, 'links_callback', Civi::$statics[__CLASS__]['links']); } return Civi::$statics[__CLASS__]['links']; @@ -198,12 +199,16 @@ class CRM_Core_DAO_JobLog extends CRM_Core_DAO { 'name' => 'job_id', 'type' => CRM_Utils_Type::T_INT, 'title' => ts('Job ID'), - 'description' => ts('Pointer to job id - not a FK though, just for logging purposes'), + 'description' => ts('Pointer to job id'), 'where' => 'civicrm_job_log.job_id', 'table_name' => 'civicrm_job_log', 'entity' => 'JobLog', 'bao' => 'CRM_Core_DAO_JobLog', 'localizable' => 0, + 'FKClassName' => 'CRM_Core_DAO_Job', + 'html' => [ + 'type' => 'Number', + ], 'add' => '4.1', ], 'name' => [ diff --git a/civicrm/CRM/Core/Error.php b/civicrm/CRM/Core/Error.php index bb39511f4a..92f14f1d9a 100644 --- a/civicrm/CRM/Core/Error.php +++ b/civicrm/CRM/Core/Error.php @@ -566,6 +566,10 @@ class CRM_Core_Error extends PEAR_ErrorStack { * Provided the user has the 'view debug output' the output should be displayed. In all * cases it should be logged. * + * @deprecated see https://docs.civicrm.org/dev/en/latest/framework/logging/ + * + * Use (e.g) `Civi::log()->error()` (priority dependent). + * * @param string $message * @param bool $out * Should we log or return the output. @@ -598,13 +602,7 @@ class CRM_Core_Error extends PEAR_ErrorStack { } if (!empty(\Civi::$statics[__CLASS__]['userFrameworkLogging'])) { - // should call $config->userSystem->logger($message) here - but I got a situation where userSystem was not an object - not sure why - if ($config->userSystem->is_drupal and function_exists('watchdog')) { - watchdog('civicrm', '%message', ['%message' => $message], $priority ?? WATCHDOG_DEBUG); - } - elseif ($config->userSystem->is_drupal and CIVICRM_UF == 'Drupal8') { - \Drupal::logger('civicrm')->log($priority ?? \Drupal\Core\Logger\RfcLogLevel::DEBUG, '%message', ['%message' => $message]); - } + $config->userSystem->logger($message, $priority); } return $str; diff --git a/civicrm/CRM/Core/Form.php b/civicrm/CRM/Core/Form.php index f71fb5335b..c3682d97b4 100644 --- a/civicrm/CRM/Core/Form.php +++ b/civicrm/CRM/Core/Form.php @@ -508,6 +508,11 @@ class CRM_Core_Form extends HTML_QuickForm_Page { unset($extra['option_context']); } + // Allow disabled to be a boolean + if (isset($attributes['disabled']) && $attributes['disabled'] === FALSE) { + unset($attributes['disabled']); + } + $element = $this->addElement($type, $name, CRM_Utils_String::purifyHTML($label), $attributes, $extra); if (HTML_QuickForm::isError($element)) { CRM_Core_Error::statusBounce(HTML_QuickForm::errorMessage($element)); @@ -1151,7 +1156,7 @@ class CRM_Core_Form extends HTML_QuickForm_Page { * * If renderer is not set create one and initialize it. * - * @return object + * @return CRM_Core_Form_Renderer */ public function &getRenderer() { if (!isset($this->_renderer)) { @@ -2203,6 +2208,33 @@ class CRM_Core_Form extends HTML_QuickForm_Page { } } + /** + * @param string $name + * @param string $label + * @param array $props + * @param bool $required + * + * @return HTML_QuickForm_Element + */ + public function addAutocomplete(string $name, string $label = '', array $props = [], bool $required = FALSE) { + $props += [ + 'entity' => 'Contact', + 'api' => [], + 'select' => [], + ]; + $props['api'] += [ + 'formName' => 'qf:' . get_class($this), + 'fieldName' => $name, + ]; + $props['class'] = ltrim(($props['class'] ?? '') . ' crm-form-autocomplete'); + $props['placeholder'] = $props['placeholder'] ?? self::selectOrAnyPlaceholder($props, $required); + $props['data-select-params'] = json_encode($props['select']); + $props['data-api-params'] = json_encode($props['api']); + $props['data-api-entity'] = $props['entity']; + CRM_Utils_Array::remove($props, 'select', 'api', 'entity'); + return $this->add('text', $name, $label, $props, $required); + } + /** * Create a single or multiple entity ref field. * @param string $name @@ -2615,6 +2647,17 @@ class CRM_Core_Form extends HTML_QuickForm_Page { } } + /** + * Push the current url to the userContext. + * + * This is like a save point :-). The next status bounce will + * return the browser to this url unless another is added. + */ + protected function pushUrlToUserContext(): void { + CRM_Core_Session::singleton() + ->pushUserContext(CRM_Utils_System::url(CRM_Utils_System::currentPath(), 'reset=1')); + } + /** * Set options and attributes for chain select fields based on the controlling field's value */ diff --git a/civicrm/CRM/Core/Form/Search.php b/civicrm/CRM/Core/Form/Search.php index aa2e13b5b1..693af70456 100644 --- a/civicrm/CRM/Core/Form/Search.php +++ b/civicrm/CRM/Core/Form/Search.php @@ -121,8 +121,8 @@ class CRM_Core_Form_Search extends CRM_Core_Form { $this->handleForcedSearch(); } $this->_formValues = $this->getFormValues(); - // For searchResultsTasks.tpl. - $this->addExpectedSmartyVariables(['savedSearch', 'selectorLabel']); + // For searchResultsTasks.tpl & displaySearchCriteria.tpl + $this->addExpectedSmartyVariables(['savedSearch', 'selectorLabel', 'operator']); } /** diff --git a/civicrm/CRM/Core/InnoDBIndexer.php b/civicrm/CRM/Core/InnoDBIndexer.php index d10c4c2e18..18532d452a 100644 --- a/civicrm/CRM/Core/InnoDBIndexer.php +++ b/civicrm/CRM/Core/InnoDBIndexer.php @@ -163,7 +163,7 @@ class CRM_Core_InnoDBIndexer { $dao = CRM_Core_DAO::executeQuery(" SELECT index_name as index_name FROM information_Schema.STATISTICS - WHERE table_schema = '" . CRM_Core_DAO::getDatabaseName() . "' + WHERE table_schema = DATABASE() AND table_name = '$table' AND index_type = 'FULLTEXT' GROUP BY index_name diff --git a/civicrm/CRM/Core/Lock.php b/civicrm/CRM/Core/Lock.php index 3a3c220e19..67adc99c02 100644 --- a/civicrm/CRM/Core/Lock.php +++ b/civicrm/CRM/Core/Lock.php @@ -171,9 +171,6 @@ class CRM_Core_Lock implements \Civi\Core\Lock\LockInterface { */ public function acquire($timeout = NULL) { if (!$this->_hasLock) { - if (!CRM_Utils_SQL::supportsMultipleLocks() && self::$jobLog && CRM_Core_DAO::singleValueQuery("SELECT IS_USED_LOCK( '" . self::$jobLog . "')")) { - return $this->hackyHandleBrokenCode(self::$jobLog); - } $query = "SELECT GET_LOCK( %1, %2 )"; $params = [ @@ -235,29 +232,4 @@ class CRM_Core_Lock implements \Civi\Core\Lock\LockInterface { return $this->_hasLock; } - /** - * CRM-12856 locks were originally set up for jobs, but the concept was extended to caching & groups without - * understanding that would undermine the job locks (because grabbing a lock implicitly releases existing ones) - * this is all a big hack to mitigate the impact of that - but should not be seen as a fix. Not sure correct fix - * but maybe locks should be used more selectively? Or else we need to handle is some cool way that Tim is yet to write :-) - * if we are running in the context of the cron log then we would rather die (or at least let our process die) - * than release that lock - so if the attempt is being made by setCache or something relatively trivial - * we'll just return TRUE, but if it's another job then we will crash as that seems 'safer' - * - * @param string $jobLog - * @throws CRM_Core_Exception - * @return bool - */ - public function hackyHandleBrokenCode($jobLog) { - if (stristr($this->_name, 'job')) { - \Civi::log()->debug('lock acquisition for ' . $this->_name . '(' . $this->_id . ')' . ' attempted when ' . $jobLog . ' is not released'); - throw new CRM_Core_Exception('lock acquisition for ' . $this->_name . '(' . $this->_id . ')' . ' attempted when ' . $jobLog . ' is not released'); - } - if (defined('CIVICRM_LOCK_DEBUG')) { - \Civi::log()->debug('(CRM-12856) faking lock for ' . $this->_name . '(' . $this->_id . ')'); - } - $this->_hasLock = TRUE; - return TRUE; - } - } diff --git a/civicrm/CRM/Core/OptionGroup.php b/civicrm/CRM/Core/OptionGroup.php index 04e989436c..b0701cc5f2 100644 --- a/civicrm/CRM/Core/OptionGroup.php +++ b/civicrm/CRM/Core/OptionGroup.php @@ -328,94 +328,6 @@ WHERE v.option_group_id = g.id } } - /** - * @deprecated - use CRM_Core_PseudoConstant::getLabel - * - * @param string $groupName - * @param $value - * @param bool $onlyActiveValue - * - * @return null - */ - public static function getLabel($groupName, $value, $onlyActiveValue = TRUE) { - CRM_Core_Error::deprecatedFunctionWarning('CRM_Core_PseudoConstant::getLabel'); - if (empty($groupName) || - empty($value) - ) { - return NULL; - } - - $query = " -SELECT v.label as label ,v.value as value -FROM civicrm_option_value v, - civicrm_option_group g -WHERE v.option_group_id = g.id - AND g.name = %1 - AND g.is_active = 1 - AND v.value = %2 -"; - if ($onlyActiveValue) { - $query .= " AND v.is_active = 1 "; - } - $p = [ - 1 => [$groupName, 'String'], - 2 => [$value, 'Integer'], - ]; - $dao = CRM_Core_DAO::executeQuery($query, $p); - if ($dao->fetch()) { - return $dao->label; - } - return NULL; - } - - /** - * @deprecated - * - * This function is not cached. - * - * @param string $groupName - * @param $label - * @param string $labelField - * @param string $labelType - * @param string $valueField - * - * @return null - */ - public static function getValue( - $groupName, - $label, - $labelField = 'label', - $labelType = 'String', - $valueField = 'value' - ) { - if (empty($label)) { - return NULL; - } - - CRM_Core_Error::deprecatedFunctionWarning('CRM_Core_PseudoConstant::getKey'); - - $query = " -SELECT v.label as label ,v.{$valueField} as value -FROM civicrm_option_value v, - civicrm_option_group g -WHERE v.option_group_id = g.id - AND g.name = %1 - AND v.is_active = 1 - AND g.is_active = 1 - AND v.$labelField = %2 -"; - - $p = [ - 1 => [$groupName, 'String'], - 2 => [$label, $labelType], - ]; - $dao = CRM_Core_DAO::executeQuery($query, $p); - if ($dao->fetch()) { - return $dao->value; - } - return NULL; - } - /** * Get option_value.value from default option_value row for an option group * diff --git a/civicrm/CRM/Core/Payment/PayPalProIPN.php b/civicrm/CRM/Core/Payment/PayPalProIPN.php index 4dc98b5c31..6f9fdeb59b 100644 --- a/civicrm/CRM/Core/Payment/PayPalProIPN.php +++ b/civicrm/CRM/Core/Payment/PayPalProIPN.php @@ -291,7 +291,7 @@ class CRM_Core_Payment_PayPalProIPN extends CRM_Core_Payment_BaseIPN { // In future moving to create pending & then complete, but this OK for now. // Also consider accepting 'Failed' like other processors. - $input['contribution_status_id'] = CRM_Core_PseudoConstant::getKey('CRM_Contribute_BAO_ContributionRecur', 'contribution_status_id', 'Completed'); + $input['contribution_status_id'] = CRM_Core_PseudoConstant::getKey('CRM_Contribute_BAO_Contribution', 'contribution_status_id', 'Completed'); $input['invoice_id'] = md5(uniqid(rand(), TRUE)); $input['original_contribution_id'] = $this->getContributionID(); $input['contribution_recur_id'] = $this->getContributionRecurID(); diff --git a/civicrm/CRM/Core/PseudoConstant.php b/civicrm/CRM/Core/PseudoConstant.php index 4e3b97c0c1..3159f67725 100644 --- a/civicrm/CRM/Core/PseudoConstant.php +++ b/civicrm/CRM/Core/PseudoConstant.php @@ -1500,6 +1500,10 @@ WHERE id = %1 $from = 'FROM %3'; $wheres = []; $order = 'ORDER BY %2'; + if (in_array('id', $availableFields, TRUE)) { + // Example: 'ORDER BY abbreviation, id' because `abbreviation`s are not unique. + $order .= ', id'; + } // Use machine name in certain contexts if ($context === 'validate' || $context === 'match') { diff --git a/civicrm/CRM/Core/SelectValues.php b/civicrm/CRM/Core/SelectValues.php index 5490d0562a..43383eda42 100644 --- a/civicrm/CRM/Core/SelectValues.php +++ b/civicrm/CRM/Core/SelectValues.php @@ -540,9 +540,12 @@ class CRM_Core_SelectValues { /** * Different type of Membership Tokens. * + * @deprecated + * * @return array */ public static function membershipTokens(): array { + CRM_Core_Error::deprecatedFunctionWarning('token processor'); return [ '{membership.id}' => ts('Membership ID'), '{membership.status_id:label}' => ts('Status'), @@ -562,6 +565,7 @@ class CRM_Core_SelectValues { * @return array */ public static function eventTokens(): array { + CRM_Core_Error::deprecatedFunctionWarning('token processor'); $tokenProcessor = new TokenProcessor(Civi::dispatcher(), ['schema' => ['eventId']]); $allTokens = $tokenProcessor->listTokens(); foreach (array_keys($allTokens) as $token) { @@ -580,6 +584,7 @@ class CRM_Core_SelectValues { * @return array */ public static function contributionTokens(): array { + CRM_Core_Error::deprecatedFunctionWarning('use the token processor'); $tokenProcessor = new TokenProcessor(Civi::dispatcher(), ['schema' => ['contributionId']]); $allTokens = $tokenProcessor->listTokens(); foreach (array_keys($allTokens) as $token) { diff --git a/civicrm/CRM/Core/Session.php b/civicrm/CRM/Core/Session.php index f1edba8947..3f0011cc78 100644 --- a/civicrm/CRM/Core/Session.php +++ b/civicrm/CRM/Core/Session.php @@ -431,13 +431,13 @@ class CRM_Core_Session { * @param bool $reset * Should we reset the status variable?. * - * @return string + * @return array * the status message if any */ - public function getStatus($reset = FALSE) { + public function getStatus($reset = FALSE) : array { $this->initialize(); - $status = NULL; + $status = []; if (array_key_exists('status', $this->_session[$this->_key])) { $status = $this->_session[$this->_key]['status']; } diff --git a/civicrm/CRM/Core/Smarty.php b/civicrm/CRM/Core/Smarty.php index 5c0d1d884a..769bb813ef 100644 --- a/civicrm/CRM/Core/Smarty.php +++ b/civicrm/CRM/Core/Smarty.php @@ -131,7 +131,6 @@ class CRM_Core_Smarty extends Smarty { $this->assign('langSwitch', CRM_Core_I18n::uiLanguages()); } - $this->register_function('crmURL', ['CRM_Utils_System', 'crmURL']); if (CRM_Utils_Constant::value('CIVICRM_SMARTY_DEFAULT_ESCAPE')) { // When default escape is enabled if the core escape is called before // any custom escaping is done the modifier_escape function is not @@ -144,6 +143,7 @@ class CRM_Core_Smarty extends Smarty { $this->default_modifiers[] = 'escape:"htmlall"'; } $this->load_filter('pre', 'resetExtScope'); + $this->load_filter('pre', 'htxtFilter'); $this->assign('crmPermissions', new CRM_Core_Smarty_Permissions()); @@ -301,16 +301,28 @@ class CRM_Core_Smarty extends Smarty { } /** - * @param $path + * Add template directory(s). + * + * @param string|array $template_dir directory(s) of template sources + * @param string $key (Smarty3+) of the array element to assign the template dir to + * @param bool $isConfig (Smarty3+) true for config_dir + * + * @return Smarty current Smarty instance for chaining */ - public function addTemplateDir($path) { + public function addTemplateDir($template_dir, $key = NULL, $isConfig = FALSE) { + if (method_exists('parent', 'addTemplateDir')) { + // More recent versions of Smarty have this method. + return parent::addTemplateDir($template_dir, $key, $isConfig); + } if (is_array($this->template_dir)) { - array_unshift($this->template_dir, $path); + if (!in_array($template_dir, $this->template_dir)) { + array_unshift($this->template_dir, $template_dir); + } } else { - $this->template_dir = [$path, $this->template_dir]; + $this->template_dir = [$template_dir, $this->template_dir]; } - + return $this; } /** @@ -473,7 +485,7 @@ class CRM_Core_Smarty extends Smarty { $value = smarty_modifier_escape($string, $esc_type, $char_set); if ($value !== $string) { - Civi::log()->debug('smarty escaping original {original}, escaped {escaped} type {type} charset {charset}', [ + Civi::log('smarty')->debug('smarty escaping original {original}, escaped {escaped} type {type} charset {charset}', [ 'original' => $string, 'escaped' => $value, 'type' => $esc_type, diff --git a/civicrm/CRM/Core/Smarty/plugins/block.ts.php b/civicrm/CRM/Core/Smarty/plugins/block.ts.php index f3cbd36fe9..6c1faeffd0 100644 --- a/civicrm/CRM/Core/Smarty/plugins/block.ts.php +++ b/civicrm/CRM/Core/Smarty/plugins/block.ts.php @@ -34,8 +34,8 @@ * the string, translated by gettext */ function smarty_block_ts($params, $text, &$smarty) { - if (!isset($params['domain'])) { - $params['domain'] = $smarty->get_template_vars('extensionKey'); + if (!isset($params['domain']) && $extensionKey = $smarty->get_template_vars('extensionKey')) { + $params['domain'] = is_array($extensionKey) ? $extensionKey : [$extensionKey, NULL]; } return ts($text, $params); } diff --git a/civicrm/CRM/Core/Smarty/plugins/function.crmURL.php b/civicrm/CRM/Core/Smarty/plugins/function.crmURL.php new file mode 100644 index 0000000000..810e3b4bc1 --- /dev/null +++ b/civicrm/CRM/Core/Smarty/plugins/function.crmURL.php @@ -0,0 +1,50 @@ +<?php +/* + +--------------------------------------------------------------------+ + | Copyright CiviCRM LLC. All rights reserved. | + | | + | This work is published under the GNU AGPLv3 license with some | + | permitted exceptions and without any warranty. For full license | + | and copyright information, see https://civicrm.org/licensing | + +--------------------------------------------------------------------+ + */ + +/** + * + * @package CRM + * @copyright CiviCRM LLC + * + */ + +/** + * Generate a URL. + * + * Ex: `{crmURL p='civicrm/acl/entityrole' q='reset=1'}` + * Ex: `{crmURL p='civicrm/profile/create' q='id=123&reset=1' fe=1}` + * + * Each URL component uses an abbreviation (e.g. "p"<=>"path"; "q"<=>"query"). + * + * @param array $params + * List of URL properties. + * - "p" (string $path) + * The path being linked to, such as "civicrm/add". + * - "q" (array|string $query) + * A query string to append to the link, or an array of key-value pairs. + * - "a" (bool $absolute) + * Whether to force the output to be an absolute link (beginning with a + * URI-scheme such as 'http:'). Useful for links that will be displayed + * outside the site, such as in an RSS feed. + * - "f" (string $fragment) + * A "#" fragment to append to the link. This could a named anchor (as + * in `#section2`) or a client-side route (as in `#/mailing/new`). + * - "h" (bool $htmlize) + * Whether to encode special html characters such as &. + * - "fe" (bool $frontend) + * This link should be to the CMS front end (applies to WP & Joomla). + * - "fb" (bool $forceBackend) + * This link should be to the CMS back end (applies to WP & Joomla). + * @return string + */ +function smarty_function_crmURL($params) { + return CRM_Utils_System::crmURL($params); +} diff --git a/civicrm/CRM/Core/Smarty/plugins/modifier.mb_truncate.php b/civicrm/CRM/Core/Smarty/plugins/modifier.mb_truncate.php index a58909ff05..e5416bc2bb 100644 --- a/civicrm/CRM/Core/Smarty/plugins/modifier.mb_truncate.php +++ b/civicrm/CRM/Core/Smarty/plugins/modifier.mb_truncate.php @@ -58,7 +58,7 @@ function smarty_modifier_mb_truncate($string, $length = 80, $etc = '...', } - if ($strlen($string) > $length) { + if ($string !== NULL && $strlen($string) > $length) { $length -= $strlen($etc); if (!$break_words) { $string = preg_replace('/\s+?(\S+)?$/', '', $substr($string, 0, $length + 1)); diff --git a/civicrm/CRM/Core/Smarty/plugins/prefilter.htxtFilter.php b/civicrm/CRM/Core/Smarty/plugins/prefilter.htxtFilter.php new file mode 100644 index 0000000000..1a2a56a085 --- /dev/null +++ b/civicrm/CRM/Core/Smarty/plugins/prefilter.htxtFilter.php @@ -0,0 +1,36 @@ +<?php + +/** + * The content of an "{htxt}" block should not be evaluated unless + * the active request is relevant. Otherwise, it will try to + * evaluate unassigned variables. + * + * @param string $tpl_source + * @param $smarty + * @return string + */ +function smarty_prefilter_htxtFilter($tpl_source, &$smarty) { + if (strpos($tpl_source, '{htxt') === FALSE) { + return $tpl_source; + } + + $htxts = 0; + $_htxts = 0; + + $result = preg_replace_callback_array([ + '/\{htxt id=([\'\"][^\'\"]+[\'\"])/' => function ($m) use (&$htxts) { + $htxts++; + return sprintf('{if $id == %s}%s', $m[1], $m[0]); + }, + ';\{/htxt\};' => function($m) use (&$_htxts) { + $_htxts++; + return '{/htxt}{/if}'; + }, + ], $tpl_source); + + if ($htxts !== $_htxts) { + throw new \RuntimeException(sprintf('Invalid {htxt} tag. Wrapped %d opening-tags and %d closing-tags.', $htxts, $_htxts)); + } + + return $result; +} diff --git a/civicrm/CRM/Custom/Form/Field.php b/civicrm/CRM/Custom/Form/Field.php index 0ae4d84ce0..8da250a92c 100644 --- a/civicrm/CRM/Custom/Form/Field.php +++ b/civicrm/CRM/Custom/Form/Field.php @@ -228,6 +228,14 @@ class CRM_Custom_Form_Field extends CRM_Core_Form { $this->add('checkbox', 'serialize', ts('Multi-Select')); + $this->addAutocomplete('fk_entity', ts('Entity'), [ + 'class' => 'twenty', + // Don't allow entity to be changed once field is created + 'disabled' => $this->_action == CRM_Core_Action::UPDATE && !empty($this->_values['fk_entity']), + 'entity' => 'Entity', + 'select' => ['minimumInputLength' => 0], + ]); + if ($this->_action == CRM_Core_Action::UPDATE) { $this->freeze('data_type'); if (!empty($this->_values['option_group_id'])) { @@ -613,6 +621,12 @@ SELECT count(*) } } + if ($dataType === 'EntityReference') { + if (empty($fields['fk_entity'])) { + $errors['fk_entity'] = ts('Selecting an entity is required'); + } + } + if ($dataType == 'Date') { if (!$fields['date_format']) { $errors['date_format'] = ts('Please select a date format.'); diff --git a/civicrm/CRM/Custom/Form/Group.php b/civicrm/CRM/Custom/Form/Group.php index be0ac00fdd..07499e96da 100644 --- a/civicrm/CRM/Custom/Form/Group.php +++ b/civicrm/CRM/Custom/Form/Group.php @@ -401,7 +401,7 @@ class CRM_Custom_Form_Group extends CRM_Core_Form { // prompt Drupal Views users to update $db_prefix in settings.php, if necessary global $db_prefix; $config = CRM_Core_Config::singleton(); - if (is_array($db_prefix) && $config->userSystem->is_drupal && module_exists('views')) { + if (is_array($db_prefix) && $config->userSystem->viewsExists()) { // get table_name for each custom group $tables = []; $sql = "SELECT table_name FROM civicrm_custom_group WHERE is_active = 1"; diff --git a/civicrm/CRM/Custom/Import/Form/DataSource.php b/civicrm/CRM/Custom/Import/Form/DataSource.php index 4f780de882..90f5174e42 100644 --- a/civicrm/CRM/Custom/Import/Form/DataSource.php +++ b/civicrm/CRM/Custom/Import/Form/DataSource.php @@ -22,10 +22,6 @@ use Civi\Api4\CustomGroup; */ class CRM_Custom_Import_Form_DataSource extends CRM_Import_Form_DataSource { - const PATH = 'civicrm/import/custom'; - - const IMPORT_ENTITY = 'Multi value custom data'; - /** * Get the name of the type to be stored in civicrm_user_job.type_id. * diff --git a/civicrm/CRM/Dedupe/Merger.php b/civicrm/CRM/Dedupe/Merger.php index 5e352409b0..4071797bdf 100644 --- a/civicrm/CRM/Dedupe/Merger.php +++ b/civicrm/CRM/Dedupe/Merger.php @@ -1706,9 +1706,6 @@ INNER JOIN civicrm_membership membership2 ON membership1.membership_type_id = m * api - through which it is properly tested - so can be refactored with some comfort.) * @param bool|int $checkPermission * Either a CRM_Core_Permission constant or FALSE to disable checks - * @param string|int $singleRecord - * holds 'new' or id if view/edit/copy form for a single record is being loaded. - * @param bool $showPublicOnly * * @return array * Custom field 'tree'. @@ -1724,7 +1721,7 @@ INNER JOIN civicrm_membership membership2 ON membership1.membership_type_id = m * * @throws \CRM_Core_Exception */ - public static function getTree( + private static function getTree( $entityType, $toReturn = [], $entityID = NULL, @@ -1734,9 +1731,7 @@ INNER JOIN civicrm_membership membership2 ON membership1.membership_type_id = m $fromCache = TRUE, $onlySubType = NULL, $returnAll = FALSE, - $checkPermission = CRM_Core_Permission::EDIT, - $singleRecord = NULL, - $showPublicOnly = FALSE + $checkPermission = CRM_Core_Permission::EDIT ) { if ($checkPermission === TRUE) { CRM_Core_Error::deprecatedWarning('Unexpected TRUE passed to CustomGroup::getTree $checkPermission param.'); @@ -1905,10 +1900,6 @@ WHERE civicrm_custom_group.is_active = 1 ); } - if ($showPublicOnly && $is_public_version) { - $strWhere .= "AND civicrm_custom_group.is_public = 1"; - } - $orderBy = " ORDER BY civicrm_custom_group.weight, civicrm_custom_group.title, @@ -1951,7 +1942,7 @@ ORDER BY civicrm_custom_group.weight, // add info to groupTree if (isset($groupTree['info']) && !empty($groupTree['info']) && - !empty($groupTree['info']['tables']) && $singleRecord != 'new' + !empty($groupTree['info']['tables']) ) { $select = $from = $where = []; $groupTree['info']['where'] = NULL; @@ -1985,7 +1976,7 @@ ORDER BY civicrm_custom_group.weight, } $multipleFieldTablesWithEntityData = array_keys($entityMultipleSelectClauses); if (!empty($multipleFieldTablesWithEntityData)) { - CRM_Core_BAO_CustomGroup::buildEntityTreeMultipleFields($groupTree, $entityID, $entityMultipleSelectClauses, $multipleFieldTablesWithEntityData, $singleRecord); + CRM_Core_BAO_CustomGroup::buildEntityTreeMultipleFields($groupTree, $entityID, $entityMultipleSelectClauses, $multipleFieldTablesWithEntityData); } } @@ -2112,34 +2103,29 @@ ORDER BY civicrm_custom_group.weight, 'groupName' => 'postal_greeting', ]; CRM_Core_OptionGroup::lookupValues($submitted, $names, TRUE); - // fix custom fields so they're edible by createProfileContact() - $cFields = self::getCustomFieldMetadata($contactType); if (!isset($submitted)) { $submitted = []; } + + // Move view only custom fields CRM-5362 + $viewOnlyCustomFields = []; foreach ($submitted as $key => $value) { if (strpos($key, 'custom_') === 0) { $fieldID = (int) substr($key, 7); - if (empty($cFields[$fieldID])) { - $htmlType = (string) $cFields[$fieldID]['attributes']['html_type']; - $isSerialized = CRM_Core_BAO_CustomField::isSerialized($cFields[$fieldID]['attributes']); - $isView = (bool) $cFields[$fieldID]['attributes']['is_view']; + $fieldMetadata = CRM_Core_BAO_CustomField::getCustomFieldsForContactType($contactType, FALSE)[$fieldID] ?? NULL; + if ($fieldMetadata) { + $htmlType = (string) $fieldMetadata['html_type']; + $isSerialized = CRM_Core_BAO_CustomField::isSerialized($fieldMetadata); + $isView = (bool) $fieldMetadata['is_view']; + if ($isView) { + $viewOnlyCustomFields[$key] = $value; + } $submitted = self::processCustomFields($mainId, $key, $submitted, $value, $fieldID, $isView, $htmlType, $isSerialized); - } } } - // move view only custom fields CRM-5362 - $viewOnlyCustomFields = []; - foreach ($submitted as $key => $value) { - $fid = CRM_Core_BAO_CustomField::getKeyID($key); - if ($fid && array_key_exists($fid, $cFields) && !empty($cFields[$fid]['attributes']['is_view']) - ) { - $viewOnlyCustomFields[$key] = $value; - } - } // special case to set values for view only, CRM-5362 if (!empty($viewOnlyCustomFields)) { $viewOnlyCustomFields['entityID'] = $mainId; @@ -2156,7 +2142,7 @@ ORDER BY civicrm_custom_group.weight, 'return' => ['created_date'], ])['created_date']; if ($otherCreatedDate < $mainCreatedDate && !empty($otherCreatedDate)) { - CRM_Core_DAO::executeQuery("UPDATE civicrm_contact SET created_date = %1 WHERE id = %2", [ + CRM_Core_DAO::executeQuery('UPDATE civicrm_contact SET created_date = %1 WHERE id = %2', [ 1 => [$otherCreatedDate, 'String'], 2 => [$mainId, 'Positive'], ]); @@ -2619,43 +2605,6 @@ ORDER BY civicrm_custom_group.weight, return $submitted; } - /** - * Get metadata for the custom fields for the merge. - * - * @param string $contactType - * - * @return array - * @throws \CRM_Core_Exception - */ - protected static function getCustomFieldMetadata($contactType) { - $treeCache = []; - if (!array_key_exists($contactType, $treeCache)) { - $treeCache[$contactType] = CRM_Core_BAO_CustomGroup::getTree( - $contactType, - NULL, - NULL, - -1, - [], - NULL, - TRUE, - NULL, - FALSE, - FALSE - ); - } - - $cFields = []; - foreach ($treeCache[$contactType] as $key => $group) { - if (!isset($group['fields'])) { - continue; - } - foreach ($group['fields'] as $fid => $field) { - $cFields[$fid]['attributes'] = $field; - } - } - return $cFields; - } - /** * Get conflicts for proposed merge pair. * @@ -3018,9 +2967,6 @@ ORDER BY civicrm_custom_group.weight, */ protected static function getLocksOnContacts($contacts):array { $locks = []; - if (!CRM_Utils_SQL::supportsMultipleLocks()) { - return $locks; - } foreach ($contacts as $contactID) { $lock = Civi::lockManager()->acquire("data.core.contact.{$contactID}"); if ($lock->isAcquired()) { diff --git a/civicrm/CRM/Event/ActionMapping.php b/civicrm/CRM/Event/ActionMapping.php index a14785f48b..c474a8dba6 100644 --- a/civicrm/CRM/Event/ActionMapping.php +++ b/civicrm/CRM/Event/ActionMapping.php @@ -37,9 +37,6 @@ class CRM_Event_ActionMapping extends \Civi\ActionSchedule\Mapping { * @param \Civi\ActionSchedule\Event\MappingRegisterEvent $registrations */ public static function onRegisterActionMappings(\Civi\ActionSchedule\Event\MappingRegisterEvent $registrations) { - if (!CRM_Core_Component::isEnabled('CiviEvent')) { - return; - } $registrations->register(CRM_Event_ActionMapping::create([ 'id' => CRM_Event_ActionMapping::EVENT_TYPE_MAPPING_ID, 'entity' => 'civicrm_participant', diff --git a/civicrm/CRM/Event/BAO/Event.php b/civicrm/CRM/Event/BAO/Event.php index ce018aadf5..55503aad23 100644 --- a/civicrm/CRM/Event/BAO/Event.php +++ b/civicrm/CRM/Event/BAO/Event.php @@ -177,6 +177,7 @@ class CRM_Event_BAO_Event extends CRM_Event_DAO_Event implements \Civi\Core\Hook * @deprecated */ public static function del($id) { + CRM_Core_Error::deprecatedFunctionWarning('deleteRecord'); return (bool) static::deleteRecord(['id' => $id]); } diff --git a/civicrm/CRM/Event/BAO/Participant.php b/civicrm/CRM/Event/BAO/Participant.php index e67401c82a..97869fe7f8 100644 --- a/civicrm/CRM/Event/BAO/Participant.php +++ b/civicrm/CRM/Event/BAO/Participant.php @@ -181,7 +181,7 @@ class CRM_Event_BAO_Participant extends CRM_Event_DAO_Participant implements \Ci ) { // Default status if not specified $participant->status_id = $participant->status_id ?: self::fields()['participant_status_id']['default']; - CRM_Activity_BAO_Activity::addActivity($participant, 'Event Registration'); + CRM_Activity_BAO_Activity::addActivity($participant, 'Event Registration', $participant->contact_id); } //CRM-5403 diff --git a/civicrm/CRM/Event/Form/ManageEvent/Delete.php b/civicrm/CRM/Event/Form/ManageEvent/Delete.php index 6260b2639a..8b6511aed7 100644 --- a/civicrm/CRM/Event/Form/ManageEvent/Delete.php +++ b/civicrm/CRM/Event/Form/ManageEvent/Delete.php @@ -81,7 +81,7 @@ class CRM_Event_Form_ManageEvent_Delete extends CRM_Event_Form_ManageEvent { ), ts('Deletion Error'), 'error'); return; } - CRM_Event_BAO_Event::del($this->_id); + CRM_Event_BAO_Event::deleteRecord(['id' => $this->_id]); if ($this->_isTemplate) { CRM_Core_Session::setStatus(ts("'%1' has been deleted.", [1 => $this->_title]), ts('Template Deleted'), 'success'); CRM_Utils_System::redirect(CRM_Utils_System::url('civicrm/admin/eventTemplate', 'reset=1')); diff --git a/civicrm/CRM/Event/Form/Registration.php b/civicrm/CRM/Event/Form/Registration.php index b22ac78543..a6cf7139aa 100644 --- a/civicrm/CRM/Event/Form/Registration.php +++ b/civicrm/CRM/Event/Form/Registration.php @@ -586,7 +586,7 @@ class CRM_Event_Form_Registration extends CRM_Core_Form { else { $priceSetId = CRM_Price_BAO_PriceSet::getFor('civicrm_event', $eventID); } - self::initSet($form, 'civicrm_event', $doNotIncludeExpiredFields, $priceSetId); + self::initSet($form, $doNotIncludeExpiredFields, $priceSetId); if (property_exists($form, '_context') && ($form->_context == 'standalone' || $form->_context == 'participant') @@ -643,15 +643,13 @@ class CRM_Event_Form_Registration extends CRM_Core_Form { * * @param CRM_Core_Form $form * Form entity id. - * @param string $entityTable * @param bool $doNotIncludeExpiredFields * @param int $priceSetId * Price Set ID * * @todo - removed unneeded code from previously-shared function */ - private static function initSet(&$form, $entityTable = 'civicrm_event', $doNotIncludeExpiredFields = FALSE, $priceSetId = NULL) { - + private static function initSet($form, $doNotIncludeExpiredFields = FALSE, $priceSetId = NULL) { //check if price set is is_config if (is_numeric($priceSetId)) { if (CRM_Core_DAO::getFieldValue('CRM_Price_DAO_PriceSet', $priceSetId, 'is_quick_config') && $form->getVar('_name') != 'Participant') { @@ -661,28 +659,11 @@ class CRM_Event_Form_Registration extends CRM_Core_Form { // get price info if ($priceSetId) { if ($form->_action & CRM_Core_Action::UPDATE) { - $entityId = $entity = NULL; - - switch ($entityTable) { - case 'civicrm_event': - $entity = 'participant'; - if (in_array(CRM_Utils_System::getClassName($form), ['CRM_Event_Form_Participant', 'CRM_Event_Form_Task_Register'])) { - $entityId = $form->_id; - } - else { - $entityId = $form->_participantId; - } - break; - - case 'civicrm_contribution_page': - case 'civicrm_contribution': - $entity = 'contribution'; - $entityId = $form->_id; - break; + if (in_array(CRM_Utils_System::getClassName($form), ['CRM_Event_Form_Participant', 'CRM_Event_Form_Task_Register'])) { + $form->_values['line_items'] = CRM_Price_BAO_LineItem::getLineItems($form->_id, 'participant'); } - - if ($entityId && $entity) { - $form->_values['line_items'] = CRM_Price_BAO_LineItem::getLineItems($entityId, $entity); + else { + $form->_values['line_items'] = CRM_Price_BAO_LineItem::getLineItems($form->_participantId, 'participant'); } $required = FALSE; } @@ -696,41 +677,40 @@ class CRM_Event_Form_Registration extends CRM_Core_Form { $form->_values['fee'] = $form->_priceSet['fields'] ?? NULL; //get the price set fields participant count. - if ($entityTable == 'civicrm_event') { - //get option count info. - $form->_priceSet['optionsCountTotal'] = CRM_Price_BAO_PriceSet::getPricesetCount($priceSetId); - if ($form->_priceSet['optionsCountTotal']) { - $optionsCountDetails = []; - if (!empty($form->_priceSet['fields'])) { - foreach ($form->_priceSet['fields'] as $field) { - foreach ($field['options'] as $option) { - $count = CRM_Utils_Array::value('count', $option, 0); - $optionsCountDetails['fields'][$field['id']]['options'][$option['id']] = $count; - } - } - } - $form->_priceSet['optionsCountDetails'] = $optionsCountDetails; - } - - //get option max value info. - $optionsMaxValueTotal = 0; - $optionsMaxValueDetails = []; - + //get option count info. + $form->_priceSet['optionsCountTotal'] = CRM_Price_BAO_PriceSet::getPricesetCount($priceSetId); + if ($form->_priceSet['optionsCountTotal']) { + $optionsCountDetails = []; if (!empty($form->_priceSet['fields'])) { foreach ($form->_priceSet['fields'] as $field) { foreach ($field['options'] as $option) { - $maxVal = CRM_Utils_Array::value('max_value', $option, 0); - $optionsMaxValueDetails['fields'][$field['id']]['options'][$option['id']] = $maxVal; - $optionsMaxValueTotal += $maxVal; + $count = CRM_Utils_Array::value('count', $option, 0); + $optionsCountDetails['fields'][$field['id']]['options'][$option['id']] = $count; } } } + $form->_priceSet['optionsCountDetails'] = $optionsCountDetails; + } - $form->_priceSet['optionsMaxValueTotal'] = $optionsMaxValueTotal; - if ($optionsMaxValueTotal) { - $form->_priceSet['optionsMaxValueDetails'] = $optionsMaxValueDetails; + //get option max value info. + $optionsMaxValueTotal = 0; + $optionsMaxValueDetails = []; + + if (!empty($form->_priceSet['fields'])) { + foreach ($form->_priceSet['fields'] as $field) { + foreach ($field['options'] as $option) { + $maxVal = CRM_Utils_Array::value('max_value', $option, 0); + $optionsMaxValueDetails['fields'][$field['id']]['options'][$option['id']] = $maxVal; + $optionsMaxValueTotal += $maxVal; + } } } + + $form->_priceSet['optionsMaxValueTotal'] = $optionsMaxValueTotal; + if ($optionsMaxValueTotal) { + $form->_priceSet['optionsMaxValueDetails'] = $optionsMaxValueDetails; + } + $form->set('priceSetId', $form->_priceSetId); $form->set('priceSet', $form->_priceSet); } diff --git a/civicrm/CRM/Event/Form/Registration/Confirm.php b/civicrm/CRM/Event/Form/Registration/Confirm.php index 184bcda8aa..3e01e84dcd 100644 --- a/civicrm/CRM/Event/Form/Registration/Confirm.php +++ b/civicrm/CRM/Event/Form/Registration/Confirm.php @@ -1156,7 +1156,7 @@ class CRM_Event_Form_Registration_Confirm extends CRM_Event_Form_Registration { * * @param CRM_Event_Form_Registration_Confirm $form * - * @throws \Exception + * @throws \CRM_Core_Exception */ public static function assignProfiles($form) { $participantParams = $form->_params; diff --git a/civicrm/CRM/Event/Form/Registration/ThankYou.php b/civicrm/CRM/Event/Form/Registration/ThankYou.php index f7f7e9386d..9464ebacce 100644 --- a/civicrm/CRM/Event/Form/Registration/ThankYou.php +++ b/civicrm/CRM/Event/Form/Registration/ThankYou.php @@ -177,6 +177,7 @@ class CRM_Event_Form_Registration_ThankYou extends CRM_Event_Form_Registration { } $this->assign('iCal', CRM_Event_BAO_Event::getICalLinks($this->_eventId)); + $this->assign('isShowICalIconsInline', TRUE); $this->freeze(); diff --git a/civicrm/CRM/Event/Import/Form/DataSource.php b/civicrm/CRM/Event/Import/Form/DataSource.php index 4817f05400..e187c522b5 100644 --- a/civicrm/CRM/Event/Import/Form/DataSource.php +++ b/civicrm/CRM/Event/Import/Form/DataSource.php @@ -20,10 +20,6 @@ */ class CRM_Event_Import_Form_DataSource extends CRM_Import_Form_DataSource { - const PATH = 'civicrm/event/import'; - - const IMPORT_ENTITY = 'Participant'; - /** * Get the name of the type to be stored in civicrm_user_job.type_id. * diff --git a/civicrm/CRM/Event/Import/Parser/Participant.php b/civicrm/CRM/Event/Import/Parser/Participant.php index 86bc1f0a4b..923143d14c 100644 --- a/civicrm/CRM/Event/Import/Parser/Participant.php +++ b/civicrm/CRM/Event/Import/Parser/Participant.php @@ -45,13 +45,6 @@ class CRM_Event_Import_Parser_Participant extends CRM_Import_Parser { */ protected $_separator; - /** - * Total number of lines in file. - * - * @var int - */ - protected $_lineCount; - /** * Whether the file has a column header or not * diff --git a/civicrm/CRM/Event/Page/DashBoard.php b/civicrm/CRM/Event/Page/DashBoard.php index 9f86809e13..bc4af9c32a 100644 --- a/civicrm/CRM/Event/Page/DashBoard.php +++ b/civicrm/CRM/Event/Page/DashBoard.php @@ -42,6 +42,7 @@ class CRM_Event_Page_DashBoard extends CRM_Core_Page { $this->assign('actionColumn', $actionColumn); $this->assign('eventSummary', $eventSummary); $this->assign('iCal', CRM_Event_BAO_Event::getICalLinks()); + $this->assign('isShowICalIconsInline', FALSE); } /** diff --git a/civicrm/CRM/Event/Page/EventInfo.php b/civicrm/CRM/Event/Page/EventInfo.php index 8790c171bf..c279ea153b 100644 --- a/civicrm/CRM/Event/Page/EventInfo.php +++ b/civicrm/CRM/Event/Page/EventInfo.php @@ -47,6 +47,7 @@ class CRM_Event_Page_EventInfo extends CRM_Core_Page { $this->assign('context', $context); $this->assign('iCal', CRM_Event_BAO_Event::getICalLinks($this->_id)); + $this->assign('isShowICalIconsInline', TRUE); // Sometimes we want to suppress the Event Full msg $noFullMsg = CRM_Utils_Request::retrieve('noFullMsg', 'String', $this, FALSE, 'false'); diff --git a/civicrm/CRM/Event/Page/ManageEvent.php b/civicrm/CRM/Event/Page/ManageEvent.php index 657b1d037a..c981862362 100644 --- a/civicrm/CRM/Event/Page/ManageEvent.php +++ b/civicrm/CRM/Event/Page/ManageEvent.php @@ -227,6 +227,7 @@ class CRM_Event_Page_ManageEvent extends CRM_Core_Page { // assign vars to templates $this->assign('action', $action); $this->assign('iCal', CRM_Event_BAO_Event::getICalLinks()); + $this->assign('isShowICalIconsInline', FALSE); $id = CRM_Utils_Request::retrieve('id', 'Positive', $this, FALSE, 0, 'REQUEST' ); diff --git a/civicrm/CRM/Import/DataSource/CSV.php b/civicrm/CRM/Import/DataSource/CSV.php index bc87dcbba4..b1f5edf7f5 100644 --- a/civicrm/CRM/Import/DataSource/CSV.php +++ b/civicrm/CRM/Import/DataSource/CSV.php @@ -23,7 +23,7 @@ class CRM_Import_DataSource_CSV extends CRM_Import_DataSource { * * @var string[] */ - protected $submittableFields = ['skipColumnHeader', 'uploadField']; + protected $submittableFields = ['skipColumnHeader', 'uploadField', 'fieldSeparator']; /** * Provides information about the data source. diff --git a/civicrm/CRM/Import/DataSource/SQL.php b/civicrm/CRM/Import/DataSource/SQL.php index ad6ac14ea0..d9fa015d90 100644 --- a/civicrm/CRM/Import/DataSource/SQL.php +++ b/civicrm/CRM/Import/DataSource/SQL.php @@ -81,7 +81,12 @@ class CRM_Import_DataSource_SQL extends CRM_Import_DataSource { public function initialize(): void { $table = CRM_Utils_SQL_TempTable::build()->setDurable(); $tableName = $table->getName(); - $table->createWithQuery($this->getSubmittedValue('sqlQuery')); + try { + $table->createWithQuery($this->getSubmittedValue('sqlQuery')); + } + catch (PEAR_Exception $e) { + throw new CRM_Core_Exception($e->getMessage(), 0, ['exception' => $e]); + } // Get the names of the fields to be imported. $columnsResult = CRM_Core_DAO::executeQuery( diff --git a/civicrm/CRM/Import/Form/DataSource.php b/civicrm/CRM/Import/Form/DataSource.php index 29008b234a..95b1bf21ad 100644 --- a/civicrm/CRM/Import/Form/DataSource.php +++ b/civicrm/CRM/Import/Form/DataSource.php @@ -25,6 +25,7 @@ abstract class CRM_Import_Form_DataSource extends CRM_Import_Forms { * Set variables up before form is built. */ public function preProcess(): void { + $this->pushUrlToUserContext(); // check for post max size CRM_Utils_Number::formatUnitSize(ini_get('post_max_size'), TRUE); $this->assign('importEntity', $this->getTranslatedEntity()); @@ -176,7 +177,12 @@ abstract class CRM_Import_Form_DataSource extends CRM_Import_Forms { $this->flushDataSource(); $this->updateUserJobMetadata('submitted_values', $this->getSubmittedValues()); } - $this->instantiateDataSource(); + try { + $this->instantiateDataSource(); + } + catch (CRM_Core_Exception $e) { + CRM_Core_Error::statusBounce($e->getMessage()); + } } /** diff --git a/civicrm/CRM/Mailing/BAO/Mailing.php b/civicrm/CRM/Mailing/BAO/Mailing.php index e772bac270..2ca7e67f9c 100644 --- a/civicrm/CRM/Mailing/BAO/Mailing.php +++ b/civicrm/CRM/Mailing/BAO/Mailing.php @@ -2405,6 +2405,7 @@ LEFT JOIN civicrm_mailing_group g ON g.mailing_id = m.id * @deprecated */ public static function del($id) { + CRM_Core_Error::deprecatedFunctionWarning('deleteRecord'); static::deleteRecord(['id' => $id]); } @@ -2436,7 +2437,7 @@ LEFT JOIN civicrm_mailing_group g ON g.mailing_id = m.id CRM_Core_Error::deprecatedWarning('This function is deprecated, use CRM_Mailing_BAO_MailingJob::del instead'); - CRM_Mailing_BAO_MailingJob::del($id); + CRM_Mailing_BAO_MailingJob::deleteRecord(['id' => $id]); } /** diff --git a/civicrm/CRM/Mailing/BAO/MailingAB.php b/civicrm/CRM/Mailing/BAO/MailingAB.php index 73ce874821..681f90d4ce 100644 --- a/civicrm/CRM/Mailing/BAO/MailingAB.php +++ b/civicrm/CRM/Mailing/BAO/MailingAB.php @@ -52,6 +52,7 @@ class CRM_Mailing_BAO_MailingAB extends CRM_Mailing_DAO_MailingAB implements \Ci * @deprecated */ public static function del($id) { + CRM_Core_Error::deprecatedFunctionWarning('deleteRecord'); static::deleteRecord(['id' => $id]); } diff --git a/civicrm/CRM/Mailing/BAO/MailingJob.php b/civicrm/CRM/Mailing/BAO/MailingJob.php index 2522030c6a..d8de39f04c 100644 --- a/civicrm/CRM/Mailing/BAO/MailingJob.php +++ b/civicrm/CRM/Mailing/BAO/MailingJob.php @@ -1102,6 +1102,7 @@ AND record_type_id = $targetRecordID * @return bool */ public static function del($id) { + CRM_Core_Error::deprecatedFunctionWarning('deleteRecord'); return (bool) self::deleteRecord(['id' => $id]); } diff --git a/civicrm/CRM/Mailing/Form/Approve.php b/civicrm/CRM/Mailing/Form/Approve.php index 1cd4140b03..a777d4f5b0 100644 --- a/civicrm/CRM/Mailing/Form/Approve.php +++ b/civicrm/CRM/Mailing/Form/Approve.php @@ -155,7 +155,7 @@ class CRM_Mailing_Form_Approve extends CRM_Core_Form { $job = new CRM_Mailing_BAO_MailingJob(); $job->mailing_id = $params['id']; while ($job->fetch()) { - CRM_Mailing_BAO_MailingJob::del($job->id); + CRM_Mailing_BAO_MailingJob::deleteRecord(['id' => $job->id]); } } else { diff --git a/civicrm/CRM/Mailing/Form/Browse.php b/civicrm/CRM/Mailing/Form/Browse.php index 9b221b4de8..a8936bdd95 100644 --- a/civicrm/CRM/Mailing/Form/Browse.php +++ b/civicrm/CRM/Mailing/Form/Browse.php @@ -61,7 +61,7 @@ class CRM_Mailing_Form_Browse extends CRM_Core_Form { public function postProcess() { if ($this->_action & CRM_Core_Action::DELETE) { - CRM_Mailing_BAO_Mailing::del($this->_mailingId); + CRM_Mailing_BAO_Mailing::deleteRecord(['id' => $this->_mailingId]); CRM_Core_Session::setStatus(ts('Selected mailing has been deleted.'), ts('Deleted'), 'success'); } elseif ($this->_action & CRM_Core_Action::DISABLE) { diff --git a/civicrm/CRM/Mailing/Info.php b/civicrm/CRM/Mailing/Info.php index e30a0dee84..bffbd7ca79 100644 --- a/civicrm/CRM/Mailing/Info.php +++ b/civicrm/CRM/Mailing/Info.php @@ -159,21 +159,7 @@ class CRM_Mailing_Info extends CRM_Core_Component_Info { */ public static function workflowEnabled() { $config = CRM_Core_Config::singleton(); - - // early exit, since not true for most - if (!$config->userSystem->is_drupal || - !function_exists('module_exists') - ) { - return FALSE; - } - - if (!module_exists('rules')) { - return FALSE; - } - - $enableWorkflow = Civi::settings()->get('civimail_workflow'); - - return $enableWorkflow && $config->userSystem->is_drupal; + return $config->userSystem->mailingWorkflowIsEnabled(); } /** diff --git a/civicrm/CRM/Mailing/Page/Browse.php b/civicrm/CRM/Mailing/Page/Browse.php index ff8fde09ee..501e56e173 100644 --- a/civicrm/CRM/Mailing/Page/Browse.php +++ b/civicrm/CRM/Mailing/Page/Browse.php @@ -199,7 +199,7 @@ class CRM_Mailing_Page_Browse extends CRM_Core_Page { CRM_Core_Error::statusBounce(ts('You do not have permission to access this page.')); } - CRM_Mailing_BAO_Mailing::del($this->_mailingId); + CRM_Mailing_BAO_Mailing::deleteRecord(['id' => $this->_mailingId]); CRM_Core_Session::setStatus(ts('Selected mailing has been deleted.'), ts('Deleted'), 'success'); CRM_Utils_System::redirect($context); } diff --git a/civicrm/CRM/Member/BAO/MembershipBlock.php b/civicrm/CRM/Member/BAO/MembershipBlock.php index 6c208c9b4b..d89eae0d2a 100644 --- a/civicrm/CRM/Member/BAO/MembershipBlock.php +++ b/civicrm/CRM/Member/BAO/MembershipBlock.php @@ -24,6 +24,7 @@ class CRM_Member_BAO_MembershipBlock extends CRM_Member_DAO_MembershipBlock { * @return CRM_Member_DAO_MembershipBlock */ public static function create($params) { + CRM_Core_Error::deprecatedFunctionWarning('writeRecord'); return self::writeRecord($params); } @@ -35,6 +36,7 @@ class CRM_Member_BAO_MembershipBlock extends CRM_Member_DAO_MembershipBlock { * @return bool */ public static function del($id) { + CRM_Core_Error::deprecatedFunctionWarning('deleteRecord'); return (bool) self::deleteRecord(['id' => $id]); } diff --git a/civicrm/CRM/Member/BAO/MembershipPayment.php b/civicrm/CRM/Member/BAO/MembershipPayment.php index a87adb5f43..ae949586bd 100644 --- a/civicrm/CRM/Member/BAO/MembershipPayment.php +++ b/civicrm/CRM/Member/BAO/MembershipPayment.php @@ -81,6 +81,7 @@ class CRM_Member_BAO_MembershipPayment extends CRM_Member_DAO_MembershipPayment * @return bool */ public static function del($id) { + CRM_Core_Error::deprecatedFunctionWarning('deleteRecord'); return (bool) self::deleteRecord(['id' => $id]); } diff --git a/civicrm/CRM/Member/BAO/MembershipStatus.php b/civicrm/CRM/Member/BAO/MembershipStatus.php index 5f02f8c598..7c791d5812 100644 --- a/civicrm/CRM/Member/BAO/MembershipStatus.php +++ b/civicrm/CRM/Member/BAO/MembershipStatus.php @@ -151,6 +151,7 @@ class CRM_Member_BAO_MembershipStatus extends CRM_Member_DAO_MembershipStatus im * @throws CRM_Core_Exception */ public static function del($membershipStatusId) { + CRM_Core_Error::deprecatedFunctionWarning('deleteRecord'); static::deleteRecord(['id' => $membershipStatusId]); } diff --git a/civicrm/CRM/Member/BAO/MembershipType.php b/civicrm/CRM/Member/BAO/MembershipType.php index 6d935c9453..789eebe74d 100644 --- a/civicrm/CRM/Member/BAO/MembershipType.php +++ b/civicrm/CRM/Member/BAO/MembershipType.php @@ -61,50 +61,38 @@ class CRM_Member_BAO_MembershipType extends CRM_Member_DAO_MembershipType implem * * @param array $params * Reference array contains the values submitted by the form. - * @param array $ids - * Array contains the id (deprecated). * * @return \CRM_Member_DAO_MembershipType * @throws \CRM_Core_Exception */ - public static function add(&$params, $ids = []) { - // DEPRECATED Check if membershipType ID was passed in via $ids - if (empty($params['id'])) { - if (isset($ids['membershipType'])) { - Civi::log()->warning('Deprecated: Passing membershipType by $ids array in CRM_Member_BAO_MembershipType::add'); - } - $params['id'] = $ids['membershipType'] ?? NULL; - } - + public static function add(&$params) { $hook = empty($params['id']) ? 'create' : 'edit'; - CRM_Utils_Hook::pre($hook, 'MembershipType', CRM_Utils_Array::value('id', $params), $params); - - $membershipTypeId = $params['id'] ?? NULL; + $membershipTypeID = $params['id'] ?? NULL; + CRM_Utils_Hook::pre($hook, 'MembershipType', $membershipTypeID, $params); - if (!$membershipTypeId && !isset($params['domain_id'])) { + if (!$membershipTypeID && !isset($params['domain_id'])) { $params['domain_id'] = CRM_Core_Config::domainID(); } // $previousID is the old organization id for membership type i.e 'member_of_contact_id'. This is used when an organization is changed. $previousID = NULL; - if ($membershipTypeId) { - $previousID = CRM_Core_DAO::getFieldValue('CRM_Member_DAO_MembershipType', $membershipTypeId, 'member_of_contact_id'); + if ($membershipTypeID) { + $previousID = CRM_Core_DAO::getFieldValue('CRM_Member_DAO_MembershipType', $membershipTypeID, 'member_of_contact_id'); } - // action is taken depending upon the mode $membershipType = new CRM_Member_DAO_MembershipType(); $membershipType->copyValues($params); $membershipType->save(); - if ($membershipTypeId) { + if ($membershipTypeID) { // on update we may need to retrieve some details for the price field function - otherwise we get e-notices on attempts to retrieve // name etc - the presence of previous id tells us this is an update $params = array_merge(civicrm_api3('membership_type', 'getsingle', ['id' => $membershipType->id]), $params); } self::createMembershipPriceField($params, $previousID, $membershipType->id); // update all price field value for quick config when membership type is set CRM-11718 - if ($membershipTypeId) { - self::updateAllPriceFieldValue($membershipTypeId, $params); + if ($membershipTypeID) { + self::updateAllPriceFieldValue($membershipTypeID, $params); } CRM_Utils_Hook::post($hook, 'MembershipType', $membershipType->id, $membershipType); @@ -135,6 +123,7 @@ class CRM_Member_BAO_MembershipType extends CRM_Member_DAO_MembershipType implem * @return bool */ public static function del($membershipTypeId) { + CRM_Core_Error::deprecatedFunctionWarning('deleteRecord'); try { static::deleteRecord(['id' => $membershipTypeId]); return TRUE; diff --git a/civicrm/CRM/Member/Form/MembershipBlock.php b/civicrm/CRM/Member/Form/MembershipBlock.php index a7a3abfac8..60ed1248bb 100644 --- a/civicrm/CRM/Member/Form/MembershipBlock.php +++ b/civicrm/CRM/Member/Form/MembershipBlock.php @@ -151,7 +151,7 @@ class CRM_Member_Form_MembershipBlock extends CRM_Contribute_Form_ContributionPa //CRM-15573 if (!empty($params['id'])) { $params['membership_types'] = serialize($membershipRequired); - CRM_Member_BAO_MembershipBlock::create($params); + CRM_Member_BAO_MembershipBlock::writeRecord($params); } $this->add('hidden', "mem_price_field_id", '', ['id' => "mem_price_field_id"]); $this->assign('is_recur', $isRecur); diff --git a/civicrm/CRM/Member/Form/MembershipStatus.php b/civicrm/CRM/Member/Form/MembershipStatus.php index 3791cbeaf3..967e81bfd2 100644 --- a/civicrm/CRM/Member/Form/MembershipStatus.php +++ b/civicrm/CRM/Member/Form/MembershipStatus.php @@ -150,7 +150,7 @@ class CRM_Member_Form_MembershipStatus extends CRM_Core_Form { public function postProcess() { if ($this->_action & CRM_Core_Action::DELETE) { try { - CRM_Member_BAO_MembershipStatus::del($this->_id); + CRM_Member_BAO_MembershipStatus::deleteRecord(['id' => $this->_id]); } catch (CRM_Core_Exception $e) { CRM_Core_Error::statusBounce($e->getMessage(), NULL, ts('Delete Failed')); diff --git a/civicrm/CRM/Member/Form/MembershipType.php b/civicrm/CRM/Member/Form/MembershipType.php index da1ee84059..686e2f36f9 100644 --- a/civicrm/CRM/Member/Form/MembershipType.php +++ b/civicrm/CRM/Member/Form/MembershipType.php @@ -383,7 +383,7 @@ class CRM_Member_Form_MembershipType extends CRM_Member_Form_MembershipConfig { public function postProcess() { if ($this->_action & CRM_Core_Action::DELETE) { try { - CRM_Member_BAO_MembershipType::del($this->_id); + CRM_Member_BAO_MembershipType::deleteRecord(['id' => $this->_id]); } catch (CRM_Core_Exception $e) { CRM_Core_Error::statusBounce($e->getMessage(), NULL, ts('Membership Type Not Deleted')); diff --git a/civicrm/CRM/Member/Import/Form/DataSource.php b/civicrm/CRM/Member/Import/Form/DataSource.php index d8a7da6d5a..cd35e7cf6d 100644 --- a/civicrm/CRM/Member/Import/Form/DataSource.php +++ b/civicrm/CRM/Member/Import/Form/DataSource.php @@ -20,10 +20,6 @@ */ class CRM_Member_Import_Form_DataSource extends CRM_Import_Form_DataSource { - const PATH = 'civicrm/member/import'; - - const IMPORT_ENTITY = 'Membership'; - /** * Get the name of the type to be stored in civicrm_user_job.type_id. * diff --git a/civicrm/CRM/Member/Import/Parser/Membership.php b/civicrm/CRM/Member/Import/Parser/Membership.php index 92cb027c6d..944119a186 100644 --- a/civicrm/CRM/Member/Import/Parser/Membership.php +++ b/civicrm/CRM/Member/Import/Parser/Membership.php @@ -48,12 +48,6 @@ class CRM_Member_Import_Parser_Membership extends CRM_Import_Parser { */ protected $_separator; - /** - * Total number of lines in file - * @var int - */ - protected $_lineCount; - /** * Get information about the provided job. * - name diff --git a/civicrm/CRM/Pledge/BAO/Pledge.php b/civicrm/CRM/Pledge/BAO/Pledge.php index 20cc015430..546a9aa290 100644 --- a/civicrm/CRM/Pledge/BAO/Pledge.php +++ b/civicrm/CRM/Pledge/BAO/Pledge.php @@ -870,14 +870,8 @@ SELECT pledge.contact_id as contact_id, } if ($sendReminders) { - // retrieve domain tokens - $tokens = [ - 'domain' => ['name', 'phone', 'address', 'email'], - 'contact' => CRM_Core_SelectValues::contactTokens(), - ]; // retrieve contact tokens - // this function does NOT return Deceased contacts since we don't want to send them email $contactDetails = civicrm_api3('Contact', 'get', [ 'is_deceased' => 0, diff --git a/civicrm/CRM/Pledge/Page/UserDashboard.php b/civicrm/CRM/Pledge/Page/UserDashboard.php index a30b8bcf9c..0c8b74375d 100644 --- a/civicrm/CRM/Pledge/Page/UserDashboard.php +++ b/civicrm/CRM/Pledge/Page/UserDashboard.php @@ -19,7 +19,7 @@ class CRM_Pledge_Page_UserDashboard extends CRM_Contact_Page_View_UserDashBoard /** * called when action is browse. */ - public function listPledges() { + public function listPledges(): void { $controller = new CRM_Core_Controller_Simple( 'CRM_Pledge_Form_Search', ts('Pledges'), @@ -35,25 +35,20 @@ class CRM_Pledge_Page_UserDashboard extends CRM_Contact_Page_View_UserDashBoard $controller->process(); $controller->run(); - // add honor block. - $honorParams = []; + // Add honor block. $honorParams = CRM_Pledge_BAO_Pledge::getHonorContacts($this->_contactId); - if (!empty($honorParams)) { - // assign vars to templates - $this->assign('pledgeHonorRows', $honorParams); - $this->assign('pledgeHonor', TRUE); - } - $session = CRM_Core_Session::singleton(); - $loggedUserID = $session->get('userID'); - $this->assign('loggedUserID', $loggedUserID); + $this->assign('pledgeHonorRows', $honorParams); + $this->assign('pledgeHonor', !empty($honorParams)); + $this->assign('loggedUserID', CRM_Core_Session::getLoggedInContactID()); } /** - * the main function that is called when the page - * loads, it decides the which action has to be taken for the page. + * The main function that is called when the page loads. + * + * @throws \CRM_Core_Exception */ - public function run() { - parent::preProcess(); + public function run(): void { + $this->preProcess(); $this->listPledges(); } diff --git a/civicrm/CRM/Report/Form/Contribute/Detail.php b/civicrm/CRM/Report/Form/Contribute/Detail.php index 70965b4bd5..5ca489a392 100644 --- a/civicrm/CRM/Report/Form/Contribute/Detail.php +++ b/civicrm/CRM/Report/Form/Contribute/Detail.php @@ -255,6 +255,14 @@ class CRM_Report_Form_Contribute_Detail extends CRM_Report_Form { ], 'grouping' => 'contri-fields', ], + 'civicrm_pledge_payment' => [ + 'dao' => 'CRM_Pledge_DAO_PledgePayment', + 'filters' => [ + 'contribution_id' => [ + 'title' => ts('Contribution is a pledge payment'), + ], + ], + ], 'civicrm_contribution_soft' => [ 'dao' => 'CRM_Contribute_DAO_ContributionSoft', 'fields' => [ @@ -986,6 +994,13 @@ WHERE civicrm_contribution_contribution_id={$row['civicrm_contribution_contribu $this->joinAddressFromContact(); $this->joinEmailFromContact(); + //for pledge payment + if ($this->isTableSelected('civicrm_pledge_payment')) { + $this->_from .= " + LEFT JOIN civicrm_pledge_payment {$this->_aliases['civicrm_pledge_payment']} ON {$this->_aliases['civicrm_contribution']}.id = {$this->_aliases['civicrm_pledge_payment']}.contribution_id + "; + } + // include contribution note if (!empty($this->_params['fields']['contribution_note']) || !empty($this->_params['note_value']) diff --git a/civicrm/CRM/Report/Form/Contribute/Summary.php b/civicrm/CRM/Report/Form/Contribute/Summary.php index cb7a89af49..a9c0877878 100644 --- a/civicrm/CRM/Report/Form/Contribute/Summary.php +++ b/civicrm/CRM/Report/Form/Contribute/Summary.php @@ -284,6 +284,14 @@ class CRM_Report_Form_Contribute_Summary extends CRM_Report_Form { 'batch_id' => ['title' => ts('Batch Title')], ], ], + 'civicrm_pledge_payment' => [ + 'dao' => 'CRM_Pledge_DAO_PledgePayment', + 'filters' => [ + 'contribution_id' => [ + 'title' => ts('Contribution is a pledge payment'), + ], + ], + ], 'civicrm_contribution_soft' => [ 'dao' => 'CRM_Contribute_DAO_ContributionSoft', 'fields' => [ @@ -527,6 +535,13 @@ class CRM_Report_Form_Contribute_Summary extends CRM_Report_Form { $this->joinPhoneFromContact(); $this->joinEmailFromContact(); + //for pledge payment + if ($this->isTableSelected('civicrm_pledge_payment')) { + $this->_from .= " + LEFT JOIN civicrm_pledge_payment {$this->_aliases['civicrm_pledge_payment']} ON {$this->_aliases['civicrm_contribution']}.id = {$this->_aliases['civicrm_pledge_payment']}.contribution_id + "; + } + //for contribution batches if ($this->isTableSelected('civicrm_batch')) { $this->_from .= " diff --git a/civicrm/CRM/Report/Form/Mailing/Summary.php b/civicrm/CRM/Report/Form/Mailing/Summary.php index a5b4035531..61a6424aae 100644 --- a/civicrm/CRM/Report/Form/Mailing/Summary.php +++ b/civicrm/CRM/Report/Form/Mailing/Summary.php @@ -334,9 +334,11 @@ class CRM_Report_Form_Mailing_Summary extends CRM_Report_Form { foreach ($this->_columns as $tableName => $table) { if (array_key_exists('fields', $table)) { foreach ($table['fields'] as $fieldName => $field) { + if (!empty($field['pseudofield'])) { + continue; + } if (!empty($field['required']) || !empty($this->_params['fields'][$fieldName])) { - - # for statistics + // For statistics if (!empty($field['statistics'])) { switch ($field['statistics']['calc']) { case 'PERCENTAGE': diff --git a/civicrm/CRM/Upgrade/Incremental/php/FiveSixty.php b/civicrm/CRM/Upgrade/Incremental/php/FiveSixty.php new file mode 100644 index 0000000000..6b9a4dedea --- /dev/null +++ b/civicrm/CRM/Upgrade/Incremental/php/FiveSixty.php @@ -0,0 +1,75 @@ +<?php +/* + +--------------------------------------------------------------------+ + | Copyright CiviCRM LLC. All rights reserved. | + | | + | This work is published under the GNU AGPLv3 license with some | + | permitted exceptions and without any warranty. For full license | + | and copyright information, see https://civicrm.org/licensing | + +--------------------------------------------------------------------+ + */ + +/** + * Upgrade logic for the 5.60.x series. + * + * Each minor version in the series is handled by either a `5.60.x.mysql.tpl` file, + * or a function in this class named `upgrade_5_60_x`. + * If only a .tpl file exists for a version, it will be run automatically. + * If the function exists, it must explicitly add the 'runSql' task if there is a corresponding .mysql.tpl. + * + * This class may also implement `setPreUpgradeMessage()` and `setPostUpgradeMessage()` functions. + */ +class CRM_Upgrade_Incremental_php_FiveSixty extends CRM_Upgrade_Incremental_Base { + + /** + * Upgrade step; adds tasks including 'runSql'. + * + * @param string $rev + * The version number matching this function name + */ + public function upgrade_5_60_alpha1($rev): void { + $this->addTask(ts('Upgrade DB to %1: SQL', [1 => $rev]), 'runSql', $rev); + $this->addTask('Add scheduled_reminder_smarty setting', 'addScheduledReminderSmartySetting'); + $this->addTask('Add column civicrm_custom_field.fk_entity', 'addColumn', 'civicrm_custom_field', 'fk_entity', "varchar(255) DEFAULT NULL COMMENT 'Name of entity being referenced.'"); + $this->addTask('Add foreign key from civicrm_job_log to civicrm_job', 'addJobLogForeignKey'); + } + + public function setPostUpgradeMessage(&$postUpgradeMessage, $rev): void { + if ($rev === '5.60.alpha1') { + $postUpgradeMessage .= '<p>' . ts('You can now choose whether to use Smarty in Scheduled Reminders at <em>Administer >> CiviMail >> CiviMail Component Settings</em>. The setting is disabled by default on new installations but we have enabled it during this upgrade to preserve the existing behavior. More information <a %1>in this lab ticket</a>.', [1 => 'href="https://lab.civicrm.org/dev/core/-/issues/4100" target="_blank"']) . '<p>'; + } + } + + public static function addScheduledReminderSmartySetting(): bool { + Civi::settings()->set('scheduled_reminder_smarty', TRUE); + return TRUE; + } + + /** + * Add FK to civicrm_job_log.job_id + * + * @return bool + */ + public static function addJobLogForeignKey(): bool { + // Update the comment for the job_id column + $commentQuery = 'ALTER TABLE civicrm_job_log MODIFY COLUMN `job_id` int(10) unsigned DEFAULT NULL COMMENT \'FK to civicrm_job.id\''; + CRM_Core_DAO::executeQuery($commentQuery); + + // Set job_id = NULL for any that don't have matching jobs (ie. job was deleted). + $updateQuery = 'UPDATE civicrm_job_log job_log LEFT JOIN civicrm_job job ON job.id = job_log.id SET job_id = NULL WHERE job.id IS NULL'; + CRM_Core_DAO::executeQuery($updateQuery); + + // Add the foreign key + if (!CRM_Core_BAO_SchemaHandler::checkFKExists('civicrm_job_log', 'FK_civicrm_job_log_job_id')) { + $sql = CRM_Core_BAO_SchemaHandler::buildForeignKeySQL([ + 'fk_table_name' => 'civicrm_job', + 'fk_field_name' => 'id', + 'name' => 'job_id', + 'fk_attributes' => ' ON DELETE SET NULL', + ], "\n", " ADD ", 'civicrm_job_log'); + CRM_Core_DAO::executeQuery("ALTER TABLE civicrm_job_log " . $sql, [], TRUE, NULL, FALSE, FALSE); + } + return TRUE; + } + +} diff --git a/civicrm/CRM/Upgrade/Incremental/sql/5.60.alpha1.mysql.tpl b/civicrm/CRM/Upgrade/Incremental/sql/5.60.alpha1.mysql.tpl new file mode 100644 index 0000000000..d1ecc1174d --- /dev/null +++ b/civicrm/CRM/Upgrade/Incremental/sql/5.60.alpha1.mysql.tpl @@ -0,0 +1 @@ +{* file to handle db changes in 5.60.alpha1 during upgrade *} diff --git a/civicrm/CRM/Upgrade/Snapshot.php b/civicrm/CRM/Upgrade/Snapshot.php index 941f1fe127..90b66e418b 100644 --- a/civicrm/CRM/Upgrade/Snapshot.php +++ b/civicrm/CRM/Upgrade/Snapshot.php @@ -207,12 +207,11 @@ class CRM_Upgrade_Snapshot { $query = ' SELECT TABLE_NAME as tableName FROM INFORMATION_SCHEMA.TABLES - WHERE TABLE_SCHEMA = %1 - AND TABLE_NAME LIKE %2 + WHERE TABLE_SCHEMA = DATABASE() + AND TABLE_NAME LIKE %1 '; $tables = CRM_Core_DAO::executeQuery($query, [ - 1 => [$dao->database(), 'String'], - 2 => ["snap_{$owner}_v%", 'String'], + 1 => ["snap_{$owner}_v%", 'String'], ])->fetchMap('tableName', 'tableName'); $oldTables = array_filter($tables, function($table) use ($owner, $cutoff) { diff --git a/civicrm/CRM/Utils/Address/BatchUpdate.php b/civicrm/CRM/Utils/Address/BatchUpdate.php index d26d35941b..e00460b990 100644 --- a/civicrm/CRM/Utils/Address/BatchUpdate.php +++ b/civicrm/CRM/Utils/Address/BatchUpdate.php @@ -134,7 +134,10 @@ class CRM_Utils_Address_BatchUpdate { $clause[] = '( a.country_id is not null )'; } - $whereClause = implode(' AND ', $clause); + $whereClause = ''; + if (!empty($clause)) { + $whereClause = 'WHERE ' . implode(' AND ', $clause); + } $query = " SELECT c.id, @@ -152,7 +155,7 @@ class CRM_Utils_Address_BatchUpdate { ON a.country_id = o.id LEFT JOIN civicrm_state_province s ON a.state_province_id = s.id - WHERE {$whereClause} + {$whereClause} ORDER BY a.id "; diff --git a/civicrm/CRM/Utils/Array.php b/civicrm/CRM/Utils/Array.php index cf03d320b0..da71c11971 100644 --- a/civicrm/CRM/Utils/Array.php +++ b/civicrm/CRM/Utils/Array.php @@ -580,6 +580,10 @@ class CRM_Utils_Array { $collator = new Collator($lcMessages . '.utf8'); $collator->asort($array); } + elseif (version_compare(PHP_VERSION, '8', '<') && class_exists('Collator')) { + $collator = new Collator('en_US.utf8'); + $collator->asort($array); + } else { // This calls PHP's built-in asort(). asort($array); diff --git a/civicrm/CRM/Utils/FakeObject.php b/civicrm/CRM/Utils/FakeObject.php index a20246fe6b..a5d653f5a6 100644 --- a/civicrm/CRM/Utils/FakeObject.php +++ b/civicrm/CRM/Utils/FakeObject.php @@ -29,7 +29,12 @@ class CRM_Utils_FakeObject { /** - * @param $array + * @var array + */ + protected $array; + + /** + * @param array $array */ public function __construct($array) { $this->array = $array; diff --git a/civicrm/CRM/Utils/Mail/Incoming.php b/civicrm/CRM/Utils/Mail/Incoming.php index d5911ac015..86b80dd733 100644 --- a/civicrm/CRM/Utils/Mail/Incoming.php +++ b/civicrm/CRM/Utils/Mail/Incoming.php @@ -400,7 +400,7 @@ class CRM_Utils_Mail_Incoming { * @param $mail * @param $createContact */ - public static function parseAddress(&$address, &$params, &$subParam, &$mail, $createContact = TRUE) { + private static function parseAddress(&$address, &$params, &$subParam, &$mail, $createContact = TRUE) { // CRM-9484 if (empty($address->email)) { return; diff --git a/civicrm/CRM/Utils/Mail/Logger.php b/civicrm/CRM/Utils/Mail/Logger.php index 7290609c21..66e75b704b 100644 --- a/civicrm/CRM/Utils/Mail/Logger.php +++ b/civicrm/CRM/Utils/Mail/Logger.php @@ -44,7 +44,7 @@ class CRM_Utils_Mail_Logger { * @param string[] $headers * @param string $message */ - public static function log(&$to, &$headers, &$message) { + private static function log($to, $headers, $message) { if (is_array($to)) { $toString = implode(', ', $to); $fileName = $to[0]; @@ -52,7 +52,7 @@ class CRM_Utils_Mail_Logger { else { $toString = $fileName = $to; } - $content = "To: " . $toString . "\n"; + $content = 'To: ' . $toString . "\n"; foreach ($headers as $key => $val) { $content .= "$key: $val\n"; } diff --git a/civicrm/CRM/Utils/REST.php b/civicrm/CRM/Utils/REST.php index 4c6edc9c66..0500b0d0c9 100644 --- a/civicrm/CRM/Utils/REST.php +++ b/civicrm/CRM/Utils/REST.php @@ -193,7 +193,6 @@ class CRM_Utils_REST { if ((count($args) != 3) && ($args[1] != 'ping')) { return self::error('Unknown function invocation.'); } - $store = NULL; if ($args[1] == 'ping') { return self::ping(); @@ -222,7 +221,7 @@ class CRM_Utils_REST { // At this point we know we are not calling ping which does not require authentication. // Therefore we now need a valid server key and API key. // Check and see if a valid secret API key is provided. - $api_key = CRM_Utils_Request::retrieve('api_key', 'String', $store, FALSE, NULL, 'REQUEST'); + $api_key = CRM_Utils_Request::retrieve('api_key', 'String'); if (!$api_key || strtolower($api_key) == 'null') { return self::error("FATAL: mandatory param 'api_key' (user key) missing"); } diff --git a/civicrm/CRM/Utils/Request.php b/civicrm/CRM/Utils/Request.php index b5f22a3f0f..0c60dd710d 100644 --- a/civicrm/CRM/Utils/Request.php +++ b/civicrm/CRM/Utils/Request.php @@ -69,7 +69,7 @@ class CRM_Utils_Request { * * @throws \CRM_Core_Exception */ - public static function retrieve($name, $type, &$store = NULL, $abort = FALSE, $default = NULL, $method = 'REQUEST') { + public static function retrieve($name, $type, $store = NULL, $abort = FALSE, $default = NULL, $method = 'REQUEST') { $value = NULL; switch ($method) { diff --git a/civicrm/CRM/Utils/SQL.php b/civicrm/CRM/Utils/SQL.php index 1ca298e96a..981d7cb6e5 100644 --- a/civicrm/CRM/Utils/SQL.php +++ b/civicrm/CRM/Utils/SQL.php @@ -135,30 +135,6 @@ class CRM_Utils_SQL { return TRUE; } - /** - * Does the DB version support mutliple locks per - * - * https://dev.mysql.com/doc/refman/5.7/en/miscellaneous-functions.html#function_get-lock - * - * This is a conservative measure to introduce the change which we expect to deprecate later. - * - * @todo we only check mariadb & mysql right now but maybe can add percona. - */ - public static function supportsMultipleLocks() { - static $isSupportLocks = NULL; - if (!isset($isSupportLocks)) { - $version = self::getDatabaseVersion(); - if (stripos($version, 'mariadb') !== FALSE) { - $isSupportLocks = version_compare($version, '10.0.2', '>='); - } - else { - $isSupportLocks = version_compare($version, '5.7.5', '>='); - } - } - - return $isSupportLocks; - } - /** * Get the version string for the database. * diff --git a/civicrm/CRM/Utils/String.php b/civicrm/CRM/Utils/String.php index 69f74151a0..7cb44d0fc1 100644 --- a/civicrm/CRM/Utils/String.php +++ b/civicrm/CRM/Utils/String.php @@ -692,18 +692,22 @@ class CRM_Utils_String { * @param string $string * E.g. "view all contacts". Syntax: "[prefix:]name". * @param string|null $defaultPrefix + * @param string $validPrefixPattern + * A regular expression used to determine if a prefix is valid. + * To wit: Prefixes MUST be strictly alphanumeric. * * @return array * (0 => string|NULL $prefix, 1 => string $value) */ - public static function parsePrefix($delim, $string, $defaultPrefix = NULL) { + public static function parsePrefix($delim, $string, $defaultPrefix = NULL, $validPrefixPattern = '/^[A-Za-z0-9]+$/') { $pos = strpos($string, $delim); if ($pos === FALSE) { return [$defaultPrefix, $string]; } - else { - return [substr($string, 0, $pos), substr($string, 1 + $pos)]; - } + + $lhs = substr($string, 0, $pos); + $rhs = substr($string, 1 + $pos); + return preg_match($validPrefixPattern, $lhs) ? [$lhs, $rhs] : [$defaultPrefix, $string]; } /** diff --git a/civicrm/CRM/Utils/System.php b/civicrm/CRM/Utils/System.php index 10c0672734..a280cf539a 100644 --- a/civicrm/CRM/Utils/System.php +++ b/civicrm/CRM/Utils/System.php @@ -445,13 +445,14 @@ class CRM_Utils_System { } /** - * Called from a template to compose a url. + * Compose a URL. This is a wrapper for `url()` which is optimized for use in Smarty. * + * @see \smarty_function_crmURL() * @param array $params - * List of parameters. - * + * URL properties. Keys are abbreviated ("p"<=>"path"). + * See Smarty doc for full details. * @return string - * url + * URL */ public static function crmURL($params) { $p = $params['p'] ?? NULL; @@ -1285,14 +1286,8 @@ class CRM_Utils_System { * IP address of logged in user. */ public static function ipAddress($strictIPV4 = TRUE) { - $address = $_SERVER['REMOTE_ADDR'] ?? NULL; - $config = CRM_Core_Config::singleton(); - if ($config->userSystem->is_drupal && function_exists('ip_address')) { - // drupal function handles the server being behind a proxy securely. We still have legacy ipn methods - // that reach this point without bootstrapping hence the check that the fn exists - $address = ip_address(); - } + $address = $config->userSystem->ipAddress(); // hack for safari if ($address == '::1') { diff --git a/civicrm/CRM/Utils/System/Backdrop.php b/civicrm/CRM/Utils/System/Backdrop.php index 014144bc0f..2b60e638e7 100644 --- a/civicrm/CRM/Utils/System/Backdrop.php +++ b/civicrm/CRM/Utils/System/Backdrop.php @@ -1116,4 +1116,84 @@ AND u.status = 1 ]; } + /** + * @inheritdoc + */ + public function viewsIntegration(): string { + global $databases; + $config = CRM_Core_Config::singleton(); + $text = ''; + $backdrop_prefix = ''; + if (isset($databases['default']['default']['prefix'])) { + if (is_array($databases['default']['default']['prefix'])) { + $backdrop_prefix = $databases['default']['default']['prefix']['default']; + } + else { + $backdrop_prefix = $databases['default']['default']['prefix']; + } + } + + if ($this->viewsExists() && + ( + $config->dsn != $config->userFrameworkDSN || !empty($backdrop_prefix) + ) + ) { + $text = '<div>' . ts('To enable CiviCRM Views integration, add or update the following item in the <code>settings.php</code> file:') . '</div>'; + + $tableNames = CRM_Core_DAO::getTableNames(); + asort($tableNames); + + $text .= '<pre>$database_prefix = ['; + + // Add default prefix. + $text .= "\n 'default' => '$backdrop_prefix',"; + $prefix = $this->getCRMDatabasePrefix(); + foreach ($tableNames as $tableName) { + $text .= "\n '" . str_pad($tableName . "'", 41) . " => '{$prefix}',"; + } + $text .= "\n];</pre>"; + } + + return $text; + } + + /** + * @inheritdoc + */ + public function theme(&$content, $print = FALSE, $maintenance = FALSE) { + $ret = FALSE; + + if (!$print) { + if ($maintenance) { + backdrop_set_breadcrumb(''); + backdrop_maintenance_theme(); + if ($region = CRM_Core_Region::instance('html-header', FALSE)) { + CRM_Utils_System::addHTMLHead($region->render('')); + } + print theme('maintenance_page', ['content' => $content]); + exit(); + } + $ret = TRUE; + } + $out = $content; + + if ($ret) { + return $out; + } + else { + print $out; + return NULL; + } + } + + /** + * @inheritdoc + */ + public function ipAddress():?string { + // Backdrop function handles the server being behind a proxy securely. We + // still have legacy ipn methods that reach this point without bootstrapping + // hence the check that the fn exists. + return function_exists('ip_address') ? ip_address() : ($_SERVER['REMOTE_ADDR'] ?? NULL); + } + } diff --git a/civicrm/CRM/Utils/System/Base.php b/civicrm/CRM/Utils/System/Base.php index 78e5f64601..0fe6c55f24 100644 --- a/civicrm/CRM/Utils/System/Base.php +++ b/civicrm/CRM/Utils/System/Base.php @@ -274,55 +274,8 @@ abstract class CRM_Utils_System_Base { * @todo Better to always return, and never print. */ public function theme(&$content, $print = FALSE, $maintenance = FALSE) { - $ret = FALSE; - - // TODO: Split up; this was copied verbatim from CiviCRM 4.0's multi-UF theming function - // but the parts should be copied into cleaner subclass implementations - $config = CRM_Core_Config::singleton(); - if ( - $config->userSystem->is_drupal && - function_exists('theme') && - !$print - ) { - if ($maintenance) { - drupal_set_breadcrumb(''); - drupal_maintenance_theme(); - if ($region = CRM_Core_Region::instance('html-header', FALSE)) { - CRM_Utils_System::addHTMLHead($region->render('')); - } - print theme('maintenance_page', ['content' => $content]); - exit(); - } - // TODO: Figure out why D7 returns but everyone else prints - $ret = TRUE; - } - $out = $content; - - if ( - !$print && - CRM_Core_Config::singleton()->userFramework == 'WordPress' - ) { - if (!function_exists('is_admin')) { - throw new \Exception('Function "is_admin()" is missing, even though WordPress is the user framework.'); - } - if (!defined('ABSPATH')) { - throw new \Exception('Constant "ABSPATH" is not defined, even though WordPress is the user framework.'); - } - if (is_admin()) { - require_once ABSPATH . 'wp-admin/admin-header.php'; - } - else { - // FIXME: we need to figure out to replace civicrm content on the frontend pages - } - } - - if ($ret) { - return $out; - } - else { - print $out; - return NULL; - } + print $content; + return NULL; } /** @@ -696,58 +649,11 @@ abstract class CRM_Utils_System_Base { /** * Determine the location of the CiviCRM source tree. * - * FIXME: - * 1. This was pulled out from a bigger function. It should be split - * into even smaller pieces and marked abstract. - * 2. This would be easier to compute by a calling a CMS API, but - * for whatever reason we take the hard way. - * * @return array * - url: string. ex: "http://example.com/sites/all/modules/civicrm" * - path: string. ex: "/var/www/sites/all/modules/civicrm" */ - public function getCiviSourceStorage() { - global $civicrm_root; - $config = CRM_Core_Config::singleton(); - - // Don't use $config->userFrameworkBaseURL; it has garbage on it. - // More generally, w shouldn't be using $config here. - if (!defined('CIVICRM_UF_BASEURL')) { - throw new RuntimeException('Undefined constant: CIVICRM_UF_BASEURL'); - } - $baseURL = CRM_Utils_File::addTrailingSlash(CIVICRM_UF_BASEURL, '/'); - if (CRM_Utils_System::isSSL()) { - $baseURL = str_replace('http://', 'https://', $baseURL); - } - - // @todo this function is only called / code is only reached when is_drupal is true - move this to the drupal classes - // and don't implement here. - if ($this->is_drupal) { - // Drupal setting - // check and see if we are installed in sites/all (for D5 and above) - // we dont use checkURL since drupal generates an error page and throws - // the system for a loop on lobo's macosx box - // or in modules - $cmsPath = $config->userSystem->cmsRootPath(); - $userFrameworkResourceURL = $baseURL . str_replace("$cmsPath/", '', - str_replace('\\', '/', $civicrm_root) - ); - - $siteName = $config->userSystem->parseDrupalSiteNameFromRoot($civicrm_root); - if ($siteName) { - $civicrmDirName = trim(basename($civicrm_root)); - $userFrameworkResourceURL = $baseURL . "sites/$siteName/modules/$civicrmDirName/"; - } - } - else { - $userFrameworkResourceURL = ''; - } - - return [ - 'url' => CRM_Utils_File::addTrailingSlash($userFrameworkResourceURL, '/'), - 'path' => CRM_Utils_File::addTrailingSlash($civicrm_root), - ]; - } + abstract public function getCiviSourceStorage():array; /** * Perform any post login activities required by the CMS. @@ -769,7 +675,7 @@ abstract class CRM_Utils_System_Base { $timeZoneOffset = $this->getTimeZoneOffset(); if ($timeZoneOffset) { $sql = "SET time_zone = '$timeZoneOffset'"; - CRM_Core_DAO::executequery($sql); + CRM_Core_DAO::executeQuery($sql); } } @@ -970,8 +876,9 @@ abstract class CRM_Utils_System_Base { * Log error to CMS. * * @param string $message + * @param string|NULL $priority */ - public function logger($message) { + public function logger($message, $priority = NULL) { } /** @@ -1159,4 +1066,70 @@ abstract class CRM_Utils_System_Base { public function checkUserNameEmailExists(&$params, &$errors, $emailName = 'email') { } + /** + * Has CMS users table + * + * @return bool + */ + public function hasUsersTable():bool { + return FALSE; + } + + /** + * CiviCRM Table prefixes + * To display for CMS integration. + * + * @return string + */ + public function viewsIntegration():string { + return ''; + } + + /** + * Can set base page for CiviCRM + * By default, CiviCRM will generate front-facing pages + * using the home page. This allows a different template + * for CiviCRM pages. + * @return bool + */ + public function canSetBasePage():bool { + return FALSE; + } + + /** + * Get the client's IP address. + * + * @return string + * IP address + */ + public function ipAddress():?string { + return $_SERVER['REMOTE_ADDR'] ?? NULL; + } + + /** + * Check if mailing workflow is enabled + * + * @return bool + */ + public function mailingWorkflowIsEnabled():bool { + return FALSE; + } + + /** + * Get Contact details from User + * The contact parameters here will be used to create a Contact + * record to match the user record. + * + * @param array $uf_match + * Array of user object, unique ID. + * @return array + * Array of contact parameters. + */ + public function getContactDetailsFromUser($uf_match):array { + $contactParameters = []; + $contactParameters['email'] = $uf_match['user']->email; + + return $contactParameters; + } + } diff --git a/civicrm/CRM/Utils/System/Drupal.php b/civicrm/CRM/Utils/System/Drupal.php index ee2c36eaad..a645c8b722 100644 --- a/civicrm/CRM/Utils/System/Drupal.php +++ b/civicrm/CRM/Utils/System/Drupal.php @@ -852,4 +852,83 @@ AND u.status = 1 } } + /** + * @inheritdoc + */ + public function viewsIntegration(): string { + global $databases; + $config = CRM_Core_Config::singleton(); + $text = ''; + $drupal_prefix = ''; + if (isset($databases['default']['default']['prefix'])) { + if (is_array($databases['default']['default']['prefix'])) { + $drupal_prefix = $databases['default']['default']['prefix']['default']; + } + else { + $drupal_prefix = $databases['default']['default']['prefix']; + } + } + + if ($this->viewsExists() && + ( + $config->dsn != $config->userFrameworkDSN || !empty($drupal_prefix) + ) + ) { + $text = '<div>' . ts('To enable CiviCRM Views integration, add or update the following item in the <code>settings.php</code> file:') . '</div>'; + + $tableNames = CRM_Core_DAO::getTableNames(); + asort($tableNames); + $text .= '<pre>$databases[\'default\'][\'default\'][\'prefix\']= ['; + + // Add default prefix. + $text .= "\n 'default' => '$drupal_prefix',"; + $prefix = $this->getCRMDatabasePrefix(); + foreach ($tableNames as $tableName) { + $text .= "\n '" . str_pad($tableName . "'", 41) . " => '{$prefix}',"; + } + $text .= "\n];</pre>"; + } + + return $text; + } + + /** + * @inheritdoc + */ + public function theme(&$content, $print = FALSE, $maintenance = FALSE) { + $ret = FALSE; + + if (!$print) { + if ($maintenance) { + drupal_set_breadcrumb(''); + drupal_maintenance_theme(); + if ($region = CRM_Core_Region::instance('html-header', FALSE)) { + CRM_Utils_System::addHTMLHead($region->render('')); + } + print theme('maintenance_page', ['content' => $content]); + exit(); + } + $ret = TRUE; + } + $out = $content; + + if ($ret) { + return $out; + } + else { + print $out; + return NULL; + } + } + + /** + * @inheritdoc + */ + public function ipAddress():?string { + // Drupal function handles the server being behind a proxy securely. We + // still have legacy ipn methods that reach this point without bootstrapping + // hence the check that the fn exists. + return function_exists('ip_address') ? ip_address() : ($_SERVER['REMOTE_ADDR'] ?? NULL); + } + } diff --git a/civicrm/CRM/Utils/System/Drupal8.php b/civicrm/CRM/Utils/System/Drupal8.php index c65589d53a..e72f65eeb0 100644 --- a/civicrm/CRM/Utils/System/Drupal8.php +++ b/civicrm/CRM/Utils/System/Drupal8.php @@ -537,6 +537,15 @@ class CRM_Utils_System_Drupal8 extends CRM_Utils_System_DrupalBase { return 'sidebar_first'; } + /** + * @inheritDoc + */ + public function logger($message, $priority = NULL) { + if (CRM_Core_Config::singleton()->userFrameworkLogging) { + \Drupal::logger('civicrm')->log($priority ?? \Drupal\Core\Logger\RfcLogLevel::DEBUG, '%message', ['%message' => $message]); + } + } + /** * @inheritDoc */ @@ -908,4 +917,41 @@ class CRM_Utils_System_Drupal8 extends CRM_Utils_System_DrupalBase { return FALSE; } + /** + * @inheritdoc + */ + public function viewsIntegration(): string { + return '<p><strong>' . ts('To enable CiviCRM Views integration, install the <a %1>CiviCRM Entity</a> module.', [1 => 'href="https://www.drupal.org/project/civicrm_entity"']) . '</strong></p>'; + } + + /** + * @inheritdoc + */ + public function theme(&$content, $print = FALSE, $maintenance = FALSE) { + // @todo use Drupal "maintenance page" template and theme during installation + // or upgrade. + print $content; + return NULL; + } + + /** + * @inheritdoc + */ + public function ipAddress():?string { + return class_exists('Drupal') ? \Drupal::request()->getClientIp() : ($_SERVER['REMOTE_ADDR'] ?? NULL); + } + + /** + * @inheritdoc + */ + public function mailingWorkflowIsEnabled():bool { + if (!\Drupal::moduleHandler()->moduleExists('rules')) { + return FALSE; + } + + $enableWorkflow = Civi::settings()->get('civimail_workflow'); + + return (bool) $enableWorkflow; + } + } diff --git a/civicrm/CRM/Utils/System/DrupalBase.php b/civicrm/CRM/Utils/System/DrupalBase.php index d3360c2de0..a59bf97f6e 100644 --- a/civicrm/CRM/Utils/System/DrupalBase.php +++ b/civicrm/CRM/Utils/System/DrupalBase.php @@ -269,9 +269,9 @@ abstract class CRM_Utils_System_DrupalBase extends CRM_Utils_System_Base { /** * @inheritDoc */ - public function logger($message) { - if (CRM_Core_Config::singleton()->userFrameworkLogging && function_exists('watchdog')) { - watchdog('civicrm', '%message', ['%message' => $message], NULL, WATCHDOG_DEBUG); + public function logger($message, $priority = NULL) { + if (CRM_Core_Config::singleton()->userFrameworkLogging) { + watchdog('civicrm', '%message', ['%message' => $message], $priority ?? WATCHDOG_DEBUG); } } @@ -321,6 +321,44 @@ abstract class CRM_Utils_System_DrupalBase extends CRM_Utils_System_Base { } } + /** + * @inheritdoc + */ + public function getCiviSourceStorage():array { + global $civicrm_root; + $config = CRM_Core_Config::singleton(); + + // Don't use $config->userFrameworkBaseURL; it has garbage on it. + // More generally, w shouldn't be using $config here. + if (!defined('CIVICRM_UF_BASEURL')) { + throw new RuntimeException('Undefined constant: CIVICRM_UF_BASEURL'); + } + $baseURL = CRM_Utils_File::addTrailingSlash(CIVICRM_UF_BASEURL, '/'); + if (CRM_Utils_System::isSSL()) { + $baseURL = str_replace('http://', 'https://', $baseURL); + } + + // Check and see if we are installed in sites/all (for D5 and above). + // We dont use checkURL since drupal generates an error page and throws + // the system for a loop on lobo's macosx box + // or in modules. + $cmsPath = $config->userSystem->cmsRootPath(); + $userFrameworkResourceURL = $baseURL . str_replace("$cmsPath/", '', + str_replace('\\', '/', $civicrm_root) + ); + + $siteName = $config->userSystem->parseDrupalSiteNameFromRoot($civicrm_root); + if ($siteName) { + $civicrmDirName = trim(basename($civicrm_root)); + $userFrameworkResourceURL = $baseURL . "sites/$siteName/modules/$civicrmDirName/"; + } + + return [ + 'url' => CRM_Utils_File::addTrailingSlash($userFrameworkResourceURL, '/'), + 'path' => CRM_Utils_File::addTrailingSlash($civicrm_root), + ]; + } + /** * @inheritDoc */ @@ -528,6 +566,13 @@ abstract class CRM_Utils_System_DrupalBase extends CRM_Utils_System_Base { return $this->url($_GET['q']); } + /** + * @inheritdoc + */ + public function hasUsersTable():bool { + return TRUE; + } + /** * Get an array of user details for a contact, containing at minimum the user ID & name. * @@ -756,4 +801,27 @@ abstract class CRM_Utils_System_DrupalBase extends CRM_Utils_System_Base { return $emailName; } + /** + * @inheritdoc + */ + public function mailingWorkflowIsEnabled():bool { + if (!module_exists('rules')) { + return FALSE; + } + + $enableWorkflow = Civi::settings()->get('civimail_workflow'); + + return (bool) $enableWorkflow; + } + + /** + * @inheritdoc + */ + public function getContactDetailsFromUser($uf_match):array { + $contactParameters = []; + $contactParameters['email'] = $uf_match['uniqId']; + + return $contactParameters; + } + } diff --git a/civicrm/CRM/Utils/System/Joomla.php b/civicrm/CRM/Utils/System/Joomla.php index f5b2bb007b..d91cc5f7f7 100644 --- a/civicrm/CRM/Utils/System/Joomla.php +++ b/civicrm/CRM/Utils/System/Joomla.php @@ -968,7 +968,7 @@ class CRM_Utils_System_Joomla extends CRM_Utils_System_Base { * - url: string. ex: "http://example.com/sites/all/modules/civicrm" * - path: string. ex: "/var/www/sites/all/modules/civicrm" */ - public function getCiviSourceStorage() { + public function getCiviSourceStorage():array { global $civicrm_root; if (!defined('CIVICRM_UF_BASEURL')) { throw new RuntimeException('Undefined constant: CIVICRM_UF_BASEURL'); @@ -1017,4 +1017,18 @@ class CRM_Utils_System_Joomla extends CRM_Utils_System_Base { ]; } + /** + * @inheritdoc + */ + public function getContactDetailsFromUser($uf_match):array { + $contactParameters = []; + $user = $uf_match['user']; + $contactParameters['email'] = $user->email; + if ($user->name) { + CRM_Utils_String::extractName($user->name, $contactParameters); + } + + return $contactParameters; + } + } diff --git a/civicrm/CRM/Utils/System/Soap.php b/civicrm/CRM/Utils/System/Soap.php index 4c9c633507..28242abec1 100644 --- a/civicrm/CRM/Utils/System/Soap.php +++ b/civicrm/CRM/Utils/System/Soap.php @@ -122,4 +122,20 @@ class CRM_Utils_System_Soap extends CRM_Utils_System_Base { throw new \RuntimeException("Not implemented"); } + /** + * @inheritdoc + */ + public function getCiviSourceStorage():array { + global $civicrm_root; + + if (!defined('CIVICRM_UF_BASEURL')) { + throw new RuntimeException('Undefined constant: CIVICRM_UF_BASEURL'); + } + + return [ + 'url' => CRM_Utils_File::addTrailingSlash('', '/'), + 'path' => CRM_Utils_File::addTrailingSlash($civicrm_root), + ]; + } + } diff --git a/civicrm/CRM/Utils/System/Standalone.php b/civicrm/CRM/Utils/System/Standalone.php index c973ac8381..e9b7355a28 100644 --- a/civicrm/CRM/Utils/System/Standalone.php +++ b/civicrm/CRM/Utils/System/Standalone.php @@ -301,6 +301,22 @@ class CRM_Utils_System_Standalone extends CRM_Utils_System_Base { return TRUE; } + /** + * @inheritdoc + */ + public function getCiviSourceStorage(): array { + global $civicrm_root; + + if (!defined('CIVICRM_UF_BASEURL')) { + throw new RuntimeException('Undefined constant: CIVICRM_UF_BASEURL'); + } + + return [ + 'url' => CRM_Utils_File::addTrailingSlash('', '/'), + 'path' => CRM_Utils_File::addTrailingSlash($civicrm_root), + ]; + } + /** * Determine the location of the CMS root. * diff --git a/civicrm/CRM/Utils/System/UnitTests.php b/civicrm/CRM/Utils/System/UnitTests.php index 868367da48..089d4e0325 100644 --- a/civicrm/CRM/Utils/System/UnitTests.php +++ b/civicrm/CRM/Utils/System/UnitTests.php @@ -60,6 +60,22 @@ class CRM_Utils_System_UnitTests extends CRM_Utils_System_Base { return TRUE; } + /** + * @inheritdoc + */ + public function getCiviSourceStorage(): array { + global $civicrm_root; + + if (!defined('CIVICRM_UF_BASEURL')) { + throw new RuntimeException('Undefined constant: CIVICRM_UF_BASEURL'); + } + + return [ + 'url' => CRM_Utils_File::addTrailingSlash('', '/'), + 'path' => CRM_Utils_File::addTrailingSlash($civicrm_root), + ]; + } + /** * @inheritDoc */ diff --git a/civicrm/CRM/Utils/System/WordPress.php b/civicrm/CRM/Utils/System/WordPress.php index 2856631fc8..4d20f89495 100644 --- a/civicrm/CRM/Utils/System/WordPress.php +++ b/civicrm/CRM/Utils/System/WordPress.php @@ -200,7 +200,7 @@ class CRM_Utils_System_WordPress extends CRM_Utils_System_Base { * - url: string. ex: "http://example.com/sites/all/modules/civicrm" * - path: string. ex: "/var/www/sites/all/modules/civicrm" */ - public function getCiviSourceStorage() { + public function getCiviSourceStorage():array { global $civicrm_root; // Don't use $config->userFrameworkBaseURL; it has garbage on it. @@ -1624,4 +1624,52 @@ class CRM_Utils_System_WordPress extends CRM_Utils_System_Base { } + /** + * @inheritdoc + */ + public function canSetBasePage():bool { + return TRUE; + } + + /** + * @inheritdoc + */ + public function theme(&$content, $print = FALSE, $maintenance = FALSE) { + if (!$print) { + if (!function_exists('is_admin')) { + throw new \Exception('Function "is_admin()" is missing, even though WordPress is the user framework.'); + } + if (!defined('ABSPATH')) { + throw new \Exception('Constant "ABSPATH" is not defined, even though WordPress is the user framework.'); + } + if (is_admin()) { + require_once ABSPATH . 'wp-admin/admin-header.php'; + } + else { + // FIXME: we need to figure out to replace civicrm content on the frontend pages + } + } + + print $content; + return NULL; + } + + /** + * @inheritdoc + */ + public function getContactDetailsFromUser($uf_match):array { + $contactParameters = []; + + $user = $uf_match['user']; + $contactParameters['email'] = $user->user_email; + if ($user->first_name) { + $contactParameters['first_name'] = $user->first_name; + } + if ($user->last_name) { + $contactParameters['last_name'] = $user->last_name; + } + + return $contactParameters; + } + } diff --git a/civicrm/CRM/Utils/Token.php b/civicrm/CRM/Utils/Token.php index ac9ae2de9d..f29df131b7 100644 --- a/civicrm/CRM/Utils/Token.php +++ b/civicrm/CRM/Utils/Token.php @@ -683,6 +683,7 @@ class CRM_Utils_Token { $html = FALSE, $escapeSmarty = FALSE ) { + CRM_Core_Error::deprecatedFunctionWarning('token processor'); if (!$categories) { $categories = self::getTokenCategories(); } @@ -722,6 +723,7 @@ class CRM_Utils_Token { * @deprecated */ public static function parseThroughSmarty($tokenHtml, $entity, $entityType = 'contact') { + CRM_Core_Error::deprecatedFunctionWarning('no replacement'); if (defined('CIVICRM_MAIL_SMARTY') && CIVICRM_MAIL_SMARTY) { $smarty = CRM_Core_Smarty::singleton(); // also add the tokens to the template @@ -1197,6 +1199,7 @@ class CRM_Utils_Token { * @deprecated */ public static function getMembershipTokenDetails($membershipIDs) { + CRM_Core_Error::deprecatedFunctionWarning('token processor'); $memberships = civicrm_api3('membership', 'get', [ 'options' => ['limit' => 0], 'membership_id' => ['IN' => (array) $membershipIDs], @@ -1389,6 +1392,7 @@ class CRM_Utils_Token { * string with replacements made */ public static function replaceEntityTokens($entity, $entityArray, $str, $knownTokens = [], $escapeSmarty = FALSE) { + CRM_Core_Error::deprecatedFunctionWarning('token processor'); if (!$knownTokens || empty($knownTokens[$entity])) { return $str; } @@ -1720,12 +1724,15 @@ class CRM_Utils_Token { } /** + * @deprecated + * * @param $value * @param $token * * @return bool|int|mixed|string|null */ protected static function convertPseudoConstantsUsingMetadata($value, $token) { + CRM_Core_Error::deprecatedFunctionWarning('token processor'); // Convert pseudoconstants using metadata if ($value && is_numeric($value)) { $allFields = CRM_Contact_BAO_Contact::exportableFields('All'); diff --git a/civicrm/Civi/ActionSchedule/Mapping.php b/civicrm/Civi/ActionSchedule/Mapping.php index 6032dcf103..2c092ddcea 100644 --- a/civicrm/Civi/ActionSchedule/Mapping.php +++ b/civicrm/Civi/ActionSchedule/Mapping.php @@ -275,17 +275,15 @@ abstract class Mapping implements MappingInterface { asort($valueLabelMap['activity_type']); $valueLabelMap['activity_status'] = \CRM_Core_PseudoConstant::activityStatus(); - if (\CRM_Core_Component::isEnabled('CiviEvent')) { - $valueLabelMap['event_type'] = \CRM_Event_PseudoConstant::eventType(); - $valueLabelMap['civicrm_event'] = \CRM_Event_PseudoConstant::event(NULL, FALSE, "( is_template IS NULL OR is_template != 1 )"); - $valueLabelMap['civicrm_participant_status_type'] = \CRM_Event_PseudoConstant::participantStatus(NULL, NULL, 'label'); - $valueLabelMap['event_template'] = \Civi\Api4\Event::get(FALSE) - ->addWhere('is_template', '=', TRUE) - ->addWhere('is_active', '=', TRUE) - ->execute() - ->indexBy('id') - ->column('template_title'); - } + $valueLabelMap['event_type'] = \CRM_Event_PseudoConstant::eventType(); + $valueLabelMap['civicrm_event'] = \CRM_Event_PseudoConstant::event(NULL, FALSE, "( is_template IS NULL OR is_template != 1 )"); + $valueLabelMap['civicrm_participant_status_type'] = \CRM_Event_PseudoConstant::participantStatus(NULL, NULL, 'label'); + $valueLabelMap['event_template'] = \Civi\Api4\Event::get(FALSE) + ->addWhere('is_template', '=', TRUE) + ->addWhere('is_active', '=', TRUE) + ->execute() + ->indexBy('id') + ->column('template_title'); $valueLabelMap['auto_renew_options'] = \CRM_Core_OptionGroup::values('auto_renew_options'); $valueLabelMap['contact_date_reminder_options'] = \CRM_Core_OptionGroup::values('contact_date_reminder_options'); $valueLabelMap['civicrm_membership_type'] = \CRM_Member_PseudoConstant::membershipType(); diff --git a/civicrm/Civi/Angular/Coder.php b/civicrm/Civi/Angular/Coder.php index a1aa080238..9799e96594 100644 --- a/civicrm/Civi/Angular/Coder.php +++ b/civicrm/Civi/Angular/Coder.php @@ -61,8 +61,16 @@ class Coder { return $html; } + /** + * Angular is not as strict about special characters inside html attributes as the xhtml spec. + * + * This unescapes everything that angular expects to be unescaped. + * + * @param $matches + * @return string + */ protected function cleanupAttribute($matches) { - list ($full, $attr, $lquote, $value, $rquote) = $matches; + [$full, $attr, $lquote, $value, $rquote] = $matches; switch ($attr) { case 'href': @@ -72,7 +80,9 @@ class Coder { break; default: - $value = html_entity_decode($value); + $value = html_entity_decode($value, ENT_NOQUOTES); + $oppositeQuote = $lquote === '"' ? "'" : '"'; + $value = str_replace(htmlspecialchars($oppositeQuote, ENT_QUOTES), $oppositeQuote, $value); break; } diff --git a/civicrm/Civi/Api4/Action/Contact/GetDuplicates.php b/civicrm/Civi/Api4/Action/Contact/GetDuplicates.php index f39298c003..9829af3b03 100644 --- a/civicrm/Civi/Api4/Action/Contact/GetDuplicates.php +++ b/civicrm/Civi/Api4/Action/Contact/GetDuplicates.php @@ -144,6 +144,7 @@ class GetDuplicates extends \Civi\Api4\Generic\DAOCreateAction { $ignore = ['id', 'contact_id', 'is_primary', 'on_hold', 'location_type_id', 'phone_type_id']; foreach (['Contact', 'Email', 'Phone', 'Address', 'IM'] as $entity) { $entityFields = (array) civicrm_api4($entity, 'getFields', [ + 'checkPermissions' => FALSE, 'action' => 'create', 'loadOptions' => $action->getLoadOptions(), 'where' => [['name', 'NOT IN', $ignore], ['type', 'IN', ['Field', 'Custom']]], diff --git a/civicrm/Civi/Api4/DedupeException.php b/civicrm/Civi/Api4/DedupeException.php index 989506cd80..8adbeab4ac 100644 --- a/civicrm/Civi/Api4/DedupeException.php +++ b/civicrm/Civi/Api4/DedupeException.php @@ -15,7 +15,7 @@ namespace Civi\Api4; * * This api exposes CiviCRM (dedupe) exceptions. * - * @searchable none + * @searchable secondary * @see https://docs.civicrm.org/user/en/latest/organising-your-data/contacts/ * @since 5.39 * @package Civi\Api4 diff --git a/civicrm/Civi/Api4/Generic/AbstractAction.php b/civicrm/Civi/Api4/Generic/AbstractAction.php index b20c7d9fcb..9d7f3d77ad 100644 --- a/civicrm/Civi/Api4/Generic/AbstractAction.php +++ b/civicrm/Civi/Api4/Generic/AbstractAction.php @@ -227,7 +227,7 @@ abstract class AbstractAction implements \ArrayAccess { return $this->$param; case 'set': - $this->$param = $arguments[0]; + $this->$param = ReflectionUtils::castTypeSoftly($arguments[0], $this->getParamInfo()[$param] ?? []); return $this; } } diff --git a/civicrm/Civi/Api4/Generic/AbstractSaveAction.php b/civicrm/Civi/Api4/Generic/AbstractSaveAction.php index 82fac7e023..e6e6959ff4 100644 --- a/civicrm/Civi/Api4/Generic/AbstractSaveAction.php +++ b/civicrm/Civi/Api4/Generic/AbstractSaveAction.php @@ -128,7 +128,7 @@ abstract class AbstractSaveAction extends AbstractAction { if (empty($record[$primaryKey]) && !empty($this->match)) { $where = []; foreach ($record as $key => $val) { - if (isset($val) && in_array($key, $this->match, TRUE)) { + if (in_array($key, $this->match, TRUE)) { if ($val === '' || is_null($val)) { // If we want to match empty string we have to match on NULL/'' $where[] = [$key, 'IS EMPTY']; diff --git a/civicrm/Civi/Api4/Service/Schema/SchemaMapBuilder.php b/civicrm/Civi/Api4/Service/Schema/SchemaMapBuilder.php index 7401539fe2..16de8c026d 100644 --- a/civicrm/Civi/Api4/Service/Schema/SchemaMapBuilder.php +++ b/civicrm/Civi/Api4/Service/Schema/SchemaMapBuilder.php @@ -105,9 +105,15 @@ class SchemaMapBuilder extends AutoService { if (!$customInfo) { return; } + $select = ['f.name', 'f.data_type', 'f.label', 'f.column_name', 'f.option_group_id', 'f.serialize', 'f.fk_entity']; + // Prevent errors during upgrade by only selecting fields supported by the current version + $supportedFields = \CRM_Utils_Array::prefixKeys(\CRM_Core_BAO_CustomField::getSupportedFields(), 'f.'); + $select = array_intersect($select, array_keys($supportedFields)); + // Also select fields from the custom_group table (these fields are so old we don't have to worry about upgrade issues) + $select = array_merge(['g.name as custom_group_name', 'g.table_name', 'g.is_multiple'], $select); $fieldData = \CRM_Utils_SQL_Select::from('civicrm_custom_field f') ->join('custom_group', 'INNER JOIN civicrm_custom_group g ON g.id = f.custom_group_id') - ->select(['g.name as custom_group_name', 'g.table_name', 'g.is_multiple', 'f.name', 'f.data_type', 'label', 'column_name', 'option_group_id', 'serialize']) + ->select($select) ->where('g.extends IN (@entity)', ['@entity' => $customInfo['extends']]) ->where('g.is_active') ->where('f.is_active') @@ -136,6 +142,12 @@ class SchemaMapBuilder extends AutoService { $customTable->addTableLink('entity_id', $joinable); } + if ($fieldData->data_type === 'EntityReference' && isset($fieldData->fk_entity)) { + $targetTable = AllCoreTables::getTableForEntityName($fieldData->fk_entity); + $joinable = new Joinable($targetTable, 'id', $fieldData->name); + $customTable->addTableLink($fieldData->column_name, $joinable); + } + if ($fieldData->data_type === 'ContactReference') { $joinable = new Joinable('civicrm_contact', 'id', $fieldData->name); if ($fieldData->serialize) { diff --git a/civicrm/Civi/Api4/Service/Spec/CustomFieldSpec.php b/civicrm/Civi/Api4/Service/Spec/CustomFieldSpec.php index 1d5b8fe5fb..803036a336 100644 --- a/civicrm/Civi/Api4/Service/Spec/CustomFieldSpec.php +++ b/civicrm/Civi/Api4/Service/Spec/CustomFieldSpec.php @@ -38,6 +38,10 @@ class CustomFieldSpec extends FieldSpec { $dataType = 'Integer'; break; + case 'EntityReference': + $dataType = 'Integer'; + break; + case 'File': case 'StateProvince': case 'Country': diff --git a/civicrm/Civi/Api4/Service/Spec/Provider/IsCurrentFieldSpecProvider.php b/civicrm/Civi/Api4/Service/Spec/Provider/IsCurrentFieldSpecProvider.php index c031c6c2f9..29ce637ad8 100644 --- a/civicrm/Civi/Api4/Service/Spec/Provider/IsCurrentFieldSpecProvider.php +++ b/civicrm/Civi/Api4/Service/Spec/Provider/IsCurrentFieldSpecProvider.php @@ -31,7 +31,7 @@ class IsCurrentFieldSpecProvider extends \Civi\Core\Service\AutoService implemen /** * @param \Civi\Api4\Service\Spec\RequestSpec $spec */ - public function modifySpec(RequestSpec $spec) { + public function modifySpec(RequestSpec $spec): void { $field = new FieldSpec('is_current', $spec->getEntity(), 'Boolean'); $field->setLabel(ts('Is Current')) ->setTitle(ts('Current')) @@ -39,27 +39,42 @@ class IsCurrentFieldSpecProvider extends \Civi\Core\Service\AutoService implemen ->setColumnName('is_current') ->setDescription(ts('Is active with a non-past end-date')) ->setType('Extra') - ->setSqlRenderer([__CLASS__, 'renderIsCurrentSql']); + ->setSqlRenderer([__CLASS__, $this->getRenderer($field->getEntity())]); $spec->addFieldSpec($field); } + /** + * Get the function to render the sql. + * + * @param string $entity + * + * @return string + */ + private function getRenderer(string $entity): string { + if (in_array($entity, ['UserJob', 'SavedSearch'])) { + return 'renderNonExpiredSql'; + } + return 'renderIsCurrentSql'; + } + /** * @param string $entity * @param string $action * * @return bool */ - public function applies($entity, $action) { + public function applies($entity, $action): bool { if ($action !== 'get') { return FALSE; } // TODO: If we wanted this to not be a hard-coded list, we could always return TRUE here // and then in the `modifySpec` function check for the 3 fields `is_active`, `start_date`, and `end_date` - return in_array($entity, ['Relationship', 'RelationshipCache', 'Event', 'Campaign'], TRUE); + return in_array($entity, ['Relationship', 'RelationshipCache', 'Event', 'Campaign', 'SavedSearch', 'UserJob'], TRUE); } /** * @param array $field + * * return string */ public static function renderIsCurrentSql(array $field): string { @@ -71,4 +86,17 @@ class IsCurrentFieldSpecProvider extends \Civi\Core\Service\AutoService implemen return "IF($isActive = 1 AND ($startDate <= '$todayStart' OR $startDate IS NULL) AND ($endDate >= '$todayEnd' OR $endDate IS NULL), '1', '0')"; } + /** + * Render the sql clause to filter on expires date. + * + * @param array $field + * + * return string + */ + public static function renderNonExpiredSql(array $field): string { + $endDate = substr_replace($field['sql_name'], 'expires_date', -11, -1); + $todayEnd = date('Ymd'); + return "IF($endDate >= '$todayEnd' OR $endDate IS NULL, 1, 0)"; + } + } diff --git a/civicrm/Civi/Api4/Service/Spec/RequestSpec.php b/civicrm/Civi/Api4/Service/Spec/RequestSpec.php index ac711c6aa8..64c259b3cf 100644 --- a/civicrm/Civi/Api4/Service/Spec/RequestSpec.php +++ b/civicrm/Civi/Api4/Service/Spec/RequestSpec.php @@ -53,7 +53,7 @@ class RequestSpec implements \Iterator { * @param string $action * @param array $values */ - public function __construct($entity, $action, $values = []) { + public function __construct(string $entity, string $action, array $values = []) { $this->entity = $entity; $this->action = $action; $this->entityTableName = CoreUtil::getTableName($entity); diff --git a/civicrm/Civi/Api4/Service/Spec/SpecFormatter.php b/civicrm/Civi/Api4/Service/Spec/SpecFormatter.php index cfdfec5586..4f32c10772 100644 --- a/civicrm/Civi/Api4/Service/Spec/SpecFormatter.php +++ b/civicrm/Civi/Api4/Service/Spec/SpecFormatter.php @@ -37,6 +37,9 @@ class SpecFormatter { $field->setType('Field'); $field->setTableName($data['custom_group_id.table_name']); } + if ($dataTypeName === 'EntityReference') { + $field->setFkEntity($data['fk_entity']); + } $field->setColumnName($data['column_name']); $field->setNullable(empty($data['is_required'])); $field->setCustomFieldId($data['id'] ?? NULL); @@ -45,7 +48,7 @@ class SpecFormatter { $field->setLabel($data['custom_group_id.title'] . ': ' . $data['label']); $field->setHelpPre($data['help_pre'] ?? NULL); $field->setHelpPost($data['help_post'] ?? NULL); - if (self::customFieldHasOptions($data)) { + if (\CRM_Core_BAO_CustomField::hasOptions($data)) { $field->setOptionsCallback([__CLASS__, 'getOptions']); $suffixes = ['label']; if (!empty($data['option_group_id'])) { @@ -100,28 +103,6 @@ class SpecFormatter { return $field; } - /** - * Does this custom field have options - * - * @param array $field - * @return bool - */ - private static function customFieldHasOptions($field) { - // This will include boolean fields with Yes/No options. - if (in_array($field['html_type'], ['Radio', 'CheckBox'])) { - return TRUE; - } - // Do this before the "Select" string search because date fields have a "Select Date" html_type - // and contactRef fields have an "Autocomplete-Select" html_type - contacts are an FK not an option list. - if (in_array($field['data_type'], ['ContactReference', 'Date'])) { - return FALSE; - } - if (strpos($field['html_type'], 'Select') !== FALSE) { - return TRUE; - } - return !empty($field['option_group_id']); - } - /** * Get the data type from an array. Defaults to 'data_type' with fallback to * mapping for the integer value 'type' @@ -293,7 +274,7 @@ class SpecFormatter { 'Link' => 'Url', ]; $inputType = $map[$inputType] ?? $inputType; - if ($dataTypeName === 'ContactReference') { + if ($dataTypeName === 'ContactReference' || $dataTypeName === 'EntityReference') { $inputType = 'EntityRef'; } if (in_array($inputType, ['Select', 'EntityRef'], TRUE) && !empty($data['serialize'])) { diff --git a/civicrm/Civi/Api4/Service/Spec/SpecGatherer.php b/civicrm/Civi/Api4/Service/Spec/SpecGatherer.php index 849f90b758..9433a1b11e 100644 --- a/civicrm/Civi/Api4/Service/Spec/SpecGatherer.php +++ b/civicrm/Civi/Api4/Service/Spec/SpecGatherer.php @@ -32,7 +32,6 @@ class SpecGatherer extends AutoService { /** * Returns a RequestSpec with all the fields available. Uses spec providers * to add or modify field specifications. - * @see \Civi\Api4\Service\Spec\Provider\CustomFieldCreationSpecProvider * * @param string $entity * @param string $action @@ -40,8 +39,11 @@ class SpecGatherer extends AutoService { * @param array $values * * @return \Civi\Api4\Service\Spec\RequestSpec + * @throws \CRM_Core_Exception + * @see \Civi\Api4\Service\Spec\Provider\CustomFieldCreationSpecProvider + * */ - public function getSpec($entity, $action, $includeCustom, $values = []) { + public function getSpec(string $entity, string $action, bool $includeCustom, array $values = []): RequestSpec { $specification = new RequestSpec($entity, $action, $values); // Real entities diff --git a/civicrm/Civi/Api4/Utils/CoreUtil.php b/civicrm/Civi/Api4/Utils/CoreUtil.php index 630c9e7137..a50543de89 100644 --- a/civicrm/Civi/Api4/Utils/CoreUtil.php +++ b/civicrm/Civi/Api4/Utils/CoreUtil.php @@ -74,7 +74,7 @@ class CoreUtil { * * @return string */ - public static function getTableName($entityName) { + public static function getTableName(string $entityName) { return self::getInfoItem($entityName, 'table_name'); } diff --git a/civicrm/Civi/Api4/Utils/ReflectionUtils.php b/civicrm/Civi/Api4/Utils/ReflectionUtils.php index 29e5c4d6c6..409c87db04 100644 --- a/civicrm/Civi/Api4/Utils/ReflectionUtils.php +++ b/civicrm/Civi/Api4/Utils/ReflectionUtils.php @@ -216,4 +216,56 @@ class ReflectionUtils { } } + /** + * Cast the $value to the preferred $type (if we're fairly confident). + * + * This is like PHP's `settype()` but totally not. It only casts in narrow circumstances. + * This reflects an opinion that some castings are better than others. + * + * These will be converted: + * + * cast('123', 'int') => 123 + * cast('123.4', 'float') => 123.4 + * cast('0', 'bool') => FALSE + * cast(1, 'bool') => TRUE + * + * However, a string like 'hello' will never cast to bool, int, or float -- because that's + * a senseless request. We'll leave that to someone else to figure. + * + * @param mixed $value + * @param array $paramInfo + * @return mixed + * If the $value is agreeable to casting according to a type-rule from $paramInfo, then + * we return the converted value. Otherwise, return the original value. + */ + public static function castTypeSoftly($value, array $paramInfo) { + if (count($paramInfo['type'] ?? []) !== 1) { + // I don't know when or why fields can have multiple types. We're just gone leave-be. + return $value; + } + + switch ($paramInfo['type'][0]) { + case 'bool': + if (in_array($value, [0, 1, '0', '1'], TRUE)) { + return (bool) $value; + } + break; + + case 'int': + if (is_numeric($value)) { + return (int) $value; + } + break; + + case 'float': + if (is_numeric($value)) { + return (float) $value; + } + break; + + } + + return $value; + } + } diff --git a/civicrm/Civi/Schema/Traits/DataTypeSpecTrait.php b/civicrm/Civi/Schema/Traits/DataTypeSpecTrait.php index 0afbef7e26..06b38dd82b 100644 --- a/civicrm/Civi/Schema/Traits/DataTypeSpecTrait.php +++ b/civicrm/Civi/Schema/Traits/DataTypeSpecTrait.php @@ -71,7 +71,7 @@ trait DataTypeSpecTrait { } if (!in_array($dataType, $this->getValidDataTypes())) { - throw new \CRM_Core_Exception(sprintf('Invalid data type "%s', $dataType)); + throw new \CRM_Core_Exception(sprintf('Invalid data type "%s"', $dataType)); } $this->dataType = $dataType; diff --git a/civicrm/Civi/Test/Api3TestTrait.php b/civicrm/Civi/Test/Api3TestTrait.php index 22e3058cfd..49d81e97b4 100644 --- a/civicrm/Civi/Test/Api3TestTrait.php +++ b/civicrm/Civi/Test/Api3TestTrait.php @@ -74,16 +74,20 @@ trait Api3TestTrait { * Api result. * @param string $prefix * Extra test to add to message. - * @param null $expectedError + * @param string|null $expectedError */ - public function assertAPIFailure($apiResult, $prefix = '', $expectedError = NULL) { + public function assertAPIFailure(array $apiResult, string $prefix = '', ?string $expectedError = NULL): void { if (!empty($prefix)) { $prefix .= ': '; } if ($expectedError && !empty($apiResult['is_error'])) { $this->assertStringContainsString($expectedError, $apiResult['error_message'], 'api error message not as expected' . $prefix); } - $this->assertEquals(1, $apiResult['is_error'], "api call should have failed but it succeeded " . $prefix . (print_r($apiResult, TRUE))); + if (!$apiResult['is_error']) { + // This section only called when it is going to fail - that means we don't have to parse the print_r in the message + // if it is not going to be used anyway. It's really helpful for debugging when needed, but potentially expensive otherwise. + $this->fail('api call should have failed but it succeeded ' . $prefix . (print_r($apiResult, TRUE))); + } $this->assertNotEmpty($apiResult['error_message']); } diff --git a/civicrm/Civi/Token/TokenException.php b/civicrm/Civi/Token/TokenException.php index 106c762128..24ea25ce33 100644 --- a/civicrm/Civi/Token/TokenException.php +++ b/civicrm/Civi/Token/TokenException.php @@ -1,6 +1,11 @@ <?php namespace Civi\Token; +/** + * @deprecated + * + * Unused - non-compliant namespace -see https://github.com/civicrm/civicrm-core/pull/25634 + */ class TokenException extends \CRM_Core_Exception { } diff --git a/civicrm/ang/api4Explorer/Explorer.js b/civicrm/ang/api4Explorer/Explorer.js index 6fb14a55c6..ee6f2a21cd 100644 --- a/civicrm/ang/api4Explorer/Explorer.js +++ b/civicrm/ang/api4Explorer/Explorer.js @@ -798,6 +798,9 @@ code.short += ' +l ' + (params.limit || '0') + (params.offset ? ('@' + params.offset) : ''); } break; + case (typeof param === 'boolean'): + code.short += ' ' + key + '=' + (param ? 1 : 0); + break; default: code.short += ' ' + key + '=' + (typeof param === 'string' ? cliFormat(param) : cliFormat(JSON.stringify(param))); } diff --git a/civicrm/api/v3/Contribution.php b/civicrm/api/v3/Contribution.php index 9c00fe34c8..61483cb9c4 100644 --- a/civicrm/api/v3/Contribution.php +++ b/civicrm/api/v3/Contribution.php @@ -674,60 +674,6 @@ function civicrm_api3_contribution_repeattransaction($params) { $params['is_post_payment_create'] ?? NULL); } -/** - * Calls IPN complete transaction for completing or repeating a transaction. - * - * The IPN function is overloaded with two purposes - this is simply a wrapper for that - * when separating them in the api layer. - * - * @deprecated - * - * @param array $params - * @param CRM_Contribute_BAO_Contribution $contribution - * @param array $input - * - * @param array $ids - * - * @return mixed - * @throws \CRM_Core_Exception - */ -function _ipn_process_transaction($params, $contribution, $input, $ids) { - CRM_Core_Error::deprecatedFunctionWarning('API3 contribution.completetransaction or contribution.repeattransaction'); - $objects = $contribution->_relatedObjects; - $objects['contribution'] = &$contribution; - $input['component'] = $contribution->_component; - $input['is_test'] = $contribution->is_test; - $input['amount'] = empty($input['total_amount']) ? $contribution->total_amount : $input['total_amount']; - - if (isset($params['is_email_receipt'])) { - $input['is_email_receipt'] = $params['is_email_receipt']; - } - if (!empty($params['trxn_date'])) { - $input['trxn_date'] = $params['trxn_date']; - } - if (!empty($params['receive_date'])) { - $input['receive_date'] = $params['receive_date']; - } - if (empty($contribution->contribution_page_id)) { - static $domainFromName; - static $domainFromEmail; - if (empty($domainFromEmail) && (empty($params['receipt_from_name']) || empty($params['receipt_from_email']))) { - [$domainFromName, $domainFromEmail] = CRM_Core_BAO_Domain::getNameAndEmail(TRUE); - } - $input['receipt_from_name'] = CRM_Utils_Array::value('receipt_from_name', $params, $domainFromName); - $input['receipt_from_email'] = CRM_Utils_Array::value('receipt_from_email', $params, $domainFromEmail); - } - $input['card_type_id'] = $params['card_type_id'] ?? NULL; - $input['pan_truncation'] = $params['pan_truncation'] ?? NULL; - if (!empty($params['payment_instrument_id'])) { - $input['payment_instrument_id'] = $params['payment_instrument_id']; - } - return CRM_Contribute_BAO_Contribution::completeOrder($input, - !empty($objects['contributionRecur']) ? $objects['contributionRecur']->id : NULL, - $objects['contribution']->id ?? NULL, - $params['is_post_payment_create'] ?? NULL); -} - /** * Provide function metadata. * diff --git a/civicrm/api/v3/Event.php b/civicrm/api/v3/Event.php index bfedf30a9c..750f7c4625 100644 --- a/civicrm/api/v3/Event.php +++ b/civicrm/api/v3/Event.php @@ -165,9 +165,12 @@ function _civicrm_api3_event_get_legacy_support_42(&$event, $event_id) { * @param array $params * * @return array + * @throws \CRM_Core_Exception + * @noinspection PhpUnused */ -function civicrm_api3_event_delete($params) { - return CRM_Event_BAO_Event::del($params['id']) ? civicrm_api3_create_success() : civicrm_api3_create_error(ts('Error while deleting event')); +function civicrm_api3_event_delete(array $params): array { + CRM_Event_BAO_Event::deleteRecord($params); + return civicrm_api3_create_success(); } /** diff --git a/civicrm/api/v3/Generic/Getlist.php b/civicrm/api/v3/Generic/Getlist.php index ec0fb38877..53aa4526e2 100644 --- a/civicrm/api/v3/Generic/Getlist.php +++ b/civicrm/api/v3/Generic/Getlist.php @@ -41,7 +41,7 @@ function civicrm_api3_generic_getList($apiRequest) { $searchResult = _civicrm_api3_generic_getlist_get_result($request, $entity, $meta, $apiRequest); $foundIDCount = 0; - if ($forceIdSearch && !empty($result['values'])) { + if ($forceIdSearch && !empty($result['values']) && isset($idRequest['id'])) { $contactSearchID = $idRequest['id']; $foundIDCount = 1; // Merge id fetch into search result. @@ -205,7 +205,7 @@ function _civicrm_api3_generic_getList_defaults(string $entity, array &$request, // Adding one extra result allows us to see if there are any more 'limit' => $resultsPerPage + 1, // Because sql is zero-based - 'offset' => ($request['page_num'] - 1) * $resultsPerPage, + 'offset' => ($request['page_num'] > 1) ? (($request['page_num'] - 1) * $resultsPerPage) : 0, ]; } } diff --git a/civicrm/api/v3/MembershipStatus.php b/civicrm/api/v3/MembershipStatus.php index c4f6fa5f2e..036f2afbb2 100644 --- a/civicrm/api/v3/MembershipStatus.php +++ b/civicrm/api/v3/MembershipStatus.php @@ -105,16 +105,13 @@ function civicrm_api3_membership_status_update($params) { * This API is used for deleting a membership status * * @param array $params + * * @return array * @throws CRM_Core_Exception - * @throws CRM_Core_Exception + * @noinspection PhpUnused */ -function civicrm_api3_membership_status_delete($params) { - - $memberStatusDelete = CRM_Member_BAO_MembershipStatus::del($params['id'], TRUE); - if ($memberStatusDelete) { - throw new CRM_Core_Exception($memberStatusDelete['error_message']); - } +function civicrm_api3_membership_status_delete(array $params): array { + CRM_Member_BAO_MembershipStatus::deleteRecord($params); return civicrm_api3_create_success(); } diff --git a/civicrm/api/v3/OptionValue.php b/civicrm/api/v3/OptionValue.php index 34a2b00507..3c09f14624 100644 --- a/civicrm/api/v3/OptionValue.php +++ b/civicrm/api/v3/OptionValue.php @@ -91,7 +91,7 @@ function _civicrm_api3_option_value_create_spec(&$params) { function civicrm_api3_option_value_delete($params) { // We will get the option group id before deleting so we can flush pseudoconstants. $optionGroupID = civicrm_api('option_value', 'getvalue', ['version' => 3, 'id' => $params['id'], 'return' => 'option_group_id']); - $result = CRM_Core_BAO_OptionValue::del($params['id']); + $result = CRM_Core_BAO_OptionValue::deleteRecord($params); if ($result) { civicrm_api('option_value', 'getfields', ['version' => 3, 'cache_clear' => 1, 'option_group_id' => $optionGroupID]); return civicrm_api3_create_success(); diff --git a/civicrm/api/v3/Profile.php b/civicrm/api/v3/Profile.php index 78306eb6ec..4c4f78355e 100644 --- a/civicrm/api/v3/Profile.php +++ b/civicrm/api/v3/Profile.php @@ -629,8 +629,19 @@ function _civicrm_api3_order_by_weight($a, $b) { */ function _civicrm_api3_map_profile_fields_to_entity(&$field) { $entity = $field['field_type']; - $contactTypes = civicrm_api3('contact', 'getoptions', ['field' => 'contact_type']); - if (in_array($entity, $contactTypes['values'])) { + // let's get the contact types and subtypes so that we can change the entity + // of such fields to 'contact' + $result = civicrm_api3('ContactType', 'get', [ + 'return' => ["name"], + 'options' => ['limit' => 0], + ]); + + $contactTypes = []; + foreach ($result['values'] as $type) { + $contactTypes[$type['id']] = $type['name']; + } + + if (in_array($entity, $contactTypes)) { $entity = 'contact'; } $entity = _civicrm_api_get_entity_name_from_camel($entity); diff --git a/civicrm/api/v3/utils.php b/civicrm/api/v3/utils.php index 2a03f8e4a7..11507b7c0a 100644 --- a/civicrm/api/v3/utils.php +++ b/civicrm/api/v3/utils.php @@ -457,25 +457,6 @@ function _civicrm_api3_store_values(array $fields, array $params, &$values): boo return $valueFound; } -/** - * Returns field names of the given entity fields. - * - * @deprecated - * @param array $fields - * Fields array to retrieve the field names for. - * @return array - */ -function _civicrm_api3_field_names($fields) { - CRM_Core_Error::deprecatedFunctionWarning('array_column'); - $result = []; - foreach ($fields as $key => $value) { - if (!empty($value['name'])) { - $result[] = $value['name']; - } - } - return $result; -} - /** * Get function for query object api. * diff --git a/civicrm/civicrm-version.php b/civicrm/civicrm-version.php index 4b9c6850ef..efb04c7cf3 100644 --- a/civicrm/civicrm-version.php +++ b/civicrm/civicrm-version.php @@ -1,7 +1,7 @@ <?php /** @deprecated */ function civicrmVersion( ) { - return array( 'version' => '5.59.4', + return array( 'version' => '5.60.0', 'cms' => 'Wordpress', 'revision' => '' ); } diff --git a/civicrm/composer.json b/civicrm/composer.json index c227b14e87..e09f2332f5 100644 --- a/civicrm/composer.json +++ b/civicrm/composer.json @@ -52,20 +52,19 @@ "require": { "php": "~7.3 || ~8", "composer-runtime-api": "~2.0", - "cache/integration-tests": "~0.17.0", "dompdf/dompdf" : "~2.0.2", "firebase/php-jwt": ">=3 <6", "rubobaquero/phpquery": "^0.9.15", - "symfony/config": "~4.4", + "symfony/config": "~4.4 || ~6.0", "symfony/polyfill-iconv": "~1.0", - "symfony/dependency-injection": "~4.4", - "symfony/event-dispatcher": "~4.4", - "symfony/filesystem": "~4.4", - "symfony/process": "~4.4", - "symfony/var-dumper": "~3.0 || ~4.4 || ~5.1", - "symfony/service-contracts": "~2.2", + "symfony/dependency-injection": "~4.4 || ~6.0", + "symfony/event-dispatcher": "~4.4 || ~6.0", + "symfony/filesystem": "~4.4 || ~6.0", + "symfony/process": "~4.4 || ~6.0", + "symfony/var-dumper": "~3.0 || ~4.4 || ~5.1 || ~6.0", + "symfony/service-contracts": "~2.2 || ~3.1", "psr/log": "~1.0 || ~2.0 || ~3.0", - "symfony/finder": "~4.4", + "symfony/finder": "~4.4 || ~6.0", "tecnickcom/tcpdf" : "6.4.*", "totten/ca-config": "~22.11", "zetacomponents/base": "1.9.*", @@ -104,7 +103,7 @@ "symfony/polyfill-php81": "^1.0", "symfony/polyfill-php82": "^1.0", "html2text/html2text": "^4.3.1", - "psr/container": "~1.0", + "psr/container": "~1.0 || ~2.0", "ext-fileinfo": "*" }, "scripts": { diff --git a/civicrm/composer.lock b/civicrm/composer.lock index a233b0ac69..898bd6d4c6 100644 --- a/civicrm/composer.lock +++ b/civicrm/composer.lock @@ -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": "7a2de17bbccf6b8df7e6fdb1f6d2480e", + "content-hash": "18f17bf90f8002419597da6e8c7db3b1", "packages": [ { "name": "adrienrn/php-mimetyper", @@ -167,131 +167,6 @@ ], "time": "2021-10-10T11:59:43+00:00" }, - { - "name": "cache/integration-tests", - "version": "0.17.0", - "source": { - "type": "git", - "url": "https://github.com/php-cache/integration-tests.git", - "reference": "eda2e6b8bc5abcd623c8047e2345cda38dd6479e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-cache/integration-tests/zipball/eda2e6b8bc5abcd623c8047e2345cda38dd6479e", - "reference": "eda2e6b8bc5abcd623c8047e2345cda38dd6479e", - "shasum": "" - }, - "require": { - "cache/tag-interop": "^1.0", - "php": ">=5.5.9", - "psr/cache": "~1.0" - }, - "conflict": { - "phpunit/phpunit": "<4.8.35|<5.4.3,>=5.0" - }, - "require-dev": { - "cache/cache": "^1.0", - "illuminate/cache": "^5.4|^5.5|^5.6", - "mockery/mockery": "^1.0", - "symfony/cache": "^3.4.31|^4.3.4|^5.0", - "symfony/phpunit-bridge": "^5.1", - "tedivm/stash": "^0.14" - }, - "type": "library", - "autoload": { - "psr-4": { - "Cache\\IntegrationTests\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Aaron Scherer", - "email": "aequasi@gmail.com", - "homepage": "https://github.com/aequasi" - }, - { - "name": "Tobias Nyholm", - "email": "tobias.nyholm@gmail.com", - "homepage": "https://github.com/nyholm" - } - ], - "description": "Integration tests for PSR-6 and PSR-16 cache implementations", - "homepage": "https://github.com/php-cache/integration-tests", - "keywords": [ - "cache", - "psr16", - "psr6", - "test" - ], - "support": { - "issues": "https://github.com/php-cache/integration-tests/issues", - "source": "https://github.com/php-cache/integration-tests/tree/0.17.0" - }, - "time": "2020-11-03T12:52:23+00:00" - }, - { - "name": "cache/tag-interop", - "version": "1.0.0", - "source": { - "type": "git", - "url": "https://github.com/php-cache/tag-interop.git", - "reference": "c7496dd81530f538af27b4f2713cde97bc292832" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-cache/tag-interop/zipball/c7496dd81530f538af27b4f2713cde97bc292832", - "reference": "c7496dd81530f538af27b4f2713cde97bc292832", - "shasum": "" - }, - "require": { - "php": "^5.5 || ^7.0", - "psr/cache": "^1.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0-dev" - } - }, - "autoload": { - "psr-4": { - "Cache\\TagInterop\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Tobias Nyholm", - "email": "tobias.nyholm@gmail.com", - "homepage": "https://github.com/Nyholm" - }, - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com", - "homepage": "https://github.com/nicolas-grekas" - } - ], - "description": "Framework interoperable interfaces for tags", - "homepage": "http://www.php-cache.com/en/latest/", - "keywords": [ - "cache", - "psr", - "psr6", - "tag" - ], - "support": { - "issues": "https://github.com/php-cache/tag-interop/issues", - "source": "https://github.com/php-cache/tag-interop/tree/master" - }, - "time": "2017-03-13T09:14:27+00:00" - }, { "name": "civicrm/civicrm-cxn-rpc", "version": "v0.20.12.01", @@ -1524,9 +1399,13 @@ ], "support": { "issues": "https://github.com/maennchen/ZipStream-PHP/issues", - "source": "https://github.com/maennchen/ZipStream-PHP/tree/master" + "source": "https://github.com/maennchen/ZipStream-PHP/tree/2.1.0" }, "funding": [ + { + "url": "https://github.com/maennchen", + "type": "github" + }, { "url": "https://opencollective.com/zipstream", "type": "open_collective" @@ -3008,55 +2887,6 @@ ], "time": "2021-04-06T13:56:45+00:00" }, - { - "name": "psr/cache", - "version": "1.0.1", - "source": { - "type": "git", - "url": "https://github.com/php-fig/cache.git", - "reference": "d11b50ad223250cf17b86e38383413f5a6764bf8" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/cache/zipball/d11b50ad223250cf17b86e38383413f5a6764bf8", - "reference": "d11b50ad223250cf17b86e38383413f5a6764bf8", - "shasum": "" - }, - "require": { - "php": ">=5.3.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "psr-4": { - "Psr\\Cache\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" - } - ], - "description": "Common interface for caching libraries", - "keywords": [ - "cache", - "psr", - "psr-6" - ], - "support": { - "source": "https://github.com/php-fig/cache/tree/master" - }, - "time": "2016-08-06T20:24:11+00:00" - }, { "name": "psr/container", "version": "1.0.0", diff --git a/civicrm/css/civicrm.css b/civicrm/css/civicrm.css index e958d97ba0..fa52f86e9c 100644 --- a/civicrm/css/civicrm.css +++ b/civicrm/css/civicrm.css @@ -200,6 +200,7 @@ input.crm-form-checkbox + label { width: 15em; } .crm-container .huge, +input.crm-form-autocomplete, input.crm-form-entityref { width: 25em; } diff --git a/civicrm/ext/afform/admin/CRM/AfformAdmin/Upgrader.php b/civicrm/ext/afform/admin/CRM/AfformAdmin/Upgrader.php index 5a9f7ce463..4a0e63fa35 100644 --- a/civicrm/ext/afform/admin/CRM/AfformAdmin/Upgrader.php +++ b/civicrm/ext/afform/admin/CRM/AfformAdmin/Upgrader.php @@ -4,7 +4,7 @@ use CRM_AfformAdmin_ExtensionUtil as E; /** * Collection of upgrade steps. */ -class CRM_AfformAdmin_Upgrader extends CRM_AfformAdmin_Upgrader_Base { +class CRM_AfformAdmin_Upgrader extends CRM_Extension_Upgrader_Base { /** * Obsolete upgrade step, no longer does anything diff --git a/civicrm/ext/afform/admin/CRM/AfformAdmin/Upgrader/Base.php b/civicrm/ext/afform/admin/CRM/AfformAdmin/Upgrader/Base.php deleted file mode 100644 index 0e582fabb2..0000000000 --- a/civicrm/ext/afform/admin/CRM/AfformAdmin/Upgrader/Base.php +++ /dev/null @@ -1,397 +0,0 @@ -<?php - -// AUTO-GENERATED FILE -- Civix may overwrite any changes made to this file -use CRM_AfformAdmin_ExtensionUtil as E; - -/** - * Base class which provides helpers to execute upgrade logic - */ -class CRM_AfformAdmin_Upgrader_Base { - - /** - * @var CRM_AfformAdmin_Upgrader_Base - */ - public static $instance; - - /** - * @var CRM_Queue_TaskContext - */ - protected $ctx; - - /** - * @var string - * eg 'com.example.myextension' - */ - protected $extensionName; - - /** - * @var string - * full path to the extension's source tree - */ - protected $extensionDir; - - /** - * @var revisionNumber[] - * sorted numerically - */ - private $revisions; - - /** - * @var bool - * Flag to clean up extension revision data in civicrm_setting - */ - private $revisionStorageIsDeprecated = FALSE; - - /** - * Obtain a reference to the active upgrade handler. - */ - public static function instance() { - if (!self::$instance) { - // FIXME auto-generate - self::$instance = new CRM_AfformAdmin_Upgrader( - 'org.civicrm.afform_admin', - realpath(__DIR__ . '/../../../') - ); - } - return self::$instance; - } - - /** - * Adapter that lets you add normal (non-static) member functions to the queue. - * - * Note: Each upgrader instance should only be associated with one - * task-context; otherwise, this will be non-reentrant. - * - * ``` - * CRM_AfformAdmin_Upgrader_Base::_queueAdapter($ctx, 'methodName', 'arg1', 'arg2'); - * ``` - */ - public static function _queueAdapter() { - $instance = self::instance(); - $args = func_get_args(); - $instance->ctx = array_shift($args); - $instance->queue = $instance->ctx->queue; - $method = array_shift($args); - return call_user_func_array([$instance, $method], $args); - } - - /** - * CRM_AfformAdmin_Upgrader_Base constructor. - * - * @param $extensionName - * @param $extensionDir - */ - public function __construct($extensionName, $extensionDir) { - $this->extensionName = $extensionName; - $this->extensionDir = $extensionDir; - } - - // ******** Task helpers ******** - - /** - * Run a CustomData file. - * - * @param string $relativePath - * the CustomData XML file path (relative to this extension's dir) - * @return bool - */ - public function executeCustomDataFile($relativePath) { - $xml_file = $this->extensionDir . '/' . $relativePath; - return $this->executeCustomDataFileByAbsPath($xml_file); - } - - /** - * Run a CustomData file - * - * @param string $xml_file - * the CustomData XML file path (absolute path) - * - * @return bool - */ - protected function executeCustomDataFileByAbsPath($xml_file) { - $import = new CRM_Utils_Migrate_Import(); - $import->run($xml_file); - return TRUE; - } - - /** - * Run a SQL file. - * - * @param string $relativePath - * the SQL file path (relative to this extension's dir) - * - * @return bool - */ - public function executeSqlFile($relativePath) { - CRM_Utils_File::sourceSQLFile( - CIVICRM_DSN, - $this->extensionDir . DIRECTORY_SEPARATOR . $relativePath - ); - return TRUE; - } - - /** - * Run the sql commands in the specified file. - * - * @param string $tplFile - * The SQL file path (relative to this extension's dir). - * Ex: "sql/mydata.mysql.tpl". - * - * @return bool - * @throws \CRM_Core_Exception - */ - public function executeSqlTemplate($tplFile) { - // Assign multilingual variable to Smarty. - $upgrade = new CRM_Upgrade_Form(); - - $tplFile = CRM_Utils_File::isAbsolute($tplFile) ? $tplFile : $this->extensionDir . DIRECTORY_SEPARATOR . $tplFile; - $smarty = CRM_Core_Smarty::singleton(); - $smarty->assign('domainID', CRM_Core_Config::domainID()); - CRM_Utils_File::sourceSQLFile( - CIVICRM_DSN, $smarty->fetch($tplFile), NULL, TRUE - ); - return TRUE; - } - - /** - * Run one SQL query. - * - * This is just a wrapper for CRM_Core_DAO::executeSql, but it - * provides syntactic sugar for queueing several tasks that - * run different queries - * - * @return bool - */ - public function executeSql($query, $params = []) { - // FIXME verify that we raise an exception on error - CRM_Core_DAO::executeQuery($query, $params); - return TRUE; - } - - /** - * Syntactic sugar for enqueuing a task which calls a function in this class. - * - * The task is weighted so that it is processed - * as part of the currently-pending revision. - * - * After passing the $funcName, you can also pass parameters that will go to - * the function. Note that all params must be serializable. - */ - public function addTask($title) { - $args = func_get_args(); - $title = array_shift($args); - $task = new CRM_Queue_Task( - [get_class($this), '_queueAdapter'], - $args, - $title - ); - return $this->queue->createItem($task, ['weight' => -1]); - } - - // ******** Revision-tracking helpers ******** - - /** - * Determine if there are any pending revisions. - * - * @return bool - */ - public function hasPendingRevisions() { - $revisions = $this->getRevisions(); - $currentRevision = $this->getCurrentRevision(); - - if (empty($revisions)) { - return FALSE; - } - if (empty($currentRevision)) { - return TRUE; - } - - return ($currentRevision < max($revisions)); - } - - /** - * Add any pending revisions to the queue. - * - * @param CRM_Queue_Queue $queue - */ - public function enqueuePendingRevisions(CRM_Queue_Queue $queue) { - $this->queue = $queue; - - $currentRevision = $this->getCurrentRevision(); - foreach ($this->getRevisions() as $revision) { - if ($revision > $currentRevision) { - $title = E::ts('Upgrade %1 to revision %2', [ - 1 => $this->extensionName, - 2 => $revision, - ]); - - // note: don't use addTask() because it sets weight=-1 - - $task = new CRM_Queue_Task( - [get_class($this), '_queueAdapter'], - ['upgrade_' . $revision], - $title - ); - $this->queue->createItem($task); - - $task = new CRM_Queue_Task( - [get_class($this), '_queueAdapter'], - ['setCurrentRevision', $revision], - $title - ); - $this->queue->createItem($task); - } - } - } - - /** - * Get a list of revisions. - * - * @return array - * revisionNumbers sorted numerically - */ - public function getRevisions() { - if (!is_array($this->revisions)) { - $this->revisions = []; - - $clazz = new ReflectionClass(get_class($this)); - $methods = $clazz->getMethods(); - foreach ($methods as $method) { - if (preg_match('/^upgrade_(.*)/', $method->name, $matches)) { - $this->revisions[] = $matches[1]; - } - } - sort($this->revisions, SORT_NUMERIC); - } - - return $this->revisions; - } - - public function getCurrentRevision() { - $revision = CRM_Core_BAO_Extension::getSchemaVersion($this->extensionName); - if (!$revision) { - $revision = $this->getCurrentRevisionDeprecated(); - } - return $revision; - } - - private function getCurrentRevisionDeprecated() { - $key = $this->extensionName . ':version'; - if ($revision = \Civi::settings()->get($key)) { - $this->revisionStorageIsDeprecated = TRUE; - } - return $revision; - } - - public function setCurrentRevision($revision) { - CRM_Core_BAO_Extension::setSchemaVersion($this->extensionName, $revision); - // clean up legacy schema version store (CRM-19252) - $this->deleteDeprecatedRevision(); - return TRUE; - } - - private function deleteDeprecatedRevision() { - if ($this->revisionStorageIsDeprecated) { - $setting = new CRM_Core_BAO_Setting(); - $setting->name = $this->extensionName . ':version'; - $setting->delete(); - CRM_Core_Error::debug_log_message("Migrated extension schema revision ID for {$this->extensionName} from civicrm_setting (deprecated) to civicrm_extension.\n"); - } - } - - // ******** Hook delegates ******** - - /** - * @see https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_install - */ - public function onInstall() { - $files = glob($this->extensionDir . '/sql/*_install.sql'); - if (is_array($files)) { - foreach ($files as $file) { - CRM_Utils_File::sourceSQLFile(CIVICRM_DSN, $file); - } - } - $files = glob($this->extensionDir . '/sql/*_install.mysql.tpl'); - if (is_array($files)) { - foreach ($files as $file) { - $this->executeSqlTemplate($file); - } - } - $files = glob($this->extensionDir . '/xml/*_install.xml'); - if (is_array($files)) { - foreach ($files as $file) { - $this->executeCustomDataFileByAbsPath($file); - } - } - if (is_callable([$this, 'install'])) { - $this->install(); - } - } - - /** - * @see https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_postInstall - */ - public function onPostInstall() { - $revisions = $this->getRevisions(); - if (!empty($revisions)) { - $this->setCurrentRevision(max($revisions)); - } - if (is_callable([$this, 'postInstall'])) { - $this->postInstall(); - } - } - - /** - * @see https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_uninstall - */ - public function onUninstall() { - $files = glob($this->extensionDir . '/sql/*_uninstall.mysql.tpl'); - if (is_array($files)) { - foreach ($files as $file) { - $this->executeSqlTemplate($file); - } - } - if (is_callable([$this, 'uninstall'])) { - $this->uninstall(); - } - $files = glob($this->extensionDir . '/sql/*_uninstall.sql'); - if (is_array($files)) { - foreach ($files as $file) { - CRM_Utils_File::sourceSQLFile(CIVICRM_DSN, $file); - } - } - } - - /** - * @see https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_enable - */ - public function onEnable() { - // stub for possible future use - if (is_callable([$this, 'enable'])) { - $this->enable(); - } - } - - /** - * @see https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_disable - */ - public function onDisable() { - // stub for possible future use - if (is_callable([$this, 'disable'])) { - $this->disable(); - } - } - - public function onUpgrade($op, CRM_Queue_Queue $queue = NULL) { - switch ($op) { - case 'check': - return [$this->hasPendingRevisions()]; - - case 'enqueue': - return $this->enqueuePendingRevisions($queue); - - default: - } - } - -} diff --git a/civicrm/ext/afform/admin/afform_admin.civix.php b/civicrm/ext/afform/admin/afform_admin.civix.php index 82e009d93c..52866d86b8 100644 --- a/civicrm/ext/afform/admin/afform_admin.civix.php +++ b/civicrm/ext/afform/admin/afform_admin.civix.php @@ -84,27 +84,17 @@ use CRM_AfformAdmin_ExtensionUtil as E; * * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_config */ -function _afform_admin_civix_civicrm_config(&$config = NULL) { +function _afform_admin_civix_civicrm_config($config = NULL) { static $configured = FALSE; if ($configured) { return; } $configured = TRUE; - $template = CRM_Core_Smarty::singleton(); - $extRoot = __DIR__ . DIRECTORY_SEPARATOR; - $extDir = $extRoot . 'templates'; - - if (is_array($template->template_dir)) { - array_unshift($template->template_dir, $extDir); - } - else { - $template->template_dir = [$extDir, $template->template_dir]; - } - $include_path = $extRoot . PATH_SEPARATOR . get_include_path(); set_include_path($include_path); + // Based on <compatibility>, this does not currently require mixin/polyfill.php. } /** @@ -114,35 +104,7 @@ function _afform_admin_civix_civicrm_config(&$config = NULL) { */ function _afform_admin_civix_civicrm_install() { _afform_admin_civix_civicrm_config(); - if ($upgrader = _afform_admin_civix_upgrader()) { - $upgrader->onInstall(); - } -} - -/** - * Implements hook_civicrm_postInstall(). - * - * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_postInstall - */ -function _afform_admin_civix_civicrm_postInstall() { - _afform_admin_civix_civicrm_config(); - if ($upgrader = _afform_admin_civix_upgrader()) { - if (is_callable([$upgrader, 'onPostInstall'])) { - $upgrader->onPostInstall(); - } - } -} - -/** - * Implements hook_civicrm_uninstall(). - * - * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_uninstall - */ -function _afform_admin_civix_civicrm_uninstall(): void { - _afform_admin_civix_civicrm_config(); - if ($upgrader = _afform_admin_civix_upgrader()) { - $upgrader->onUninstall(); - } + // Based on <compatibility>, this does not currently require mixin/polyfill.php. } /** @@ -152,56 +114,7 @@ function _afform_admin_civix_civicrm_uninstall(): void { */ function _afform_admin_civix_civicrm_enable(): void { _afform_admin_civix_civicrm_config(); - if ($upgrader = _afform_admin_civix_upgrader()) { - if (is_callable([$upgrader, 'onEnable'])) { - $upgrader->onEnable(); - } - } -} - -/** - * (Delegated) Implements hook_civicrm_disable(). - * - * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_disable - * @return mixed - */ -function _afform_admin_civix_civicrm_disable(): void { - _afform_admin_civix_civicrm_config(); - if ($upgrader = _afform_admin_civix_upgrader()) { - if (is_callable([$upgrader, 'onDisable'])) { - $upgrader->onDisable(); - } - } -} - -/** - * (Delegated) Implements hook_civicrm_upgrade(). - * - * @param $op string, the type of operation being performed; 'check' or 'enqueue' - * @param $queue CRM_Queue_Queue, (for 'enqueue') the modifiable list of pending up upgrade tasks - * - * @return mixed - * based on op. for 'check', returns array(boolean) (TRUE if upgrades are pending) - * for 'enqueue', returns void - * - * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_upgrade - */ -function _afform_admin_civix_civicrm_upgrade($op, CRM_Queue_Queue $queue = NULL) { - if ($upgrader = _afform_admin_civix_upgrader()) { - return $upgrader->onUpgrade($op, $queue); - } -} - -/** - * @return CRM_AfformAdmin_Upgrader - */ -function _afform_admin_civix_upgrader() { - if (!file_exists(__DIR__ . '/CRM/AfformAdmin/Upgrader.php')) { - return NULL; - } - else { - return CRM_AfformAdmin_Upgrader_Base::instance(); - } + // Based on <compatibility>, this does not currently require mixin/polyfill.php. } /** @@ -285,14 +198,3 @@ function _afform_admin_civix_fixNavigationMenuItems(&$nodes, &$maxNavID, $parent } } } - -/** - * (Delegated) Implements hook_civicrm_entityTypes(). - * - * Find any *.entityType.php files, merge their content, and return. - * - * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_entityTypes - */ -function _afform_admin_civix_civicrm_entityTypes(&$entityTypes) { - $entityTypes = array_merge($entityTypes, []); -} diff --git a/civicrm/ext/afform/admin/afform_admin.php b/civicrm/ext/afform/admin/afform_admin.php index 61b588aa97..d4436ac868 100644 --- a/civicrm/ext/afform/admin/afform_admin.php +++ b/civicrm/ext/afform/admin/afform_admin.php @@ -21,24 +21,6 @@ function afform_admin_civicrm_install() { _afform_admin_civix_civicrm_install(); } -/** - * Implements hook_civicrm_postInstall(). - * - * @link http://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_postInstall - */ -function afform_admin_civicrm_postInstall() { - _afform_admin_civix_civicrm_postInstall(); -} - -/** - * Implements hook_civicrm_uninstall(). - * - * @link http://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_uninstall - */ -function afform_admin_civicrm_uninstall() { - _afform_admin_civix_civicrm_uninstall(); -} - /** * Implements hook_civicrm_enable(). * @@ -47,32 +29,3 @@ function afform_admin_civicrm_uninstall() { function afform_admin_civicrm_enable() { _afform_admin_civix_civicrm_enable(); } - -/** - * Implements hook_civicrm_disable(). - * - * @link http://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_disable - */ -function afform_admin_civicrm_disable() { - _afform_admin_civix_civicrm_disable(); -} - -/** - * Implements hook_civicrm_upgrade(). - * - * @link http://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_upgrade - */ -function afform_admin_civicrm_upgrade($op, CRM_Queue_Queue $queue = NULL) { - return _afform_admin_civix_civicrm_upgrade($op, $queue); -} - -/** - * Implements hook_civicrm_entityTypes(). - * - * Declare entity types provided by this module. - * - * @link http://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_entityTypes - */ -function afform_admin_civicrm_entityTypes(&$entityTypes) { - _afform_admin_civix_civicrm_entityTypes($entityTypes); -} diff --git a/civicrm/ext/afform/admin/ang/afGuiEditor/elements/afGuiContainer.component.js b/civicrm/ext/afform/admin/ang/afGuiEditor/elements/afGuiContainer.component.js index 06c8648d1a..79382e2ba4 100644 --- a/civicrm/ext/afform/admin/ang/afGuiEditor/elements/afGuiContainer.component.js +++ b/civicrm/ext/afform/admin/ang/afGuiEditor/elements/afGuiContainer.component.js @@ -78,9 +78,10 @@ } }; - this.getSearchDisplay = function(node) { - var searchKey = $scope.getSearchKey(node); - if (searchKey) { + // Finds a SearchDisplay within this container or within the fieldset containing this container + this.getSearchDisplay = function() { + var searchKey = ctrl.getDataEntity(); + if (searchKey && !ctrl.entityName) { return afGui.getSearchDisplay.apply(null, searchKey.split('.')); } }; @@ -416,8 +417,7 @@ var joinType = ctrl.entityName.split('-join-'); entityType = joinType[1] || (ctrl.editor && ctrl.editor.getEntity(joinType[0]).type); } else { - var searchKey = ctrl.getDataEntity(), - searchDisplay = afGui.getSearchDisplay.apply(null, searchKey.split('.')), + var searchDisplay = ctrl.getSearchDisplay(), fieldName = fieldKey.substr(fieldKey.indexOf('.') + 1), prefix = _.includes(fieldKey, '.') ? fieldKey.split('.')[0] : null; if (prefix) { diff --git a/civicrm/ext/afform/admin/ang/afGuiEditor/elements/afGuiField.component.js b/civicrm/ext/afform/admin/ang/afGuiEditor/elements/afGuiField.component.js index 1550f94faa..66136f86f6 100644 --- a/civicrm/ext/afform/admin/ang/afGuiEditor/elements/afGuiField.component.js +++ b/civicrm/ext/afform/admin/ang/afGuiEditor/elements/afGuiField.component.js @@ -89,8 +89,8 @@ this.getDefn = function() { var defn = afGui.getField(ctrl.container.getFieldEntityType(ctrl.node.name), ctrl.node.name); // Calc fields are specific to a search display, not part of the schema - if (!defn && ctrl.container.getSearchDisplay(ctrl.container.node)) { - var searchDisplay = ctrl.container.getSearchDisplay(ctrl.container.node); + if (!defn && ctrl.container.getSearchDisplay()) { + var searchDisplay = ctrl.container.getSearchDisplay(); defn = _.findWhere(searchDisplay.calc_fields, {name: ctrl.node.name}); } defn = defn || { diff --git a/civicrm/ext/afform/admin/info.xml b/civicrm/ext/afform/admin/info.xml index 72a3c53f90..857440b23c 100644 --- a/civicrm/ext/afform/admin/info.xml +++ b/civicrm/ext/afform/admin/info.xml @@ -13,10 +13,10 @@ <url desc="Licensing">http://www.gnu.org/licenses/agpl-3.0.html</url> </urls> <releaseDate>2020-01-09</releaseDate> - <version>5.59.4</version> + <version>5.60.0</version> <develStage>beta</develStage> <compatibility> - <ver>5.59</ver> + <ver>5.60</ver> </compatibility> <comments>FormBuilder provides a UI to administer and edit forms. It is an optional admin tool and not required for the forms to function.</comments> <requires> @@ -25,7 +25,7 @@ </requires> <civix> <namespace>CRM/AfformAdmin</namespace> - <format>22.10.0</format> + <format>23.02.0</format> </civix> <classloader> <psr4 prefix="Civi\" path="Civi"/> @@ -36,5 +36,7 @@ <mixin>menu-xml@1.0.0</mixin> <mixin>mgd-php@1.0.0</mixin> <mixin>afform-entity-php@1.0.0</mixin> + <mixin>smarty-v2@1.0.0</mixin> </mixins> + <upgrader>CRM_AfformAdmin_Upgrader</upgrader> </extension> diff --git a/civicrm/ext/afform/core/Civi/Api4/Action/Afform/AbstractProcessor.php b/civicrm/ext/afform/core/Civi/Api4/Action/Afform/AbstractProcessor.php index ff7105d45f..707c160afe 100644 --- a/civicrm/ext/afform/core/Civi/Api4/Action/Afform/AbstractProcessor.php +++ b/civicrm/ext/afform/core/Civi/Api4/Action/Afform/AbstractProcessor.php @@ -112,7 +112,7 @@ abstract class AbstractProcessor extends \Civi\Api4\Generic\AbstractAction { $api4 = $this->_formDataModel->getSecureApi4($entity['name']); $idField = CoreUtil::getIdFieldName($entity['type']); - if ($ids && !empty($entity['fields'][$idField]['saved_search'])) { + if ($ids && !empty($entity['fields'][$idField]['defn']['saved_search'])) { $ids = $this->validateBySavedSearch($entity, $ids); } if (!$ids) { @@ -144,6 +144,14 @@ abstract class AbstractProcessor extends \Civi\Api4\Generic\AbstractAction { } } + /** + * Validate that given id(s) are actually returned by the Autocomplete API + * + * @param $entity + * @param array $ids + * @return array + * @throws \CRM_Core_Exception + */ private function validateBySavedSearch($entity, array $ids) { $idField = CoreUtil::getIdFieldName($entity['type']); $fetched = civicrm_api4($entity['type'], 'autocomplete', [ diff --git a/civicrm/ext/afform/core/Civi/Api4/Action/Afform/Submit.php b/civicrm/ext/afform/core/Civi/Api4/Action/Afform/Submit.php index c502c51026..83bdf2d759 100644 --- a/civicrm/ext/afform/core/Civi/Api4/Action/Afform/Submit.php +++ b/civicrm/ext/afform/core/Civi/Api4/Action/Afform/Submit.php @@ -361,9 +361,11 @@ class Submit extends AbstractProcessor { ]; // Reciprocal relationship types need an extra check if ($isReciprocal) { - $where[] = ['OR', - ['AND', ['contact_id_a', '=', $contact_id_a], ['contact_id_b', '=', $contact_id_b]], - ['AND', ['contact_id_a', '=', $contact_id_b], ['contact_id_b', '=', $contact_id_a]], + $where[] = [ + 'OR', [ + ['AND', [['contact_id_a', '=', $contact_id_a], ['contact_id_b', '=', $contact_id_b]]], + ['AND', [['contact_id_a', '=', $contact_id_b], ['contact_id_b', '=', $contact_id_a]]], + ], ]; } else { diff --git a/civicrm/ext/afform/core/Civi/Api4/Subscriber/AfformAutocompleteSubscriber.php b/civicrm/ext/afform/core/Civi/Api4/Subscriber/AfformAutocompleteSubscriber.php index c94d392e50..70a1bc05ef 100644 --- a/civicrm/ext/afform/core/Civi/Api4/Subscriber/AfformAutocompleteSubscriber.php +++ b/civicrm/ext/afform/core/Civi/Api4/Subscriber/AfformAutocompleteSubscriber.php @@ -78,8 +78,15 @@ class AfformAutocompleteSubscriber extends AutoService implements EventSubscribe [$entityName, $joinEntity] = array_pad(explode('+', $entityName), 2, NULL); $entity = $formDataModel->getEntity($entityName); + // If no model entity, it's a search display + if (!$entity) { + $searchDisplay = $formDataModel->getSearchDisplay($entityName); + $apiEntity = civicrm_api4('SavedSearch', 'get', ['where' => [['name', '=', $searchDisplay['searchName']]]]) + ->first()['api_entity'] ?? NULL; + $formField = $searchDisplay['fields'][$fieldName]['defn'] ?? []; + } // If using a join (e.g. Contact -> Email) - if ($joinEntity) { + elseif ($joinEntity) { $apiEntity = $joinEntity; $isId = FALSE; $formField = $entity['joins'][$joinEntity]['fields'][$fieldName]['defn'] ?? []; @@ -97,7 +104,7 @@ class AfformAutocompleteSubscriber extends AutoService implements EventSubscribe // For the "Existing Entity" selector, // Look up the "type" fields (e.g. contact_type, activity_type_id, case_type_id, etc) // And apply it as a filter if specified on the form. - if ($isId) { + if ($isId && $entity) { if ($entity['type'] === 'Contact') { $typeFields = ['contact_type', 'contact_sub_type']; } diff --git a/civicrm/ext/afform/core/afform.civix.php b/civicrm/ext/afform/core/afform.civix.php index 85f9a14182..9519d92694 100644 --- a/civicrm/ext/afform/core/afform.civix.php +++ b/civicrm/ext/afform/core/afform.civix.php @@ -92,9 +92,6 @@ function _afform_civix_civicrm_config($config = NULL) { $configured = TRUE; $extRoot = __DIR__ . DIRECTORY_SEPARATOR; - $extDir = $extRoot . 'templates'; - CRM_Core_Smarty::singleton()->addTemplateDir($extDir); - $include_path = $extRoot . PATH_SEPARATOR . get_include_path(); set_include_path($include_path); // Based on <compatibility>, this does not currently require mixin/polyfill.php. @@ -201,20 +198,3 @@ function _afform_civix_fixNavigationMenuItems(&$nodes, &$maxNavID, $parentID) { } } } - -/** - * (Delegated) Implements hook_civicrm_entityTypes(). - * - * Find any *.entityType.php files, merge their content, and return. - * - * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_entityTypes - */ -function _afform_civix_civicrm_entityTypes(&$entityTypes) { - $entityTypes = array_merge($entityTypes, [ - 'CRM_Afform_DAO_AfformSubmission' => [ - 'name' => 'AfformSubmission', - 'class' => 'CRM_Afform_DAO_AfformSubmission', - 'table' => 'civicrm_afform_submission', - ], - ]); -} diff --git a/civicrm/ext/afform/core/afform.php b/civicrm/ext/afform/core/afform.php index b381f64801..5cb43af6f8 100644 --- a/civicrm/ext/afform/core/afform.php +++ b/civicrm/ext/afform/core/afform.php @@ -360,17 +360,6 @@ function _afform_get_partials($moduleName, $module) { ]; } -/** - * Implements hook_civicrm_entityTypes(). - * - * Declare entity types provided by this module. - * - * @link http://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_entityTypes - */ -function afform_civicrm_entityTypes(&$entityTypes) { - _afform_civix_civicrm_entityTypes($entityTypes); -} - /** * Implements hook_civicrm_buildAsset(). */ diff --git a/civicrm/ext/afform/core/ang/af/fields/EntityRef.html b/civicrm/ext/afform/core/ang/af/fields/EntityRef.html index 1b783ff44c..38447c8eaf 100644 --- a/civicrm/ext/afform/core/ang/af/fields/EntityRef.html +++ b/civicrm/ext/afform/core/ang/af/fields/EntityRef.html @@ -5,7 +5,7 @@ ng-model="getSetSelect" ng-model-options="{getterSetter: true}" crm-autocomplete="$ctrl.defn.fk_entity" - crm-autocomplete-params="{formName: 'afform:' + $ctrl.afFieldset.getFormName(), fieldName: $ctrl.afFieldset.modelName + ':' + $ctrl.fieldName}" + crm-autocomplete-params="{formName: 'afform:' + $ctrl.afFieldset.getFormName(), fieldName: $ctrl.afFieldset.getName() + ':' + $ctrl.fieldName}" multi="$ctrl.defn.input_attrs.multiple" auto-open="$ctrl.defn.input_attrs.autoOpen" placeholder="{{:: $ctrl.defn.input_attrs.placeholder }}" diff --git a/civicrm/ext/afform/core/info.xml b/civicrm/ext/afform/core/info.xml index dd0a196c11..38324b4412 100644 --- a/civicrm/ext/afform/core/info.xml +++ b/civicrm/ext/afform/core/info.xml @@ -13,15 +13,15 @@ <url desc="Licensing">http://www.gnu.org/licenses/agpl-3.0.html</url> </urls> <releaseDate>2020-01-09</releaseDate> - <version>5.59.4</version> + <version>5.60.0</version> <develStage>beta</develStage> <compatibility> - <ver>5.59</ver> + <ver>5.60</ver> </compatibility> <comments>The Form Core extension is required to use any dynamic form. To administer and edit forms, also install the FormBuilder extension.</comments> <civix> <namespace>CRM/Afform</namespace> - <format>22.12.1</format> + <format>23.02.0</format> </civix> <classloader> <psr4 prefix="Civi\" path="Civi"/> @@ -34,6 +34,8 @@ <mixin>ang-php@1.0.0</mixin> <mixin>mgd-php@1.0.0</mixin> <mixin>scan-classes@1.0.0</mixin> + <mixin>smarty-v2@1.0.0</mixin> + <mixin>entity-types-php@1.0.0</mixin> </mixins> <upgrader>CRM_Afform_Upgrader</upgrader> </extension> diff --git a/civicrm/ext/afform/html/info.xml b/civicrm/ext/afform/html/info.xml index c360e03868..a5e601ca16 100644 --- a/civicrm/ext/afform/html/info.xml +++ b/civicrm/ext/afform/html/info.xml @@ -13,10 +13,10 @@ <url desc="Licensing">http://www.gnu.org/licenses/agpl-3.0.html</url> </urls> <releaseDate>2020-01-09</releaseDate> - <version>5.59.4</version> + <version>5.60.0</version> <develStage>alpha</develStage> <compatibility> - <ver>5.59</ver> + <ver>5.60</ver> </compatibility> <requires> <ext>org.civicrm.afform</ext> diff --git a/civicrm/ext/afform/mock/info.xml b/civicrm/ext/afform/mock/info.xml index 4337a37ed2..c359d8004c 100644 --- a/civicrm/ext/afform/mock/info.xml +++ b/civicrm/ext/afform/mock/info.xml @@ -12,13 +12,13 @@ <url desc="Licensing">http://www.gnu.org/licenses/agpl-3.0.html</url> </urls> <releaseDate>2020-01-09</releaseDate> - <version>5.59.4</version> + <version>5.60.0</version> <tags> <tag>mgmt:hidden</tag> </tags> <develStage>alpha</develStage> <compatibility> - <ver>5.59</ver> + <ver>5.60</ver> </compatibility> <requires> <ext>org.civicrm.afform</ext> diff --git a/civicrm/ext/authx/authx.civix.php b/civicrm/ext/authx/authx.civix.php index 98e7ecc984..4e1b32a58e 100644 --- a/civicrm/ext/authx/authx.civix.php +++ b/civicrm/ext/authx/authx.civix.php @@ -84,27 +84,17 @@ use CRM_Authx_ExtensionUtil as E; * * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_config */ -function _authx_civix_civicrm_config(&$config = NULL) { +function _authx_civix_civicrm_config($config = NULL) { static $configured = FALSE; if ($configured) { return; } $configured = TRUE; - $template = CRM_Core_Smarty::singleton(); - $extRoot = __DIR__ . DIRECTORY_SEPARATOR; - $extDir = $extRoot . 'templates'; - - if (is_array($template->template_dir)) { - array_unshift($template->template_dir, $extDir); - } - else { - $template->template_dir = [$extDir, $template->template_dir]; - } - $include_path = $extRoot . PATH_SEPARATOR . get_include_path(); set_include_path($include_path); + // Based on <compatibility>, this does not currently require mixin/polyfill.php. } /** @@ -114,35 +104,7 @@ function _authx_civix_civicrm_config(&$config = NULL) { */ function _authx_civix_civicrm_install() { _authx_civix_civicrm_config(); - if ($upgrader = _authx_civix_upgrader()) { - $upgrader->onInstall(); - } -} - -/** - * Implements hook_civicrm_postInstall(). - * - * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_postInstall - */ -function _authx_civix_civicrm_postInstall() { - _authx_civix_civicrm_config(); - if ($upgrader = _authx_civix_upgrader()) { - if (is_callable([$upgrader, 'onPostInstall'])) { - $upgrader->onPostInstall(); - } - } -} - -/** - * Implements hook_civicrm_uninstall(). - * - * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_uninstall - */ -function _authx_civix_civicrm_uninstall(): void { - _authx_civix_civicrm_config(); - if ($upgrader = _authx_civix_upgrader()) { - $upgrader->onUninstall(); - } + // Based on <compatibility>, this does not currently require mixin/polyfill.php. } /** @@ -152,56 +114,7 @@ function _authx_civix_civicrm_uninstall(): void { */ function _authx_civix_civicrm_enable(): void { _authx_civix_civicrm_config(); - if ($upgrader = _authx_civix_upgrader()) { - if (is_callable([$upgrader, 'onEnable'])) { - $upgrader->onEnable(); - } - } -} - -/** - * (Delegated) Implements hook_civicrm_disable(). - * - * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_disable - * @return mixed - */ -function _authx_civix_civicrm_disable(): void { - _authx_civix_civicrm_config(); - if ($upgrader = _authx_civix_upgrader()) { - if (is_callable([$upgrader, 'onDisable'])) { - $upgrader->onDisable(); - } - } -} - -/** - * (Delegated) Implements hook_civicrm_upgrade(). - * - * @param $op string, the type of operation being performed; 'check' or 'enqueue' - * @param $queue CRM_Queue_Queue, (for 'enqueue') the modifiable list of pending up upgrade tasks - * - * @return mixed - * based on op. for 'check', returns array(boolean) (TRUE if upgrades are pending) - * for 'enqueue', returns void - * - * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_upgrade - */ -function _authx_civix_civicrm_upgrade($op, CRM_Queue_Queue $queue = NULL) { - if ($upgrader = _authx_civix_upgrader()) { - return $upgrader->onUpgrade($op, $queue); - } -} - -/** - * @return CRM_Authx_Upgrader - */ -function _authx_civix_upgrader() { - if (!file_exists(__DIR__ . '/CRM/Authx/Upgrader.php')) { - return NULL; - } - else { - return CRM_Authx_Upgrader_Base::instance(); - } + // Based on <compatibility>, this does not currently require mixin/polyfill.php. } /** @@ -285,14 +198,3 @@ function _authx_civix_fixNavigationMenuItems(&$nodes, &$maxNavID, $parentID) { } } } - -/** - * (Delegated) Implements hook_civicrm_entityTypes(). - * - * Find any *.entityType.php files, merge their content, and return. - * - * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_entityTypes - */ -function _authx_civix_civicrm_entityTypes(&$entityTypes) { - $entityTypes = array_merge($entityTypes, []); -} diff --git a/civicrm/ext/authx/authx.php b/civicrm/ext/authx/authx.php index f6c50359a9..432afe1d89 100644 --- a/civicrm/ext/authx/authx.php +++ b/civicrm/ext/authx/authx.php @@ -100,24 +100,6 @@ function authx_civicrm_install() { } -/** - * Implements hook_civicrm_postInstall(). - * - * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_postInstall - */ -function authx_civicrm_postInstall() { - _authx_civix_civicrm_postInstall(); -} - -/** - * Implements hook_civicrm_uninstall(). - * - * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_uninstall - */ -function authx_civicrm_uninstall() { - _authx_civix_civicrm_uninstall(); -} - /** * Implements hook_civicrm_enable(). * @@ -134,35 +116,6 @@ function authx_civicrm_enable() { } } -/** - * Implements hook_civicrm_disable(). - * - * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_disable - */ -function authx_civicrm_disable() { - _authx_civix_civicrm_disable(); -} - -/** - * Implements hook_civicrm_upgrade(). - * - * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_upgrade - */ -function authx_civicrm_upgrade($op, CRM_Queue_Queue $queue = NULL) { - return _authx_civix_civicrm_upgrade($op, $queue); -} - -/** - * Implements hook_civicrm_entityTypes(). - * - * Declare entity types provided by this module. - * - * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_entityTypes - */ -function authx_civicrm_entityTypes(&$entityTypes) { - _authx_civix_civicrm_entityTypes($entityTypes); -} - /** * Implements hook_civicrm_permission(). * diff --git a/civicrm/ext/authx/info.xml b/civicrm/ext/authx/info.xml index 358aca262d..8847d710de 100644 --- a/civicrm/ext/authx/info.xml +++ b/civicrm/ext/authx/info.xml @@ -15,10 +15,10 @@ <url desc="Licensing">http://www.gnu.org/licenses/agpl-3.0.html</url> </urls> <releaseDate>2021-02-11</releaseDate> - <version>5.59.4</version> + <version>5.60.0</version> <develStage>stable</develStage> <compatibility> - <ver>5.59</ver> + <ver>5.60</ver> </compatibility> <comments>AuthX enables remote applications to connect to CiviCRM. Use it to enable and disable different forms of authentication (such as username-password, API key, and/or JWT).</comments> <classloader> @@ -32,6 +32,6 @@ </mixins> <civix> <namespace>CRM/Authx</namespace> - <format>22.10.0</format> + <format>23.02.0</format> </civix> </extension> diff --git a/civicrm/ext/civicrm_admin_ui/civicrm_admin_ui.civix.php b/civicrm/ext/civicrm_admin_ui/civicrm_admin_ui.civix.php index ef54bbc93e..69a952d2b2 100644 --- a/civicrm/ext/civicrm_admin_ui/civicrm_admin_ui.civix.php +++ b/civicrm/ext/civicrm_admin_ui/civicrm_admin_ui.civix.php @@ -84,27 +84,17 @@ use CRM_CivicrmAdminUi_ExtensionUtil as E; * * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_config */ -function _civicrm_admin_ui_civix_civicrm_config(&$config = NULL) { +function _civicrm_admin_ui_civix_civicrm_config($config = NULL) { static $configured = FALSE; if ($configured) { return; } $configured = TRUE; - $template = CRM_Core_Smarty::singleton(); - $extRoot = __DIR__ . DIRECTORY_SEPARATOR; - $extDir = $extRoot . 'templates'; - - if (is_array($template->template_dir)) { - array_unshift($template->template_dir, $extDir); - } - else { - $template->template_dir = [$extDir, $template->template_dir]; - } - $include_path = $extRoot . PATH_SEPARATOR . get_include_path(); set_include_path($include_path); + // Based on <compatibility>, this does not currently require mixin/polyfill.php. } /** @@ -114,35 +104,7 @@ function _civicrm_admin_ui_civix_civicrm_config(&$config = NULL) { */ function _civicrm_admin_ui_civix_civicrm_install() { _civicrm_admin_ui_civix_civicrm_config(); - if ($upgrader = _civicrm_admin_ui_civix_upgrader()) { - $upgrader->onInstall(); - } -} - -/** - * Implements hook_civicrm_postInstall(). - * - * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_postInstall - */ -function _civicrm_admin_ui_civix_civicrm_postInstall() { - _civicrm_admin_ui_civix_civicrm_config(); - if ($upgrader = _civicrm_admin_ui_civix_upgrader()) { - if (is_callable([$upgrader, 'onPostInstall'])) { - $upgrader->onPostInstall(); - } - } -} - -/** - * Implements hook_civicrm_uninstall(). - * - * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_uninstall - */ -function _civicrm_admin_ui_civix_civicrm_uninstall(): void { - _civicrm_admin_ui_civix_civicrm_config(); - if ($upgrader = _civicrm_admin_ui_civix_upgrader()) { - $upgrader->onUninstall(); - } + // Based on <compatibility>, this does not currently require mixin/polyfill.php. } /** @@ -152,56 +114,7 @@ function _civicrm_admin_ui_civix_civicrm_uninstall(): void { */ function _civicrm_admin_ui_civix_civicrm_enable(): void { _civicrm_admin_ui_civix_civicrm_config(); - if ($upgrader = _civicrm_admin_ui_civix_upgrader()) { - if (is_callable([$upgrader, 'onEnable'])) { - $upgrader->onEnable(); - } - } -} - -/** - * (Delegated) Implements hook_civicrm_disable(). - * - * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_disable - * @return mixed - */ -function _civicrm_admin_ui_civix_civicrm_disable(): void { - _civicrm_admin_ui_civix_civicrm_config(); - if ($upgrader = _civicrm_admin_ui_civix_upgrader()) { - if (is_callable([$upgrader, 'onDisable'])) { - $upgrader->onDisable(); - } - } -} - -/** - * (Delegated) Implements hook_civicrm_upgrade(). - * - * @param $op string, the type of operation being performed; 'check' or 'enqueue' - * @param $queue CRM_Queue_Queue, (for 'enqueue') the modifiable list of pending up upgrade tasks - * - * @return mixed - * based on op. for 'check', returns array(boolean) (TRUE if upgrades are pending) - * for 'enqueue', returns void - * - * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_upgrade - */ -function _civicrm_admin_ui_civix_civicrm_upgrade($op, CRM_Queue_Queue $queue = NULL) { - if ($upgrader = _civicrm_admin_ui_civix_upgrader()) { - return $upgrader->onUpgrade($op, $queue); - } -} - -/** - * @return CRM_CivicrmAdminUi_Upgrader - */ -function _civicrm_admin_ui_civix_upgrader() { - if (!file_exists(__DIR__ . '/CRM/CivicrmAdminUi/Upgrader.php')) { - return NULL; - } - else { - return CRM_CivicrmAdminUi_Upgrader_Base::instance(); - } + // Based on <compatibility>, this does not currently require mixin/polyfill.php. } /** @@ -285,14 +198,3 @@ function _civicrm_admin_ui_civix_fixNavigationMenuItems(&$nodes, &$maxNavID, $pa } } } - -/** - * (Delegated) Implements hook_civicrm_entityTypes(). - * - * Find any *.entityType.php files, merge their content, and return. - * - * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_entityTypes - */ -function _civicrm_admin_ui_civix_civicrm_entityTypes(&$entityTypes) { - $entityTypes = array_merge($entityTypes, []); -} diff --git a/civicrm/ext/civicrm_admin_ui/civicrm_admin_ui.php b/civicrm/ext/civicrm_admin_ui/civicrm_admin_ui.php index 456b78b883..85db9c3277 100644 --- a/civicrm/ext/civicrm_admin_ui/civicrm_admin_ui.php +++ b/civicrm/ext/civicrm_admin_ui/civicrm_admin_ui.php @@ -13,14 +13,3 @@ use CRM_CivicrmAdminUi_ExtensionUtil as E; function civicrm_admin_ui_civicrm_config(&$config) { _civicrm_admin_ui_civix_civicrm_config($config); } - -/** - * Implements hook_civicrm_entityTypes(). - * - * Declare entity types provided by this module. - * - * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_entityTypes - */ -function civicrm_admin_ui_civicrm_entityTypes(&$entityTypes) { - _civicrm_admin_ui_civix_civicrm_entityTypes($entityTypes); -} diff --git a/civicrm/ext/civicrm_admin_ui/info.xml b/civicrm/ext/civicrm_admin_ui/info.xml index 1cf065a4c3..55f7fdc0b8 100644 --- a/civicrm/ext/civicrm_admin_ui/info.xml +++ b/civicrm/ext/civicrm_admin_ui/info.xml @@ -15,10 +15,10 @@ <url desc="Licensing">http://www.gnu.org/licenses/agpl-3.0.html</url> </urls> <releaseDate>2022-01-02</releaseDate> - <version>5.59.4</version> + <version>5.60.0</version> <develStage>alpha</develStage> <compatibility> - <ver>5.59</ver> + <ver>5.60</ver> </compatibility> <requires> <ext>org.civicrm.search_kit</ext> @@ -32,7 +32,7 @@ <civix> <namespace>CRM/CivicrmAdminUi</namespace> <angularModule>crmCivicrmAdminUi</angularModule> - <format>22.10.0</format> + <format>23.02.0</format> </civix> <mixins> <mixin>mgd-php@1.0.0</mixin> diff --git a/civicrm/ext/civigrant/civigrant.civix.php b/civicrm/ext/civigrant/civigrant.civix.php index 0b066cd2fa..2b49bd6d7a 100644 --- a/civicrm/ext/civigrant/civigrant.civix.php +++ b/civicrm/ext/civigrant/civigrant.civix.php @@ -84,7 +84,7 @@ use CRM_Grant_ExtensionUtil as E; * * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_config */ -function _civigrant_civix_civicrm_config(&$config = NULL) { +function _civigrant_civix_civicrm_config($config = NULL) { static $configured = FALSE; if ($configured) { return; @@ -94,6 +94,7 @@ function _civigrant_civix_civicrm_config(&$config = NULL) { $extRoot = __DIR__ . DIRECTORY_SEPARATOR; $include_path = $extRoot . PATH_SEPARATOR . get_include_path(); set_include_path($include_path); + // Based on <compatibility>, this does not currently require mixin/polyfill.php. } /** @@ -103,35 +104,7 @@ function _civigrant_civix_civicrm_config(&$config = NULL) { */ function _civigrant_civix_civicrm_install() { _civigrant_civix_civicrm_config(); - if ($upgrader = _civigrant_civix_upgrader()) { - $upgrader->onInstall(); - } -} - -/** - * Implements hook_civicrm_postInstall(). - * - * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_postInstall - */ -function _civigrant_civix_civicrm_postInstall() { - _civigrant_civix_civicrm_config(); - if ($upgrader = _civigrant_civix_upgrader()) { - if (is_callable([$upgrader, 'onPostInstall'])) { - $upgrader->onPostInstall(); - } - } -} - -/** - * Implements hook_civicrm_uninstall(). - * - * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_uninstall - */ -function _civigrant_civix_civicrm_uninstall(): void { - _civigrant_civix_civicrm_config(); - if ($upgrader = _civigrant_civix_upgrader()) { - $upgrader->onUninstall(); - } + // Based on <compatibility>, this does not currently require mixin/polyfill.php. } /** @@ -141,56 +114,7 @@ function _civigrant_civix_civicrm_uninstall(): void { */ function _civigrant_civix_civicrm_enable(): void { _civigrant_civix_civicrm_config(); - if ($upgrader = _civigrant_civix_upgrader()) { - if (is_callable([$upgrader, 'onEnable'])) { - $upgrader->onEnable(); - } - } -} - -/** - * (Delegated) Implements hook_civicrm_disable(). - * - * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_disable - * @return mixed - */ -function _civigrant_civix_civicrm_disable(): void { - _civigrant_civix_civicrm_config(); - if ($upgrader = _civigrant_civix_upgrader()) { - if (is_callable([$upgrader, 'onDisable'])) { - $upgrader->onDisable(); - } - } -} - -/** - * (Delegated) Implements hook_civicrm_upgrade(). - * - * @param $op string, the type of operation being performed; 'check' or 'enqueue' - * @param $queue CRM_Queue_Queue, (for 'enqueue') the modifiable list of pending up upgrade tasks - * - * @return mixed - * based on op. for 'check', returns array(boolean) (TRUE if upgrades are pending) - * for 'enqueue', returns void - * - * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_upgrade - */ -function _civigrant_civix_civicrm_upgrade($op, CRM_Queue_Queue $queue = NULL) { - if ($upgrader = _civigrant_civix_upgrader()) { - return $upgrader->onUpgrade($op, $queue); - } -} - -/** - * @return CRM_Grant_Upgrader - */ -function _civigrant_civix_upgrader() { - if (!file_exists(__DIR__ . '/CRM/Grant/Upgrader.php')) { - return NULL; - } - else { - return CRM_Grant_Upgrader_Base::instance(); - } + // Based on <compatibility>, this does not currently require mixin/polyfill.php. } /** @@ -274,20 +198,3 @@ function _civigrant_civix_fixNavigationMenuItems(&$nodes, &$maxNavID, $parentID) } } } - -/** - * (Delegated) Implements hook_civicrm_entityTypes(). - * - * Find any *.entityType.php files, merge their content, and return. - * - * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_entityTypes - */ -function _civigrant_civix_civicrm_entityTypes(&$entityTypes) { - $entityTypes = array_merge($entityTypes, [ - 'CRM_Grant_DAO_Grant' => [ - 'name' => 'Grant', - 'class' => 'CRM_Grant_DAO_Grant', - 'table' => 'civicrm_grant', - ], - ]); -} diff --git a/civicrm/ext/civigrant/civigrant.php b/civicrm/ext/civigrant/civigrant.php index bd14f68621..9f4ca39e70 100644 --- a/civicrm/ext/civigrant/civigrant.php +++ b/civicrm/ext/civigrant/civigrant.php @@ -12,17 +12,6 @@ function civigrant_civicrm_config(&$config) { _civigrant_civix_civicrm_config($config); } -/** - * Implements hook_civicrm_entityTypes(). - * - * Declare entity types provided by this module. - * - * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_entityTypes - */ -function civigrant_civicrm_entityTypes(&$entityTypes) { - _civigrant_civix_civicrm_entityTypes($entityTypes); -} - /** * Implements hook_civicrm_links(). * diff --git a/civicrm/ext/civigrant/info.xml b/civicrm/ext/civigrant/info.xml index 17a488eb54..640df3e62a 100644 --- a/civicrm/ext/civigrant/info.xml +++ b/civicrm/ext/civigrant/info.xml @@ -13,10 +13,10 @@ <url desc="Licensing">http://www.gnu.org/licenses/agpl-3.0.html</url> </urls> <releaseDate>2021-11-11</releaseDate> - <version>5.59.4</version> + <version>5.60.0</version> <develStage>stable</develStage> <compatibility> - <ver>5.59</ver> + <ver>5.60</ver> </compatibility> <comments>CiviGrant was originally a core component before migrating to an extension</comments> <requires> @@ -33,9 +33,10 @@ <mixin>mgd-php@1.0.0</mixin> <mixin>afform-entity-php@1.0.0</mixin> <mixin>smarty-v2@1.0.0</mixin> + <mixin>entity-types-php@1.0.0</mixin> </mixins> <civix> <namespace>CRM/Grant</namespace> - <format>22.10.0</format> + <format>23.02.0</format> </civix> </extension> diff --git a/civicrm/ext/civigrant/templates/CRM/Grant/Form/Task/Delete.tpl b/civicrm/ext/civigrant/templates/CRM/Grant/Form/Task/Delete.tpl index 85f3168b06..be3e263e63 100644 --- a/civicrm/ext/civigrant/templates/CRM/Grant/Form/Task/Delete.tpl +++ b/civicrm/ext/civigrant/templates/CRM/Grant/Form/Task/Delete.tpl @@ -14,5 +14,5 @@ {ts}Are you sure you want to delete the selected Grants? This delete operation cannot be undone and will delete all transactions associated with these grants.{/ts} <p>{include file="CRM/Grant/Form/Task.tpl"}</p> </div> - <div class="crm-submit-buttons">{include file="CRM/common/formButtons.tpl"}</div> + <div class="crm-submit-buttons">{include file="CRM/common/formButtons.tpl" location=''}</div> </div> diff --git a/civicrm/ext/civiimport/Civi/Api4/Event/Subscriber/ImportSubscriber.php b/civicrm/ext/civiimport/Civi/Api4/Event/Subscriber/ImportSubscriber.php index 4ee6bbbe5e..0eade33f0d 100644 --- a/civicrm/ext/civiimport/Civi/Api4/Event/Subscriber/ImportSubscriber.php +++ b/civicrm/ext/civiimport/Civi/Api4/Event/Subscriber/ImportSubscriber.php @@ -104,7 +104,7 @@ class ImportSubscriber extends AutoService implements EventSubscriberInterface { public function onApiAuthorize(AuthorizeEvent $event): void { $apiRequest = $event->getApiRequest(); $entity = $apiRequest['entity']; - if (strpos($entity, 'Import_') === 0) { + if (strpos($entity, 'Import_') === 0 && !in_array($event->getActionName(), ['getFields', 'getActions', 'checkAccess'], TRUE)) { $userJobID = (int) (str_replace('Import_', '', $entity)); if (!UserJob::get(TRUE)->addWhere('id', '=', $userJobID)->selectRowCount()->execute()->count()) { throw new UnauthorizedException('Import access not permitted'); diff --git a/civicrm/ext/civiimport/civiimport.civix.php b/civicrm/ext/civiimport/civiimport.civix.php index d7f10c0883..c912ca5bcf 100644 --- a/civicrm/ext/civiimport/civiimport.civix.php +++ b/civicrm/ext/civiimport/civiimport.civix.php @@ -84,27 +84,17 @@ use CRM_Civiimport_ExtensionUtil as E; * * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_config */ -function _civiimport_civix_civicrm_config(&$config = NULL) { +function _civiimport_civix_civicrm_config($config = NULL) { static $configured = FALSE; if ($configured) { return; } $configured = TRUE; - $template = CRM_Core_Smarty::singleton(); - $extRoot = __DIR__ . DIRECTORY_SEPARATOR; - $extDir = $extRoot . 'templates'; - - if (is_array($template->template_dir)) { - array_unshift($template->template_dir, $extDir); - } - else { - $template->template_dir = [$extDir, $template->template_dir]; - } - $include_path = $extRoot . PATH_SEPARATOR . get_include_path(); set_include_path($include_path); + // Based on <compatibility>, this does not currently require mixin/polyfill.php. } /** @@ -114,35 +104,7 @@ function _civiimport_civix_civicrm_config(&$config = NULL) { */ function _civiimport_civix_civicrm_install() { _civiimport_civix_civicrm_config(); - if ($upgrader = _civiimport_civix_upgrader()) { - $upgrader->onInstall(); - } -} - -/** - * Implements hook_civicrm_postInstall(). - * - * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_postInstall - */ -function _civiimport_civix_civicrm_postInstall() { - _civiimport_civix_civicrm_config(); - if ($upgrader = _civiimport_civix_upgrader()) { - if (is_callable([$upgrader, 'onPostInstall'])) { - $upgrader->onPostInstall(); - } - } -} - -/** - * Implements hook_civicrm_uninstall(). - * - * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_uninstall - */ -function _civiimport_civix_civicrm_uninstall(): void { - _civiimport_civix_civicrm_config(); - if ($upgrader = _civiimport_civix_upgrader()) { - $upgrader->onUninstall(); - } + // Based on <compatibility>, this does not currently require mixin/polyfill.php. } /** @@ -152,56 +114,7 @@ function _civiimport_civix_civicrm_uninstall(): void { */ function _civiimport_civix_civicrm_enable(): void { _civiimport_civix_civicrm_config(); - if ($upgrader = _civiimport_civix_upgrader()) { - if (is_callable([$upgrader, 'onEnable'])) { - $upgrader->onEnable(); - } - } -} - -/** - * (Delegated) Implements hook_civicrm_disable(). - * - * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_disable - * @return mixed - */ -function _civiimport_civix_civicrm_disable(): void { - _civiimport_civix_civicrm_config(); - if ($upgrader = _civiimport_civix_upgrader()) { - if (is_callable([$upgrader, 'onDisable'])) { - $upgrader->onDisable(); - } - } -} - -/** - * (Delegated) Implements hook_civicrm_upgrade(). - * - * @param $op string, the type of operation being performed; 'check' or 'enqueue' - * @param $queue CRM_Queue_Queue, (for 'enqueue') the modifiable list of pending up upgrade tasks - * - * @return mixed - * based on op. for 'check', returns array(boolean) (TRUE if upgrades are pending) - * for 'enqueue', returns void - * - * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_upgrade - */ -function _civiimport_civix_civicrm_upgrade($op, CRM_Queue_Queue $queue = NULL) { - if ($upgrader = _civiimport_civix_upgrader()) { - return $upgrader->onUpgrade($op, $queue); - } -} - -/** - * @return CRM_Civiimport_Upgrader - */ -function _civiimport_civix_upgrader() { - if (!file_exists(__DIR__ . '/CRM/Civiimport/Upgrader.php')) { - return NULL; - } - else { - return CRM_Civiimport_Upgrader_Base::instance(); - } + // Based on <compatibility>, this does not currently require mixin/polyfill.php. } /** @@ -285,14 +198,3 @@ function _civiimport_civix_fixNavigationMenuItems(&$nodes, &$maxNavID, $parentID } } } - -/** - * (Delegated) Implements hook_civicrm_entityTypes(). - * - * Find any *.entityType.php files, merge their content, and return. - * - * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_entityTypes - */ -function _civiimport_civix_civicrm_entityTypes(&$entityTypes) { - $entityTypes = array_merge($entityTypes, []); -} diff --git a/civicrm/ext/civiimport/civiimport.php b/civicrm/ext/civiimport/civiimport.php index ded5220c2c..eef2432d68 100644 --- a/civicrm/ext/civiimport/civiimport.php +++ b/civicrm/ext/civiimport/civiimport.php @@ -31,24 +31,6 @@ function civiimport_civicrm_install() { _civiimport_civix_civicrm_install(); } -/** - * Implements hook_civicrm_postInstall(). - * - * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_postInstall - */ -function civiimport_civicrm_postInstall() { - _civiimport_civix_civicrm_postInstall(); -} - -/** - * Implements hook_civicrm_uninstall(). - * - * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_uninstall - */ -function civiimport_civicrm_uninstall() { - _civiimport_civix_civicrm_uninstall(); -} - /** * Implements hook_civicrm_enable(). * @@ -58,24 +40,6 @@ function civiimport_civicrm_enable() { _civiimport_civix_civicrm_enable(); } -/** - * Implements hook_civicrm_disable(). - * - * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_disable - */ -function civiimport_civicrm_disable() { - _civiimport_civix_civicrm_disable(); -} - -/** - * Implements hook_civicrm_upgrade(). - * - * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_upgrade - */ -function civiimport_civicrm_upgrade($op, CRM_Queue_Queue $queue = NULL) { - return _civiimport_civix_civicrm_upgrade($op, $queue); -} - /** * Implements hook_civicrm_entityTypes(). * diff --git a/civicrm/ext/civiimport/info.xml b/civicrm/ext/civiimport/info.xml index 1097ce32be..23ad03fd91 100644 --- a/civicrm/ext/civiimport/info.xml +++ b/civicrm/ext/civiimport/info.xml @@ -15,10 +15,10 @@ <url desc="Licensing">http://www.gnu.org/licenses/agpl-3.0.html</url> </urls> <releaseDate>2022-08-11</releaseDate> - <version>5.59.4</version> + <version>5.60.0</version> <develStage>alpha</develStage> <compatibility> - <ver>5.59</ver> + <ver>5.60</ver> </compatibility> <comments>Core extension for us to start moving import logic into, has more functionality</comments> <requires> @@ -31,7 +31,7 @@ </classloader> <civix> <namespace>CRM/Civiimport</namespace> - <format>22.10.0</format> + <format>23.02.0</format> <angularModule>crmCiviimport</angularModule> </civix> <mixins> @@ -39,5 +39,6 @@ <mixin>scan-classes@1.0.0</mixin> <mixin>setting-php@1.0.0</mixin> <mixin>ang-php@1.0.0</mixin> + <mixin>smarty-v2@1.0.0</mixin> </mixins> </extension> diff --git a/civicrm/ext/ckeditor4/CRM/Ckeditor4/Upgrader.php b/civicrm/ext/ckeditor4/CRM/Ckeditor4/Upgrader.php index 76d3f1b7d7..6455ef964f 100644 --- a/civicrm/ext/ckeditor4/CRM/Ckeditor4/Upgrader.php +++ b/civicrm/ext/ckeditor4/CRM/Ckeditor4/Upgrader.php @@ -4,7 +4,7 @@ use CRM_Ckeditor4_ExtensionUtil as E; /** * Collection of upgrade steps. */ -class CRM_Ckeditor4_Upgrader extends CRM_Ckeditor4_Upgrader_Base { +class CRM_Ckeditor4_Upgrader extends CRM_Extension_Upgrader_Base { /** * Install extension. diff --git a/civicrm/ext/ckeditor4/CRM/Ckeditor4/Upgrader/Base.php b/civicrm/ext/ckeditor4/CRM/Ckeditor4/Upgrader/Base.php deleted file mode 100644 index f323ad0941..0000000000 --- a/civicrm/ext/ckeditor4/CRM/Ckeditor4/Upgrader/Base.php +++ /dev/null @@ -1,396 +0,0 @@ -<?php - -// AUTO-GENERATED FILE -- Civix may overwrite any changes made to this file -use CRM_Ckeditor4_ExtensionUtil as E; - -/** - * Base class which provides helpers to execute upgrade logic - */ -class CRM_Ckeditor4_Upgrader_Base { - - /** - * @var CRM_Ckeditor4_Upgrader_Base - */ - public static $instance; - - /** - * @var CRM_Queue_TaskContext - */ - protected $ctx; - - /** - * @var string - * eg 'com.example.myextension' - */ - protected $extensionName; - - /** - * @var string - * full path to the extension's source tree - */ - protected $extensionDir; - - /** - * @var array - * sorted numerically - */ - private $revisions; - - /** - * @var bool - * Flag to clean up extension revision data in civicrm_setting - */ - private $revisionStorageIsDeprecated = FALSE; - - /** - * Obtain a reference to the active upgrade handler. - */ - public static function instance() { - if (!self::$instance) { - self::$instance = new CRM_Ckeditor4_Upgrader( - 'ckeditor4', - E::path() - ); - } - return self::$instance; - } - - /** - * Adapter that lets you add normal (non-static) member functions to the queue. - * - * Note: Each upgrader instance should only be associated with one - * task-context; otherwise, this will be non-reentrant. - * - * ``` - * CRM_Ckeditor4_Upgrader_Base::_queueAdapter($ctx, 'methodName', 'arg1', 'arg2'); - * ``` - */ - public static function _queueAdapter() { - $instance = self::instance(); - $args = func_get_args(); - $instance->ctx = array_shift($args); - $instance->queue = $instance->ctx->queue; - $method = array_shift($args); - return call_user_func_array([$instance, $method], $args); - } - - /** - * CRM_Ckeditor4_Upgrader_Base constructor. - * - * @param $extensionName - * @param $extensionDir - */ - public function __construct($extensionName, $extensionDir) { - $this->extensionName = $extensionName; - $this->extensionDir = $extensionDir; - } - - // ******** Task helpers ******** - - /** - * Run a CustomData file. - * - * @param string $relativePath - * the CustomData XML file path (relative to this extension's dir) - * @return bool - */ - public function executeCustomDataFile($relativePath) { - $xml_file = $this->extensionDir . '/' . $relativePath; - return $this->executeCustomDataFileByAbsPath($xml_file); - } - - /** - * Run a CustomData file - * - * @param string $xml_file - * the CustomData XML file path (absolute path) - * - * @return bool - */ - protected function executeCustomDataFileByAbsPath($xml_file) { - $import = new CRM_Utils_Migrate_Import(); - $import->run($xml_file); - return TRUE; - } - - /** - * Run a SQL file. - * - * @param string $relativePath - * the SQL file path (relative to this extension's dir) - * - * @return bool - */ - public function executeSqlFile($relativePath) { - CRM_Utils_File::sourceSQLFile( - CIVICRM_DSN, - $this->extensionDir . DIRECTORY_SEPARATOR . $relativePath - ); - return TRUE; - } - - /** - * Run the sql commands in the specified file. - * - * @param string $tplFile - * The SQL file path (relative to this extension's dir). - * Ex: "sql/mydata.mysql.tpl". - * - * @return bool - * @throws \CRM_Core_Exception - */ - public function executeSqlTemplate($tplFile) { - // Assign multilingual variable to Smarty. - $upgrade = new CRM_Upgrade_Form(); - - $tplFile = CRM_Utils_File::isAbsolute($tplFile) ? $tplFile : $this->extensionDir . DIRECTORY_SEPARATOR . $tplFile; - $smarty = CRM_Core_Smarty::singleton(); - $smarty->assign('domainID', CRM_Core_Config::domainID()); - CRM_Utils_File::sourceSQLFile( - CIVICRM_DSN, $smarty->fetch($tplFile), NULL, TRUE - ); - return TRUE; - } - - /** - * Run one SQL query. - * - * This is just a wrapper for CRM_Core_DAO::executeSql, but it - * provides syntactic sugar for queueing several tasks that - * run different queries - * - * @return bool - */ - public function executeSql($query, $params = []) { - // FIXME verify that we raise an exception on error - CRM_Core_DAO::executeQuery($query, $params); - return TRUE; - } - - /** - * Syntactic sugar for enqueuing a task which calls a function in this class. - * - * The task is weighted so that it is processed - * as part of the currently-pending revision. - * - * After passing the $funcName, you can also pass parameters that will go to - * the function. Note that all params must be serializable. - */ - public function addTask($title) { - $args = func_get_args(); - $title = array_shift($args); - $task = new CRM_Queue_Task( - [get_class($this), '_queueAdapter'], - $args, - $title - ); - return $this->queue->createItem($task, ['weight' => -1]); - } - - // ******** Revision-tracking helpers ******** - - /** - * Determine if there are any pending revisions. - * - * @return bool - */ - public function hasPendingRevisions() { - $revisions = $this->getRevisions(); - $currentRevision = $this->getCurrentRevision(); - - if (empty($revisions)) { - return FALSE; - } - if (empty($currentRevision)) { - return TRUE; - } - - return ($currentRevision < max($revisions)); - } - - /** - * Add any pending revisions to the queue. - * - * @param CRM_Queue_Queue $queue - */ - public function enqueuePendingRevisions(CRM_Queue_Queue $queue) { - $this->queue = $queue; - - $currentRevision = $this->getCurrentRevision(); - foreach ($this->getRevisions() as $revision) { - if ($revision > $currentRevision) { - $title = E::ts('Upgrade %1 to revision %2', [ - 1 => $this->extensionName, - 2 => $revision, - ]); - - // note: don't use addTask() because it sets weight=-1 - - $task = new CRM_Queue_Task( - [get_class($this), '_queueAdapter'], - ['upgrade_' . $revision], - $title - ); - $this->queue->createItem($task); - - $task = new CRM_Queue_Task( - [get_class($this), '_queueAdapter'], - ['setCurrentRevision', $revision], - $title - ); - $this->queue->createItem($task); - } - } - } - - /** - * Get a list of revisions. - * - * @return array - * revisionNumbers sorted numerically - */ - public function getRevisions() { - if (!is_array($this->revisions)) { - $this->revisions = []; - - $clazz = new ReflectionClass(get_class($this)); - $methods = $clazz->getMethods(); - foreach ($methods as $method) { - if (preg_match('/^upgrade_(.*)/', $method->name, $matches)) { - $this->revisions[] = $matches[1]; - } - } - sort($this->revisions, SORT_NUMERIC); - } - - return $this->revisions; - } - - public function getCurrentRevision() { - $revision = CRM_Core_BAO_Extension::getSchemaVersion($this->extensionName); - if (!$revision) { - $revision = $this->getCurrentRevisionDeprecated(); - } - return $revision; - } - - private function getCurrentRevisionDeprecated() { - $key = $this->extensionName . ':version'; - if ($revision = \Civi::settings()->get($key)) { - $this->revisionStorageIsDeprecated = TRUE; - } - return $revision; - } - - public function setCurrentRevision($revision) { - CRM_Core_BAO_Extension::setSchemaVersion($this->extensionName, $revision); - // clean up legacy schema version store (CRM-19252) - $this->deleteDeprecatedRevision(); - return TRUE; - } - - private function deleteDeprecatedRevision() { - if ($this->revisionStorageIsDeprecated) { - $setting = new CRM_Core_BAO_Setting(); - $setting->name = $this->extensionName . ':version'; - $setting->delete(); - CRM_Core_Error::debug_log_message("Migrated extension schema revision ID for {$this->extensionName} from civicrm_setting (deprecated) to civicrm_extension.\n"); - } - } - - // ******** Hook delegates ******** - - /** - * @see https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_install - */ - public function onInstall() { - $files = glob($this->extensionDir . '/sql/*_install.sql'); - if (is_array($files)) { - foreach ($files as $file) { - CRM_Utils_File::sourceSQLFile(CIVICRM_DSN, $file); - } - } - $files = glob($this->extensionDir . '/sql/*_install.mysql.tpl'); - if (is_array($files)) { - foreach ($files as $file) { - $this->executeSqlTemplate($file); - } - } - $files = glob($this->extensionDir . '/xml/*_install.xml'); - if (is_array($files)) { - foreach ($files as $file) { - $this->executeCustomDataFileByAbsPath($file); - } - } - if (is_callable([$this, 'install'])) { - $this->install(); - } - } - - /** - * @see https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_postInstall - */ - public function onPostInstall() { - $revisions = $this->getRevisions(); - if (!empty($revisions)) { - $this->setCurrentRevision(max($revisions)); - } - if (is_callable([$this, 'postInstall'])) { - $this->postInstall(); - } - } - - /** - * @see https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_uninstall - */ - public function onUninstall() { - $files = glob($this->extensionDir . '/sql/*_uninstall.mysql.tpl'); - if (is_array($files)) { - foreach ($files as $file) { - $this->executeSqlTemplate($file); - } - } - if (is_callable([$this, 'uninstall'])) { - $this->uninstall(); - } - $files = glob($this->extensionDir . '/sql/*_uninstall.sql'); - if (is_array($files)) { - foreach ($files as $file) { - CRM_Utils_File::sourceSQLFile(CIVICRM_DSN, $file); - } - } - } - - /** - * @see https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_enable - */ - public function onEnable() { - // stub for possible future use - if (is_callable([$this, 'enable'])) { - $this->enable(); - } - } - - /** - * @see https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_disable - */ - public function onDisable() { - // stub for possible future use - if (is_callable([$this, 'disable'])) { - $this->disable(); - } - } - - public function onUpgrade($op, CRM_Queue_Queue $queue = NULL) { - switch ($op) { - case 'check': - return [$this->hasPendingRevisions()]; - - case 'enqueue': - return $this->enqueuePendingRevisions($queue); - - default: - } - } - -} diff --git a/civicrm/ext/ckeditor4/ckeditor4.civix.php b/civicrm/ext/ckeditor4/ckeditor4.civix.php index e7ce69749e..39aa238b67 100644 --- a/civicrm/ext/ckeditor4/ckeditor4.civix.php +++ b/civicrm/ext/ckeditor4/ckeditor4.civix.php @@ -84,27 +84,17 @@ use CRM_Ckeditor4_ExtensionUtil as E; * * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_config */ -function _ckeditor4_civix_civicrm_config(&$config = NULL) { +function _ckeditor4_civix_civicrm_config($config = NULL) { static $configured = FALSE; if ($configured) { return; } $configured = TRUE; - $template = CRM_Core_Smarty::singleton(); - $extRoot = __DIR__ . DIRECTORY_SEPARATOR; - $extDir = $extRoot . 'templates'; - - if (is_array($template->template_dir)) { - array_unshift($template->template_dir, $extDir); - } - else { - $template->template_dir = [$extDir, $template->template_dir]; - } - $include_path = $extRoot . PATH_SEPARATOR . get_include_path(); set_include_path($include_path); + // Based on <compatibility>, this does not currently require mixin/polyfill.php. } /** @@ -114,35 +104,7 @@ function _ckeditor4_civix_civicrm_config(&$config = NULL) { */ function _ckeditor4_civix_civicrm_install() { _ckeditor4_civix_civicrm_config(); - if ($upgrader = _ckeditor4_civix_upgrader()) { - $upgrader->onInstall(); - } -} - -/** - * Implements hook_civicrm_postInstall(). - * - * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_postInstall - */ -function _ckeditor4_civix_civicrm_postInstall() { - _ckeditor4_civix_civicrm_config(); - if ($upgrader = _ckeditor4_civix_upgrader()) { - if (is_callable([$upgrader, 'onPostInstall'])) { - $upgrader->onPostInstall(); - } - } -} - -/** - * Implements hook_civicrm_uninstall(). - * - * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_uninstall - */ -function _ckeditor4_civix_civicrm_uninstall(): void { - _ckeditor4_civix_civicrm_config(); - if ($upgrader = _ckeditor4_civix_upgrader()) { - $upgrader->onUninstall(); - } + // Based on <compatibility>, this does not currently require mixin/polyfill.php. } /** @@ -152,56 +114,7 @@ function _ckeditor4_civix_civicrm_uninstall(): void { */ function _ckeditor4_civix_civicrm_enable(): void { _ckeditor4_civix_civicrm_config(); - if ($upgrader = _ckeditor4_civix_upgrader()) { - if (is_callable([$upgrader, 'onEnable'])) { - $upgrader->onEnable(); - } - } -} - -/** - * (Delegated) Implements hook_civicrm_disable(). - * - * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_disable - * @return mixed - */ -function _ckeditor4_civix_civicrm_disable(): void { - _ckeditor4_civix_civicrm_config(); - if ($upgrader = _ckeditor4_civix_upgrader()) { - if (is_callable([$upgrader, 'onDisable'])) { - $upgrader->onDisable(); - } - } -} - -/** - * (Delegated) Implements hook_civicrm_upgrade(). - * - * @param $op string, the type of operation being performed; 'check' or 'enqueue' - * @param $queue CRM_Queue_Queue, (for 'enqueue') the modifiable list of pending up upgrade tasks - * - * @return mixed - * based on op. for 'check', returns array(boolean) (TRUE if upgrades are pending) - * for 'enqueue', returns void - * - * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_upgrade - */ -function _ckeditor4_civix_civicrm_upgrade($op, CRM_Queue_Queue $queue = NULL) { - if ($upgrader = _ckeditor4_civix_upgrader()) { - return $upgrader->onUpgrade($op, $queue); - } -} - -/** - * @return CRM_Ckeditor4_Upgrader - */ -function _ckeditor4_civix_upgrader() { - if (!file_exists(__DIR__ . '/CRM/Ckeditor4/Upgrader.php')) { - return NULL; - } - else { - return CRM_Ckeditor4_Upgrader_Base::instance(); - } + // Based on <compatibility>, this does not currently require mixin/polyfill.php. } /** @@ -285,14 +198,3 @@ function _ckeditor4_civix_fixNavigationMenuItems(&$nodes, &$maxNavID, $parentID) } } } - -/** - * (Delegated) Implements hook_civicrm_entityTypes(). - * - * Find any *.entityType.php files, merge their content, and return. - * - * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_entityTypes - */ -function _ckeditor4_civix_civicrm_entityTypes(&$entityTypes) { - $entityTypes = array_merge($entityTypes, []); -} diff --git a/civicrm/ext/ckeditor4/ckeditor4.php b/civicrm/ext/ckeditor4/ckeditor4.php index cdd366c94d..5bd699dccc 100644 --- a/civicrm/ext/ckeditor4/ckeditor4.php +++ b/civicrm/ext/ckeditor4/ckeditor4.php @@ -23,24 +23,6 @@ function ckeditor4_civicrm_install() { _ckeditor4_civix_civicrm_install(); } -/** - * Implements hook_civicrm_postInstall(). - * - * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_postInstall - */ -function ckeditor4_civicrm_postInstall() { - _ckeditor4_civix_civicrm_postInstall(); -} - -/** - * Implements hook_civicrm_uninstall(). - * - * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_uninstall - */ -function ckeditor4_civicrm_uninstall() { - _ckeditor4_civix_civicrm_uninstall(); -} - /** * Implements hook_civicrm_enable(). * @@ -50,35 +32,6 @@ function ckeditor4_civicrm_enable() { _ckeditor4_civix_civicrm_enable(); } -/** - * Implements hook_civicrm_disable(). - * - * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_disable - */ -function ckeditor4_civicrm_disable() { - _ckeditor4_civix_civicrm_disable(); -} - -/** - * Implements hook_civicrm_upgrade(). - * - * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_upgrade - */ -function ckeditor4_civicrm_upgrade($op, CRM_Queue_Queue $queue = NULL) { - return _ckeditor4_civix_civicrm_upgrade($op, $queue); -} - -/** - * Implements hook_civicrm_entityTypes(). - * - * Declare entity types provided by this module. - * - * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_entityTypes - */ -function ckeditor4_civicrm_entityTypes(&$entityTypes) { - _ckeditor4_civix_civicrm_entityTypes($entityTypes); -} - function ckeditor4_civicrm_buildForm($formName, $form) { if ($formName === 'CRM_Admin_Form_Preferences_Display') { $form->addElement( diff --git a/civicrm/ext/ckeditor4/info.xml b/civicrm/ext/ckeditor4/info.xml index af8a9d240b..2a83898bf1 100644 --- a/civicrm/ext/ckeditor4/info.xml +++ b/civicrm/ext/ckeditor4/info.xml @@ -15,10 +15,10 @@ <url desc="Licensing">https://www.gnu.org/licenses/agpl-3.0.html</url> </urls> <releaseDate>2021-05-23</releaseDate> - <version>5.59.4</version> + <version>5.60.0</version> <develStage>stable</develStage> <compatibility> - <ver>5.59</ver> + <ver>5.60</ver> </compatibility> <comments>This is the version of CKEditor that originally shipped with CiviCRM core</comments> <classloader> @@ -27,9 +27,11 @@ </classloader> <mixins> <mixin>menu-xml@1.0.0</mixin> + <mixin>smarty-v2@1.0.0</mixin> </mixins> <civix> <namespace>CRM/Ckeditor4</namespace> - <format>22.10.0</format> + <format>23.02.0</format> </civix> + <upgrader>CRM_Ckeditor4_Upgrader</upgrader> </extension> diff --git a/civicrm/ext/contributioncancelactions/info.xml b/civicrm/ext/contributioncancelactions/info.xml index f40b8c2d32..d80fb16559 100644 --- a/civicrm/ext/contributioncancelactions/info.xml +++ b/civicrm/ext/contributioncancelactions/info.xml @@ -15,10 +15,10 @@ <url desc="Licensing">http://www.gnu.org/licenses/agpl-3.0.html</url> </urls> <releaseDate>2020-10-12</releaseDate> - <version>5.59.4</version> + <version>5.60.0</version> <develStage>stable</develStage> <compatibility> - <ver>5.59</ver> + <ver>5.60</ver> </compatibility> <comments>This code has been moved from core to a separate extension in 5.32. Note that if you disable it failed or cancelled contributions will not cause related memberships and participant records to be updated</comments> <classloader> diff --git a/civicrm/ext/elavon/info.xml b/civicrm/ext/elavon/info.xml index cf49eca08d..53e5119a3c 100644 --- a/civicrm/ext/elavon/info.xml +++ b/civicrm/ext/elavon/info.xml @@ -15,10 +15,10 @@ <url desc="Licensing">http://www.gnu.org/licenses/agpl-3.0.html</url> </urls> <releaseDate>2022-08-05</releaseDate> - <version>5.59.4</version> + <version>5.60.0</version> <develStage>stable</develStage> <compatibility> - <ver>5.59</ver> + <ver>5.60</ver> </compatibility> <comments/> <classloader> diff --git a/civicrm/ext/eventcart/info.xml b/civicrm/ext/eventcart/info.xml index 11f7c54850..aaeb0c4aa6 100644 --- a/civicrm/ext/eventcart/info.xml +++ b/civicrm/ext/eventcart/info.xml @@ -13,13 +13,13 @@ <url desc="Licensing">http://www.gnu.org/licenses/agpl-3.0.html</url> </urls> <releaseDate>2020-08-03</releaseDate> - <version>5.59.4</version> + <version>5.60.0</version> <tags> <tag>mgmt:hidden</tag> </tags> <develStage>stable</develStage> <compatibility> - <ver>5.59</ver> + <ver>5.60</ver> </compatibility> <classloader> <psr0 prefix="CRM_" path="."/> diff --git a/civicrm/ext/ewaysingle/info.xml b/civicrm/ext/ewaysingle/info.xml index 644b6c005d..42ff6c25e3 100644 --- a/civicrm/ext/ewaysingle/info.xml +++ b/civicrm/ext/ewaysingle/info.xml @@ -15,13 +15,13 @@ <url desc="Licensing">http://www.gnu.org/licenses/agpl-3.0.html</url> </urls> <releaseDate>2020-10-07</releaseDate> - <version>5.59.4</version> + <version>5.60.0</version> <tags> <tag>mgmt:hidden</tag> </tags> <develStage>stable</develStage> <compatibility> - <ver>5.59</ver> + <ver>5.60</ver> </compatibility> <comments>This is an extension to contain the eWAY Single Currency Payment Processor</comments> <classloader> diff --git a/civicrm/ext/financialacls/financialacls.civix.php b/civicrm/ext/financialacls/financialacls.civix.php index 62bdbe3f8b..d7b20fa37a 100644 --- a/civicrm/ext/financialacls/financialacls.civix.php +++ b/civicrm/ext/financialacls/financialacls.civix.php @@ -84,27 +84,17 @@ use CRM_Financialacls_ExtensionUtil as E; * * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_config */ -function _financialacls_civix_civicrm_config(&$config = NULL) { +function _financialacls_civix_civicrm_config($config = NULL) { static $configured = FALSE; if ($configured) { return; } $configured = TRUE; - $template = CRM_Core_Smarty::singleton(); - $extRoot = __DIR__ . DIRECTORY_SEPARATOR; - $extDir = $extRoot . 'templates'; - - if (is_array($template->template_dir)) { - array_unshift($template->template_dir, $extDir); - } - else { - $template->template_dir = [$extDir, $template->template_dir]; - } - $include_path = $extRoot . PATH_SEPARATOR . get_include_path(); set_include_path($include_path); + // Based on <compatibility>, this does not currently require mixin/polyfill.php. } /** @@ -114,35 +104,7 @@ function _financialacls_civix_civicrm_config(&$config = NULL) { */ function _financialacls_civix_civicrm_install() { _financialacls_civix_civicrm_config(); - if ($upgrader = _financialacls_civix_upgrader()) { - $upgrader->onInstall(); - } -} - -/** - * Implements hook_civicrm_postInstall(). - * - * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_postInstall - */ -function _financialacls_civix_civicrm_postInstall() { - _financialacls_civix_civicrm_config(); - if ($upgrader = _financialacls_civix_upgrader()) { - if (is_callable([$upgrader, 'onPostInstall'])) { - $upgrader->onPostInstall(); - } - } -} - -/** - * Implements hook_civicrm_uninstall(). - * - * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_uninstall - */ -function _financialacls_civix_civicrm_uninstall(): void { - _financialacls_civix_civicrm_config(); - if ($upgrader = _financialacls_civix_upgrader()) { - $upgrader->onUninstall(); - } + // Based on <compatibility>, this does not currently require mixin/polyfill.php. } /** @@ -152,56 +114,7 @@ function _financialacls_civix_civicrm_uninstall(): void { */ function _financialacls_civix_civicrm_enable(): void { _financialacls_civix_civicrm_config(); - if ($upgrader = _financialacls_civix_upgrader()) { - if (is_callable([$upgrader, 'onEnable'])) { - $upgrader->onEnable(); - } - } -} - -/** - * (Delegated) Implements hook_civicrm_disable(). - * - * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_disable - * @return mixed - */ -function _financialacls_civix_civicrm_disable(): void { - _financialacls_civix_civicrm_config(); - if ($upgrader = _financialacls_civix_upgrader()) { - if (is_callable([$upgrader, 'onDisable'])) { - $upgrader->onDisable(); - } - } -} - -/** - * (Delegated) Implements hook_civicrm_upgrade(). - * - * @param $op string, the type of operation being performed; 'check' or 'enqueue' - * @param $queue CRM_Queue_Queue, (for 'enqueue') the modifiable list of pending up upgrade tasks - * - * @return mixed - * based on op. for 'check', returns array(boolean) (TRUE if upgrades are pending) - * for 'enqueue', returns void - * - * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_upgrade - */ -function _financialacls_civix_civicrm_upgrade($op, CRM_Queue_Queue $queue = NULL) { - if ($upgrader = _financialacls_civix_upgrader()) { - return $upgrader->onUpgrade($op, $queue); - } -} - -/** - * @return CRM_Financialacls_Upgrader - */ -function _financialacls_civix_upgrader() { - if (!file_exists(__DIR__ . '/CRM/Financialacls/Upgrader.php')) { - return NULL; - } - else { - return CRM_Financialacls_Upgrader_Base::instance(); - } + // Based on <compatibility>, this does not currently require mixin/polyfill.php. } /** @@ -285,14 +198,3 @@ function _financialacls_civix_fixNavigationMenuItems(&$nodes, &$maxNavID, $paren } } } - -/** - * (Delegated) Implements hook_civicrm_entityTypes(). - * - * Find any *.entityType.php files, merge their content, and return. - * - * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_entityTypes - */ -function _financialacls_civix_civicrm_entityTypes(&$entityTypes) { - $entityTypes = array_merge($entityTypes, []); -} diff --git a/civicrm/ext/financialacls/financialacls.php b/civicrm/ext/financialacls/financialacls.php index af3378eb49..8dea84fe6f 100644 --- a/civicrm/ext/financialacls/financialacls.php +++ b/civicrm/ext/financialacls/financialacls.php @@ -34,24 +34,6 @@ function financialacls_civicrm_install() { _financialacls_civix_civicrm_install(); } -/** - * Implements hook_civicrm_postInstall(). - * - * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_postInstall - */ -function financialacls_civicrm_postInstall() { - _financialacls_civix_civicrm_postInstall(); -} - -/** - * Implements hook_civicrm_uninstall(). - * - * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_uninstall - */ -function financialacls_civicrm_uninstall() { - _financialacls_civix_civicrm_uninstall(); -} - /** * Implements hook_civicrm_enable(). * @@ -61,35 +43,6 @@ function financialacls_civicrm_enable() { _financialacls_civix_civicrm_enable(); } -/** - * Implements hook_civicrm_disable(). - * - * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_disable - */ -function financialacls_civicrm_disable() { - _financialacls_civix_civicrm_disable(); -} - -/** - * Implements hook_civicrm_upgrade(). - * - * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_upgrade - */ -function financialacls_civicrm_upgrade($op, CRM_Queue_Queue $queue = NULL) { - return _financialacls_civix_civicrm_upgrade($op, $queue); -} - -/** - * Implements hook_civicrm_entityTypes(). - * - * Declare entity types provided by this module. - * - * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_entityTypes - */ -function financialacls_civicrm_entityTypes(&$entityTypes) { - _financialacls_civix_civicrm_entityTypes($entityTypes); -} - /** * Intervene to prevent deletion, where permissions block it. * diff --git a/civicrm/ext/financialacls/info.xml b/civicrm/ext/financialacls/info.xml index f79347bbbf..365ef0dae2 100644 --- a/civicrm/ext/financialacls/info.xml +++ b/civicrm/ext/financialacls/info.xml @@ -15,10 +15,10 @@ <url desc="Licensing">http://www.gnu.org/licenses/agpl-3.0.html</url> </urls> <releaseDate>2020-08-27</releaseDate> - <version>5.59.4</version> + <version>5.60.0</version> <develStage>stable</develStage> <compatibility> - <ver>5.59</ver> + <ver>5.60</ver> </compatibility> <tags> <tag>mgmt:hidden</tag> @@ -33,6 +33,6 @@ </mixins> <civix> <namespace>CRM/Financialacls</namespace> - <format>22.10.0</format> + <format>23.02.0</format> </civix> </extension> diff --git a/civicrm/ext/flexmailer/flexmailer.civix.php b/civicrm/ext/flexmailer/flexmailer.civix.php index 6a215af368..2905f48988 100644 --- a/civicrm/ext/flexmailer/flexmailer.civix.php +++ b/civicrm/ext/flexmailer/flexmailer.civix.php @@ -92,9 +92,6 @@ function _flexmailer_civix_civicrm_config($config = NULL) { $configured = TRUE; $extRoot = __DIR__ . DIRECTORY_SEPARATOR; - $extDir = $extRoot . 'templates'; - CRM_Core_Smarty::singleton()->addTemplateDir($extDir); - $include_path = $extRoot . PATH_SEPARATOR . get_include_path(); set_include_path($include_path); // Based on <compatibility>, this does not currently require mixin/polyfill.php. @@ -201,14 +198,3 @@ function _flexmailer_civix_fixNavigationMenuItems(&$nodes, &$maxNavID, $parentID } } } - -/** - * (Delegated) Implements hook_civicrm_entityTypes(). - * - * Find any *.entityType.php files, merge their content, and return. - * - * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_entityTypes - */ -function _flexmailer_civix_civicrm_entityTypes(&$entityTypes) { - $entityTypes = array_merge($entityTypes, []); -} diff --git a/civicrm/ext/flexmailer/info.xml b/civicrm/ext/flexmailer/info.xml index 8abc677e8f..4128a21c65 100644 --- a/civicrm/ext/flexmailer/info.xml +++ b/civicrm/ext/flexmailer/info.xml @@ -15,7 +15,7 @@ <url desc="Licensing">http://www.gnu.org/licenses/agpl-3.0.html</url> </urls> <releaseDate>2020-08-05</releaseDate> - <version>5.59.4</version> + <version>5.60.0</version> <develStage>stable</develStage> <comments> FlexMailer is an email delivery engine which replaces the internal guts @@ -23,7 +23,7 @@ to provide richer email features. </comments> <compatibility> - <ver>5.59</ver> + <ver>5.60</ver> </compatibility> <tags> <tag>mgmt:required</tag> @@ -37,6 +37,6 @@ </mixins> <civix> <namespace>CRM/Flexmailer</namespace> - <format>22.12.1</format> + <format>23.02.0</format> </civix> </extension> diff --git a/civicrm/ext/flexmailer/src/Listener/BounceTracker.php b/civicrm/ext/flexmailer/src/Listener/BounceTracker.php index 210fea22df..e3c3dd1125 100644 --- a/civicrm/ext/flexmailer/src/Listener/BounceTracker.php +++ b/civicrm/ext/flexmailer/src/Listener/BounceTracker.php @@ -25,6 +25,7 @@ class BounceTracker extends BaseListener { } $mailing = $e->getMailing(); + $defaultReturnPath = \CRM_Core_BAO_MailSettings::defaultReturnPath(); foreach ($e->getTasks() as $task) { /** @var \Civi\FlexMailer\FlexMailerTask $task */ @@ -33,7 +34,7 @@ class BounceTracker extends BaseListener { $task->getAddress()); if (!$task->getMailParam('Return-Path')) { - $task->setMailParam('Return-Path', $verp['bounce']); + $task->setMailParam('Return-Path', $defaultReturnPath ?? $verp['bounce']); } if (!$task->getMailParam('X-CiviMail-Bounce')) { $task->setMailParam('X-CiviMail-Bounce', $verp['bounce']); diff --git a/civicrm/ext/greenwich/greenwich.civix.php b/civicrm/ext/greenwich/greenwich.civix.php index 3e018c743b..2c4dfb1309 100644 --- a/civicrm/ext/greenwich/greenwich.civix.php +++ b/civicrm/ext/greenwich/greenwich.civix.php @@ -92,9 +92,6 @@ function _greenwich_civix_civicrm_config($config = NULL) { $configured = TRUE; $extRoot = __DIR__ . DIRECTORY_SEPARATOR; - $extDir = $extRoot . 'templates'; - CRM_Core_Smarty::singleton()->addTemplateDir($extDir); - $include_path = $extRoot . PATH_SEPARATOR . get_include_path(); set_include_path($include_path); // Based on <compatibility>, this does not currently require mixin/polyfill.php. @@ -201,14 +198,3 @@ function _greenwich_civix_fixNavigationMenuItems(&$nodes, &$maxNavID, $parentID) } } } - -/** - * (Delegated) Implements hook_civicrm_entityTypes(). - * - * Find any *.entityType.php files, merge their content, and return. - * - * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_entityTypes - */ -function _greenwich_civix_civicrm_entityTypes(&$entityTypes) { - $entityTypes = array_merge($entityTypes, []); -} diff --git a/civicrm/ext/greenwich/info.xml b/civicrm/ext/greenwich/info.xml index 4d92444446..77e8c3a42a 100644 --- a/civicrm/ext/greenwich/info.xml +++ b/civicrm/ext/greenwich/info.xml @@ -15,13 +15,13 @@ <url desc="Licensing">http://www.gnu.org/licenses/agpl-3.0.html</url> </urls> <releaseDate>2020-07-21</releaseDate> - <version>5.59.4</version> + <version>5.60.0</version> <tags> <tag>mgmt:hidden</tag> </tags> <develStage>stable</develStage> <compatibility> - <ver>5.59</ver> + <ver>5.60</ver> </compatibility> <classloader> <psr0 prefix="CRM_" path="."/> @@ -29,6 +29,6 @@ </classloader> <civix> <namespace>CRM/Greenwich</namespace> - <format>22.12.1</format> + <format>23.02.0</format> </civix> </extension> diff --git a/civicrm/ext/legacycustomsearches/CRM/Contact/Selector/Custom.php b/civicrm/ext/legacycustomsearches/CRM/Contact/Selector/Custom.php index 95507319a9..7c0a3b50f3 100644 --- a/civicrm/ext/legacycustomsearches/CRM/Contact/Selector/Custom.php +++ b/civicrm/ext/legacycustomsearches/CRM/Contact/Selector/Custom.php @@ -13,7 +13,6 @@ * * @package CRM * @copyright CiviCRM LLC https://civicrm.org/licensing - * $Id: Selector.php 11510 2007-09-18 09:21:34Z lobo $ */ /** @@ -28,7 +27,7 @@ class CRM_Contact_Selector_Custom extends CRM_Contact_Selector { * * @var array */ - public static $_links = NULL; + public static $_links; /** * We use desc to remind us what that column is, name is used in the tpl @@ -360,6 +359,107 @@ class CRM_Contact_Selector_Custom extends CRM_Contact_Selector { return $rows; } + /** + * @param CRM_Utils_Sort $sort + * + * @return string + * @throws \CRM_Core_Exception + */ + private function buildPrevNextCache($sort): string { + $cacheKey = 'civicrm search ' . $this->_key; + + // We should clear the cache in following conditions: + // 1. when starting from scratch, i.e new search + // 2. if records are sorted + + // get current page requested + $pageNum = CRM_Utils_Request::retrieve('crmPID', 'Integer'); + + // get the current sort order + $currentSortID = CRM_Utils_Request::retrieve('crmSID', 'String'); + + $session = CRM_Core_Session::singleton(); + + // get previous sort id + $previousSortID = $session->get('previousSortID'); + + // check for current != previous to ensure cache is not reset if paging is done without changing + // sort criteria + if (!$pageNum || (!empty($currentSortID) && $currentSortID != $previousSortID)) { + Civi::service('prevnext')->deleteItem(NULL, $cacheKey, 'civicrm_contact'); + // this means it's fresh search, so set pageNum=1 + if (!$pageNum) { + $pageNum = 1; + } + } + + // set the current sort as previous sort + if (!empty($currentSortID)) { + $session->set('previousSortID', $currentSortID); + } + + $pageSize = CRM_Utils_Request::retrieve('crmRowCount', 'Integer', CRM_Core_DAO::$_nullObject, FALSE, 50); + $firstRecord = ($pageNum - 1) * $pageSize; + + //for alphabetic pagination selection save + $sortByCharacter = CRM_Utils_Request::retrieve('sortByCharacter', 'String'); + + //for text field pagination selection save + $countRow = Civi::service('prevnext')->getCount($cacheKey); + // $sortByCharacter triggers a refresh in the prevNext cache + if ($sortByCharacter && $sortByCharacter !== 'all') { + $this->fillPrevNextCache($sort, $cacheKey, 0, max(self::CACHE_SIZE, $pageSize)); + } + elseif (($firstRecord + $pageSize) >= $countRow) { + $this->fillPrevNextCache($sort, $cacheKey, $countRow, max(self::CACHE_SIZE, $pageSize) + $firstRecord - $countRow); + } + return $cacheKey; + } + + /** + * @param CRM_Utils_Sort $sort + * @param string $cacheKey + * @param int $start + * @param int $end + * + * @throws \CRM_Core_Exception + */ + public function fillPrevNextCache($sort, $cacheKey, $start = 0, $end = self::CACHE_SIZE): void { + $sql = $this->_search->contactIDs($start, $end, $sort, TRUE); + + // CRM-9096 + // due to limitations in our search query writer, the above query does not work + // in cases where the query is being sorted on a non-contact table + // this results in a fatal error :( + // see below for the gross hack of trapping the error and not filling + // the prev next cache in this situation + // the other alternative of running the FULL query will just be incredibly inefficient + // and slow things down way too much on large data sets / complex queries + + $selectSQL = CRM_Core_DAO::composeQuery("SELECT DISTINCT %1, contact_a.id, contact_a.sort_name", [1 => [$cacheKey, 'String']]); + + $sql = str_ireplace(['SELECT contact_a.id as contact_id', 'SELECT contact_a.id as id'], $selectSQL, $sql); + $sql = str_ireplace('ORDER BY `contact_id`', 'ORDER BY `id`', $sql, $sql); + + try { + Civi::service('prevnext')->fillWithSql($cacheKey, $sql); + } + catch (\Exception $e) { + CRM_Core_Error::deprecatedFunctionWarning('Custom searches should return sql capable of filling the prevnext cache.'); + // This will always show for CiviRules :-( as a) it orders by 'rule_label' + // which is not available in the query & b) it uses contact not contact_a + // as an alias. + // CRM_Core_Session::setStatus(ts('Query Failed')); + return; + } + + if (Civi::service('prevnext') instanceof CRM_Core_PrevNextCache_Sql) { + // SQL-backed prevnext cache uses an extra record for pruning the cache. + // Also ensure that caches stay alive for 2 days as per previous code + Civi::cache('prevNextCache')->set($cacheKey, $cacheKey, 60 * 60 * 24 * CRM_Core_PrevNextCache_Sql::cacheDays); + } + } + /** * Given the current formValues, gets the query in local language. * diff --git a/civicrm/ext/legacycustomsearches/info.xml b/civicrm/ext/legacycustomsearches/info.xml index fd05619ca0..ac5c0f1ed8 100644 --- a/civicrm/ext/legacycustomsearches/info.xml +++ b/civicrm/ext/legacycustomsearches/info.xml @@ -15,13 +15,13 @@ <url desc="Licensing">http://www.gnu.org/licenses/agpl-3.0.html</url> </urls> <releaseDate>2021-07-25</releaseDate> - <version>5.59.4</version> + <version>5.60.0</version> <develStage>stable</develStage> <tags> <tag>mgmt:hidden</tag> </tags> <compatibility> - <ver>5.59</ver> + <ver>5.60</ver> </compatibility> <comments>This is hidden on install to give extensions that require it time to add it to their requires and to allow us to get it out of GroupContact load</comments> <classloader> @@ -31,9 +31,10 @@ <mixins> <mixin>menu-xml@1.0.0</mixin> <mixin>mgd-php@1.0.0</mixin> + <mixin>smarty-v2@1.0.0</mixin> </mixins> <civix> <namespace>CRM/Legacycustomsearches</namespace> - <format>22.10.0</format> + <format>23.02.0</format> </civix> </extension> diff --git a/civicrm/ext/legacycustomsearches/legacycustomsearches.civix.php b/civicrm/ext/legacycustomsearches/legacycustomsearches.civix.php index b769c8311f..ffcb4eeb94 100644 --- a/civicrm/ext/legacycustomsearches/legacycustomsearches.civix.php +++ b/civicrm/ext/legacycustomsearches/legacycustomsearches.civix.php @@ -84,27 +84,17 @@ use CRM_Legacycustomsearches_ExtensionUtil as E; * * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_config */ -function _legacycustomsearches_civix_civicrm_config(&$config = NULL) { +function _legacycustomsearches_civix_civicrm_config($config = NULL) { static $configured = FALSE; if ($configured) { return; } $configured = TRUE; - $template = CRM_Core_Smarty::singleton(); - $extRoot = __DIR__ . DIRECTORY_SEPARATOR; - $extDir = $extRoot . 'templates'; - - if (is_array($template->template_dir)) { - array_unshift($template->template_dir, $extDir); - } - else { - $template->template_dir = [$extDir, $template->template_dir]; - } - $include_path = $extRoot . PATH_SEPARATOR . get_include_path(); set_include_path($include_path); + // Based on <compatibility>, this does not currently require mixin/polyfill.php. } /** @@ -114,35 +104,7 @@ function _legacycustomsearches_civix_civicrm_config(&$config = NULL) { */ function _legacycustomsearches_civix_civicrm_install() { _legacycustomsearches_civix_civicrm_config(); - if ($upgrader = _legacycustomsearches_civix_upgrader()) { - $upgrader->onInstall(); - } -} - -/** - * Implements hook_civicrm_postInstall(). - * - * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_postInstall - */ -function _legacycustomsearches_civix_civicrm_postInstall() { - _legacycustomsearches_civix_civicrm_config(); - if ($upgrader = _legacycustomsearches_civix_upgrader()) { - if (is_callable([$upgrader, 'onPostInstall'])) { - $upgrader->onPostInstall(); - } - } -} - -/** - * Implements hook_civicrm_uninstall(). - * - * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_uninstall - */ -function _legacycustomsearches_civix_civicrm_uninstall(): void { - _legacycustomsearches_civix_civicrm_config(); - if ($upgrader = _legacycustomsearches_civix_upgrader()) { - $upgrader->onUninstall(); - } + // Based on <compatibility>, this does not currently require mixin/polyfill.php. } /** @@ -152,56 +114,7 @@ function _legacycustomsearches_civix_civicrm_uninstall(): void { */ function _legacycustomsearches_civix_civicrm_enable(): void { _legacycustomsearches_civix_civicrm_config(); - if ($upgrader = _legacycustomsearches_civix_upgrader()) { - if (is_callable([$upgrader, 'onEnable'])) { - $upgrader->onEnable(); - } - } -} - -/** - * (Delegated) Implements hook_civicrm_disable(). - * - * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_disable - * @return mixed - */ -function _legacycustomsearches_civix_civicrm_disable(): void { - _legacycustomsearches_civix_civicrm_config(); - if ($upgrader = _legacycustomsearches_civix_upgrader()) { - if (is_callable([$upgrader, 'onDisable'])) { - $upgrader->onDisable(); - } - } -} - -/** - * (Delegated) Implements hook_civicrm_upgrade(). - * - * @param $op string, the type of operation being performed; 'check' or 'enqueue' - * @param $queue CRM_Queue_Queue, (for 'enqueue') the modifiable list of pending up upgrade tasks - * - * @return mixed - * based on op. for 'check', returns array(boolean) (TRUE if upgrades are pending) - * for 'enqueue', returns void - * - * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_upgrade - */ -function _legacycustomsearches_civix_civicrm_upgrade($op, CRM_Queue_Queue $queue = NULL) { - if ($upgrader = _legacycustomsearches_civix_upgrader()) { - return $upgrader->onUpgrade($op, $queue); - } -} - -/** - * @return CRM_Legacycustomsearches_Upgrader - */ -function _legacycustomsearches_civix_upgrader() { - if (!file_exists(__DIR__ . '/CRM/Legacycustomsearches/Upgrader.php')) { - return NULL; - } - else { - return CRM_Legacycustomsearches_Upgrader_Base::instance(); - } + // Based on <compatibility>, this does not currently require mixin/polyfill.php. } /** @@ -285,14 +198,3 @@ function _legacycustomsearches_civix_fixNavigationMenuItems(&$nodes, &$maxNavID, } } } - -/** - * (Delegated) Implements hook_civicrm_entityTypes(). - * - * Find any *.entityType.php files, merge their content, and return. - * - * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_entityTypes - */ -function _legacycustomsearches_civix_civicrm_entityTypes(&$entityTypes) { - $entityTypes = array_merge($entityTypes, []); -} diff --git a/civicrm/ext/legacycustomsearches/legacycustomsearches.php b/civicrm/ext/legacycustomsearches/legacycustomsearches.php index 92c9aa328a..9d16959ce5 100644 --- a/civicrm/ext/legacycustomsearches/legacycustomsearches.php +++ b/civicrm/ext/legacycustomsearches/legacycustomsearches.php @@ -23,24 +23,6 @@ function legacycustomsearches_civicrm_install() { _legacycustomsearches_civix_civicrm_install(); } -/** - * Implements hook_civicrm_postInstall(). - * - * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_postInstall - */ -function legacycustomsearches_civicrm_postInstall() { - _legacycustomsearches_civix_civicrm_postInstall(); -} - -/** - * Implements hook_civicrm_uninstall(). - * - * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_uninstall - */ -function legacycustomsearches_civicrm_uninstall() { - _legacycustomsearches_civix_civicrm_uninstall(); -} - /** * Implements hook_civicrm_enable(). * @@ -49,32 +31,3 @@ function legacycustomsearches_civicrm_uninstall() { function legacycustomsearches_civicrm_enable() { _legacycustomsearches_civix_civicrm_enable(); } - -/** - * Implements hook_civicrm_disable(). - * - * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_disable - */ -function legacycustomsearches_civicrm_disable() { - _legacycustomsearches_civix_civicrm_disable(); -} - -/** - * Implements hook_civicrm_upgrade(). - * - * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_upgrade - */ -function legacycustomsearches_civicrm_upgrade($op, CRM_Queue_Queue $queue = NULL) { - return _legacycustomsearches_civix_civicrm_upgrade($op, $queue); -} - -/** - * Implements hook_civicrm_entityTypes(). - * - * Declare entity types provided by this module. - * - * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_entityTypes - */ -function legacycustomsearches_civicrm_entityTypes(&$entityTypes) { - _legacycustomsearches_civix_civicrm_entityTypes($entityTypes); -} diff --git a/civicrm/ext/legacycustomsearches/templates/CRM/Contact/Form/Search/Custom/MultipleValuesCriteria.tpl b/civicrm/ext/legacycustomsearches/templates/CRM/Contact/Form/Search/Custom/MultipleValuesCriteria.tpl index 3326b6fbfd..1b3ab635b7 100644 --- a/civicrm/ext/legacycustomsearches/templates/CRM/Contact/Form/Search/Custom/MultipleValuesCriteria.tpl +++ b/civicrm/ext/legacycustomsearches/templates/CRM/Contact/Form/Search/Custom/MultipleValuesCriteria.tpl @@ -86,7 +86,7 @@ </div> </div> - <div class="crm-submit-buttons">{include file="CRM/common/formButtons.tpl"}</div> + <div class="crm-submit-buttons">{include file="CRM/common/formButtons.tpl" location=''}</div> </div><!-- /.crm-accordion-body --> </div><!-- /.crm-accordion-wrapper --> </div><!-- /.crm-form-block --> diff --git a/civicrm/ext/message_admin/info.xml b/civicrm/ext/message_admin/info.xml index 27dd551427..2807a6109b 100644 --- a/civicrm/ext/message_admin/info.xml +++ b/civicrm/ext/message_admin/info.xml @@ -15,10 +15,10 @@ <url desc="Licensing">http://www.gnu.org/licenses/agpl-3.0.html</url> </urls> <releaseDate>2021-06-12</releaseDate> - <version>5.59.4</version> + <version>5.60.0</version> <develStage>alpha</develStage> <compatibility> - <ver>5.59</ver> + <ver>5.60</ver> </compatibility> <requires> <ext>org.civicrm.afform</ext> @@ -31,9 +31,10 @@ <mixins> <mixin>ang-php@1.0.0</mixin> <mixin>menu-xml@1.0.0</mixin> + <mixin>smarty-v2@1.0.0</mixin> </mixins> <civix> <namespace>CRM/MessageAdmin</namespace> - <format>22.12.1</format> + <format>23.02.0</format> </civix> </extension> diff --git a/civicrm/ext/message_admin/message_admin.civix.php b/civicrm/ext/message_admin/message_admin.civix.php index b386a62dc7..78da356905 100644 --- a/civicrm/ext/message_admin/message_admin.civix.php +++ b/civicrm/ext/message_admin/message_admin.civix.php @@ -92,9 +92,6 @@ function _message_admin_civix_civicrm_config($config = NULL) { $configured = TRUE; $extRoot = __DIR__ . DIRECTORY_SEPARATOR; - $extDir = $extRoot . 'templates'; - CRM_Core_Smarty::singleton()->addTemplateDir($extDir); - $include_path = $extRoot . PATH_SEPARATOR . get_include_path(); set_include_path($include_path); // Based on <compatibility>, this does not currently require mixin/polyfill.php. @@ -201,14 +198,3 @@ function _message_admin_civix_fixNavigationMenuItems(&$nodes, &$maxNavID, $paren } } } - -/** - * (Delegated) Implements hook_civicrm_entityTypes(). - * - * Find any *.entityType.php files, merge their content, and return. - * - * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_entityTypes - */ -function _message_admin_civix_civicrm_entityTypes(&$entityTypes) { - $entityTypes = array_merge($entityTypes, []); -} diff --git a/civicrm/ext/message_admin/message_admin.php b/civicrm/ext/message_admin/message_admin.php index 872e322729..41fa59a346 100644 --- a/civicrm/ext/message_admin/message_admin.php +++ b/civicrm/ext/message_admin/message_admin.php @@ -32,17 +32,6 @@ function message_admin_civicrm_enable() { _message_admin_civix_civicrm_enable(); } -/** - * Implements hook_civicrm_entityTypes(). - * - * Declare entity types provided by this module. - * - * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_entityTypes - */ -function message_admin_civicrm_entityTypes(&$entityTypes) { - _message_admin_civix_civicrm_entityTypes($entityTypes); -} - // --- Functions below this ship commented out. Uncomment as required. --- /** diff --git a/civicrm/ext/oauth-client/Civi/Api4/Action/OAuthClient/AuthorizationCode.php b/civicrm/ext/oauth-client/Civi/Api4/Action/OAuthClient/AuthorizationCode.php index f9c896a5b0..73a01aaf0f 100644 --- a/civicrm/ext/oauth-client/Civi/Api4/Action/OAuthClient/AuthorizationCode.php +++ b/civicrm/ext/oauth-client/Civi/Api4/Action/OAuthClient/AuthorizationCode.php @@ -91,20 +91,19 @@ class AuthorizationCode extends AbstractGrantAction { parent::validate(); if ($this->landingUrl) { $landingUrlParsed = parse_url($this->landingUrl); - $landingUrlIp = gethostbyname($landingUrlParsed['host']); + $landingUrlIp = gethostbyname($landingUrlParsed['host'] . '.'); $allowedBases = [ \Civi::paths()->getVariable('cms.root', 'url'), \Civi::paths()->getVariable('civicrm.root', 'url'), ]; - $ok = max(array_map(function($allowed) use ($landingUrlParsed, $landingUrlIp) { + foreach ($allowedBases as $allowed) { $allowedParsed = parse_url($allowed); - $allowedIp = gethostbyname($allowedParsed['host']); - $ok = $landingUrlIp === $allowedIp && $landingUrlParsed['scheme'] == $allowedParsed['scheme']; - return (int) $ok; - }, $allowedBases)); - if (!$ok) { - throw new OAuthException("Cannot initiate OAuth. Unsupported landing URL."); + $allowedIp = gethostbyname($allowedParsed['host'] . '.'); + if ($landingUrlIp === $allowedIp && $landingUrlParsed['scheme'] == $allowedParsed['scheme']) { + return; + } } + throw new OAuthException("Cannot initiate OAuth. Unsupported landing URL."); } } diff --git a/civicrm/ext/oauth-client/Civi/OAuth/OAuthLeagueFacade.php b/civicrm/ext/oauth-client/Civi/OAuth/OAuthLeagueFacade.php index 27d0c18fcb..be66cfe0c7 100644 --- a/civicrm/ext/oauth-client/Civi/OAuth/OAuthLeagueFacade.php +++ b/civicrm/ext/oauth-client/Civi/OAuth/OAuthLeagueFacade.php @@ -36,13 +36,12 @@ class OAuthLeagueFacade { $localOptions['clientId'] = $clientDef['guid']; $localOptions['tenant'] = !empty($clientDef['tenant']) ? $clientDef['tenant'] : ''; $localOptions['clientSecret'] = $clientDef['secret']; - // NOTE: If we ever have frontend users, this may need to change. - $localOptions['redirectUri'] = \CRM_OAuth_BAO_OAuthClient::getRedirectUri(); $options = array_merge( $providerDef['options'] ?? [], $clientDef['options'] ?? [], $localOptions ); + $options['redirectUri'] = $options['redirectUri'] ?? \CRM_OAuth_BAO_OAuthClient::getRedirectUri(); return [$class, $options]; } diff --git a/civicrm/ext/oauth-client/info.xml b/civicrm/ext/oauth-client/info.xml index b5f07c6f09..5276987323 100644 --- a/civicrm/ext/oauth-client/info.xml +++ b/civicrm/ext/oauth-client/info.xml @@ -15,10 +15,10 @@ <url desc="Licensing">http://www.gnu.org/licenses/agpl-3.0.html</url> </urls> <releaseDate>2020-10-23</releaseDate> - <version>5.59.4</version> + <version>5.60.0</version> <develStage>stable</develStage> <compatibility> - <ver>5.59</ver> + <ver>5.60</ver> </compatibility> <requires> <ext version="~4.5">org.civicrm.afform</ext> @@ -33,9 +33,11 @@ <mixin>ang-php@1.0.0</mixin> <mixin>menu-xml@1.0.0</mixin> <mixin>setting-php@1.0.0</mixin> + <mixin>smarty-v2@1.0.0</mixin> + <mixin>entity-types-php@1.0.0</mixin> </mixins> <civix> <namespace>CRM/OAuth</namespace> - <format>22.12.1</format> + <format>23.02.0</format> </civix> </extension> diff --git a/civicrm/ext/oauth-client/oauth_client.civix.php b/civicrm/ext/oauth-client/oauth_client.civix.php index 91cdf5cfa0..bf8cc5fd0a 100644 --- a/civicrm/ext/oauth-client/oauth_client.civix.php +++ b/civicrm/ext/oauth-client/oauth_client.civix.php @@ -92,9 +92,6 @@ function _oauth_client_civix_civicrm_config($config = NULL) { $configured = TRUE; $extRoot = __DIR__ . DIRECTORY_SEPARATOR; - $extDir = $extRoot . 'templates'; - CRM_Core_Smarty::singleton()->addTemplateDir($extDir); - $include_path = $extRoot . PATH_SEPARATOR . get_include_path(); set_include_path($include_path); // Based on <compatibility>, this does not currently require mixin/polyfill.php. @@ -201,30 +198,3 @@ function _oauth_client_civix_fixNavigationMenuItems(&$nodes, &$maxNavID, $parent } } } - -/** - * (Delegated) Implements hook_civicrm_entityTypes(). - * - * Find any *.entityType.php files, merge their content, and return. - * - * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_entityTypes - */ -function _oauth_client_civix_civicrm_entityTypes(&$entityTypes) { - $entityTypes = array_merge($entityTypes, [ - 'CRM_OAuth_DAO_OAuthClient' => [ - 'name' => 'OAuthClient', - 'class' => 'CRM_OAuth_DAO_OAuthClient', - 'table' => 'civicrm_oauth_client', - ], - 'CRM_OAuth_DAO_OAuthContactToken' => [ - 'name' => 'OAuthContactToken', - 'class' => 'CRM_OAuth_DAO_OAuthContactToken', - 'table' => 'civicrm_oauth_contact_token', - ], - 'CRM_OAuth_DAO_OAuthSysToken' => [ - 'name' => 'OAuthSysToken', - 'class' => 'CRM_OAuth_DAO_OAuthSysToken', - 'table' => 'civicrm_oauth_systoken', - ], - ]); -} diff --git a/civicrm/ext/oauth-client/oauth_client.php b/civicrm/ext/oauth-client/oauth_client.php index c1260c0fd6..fd23498bf8 100644 --- a/civicrm/ext/oauth-client/oauth_client.php +++ b/civicrm/ext/oauth-client/oauth_client.php @@ -44,17 +44,6 @@ function oauth_client_civicrm_permission(&$permissions) { ]; } -/** - * Implements hook_civicrm_entityTypes(). - * - * Declare entity types provided by this module. - * - * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_entityTypes - */ -function oauth_client_civicrm_entityTypes(&$entityTypes) { - _oauth_client_civix_civicrm_entityTypes($entityTypes); -} - /** * @param \Symfony\Component\DependencyInjection\ContainerBuilder $container */ diff --git a/civicrm/ext/payflowpro/info.xml b/civicrm/ext/payflowpro/info.xml index 5aa54aaf0a..49a8e72907 100644 --- a/civicrm/ext/payflowpro/info.xml +++ b/civicrm/ext/payflowpro/info.xml @@ -15,10 +15,10 @@ <url desc="Licensing">http://www.gnu.org/licenses/agpl-3.0.html</url> </urls> <releaseDate>2021-04-13</releaseDate> - <version>5.59.4</version> + <version>5.60.0</version> <develStage>stable</develStage> <compatibility> - <ver>5.59</ver> + <ver>5.60</ver> </compatibility> <comments>This extension is extraction of the original Core Payflow Pro Payment Processor</comments> <classloader> diff --git a/civicrm/ext/recaptcha/info.xml b/civicrm/ext/recaptcha/info.xml index 7eb2eca5e1..a110ae64ea 100644 --- a/civicrm/ext/recaptcha/info.xml +++ b/civicrm/ext/recaptcha/info.xml @@ -13,13 +13,13 @@ <url desc="Licensing">http://www.gnu.org/licenses/agpl-3.0.html</url> </urls> <releaseDate>2021-04-03</releaseDate> - <version>5.59.4</version> + <version>5.60.0</version> <tags> <tag>mgmt:hidden</tag> </tags> <develStage>stable</develStage> <compatibility> - <ver>5.59</ver> + <ver>5.60</ver> </compatibility> <classloader> <psr0 prefix="CRM_" path="."/> @@ -30,9 +30,10 @@ <mixin>setting-php@1.0.0</mixin> <mixin>ang-php@1.0.0</mixin> <mixin>scan-classes@1.0.0</mixin> + <mixin>smarty-v2@1.0.0</mixin> </mixins> <civix> <namespace>CRM/Recaptcha</namespace> - <format>22.10.0</format> + <format>23.02.0</format> </civix> </extension> diff --git a/civicrm/ext/recaptcha/recaptcha.civix.php b/civicrm/ext/recaptcha/recaptcha.civix.php index 67c3221da5..13f0af1218 100644 --- a/civicrm/ext/recaptcha/recaptcha.civix.php +++ b/civicrm/ext/recaptcha/recaptcha.civix.php @@ -84,27 +84,17 @@ use CRM_Recaptcha_ExtensionUtil as E; * * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_config */ -function _recaptcha_civix_civicrm_config(&$config = NULL) { +function _recaptcha_civix_civicrm_config($config = NULL) { static $configured = FALSE; if ($configured) { return; } $configured = TRUE; - $template = CRM_Core_Smarty::singleton(); - $extRoot = __DIR__ . DIRECTORY_SEPARATOR; - $extDir = $extRoot . 'templates'; - - if (is_array($template->template_dir)) { - array_unshift($template->template_dir, $extDir); - } - else { - $template->template_dir = [$extDir, $template->template_dir]; - } - $include_path = $extRoot . PATH_SEPARATOR . get_include_path(); set_include_path($include_path); + // Based on <compatibility>, this does not currently require mixin/polyfill.php. } /** @@ -114,35 +104,7 @@ function _recaptcha_civix_civicrm_config(&$config = NULL) { */ function _recaptcha_civix_civicrm_install() { _recaptcha_civix_civicrm_config(); - if ($upgrader = _recaptcha_civix_upgrader()) { - $upgrader->onInstall(); - } -} - -/** - * Implements hook_civicrm_postInstall(). - * - * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_postInstall - */ -function _recaptcha_civix_civicrm_postInstall() { - _recaptcha_civix_civicrm_config(); - if ($upgrader = _recaptcha_civix_upgrader()) { - if (is_callable([$upgrader, 'onPostInstall'])) { - $upgrader->onPostInstall(); - } - } -} - -/** - * Implements hook_civicrm_uninstall(). - * - * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_uninstall - */ -function _recaptcha_civix_civicrm_uninstall(): void { - _recaptcha_civix_civicrm_config(); - if ($upgrader = _recaptcha_civix_upgrader()) { - $upgrader->onUninstall(); - } + // Based on <compatibility>, this does not currently require mixin/polyfill.php. } /** @@ -152,56 +114,7 @@ function _recaptcha_civix_civicrm_uninstall(): void { */ function _recaptcha_civix_civicrm_enable(): void { _recaptcha_civix_civicrm_config(); - if ($upgrader = _recaptcha_civix_upgrader()) { - if (is_callable([$upgrader, 'onEnable'])) { - $upgrader->onEnable(); - } - } -} - -/** - * (Delegated) Implements hook_civicrm_disable(). - * - * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_disable - * @return mixed - */ -function _recaptcha_civix_civicrm_disable(): void { - _recaptcha_civix_civicrm_config(); - if ($upgrader = _recaptcha_civix_upgrader()) { - if (is_callable([$upgrader, 'onDisable'])) { - $upgrader->onDisable(); - } - } -} - -/** - * (Delegated) Implements hook_civicrm_upgrade(). - * - * @param $op string, the type of operation being performed; 'check' or 'enqueue' - * @param $queue CRM_Queue_Queue, (for 'enqueue') the modifiable list of pending up upgrade tasks - * - * @return mixed - * based on op. for 'check', returns array(boolean) (TRUE if upgrades are pending) - * for 'enqueue', returns void - * - * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_upgrade - */ -function _recaptcha_civix_civicrm_upgrade($op, CRM_Queue_Queue $queue = NULL) { - if ($upgrader = _recaptcha_civix_upgrader()) { - return $upgrader->onUpgrade($op, $queue); - } -} - -/** - * @return CRM_Recaptcha_Upgrader - */ -function _recaptcha_civix_upgrader() { - if (!file_exists(__DIR__ . '/CRM/Recaptcha/Upgrader.php')) { - return NULL; - } - else { - return CRM_Recaptcha_Upgrader_Base::instance(); - } + // Based on <compatibility>, this does not currently require mixin/polyfill.php. } /** @@ -285,14 +198,3 @@ function _recaptcha_civix_fixNavigationMenuItems(&$nodes, &$maxNavID, $parentID) } } } - -/** - * (Delegated) Implements hook_civicrm_entityTypes(). - * - * Find any *.entityType.php files, merge their content, and return. - * - * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_entityTypes - */ -function _recaptcha_civix_civicrm_entityTypes(&$entityTypes) { - $entityTypes = array_merge($entityTypes, []); -} diff --git a/civicrm/ext/recaptcha/recaptcha.php b/civicrm/ext/recaptcha/recaptcha.php index 64c46c5225..e959cfb329 100644 --- a/civicrm/ext/recaptcha/recaptcha.php +++ b/civicrm/ext/recaptcha/recaptcha.php @@ -23,24 +23,6 @@ function recaptcha_civicrm_install() { _recaptcha_civix_civicrm_install(); } -/** - * Implements hook_civicrm_postInstall(). - * - * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_postInstall - */ -function recaptcha_civicrm_postInstall() { - _recaptcha_civix_civicrm_postInstall(); -} - -/** - * Implements hook_civicrm_uninstall(). - * - * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_uninstall - */ -function recaptcha_civicrm_uninstall() { - _recaptcha_civix_civicrm_uninstall(); -} - /** * Implements hook_civicrm_enable(). * @@ -50,35 +32,6 @@ function recaptcha_civicrm_enable() { _recaptcha_civix_civicrm_enable(); } -/** - * Implements hook_civicrm_disable(). - * - * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_disable - */ -function recaptcha_civicrm_disable() { - _recaptcha_civix_civicrm_disable(); -} - -/** - * Implements hook_civicrm_upgrade(). - * - * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_upgrade - */ -function recaptcha_civicrm_upgrade($op, CRM_Queue_Queue $queue = NULL) { - return _recaptcha_civix_civicrm_upgrade($op, $queue); -} - -/** - * Implements hook_civicrm_entityTypes(). - * - * Declare entity types provided by this module. - * - * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_entityTypes - */ -function recaptcha_civicrm_entityTypes(&$entityTypes) { - _recaptcha_civix_civicrm_entityTypes($entityTypes); -} - /** * Implements hook_civicrm_navigationMenu(). */ diff --git a/civicrm/ext/search_kit/CRM/Search/Upgrader.php b/civicrm/ext/search_kit/CRM/Search/Upgrader.php index 8451a3c491..aa37914a90 100644 --- a/civicrm/ext/search_kit/CRM/Search/Upgrader.php +++ b/civicrm/ext/search_kit/CRM/Search/Upgrader.php @@ -4,7 +4,7 @@ use CRM_Search_ExtensionUtil as E; /** * Collection of upgrade steps. */ -class CRM_Search_Upgrader extends CRM_Search_Upgrader_Base { +class CRM_Search_Upgrader extends CRM_Extension_Upgrader_Base { /** * Upgrade 1000 - install schema diff --git a/civicrm/ext/search_kit/CRM/Search/Upgrader/Base.php b/civicrm/ext/search_kit/CRM/Search/Upgrader/Base.php deleted file mode 100644 index 4efc0e415f..0000000000 --- a/civicrm/ext/search_kit/CRM/Search/Upgrader/Base.php +++ /dev/null @@ -1,7 +0,0 @@ -<?php - -/** - * Base class which provides helpers to execute upgrade logic - */ -class CRM_Search_Upgrader_Base extends CRM_Extension_Upgrader_Base { -} diff --git a/civicrm/ext/search_kit/Civi/Api4/Action/SearchDisplay/GetSearchTasks.php b/civicrm/ext/search_kit/Civi/Api4/Action/SearchDisplay/GetSearchTasks.php index b2ca9c97c0..f1fb340a88 100644 --- a/civicrm/ext/search_kit/Civi/Api4/Action/SearchDisplay/GetSearchTasks.php +++ b/civicrm/ext/search_kit/Civi/Api4/Action/SearchDisplay/GetSearchTasks.php @@ -206,13 +206,15 @@ class GetSearchTasks extends \Civi\Api4\Generic\AbstractAction { } } - // Call `hook_civicrm_searchKitTasks`. - // Note - this hook serves 2 purposes, both to augment this list of tasks AND to - // get a full list of Angular modules which provide tasks. That's why this hook needs - // the base-level array and not just the array of tasks for `$this->entity`. - // Although it may seem wasteful to have extensions add tasks for all possible entities and then - // discard most of it (all but the ones relevant to `$this->entity`), it's necessary to do it this way - // so that they can be declared as angular dependencies - see search_kit_civicrm_angularModules(). + // Call `hook_civicrm_searchKitTasks` which serves 3 purposes: + // 1. For extensions to augment this list of tasks + // 2. To allow tasks to be added/removed per search display + // Note: Use Events::W_LATE to do so after the tasks are filtered per search-display settings. + // 3. To get a full list of Angular modules which provide tasks. + // Note: That's why this hook needs the base-level array and not just the array of tasks for `$this->entity`. + // Although it may seem wasteful to have extensions add tasks for all possible entities and then + // discard most of it (all but the ones relevant to `$this->entity`), it's necessary to do it this way + // so that they can be declared as angular dependencies - see search_kit_civicrm_angularModules(). $null = NULL; $checkPermissions = $this->checkPermissions; $userId = $this->checkPermissions ? \CRM_Core_Session::getLoggedInContactID() : NULL; @@ -234,7 +236,7 @@ class GetSearchTasks extends \Civi\Api4\Generic\AbstractAction { $result->exchangeArray($tasks[$entity['name']]); } - public static function fields() { + public static function fields(): array { return [ [ 'name' => 'name', diff --git a/civicrm/ext/search_kit/Civi/Api4/Event/Subscriber/SearchDisplayTasksSubscriber.php b/civicrm/ext/search_kit/Civi/Api4/Event/Subscriber/SearchDisplayTasksSubscriber.php new file mode 100644 index 0000000000..832ce2808e --- /dev/null +++ b/civicrm/ext/search_kit/Civi/Api4/Event/Subscriber/SearchDisplayTasksSubscriber.php @@ -0,0 +1,48 @@ +<?php +/* + +--------------------------------------------------------------------+ + | Copyright CiviCRM LLC. All rights reserved. | + | | + | This work is published under the GNU AGPLv3 license with some | + | permitted exceptions and without any warranty. For full license | + | and copyright information, see https://civicrm.org/licensing | + +--------------------------------------------------------------------+ + */ + +namespace Civi\Api4\Event\Subscriber; + +use Civi\Core\Event\GenericHookEvent; +use Symfony\Component\EventDispatcher\EventSubscriberInterface; + +/** + * Event subscriber to filter search display tasks + * @service + * @internal + */ +class SearchDisplayTasksSubscriber extends \Civi\Core\Service\AutoService implements EventSubscriberInterface { + + /** + * Filter tasks with a priority of -50, which allows W_MIDDLE & W_EARLY to go first, but W_LATE to go after. + * + * @return array + */ + public static function getSubscribedEvents() { + return [ + 'hook_civicrm_searchKitTasks' => [ + ['filterTasksForDisplay', -50], + ], + ]; + } + + /** + * @param \Civi\Core\Event\GenericHookEvent $event + */ + public function filterTasksForDisplay(GenericHookEvent $event): void { + $enabledActions = $event->display['settings']['actions'] ?? NULL; + $entityName = $event->search['api_entity'] ?? NULL; + if ($entityName && is_array($enabledActions)) { + $event->tasks[$entityName] = array_intersect_key($event->tasks[$entityName], array_flip($enabledActions)); + } + } + +} diff --git a/civicrm/ext/search_kit/Civi/Search/Admin.php b/civicrm/ext/search_kit/Civi/Search/Admin.php index ee85568afd..4967484f6f 100644 --- a/civicrm/ext/search_kit/Civi/Search/Admin.php +++ b/civicrm/ext/search_kit/Civi/Search/Admin.php @@ -191,9 +191,10 @@ class Admin { foreach (array_reverse($entity['fields'], TRUE) as $index => $field) { if (!empty($field['fk_entity']) && !$field['options'] && !empty($schema[$field['fk_entity']]['label_field'])) { $isCustom = strpos($field['name'], '.'); - // Custom fields: append "Contact ID" to original field label + // Custom fields: append "Contact ID" etc. to original field label if ($isCustom) { - $entity['fields'][$index]['label'] .= ' ' . E::ts('Contact ID'); + $idField = array_column($schema[$field['fk_entity']]['fields'], NULL, 'name')['id']; + $entity['fields'][$index]['label'] .= ' ' . $idField['title']; } // DAO fields: use title instead of label since it represents the id (title usually ends in ID but label does not) else { diff --git a/civicrm/ext/search_kit/ang/crmSearchAdmin/crmSearchAdminLinkGroup.html b/civicrm/ext/search_kit/ang/crmSearchAdmin/crmSearchAdminLinkGroup.html index 51d0d2a47c..11a1765f09 100644 --- a/civicrm/ext/search_kit/ang/crmSearchAdmin/crmSearchAdminLinkGroup.html +++ b/civicrm/ext/search_kit/ang/crmSearchAdmin/crmSearchAdminLinkGroup.html @@ -71,7 +71,7 @@ <tfoot> <tr> <td colspan="6" class="form-inline"> - <select class="form-control crm-search-admin-add-link" ng-show="$ctrl.links.length"> + <select class="form-control crm-search-admin-add-link"> <option value=""> + {{:: ts('Add...') }} </option> diff --git a/civicrm/ext/search_kit/ang/crmSearchAdmin/displays/common/searchAdminTasksConfig.component.js b/civicrm/ext/search_kit/ang/crmSearchAdmin/displays/common/searchAdminTasksConfig.component.js new file mode 100644 index 0000000000..11887b9570 --- /dev/null +++ b/civicrm/ext/search_kit/ang/crmSearchAdmin/displays/common/searchAdminTasksConfig.component.js @@ -0,0 +1,58 @@ +(function(angular, $, _) { + "use strict"; + + angular.module('crmSearchAdmin').component('searchAdminTasksConfig', { + bindings: { + display: '<', + apiEntity: '<', + apiParams: '<' + }, + templateUrl: '~/crmSearchAdmin/displays/common/searchAdminTasksConfig.html', + controller: function($scope, crmApi4, $timeout) { + var ts = $scope.ts = CRM.ts('org.civicrm.search_kit'), + ctrl = this; + + this.$onInit = function() { + crmApi4('SearchDisplay', 'getSearchTasks', { + entity: ctrl.apiEntity, + savedSearch: {api_entity: ctrl.apiEntity, api_params: ctrl.apiParams} + }).then(function(tasks) { + ctrl.allTasks = tasks; + }); + }; + + this.toggleActions = function() { + this.display.settings.actions = !this.display.settings.actions; + ctrl.menuOpen = false; + }; + + this.toggleTask = function(name) { + // Timeout waits for checkbox state to change, otherwise checkbox 'checked' property gets out-of-sync with angular model + $timeout(function() { + // Disabling one when all enabled, convert to array + if (typeof ctrl.display.settings.actions === 'boolean') { + ctrl.display.settings.actions = _.map(ctrl.allTasks, 'name'); + } + // Remove enabled task + if (ctrl.display.settings.actions.includes(name)) { + _.pull(ctrl.display.settings.actions, name); + } + // Add disabled task + else { + ctrl.display.settings.actions.push(name); + } + // All enabled, convert to boolean + if (ctrl.display.settings.actions.length === ctrl.allTasks.length) { + ctrl.display.settings.actions = true; + } + }); + }; + + this.isEnabled = function(name) { + return (typeof this.display.settings.actions === 'boolean') || this.display.settings.actions.includes(name); + }; + + } + }); + +})(angular, CRM.$, CRM._); diff --git a/civicrm/ext/search_kit/ang/crmSearchAdmin/displays/common/searchAdminTasksConfig.html b/civicrm/ext/search_kit/ang/crmSearchAdmin/displays/common/searchAdminTasksConfig.html new file mode 100644 index 0000000000..b6ae4adc2c --- /dev/null +++ b/civicrm/ext/search_kit/ang/crmSearchAdmin/displays/common/searchAdminTasksConfig.html @@ -0,0 +1,26 @@ +<div class="checkbox-inline form-control"> + <label> + <input type="checkbox" ng-checked="$ctrl.display.settings.actions" ng-click="$ctrl.toggleActions()"> + <span>{{:: ts('Actions Menu') }}</span> + </label> +</div> +<div class="input-group" ng-if="$ctrl.display.settings.actions"> + <div class="input-group-btn"> + <button type="button" ng-click="$ctrl.menuOpen = true" class="btn btn-sm btn-default dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> + <span ng-if="$ctrl.display.settings.actions === true">{{:: ts('All Enabled') }}</span> + <span ng-if="$ctrl.display.settings.actions !== true">{{ ts('%1 Enabled', {1: $ctrl.display.settings.actions.length}) }}</span> + <span class="caret"></span> + </button> + <ul class="dropdown-menu" ng-if="$ctrl.menuOpen"> + <li ng-if="!$ctrl.allTasks" class="disabled"> + <a href><i class="crm-i fa-spinner fa-spin"></i></a> + </li> + <li ng-repeat="task in $ctrl.allTasks"> + <a href ng-click="$ctrl.toggleTask(task.name); $event.stopPropagation()"> + <input type="checkbox" ng-checked="$ctrl.isEnabled(task.name)"> + {{:: task.title }} + </a> + </li> + </ul> + </div> +</div> diff --git a/civicrm/ext/search_kit/ang/crmSearchAdmin/displays/searchAdminDisplayTable.html b/civicrm/ext/search_kit/ang/crmSearchAdmin/displays/searchAdminDisplayTable.html index 9de37446b5..737dbdd479 100644 --- a/civicrm/ext/search_kit/ang/crmSearchAdmin/displays/searchAdminDisplayTable.html +++ b/civicrm/ext/search_kit/ang/crmSearchAdmin/displays/searchAdminDisplayTable.html @@ -10,12 +10,9 @@ </div> </div> <div class="form-inline"> - <div class="checkbox-inline form-control"> - <label> - <input type="checkbox" ng-model="$ctrl.display.settings.actions"> - <span>{{:: ts('Enable Actions') }}</span> - </label> - </div> + <search-admin-tasks-config display="$ctrl.display" api-entity="$ctrl.apiEntity" api-params="$ctrl.apiParams"></search-admin-tasks-config> + </div> + <div class="form-inline"> <div class="form-group" ng-include="'~/crmSearchAdmin/displays/common/searchButtonConfig.html'"></div> </div> <div class="form-inline"> diff --git a/civicrm/ext/search_kit/ang/crmSearchAdmin/resultsTable/debug.html b/civicrm/ext/search_kit/ang/crmSearchAdmin/resultsTable/debug.html index d435faed5d..f80476cdaf 100644 --- a/civicrm/ext/search_kit/ang/crmSearchAdmin/resultsTable/debug.html +++ b/civicrm/ext/search_kit/ang/crmSearchAdmin/resultsTable/debug.html @@ -9,9 +9,8 @@ <strong>API:</strong> </div> <pre>{{ $ctrl.debug.apiParams }}</pre> - <div ng-if="$ctrl.debug.sql"> - <strong>SQL:</strong> - </div> + <strong>SQL:</strong> + <pre ng-if="!$ctrl.debug.sql">{{:: ts('Run search to view SQL') }}</pre> <pre ng-repeat="query in $ctrl.debug.sql">{{ query }}</pre> </div> </fieldset> diff --git a/civicrm/ext/search_kit/ang/crmSearchAdmin/searchListing/crmSearchAdminSearchListing.component.js b/civicrm/ext/search_kit/ang/crmSearchAdmin/searchListing/crmSearchAdminSearchListing.component.js index 69d59c8010..c9b75271f1 100644 --- a/civicrm/ext/search_kit/ang/crmSearchAdmin/searchListing/crmSearchAdminSearchListing.component.js +++ b/civicrm/ext/search_kit/ang/crmSearchAdmin/searchListing/crmSearchAdminSearchListing.component.js @@ -56,7 +56,7 @@ ['Group AS group', 'LEFT', ['id', '=', 'group.saved_search_id']], ['EntityTag AS entity_tag', 'LEFT', ['entity_tag.entity_table', '=', '"civicrm_saved_search"'], ['id', '=', 'entity_tag.entity_id']], ], - where: [['api_entity', 'IS NOT NULL']], + where: [['api_entity', 'IS NOT NULL'], ['is_current', '=', true]], groupBy: ['id'] } }; diff --git a/civicrm/ext/search_kit/info.xml b/civicrm/ext/search_kit/info.xml index ed8ca3afd2..e4fab06e36 100644 --- a/civicrm/ext/search_kit/info.xml +++ b/civicrm/ext/search_kit/info.xml @@ -15,13 +15,13 @@ <url desc="Licensing">http://www.gnu.org/licenses/agpl-3.0.html</url> </urls> <releaseDate>2021-01-06</releaseDate> - <version>5.59.4</version> + <version>5.60.0</version> <develStage>stable</develStage> <tags> <tag>mgmt:required</tag> </tags> <compatibility> - <ver>5.59</ver> + <ver>5.60</ver> </compatibility> <comments>Click on the chat link above to discuss development, report problems or ask questions.</comments> <classloader> @@ -39,6 +39,6 @@ </mixins> <civix> <namespace>CRM/Search</namespace> - <format>22.10.0</format> + <format>23.02.0</format> </civix> </extension> diff --git a/civicrm/ext/search_kit/search_kit.civix.php b/civicrm/ext/search_kit/search_kit.civix.php index b74feb61fc..a0be0f9032 100644 --- a/civicrm/ext/search_kit/search_kit.civix.php +++ b/civicrm/ext/search_kit/search_kit.civix.php @@ -84,7 +84,7 @@ use CRM_Search_ExtensionUtil as E; * * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_config */ -function _search_kit_civix_civicrm_config(&$config = NULL) { +function _search_kit_civix_civicrm_config($config = NULL) { static $configured = FALSE; if ($configured) { return; @@ -92,9 +92,9 @@ function _search_kit_civix_civicrm_config(&$config = NULL) { $configured = TRUE; $extRoot = __DIR__ . DIRECTORY_SEPARATOR; - $include_path = $extRoot . PATH_SEPARATOR . get_include_path(); set_include_path($include_path); + // Based on <compatibility>, this does not currently require mixin/polyfill.php. } /** @@ -104,35 +104,7 @@ function _search_kit_civix_civicrm_config(&$config = NULL) { */ function _search_kit_civix_civicrm_install() { _search_kit_civix_civicrm_config(); - if ($upgrader = _search_kit_civix_upgrader()) { - $upgrader->onInstall(); - } -} - -/** - * Implements hook_civicrm_postInstall(). - * - * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_postInstall - */ -function _search_kit_civix_civicrm_postInstall() { - _search_kit_civix_civicrm_config(); - if ($upgrader = _search_kit_civix_upgrader()) { - if (is_callable([$upgrader, 'onPostInstall'])) { - $upgrader->onPostInstall(); - } - } -} - -/** - * Implements hook_civicrm_uninstall(). - * - * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_uninstall - */ -function _search_kit_civix_civicrm_uninstall(): void { - _search_kit_civix_civicrm_config(); - if ($upgrader = _search_kit_civix_upgrader()) { - $upgrader->onUninstall(); - } + // Based on <compatibility>, this does not currently require mixin/polyfill.php. } /** @@ -142,56 +114,7 @@ function _search_kit_civix_civicrm_uninstall(): void { */ function _search_kit_civix_civicrm_enable(): void { _search_kit_civix_civicrm_config(); - if ($upgrader = _search_kit_civix_upgrader()) { - if (is_callable([$upgrader, 'onEnable'])) { - $upgrader->onEnable(); - } - } -} - -/** - * (Delegated) Implements hook_civicrm_disable(). - * - * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_disable - * @return mixed - */ -function _search_kit_civix_civicrm_disable(): void { - _search_kit_civix_civicrm_config(); - if ($upgrader = _search_kit_civix_upgrader()) { - if (is_callable([$upgrader, 'onDisable'])) { - $upgrader->onDisable(); - } - } -} - -/** - * (Delegated) Implements hook_civicrm_upgrade(). - * - * @param $op string, the type of operation being performed; 'check' or 'enqueue' - * @param $queue CRM_Queue_Queue, (for 'enqueue') the modifiable list of pending up upgrade tasks - * - * @return mixed - * based on op. for 'check', returns array(boolean) (TRUE if upgrades are pending) - * for 'enqueue', returns void - * - * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_upgrade - */ -function _search_kit_civix_civicrm_upgrade($op, CRM_Queue_Queue $queue = NULL) { - if ($upgrader = _search_kit_civix_upgrader()) { - return $upgrader->onUpgrade($op, $queue); - } -} - -/** - * @return CRM_Search_Upgrader - */ -function _search_kit_civix_upgrader() { - if (!file_exists(__DIR__ . '/CRM/Search/Upgrader.php')) { - return NULL; - } - else { - return CRM_Search_Upgrader_Base::instance(); - } + // Based on <compatibility>, this does not currently require mixin/polyfill.php. } /** @@ -275,25 +198,3 @@ function _search_kit_civix_fixNavigationMenuItems(&$nodes, &$maxNavID, $parentID } } } - -/** - * (Delegated) Implements hook_civicrm_entityTypes(). - * - * Find any *.entityType.php files, merge their content, and return. - * - * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_entityTypes - */ -function _search_kit_civix_civicrm_entityTypes(&$entityTypes) { - $entityTypes = array_merge($entityTypes, [ - 'CRM_Search_DAO_SearchDisplay' => [ - 'name' => 'SearchDisplay', - 'class' => 'CRM_Search_DAO_SearchDisplay', - 'table' => 'civicrm_search_display', - ], - 'CRM_Search_DAO_SearchSegment' => [ - 'name' => 'SearchSegment', - 'class' => 'CRM_Search_DAO_SearchSegment', - 'table' => 'civicrm_search_segment', - ], - ]); -} diff --git a/civicrm/ext/sequentialcreditnotes/info.xml b/civicrm/ext/sequentialcreditnotes/info.xml index 1fb3612d03..d938f5f572 100644 --- a/civicrm/ext/sequentialcreditnotes/info.xml +++ b/civicrm/ext/sequentialcreditnotes/info.xml @@ -15,19 +15,19 @@ <url desc="Licensing">http://www.gnu.org/licenses/agpl-3.0.html</url> </urls> <releaseDate>2020-01-28</releaseDate> - <version>5.59.4</version> + <version>5.60.0</version> <tags> <tag>mgmt:hidden</tag> </tags> <develStage>stable</develStage> <compatibility> - <ver>5.59</ver> + <ver>5.60</ver> </compatibility> <mixins> <mixin>setting-php@1.0.0</mixin> </mixins> <civix> <namespace>CRM/Sequentialcreditnotes</namespace> - <format>22.10.0</format> + <format>23.02.0</format> </civix> </extension> diff --git a/civicrm/ext/sequentialcreditnotes/sequentialcreditnotes.civix.php b/civicrm/ext/sequentialcreditnotes/sequentialcreditnotes.civix.php index e17812d6ab..4b35c35b76 100644 --- a/civicrm/ext/sequentialcreditnotes/sequentialcreditnotes.civix.php +++ b/civicrm/ext/sequentialcreditnotes/sequentialcreditnotes.civix.php @@ -84,27 +84,17 @@ use CRM_Sequentialcreditnotes_ExtensionUtil as E; * * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_config */ -function _sequentialcreditnotes_civix_civicrm_config(&$config = NULL) { +function _sequentialcreditnotes_civix_civicrm_config($config = NULL) { static $configured = FALSE; if ($configured) { return; } $configured = TRUE; - $template = CRM_Core_Smarty::singleton(); - $extRoot = __DIR__ . DIRECTORY_SEPARATOR; - $extDir = $extRoot . 'templates'; - - if (is_array($template->template_dir)) { - array_unshift($template->template_dir, $extDir); - } - else { - $template->template_dir = [$extDir, $template->template_dir]; - } - $include_path = $extRoot . PATH_SEPARATOR . get_include_path(); set_include_path($include_path); + // Based on <compatibility>, this does not currently require mixin/polyfill.php. } /** @@ -114,35 +104,7 @@ function _sequentialcreditnotes_civix_civicrm_config(&$config = NULL) { */ function _sequentialcreditnotes_civix_civicrm_install() { _sequentialcreditnotes_civix_civicrm_config(); - if ($upgrader = _sequentialcreditnotes_civix_upgrader()) { - $upgrader->onInstall(); - } -} - -/** - * Implements hook_civicrm_postInstall(). - * - * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_postInstall - */ -function _sequentialcreditnotes_civix_civicrm_postInstall() { - _sequentialcreditnotes_civix_civicrm_config(); - if ($upgrader = _sequentialcreditnotes_civix_upgrader()) { - if (is_callable([$upgrader, 'onPostInstall'])) { - $upgrader->onPostInstall(); - } - } -} - -/** - * Implements hook_civicrm_uninstall(). - * - * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_uninstall - */ -function _sequentialcreditnotes_civix_civicrm_uninstall(): void { - _sequentialcreditnotes_civix_civicrm_config(); - if ($upgrader = _sequentialcreditnotes_civix_upgrader()) { - $upgrader->onUninstall(); - } + // Based on <compatibility>, this does not currently require mixin/polyfill.php. } /** @@ -152,56 +114,7 @@ function _sequentialcreditnotes_civix_civicrm_uninstall(): void { */ function _sequentialcreditnotes_civix_civicrm_enable(): void { _sequentialcreditnotes_civix_civicrm_config(); - if ($upgrader = _sequentialcreditnotes_civix_upgrader()) { - if (is_callable([$upgrader, 'onEnable'])) { - $upgrader->onEnable(); - } - } -} - -/** - * (Delegated) Implements hook_civicrm_disable(). - * - * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_disable - * @return mixed - */ -function _sequentialcreditnotes_civix_civicrm_disable(): void { - _sequentialcreditnotes_civix_civicrm_config(); - if ($upgrader = _sequentialcreditnotes_civix_upgrader()) { - if (is_callable([$upgrader, 'onDisable'])) { - $upgrader->onDisable(); - } - } -} - -/** - * (Delegated) Implements hook_civicrm_upgrade(). - * - * @param $op string, the type of operation being performed; 'check' or 'enqueue' - * @param $queue CRM_Queue_Queue, (for 'enqueue') the modifiable list of pending up upgrade tasks - * - * @return mixed - * based on op. for 'check', returns array(boolean) (TRUE if upgrades are pending) - * for 'enqueue', returns void - * - * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_upgrade - */ -function _sequentialcreditnotes_civix_civicrm_upgrade($op, CRM_Queue_Queue $queue = NULL) { - if ($upgrader = _sequentialcreditnotes_civix_upgrader()) { - return $upgrader->onUpgrade($op, $queue); - } -} - -/** - * @return CRM_Sequentialcreditnotes_Upgrader - */ -function _sequentialcreditnotes_civix_upgrader() { - if (!file_exists(__DIR__ . '/CRM/Sequentialcreditnotes/Upgrader.php')) { - return NULL; - } - else { - return CRM_Sequentialcreditnotes_Upgrader_Base::instance(); - } + // Based on <compatibility>, this does not currently require mixin/polyfill.php. } /** @@ -285,14 +198,3 @@ function _sequentialcreditnotes_civix_fixNavigationMenuItems(&$nodes, &$maxNavID } } } - -/** - * (Delegated) Implements hook_civicrm_entityTypes(). - * - * Find any *.entityType.php files, merge their content, and return. - * - * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_entityTypes - */ -function _sequentialcreditnotes_civix_civicrm_entityTypes(&$entityTypes) { - $entityTypes = array_merge($entityTypes, []); -} diff --git a/civicrm/js/Common.js b/civicrm/js/Common.js index 7d26948058..021254d07c 100644 --- a/civicrm/js/Common.js +++ b/civicrm/js/Common.js @@ -1133,6 +1133,9 @@ if (!CRM.vars) CRM.vars = {}; } $('.crm-select2:not(.select2-offscreen, .select2-container)', e.target).crmSelect2(); $('.crm-form-entityref:not(.select2-offscreen, .select2-container)', e.target).crmEntityRef(); + $('.crm-form-autocomplete:not(.select2-offscreen, .select2-container)[data-api-entity]', e.target).each(function() { + $(this).crmAutocomplete($(this).data('apiEntity'), $(this).data('apiParams'), $(this).data('selectParams')); + }); $('select.crm-chain-select-control', e.target).off('.chainSelect').on('change.chainSelect', chainSelect); $('.crm-form-text[data-crm-datepicker]', e.target).each(function() { $(this).crmDatepicker($(this).data('crmDatepicker')); diff --git a/civicrm/mixin/smarty-v2@1/mixin.php b/civicrm/mixin/smarty-v2@1/mixin.php index 0b371057cc..5972dbdc57 100644 --- a/civicrm/mixin/smarty-v2@1/mixin.php +++ b/civicrm/mixin/smarty-v2@1/mixin.php @@ -4,7 +4,7 @@ * Auto-register "templates/" folder. * * @mixinName smarty-v2 - * @mixinVersion 1.0.0 + * @mixinVersion 1.0.1 * @since 5.59 * * @param CRM_Extension_MixInfo $mixInfo @@ -19,14 +19,9 @@ return function ($mixInfo, $bootCache) { } $register = function() use ($dir) { - // This implementation is useful for older versions of CiviCRM. It can be replaced/updated going forward (v1.1+). - $smarty = CRM_Core_Smarty::singleton(); - if (!is_array($smarty->template_dir)) { - $this->template_dir = [$smarty->template_dir]; - } - if (!in_array($dir, $smarty->template_dir)) { - array_unshift($smarty->template_dir, $dir); - } + // This implementation has a theoretical edge-case bug on older versions of CiviCRM where a template could + // be registered more than once. + CRM_Core_Smarty::singleton()->addTemplateDir($dir); }; // Let's figure out what environment we're in -- so that we know the best way to call $register(). diff --git a/civicrm/release-notes.md b/civicrm/release-notes.md index 7741436a04..301b093190 100644 --- a/civicrm/release-notes.md +++ b/civicrm/release-notes.md @@ -15,41 +15,16 @@ Other resources for identifying changes are: * https://github.com/civicrm/civicrm-joomla * https://github.com/civicrm/civicrm-wordpress -## CiviCRM 5.59.4 +## CiviCRM 5.60.0 -Released March 27, 2023 +Released April 5, 2023 -- **[Synopsis](release-notes/5.59.4.md#synopsis)** -- **[Bugs resolved](release-notes/5.59.4.md#bugs)** -- **[Credits](release-notes/5.59.4.md#credits)** -- **[Feedback](release-notes/5.59.4.md#feedback)** - -## CiviCRM 5.59.3 - -Released March 15, 2023 - -- **[Synopsis](release-notes/5.59.3.md#synopsis)** -- **[Bugs resolved](release-notes/5.59.3.md#bugs)** -- **[Credits](release-notes/5.59.3.md#credits)** -- **[Feedback](release-notes/5.59.3.md#feedback)** - -## CiviCRM 5.59.2 - -Released March 10, 2023 - -- **[Synopsis](release-notes/5.59.2.md#synopsis)** -- **[Bugs resolved](release-notes/5.59.2.md#bugs)** -- **[Credits](release-notes/5.59.2.md#credits)** -- **[Feedback](release-notes/5.59.2.md#feedback)** - -## CiviCRM 5.59.1 - -Released March 3, 2023 - -- **[Synopsis](release-notes/5.59.1.md#synopsis)** -- **[Bugs resolved](release-notes/5.59.1.md#bugs)** -- **[Credits](release-notes/5.59.1.md#credits)** -- **[Feedback](release-notes/5.59.1.md#feedback)** +- **[Synopsis](release-notes/5.60.0.md#synopsis)** +- **[Features](release-notes/5.60.0.md#features)** +- **[Bugs resolved](release-notes/5.60.0.md#bugs)** +- **[Miscellany](release-notes/5.60.0.md#misc)** +- **[Credits](release-notes/5.60.0.md#credits)** +- **[Feedback](release-notes/5.60.0.md#feedback)** ## CiviCRM 5.59.0 diff --git a/civicrm/release-notes/5.59.1.md b/civicrm/release-notes/5.59.1.md deleted file mode 100644 index e66582b65e..0000000000 --- a/civicrm/release-notes/5.59.1.md +++ /dev/null @@ -1,41 +0,0 @@ -# CiviCRM 5.59.1 - -Released March 3, 2023 - -- **[Synopsis](#synopsis)** -- **[Bugs resolved](#bugs)** -- **[Credits](#credits)** -- **[Feedback](#feedback)** - -## <a name="synopsis"></a>Synopsis - -| *Does this version...?* | | -| --------------------------------------------------------------- | -------- | -| Change the database schema? | no | -| Alter the API? | no | -| Require attention to configuration options? | no | -| **Fix problems installing or upgrading to a previous version?** | **yes** | -| Introduce features? | no | -| **Fix bugs?** | **yes** | -| Fix security vulnerabilities? | no | - -## <a name="bugs"></a>Bugs resolved - -* **_CiviContribute_: Contribution pages crash if CiviMember is disabled ([#25729](https://github.com/civicrm/civicrm-core/pull/25729))** -* **_Tokens_: Abbreviated state/province does not display ([dev/core#4147](https://lab.civicrm.org/dev/core/-/issues/4147): [#25704](https://github.com/civicrm/civicrm-core/pull/25704))** -* **_Multilingual_: Site reports `DB Error: -32` after running upgrade ([dev/core#4155](https://lab.civicrm.org/dev/core/-/issues/4155): [#25733](https://github.com/civicrm/civicrm-core/pull/25733))** - - If you previously ran the 5.59.0 upgrade on a multilingual site and have a persistent fatal error, then you may wish to (a) consult the Gitlab discussion for resolution steps or (b) rollback to the original DB and upgrade to 5.59.1 instead. - -## <a name="credits"></a>Credits - -This release was developed by the following authors and reviewers: - -Wikimedia Foundation - Eileen McNaughton; Megaphone Technology Consulting - Jon Goldberg; -JMA Consulting - Seamus Lee; CiviCRM - Tim Otten; Agileware - Justin Freeman - -## <a name="feedback"></a>Feedback - -These release notes are edited by Tim Otten and Andie Hunt. If you'd like to -provide feedback on them, please login to https://chat.civicrm.org/civicrm and -contact `@agh1`. diff --git a/civicrm/release-notes/5.59.2.md b/civicrm/release-notes/5.59.2.md deleted file mode 100644 index b807de68d1..0000000000 --- a/civicrm/release-notes/5.59.2.md +++ /dev/null @@ -1,39 +0,0 @@ -# CiviCRM 5.59.2 - -Released March 10, 2023 - -- **[Synopsis](#synopsis)** -- **[Bugs resolved](#bugs)** -- **[Credits](#credits)** -- **[Feedback](#feedback)** - -## <a name="synopsis"></a>Synopsis - -| *Does this version...?* | | -| --------------------------------------------------------------- | -------- | -| Change the database schema? | no | -| Alter the API? | no | -| Require attention to configuration options? | no | -| Fix problems installing or upgrading to a previous version? | no | -| Introduce features? | no | -| **Fix bugs?** | **yes** | -| Fix security vulnerabilities? | no | - -## <a name="bugs"></a>Bugs resolved - -* **_Import_: Contribution note does not accept empty string ([dev/core#4105](https://lab.civicrm.org/dev/core/-/issues/4105): [#25569](https://github.com/civicrm/civicrm-core/pull/25569))** -* **_PayPal Pro_: New recurring payments recorded twice ([dev/core#4158](https://lab.civicrm.org/dev/core/-/issues/4158): [#25775](https://github.com/civicrm/civicrm-core/pull/25775))** - -## <a name="credits"></a>Credits - -This release was developed by the following authors and reviewers: - -Wikimedia Foundation - Eileen McNaughton; PERORA SRL - Samuele Masetto; MJW Consulting - -Matthew Wire; Megaphone Technology Consulting - Jon Goldberg; Korlon - Stuart Gaston; JMA -Consulting - Seamus Lee; Dave D; CiviCRM - Tim Otten - -## <a name="feedback"></a>Feedback - -These release notes are edited by Tim Otten and Andie Hunt. If you'd like to -provide feedback on them, please login to https://chat.civicrm.org/civicrm and -contact `@agh1`. diff --git a/civicrm/release-notes/5.59.3.md b/civicrm/release-notes/5.59.3.md deleted file mode 100644 index ccb3b0de04..0000000000 --- a/civicrm/release-notes/5.59.3.md +++ /dev/null @@ -1,38 +0,0 @@ -# CiviCRM 5.59.3 - -Released March 15, 2023 - -- **[Synopsis](#synopsis)** -- **[Bugs resolved](#bugs)** -- **[Credits](#credits)** -- **[Feedback](#feedback)** - -## <a name="synopsis"></a>Synopsis - -| *Does this version...?* | | -| --------------------------------------------------------------- | -------- | -| Change the database schema? | no | -| Alter the API? | no | -| Require attention to configuration options? | no | -| Fix problems installing or upgrading to a previous version? | no | -| Introduce features? | no | -| **Fix bugs?** | **yes** | -| Fix security vulnerabilities? | no | - -## <a name="bugs"></a>Bugs resolved - -* **_Import_: Contribution import fails on empty soft credit ([dev/core#4166](https://lab.civicrm.org/dev/core/-/issues/4166): [#25806](https://github.com/civicrm/civicrm-core/pull/25806))** -* **_Dedupe_: Employer name becomes stale after merging organizations (partial fix) ([dev/core#4156](https://lab.civicrm.org/dev/core/-/issues/4156): [#25778](https://github.com/civicrm/civicrm-core/pull/25778))** - -## <a name="credits"></a>Credits - -This release was developed by the following authors and reviewers: - -Wikimedia Foundation - Eileen McNaughton; lkuttner; Coop SymbioTIC - Mathieu Lutfy; -CiviCRM - Tim Otten; CiviCoop - Erik Hommel; Agileware - Justin Freeman - -## <a name="feedback"></a>Feedback - -These release notes are edited by Tim Otten and Andie Hunt. If you'd like to -provide feedback on them, please login to https://chat.civicrm.org/civicrm and -contact `@agh1`. diff --git a/civicrm/release-notes/5.59.4.md b/civicrm/release-notes/5.59.4.md deleted file mode 100644 index 59272f37d8..0000000000 --- a/civicrm/release-notes/5.59.4.md +++ /dev/null @@ -1,43 +0,0 @@ -# CiviCRM 5.59.4 - -Released March 27, 2023 - -- **[Synopsis](#synopsis)** -- **[Bugs resolved](#bugs)** -- **[Credits](#credits)** -- **[Feedback](#feedback)** - -## <a name="synopsis"></a>Synopsis - -| *Does this version...?* | | -| --------------------------------------------------------------- | -------- | -| Change the database schema? | no | -| Alter the API? | no | -| Require attention to configuration options? | no | -| Fix problems installing or upgrading to a previous version? | no | -| Introduce features? | no | -| **Fix bugs?** | **yes** | -| Fix security vulnerabilities? | no | - -## <a name="bugs"></a>Bugs resolved - -* **_CiviCase_: "Delete Case" leads to "Network Error" ([dev/core#4190](https://lab.civicrm.org/dev/core/-/issues/4190): [#25849](https://github.com/civicrm/civicrm-core/pull/25849))** -* **_CiviContribute_: Sorting by soft-credit name/date leads to AJAX error ([dev/core#4187](https://lab.civicrm.org/dev/core/-/issues/4187): [#25846](https://github.com/civicrm/civicrm-core/pull/25846))** -* **_CiviContribute_: Confirmation screen displays extraneous debit fields ([dev/core#4189](https://lab.civicrm.org/dev/core/-/issues/4189): [#25910](https://github.com/civicrm/civicrm-core/pull/25910))** -* **_CiviEvent_: Event created via API incorrectly marked as template ([dev/core#4205](https://lab.civicrm.org/dev/core/-/issues/4205): [#25932](https://github.com/civicrm/civicrm-core/pull/25932))** -* **_Dedupe/Merge_: Harden against possibility of inconsistent value for `is_view` ([dev/core#4197](https://lab.civicrm.org/dev/core/-/issues/4197): [#25912](https://github.com/civicrm/civicrm-core/pull/25912))** - -## <a name="credits"></a>Credits - -This release was developed by the following authors and reviewers: - -Wikimedia Foundation - Eileen McNaughton; Romy Ebert; MJW Consulting - Matthew Wire; -Lemniscus - Noah Miller; Korlon - Stuart Gaston; JMA Consulting - Seamus Lee; Coop -SymbioTIC - Mathieu Lutfy; composerjk; CiviCRM - Tim Otten; Black Brick Software - David -Hayes; Benjamin W; Andreas Howiller - -## <a name="feedback"></a>Feedback - -These release notes are edited by Tim Otten and Andie Hunt. If you'd like to -provide feedback on them, please login to https://chat.civicrm.org/civicrm and -contact `@agh1`. diff --git a/civicrm/release-notes/5.60.0.md b/civicrm/release-notes/5.60.0.md new file mode 100644 index 0000000000..cfb559d35c --- /dev/null +++ b/civicrm/release-notes/5.60.0.md @@ -0,0 +1,696 @@ +# CiviCRM 5.60.0 + +Released April 5, 2023 + +- **[Synopsis](#synopsis)** +- **[Features](#features)** +- **[Bugs resolved](#bugs)** +- **[Miscellany](#misc)** +- **[Credits](#credits)** +- **[Feedback](#feedback)** + +## <a name="synopsis"></a>Synopsis + +| *Does this version...?* | | +|:--------------------------------------------------------------- |:-------:| +| Fix security vulnerabilities? | no | +| **Change the database schema?** | **yes** | +| **Alter the API?** | **yes** | +| Require attention to configuration options? | no | +| **Fix problems installing or upgrading to a previous version?** | **yes** | +| **Introduce features?** | **yes** | +| **Fix bugs?** | **yes** | + +## <a name="features"></a>Features + +### CiviCRM Core + +- **Add Entity Reference custom field type (implementing EntityRef QuickForm + element type) + ([dev/core#3721](https://lab.civicrm.org/dev/core/-/issues/3721): + [25471](https://github.com/civicrm/civicrm-core/pull/25471))** + + Adds a new type of custom field "EntityReference" which creates an + autocomplete widget. + +- **Add 'SavePoint' to import to statusBounce back to + ([25602](https://github.com/civicrm/civicrm-core/pull/25602))** + + Adds a 'SavePoint' to import so that the user can be bounced back to the save + point if the import fails later down the road. + +- **SearchKit: Decide on available actions per display (funded) + ([dev/core#4118](https://lab.civicrm.org/dev/core/-/issues/4118): + [25521](https://github.com/civicrm/civicrm-core/pull/25521))** + + Allows the admin to limit the available choices of bulk actions (tasks) in a + Search Display. + +- **Make dedupe exceptions searchable in SearchKit + ([25522](https://github.com/civicrm/civicrm-core/pull/25522))** + + Makes dedupe exceptions searchable in SearchKit. + +- **Filter Searches by 'is_current' / expires_date (Work Towards + [dev/core#4117](https://lab.civicrm.org/dev/core/-/issues/4117): + [25516](https://github.com/civicrm/civicrm-core/pull/25516))** + + Adds `is_current` filter to searches. + +- **Log Smarty debug to it's own channel + ([25682](https://github.com/civicrm/civicrm-core/pull/25682))** + + Makes it so output from smarty secure mode goes into it's own file. + +- **Allow OAuth redirect URI to be overridden in client or provider config + ([25445](https://github.com/civicrm/civicrm-core/pull/25445))** + + Makes the oauth-client extension respect whatever Redirect URI is set in the + "client" or "provider" configuration. + +- **Make `activity_type_id` available to `links` hook, test + ([25565](https://github.com/civicrm/civicrm-core/pull/25565))** + + Improves hook_civicrm_links by making activity_type_id available (in relevant + contexts). + +- **Add setting to disable Smarty in Scheduled reminders + ([dev/core#4100](https://lab.civicrm.org/dev/core/-/issues/4100): + [25444](https://github.com/civicrm/civicrm-core/pull/25444))** + + Adds a setting to disable Smarty in Scheduled reminders. + +### CiviCase + +- **Afform: Allow selecting case for relationship + ([25618](https://github.com/civicrm/civicrm-core/pull/25618))** + + Makes it so one can select a case for a relationship on Afforms. + +### CiviContribute + +- **Add filter on pledge payment in contribution report templates + ([dev/core#4106](https://lab.civicrm.org/dev/core/-/issues/4106): + [25629](https://github.com/civicrm/civicrm-core/pull/25629))** + + Adds a pledge payment filter to the Contribution Detail and Summary reports. + +- **PaymentProcessor - Use ajax refresh + ([25512](https://github.com/civicrm/civicrm-core/pull/25512))** + + Makes page refresh a bit nicer when changing payment processor types on the + admin form. + +### CiviMail + +- **HTML definition for subscription history date + ([25655](https://github.com/civicrm/civicrm-core/pull/25655))** + + Adds an HTML type to the "Group Membership Action Date" field so it can be + used in FormBuilder as a filter. + +### Drupal Integration + +- **Epic: Drupal 10 readiness (Work Towards + [dev/drupal#176](https://lab.civicrm.org/dev/drupal/-/issues/176): + [25499](https://github.com/civicrm/civicrm-core/pull/25499) and + [25054](https://github.com/civicrm/civicrm-core/pull/25054))** + + Work towards drupal 10 readiness by allowing symfony 6. + +- **CMS Database Integration - Per-table prefixes are no longer supported + ([dev/core#4028](https://lab.civicrm.org/dev/core/-/issues/4028): + [25328](https://github.com/civicrm/civicrm-core/pull/25328))** + + Makes the CRM_Admin_Form_Setting_UF more CMS agnostic by removing the Drupal + 7 mapping table. + +## <a name="bugs"></a>Bugs resolved + +### Core CiviCRM + +- **Make 5.60 upgrade rerunnable + ([25950](https://github.com/civicrm/civicrm-core/pull/25950))** + +- **Import search authorization issues + ([dev/core#4184](https://lab.civicrm.org/dev/core/-/issues/4184): + [25810](https://github.com/civicrm/civicrm-core/pull/25810))** + +- **Individual's Employer and Membership by Relationship Are Not Updated After + Merging Their Organization + ([dev/core#4156](https://lab.civicrm.org/dev/core/-/issues/4156): + [25778](https://github.com/civicrm/civicrm-core/pull/25778))** + +- **Fatal error on merge + ([dev/core#4197](https://lab.civicrm.org/dev/core/-/issues/4197): + [25912](https://github.com/civicrm/civicrm-core/pull/25912))** + +- **Finish making legacycustomsearches optional (Work Towards + [dev/core#4112](https://lab.civicrm.org/dev/core/-/issues/4112): + [25392](https://github.com/civicrm/civicrm-core/pull/25392))** + + Privatize `prevNextCache` functions. + +- **Administrator > Communications > Schedule Reminders error when CiviEvent + disabled ([dev/core#4145](https://lab.civicrm.org/dev/core/-/issues/4145): + [25703](https://github.com/civicrm/civicrm-core/pull/25703))** + +- **Upgrade Smarty + (Work Towards [dev/core#4146](https://lab.civicrm.org/dev/core/-/issues/4146): + [25669](https://github.com/civicrm/civicrm-core/pull/25669))** + + Removes (old) Smarty-forward incompatible syntax from Address.tpl. + +- **When using PHP 8.1, the Contact token for the Address State / Province field + returns no value when used in Message Templates. Works fine on PHP 7.4 + ([dev/core#4147](https://lab.civicrm.org/dev/core/-/issues/4147): + [25704](https://github.com/civicrm/civicrm-core/pull/25704))** + +- **Fix for 5.59 upgrade on multilingual + ([25733](https://github.com/civicrm/civicrm-core/pull/25733))** + +- **Load submitted `fieldSeparator` on back on `Import Datasource` screen + ([25758](https://github.com/civicrm/civicrm-core/pull/25758))** + +- **API4: Allow save() to match on null values + ([24971](https://github.com/civicrm/civicrm-core/pull/24971))** + +- **API v4 explorer: boolean params don't render correctly for CV (short) + ([dev/core#4129](https://lab.civicrm.org/dev/core/-/issues/4129): + [25589](https://github.com/civicrm/civicrm-core/pull/25589))** + +- **Stricter typing in Apiv4 + ([25706](https://github.com/civicrm/civicrm-core/pull/25706))** + +- **Afform - Fix validateBySavedSearch + ([25822](https://github.com/civicrm/civicrm-core/pull/25822))** + +- **Afform: Fix broken syntax for saving reciprocal relationships + ([25620](https://github.com/civicrm/civicrm-core/pull/25620))** + +- **Afform - Fix editing search filters nested within multiple containers + ([25742](https://github.com/civicrm/civicrm-core/pull/25742))** + +- **Form Builder - autocomplete input does not use configured filtering + ([dev/core#4138](https://lab.civicrm.org/dev/core/-/issues/4138): + [25646](https://github.com/civicrm/civicrm-core/pull/25646))** + +- **Filter expired searches from search kit results + ([25568](https://github.com/civicrm/civicrm-core/pull/25568))** + +- **SearchKit - Fix handling of new Custom EntityReference fields + ([25927](https://github.com/civicrm/civicrm-core/pull/25927))** + +- **SearchKit - Clarify how to view SQL output + ([25671](https://github.com/civicrm/civicrm-core/pull/25671))** + +- **Always show "add more buttons" dropdown in searchkit view + ([25596](https://github.com/civicrm/civicrm-core/pull/25596))** + +- **Make job ID accessible to searchkit for joblog + ([24746](https://github.com/civicrm/civicrm-core/pull/24746))** + +- **Add Activity Target consistently + ([dev/core#4142](https://lab.civicrm.org/dev/core/-/issues/4142): + [25650](https://github.com/civicrm/civicrm-core/pull/25650))** + +- **Allow (some) permissions with colons + ([23782](https://github.com/civicrm/civicrm-core/pull/23782))** + +- **Update Smarty addTemplateDir function signature to future smarty + ([25248](https://github.com/civicrm/civicrm-core/pull/25248))** + +- **Add `crmUrl function` to smarty in the standard way + ([25661](https://github.com/civicrm/civicrm-core/pull/25661))** + +- **Reduce unneeded DNS queries during OAuth flow + ([25446](https://github.com/civicrm/civicrm-core/pull/25446))** + +- **Angular Coder: Fix unescaping of quotes breaking attributes + ([25630](https://github.com/civicrm/civicrm-core/pull/25630))** + +- **EntityRef - Format custom field display value on QuickForms + ([25632](https://github.com/civicrm/civicrm-core/pull/25632))** + +- **getStatus() should be returning a string + ([25441](https://github.com/civicrm/civicrm-core/pull/25441))** + +- **Regression: Fix DB syntax error on Parse address scheduled job + ([25616](https://github.com/civicrm/civicrm-core/pull/25616))** + +- **update entity mapping logic for profile fields to include contact subtypes + ([25570](https://github.com/civicrm/civicrm-core/pull/25570))** + +- **Smarty {ts} - For extensions, use fallback similar to E::ts() and JS ts() + ([25383](https://github.com/civicrm/civicrm-core/pull/25383))** + +- **Disambiguate `Address.state_province_id:abbr` (PHP asort) + ([25552](https://github.com/civicrm/civicrm-core/pull/25552) and + [25550](https://github.com/civicrm/civicrm-core/pull/25550))** + +- **Default to supporting partial locales + ([25063](https://github.com/civicrm/civicrm-core/pull/25063))** + +- **Do not use reference for Object parameter, death to `_NULLObject` + ([25541](https://github.com/civicrm/civicrm-core/pull/25541))** + +- **only load dedupe rules for the chosen entity + ([25515](https://github.com/civicrm/civicrm-core/pull/25515))** + +- **A couple of minor smarty notice fixes + ([25514](https://github.com/civicrm/civicrm-core/pull/25514))** + +- **Use mysql DATABASE() function instead of php code + ([25530](https://github.com/civicrm/civicrm-core/pull/25530))** + +- **Use `DATABASE()` function rather than lossa code + ([25528](https://github.com/civicrm/civicrm-core/pull/25528))** + +- **Fix more schema checks to use mysql DATABASE() function, deprecate php + function ([25593](https://github.com/civicrm/civicrm-core/pull/25593))** + +- **Fix a couple more places to use mysql DATABASE() function + ([25537](https://github.com/civicrm/civicrm-core/pull/25537))** + +- **Fix Scheduled reminders form to use tokenProcessor to get token list + ([25052](https://github.com/civicrm/civicrm-core/pull/25052))** + +- **fix the id help instead use class help + ([25487](https://github.com/civicrm/civicrm-core/pull/25487))** + +- **Fix user profile file fields not saving. + ([80](https://github.com/civicrm/civicrm-drupal-8/pull/80))** + +- **Fix fatal error on upgrade success screen + ([25554](https://github.com/civicrm/civicrm-core/pull/25554))** + +- **Typo executequery => executeQuery + ([25539](https://github.com/civicrm/civicrm-core/pull/25539))** + +- **Smarty - Fix warnings about 'mb_truncate' modifier + ([25651](https://github.com/civicrm/civicrm-core/pull/25651))** + +- **Smarty - {htxt} blocks should not be evaluated unless needed + ([25653](https://github.com/civicrm/civicrm-core/pull/25653))** + +- **Smarty notice fix + ([25544](https://github.com/civicrm/civicrm-core/pull/25544))** + +- **E-notice fix Ical display + ([25612](https://github.com/civicrm/civicrm-core/pull/25612))** + +- **Fix e-notice pattern around location not defined in formButtons.tpl + ([25668](https://github.com/civicrm/civicrm-core/pull/25668))** + +- **Fix Contact import e-notice on preview screen + ([25302](https://github.com/civicrm/civicrm-core/pull/25302))** + +- **Fix mixin to use `addTemplateDir` + ([25667](https://github.com/civicrm/civicrm-core/pull/25667))** + +- **Fix add version for civicrm_custom_field.fk_entity + ([25642](https://github.com/civicrm/civicrm-core/pull/25642))** + +- **Fix handling of invalid sql query during import + ([25600](https://github.com/civicrm/civicrm-core/pull/25600))** + +- **Enotice fix, pledge block on UserDashboard + ([25546](https://github.com/civicrm/civicrm-core/pull/25546))** + +- **Notice fix on preferred_language, when null + ([25656](https://github.com/civicrm/civicrm-core/pull/25656))** + +### CiviCase + +- **PHP8: Delete Case link causes fatal error + ([dev/core#4190](https://lab.civicrm.org/dev/core/-/issues/4190): + [25849](https://github.com/civicrm/civicrm-core/pull/25849))** + +- **CiviCase Dashboard exports all records instead of the results + ([dev/core#4126](https://lab.civicrm.org/dev/core/-/issues/4126): + [25649](https://github.com/civicrm/civicrm-core/pull/25649))** + +### CiviContribute + +- **Around 5.49 pan_truncation and card_type_id (containing card type VISA/MC + and last 4 digits last four digits stopped getting recorded + ([dev/core#4029](https://lab.civicrm.org/dev/core/-/issues/4029): + [25963](https://github.com/civicrm/civicrm-core/pull/25963))** + +- **Contribution Confirm incorrectly debit card information even if using + credit card ([dev/core#4189](https://lab.civicrm.org/dev/core/-/issues/4189): + [25910](https://github.com/civicrm/civicrm-core/pull/25910))** + +- **Import contribution fails if using soft-credit and a row has an empty field + ([dev/core#4166](https://lab.civicrm.org/dev/core/-/issues/4166): + [25806](https://github.com/civicrm/civicrm-core/pull/25806))** + +- **Fix empty values of Note on Import contribution + ([25569](https://github.com/civicrm/civicrm-core/pull/25569))** + +- **Fix for issue when optional contact_id is blank importing contributions + ([25897](https://github.com/civicrm/civicrm-core/pull/25897))** + +- **New PaypalPro Recurring Payments (PPRP) creating duplicate contributions + and inaccurate status + ([dev/core#4158](https://lab.civicrm.org/dev/core/-/issues/4158): + [25775](https://github.com/civicrm/civicrm-core/pull/25775))** + +- **PayPal Prp IPN - Fix incorrect option_group update + ([25724](https://github.com/civicrm/civicrm-core/pull/25724))** + +- **CiviContribute - Fix warning about 'suppressedEmails' when generating PDF + ([25576](https://github.com/civicrm/civicrm-core/pull/25576))** + +- **Contribution pages crash for logged-in users when CiviMember is disabled + ([25729](https://github.com/civicrm/civicrm-core/pull/25729))** + +- **Enotice fix on userDashboard with contributions, replace deprecated + functions with api4v calls + ([24861](https://github.com/civicrm/civicrm-core/pull/24861))** + +- **Smarty notice fix on bank_account_number + ([25680](https://github.com/civicrm/civicrm-core/pull/25680))** + +- **AJAX error when sorting soft credit by name or date + ([dev/core#4187](https://lab.civicrm.org/dev/core/-/issues/4187): + [25846](https://github.com/civicrm/civicrm-core/pull/25846))** + +### CiviEvent + +- **Can't create new events from a template using the API + ([dev/core#4205](https://lab.civicrm.org/dev/core/-/issues/4205): + [25932](https://github.com/civicrm/civicrm-core/pull/25932))** + +### CiviMail + +- **Mailing Summary Report: support pseudofields + ([25560](https://github.com/civicrm/civicrm-core/pull/25560))** + +- **FlexMailer: Default Return Path not respected + ([dev/core#4070](https://lab.civicrm.org/dev/core/-/issues/4070): + [25309](https://github.com/civicrm/civicrm-core/pull/25309))** + +### Drupal Integration + +- **is_drupal: move functionality that calls this deprecated variable to System + classes ([dev/core#4127](https://lab.civicrm.org/dev/core/-/issues/4127): + [25585](https://github.com/civicrm/civicrm-core/pull/25585), + [25571](https://github.com/civicrm/civicrm-core/pull/25571), + [25587](https://github.com/civicrm/civicrm-core/pull/25587), + [25573](https://github.com/civicrm/civicrm-core/pull/25573), + [25586](https://github.com/civicrm/civicrm-core/pull/25586) and + [25572](https://github.com/civicrm/civicrm-core/pull/25572))** + +### WordPress Integration + +- **distmaker - Fix export of WordPress patches + ([25599](https://github.com/civicrm/civicrm-core/pull/25599))** + +## <a name="misc"></a>Miscellany + +- **Simplify steps of loading SimpleCacheTest from cache/integration-tests + ([25942](https://github.com/civicrm/civicrm-core/pull/25942))** + +- **composer require --dev yoast/phpunit-polyfills + ([25631](https://github.com/civicrm/civicrm-core/pull/25631))** + +- **Move form specific code to the form + ([25457](https://github.com/civicrm/civicrm-core/pull/25457))** + +- **Make private function private + ([25604](https://github.com/civicrm/civicrm-core/pull/25604))** + +- **Make unshared `getTree` function private, remove never passed params + ([25517](https://github.com/civicrm/civicrm-core/pull/25517))** + +- **APIv4 - Limited support for casting + ([25595](https://github.com/civicrm/civicrm-core/pull/25595))** + +- **Split up CRM_Utils_System_Base::theme + ([dev/core#4076](https://lab.civicrm.org/dev/core/-/issues/4076): + [25329](https://github.com/civicrm/civicrm-core/pull/25329))** + +- **Preliminary cleanup, comments, type hints + ([25564](https://github.com/civicrm/civicrm-core/pull/25564))** + +- **run `civix update` on `recaptcha`, `legacyCustomSearches`, `financialacls` + ([25663](https://github.com/civicrm/civicrm-core/pull/25663))** + +- **ext - General update to civix v23.02.0 + ([25659](https://github.com/civicrm/civicrm-core/pull/25659))** + +- **CiviCRM Stable Version bump + ([291](https://github.com/civicrm/civicrm-wordpress/pull/291))** + +- **Post divide code tidy up + ([25195](https://github.com/civicrm/civicrm-core/pull/25195))** + +- **Add gentle deprecation to `debug_log_message` + ([25683](https://github.com/civicrm/civicrm-core/pull/25683))** + +- **Stop loading unused `relatedObjects` + ([25617](https://github.com/civicrm/civicrm-core/pull/25617))** + +- **Bump dompdf/dompdf from 2.0.2 to 2.0.3 + ([25520](https://github.com/civicrm/civicrm-core/pull/25520))** + +- **Add noisy deprecation to `replaceHookTokens` + ([25510](https://github.com/civicrm/civicrm-core/pull/25510))** + +- **Deprecate unused, exception class with non-standard name-spacing + ([25641](https://github.com/civicrm/civicrm-core/pull/25641))** + +- **Fully deprecate `CRM_Utils_Token::getMembershipTokenDetails`, + `CRM_Utils_Token::replaceEntityTokens` + ([25507](https://github.com/civicrm/civicrm-core/pull/25507))** + +- **Extra deprecation for clarity on token function + `convertPseudoConstantsUsingMetadata` + ([25511](https://github.com/civicrm/civicrm-core/pull/25511))** + +- **Pull over a few more deprecations + blockDelete deprecation + ([25695](https://github.com/civicrm/civicrm-core/pull/25695))** + +- **Address portions of deprecated code replacement + ([25693](https://github.com/civicrm/civicrm-core/pull/25693))** + +- **Deprecate unused `CRM_Core_BAO_UFField::copy()` function + ([25594](https://github.com/civicrm/civicrm-core/pull/25594))** + +- **Deprecations for Mailing::delete functions + ([25691](https://github.com/civicrm/civicrm-core/pull/25691))** + +- **Deprecations for delete on ACL entities + ([25690](https://github.com/civicrm/civicrm-core/pull/25690))** + +- **Fully deprecate legacy contributionTokens + ([25505](https://github.com/civicrm/civicrm-core/pull/25505))** + +- **Fully deprecate `CRM_Core_SelectValues::eventTokens()` + ([25509](https://github.com/civicrm/civicrm-core/pull/25509))** + +- **Fully deprecate `CRM_Core_SelectValues::membershipTokens()` + ([25506](https://github.com/civicrm/civicrm-core/pull/25506))** + +- **Add noisy deprecation to deprecated function, after universe search + ([25662](https://github.com/civicrm/civicrm-core/pull/25662))** + +- **Remove legacy handling of locks for discontinued mysql/mariaDB versions + ([25654](https://github.com/civicrm/civicrm-core/pull/25654))** + +- **Remove forward incompatible syntax from template + ([25664](https://github.com/civicrm/civicrm-core/pull/25664))** + +- **Remove conditional assignment around `is_deductible` + ([25237](https://github.com/civicrm/civicrm-core/pull/25237))** + +- **Remove unnecessary pass-by-reference + ([25678](https://github.com/civicrm/civicrm-core/pull/25678))** + +- **Remove empty on location - it should always be set now + ([25675](https://github.com/civicrm/civicrm-core/pull/25675))** + +- **Remove always-NULL `$singleRecord` variable + ([25519](https://github.com/civicrm/civicrm-core/pull/25519))** + +- **Remove 2020-deprecated handling of `legacyAddressCreate` + ([25686](https://github.com/civicrm/civicrm-core/pull/25686))** + +- **Remove code deprecated in 2018 + ([25679](https://github.com/civicrm/civicrm-core/pull/25679))** + +- **Remove function noisily deprecated when the world was young (2020) + ([25685](https://github.com/civicrm/civicrm-core/pull/25685))** + +- **Remove deprecated function call + ([25684](https://github.com/civicrm/civicrm-core/pull/25684))** + +- **Remove deprecated functions from tests + ([25688](https://github.com/civicrm/civicrm-core/pull/25688))** + +- **Remove deprecated function calls to Event::del, Membership functions del, + OptionValue ([25705](https://github.com/civicrm/civicrm-core/pull/25705))** + +- **Remove function deprecated a year ago + ([25615](https://github.com/civicrm/civicrm-core/pull/25615))** + +- **Remove deprecated use of $ids + ([25698](https://github.com/civicrm/civicrm-core/pull/25698))** + +- **Delete long-deprecated functions + ([25696](https://github.com/civicrm/civicrm-core/pull/25696))** + +- **Remove the correct extraneous field separator field + ([25753](https://github.com/civicrm/civicrm-core/pull/25753))** + +- **Remove never-true IF + ([25518](https://github.com/civicrm/civicrm-core/pull/25518))** + +- **Remove unused constants left over from import cleanup + ([25601](https://github.com/civicrm/civicrm-core/pull/25601))** + +- **Remove interaction with complex legacy `getTree` function + ([25395](https://github.com/civicrm/civicrm-core/pull/25395))** + +- **Remove empty function + ([25592](https://github.com/civicrm/civicrm-core/pull/25592))** + +- **Remove unused variable + ([25508](https://github.com/civicrm/civicrm-core/pull/25508))** + +- **Remove unused variables + ([25670](https://github.com/civicrm/civicrm-core/pull/25670))** + +- **Remove unused property - not used since import code refactor `_lineCount` + ([25466](https://github.com/civicrm/civicrm-core/pull/25466))** + +- **(REF) Tidy up unused params in api_v3_ContributionSoftTest + ([25322](https://github.com/civicrm/civicrm-core/pull/25322))** + +- **[REF] Fix undefined variable notice in WordPress tests + ([25591](https://github.com/civicrm/civicrm-core/pull/25591))** + +- **(REF) Remove test reference to property which no longer exists + ([25624](https://github.com/civicrm/civicrm-core/pull/25624))** + +- **(REF) Remove unused setup from AdhocMailingTest + ([25500](https://github.com/civicrm/civicrm-core/pull/25500))** + +- **[REF] Add support for composer installers v2 which seems to be needed for + d10 ([79](https://github.com/civicrm/civicrm-drupal-8/pull/79))** + +- **Php8.x compatibility - do not try to count NULL + ([25652](https://github.com/civicrm/civicrm-core/pull/25652))** + +- **[REF][PHP8.2] Remove use of dynamic properties in + CRM_Contact_Form_Task_EmailTest + ([25562](https://github.com/civicrm/civicrm-core/pull/25562))** + +- **[REF][PHP8.2] Get rid of dynamic properties in + CRM_Core_Payment_AuthorizeNetTest + ([25561](https://github.com/civicrm/civicrm-core/pull/25561))** + +- **[REF][PHP8.2] Stop use of dynamic property in AdditionalPaymentTest + ([25559](https://github.com/civicrm/civicrm-core/pull/25559))** + +- **[REF][PHP8.2] Use variable instead of dynmaic property + (CRM_Group_Page_AjaxTest) + ([25558](https://github.com/civicrm/civicrm-core/pull/25558))** + +- **[REF][PHP8.2] Declare property in CRM_Pledge_BAO_PledgeBlockTest + ([25557](https://github.com/civicrm/civicrm-core/pull/25557))** + +- **[REF][PHP8.2] Declare property in CRM_Utils_FakeObject + ([25556](https://github.com/civicrm/civicrm-core/pull/25556))** + +- **[REF][PHP8.2] Refactor properties on CRM_Event_Form_SearchTest + ([25501](https://github.com/civicrm/civicrm-core/pull/25501))** + +- **[REF][PHP8.2] Declare dynamic property in two SMS tests + ([25502](https://github.com/civicrm/civicrm-core/pull/25502))** + +- **[REF][PHP8.2] Remove unnecessary dynamic property + ([25622](https://github.com/civicrm/civicrm-core/pull/25622))** + +- **[REF][PHP8.2] Fix use of self in callables deprecation + ([25625](https://github.com/civicrm/civicrm-core/pull/25625))** + +- **[REF][PHP8.2] Tidy up properties on api_v3_GroupContactTest + ([25626](https://github.com/civicrm/civicrm-core/pull/25626))** + +- **[REF][PHP8.2] Tidy up properties in CRM_Event_BAO_EventPermissionsTest + ([25623](https://github.com/civicrm/civicrm-core/pull/25623))** + +- **update CiviCrmTestBase setup() method declaration to match BrowserTestBase + ([78](https://github.com/civicrm/civicrm-drupal-8/pull/78))** + +- **(NFC) crmURL - Add examples and whitespace. Crosslink docs. + ([25665](https://github.com/civicrm/civicrm-core/pull/25665))** + +- **[NFC] php8.2 support in test class `ActivitySearchTest` + ([25607](https://github.com/civicrm/civicrm-core/pull/25607))** + +- **NFC cleanup in test class + ([25524](https://github.com/civicrm/civicrm-core/pull/25524))** + +- **(NFC) Version Check Test - Fix multi-user and concurrent execution + [25909](https://github.com/civicrm/civicrm-core/pull/25909)** + +- **[NFC] doc block fix + ([25610](https://github.com/civicrm/civicrm-core/pull/25610))** + +- **Fix test to test the thing it was written to test + ([25608](https://github.com/civicrm/civicrm-core/pull/25608))** + +- **Event test cleanup, fix test to use submitted form values, rather than + require a lot of contorting + ([25621](https://github.com/civicrm/civicrm-core/pull/25621))** + +- **Remove invalid 'world_region' => 'India' from test + ([25540](https://github.com/civicrm/civicrm-core/pull/25540))** + +- **Php8.2 test fix, remove one instance of undeclared property + ([25619](https://github.com/civicrm/civicrm-core/pull/25619))** + +- **Extend testing for ContributionConfirm & consolidate + `isSeparateMembershipPayment` + ([25270](https://github.com/civicrm/civicrm-core/pull/25270))** + +- **Upgrade test to use more recent methodology for testing forms + ([25551](https://github.com/civicrm/civicrm-core/pull/25551))** + +- **Add extra test, comment how it could be used to fix bug + ([25503](https://github.com/civicrm/civicrm-core/pull/25503))** + +- **Reduce processing load in test `assertAPIFailure` + ([25648](https://github.com/civicrm/civicrm-core/pull/25648))** + +## <a name="credits"></a>Credits + +This release was developed by the following code authors: + +AGH Strategies - Alice Frumin, Andie Hunt; BrightMinded Ltd - Bradley Taylor; +CiviCRM - Coleman Watts, Tim Otten; CiviDesk - Yashodha Chaku; Coop SymbioTIC - +Mathieu Lutfy; Dave D; ES-Progress - Sandor Semsey; Freeform Solutions - Herb +van den Dool; Fuzion - Jitendra Purohit; Giant Rabbit - Anthony Nemirovsky; +iXiam - Luciano Spiegel; JMA Consulting - Seamus Lee; Lemniscus - Noah Miller; +Megaphone Technology Consulting - Jon Goldberg; MJW Consulting - Matthew Wire; +PERORA SRL - Samuele Masetto; Progressive Technology Project - Jamie McClelland; +Skvare - Mark Hanna; Tadpole Collective - Kevin Cristiano; Third Sector +Design - Kurund Jalmi, Michael McAndrew; Wikimedia Foundation - Eileen +McNaughton + +Most authors also reviewed code for this release; in addition, the following +reviewers contributed their comments: + +Agileware - Francis Whittle, Justin Freeman; Andreas Howiller; Becca Tregenna; +Blackfly Solutions - Alan Dixon; Fuzion - Luke Stewart; Jens Schuppe; +JMA Consulting - Joe Murray; Megaphone Technology Consulting - Brienne Kordis; +Squiffle Consulting - Aidan Saunders; Stephen Palmstrom + +## <a name="feedback"></a>Feedback + +These release notes are edited by Alice Frumin and Andie Hunt. If you'd like +to provide feedback on them, please log in to https://chat.civicrm.org/civicrm +and contact `@agh1`. diff --git a/civicrm/settings/Localization.setting.php b/civicrm/settings/Localization.setting.php index 19e0be3164..c18312366a 100644 --- a/civicrm/settings/Localization.setting.php +++ b/civicrm/settings/Localization.setting.php @@ -415,7 +415,7 @@ return [ 'name' => 'partial_locales', 'type' => 'Boolean', 'quick_form_type' => 'YesNo', - 'default' => '0', + 'default' => '1', 'add' => '5.54', 'title' => ts('Partial Locales'), 'is_domain' => 1, diff --git a/civicrm/settings/Mailing.setting.php b/civicrm/settings/Mailing.setting.php index 97904cad54..434e78a7ee 100644 --- a/civicrm/settings/Mailing.setting.php +++ b/civicrm/settings/Mailing.setting.php @@ -393,4 +393,18 @@ return [ 'description' => ts('The frequency that CiviMail updates its sent mail database.'), 'help_text' => NULL, ], + 'scheduled_reminder_smarty' => [ + 'group_name' => 'Mailing Preferences', + 'group' => 'mailing', + 'name' => 'scheduled_reminder_smarty', + 'type' => 'Boolean', + 'html_type' => 'checkbox', + 'default' => 0, + 'title' => ts('Use Smarty in scheduled reminders'), + 'add' => '5.60', + 'is_domain' => 1, + 'is_contact' => 0, + 'description' => ts('Controls whether scheduled reminders will attempt to process smarty tokens.'), + 'help_text' => NULL, + ], ]; diff --git a/civicrm/sql/civicrm.mysql b/civicrm/sql/civicrm.mysql index eacd6acbbf..f0efa3f59e 100644 --- a/civicrm/sql/civicrm.mysql +++ b/civicrm/sql/civicrm.mysql @@ -1476,6 +1476,7 @@ CREATE TABLE `civicrm_custom_field` ( `serialize` int unsigned NOT NULL DEFAULT 0 COMMENT 'Serialization method - a non-zero value indicates a multi-valued field.', `filter` varchar(255) COMMENT 'Stores Contact Get API params contact reference custom fields. May be used for other filters in the future.', `in_selector` tinyint NOT NULL DEFAULT 0 COMMENT 'Should the multi-record custom field values be displayed in tab table listing', + `fk_entity` varchar(255) DEFAULT NULL COMMENT 'Name of entity being referenced.', PRIMARY KEY (`id`), UNIQUE INDEX `UI_label_custom_group_id`(label, custom_group_id), UNIQUE INDEX `UI_name_custom_group_id`(name, custom_group_id), @@ -1614,13 +1615,14 @@ CREATE TABLE `civicrm_job_log` ( `id` int unsigned NOT NULL AUTO_INCREMENT COMMENT 'Job log entry ID', `domain_id` int unsigned NOT NULL COMMENT 'Which Domain is this scheduled job for', `run_time` timestamp COMMENT 'Log entry date', - `job_id` int unsigned COMMENT 'Pointer to job id - not a FK though, just for logging purposes', + `job_id` int unsigned COMMENT 'Pointer to job id', `name` varchar(255) COMMENT 'Title of the job', `command` varchar(255) COMMENT 'Full path to file containing job script', `description` varchar(255) COMMENT 'Title line of log entry', `data` longtext COMMENT 'Potential extended data for specific job run (e.g. tracebacks).', PRIMARY KEY (`id`), - CONSTRAINT FK_civicrm_job_log_domain_id FOREIGN KEY (`domain_id`) REFERENCES `civicrm_domain`(`id`) + CONSTRAINT FK_civicrm_job_log_domain_id FOREIGN KEY (`domain_id`) REFERENCES `civicrm_domain`(`id`), + CONSTRAINT FK_civicrm_job_log_job_id FOREIGN KEY (`job_id`) REFERENCES `civicrm_job`(`id`) ON DELETE SET NULL ) ENGINE=InnoDB DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci ROW_FORMAT=DYNAMIC; diff --git a/civicrm/sql/civicrm_data.mysql b/civicrm/sql/civicrm_data.mysql index ee8acfbe9f..e095141abd 100644 --- a/civicrm/sql/civicrm_data.mysql +++ b/civicrm/sql/civicrm_data.mysql @@ -8119,7 +8119,7 @@ INSERT INTO civicrm_msg_template {$contact_phone} {/if} {/if} -{if !empty($is_deductible) AND !empty($price)} +{if $is_deductible AND !empty($price)} {ts 1=$price|crmMoney:$currency}The value of this premium is %1. This may affect the amount of the tax deduction you can claim. Consult your tax advisor for more information.{/ts}{/if} {/if} @@ -8541,7 +8541,7 @@ INSERT INTO civicrm_msg_template </td> </tr> {/if} - {if !empty($is_deductible) AND !empty($price)} + {if $is_deductible AND !empty($price)} <tr> <td colspan="2" {$valueStyle}> <p>{ts 1=$price|crmMoney:$currency}The value of this premium is %1. This may affect the amount of the tax deduction you can claim. Consult your tax advisor for more information.{/ts}</p> @@ -8774,7 +8774,7 @@ INSERT INTO civicrm_msg_template {$contact_phone} {/if} {/if} -{if !empty($is_deductible) AND !empty($price)} +{if $is_deductible AND !empty($price)} {ts 1=$price|crmMoney:$currency}The value of this premium is %1. This may affect the amount of the tax deduction you can claim. Consult your tax advisor for more information.{/ts}{/if} {/if} @@ -9196,7 +9196,7 @@ INSERT INTO civicrm_msg_template </td> </tr> {/if} - {if !empty($is_deductible) AND !empty($price)} + {if $is_deductible AND !empty($price)} <tr> <td colspan="2" {$valueStyle}> <p>{ts 1=$price|crmMoney:$currency}The value of this premium is %1. This may affect the amount of the tax deduction you can claim. Consult your tax advisor for more information.{/ts}</p> @@ -18847,7 +18847,7 @@ or want to inquire about reinstating your registration for this event.{/ts}</p> {$contact_phone} {/if} {/if} -{if !empty($is_deductible) AND !empty($price)} +{if $is_deductible AND !empty($price)} {ts 1=$price|crmMoney}The value of this premium is %1. This may affect the amount of the tax deduction you can claim. Consult your tax advisor for more information.{/ts}{/if} {/if} @@ -19374,7 +19374,7 @@ or want to inquire about reinstating your registration for this event.{/ts}</p> </td> </tr> {/if} - {if !empty($is_deductible) AND !empty($price)} + {if $is_deductible AND !empty($price)} <tr> <td colspan="2" {$valueStyle}> <p>{ts 1=$price|crmMoney}The value of this premium is %1. This may affect the amount of the tax deduction you can claim. Consult your tax advisor for more information.{/ts}</p> @@ -19641,7 +19641,7 @@ or want to inquire about reinstating your registration for this event.{/ts}</p> {$contact_phone} {/if} {/if} -{if !empty($is_deductible) AND !empty($price)} +{if $is_deductible AND !empty($price)} {ts 1=$price|crmMoney}The value of this premium is %1. This may affect the amount of the tax deduction you can claim. Consult your tax advisor for more information.{/ts}{/if} {/if} @@ -20168,7 +20168,7 @@ or want to inquire about reinstating your registration for this event.{/ts}</p> </td> </tr> {/if} - {if !empty($is_deductible) AND !empty($price)} + {if $is_deductible AND !empty($price)} <tr> <td colspan="2" {$valueStyle}> <p>{ts 1=$price|crmMoney}The value of this premium is %1. This may affect the amount of the tax deduction you can claim. Consult your tax advisor for more information.{/ts}</p> @@ -23678,4 +23678,4 @@ INSERT INTO `civicrm_report_instance` ( `domain_id`, `title`, `report_id`, `description`, `permission`, `form_values`) VALUES ( @domainID, 'Survey Details', 'survey/detail', 'Detailed report for canvassing, phone-banking, walk lists or other surveys.', 'access CiviReport', 'a:39:{s:6:"fields";a:2:{s:9:"sort_name";s:1:"1";s:6:"result";s:1:"1";}s:22:"assignee_contact_id_op";s:2:"eq";s:25:"assignee_contact_id_value";s:0:"";s:12:"sort_name_op";s:3:"has";s:15:"sort_name_value";s:0:"";s:17:"street_number_min";s:0:"";s:17:"street_number_max";s:0:"";s:16:"street_number_op";s:3:"lte";s:19:"street_number_value";s:0:"";s:14:"street_name_op";s:3:"has";s:17:"street_name_value";s:0:"";s:15:"postal_code_min";s:0:"";s:15:"postal_code_max";s:0:"";s:14:"postal_code_op";s:3:"lte";s:17:"postal_code_value";s:0:"";s:7:"city_op";s:3:"has";s:10:"city_value";s:0:"";s:20:"state_province_id_op";s:2:"in";s:23:"state_province_id_value";a:0:{}s:13:"country_id_op";s:2:"in";s:16:"country_id_value";a:0:{}s:12:"survey_id_op";s:2:"in";s:15:"survey_id_value";a:0:{}s:12:"status_id_op";s:2:"eq";s:15:"status_id_value";s:1:"1";s:11:"custom_1_op";s:2:"in";s:14:"custom_1_value";a:0:{}s:11:"custom_2_op";s:2:"in";s:14:"custom_2_value";a:0:{}s:17:"custom_3_relative";s:1:"0";s:13:"custom_3_from";s:0:"";s:11:"custom_3_to";s:0:"";s:11:"description";s:75:"Detailed report for canvassing, phone-banking, walk lists or other surveys.";s:13:"email_subject";s:0:"";s:8:"email_to";s:0:"";s:8:"email_cc";s:0:"";s:10:"permission";s:17:"access CiviReport";s:6:"groups";s:0:"";s:9:"domain_id";i:1;}'); -UPDATE civicrm_domain SET version = '5.59.4'; +UPDATE civicrm_domain SET version = '5.60.0'; diff --git a/civicrm/sql/civicrm_generated.mysql b/civicrm/sql/civicrm_generated.mysql index d747b24a9b..25f1891768 100644 --- a/civicrm/sql/civicrm_generated.mysql +++ b/civicrm/sql/civicrm_generated.mysql @@ -3055,7 +3055,7 @@ UNLOCK TABLES; LOCK TABLES `civicrm_domain` WRITE; /*!40000 ALTER TABLE `civicrm_domain` DISABLE KEYS */; INSERT INTO `civicrm_domain` (`id`, `name`, `description`, `version`, `contact_id`, `locales`, `locale_custom_strings`) VALUES - (1,'Default Domain Name',NULL,'5.59.4',1,NULL,'a:1:{s:5:\"en_US\";a:0:{}}'); + (1,'Default Domain Name',NULL,'5.60.0',1,NULL,'a:1:{s:5:\"en_US\";a:0:{}}'); /*!40000 ALTER TABLE `civicrm_domain` ENABLE KEYS */; UNLOCK TABLES; diff --git a/civicrm/templates/CRM/Admin/Form/ParticipantStatusType.tpl b/civicrm/templates/CRM/Admin/Form/ParticipantStatusType.tpl index b7afd0d559..89508dfc70 100644 --- a/civicrm/templates/CRM/Admin/Form/ParticipantStatusType.tpl +++ b/civicrm/templates/CRM/Admin/Form/ParticipantStatusType.tpl @@ -18,7 +18,7 @@ {icon icon="fa-info-circle"}{/icon} {ts}WARNING: Deleting this Participant Status will remove all of its settings.{/ts} {ts}Do you want to continue?{/ts} </div> - <div>{include file="CRM/common/formButtons.tpl"} + <div>{include file="CRM/common/formButtons.tpl" location=''} </div> {else} <table class="form-layout-compressed"> diff --git a/civicrm/templates/CRM/Admin/Form/PaymentProcessor.tpl b/civicrm/templates/CRM/Admin/Form/PaymentProcessor.tpl index 28827b4409..91e3ef405b 100644 --- a/civicrm/templates/CRM/Admin/Form/PaymentProcessor.tpl +++ b/civicrm/templates/CRM/Admin/Form/PaymentProcessor.tpl @@ -145,12 +145,15 @@ {if $action eq 1 or $action eq 2} <script type="text/javascript"> {literal} - function reload(refresh) { - var paymentProcessorType = cj("#payment_processor_type_id"); - var url = {/literal}"{$refreshURL}"{literal} + "&pp=" + paymentProcessorType.val(); - paymentProcessorType.closest('form').attr('data-warn-changes', 'false'); - window.location.href = url; - } + CRM.$(function($) { + $('#payment_processor_type_id').change(function() { + var url = {/literal}"{$refreshURL}"{literal} + "&pp=" + $(this).val(); + $(this).closest('form').attr('data-warn-changes', 'false') + // Ajax refresh (works in a popup or full-screen) + .closest('.crm-ajax-container, #crm-main-content-wrapper') + .crmSnippet({url: url}).crmSnippet('refresh'); + }); + }); {/literal} </script> diff --git a/civicrm/templates/CRM/Admin/Form/Setting/Smtp.tpl b/civicrm/templates/CRM/Admin/Form/Setting/Smtp.tpl index 9df670fd0e..83c2485186 100644 --- a/civicrm/templates/CRM/Admin/Form/Setting/Smtp.tpl +++ b/civicrm/templates/CRM/Admin/Form/Setting/Smtp.tpl @@ -85,7 +85,7 @@ </div> <div class="spacer"></div> <div class="crm-submit-buttons"> - {include file="CRM/common/formButtons.tpl"} + {include file="CRM/common/formButtons.tpl" location=''} </div> {literal} diff --git a/civicrm/templates/CRM/Admin/Form/Setting/UF.tpl b/civicrm/templates/CRM/Admin/Form/Setting/UF.tpl index be63b58336..9938e4d90c 100644 --- a/civicrm/templates/CRM/Admin/Form/Setting/UF.tpl +++ b/civicrm/templates/CRM/Admin/Form/Setting/UF.tpl @@ -34,12 +34,11 @@ </table> <div class="crm-submit-buttons">{include file="CRM/common/formButtons.tpl" location="bottom"}</div> <div class="spacer"></div> -{if $tablePrefixes} +{if $viewsIntegration} <div class="form-item"> <fieldset> <legend>{ts}Views integration settings{/ts}</legend> - <div>{ts}To enable CiviCRM Views integration, add or update the following item in the <code>settings.php</code> file:{/ts}</div> - <pre>{$tablePrefixes}</pre> + <div>{$viewsIntegration}</div> </fieldset> </div> {/if} diff --git a/civicrm/templates/CRM/Batch/Form/Search.tpl b/civicrm/templates/CRM/Batch/Form/Search.tpl index dd1379ebdd..66054c2c9c 100644 --- a/civicrm/templates/CRM/Batch/Form/Search.tpl +++ b/civicrm/templates/CRM/Batch/Form/Search.tpl @@ -17,7 +17,7 @@ {ts}Complete OR partial batch name.{/ts} </span> </td> - <td>{include file="CRM/common/formButtons.tpl"}</td> + <td>{include file="CRM/common/formButtons.tpl" location=''}</td> </tr> </table> </div> diff --git a/civicrm/templates/CRM/Contact/Form/Inline/Address.tpl b/civicrm/templates/CRM/Contact/Form/Inline/Address.tpl index 56bb901e23..2a9ceebcea 100644 --- a/civicrm/templates/CRM/Contact/Form/Inline/Address.tpl +++ b/civicrm/templates/CRM/Contact/Form/Inline/Address.tpl @@ -13,7 +13,7 @@ <tr> <td> <div class="crm-submit-buttons"> - {include file="CRM/common/formButtons.tpl"} + {include file="CRM/common/formButtons.tpl" location=''} {if $addressId} <a class="button delete-button" href="#" style="display:inline-block;float:none;"><div class="icon delete-icon"></div> {ts}Delete{/ts}</a> diff --git a/civicrm/templates/CRM/Contact/Form/Inline/CommunicationPreferences.tpl b/civicrm/templates/CRM/Contact/Form/Inline/CommunicationPreferences.tpl index ccefcd6809..eda461fe0d 100644 --- a/civicrm/templates/CRM/Contact/Form/Inline/CommunicationPreferences.tpl +++ b/civicrm/templates/CRM/Contact/Form/Inline/CommunicationPreferences.tpl @@ -13,7 +13,7 @@ <div class="crm-inline-edit-form"> <div class="crm-inline-button"> - {include file="CRM/common/formButtons.tpl"} + {include file="CRM/common/formButtons.tpl" location=''} </div> <div class="crm-clear"> {foreach key=key item=item from=$commPreference} diff --git a/civicrm/templates/CRM/Contact/Form/Inline/ContactInfo.tpl b/civicrm/templates/CRM/Contact/Form/Inline/ContactInfo.tpl index f9efa336c4..137bd07e51 100644 --- a/civicrm/templates/CRM/Contact/Form/Inline/ContactInfo.tpl +++ b/civicrm/templates/CRM/Contact/Form/Inline/ContactInfo.tpl @@ -10,7 +10,7 @@ {$form.oplock_ts.html} <div class="crm-inline-edit-form"> <div class="crm-inline-button"> - {include file="CRM/common/formButtons.tpl"} + {include file="CRM/common/formButtons.tpl" location=''} </div> <div class="crm-clear"> diff --git a/civicrm/templates/CRM/Contact/Form/Inline/ContactName.tpl b/civicrm/templates/CRM/Contact/Form/Inline/ContactName.tpl index 021cff1c51..6b9aacfde0 100644 --- a/civicrm/templates/CRM/Contact/Form/Inline/ContactName.tpl +++ b/civicrm/templates/CRM/Contact/Form/Inline/ContactName.tpl @@ -11,7 +11,7 @@ {$form.oplock_ts.html} <div class="crm-inline-edit-form"> <div class="crm-inline-button"> - {include file="CRM/common/formButtons.tpl"} + {include file="CRM/common/formButtons.tpl" location=''} </div> {crmRegion name="contact-form-inline-contactname"} {if $contactType eq 'Individual'} diff --git a/civicrm/templates/CRM/Contact/Form/Inline/CustomData.tpl b/civicrm/templates/CRM/Contact/Form/Inline/CustomData.tpl index 43961f65ca..0d3929be13 100644 --- a/civicrm/templates/CRM/Contact/Form/Inline/CustomData.tpl +++ b/civicrm/templates/CRM/Contact/Form/Inline/CustomData.tpl @@ -11,7 +11,7 @@ {$form.oplock_ts.html} <div class="crm-inline-edit-form"> <div class="crm-inline-button"> - {include file="CRM/common/formButtons.tpl"} + {include file="CRM/common/formButtons.tpl" location=''} </div> {include file="CRM/Custom/Form/CustomData.tpl" skipTitle=true} </div> <!-- end of main --> diff --git a/civicrm/templates/CRM/Contact/Form/Inline/Demographics.tpl b/civicrm/templates/CRM/Contact/Form/Inline/Demographics.tpl index a26dedfe54..e4e8f2e701 100644 --- a/civicrm/templates/CRM/Contact/Form/Inline/Demographics.tpl +++ b/civicrm/templates/CRM/Contact/Form/Inline/Demographics.tpl @@ -10,7 +10,7 @@ {$form.oplock_ts.html} <div class="crm-inline-edit-form"> <div class="crm-inline-button"> - {include file="CRM/common/formButtons.tpl"} + {include file="CRM/common/formButtons.tpl" location=''} </div> <div class="crm-clear"> diff --git a/civicrm/templates/CRM/Contact/Form/Inline/Email.tpl b/civicrm/templates/CRM/Contact/Form/Inline/Email.tpl index b4b11bc728..e84a752511 100644 --- a/civicrm/templates/CRM/Contact/Form/Inline/Email.tpl +++ b/civicrm/templates/CRM/Contact/Form/Inline/Email.tpl @@ -13,7 +13,7 @@ <tr> <td colspan="5"> <div class="crm-submit-buttons"> - {include file="CRM/common/formButtons.tpl"} + {include file="CRM/common/formButtons.tpl" location=''} </div> </td> </tr> diff --git a/civicrm/templates/CRM/Contact/Form/Inline/IM.tpl b/civicrm/templates/CRM/Contact/Form/Inline/IM.tpl index e76a1b15dc..5291433fbb 100644 --- a/civicrm/templates/CRM/Contact/Form/Inline/IM.tpl +++ b/civicrm/templates/CRM/Contact/Form/Inline/IM.tpl @@ -13,7 +13,7 @@ <tr> <td colspan="5"> <div class="crm-submit-buttons"> - {include file="CRM/common/formButtons.tpl"} + {include file="CRM/common/formButtons.tpl" location=''} </div> </td> </tr> diff --git a/civicrm/templates/CRM/Contact/Form/Inline/OpenID.tpl b/civicrm/templates/CRM/Contact/Form/Inline/OpenID.tpl index bcb0a09472..7fd73b6118 100644 --- a/civicrm/templates/CRM/Contact/Form/Inline/OpenID.tpl +++ b/civicrm/templates/CRM/Contact/Form/Inline/OpenID.tpl @@ -13,7 +13,7 @@ <tr> <td colspan="4"> <div class="crm-submit-buttons"> - {include file="CRM/common/formButtons.tpl"} + {include file="CRM/common/formButtons.tpl" location=''} </div> </td> </tr> diff --git a/civicrm/templates/CRM/Contact/Form/Inline/Phone.tpl b/civicrm/templates/CRM/Contact/Form/Inline/Phone.tpl index 3e2c3af7c1..fa90b955ce 100644 --- a/civicrm/templates/CRM/Contact/Form/Inline/Phone.tpl +++ b/civicrm/templates/CRM/Contact/Form/Inline/Phone.tpl @@ -13,7 +13,7 @@ <tr> <td colspan="5"> <div class="crm-submit-buttons"> - {include file="CRM/common/formButtons.tpl"} + {include file="CRM/common/formButtons.tpl" location=''} </div> </td> </tr> diff --git a/civicrm/templates/CRM/Contact/Form/Inline/Website.tpl b/civicrm/templates/CRM/Contact/Form/Inline/Website.tpl index e5d5bf5838..f58852cc8d 100644 --- a/civicrm/templates/CRM/Contact/Form/Inline/Website.tpl +++ b/civicrm/templates/CRM/Contact/Form/Inline/Website.tpl @@ -13,7 +13,7 @@ <tr> <td colspan="5"> <div class="crm-submit-buttons"> - {include file="CRM/common/formButtons.tpl"} + {include file="CRM/common/formButtons.tpl" location=''} </div> </td> </tr> diff --git a/civicrm/templates/CRM/Contact/Form/Task/AddToParentClass.tpl b/civicrm/templates/CRM/Contact/Form/Task/AddToParentClass.tpl index a97a336420..c014c75c2a 100644 --- a/civicrm/templates/CRM/Contact/Form/Task/AddToParentClass.tpl +++ b/civicrm/templates/CRM/Contact/Form/Task/AddToParentClass.tpl @@ -84,7 +84,7 @@ <div class="description"> </div> - <div class="crm-submit-buttons">{include file="CRM/common/formButtons.tpl"}</div> + <div class="crm-submit-buttons">{include file="CRM/common/formButtons.tpl" location=''}</div> </div> diff --git a/civicrm/templates/CRM/Contact/Form/Task/Delete.tpl b/civicrm/templates/CRM/Contact/Form/Task/Delete.tpl index 436464f40e..a8b01b8359 100644 --- a/civicrm/templates/CRM/Contact/Form/Task/Delete.tpl +++ b/civicrm/templates/CRM/Contact/Form/Task/Delete.tpl @@ -22,5 +22,5 @@ <h3>{include file="CRM/Contact/Form/Task.tpl"}</h3> - <div class="crm-submit-buttons">{include file="CRM/common/formButtons.tpl"}</div> + <div class="crm-submit-buttons">{include file="CRM/common/formButtons.tpl" location=''}</div> </div> diff --git a/civicrm/templates/CRM/Contact/Form/Task/PickProfile.tpl b/civicrm/templates/CRM/Contact/Form/Task/PickProfile.tpl index ddfe7ac4ee..4ddd6cf968 100644 --- a/civicrm/templates/CRM/Contact/Form/Task/PickProfile.tpl +++ b/civicrm/templates/CRM/Contact/Form/Task/PickProfile.tpl @@ -21,6 +21,6 @@ </td> </tr> </table> -<div class="crm-submit-buttons">{include file="CRM/common/formButtons.tpl"}</div> +<div class="crm-submit-buttons">{include file="CRM/common/formButtons.tpl" location=''}</div> </div> diff --git a/civicrm/templates/CRM/Contact/Form/Task/Unhold.tpl b/civicrm/templates/CRM/Contact/Form/Task/Unhold.tpl index e2f019db57..7012f28248 100644 --- a/civicrm/templates/CRM/Contact/Form/Task/Unhold.tpl +++ b/civicrm/templates/CRM/Contact/Form/Task/Unhold.tpl @@ -14,5 +14,5 @@ <p>{ts}Are you sure you want to unhold email of selected contact(s)?.{/ts} {ts}This action cannot be undone.{/ts}</p> <p>{include file="CRM/Contact/Form/Task.tpl"}</p> </div> -<div class="crm-submit-buttons">{include file="CRM/common/formButtons.tpl"}</div> +<div class="crm-submit-buttons">{include file="CRM/common/formButtons.tpl" location=''}</div> </div> diff --git a/civicrm/templates/CRM/Contact/Import/Form/DataSource.tpl b/civicrm/templates/CRM/Contact/Import/Form/DataSource.tpl index eb3c00a426..7d9987b31d 100644 --- a/civicrm/templates/CRM/Contact/Import/Form/DataSource.tpl +++ b/civicrm/templates/CRM/Contact/Import/Form/DataSource.tpl @@ -53,10 +53,6 @@ <td><span id="contact-dedupe_rule_id">{$form.dedupe_rule_id.html}</span> {help id='id-dedupe_rule'}</td> </tr> {/if} - <tr class="crm-import-datasource-form-block-fieldSeparator"> - <td class="label">{$form.fieldSeparator.label}</td> - <td>{$form.fieldSeparator.html} {help id='id-fieldSeparator'}</td> - </tr> <tr>{include file="CRM/Core/Date.tpl"}</tr> <tr> <td></td><td class="description">{ts}Select the format that is used for date fields in your import data.{/ts}</td> diff --git a/civicrm/templates/CRM/Contact/Import/Form/Preview.tpl b/civicrm/templates/CRM/Contact/Import/Form/Preview.tpl index 47283e4dff..eab53cdd04 100644 --- a/civicrm/templates/CRM/Contact/Import/Form/Preview.tpl +++ b/civicrm/templates/CRM/Contact/Import/Form/Preview.tpl @@ -143,13 +143,13 @@ {literal} <script type="text/javascript"> -{/literal}{if $invalidGroupName}{literal} -cj("#new-group.collapsed").crmAccordionToggle(); -{/literal}{/if}{literal} +if (cj("#newGroupName").val()) { + cj("#new-group.collapsed").crmAccordionToggle(); +} -{/literal}{if $invalidTagName}{literal} -cj("#new-tag.collapsed").crmAccordionToggle(); -{/literal}{/if}{literal} +if (cj("#newTagName").val()) { + cj("#new-tag.collapsed").crmAccordionToggle(); +} </script> {/literal} diff --git a/civicrm/templates/CRM/Contact/Page/Inline/Address.tpl b/civicrm/templates/CRM/Contact/Page/Inline/Address.tpl index 453d330884..9c248f2b65 100644 --- a/civicrm/templates/CRM/Contact/Page/Inline/Address.tpl +++ b/civicrm/templates/CRM/Contact/Page/Inline/Address.tpl @@ -31,7 +31,8 @@ !empty($add.geo_code_2) AND is_numeric($add.geo_code_2) } - <br /><a href="{crmURL p='civicrm/contact/map' q="reset=1&cid=`$contactId`&lid=`$add.location_type_id`"}" title="{ts 1=`$add.location_type`}Map %1 Address{/ts}"><i class="crm-i fa-map-marker" aria-hidden="true"></i> {ts}Map{/ts}</a> + {assign var='mapLocationTypeID' value=$add.location_type_id} + <br /><a href="{crmURL p='civicrm/contact/map' q="reset=1&cid=$contactId&lid=$mapLocationTypeID"}" title="{ts 1=$add.location_type}Map %1 Address{/ts}"><i class="crm-i fa-map-marker" aria-hidden="true"></i> {ts}Map{/ts}</a> {/if} </div> <div class="crm-content"> diff --git a/civicrm/templates/CRM/Contact/Page/View/Delete.tpl b/civicrm/templates/CRM/Contact/Page/View/Delete.tpl index 5b8c511577..63d60e06b6 100644 --- a/civicrm/templates/CRM/Contact/Page/View/Delete.tpl +++ b/civicrm/templates/CRM/Contact/Page/View/Delete.tpl @@ -14,4 +14,4 @@ <p>{ts}This action cannot be undone.{/ts}</p> </div> <p> -<div class="crm-submit-buttons">{include file="CRM/common/formButtons.tpl"}</div> +<div class="crm-submit-buttons">{include file="CRM/common/formButtons.tpl" location=''}</div> diff --git a/civicrm/templates/CRM/Contact/Page/View/Note.tpl b/civicrm/templates/CRM/Contact/Page/View/Note.tpl index 2ea05f614e..cc11d8e9c2 100644 --- a/civicrm/templates/CRM/Contact/Page/View/Note.tpl +++ b/civicrm/templates/CRM/Contact/Page/View/Note.tpl @@ -83,7 +83,7 @@ {/if} {if ($action eq 8)} <div class=status>{ts 1=$notes.$id.note}Are you sure you want to delete the note '%1'?{/ts}</div> -<div class="crm-submit-buttons">{include file="CRM/common/formButtons.tpl"}</div> +<div class="crm-submit-buttons">{include file="CRM/common/formButtons.tpl" location=''}</div> {/if} diff --git a/civicrm/templates/CRM/Contribute/Form/AdditionalPayment.tpl b/civicrm/templates/CRM/Contribute/Form/AdditionalPayment.tpl index 88f1bdae27..df7c946dba 100644 --- a/civicrm/templates/CRM/Contribute/Form/AdditionalPayment.tpl +++ b/civicrm/templates/CRM/Contribute/Form/AdditionalPayment.tpl @@ -11,7 +11,7 @@ {include file="CRM/Contribute/Form/PaymentInfoBlock.tpl"} {if !$suppressPaymentFormButtons} <div class="crm-submit-buttons"> - {include file="CRM/common/formButtons.tpl"} + {include file="CRM/common/formButtons.tpl" location=''} </div> {/if} {else} @@ -39,7 +39,7 @@ {/if} {/if} <div class="crm-submit-buttons"> - {include file="CRM/common/formButtons.tpl"} + {include file="CRM/common/formButtons.tpl" location=''} </div> <table class="form-layout-compressed"> <tr> diff --git a/civicrm/templates/CRM/Contribute/Form/Contribution.tpl b/civicrm/templates/CRM/Contribute/Form/Contribution.tpl index 1549c4f315..702832d7c1 100644 --- a/civicrm/templates/CRM/Contribute/Form/Contribution.tpl +++ b/civicrm/templates/CRM/Contribute/Form/Contribution.tpl @@ -56,7 +56,7 @@ </div> {/if} <div class="crm-submit-buttons"> - {include file="CRM/common/formButtons.tpl"} + {include file="CRM/common/formButtons.tpl" location=''} </div> {if !empty($isOnline)}{assign var=valueStyle value=" class='view-value'"}{else}{assign var=valueStyle value=""}{/if} <table class="form-layout-compressed"> diff --git a/civicrm/templates/CRM/Contribute/Form/Contribution/Main.tpl b/civicrm/templates/CRM/Contribute/Form/Contribution/Main.tpl index 0c46bda378..e5e6f688f7 100644 --- a/civicrm/templates/CRM/Contribute/Form/Contribution/Main.tpl +++ b/civicrm/templates/CRM/Contribute/Form/Contribution/Main.tpl @@ -287,7 +287,7 @@ {include file="CRM/UF/Form/Block.tpl" fields=$customPost} </div> - {if $is_monetary and $form.bank_account_number} + {if $is_monetary && array_key_exists('bank_account_number', $form)} <div id="payment_notice"> <fieldset class="crm-public-form-item crm-group payment_notice-group"> <legend>{ts}Agreement{/ts}</legend> diff --git a/civicrm/templates/CRM/Contribute/Form/Contribution/MembershipBlock.tpl b/civicrm/templates/CRM/Contribute/Form/Contribution/MembershipBlock.tpl index 51d6ab1abd..796834c64b 100644 --- a/civicrm/templates/CRM/Contribute/Form/Contribution/MembershipBlock.tpl +++ b/civicrm/templates/CRM/Contribute/Form/Contribution/MembershipBlock.tpl @@ -34,7 +34,7 @@ {if !empty($membershipTypes)} {foreach from=$membershipTypes item=row} {if array_key_exists( 'current_membership', $row )} - <div id='help'> + <div class='help'> {* Lifetime memberships have no end-date so current_membership array key exists but is NULL *} {if $row.current_membership} {if $row.current_membership|crmDate:"%Y%m%d" LT $smarty.now|crmDate:"%Y%m%d"} diff --git a/civicrm/templates/CRM/Contribute/Form/ContributionPage/AddProduct.tpl b/civicrm/templates/CRM/Contribute/Form/ContributionPage/AddProduct.tpl index 3d282628fa..75725faa39 100644 --- a/civicrm/templates/CRM/Contribute/Form/ContributionPage/AddProduct.tpl +++ b/civicrm/templates/CRM/Contribute/Form/ContributionPage/AddProduct.tpl @@ -52,7 +52,7 @@ </div> {else} <div class="crm-done-button"> - {include file="CRM/common/formButtons.tpl"} + {include file="CRM/common/formButtons.tpl" location=''} </div> {/if} {* $action ne view *} </div> diff --git a/civicrm/templates/CRM/Contribute/Form/ContributionPage/Delete.tpl b/civicrm/templates/CRM/Contribute/Form/ContributionPage/Delete.tpl index 98544852fb..aa7887845d 100644 --- a/civicrm/templates/CRM/Contribute/Form/ContributionPage/Delete.tpl +++ b/civicrm/templates/CRM/Contribute/Form/ContributionPage/Delete.tpl @@ -17,5 +17,5 @@ {/if} </div> <div class="form-item"> - {include file="CRM/common/formButtons.tpl"} + {include file="CRM/common/formButtons.tpl" location=''} </div> diff --git a/civicrm/templates/CRM/Contribute/Form/SearchContribution.tpl b/civicrm/templates/CRM/Contribute/Form/SearchContribution.tpl index ae2d9650ac..a282a719b5 100644 --- a/civicrm/templates/CRM/Contribute/Form/SearchContribution.tpl +++ b/civicrm/templates/CRM/Contribute/Form/SearchContribution.tpl @@ -34,5 +34,5 @@ campaignTrClass='' campaignTdClass=''} </table> - <div class="crm-submit-buttons">{include file="CRM/common/formButtons.tpl"}</div> + <div class="crm-submit-buttons">{include file="CRM/common/formButtons.tpl" location=''}</div> </div> diff --git a/civicrm/templates/CRM/Contribute/Page/UserDashboard.tpl b/civicrm/templates/CRM/Contribute/Page/UserDashboard.tpl index e662f12044..ec1c9e6559 100644 --- a/civicrm/templates/CRM/Contribute/Page/UserDashboard.tpl +++ b/civicrm/templates/CRM/Contribute/Page/UserDashboard.tpl @@ -27,23 +27,23 @@ </tr> {foreach from=$contribute_rows item=row} - <tr id='rowid{$row.contribution_id}' + <tr id='rowid{$row.id}' class="{cycle values="odd-row,even-row"}{if !empty($row.cancel_date)} disabled{/if}"> - <td>{$row.total_amount|crmMoney:$row.currency} {if !empty($row.amount_level) && !is_array($row.amount_level)} - {$row.amount_level} {/if} + <td>{$row.total_amount|crmMoney:$row.currency} {if !empty($row.amount_level) && !is_array($row.amount_level)} - {$row.amount_level|escape|smarty:nodefaults} {/if} {if !empty($row.contribution_recur_id)} <br/> {ts}(Recurring Contribution){/ts} {/if} </td> - <td>{$row.financial_type}</td> + <td>{$row.financial_type|escape|smarty:nodefaults}</td> <td>{$row.receive_date|truncate:10:''|crmDate}</td> <td>{$row.receipt_date|truncate:10:''|crmDate}</td> <td>{$row.balance_amount|crmMoney:$row.currency}</td> - <td>{$row.contribution_status}</td> + <td>{$row.contribution_status|escape|smarty:nodefaults}</td> {if $isIncludeInvoiceLinks} <td> {* @todo Instead of this tpl handling assign actions as an array attached the row, iterate through - will better accomodate extension overrides and competition for scarce real estate on this page*} - {assign var='id' value=$row.contribution_id} + {assign var='id' value=$row.id} {assign var='contact_id' value=$row.contact_id} {assign var='urlParams' value="reset=1&id=$id&cid=$contact_id"} {if call_user_func(array('CRM_Core_Permission','check'), 'view my invoices') OR call_user_func(array('CRM_Core_Permission','check'), 'access CiviContribute')} @@ -80,42 +80,38 @@ </div> {/if} - - {if !empty($honor)} - {if $honorRows} - {strip} - <div class="help"> - {ts}Contributions made in your honor{/ts}: - </div> - <table class="selector"> - <tr class="columnheader"> - <th>{ts}Contributor{/ts}</th> - <th>{ts}Amount{/ts}</th> - <th>{ts}Type{/ts}</th> - <th>{ts}Financial Type{/ts}</th> - <th>{ts}Received date{/ts}</th> - <th>{ts}Receipt Sent{/ts}</th> - <th>{ts}Status{/ts}</th> + {if !empty($soft_credit_contributions)} + {strip} + <div class="help"> + {ts}Contributions made in your honor{/ts}: + </div> + <table class="selector"> + <tr class="columnheader"> + <th>{ts}Contributor{/ts}</th> + <th>{ts}Amount{/ts}</th> + <th>{ts}Type{/ts}</th> + <th>{ts}Financial Type{/ts}</th> + <th>{ts}Received date{/ts}</th> + <th>{ts}Receipt Sent{/ts}</th> + <th>{ts}Status{/ts}</th> + </tr> + {foreach from=$soft_credit_contributions item=row} + <tr id='rowid{$row.contact_id}' class="{cycle values="odd-row,even-row"}"> + <td><a href="{crmURL p="civicrm/contact/view" q="reset=1&cid=`$row.contact_id`"}" + id="view_contact">{$row.display_name|escape|smarty:nodefaults}</a></td> + <td>{$row.total_amount|crmMoney:$row.currency}</td> + <td>{$row.soft_credit_type|escape|smarty:nodefaults}</td> + <td>{$row.financial_type|escape|smarty:nodefaults}</td> + <td>{$row.receive_date|truncate:10:''|crmDate}</td> + <td>{$row.receipt_date|truncate:10:''|crmDate}</td> + <td>{$row.contribution_status|escape|smarty:nodefaults}</td> </tr> - {foreach from=$honorRows item=row} - <tr id='rowid{$row.honorId}' class="{cycle values="odd-row,even-row"}"> - <td><a href="{crmURL p="civicrm/contact/view" q="reset=1&cid=`$row.honorId`"}" - id="view_contact">{$row.display_name}</a></td> - <td>{$row.amount}</td> - <td>{$row.honor_type}</td> - <td>{$row.type}</td> - <td>{$row.receive_date|truncate:10:''|crmDate}</td> - <td>{$row.receipt_date|truncate:10:''|crmDate}</td> - <td>{$row.contribution_status}</td> - </tr> - {/foreach} - </table> - {/strip} - {/if} + {/foreach} + </table> + {/strip} {/if} - {if !empty($recur)} - {if $recurRows} + {if !empty($recurRows)} {strip} <div><label>{ts}Recurring Contribution(s){/ts}</label></div> <table class="selector"> @@ -126,24 +122,23 @@ <th>{ts}Created{/ts}</th> <th></th> </tr> - {foreach from=$recurRows item=row key=id} + {foreach from=$recurRows item=row} <tr class="{cycle values="odd-row,even-row"}"> - <td><label>{$recurRows.$id.amount|crmMoney}</label> - every {$recurRows.$id.frequency_interval} {$recurRows.$id.frequency_unit} - for {$recurRows.$id.installments} installments + <td><label>{$row.amount|crmMoney}</label> + every {$row.frequency_interval} {$row.frequency_unit} for {$row.installments} installments </td> - <td>{$recurRows.$id.recur_status}</td> - <td>{if $recurRows.$id.completed}<a href="{$recurRows.$id.link}">{$recurRows.$id.completed} - /{$recurRows.$id.installments}</a> - {else}0/{$recurRows.$id.installments} {/if}</td> - <td>{$recurRows.$id.create_date|crmDate}</td> - <td>{$recurRows.$id.action|replace:'xx':$recurRows.id}</td> + <td>{$row.recur_status|escape|smarty:nodefaults}</td> + <td>{if $row.completed}<a href="{$row.link}">{$row.completed} + /{$row.installments}</a> + {else}0/{$row.installments} {/if}</td> + <td>{$row.create_date|crmDate}</td> + <td>{$row.action|replace:'xx':$row.id}</td> </tr> {/foreach} </table> {/strip} {/if} - {/if} + </div> {crmRegion name="crm-contribute-userdashboard-post"} {/crmRegion} diff --git a/civicrm/templates/CRM/Custom/Form/Edit/CustomField.tpl b/civicrm/templates/CRM/Custom/Form/Edit/CustomField.tpl index 119e8bbdab..fbf5ee179e 100644 --- a/civicrm/templates/CRM/Custom/Form/Edit/CustomField.tpl +++ b/civicrm/templates/CRM/Custom/Form/Edit/CustomField.tpl @@ -26,7 +26,7 @@ {assign var="index" value="1"} {foreach name=outer key=key item=item from=$formElement} {if $index < 10} - {assign var="index" value=`$index+1`} + {assign var="index" value=$index+1} {else} <td class="labels font-light">{$formElement.$key.html}</td> {if $count == $element.options_per_line} @@ -34,7 +34,7 @@ <tr> {assign var="count" value="1"} {else} - {assign var="count" value=`$count+1`} + {assign var="count" value=$count+1} {/if} {/if} {/foreach} diff --git a/civicrm/templates/CRM/Custom/Form/Field.tpl b/civicrm/templates/CRM/Custom/Form/Field.tpl index c2e13ab33c..05df6d9dd1 100644 --- a/civicrm/templates/CRM/Custom/Form/Field.tpl +++ b/civicrm/templates/CRM/Custom/Form/Field.tpl @@ -26,6 +26,10 @@ <td class="label">{$form.html_type.label}</td> <td class="html-adjust">{$form.html_type.html}</td> </tr> + <tr class="crm-custom-field-form-block-fk_entity"> + <td class="label">{$form.fk_entity.label} <span class="crm-marker">*</span></td> + <td class="html-adjust">{$form.fk_entity.html}</td> + </tr> <tr class="crm-custom-field-form-block-serialize"> <td class="label">{$form.serialize.label}</td> <td class="html-adjust">{$form.serialize.html}</td> @@ -185,8 +189,13 @@ if (!$('#html_type', $form).val()) { $('#html_type', $form).val(dataToHTML[dataType][0]).change(); } + // Hide html_type if there is only one option + $('.crm-custom-field-form-block-html_type').toggle(allowedHtmlTypes.length > 1); customOptionHtmlType(dataType); makeDefaultValueField(dataType); + + // Show/hide entityReference selector + $('.crm-custom-field-form-block-fk_entity').toggle(dataType === 'EntityReference'); } function onChangeHtmlType() { @@ -282,7 +291,7 @@ $("#noteColumns, #noteRows, #noteLength", $form).toggle(dataType === 'Memo'); - $(".crm-custom-field-form-block-serialize", $form).toggle(htmlType === 'Select' || htmlType === 'Autocomplete-Select'); + $(".crm-custom-field-form-block-serialize", $form).toggle(htmlType === 'Select' || htmlType === 'Autocomplete-Select' && dataType !== 'EntityReference'); } function makeDefaultValueField(dataType) { diff --git a/civicrm/templates/CRM/Event/Form/Registration/AdditionalParticipant.tpl b/civicrm/templates/CRM/Event/Form/Registration/AdditionalParticipant.tpl index a38d3f94b8..1c00dbfcc6 100644 --- a/civicrm/templates/CRM/Event/Form/Registration/AdditionalParticipant.tpl +++ b/civicrm/templates/CRM/Event/Form/Registration/AdditionalParticipant.tpl @@ -55,7 +55,7 @@ </div> <div id="crm-submit-buttons" class="crm-submit-buttons"> - {include file="CRM/common/formButtons.tpl"} + {include file="CRM/common/formButtons.tpl" location=''} </div> </div> diff --git a/civicrm/templates/CRM/Event/Form/Search.tpl b/civicrm/templates/CRM/Event/Form/Search.tpl index b89051349c..bd75709472 100644 --- a/civicrm/templates/CRM/Event/Form/Search.tpl +++ b/civicrm/templates/CRM/Event/Form/Search.tpl @@ -24,7 +24,7 @@ {include file="CRM/Event/Form/Search/Common.tpl"} <tr> - <td colspan="2">{include file="CRM/common/formButtons.tpl"}</td> + <td colspan="2">{include file="CRM/common/formButtons.tpl" location=''}</td> </tr> </table> {/strip} diff --git a/civicrm/templates/CRM/Event/Form/SearchEvent.tpl b/civicrm/templates/CRM/Event/Form/SearchEvent.tpl index fb278a55be..fc064e42b9 100644 --- a/civicrm/templates/CRM/Event/Form/SearchEvent.tpl +++ b/civicrm/templates/CRM/Event/Form/SearchEvent.tpl @@ -47,7 +47,7 @@ {* campaign in event search *} {include file="CRM/Campaign/Form/addCampaignToSearch.tpl" campaignTrClass='crm-event-searchevent-form-block-campaign_id' campaignTdClass=''} - <td class="right">{include file="CRM/common/formButtons.tpl"}</td> + <td class="right">{include file="CRM/common/formButtons.tpl" location=''}</td> </table> </div> </div> diff --git a/civicrm/templates/CRM/Event/Form/Task/Batch.tpl b/civicrm/templates/CRM/Event/Form/Task/Batch.tpl index 895ec862e6..27760a6b08 100644 --- a/civicrm/templates/CRM/Event/Form/Task/Batch.tpl +++ b/civicrm/templates/CRM/Event/Form/Task/Batch.tpl @@ -93,7 +93,7 @@ </tr> </table> <div class="crm-submit-buttons"> -{if $fields}{$form._qf_Batch_refresh.html}{/if}{include file="CRM/common/formButtons.tpl"} +{if $fields}{$form._qf_Batch_refresh.html}{/if}{include file="CRM/common/formButtons.tpl" location=''} </div> </div> diff --git a/civicrm/templates/CRM/Event/Form/Task/Print.tpl b/civicrm/templates/CRM/Event/Form/Task/Print.tpl index 689580967b..a321e22098 100644 --- a/civicrm/templates/CRM/Event/Form/Task/Print.tpl +++ b/civicrm/templates/CRM/Event/Form/Task/Print.tpl @@ -54,7 +54,7 @@ </table> <div class="form-item"> - <span class="element-right">{include file="CRM/common/formButtons.tpl"}</span> + <span class="element-right">{include file="CRM/common/formButtons.tpl" location=''}</span> </div> {else} diff --git a/civicrm/templates/CRM/Event/Form/Task/Result.tpl b/civicrm/templates/CRM/Event/Form/Task/Result.tpl index ccd03315d4..755e964d0e 100644 --- a/civicrm/templates/CRM/Event/Form/Task/Result.tpl +++ b/civicrm/templates/CRM/Event/Form/Task/Result.tpl @@ -9,6 +9,6 @@ *} <div class='spacer'></div> <div class="crm-submit-buttons"> - {include file="CRM/common/formButtons.tpl"} + {include file="CRM/common/formButtons.tpl" location=''} </div> diff --git a/civicrm/templates/CRM/Event/Page/iCalLinks.tpl b/civicrm/templates/CRM/Event/Page/iCalLinks.tpl index 2f6a315567..932666e217 100644 --- a/civicrm/templates/CRM/Event/Page/iCalLinks.tpl +++ b/civicrm/templates/CRM/Event/Page/iCalLinks.tpl @@ -9,7 +9,7 @@ *} {* Display icons / links for ical download and feed for EventInfo.tpl, ThankYou.tpl, DashBoard.tpl, and ManageEvent.tpl *} {foreach from=$iCal item="iCalItem"} - <a href="{$iCalItem.url}" {if !empty($event)} class="crm-event-feed-link"{/if}> + <a href="{$iCalItem.url}" {if $isShowICalIconsInline} class="crm-event-feed-link"{/if}> <span class="fa-stack" aria-hidden="true"><i class="crm-i fa-calendar-o fa-stack-2x"></i><i style="top: 15%;" class="crm-i {$iCalItem.icon} fa-stack-1x"></i></span> <span class="label">{$iCalItem.text}</span> </a> diff --git a/civicrm/templates/CRM/Form/body.tpl b/civicrm/templates/CRM/Form/body.tpl index 4f8e4667bf..20b8b57629 100644 --- a/civicrm/templates/CRM/Form/body.tpl +++ b/civicrm/templates/CRM/Form/body.tpl @@ -15,7 +15,7 @@ <div>{$form.hidden}</div> {/if} -{if ($snippet !== 'json') and !$suppressForm and count($form.errors) gt 0} +{if ($snippet !== 'json') and !$suppressForm and $form.errors !== NULL && count($form.errors) gt 0} <div class="messages crm-error"> <i class="crm-i fa-exclamation-triangle crm-i-red" aria-hidden="true"></i> {ts}Please correct the following errors in the form fields below:{/ts} diff --git a/civicrm/templates/CRM/Mailing/Form/Approve.tpl b/civicrm/templates/CRM/Mailing/Form/Approve.tpl index 2cc127b950..18e4779649 100644 --- a/civicrm/templates/CRM/Mailing/Form/Approve.tpl +++ b/civicrm/templates/CRM/Mailing/Form/Approve.tpl @@ -22,7 +22,7 @@ </tr> </tbody> </table> -<div class="crm-submit-buttons">{include file="CRM/common/formButtons.tpl"}</div> +<div class="crm-submit-buttons">{include file="CRM/common/formButtons.tpl" location=''}</div> <div class="crm-accordion-wrapper crm-plain_text_email-accordion collapsed"> <div class="crm-accordion-header"> diff --git a/civicrm/templates/CRM/Mailing/Form/Component.tpl b/civicrm/templates/CRM/Mailing/Form/Component.tpl index d176406c02..ab135483bb 100644 --- a/civicrm/templates/CRM/Mailing/Form/Component.tpl +++ b/civicrm/templates/CRM/Mailing/Form/Component.tpl @@ -20,5 +20,5 @@ <tr class="crm-mailing-component-form-block-is_active"><td class="label">{$form.is_active.label}</td><td>{$form.is_active.html}</td> </table> </fieldset> -<div class="crm-submit-buttons">{include file="CRM/common/formButtons.tpl"}</div> +<div class="crm-submit-buttons">{include file="CRM/common/formButtons.tpl" location=''}</div> </div> diff --git a/civicrm/templates/CRM/Mailing/MailingUI.hlp b/civicrm/templates/CRM/Mailing/MailingUI.hlp index c8f4b148f8..f3c4038e23 100644 --- a/civicrm/templates/CRM/Mailing/MailingUI.hlp +++ b/civicrm/templates/CRM/Mailing/MailingUI.hlp @@ -15,7 +15,7 @@ </p> {/htxt} -{htxt id ="from_email"} +{htxt id="from_email"} <p>{ts}Select the "FROM" Email Address for this mailing from the dropdown list. Available email addresses are configurable by users with Administer CiviCRM permission. EXAMPLE: "Client Services" <clientservices@example.org>{/ts}</p> {if call_user_func(array('CRM_Core_Permission','check'), 'administer CiviCRM') } {capture assign="fromConfig"}{crmURL p="civicrm/admin/options/from_email_address" q="reset=1"}{/capture} diff --git a/civicrm/templates/CRM/Member/Form/Search.tpl b/civicrm/templates/CRM/Member/Form/Search.tpl index 7db4c4bfc8..20b9294115 100644 --- a/civicrm/templates/CRM/Member/Form/Search.tpl +++ b/civicrm/templates/CRM/Member/Form/Search.tpl @@ -19,7 +19,7 @@ {include file="CRM/Member/Form/Search/Common.tpl"} <tr> - <td colspan="2">{include file="CRM/common/formButtons.tpl"}</td> + <td colspan="2">{include file="CRM/common/formButtons.tpl" location=''}</td> </tr> </table> {/strip} diff --git a/civicrm/templates/CRM/Member/Form/Task/Result.tpl b/civicrm/templates/CRM/Member/Form/Task/Result.tpl index d3017428f4..a7b04880d9 100644 --- a/civicrm/templates/CRM/Member/Form/Task/Result.tpl +++ b/civicrm/templates/CRM/Member/Form/Task/Result.tpl @@ -10,7 +10,7 @@ <div class='spacer'></div> <div class="form-item"> <p> - {include file="CRM/common/formButtons.tpl"} + {include file="CRM/common/formButtons.tpl" location=''} </p> </div> diff --git a/civicrm/templates/CRM/Price/Form/DeleteSet.tpl b/civicrm/templates/CRM/Price/Form/DeleteSet.tpl index a53d480358..4dd00ba129 100644 --- a/civicrm/templates/CRM/Price/Form/DeleteSet.tpl +++ b/civicrm/templates/CRM/Price/Form/DeleteSet.tpl @@ -11,9 +11,9 @@ <div class="messages status no-popup"> <img src="{$config->resourceBase}i/Inform.gif" alt="{ts}status{/ts}"/> {ts 1=$title}WARNING: Deleting this price set will result in the loss of all '%1' data.{/ts} {ts}This action cannot be undone.{/ts} {ts}Do you want to continue?{/ts} - + </div> <div class="form-item"> - {include file="CRM/common/formButtons.tpl"} + {include file="CRM/common/formButtons.tpl" location=''} </div> diff --git a/civicrm/templates/CRM/Price/Form/Option.tpl b/civicrm/templates/CRM/Price/Form/Option.tpl index 6924efaad0..a7d351009d 100644 --- a/civicrm/templates/CRM/Price/Form/Option.tpl +++ b/civicrm/templates/CRM/Price/Form/Option.tpl @@ -114,7 +114,7 @@ <div class="crm-submit-buttons"> - {include file="CRM/common/formButtons.tpl"} + {include file="CRM/common/formButtons.tpl" location=''} </div> </div> diff --git a/civicrm/templates/CRM/Profile/Form/Dynamic.tpl b/civicrm/templates/CRM/Profile/Form/Dynamic.tpl index ba9421498c..c35fdce222 100644 --- a/civicrm/templates/CRM/Profile/Form/Dynamic.tpl +++ b/civicrm/templates/CRM/Profile/Form/Dynamic.tpl @@ -50,7 +50,7 @@ {if $action eq 2 and $multiRecordFieldListing} <h1>{ts}Edit Details{/ts}</h1> <div class="crm-submit-buttons" style='float:right'> - {include file="CRM/common/formButtons.tpl"}{if $isDuplicate}{$form._qf_Edit_upload_duplicate.html}{/if} + {include file="CRM/common/formButtons.tpl" location=''}{if $isDuplicate}{$form._qf_Edit_upload_duplicate.html}{/if} </div> {/if} @@ -201,7 +201,7 @@ </div> {/if} <div class="crm-submit-buttons" style='{$floatStyle}'> - {include file="CRM/common/formButtons.tpl"}{if $isDuplicate}{$form._qf_Edit_upload_duplicate.html}{/if} + {include file="CRM/common/formButtons.tpl" location=''}{if $isDuplicate}{$form._qf_Edit_upload_duplicate.html}{/if} {if $includeCancelButton} <a class="button cancel" href="{$cancelURL}"> <span> diff --git a/civicrm/templates/CRM/Profile/Form/Search.tpl b/civicrm/templates/CRM/Profile/Form/Search.tpl index 0b093ea450..a0b0f0c46b 100644 --- a/civicrm/templates/CRM/Profile/Form/Search.tpl +++ b/civicrm/templates/CRM/Profile/Form/Search.tpl @@ -75,7 +75,7 @@ <tr><td colspan="2">{include file="CRM/Contact/Form/Task/ProximityCommon.tpl"}</td></tr> {/if} - <tr><td></td><td>{include file="CRM/common/formButtons.tpl"}</td></tr> + <tr><td></td><td>{include file="CRM/common/formButtons.tpl" location=''}</td></tr> </table> {if $groupId} diff --git a/civicrm/templates/CRM/SMS/Form/Group.hlp b/civicrm/templates/CRM/SMS/Form/Group.hlp index 1fc6605f45..99a8e5fc63 100644 --- a/civicrm/templates/CRM/SMS/Form/Group.hlp +++ b/civicrm/templates/CRM/SMS/Form/Group.hlp @@ -47,10 +47,10 @@ <p>{ts}If you have sent other Mass SMS - you can additionally Include (or Exclude) contacts who received those Mass SMS. CiviCRM will eliminate any duplications so that contacts who are in an Included Group AND were recipients of an Included Mailing will only be sent one copy of this SMS.{/ts}</p> {/htxt} -{htxt id ="id-sms_provider-title"} +{htxt id="id-sms_provider-title"} {ts}SMS Provider{/ts} {/htxt} -{htxt id ="id-sms_provider"} +{htxt id="id-sms_provider"} <p>{ts}Select the SMS provider for this mass message from the dropdown list.{/ts}</p> {if $params.isAdmin} {capture assign="fromConfig"}{crmURL p="civicrm/admin/sms/provider" q="reset=1"}{/capture} diff --git a/civicrm/templates/CRM/SMS/Form/Group.tpl b/civicrm/templates/CRM/SMS/Form/Group.tpl index 2ce5486d8c..3df24931d5 100644 --- a/civicrm/templates/CRM/SMS/Form/Group.tpl +++ b/civicrm/templates/CRM/SMS/Form/Group.tpl @@ -49,7 +49,7 @@ </div><!-- /.crm-accordion-body --> </div><!-- /.crm-accordion-wrapper --> - <div class="crm-submit-buttons">{include file="CRM/common/formButtons.tpl"}</div> + <div class="crm-submit-buttons">{include file="CRM/common/formButtons.tpl" location=''}</div> </div> </div> diff --git a/civicrm/templates/CRM/SMS/Form/Schedule.tpl b/civicrm/templates/CRM/SMS/Form/Schedule.tpl index 7e168f26e3..fe5af9ab51 100644 --- a/civicrm/templates/CRM/SMS/Form/Schedule.tpl +++ b/civicrm/templates/CRM/SMS/Form/Schedule.tpl @@ -24,7 +24,7 @@ </div> <div class="description">{ts}Set a date and time when you want CiviSMS to start sending this Mass SMS.{/ts}</div> </div> -<div class="crm-submit-buttons">{include file="CRM/common/formButtons.tpl"}</div> +<div class="crm-submit-buttons">{include file="CRM/common/formButtons.tpl" location=''}</div> {if $preview} <div class="crm-accordion-wrapper crm-plain_text_sms-accordion collapsed"> diff --git a/civicrm/templates/CRM/SMS/Form/Upload.tpl b/civicrm/templates/CRM/SMS/Form/Upload.tpl index 617b079582..c9b425d4c5 100644 --- a/civicrm/templates/CRM/SMS/Form/Upload.tpl +++ b/civicrm/templates/CRM/SMS/Form/Upload.tpl @@ -40,7 +40,7 @@ </table> </fieldset> - <div class="crm-submit-buttons">{include file="CRM/common/formButtons.tpl"}</div> + <div class="crm-submit-buttons">{include file="CRM/common/formButtons.tpl" location=''}</div> </div><!-- / .crm-form-block --> {* -- Javascript for showing/hiding the upload/compose options -- *} diff --git a/civicrm/templates/CRM/UF/Form/Preview.tpl b/civicrm/templates/CRM/UF/Form/Preview.tpl index 5d01c52e83..056c2b278f 100644 --- a/civicrm/templates/CRM/UF/Form/Preview.tpl +++ b/civicrm/templates/CRM/UF/Form/Preview.tpl @@ -40,6 +40,6 @@ {/if} {* fields array is not empty *} <div class="crm-submit-buttons"> - {include file="CRM/common/formButtons.tpl"} + {include file="CRM/common/formButtons.tpl" location=''} </div> </div> diff --git a/civicrm/templates/CRM/common/formButtons.tpl b/civicrm/templates/CRM/common/formButtons.tpl index 649739f574..be89d454e1 100644 --- a/civicrm/templates/CRM/common/formButtons.tpl +++ b/civicrm/templates/CRM/common/formButtons.tpl @@ -30,7 +30,7 @@ {foreach from=$form.buttons item=button key=key name=btns} {if $key|substring:0:4 EQ '_qf_'} - {if !empty($location)} + {if $location} {$form.buttons.$key.html|crmReplace:id:"$key-$location"} {else} {$form.buttons.$key.html} diff --git a/civicrm/templates/CRM/common/success.tpl b/civicrm/templates/CRM/common/success.tpl index 4ebd3f19c1..2fdc0b5eb2 100644 --- a/civicrm/templates/CRM/common/success.tpl +++ b/civicrm/templates/CRM/common/success.tpl @@ -48,10 +48,6 @@ </p> </div> <p><span class="crm-status-icon success"> </span>{$message}</p> - {if !empty($afterUpgradeMessage)} - <h3>{ts}Important Notes{/ts}</h3> - <p>{$afterUpgradeMessage}</p> - {/if} <p><a href="{crmURL p='civicrm/dashboard' q='reset=1'}" title="{ts}CiviCRM home page{/ts}" style="text-decoration: underline;">{ts}Return to CiviCRM home page.{/ts}</a></p> </div> {/if} diff --git a/civicrm/vendor/autoload.php b/civicrm/vendor/autoload.php index e35fae40b4..38c3c6e530 100644 --- a/civicrm/vendor/autoload.php +++ b/civicrm/vendor/autoload.php @@ -4,4 +4,4 @@ require_once __DIR__ . '/composer/autoload_real.php'; -return ComposerAutoloaderInit85641ecafad0fd91a9bd9d9f47db5e32::getLoader(); +return ComposerAutoloaderInite1ca47ea801818fa75d60df4388c9f11::getLoader(); diff --git a/civicrm/vendor/cache/integration-tests/.gitignore b/civicrm/vendor/cache/integration-tests/.gitignore deleted file mode 100755 index 77bed77d04..0000000000 --- a/civicrm/vendor/cache/integration-tests/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -.phpunit.result.cache -composer.lock -vendor diff --git a/civicrm/vendor/cache/integration-tests/.travis.yml b/civicrm/vendor/cache/integration-tests/.travis.yml deleted file mode 100644 index 52786a2a76..0000000000 --- a/civicrm/vendor/cache/integration-tests/.travis.yml +++ /dev/null @@ -1,45 +0,0 @@ -dist: trusty -language: php -sudo: true - -env: - global: - - SYMFONY_PHPUNIT_VERSION=5.7 - -matrix: - fast_finish: true - include: - - php: 7.0 - env: SUITE=PHPCache - - php: 7.0 - env: SUITE=Symfony - - php: 7.0 - env: SUITE=Laravel - - php: 7.0 - env: SUITE=Stash - - php: 7.1 - env: SUITE=PHPCache - - php: 7.2 - env: SUITE=PHPCache - allow_failures: - - env: SUITE=Stash - -services: - - redis - - memcached - -cache: - directories: - - "$HOME/.composer/cache" - -before_install: - - echo "Disable xdebug" && phpenv config-rm xdebug.ini - -install: - - echo "extension = memcached.so" >> ~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/travis.ini - - echo "extension = redis.so" >> ~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/travis.ini - - composer update --prefer-source - -script: - - ./vendor/bin/simple-phpunit --testsuite $SUITE - diff --git a/civicrm/vendor/cache/integration-tests/LICENSE b/civicrm/vendor/cache/integration-tests/LICENSE deleted file mode 100755 index f166f6e87e..0000000000 --- a/civicrm/vendor/cache/integration-tests/LICENSE +++ /dev/null @@ -1,22 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2015 Aaron Scherer - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - diff --git a/civicrm/vendor/cache/integration-tests/README.md b/civicrm/vendor/cache/integration-tests/README.md deleted file mode 100644 index d8c4901b4d..0000000000 --- a/civicrm/vendor/cache/integration-tests/README.md +++ /dev/null @@ -1,58 +0,0 @@ -# PSR-6 and PSR-16 Integration tests -[](https://gitter.im/php-cache/cache?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) -[](https://packagist.org/packages/cache/integration-tests) -[](https://packagist.org/packages/cache/integration-tests) -[](https://packagist.org/packages/cache/integration-tests) -[](LICENSE) - -This repository contains integration tests to make sure your implementation of a PSR-6 and/or PSR-16 cache follows the rules by PHP-FIG. -It is a part of the PHP Cache organisation. To read about us please read the shared documentation at [www.php-cache.com](http://www.php-cache.com). - -### Install - -```bash -composer require --dev cache/integration-tests:dev-master -``` - -### Use - -Create a test that looks like this: - -```php -class PoolIntegrationTest extends CachePoolTest -{ - public function createCachePool() - { - return new CachePool(); - } -} -``` - -You could also test your tag implementation: - -```php -class TagIntegrationTest extends TaggableCachePoolTest -{ - public function createCachePool() - { - return new CachePool(); - } -} -``` - -You can also test a PSR-16 implementation: - -```php -class CacheIntegrationTest extends SimpleCacheTest -{ - public function createSimpleCache() - { - return new SimpleCache(); - } -} -``` - -### Contribute - -Contributions are very welcome! Send a pull request or -report any issues you find on the [issue tracker](http://issues.php-cache.com). diff --git a/civicrm/vendor/cache/integration-tests/composer.json b/civicrm/vendor/cache/integration-tests/composer.json deleted file mode 100755 index f242a6690d..0000000000 --- a/civicrm/vendor/cache/integration-tests/composer.json +++ /dev/null @@ -1,48 +0,0 @@ -{ - "name": "cache/integration-tests", - "type": "library", - "description": "Integration tests for PSR-6 and PSR-16 cache implementations", - "keywords": [ - "cache", - "psr6", - "psr16", - "test" - ], - "homepage": "https://github.com/php-cache/integration-tests", - "license": "MIT", - "authors": [ - { - "name": "Aaron Scherer", - "email": "aequasi@gmail.com", - "homepage": "https://github.com/aequasi" - }, - { - "name": "Tobias Nyholm", - "email": "tobias.nyholm@gmail.com", - "homepage": "https://github.com/nyholm" - } - ], - "require": { - "php": ">=5.5.9", - "psr/cache": "~1.0", - "cache/tag-interop": "^1.0" - }, - "require-dev": { - "cache/cache": "^1.0", - "symfony/cache": "^3.4.31|^4.3.4|^5.0", - "symfony/phpunit-bridge": "^5.1", - "illuminate/cache": "^5.4|^5.5|^5.6", - "tedivm/stash": "^0.14", - "mockery/mockery": "^1.0" - }, - "conflict": { - "phpunit/phpunit": "<4.8.35|<5.4.3,>=5.0" - }, - "autoload": { - "psr-4": { - "Cache\\IntegrationTests\\": "src/" - } - }, - "minimum-stability": "dev", - "prefer-stable": true -} diff --git a/civicrm/vendor/cache/integration-tests/phpunit.xml.dist b/civicrm/vendor/cache/integration-tests/phpunit.xml.dist deleted file mode 100644 index d2c2c2abcb..0000000000 --- a/civicrm/vendor/cache/integration-tests/phpunit.xml.dist +++ /dev/null @@ -1,63 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> - -<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/4.8/phpunit.xsd" - backupGlobals="false" - backupStaticAttributes="false" - colors="true" - convertErrorsToExceptions="true" - convertNoticesToExceptions="true" - convertWarningsToExceptions="true" - processIsolation="false" - stopOnFailure="false" - syntaxCheck="false" - bootstrap="vendor/autoload.php" - > - <testsuites> - <testsuite name="PHPCache"> - <directory>./vendor/cache/cache/src/Adapter/Redis/Tests/</directory> - <directory>./vendor/cache/cache/src/Bridge/SimpleCache/Tests/</directory> - </testsuite> - - <testsuite name="Laravel"> - <directory>./vendor/cache/cache/src/Adapter/Illuminate/Tests/</directory> - </testsuite> - - <testsuite name="Symfony"> - <file>./vendor/symfony/cache/Tests/Adapter/FilesystemAdapterTest.php</file> - </testsuite> - - <testsuite name="Stash"> - <file>./tests/StashTest.php</file> - </testsuite> - </testsuites> - - <filter> - <whitelist> - <directory>./</directory> - <exclude> - <directory>./Tests</directory> - <directory>./vendor</directory> - </exclude> - </whitelist> - </filter> - - <listeners> - <listener class="Symfony\Bridge\PhpUnit\SymfonyTestsListener"> - <arguments> - <array> - <element key="time-sensitive"> - <array> - <element key="0"><string>Cache\IntegrationTests</string></element> - <element key="2"><string>Symfony\Component\Cache</string></element> - <element key="3"><string>Symfony\Component\Cache\Tests\Fixtures</string></element> - <element key="4"><string>Symfony\Component\Cache\Tests\Traits</string></element> - <element key="5"><string>Symfony\Component\Cache\Traits</string></element> - </array> - </element> - </array> - </arguments> - </listener> - </listeners> - -</phpunit> diff --git a/civicrm/vendor/cache/integration-tests/src/CachePoolTest.php b/civicrm/vendor/cache/integration-tests/src/CachePoolTest.php deleted file mode 100644 index e5cb3e0a86..0000000000 --- a/civicrm/vendor/cache/integration-tests/src/CachePoolTest.php +++ /dev/null @@ -1,874 +0,0 @@ -<?php - -/* - * This file is part of php-cache organization. - * - * (c) 2015-2015 Aaron Scherer <aequasi@gmail.com>, Tobias Nyholm <tobias.nyholm@gmail.com> - * - * This source file is subject to the MIT license that is bundled - * with this source code in the file LICENSE. - */ - -namespace Cache\IntegrationTests; - -use PHPUnit\Framework\TestCase; -use Psr\Cache\CacheItemInterface; -use Psr\Cache\CacheItemPoolInterface; - -abstract class CachePoolTest extends TestCase -{ - /** - * @type array with functionName => reason. - */ - protected $skippedTests = []; - - /** - * @type CacheItemPoolInterface - */ - protected $cache; - - /** - * @return CacheItemPoolInterface that is used in the tests - */ - abstract public function createCachePool(); - - /** - * @before - */ - public function setupService() - { - $this->cache = $this->createCachePool(); - } - - /** - * @after - */ - public function tearDownService() - { - if ($this->cache !== null) { - $this->cache->clear(); - } - } - - /** - * Data provider for invalid keys. - * - * @return array - */ - public static function invalidKeys() - { - return [ - [true], - [false], - [null], - [2], - [2.5], - ['{str'], - ['rand{'], - ['rand{str'], - ['rand}str'], - ['rand(str'], - ['rand)str'], - ['rand/str'], - ['rand\\str'], - ['rand@str'], - ['rand:str'], - [new \stdClass()], - [['array']], - ]; - } - - public function testBasicUsage() - { - if (isset($this->skippedTests[__FUNCTION__])) { - $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - } - - $item = $this->cache->getItem('key'); - $item->set('4711'); - $this->cache->save($item); - - $item = $this->cache->getItem('key2'); - $item->set('4712'); - $this->cache->save($item); - - $fooItem = $this->cache->getItem('key'); - $this->assertTrue($fooItem->isHit()); - $this->assertEquals('4711', $fooItem->get()); - - $barItem = $this->cache->getItem('key2'); - $this->assertTrue($barItem->isHit()); - $this->assertEquals('4712', $barItem->get()); - - // Remove 'key' and make sure 'key2' is still there - $this->cache->deleteItem('key'); - $this->assertFalse($this->cache->getItem('key')->isHit()); - $this->assertTrue($this->cache->getItem('key2')->isHit()); - - // Remove everything - $this->cache->clear(); - $this->assertFalse($this->cache->getItem('key')->isHit()); - $this->assertFalse($this->cache->getItem('key2')->isHit()); - } - - public function testBasicUsageWithLongKey() - { - if (isset($this->skippedTests[__FUNCTION__])) { - $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - } - - $pool = $this->createCachePool(); - - $key = str_repeat('a', 300); - - $item = $pool->getItem($key); - $this->assertFalse($item->isHit()); - $this->assertSame($key, $item->getKey()); - - $item->set('value'); - $this->assertTrue($pool->save($item)); - - $item = $pool->getItem($key); - $this->assertTrue($item->isHit()); - $this->assertSame($key, $item->getKey()); - $this->assertSame('value', $item->get()); - - $this->assertTrue($pool->deleteItem($key)); - - $item = $pool->getItem($key); - $this->assertFalse($item->isHit()); - } - - public function testItemModifiersReturnsStatic() - { - if (isset($this->skippedTests[__FUNCTION__])) { - $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - } - - $item = $this->cache->getItem('key'); - $this->assertSame($item, $item->set('4711')); - $this->assertSame($item, $item->expiresAfter(2)); - $this->assertSame($item, $item->expiresAt(new \DateTime('+2hours'))); - } - - public function testGetItem() - { - if (isset($this->skippedTests[__FUNCTION__])) { - $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - } - - $item = $this->cache->getItem('key'); - $item->set('value'); - $this->cache->save($item); - - // get existing item - $item = $this->cache->getItem('key'); - $this->assertEquals('value', $item->get(), 'A stored item must be returned from cached.'); - $this->assertEquals('key', $item->getKey(), 'Cache key can not change.'); - - // get non-existent item - $item = $this->cache->getItem('key2'); - $this->assertFalse($item->isHit()); - $this->assertNull($item->get(), "Item's value must be null when isHit is false."); - } - - public function testGetItems() - { - if (isset($this->skippedTests[__FUNCTION__])) { - $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - } - - $keys = ['foo', 'bar', 'baz']; - $items = $this->cache->getItems($keys); - - $count = 0; - - /** @type CacheItemInterface $item */ - foreach ($items as $i => $item) { - $item->set($i); - $this->cache->save($item); - - $count++; - } - - $this->assertSame(3, $count); - - $keys[] = 'biz'; - /** @type CacheItemInterface[] $items */ - $items = $this->cache->getItems($keys); - $count = 0; - foreach ($items as $key => $item) { - $itemKey = $item->getKey(); - $this->assertEquals($itemKey, $key, 'Keys must be preserved when fetching multiple items'); - $this->assertEquals($key !== 'biz', $item->isHit()); - $this->assertTrue(in_array($key, $keys), 'Cache key can not change.'); - - // Remove $key for $keys - foreach ($keys as $k => $v) { - if ($v === $key) { - unset($keys[$k]); - } - } - - $count++; - } - - $this->assertSame(4, $count); - } - - public function testGetItemsEmpty() - { - if (isset($this->skippedTests[__FUNCTION__])) { - $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - } - - $items = $this->cache->getItems([]); - $this->assertTrue( - is_array($items) || $items instanceof \Traversable, - 'A call to getItems with an empty array must always return an array or \Traversable.' - ); - - $count = 0; - foreach ($items as $item) { - $count++; - } - - $this->assertSame(0, $count); - } - - public function testHasItem() - { - if (isset($this->skippedTests[__FUNCTION__])) { - $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - } - - $item = $this->cache->getItem('key'); - $item->set('value'); - $this->cache->save($item); - - // has existing item - $this->assertTrue($this->cache->hasItem('key')); - - // has non-existent item - $this->assertFalse($this->cache->hasItem('key2')); - } - - public function testClear() - { - if (isset($this->skippedTests[__FUNCTION__])) { - $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - } - - $item = $this->cache->getItem('key'); - $item->set('value'); - $this->cache->save($item); - - $return = $this->cache->clear(); - - $this->assertTrue($return, 'clear() must return true if cache was cleared. '); - $this->assertFalse($this->cache->getItem('key')->isHit(), 'No item should be a hit after the cache is cleared. '); - $this->assertFalse($this->cache->hasItem('key2'), 'The cache pool should be empty after it is cleared.'); - } - - public function testClearWithDeferredItems() - { - if (isset($this->skippedTests[__FUNCTION__])) { - $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - } - - $item = $this->cache->getItem('key'); - $item->set('value'); - $this->cache->saveDeferred($item); - - $this->cache->clear(); - $this->cache->commit(); - - $this->assertFalse($this->cache->getItem('key')->isHit(), 'Deferred items must be cleared on clear(). '); - } - - public function testDeleteItem() - { - if (isset($this->skippedTests[__FUNCTION__])) { - $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - } - - $item = $this->cache->getItem('key'); - $item->set('value'); - $this->cache->save($item); - - $this->assertTrue($this->cache->deleteItem('key')); - $this->assertFalse($this->cache->getItem('key')->isHit(), 'A deleted item should not be a hit.'); - $this->assertFalse($this->cache->hasItem('key'), 'A deleted item should not be a in cache.'); - - $this->assertTrue($this->cache->deleteItem('key2'), 'Deleting an item that does not exist should return true.'); - } - - public function testDeleteItems() - { - if (isset($this->skippedTests[__FUNCTION__])) { - $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - } - - $items = $this->cache->getItems(['foo', 'bar', 'baz']); - - /** @type CacheItemInterface $item */ - foreach ($items as $idx => $item) { - $item->set($idx); - $this->cache->save($item); - } - - // All should be a hit but 'biz' - $this->assertTrue($this->cache->getItem('foo')->isHit()); - $this->assertTrue($this->cache->getItem('bar')->isHit()); - $this->assertTrue($this->cache->getItem('baz')->isHit()); - $this->assertFalse($this->cache->getItem('biz')->isHit()); - - $return = $this->cache->deleteItems(['foo', 'bar', 'biz']); - $this->assertTrue($return); - - $this->assertFalse($this->cache->getItem('foo')->isHit()); - $this->assertFalse($this->cache->getItem('bar')->isHit()); - $this->assertTrue($this->cache->getItem('baz')->isHit()); - $this->assertFalse($this->cache->getItem('biz')->isHit()); - } - - public function testSave() - { - if (isset($this->skippedTests[__FUNCTION__])) { - $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - } - - $item = $this->cache->getItem('key'); - $item->set('value'); - $return = $this->cache->save($item); - - $this->assertTrue($return, 'save() should return true when items are saved.'); - $this->assertEquals('value', $this->cache->getItem('key')->get()); - } - - public function testSaveExpired() - { - if (isset($this->skippedTests[__FUNCTION__])) { - $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - } - - $item = $this->cache->getItem('key'); - $item->set('value'); - $item->expiresAt(\DateTime::createFromFormat('U', time() + 10)); - $this->cache->save($item); - $item->expiresAt(\DateTime::createFromFormat('U', time() - 1)); - $this->cache->save($item); - $item = $this->cache->getItem('key'); - $this->assertFalse($item->isHit(), 'Cache should not save expired items'); - } - - public function testSaveWithoutExpire() - { - if (isset($this->skippedTests[__FUNCTION__])) { - $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - } - - $item = $this->cache->getItem('test_ttl_null'); - $item->set('data'); - $this->cache->save($item); - - // Use a new pool instance to ensure that we don't hit any caches - $pool = $this->createCachePool(); - $item = $pool->getItem('test_ttl_null'); - - $this->assertTrue($item->isHit(), 'Cache should have retrieved the items'); - $this->assertEquals('data', $item->get()); - } - - public function testDeferredSave() - { - if (isset($this->skippedTests[__FUNCTION__])) { - $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - } - - $item = $this->cache->getItem('key'); - $item->set('4711'); - $return = $this->cache->saveDeferred($item); - $this->assertTrue($return, 'save() should return true when items are saved.'); - - $item = $this->cache->getItem('key2'); - $item->set('4712'); - $this->cache->saveDeferred($item); - - // They are not saved yet but should be a hit - $this->assertTrue($this->cache->hasItem('key'), 'Deferred items should be considered as a part of the cache even before they are committed'); - $this->assertTrue($this->cache->getItem('key')->isHit(), 'Deferred items should be a hit even before they are committed'); - $this->assertTrue($this->cache->getItem('key2')->isHit()); - - $this->cache->commit(); - - // They should be a hit after the commit as well - $this->assertTrue($this->cache->getItem('key')->isHit()); - $this->assertTrue($this->cache->getItem('key2')->isHit()); - } - - public function testDeferredExpired() - { - if (isset($this->skippedTests[__FUNCTION__])) { - $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - } - - $item = $this->cache->getItem('key'); - $item->set('4711'); - $item->expiresAt(\DateTime::createFromFormat('U', time() - 1)); - $this->cache->saveDeferred($item); - - $this->assertFalse($this->cache->hasItem('key'), 'Cache should not have expired deferred item'); - $this->cache->commit(); - $item = $this->cache->getItem('key'); - $this->assertFalse($item->isHit(), 'Cache should not save expired items'); - } - - public function testDeleteDeferredItem() - { - if (isset($this->skippedTests[__FUNCTION__])) { - $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - } - - $item = $this->cache->getItem('key'); - $item->set('4711'); - $this->cache->saveDeferred($item); - $this->assertTrue($this->cache->getItem('key')->isHit()); - - $this->cache->deleteItem('key'); - $this->assertFalse($this->cache->hasItem('key'), 'You must be able to delete a deferred item before committed. '); - $this->assertFalse($this->cache->getItem('key')->isHit(), 'You must be able to delete a deferred item before committed. '); - - $this->cache->commit(); - $this->assertFalse($this->cache->hasItem('key'), 'A deleted item should not reappear after commit. '); - $this->assertFalse($this->cache->getItem('key')->isHit(), 'A deleted item should not reappear after commit. '); - } - - public function testDeferredSaveWithoutCommit() - { - if (isset($this->skippedTests[__FUNCTION__])) { - $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - } - - $this->prepareDeferredSaveWithoutCommit(); - gc_collect_cycles(); - - $cache = $this->createCachePool(); - $this->assertTrue($cache->getItem('key')->isHit(), 'A deferred item should automatically be committed on CachePool::__destruct().'); - } - - private function prepareDeferredSaveWithoutCommit() - { - $cache = $this->cache; - $this->cache = null; - - $item = $cache->getItem('key'); - $item->set('4711'); - $cache->saveDeferred($item); - } - - public function testCommit() - { - if (isset($this->skippedTests[__FUNCTION__])) { - $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - } - - $item = $this->cache->getItem('key'); - $item->set('value'); - $this->cache->saveDeferred($item); - $return = $this->cache->commit(); - - $this->assertTrue($return, 'commit() should return true on successful commit. '); - $this->assertEquals('value', $this->cache->getItem('key')->get()); - - $return = $this->cache->commit(); - $this->assertTrue($return, 'commit() should return true even if no items were deferred. '); - } - - /** - * @medium - */ - public function testExpiration() - { - if (isset($this->skippedTests[__FUNCTION__])) { - $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - } - - $item = $this->cache->getItem('key'); - $item->set('value'); - $item->expiresAfter(2); - $this->cache->save($item); - - sleep(3); - $item = $this->cache->getItem('key'); - $this->assertFalse($item->isHit()); - $this->assertNull($item->get(), "Item's value must be null when isHit() is false."); - } - - public function testExpiresAt() - { - if (isset($this->skippedTests[__FUNCTION__])) { - $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - } - - $item = $this->cache->getItem('key'); - $item->set('value'); - $item->expiresAt(new \DateTime('+2hours')); - $this->cache->save($item); - - $item = $this->cache->getItem('key'); - $this->assertTrue($item->isHit()); - } - - public function testExpiresAtWithNull() - { - if (isset($this->skippedTests[__FUNCTION__])) { - $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - } - - $item = $this->cache->getItem('key'); - $item->set('value'); - $item->expiresAt(null); - $this->cache->save($item); - - $item = $this->cache->getItem('key'); - $this->assertTrue($item->isHit()); - } - - public function testExpiresAfterWithNull() - { - if (isset($this->skippedTests[__FUNCTION__])) { - $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - } - - $item = $this->cache->getItem('key'); - $item->set('value'); - $item->expiresAfter(null); - $this->cache->save($item); - - $item = $this->cache->getItem('key'); - $this->assertTrue($item->isHit()); - } - - public function testKeyLength() - { - if (isset($this->skippedTests[__FUNCTION__])) { - $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - } - - $key = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_.'; - $item = $this->cache->getItem($key); - $item->set('value'); - $this->assertTrue($this->cache->save($item), 'The implementation does not support a valid cache key'); - - $this->assertTrue($this->cache->hasItem($key)); - } - - /** - * @dataProvider invalidKeys - */ - public function testGetItemInvalidKeys($key) - { - if (isset($this->skippedTests[__FUNCTION__])) { - $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - } - - $this->expectException('Psr\Cache\InvalidArgumentException'); - $this->cache->getItem($key); - } - - /** - * @dataProvider invalidKeys - */ - public function testGetItemsInvalidKeys($key) - { - if (isset($this->skippedTests[__FUNCTION__])) { - $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - } - - $this->expectException('Psr\Cache\InvalidArgumentException'); - $this->cache->getItems(['key1', $key, 'key2']); - } - - /** - * @dataProvider invalidKeys - */ - public function testHasItemInvalidKeys($key) - { - if (isset($this->skippedTests[__FUNCTION__])) { - $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - } - - $this->expectException('Psr\Cache\InvalidArgumentException'); - $this->cache->hasItem($key); - } - - /** - * @dataProvider invalidKeys - */ - public function testDeleteItemInvalidKeys($key) - { - if (isset($this->skippedTests[__FUNCTION__])) { - $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - } - - $this->expectException('Psr\Cache\InvalidArgumentException'); - $this->cache->deleteItem($key); - } - - /** - * @dataProvider invalidKeys - */ - public function testDeleteItemsInvalidKeys($key) - { - if (isset($this->skippedTests[__FUNCTION__])) { - $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - } - - $this->expectException('Psr\Cache\InvalidArgumentException'); - $this->cache->deleteItems(['key1', $key, 'key2']); - } - - public function testDataTypeString() - { - if (isset($this->skippedTests[__FUNCTION__])) { - $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - } - - $item = $this->cache->getItem('key'); - $item->set('5'); - $this->cache->save($item); - - $item = $this->cache->getItem('key'); - $this->assertTrue('5' === $item->get(), 'Wrong data type. If we store a string we must get an string back.'); - $this->assertTrue(is_string($item->get()), 'Wrong data type. If we store a string we must get an string back.'); - } - - public function testDataTypeInteger() - { - if (isset($this->skippedTests[__FUNCTION__])) { - $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - } - - $item = $this->cache->getItem('key'); - $item->set(5); - $this->cache->save($item); - - $item = $this->cache->getItem('key'); - $this->assertTrue(5 === $item->get(), 'Wrong data type. If we store an int we must get an int back.'); - $this->assertTrue(is_int($item->get()), 'Wrong data type. If we store an int we must get an int back.'); - } - - public function testDataTypeNull() - { - if (isset($this->skippedTests[__FUNCTION__])) { - $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - } - - $item = $this->cache->getItem('key'); - $item->set(null); - $this->cache->save($item); - - $this->assertTrue($this->cache->hasItem('key'), 'Null is a perfectly fine cache value. hasItem() should return true when null are stored. '); - $item = $this->cache->getItem('key'); - $this->assertTrue(null === $item->get(), 'Wrong data type. If we store null we must get an null back.'); - $this->assertTrue(is_null($item->get()), 'Wrong data type. If we store null we must get an null back.'); - $this->assertTrue($item->isHit(), 'isHit() should return true when null are stored. '); - } - - public function testDataTypeFloat() - { - if (isset($this->skippedTests[__FUNCTION__])) { - $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - } - - $float = 1.23456789; - $item = $this->cache->getItem('key'); - $item->set($float); - $this->cache->save($item); - - $item = $this->cache->getItem('key'); - $this->assertTrue(is_float($item->get()), 'Wrong data type. If we store float we must get an float back.'); - $this->assertEquals($float, $item->get()); - $this->assertTrue($item->isHit(), 'isHit() should return true when float are stored. '); - } - - public function testDataTypeBoolean() - { - if (isset($this->skippedTests[__FUNCTION__])) { - $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - } - - $item = $this->cache->getItem('key'); - $item->set(true); - $this->cache->save($item); - - $item = $this->cache->getItem('key'); - $this->assertTrue(is_bool($item->get()), 'Wrong data type. If we store boolean we must get an boolean back.'); - $this->assertTrue($item->get()); - $this->assertTrue($item->isHit(), 'isHit() should return true when true are stored. '); - } - - public function testDataTypeArray() - { - if (isset($this->skippedTests[__FUNCTION__])) { - $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - } - - $array = ['a' => 'foo', 2 => 'bar']; - $item = $this->cache->getItem('key'); - $item->set($array); - $this->cache->save($item); - - $item = $this->cache->getItem('key'); - $this->assertTrue(is_array($item->get()), 'Wrong data type. If we store array we must get an array back.'); - $this->assertEquals($array, $item->get()); - $this->assertTrue($item->isHit(), 'isHit() should return true when array are stored. '); - } - - public function testDataTypeObject() - { - if (isset($this->skippedTests[__FUNCTION__])) { - $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - } - - $object = new \stdClass(); - $object->a = 'foo'; - $item = $this->cache->getItem('key'); - $item->set($object); - $this->cache->save($item); - - $item = $this->cache->getItem('key'); - $this->assertTrue(is_object($item->get()), 'Wrong data type. If we store object we must get an object back.'); - $this->assertEquals($object, $item->get()); - $this->assertTrue($item->isHit(), 'isHit() should return true when object are stored. '); - } - - public function testBinaryData() - { - if (isset($this->skippedTests[__FUNCTION__])) { - $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - } - - $data = ''; - for ($i = 0; $i < 256; $i++) { - $data .= chr($i); - } - - $item = $this->cache->getItem('key'); - $item->set($data); - $this->cache->save($item); - - $item = $this->cache->getItem('key'); - $this->assertTrue($data === $item->get(), 'Binary data must survive a round trip.'); - } - - public function testIsHit() - { - if (isset($this->skippedTests[__FUNCTION__])) { - $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - } - - $item = $this->cache->getItem('key'); - $item->set('value'); - $this->cache->save($item); - - $item = $this->cache->getItem('key'); - $this->assertTrue($item->isHit()); - } - - public function testIsHitDeferred() - { - if (isset($this->skippedTests[__FUNCTION__])) { - $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - } - - $item = $this->cache->getItem('key'); - $item->set('value'); - $this->cache->saveDeferred($item); - - // Test accessing the value before it is committed - $item = $this->cache->getItem('key'); - $this->assertTrue($item->isHit()); - - $this->cache->commit(); - $item = $this->cache->getItem('key'); - $this->assertTrue($item->isHit()); - } - - public function testSaveDeferredWhenChangingValues() - { - if (isset($this->skippedTests[__FUNCTION__])) { - $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - } - - $item = $this->cache->getItem('key'); - $item->set('value'); - $this->cache->saveDeferred($item); - - $item = $this->cache->getItem('key'); - $item->set('new value'); - - $item = $this->cache->getItem('key'); - $this->assertEquals('value', $item->get(), 'Items that is put in the deferred queue should not get their values changed'); - - $this->cache->commit(); - $item = $this->cache->getItem('key'); - $this->assertEquals('value', $item->get(), 'Items that is put in the deferred queue should not get their values changed'); - } - - public function testSaveDeferredOverwrite() - { - if (isset($this->skippedTests[__FUNCTION__])) { - $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - } - - $item = $this->cache->getItem('key'); - $item->set('value'); - $this->cache->saveDeferred($item); - - $item = $this->cache->getItem('key'); - $item->set('new value'); - $this->cache->saveDeferred($item); - - $item = $this->cache->getItem('key'); - $this->assertEquals('new value', $item->get()); - - $this->cache->commit(); - $item = $this->cache->getItem('key'); - $this->assertEquals('new value', $item->get()); - } - - public function testSavingObject() - { - if (isset($this->skippedTests[__FUNCTION__])) { - $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - } - - $item = $this->cache->getItem('key'); - $item->set(new \DateTime()); - $this->cache->save($item); - - $item = $this->cache->getItem('key'); - $value = $item->get(); - $this->assertInstanceOf('DateTime', $value, 'You must be able to store objects in cache.'); - } - - /** - * @medium - */ - public function testHasItemReturnsFalseWhenDeferredItemIsExpired() - { - if (isset($this->skippedTests[__FUNCTION__])) { - $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - } - - $item = $this->cache->getItem('key'); - $item->set('value'); - $item->expiresAfter(2); - $this->cache->saveDeferred($item); - - sleep(3); - $this->assertFalse($this->cache->hasItem('key')); - } -} diff --git a/civicrm/vendor/cache/integration-tests/src/HierarchicalCachePoolTest.php b/civicrm/vendor/cache/integration-tests/src/HierarchicalCachePoolTest.php deleted file mode 100644 index 7413d1ea18..0000000000 --- a/civicrm/vendor/cache/integration-tests/src/HierarchicalCachePoolTest.php +++ /dev/null @@ -1,150 +0,0 @@ -<?php - -/* - * This file is part of php-cache organization. - * - * (c) 2015-2015 Aaron Scherer <aequasi@gmail.com>, Tobias Nyholm <tobias.nyholm@gmail.com> - * - * This source file is subject to the MIT license that is bundled - * with this source code in the file LICENSE. - */ - -namespace Cache\IntegrationTests; - -use PHPUnit\Framework\TestCase; -use Psr\Cache\CacheItemPoolInterface; - -/** - * @author Tobias Nyholm <tobias.nyholm@gmail.com> - */ -abstract class HierarchicalCachePoolTest extends TestCase -{ - /** - * @type array with functionName => reason. - */ - protected $skippedTests = []; - - /** - * @type CacheItemPoolInterface - */ - protected $cache; - - /** - * @return CacheItemPoolInterface that is used in the tests - */ - abstract public function createCachePool(); - - /** - * @before - */ - public function setupService() - { - $this->cache = $this->createCachePool(); - } - - /** - * @after - */ - public function tearDownService() - { - if ($this->cache !== null) { - $this->cache->clear(); - } - } - - public function testBasicUsage() - { - if (isset($this->skippedTests[__FUNCTION__])) { - $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - } - - $user = 4711; - for ($i = 0; $i < 10; $i++) { - $item = $this->cache->getItem(sprintf('|users|%d|followers|%d|likes', $user, $i)); - $item->set('Justin Bieber'); - $this->cache->save($item); - } - - $this->assertTrue($this->cache->hasItem('|users|4711|followers|4|likes')); - $this->cache->deleteItem('|users|4711|followers'); - $this->assertFalse($this->cache->hasItem('|users|4711|followers|4|likes')); - } - - public function testChain() - { - if (isset($this->skippedTests[__FUNCTION__])) { - $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - } - - $item = $this->cache->getItem('|aaa|bbb|ccc|ddd'); - $item->set('value'); - $this->cache->save($item); - - $item = $this->cache->getItem('|aaa|bbb|ccc|xxx'); - $item->set('value'); - $this->cache->save($item); - - $item = $this->cache->getItem('|aaa|bbb|zzz|ddd'); - $item->set('value'); - $this->cache->save($item); - - $this->assertTrue($this->cache->hasItem('|aaa|bbb|ccc|ddd')); - $this->assertTrue($this->cache->hasItem('|aaa|bbb|ccc|xxx')); - $this->assertTrue($this->cache->hasItem('|aaa|bbb|zzz|ddd')); - $this->assertFalse($this->cache->hasItem('|aaa|bbb|ccc')); - $this->assertFalse($this->cache->hasItem('|aaa|bbb|zzz')); - $this->assertFalse($this->cache->hasItem('|aaa|bbb')); - $this->assertFalse($this->cache->hasItem('|aaa')); - $this->assertFalse($this->cache->hasItem('|')); - - // This is a different thing - $this->cache->deleteItem('|aaa|bbb|cc'); - $this->assertTrue($this->cache->hasItem('|aaa|bbb|ccc|ddd')); - $this->assertTrue($this->cache->hasItem('|aaa|bbb|ccc|xxx')); - $this->assertTrue($this->cache->hasItem('|aaa|bbb|zzz|ddd')); - - $this->cache->deleteItem('|aaa|bbb|ccc'); - $this->assertFalse($this->cache->hasItem('|aaa|bbb|ccc|ddd')); - $this->assertFalse($this->cache->hasItem('|aaa|bbb|ccc|xxx')); - $this->assertTrue($this->cache->hasItem('|aaa|bbb|zzz|ddd')); - - $this->cache->deleteItem('|aaa'); - $this->assertFalse($this->cache->hasItem('|aaa|bbb|zzz|ddd')); - } - - public function testRemoval() - { - if (isset($this->skippedTests[__FUNCTION__])) { - $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - } - - $item = $this->cache->getItem('foo'); - $item->set('value'); - $this->cache->save($item); - - $item = $this->cache->getItem('|aaa|bbb'); - $item->set('value'); - $this->cache->save($item); - - $this->cache->deleteItem('|'); - $this->assertFalse($this->cache->hasItem('|aaa|bbb'), 'Hierarchy items should be removed when deleting root'); - $this->assertTrue($this->cache->hasItem('foo'), 'All cache should not be cleared when deleting root'); - } - - public function testRemovalWhenDeferred() - { - if (isset($this->skippedTests[__FUNCTION__])) { - $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - } - - $item = $this->cache->getItem('|aaa|bbb'); - $item->set('value'); - $this->cache->saveDeferred($item); - - $this->cache->deleteItem('|'); - $this->assertFalse($this->cache->hasItem('|aaa|bbb'), 'Deferred hierarchy items should be removed'); - - $this->cache->commit(); - $this->assertFalse($this->cache->hasItem('|aaa|bbb'), 'Deferred hierarchy items should be removed'); - } -} diff --git a/civicrm/vendor/cache/integration-tests/src/SimpleCacheTest.php b/civicrm/vendor/cache/integration-tests/src/SimpleCacheTest.php deleted file mode 100644 index 1d3216e12c..0000000000 --- a/civicrm/vendor/cache/integration-tests/src/SimpleCacheTest.php +++ /dev/null @@ -1,789 +0,0 @@ -<?php - -/* - * This file is part of php-cache organization. - * - * (c) 2015-2015 Aaron Scherer <aequasi@gmail.com>, Tobias Nyholm <tobias.nyholm@gmail.com> - * - * This source file is subject to the MIT license that is bundled - * with this source code in the file LICENSE. - */ - -namespace Cache\IntegrationTests; - -use PHPUnit\Framework\TestCase; -use Psr\SimpleCache\CacheInterface; - -abstract class SimpleCacheTest extends TestCase -{ - /** - * @type array with functionName => reason. - */ - protected $skippedTests = []; - - /** - * @type CacheInterface - */ - protected $cache; - - /** - * @return CacheInterface that is used in the tests - */ - abstract public function createSimpleCache(); - - /** - * Advance time perceived by the cache for the purposes of testing TTL. - * - * The default implementation sleeps for the specified duration, - * but subclasses are encouraged to override this, - * adjusting a mocked time possibly set up in {@link createSimpleCache()}, - * to speed up the tests. - * - * @param int $seconds - */ - public function advanceTime($seconds) - { - sleep($seconds); - } - - /** - * @before - */ - public function setupService() - { - $this->cache = $this->createSimpleCache(); - } - - /** - * @after - */ - public function tearDownService() - { - if ($this->cache !== null) { - $this->cache->clear(); - } - } - - /** - * Data provider for invalid cache keys. - * - * @return array - */ - public static function invalidKeys() - { - return array_merge( - self::invalidArrayKeys(), - [ - [2], - ] - ); - } - - /** - * Data provider for invalid array keys. - * - * @return array - */ - public static function invalidArrayKeys() - { - return [ - [''], - [true], - [false], - [null], - [2.5], - ['{str'], - ['rand{'], - ['rand{str'], - ['rand}str'], - ['rand(str'], - ['rand)str'], - ['rand/str'], - ['rand\\str'], - ['rand@str'], - ['rand:str'], - [new \stdClass()], - [['array']], - ]; - } - - /** - * @return array - */ - public static function invalidTtl() - { - return [ - [''], - [true], - [false], - ['abc'], - [2.5], - [' 1'], // can be casted to a int - ['12foo'], // can be casted to a int - ['025'], // can be interpreted as hex - [new \stdClass()], - [['array']], - ]; - } - - /** - * Data provider for valid keys. - * - * @return array - */ - public static function validKeys() - { - return [ - ['AbC19_.'], - ['1234567890123456789012345678901234567890123456789012345678901234'], - ]; - } - - /** - * Data provider for valid data to store. - * - * @return array - */ - public static function validData() - { - return [ - ['AbC19_.'], - [4711], - [47.11], - [true], - [null], - [['key' => 'value']], - [new \stdClass()], - ]; - } - - public function testSet() - { - if (isset($this->skippedTests[__FUNCTION__])) { - $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - } - - $result = $this->cache->set('key', 'value'); - $this->assertTrue($result, 'set() must return true if success'); - $this->assertEquals('value', $this->cache->get('key')); - } - - /** - * @medium - */ - public function testSetTtl() - { - if (isset($this->skippedTests[__FUNCTION__])) { - $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - } - - $result = $this->cache->set('key1', 'value', 2); - $this->assertTrue($result, 'set() must return true if success'); - $this->assertEquals('value', $this->cache->get('key1')); - - $this->cache->set('key2', 'value', new \DateInterval('PT2S')); - $this->assertEquals('value', $this->cache->get('key2')); - - $this->advanceTime(3); - - $this->assertNull($this->cache->get('key1'), 'Value must expire after ttl.'); - $this->assertNull($this->cache->get('key2'), 'Value must expire after ttl.'); - } - - public function testSetExpiredTtl() - { - if (isset($this->skippedTests[__FUNCTION__])) { - $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - } - - $this->cache->set('key0', 'value'); - $this->cache->set('key0', 'value', 0); - $this->assertNull($this->cache->get('key0')); - $this->assertFalse($this->cache->has('key0')); - - $this->cache->set('key1', 'value', -1); - $this->assertNull($this->cache->get('key1')); - $this->assertFalse($this->cache->has('key1')); - } - - public function testGet() - { - if (isset($this->skippedTests[__FUNCTION__])) { - $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - } - - $this->assertNull($this->cache->get('key')); - $this->assertEquals('foo', $this->cache->get('key', 'foo')); - - $this->cache->set('key', 'value'); - $this->assertEquals('value', $this->cache->get('key', 'foo')); - } - - public function testDelete() - { - if (isset($this->skippedTests[__FUNCTION__])) { - $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - } - - $this->assertTrue($this->cache->delete('key'), 'Deleting a value that does not exist should return true'); - $this->cache->set('key', 'value'); - $this->assertTrue($this->cache->delete('key'), 'Delete must return true on success'); - $this->assertNull($this->cache->get('key'), 'Values must be deleted on delete()'); - } - - public function testClear() - { - if (isset($this->skippedTests[__FUNCTION__])) { - $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - } - - $this->assertTrue($this->cache->clear(), 'Clearing an empty cache should return true'); - $this->cache->set('key', 'value'); - $this->assertTrue($this->cache->clear(), 'Delete must return true on success'); - $this->assertNull($this->cache->get('key'), 'Values must be deleted on clear()'); - } - - public function testSetMultiple() - { - if (isset($this->skippedTests[__FUNCTION__])) { - $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - } - - $result = $this->cache->setMultiple(['key0' => 'value0', 'key1' => 'value1']); - $this->assertTrue($result, 'setMultiple() must return true if success'); - $this->assertEquals('value0', $this->cache->get('key0')); - $this->assertEquals('value1', $this->cache->get('key1')); - } - - public function testSetMultipleWithIntegerArrayKey() - { - if (isset($this->skippedTests[__FUNCTION__])) { - $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - } - - $result = $this->cache->setMultiple(['0' => 'value0']); - $this->assertTrue($result, 'setMultiple() must return true if success'); - $this->assertEquals('value0', $this->cache->get('0')); - } - - /** - * @medium - */ - public function testSetMultipleTtl() - { - if (isset($this->skippedTests[__FUNCTION__])) { - $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - } - - $this->cache->setMultiple(['key2' => 'value2', 'key3' => 'value3'], 2); - $this->assertEquals('value2', $this->cache->get('key2')); - $this->assertEquals('value3', $this->cache->get('key3')); - - $this->cache->setMultiple(['key4' => 'value4'], new \DateInterval('PT2S')); - $this->assertEquals('value4', $this->cache->get('key4')); - - $this->advanceTime(3); - $this->assertNull($this->cache->get('key2'), 'Value must expire after ttl.'); - $this->assertNull($this->cache->get('key3'), 'Value must expire after ttl.'); - $this->assertNull($this->cache->get('key4'), 'Value must expire after ttl.'); - } - - public function testSetMultipleExpiredTtl() - { - if (isset($this->skippedTests[__FUNCTION__])) { - $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - } - - $this->cache->setMultiple(['key0' => 'value0', 'key1' => 'value1'], 0); - $this->assertNull($this->cache->get('key0')); - $this->assertNull($this->cache->get('key1')); - } - - public function testSetMultipleWithGenerator() - { - if (isset($this->skippedTests[__FUNCTION__])) { - $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - } - - $gen = function () { - yield 'key0' => 'value0'; - yield 'key1' => 'value1'; - }; - - $this->cache->setMultiple($gen()); - $this->assertEquals('value0', $this->cache->get('key0')); - $this->assertEquals('value1', $this->cache->get('key1')); - } - - public function testGetMultiple() - { - if (isset($this->skippedTests[__FUNCTION__])) { - $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - } - - $result = $this->cache->getMultiple(['key0', 'key1']); - $keys = []; - foreach ($result as $i => $r) { - $keys[] = $i; - $this->assertNull($r); - } - sort($keys); - $this->assertSame(['key0', 'key1'], $keys); - - $this->cache->set('key3', 'value'); - $result = $this->cache->getMultiple(['key2', 'key3', 'key4'], 'foo'); - $keys = []; - foreach ($result as $key => $r) { - $keys[] = $key; - if ($key === 'key3') { - $this->assertEquals('value', $r); - } else { - $this->assertEquals('foo', $r); - } - } - sort($keys); - $this->assertSame(['key2', 'key3', 'key4'], $keys); - } - - public function testGetMultipleWithGenerator() - { - if (isset($this->skippedTests[__FUNCTION__])) { - $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - } - - $gen = function () { - yield 1 => 'key0'; - yield 1 => 'key1'; - }; - - $this->cache->set('key0', 'value0'); - $result = $this->cache->getMultiple($gen()); - $keys = []; - foreach ($result as $key => $r) { - $keys[] = $key; - if ($key === 'key0') { - $this->assertEquals('value0', $r); - } elseif ($key === 'key1') { - $this->assertNull($r); - } else { - $this->assertFalse(true, 'This should not happend'); - } - } - sort($keys); - $this->assertSame(['key0', 'key1'], $keys); - $this->assertEquals('value0', $this->cache->get('key0')); - $this->assertNull($this->cache->get('key1')); - } - - public function testDeleteMultiple() - { - if (isset($this->skippedTests[__FUNCTION__])) { - $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - } - - $this->assertTrue($this->cache->deleteMultiple([]), 'Deleting a empty array should return true'); - $this->assertTrue($this->cache->deleteMultiple(['key']), 'Deleting a value that does not exist should return true'); - - $this->cache->set('key0', 'value0'); - $this->cache->set('key1', 'value1'); - $this->assertTrue($this->cache->deleteMultiple(['key0', 'key1']), 'Delete must return true on success'); - $this->assertNull($this->cache->get('key0'), 'Values must be deleted on deleteMultiple()'); - $this->assertNull($this->cache->get('key1'), 'Values must be deleted on deleteMultiple()'); - } - - public function testDeleteMultipleGenerator() - { - if (isset($this->skippedTests[__FUNCTION__])) { - $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - } - - $gen = function () { - yield 1 => 'key0'; - yield 1 => 'key1'; - }; - $this->cache->set('key0', 'value0'); - $this->assertTrue($this->cache->deleteMultiple($gen()), 'Deleting a generator should return true'); - - $this->assertNull($this->cache->get('key0'), 'Values must be deleted on deleteMultiple()'); - $this->assertNull($this->cache->get('key1'), 'Values must be deleted on deleteMultiple()'); - } - - public function testHas() - { - if (isset($this->skippedTests[__FUNCTION__])) { - $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - } - - $this->assertFalse($this->cache->has('key0')); - $this->cache->set('key0', 'value0'); - $this->assertTrue($this->cache->has('key0')); - } - - public function testBasicUsageWithLongKey() - { - if (isset($this->skippedTests[__FUNCTION__])) { - $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - } - - $key = str_repeat('a', 300); - - $this->assertFalse($this->cache->has($key)); - $this->assertTrue($this->cache->set($key, 'value')); - - $this->assertTrue($this->cache->has($key)); - $this->assertSame('value', $this->cache->get($key)); - - $this->assertTrue($this->cache->delete($key)); - - $this->assertFalse($this->cache->has($key)); - } - - /** - * @dataProvider invalidKeys - */ - public function testGetInvalidKeys($key) - { - if (isset($this->skippedTests[__FUNCTION__])) { - $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - } - - $this->expectException('Psr\SimpleCache\InvalidArgumentException'); - $this->cache->get($key); - } - - /** - * @dataProvider invalidKeys - */ - public function testGetMultipleInvalidKeys($key) - { - if (isset($this->skippedTests[__FUNCTION__])) { - $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - } - - $this->expectException('Psr\SimpleCache\InvalidArgumentException'); - $result = $this->cache->getMultiple(['key1', $key, 'key2']); - } - - public function testGetMultipleNoIterable() - { - if (isset($this->skippedTests[__FUNCTION__])) { - $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - } - - $this->expectException('Psr\SimpleCache\InvalidArgumentException'); - $result = $this->cache->getMultiple('key'); - } - - /** - * @dataProvider invalidKeys - */ - public function testSetInvalidKeys($key) - { - if (isset($this->skippedTests[__FUNCTION__])) { - $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - } - - $this->expectException('Psr\SimpleCache\InvalidArgumentException'); - $this->cache->set($key, 'foobar'); - } - - /** - * @dataProvider invalidArrayKeys - */ - public function testSetMultipleInvalidKeys($key) - { - if (isset($this->skippedTests[__FUNCTION__])) { - $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - } - - $values = function () use ($key) { - yield 'key1' => 'foo'; - yield $key => 'bar'; - yield 'key2' => 'baz'; - }; - $this->expectException('Psr\SimpleCache\InvalidArgumentException'); - $this->cache->setMultiple($values()); - } - - public function testSetMultipleNoIterable() - { - if (isset($this->skippedTests[__FUNCTION__])) { - $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - } - - $this->expectException('Psr\SimpleCache\InvalidArgumentException'); - $this->cache->setMultiple('key'); - } - - /** - * @dataProvider invalidKeys - */ - public function testHasInvalidKeys($key) - { - if (isset($this->skippedTests[__FUNCTION__])) { - $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - } - - $this->expectException('Psr\SimpleCache\InvalidArgumentException'); - $this->cache->has($key); - } - - /** - * @dataProvider invalidKeys - */ - public function testDeleteInvalidKeys($key) - { - if (isset($this->skippedTests[__FUNCTION__])) { - $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - } - - $this->expectException('Psr\SimpleCache\InvalidArgumentException'); - $this->cache->delete($key); - } - - /** - * @dataProvider invalidKeys - */ - public function testDeleteMultipleInvalidKeys($key) - { - if (isset($this->skippedTests[__FUNCTION__])) { - $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - } - - $this->expectException('Psr\SimpleCache\InvalidArgumentException'); - $this->cache->deleteMultiple(['key1', $key, 'key2']); - } - - public function testDeleteMultipleNoIterable() - { - if (isset($this->skippedTests[__FUNCTION__])) { - $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - } - - $this->expectException('Psr\SimpleCache\InvalidArgumentException'); - $this->cache->deleteMultiple('key'); - } - - /** - * @dataProvider invalidTtl - */ - public function testSetInvalidTtl($ttl) - { - if (isset($this->skippedTests[__FUNCTION__])) { - $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - } - - $this->expectException('Psr\SimpleCache\InvalidArgumentException'); - $this->cache->set('key', 'value', $ttl); - } - - /** - * @dataProvider invalidTtl - */ - public function testSetMultipleInvalidTtl($ttl) - { - if (isset($this->skippedTests[__FUNCTION__])) { - $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - } - - $this->expectException('Psr\SimpleCache\InvalidArgumentException'); - $this->cache->setMultiple(['key' => 'value'], $ttl); - } - - public function testNullOverwrite() - { - if (isset($this->skippedTests[__FUNCTION__])) { - $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - } - - $this->cache->set('key', 5); - $this->cache->set('key', null); - - $this->assertNull($this->cache->get('key'), 'Setting null to a key must overwrite previous value'); - } - - public function testDataTypeString() - { - if (isset($this->skippedTests[__FUNCTION__])) { - $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - } - - $this->cache->set('key', '5'); - $result = $this->cache->get('key'); - $this->assertTrue('5' === $result, 'Wrong data type. If we store a string we must get an string back.'); - $this->assertTrue(is_string($result), 'Wrong data type. If we store a string we must get an string back.'); - } - - public function testDataTypeInteger() - { - if (isset($this->skippedTests[__FUNCTION__])) { - $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - } - - $this->cache->set('key', 5); - $result = $this->cache->get('key'); - $this->assertTrue(5 === $result, 'Wrong data type. If we store an int we must get an int back.'); - $this->assertTrue(is_int($result), 'Wrong data type. If we store an int we must get an int back.'); - } - - public function testDataTypeFloat() - { - if (isset($this->skippedTests[__FUNCTION__])) { - $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - } - - $float = 1.23456789; - $this->cache->set('key', $float); - $result = $this->cache->get('key'); - $this->assertTrue(is_float($result), 'Wrong data type. If we store float we must get an float back.'); - $this->assertEquals($float, $result); - } - - public function testDataTypeBoolean() - { - if (isset($this->skippedTests[__FUNCTION__])) { - $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - } - - $this->cache->set('key', false); - $result = $this->cache->get('key'); - $this->assertTrue(is_bool($result), 'Wrong data type. If we store boolean we must get an boolean back.'); - $this->assertFalse($result); - $this->assertTrue($this->cache->has('key'), 'has() should return true when true are stored. '); - } - - public function testDataTypeArray() - { - if (isset($this->skippedTests[__FUNCTION__])) { - $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - } - - $array = ['a' => 'foo', 2 => 'bar']; - $this->cache->set('key', $array); - $result = $this->cache->get('key'); - $this->assertTrue(is_array($result), 'Wrong data type. If we store array we must get an array back.'); - $this->assertEquals($array, $result); - } - - public function testDataTypeObject() - { - if (isset($this->skippedTests[__FUNCTION__])) { - $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - } - - $object = new \stdClass(); - $object->a = 'foo'; - $this->cache->set('key', $object); - $result = $this->cache->get('key'); - $this->assertTrue(is_object($result), 'Wrong data type. If we store object we must get an object back.'); - $this->assertEquals($object, $result); - } - - public function testBinaryData() - { - if (isset($this->skippedTests[__FUNCTION__])) { - $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - } - - $data = ''; - for ($i = 0; $i < 256; $i++) { - $data .= chr($i); - } - - $array = ['a' => 'foo', 2 => 'bar']; - $this->cache->set('key', $data); - $result = $this->cache->get('key'); - $this->assertTrue($data === $result, 'Binary data must survive a round trip.'); - } - - /** - * @dataProvider validKeys - */ - public function testSetValidKeys($key) - { - if (isset($this->skippedTests[__FUNCTION__])) { - $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - } - - $this->cache->set($key, 'foobar'); - $this->assertEquals('foobar', $this->cache->get($key)); - } - - /** - * @dataProvider validKeys - */ - public function testSetMultipleValidKeys($key) - { - if (isset($this->skippedTests[__FUNCTION__])) { - $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - } - - $this->cache->setMultiple([$key => 'foobar']); - $result = $this->cache->getMultiple([$key]); - $keys = []; - foreach ($result as $i => $r) { - $keys[] = $i; - $this->assertEquals($key, $i); - $this->assertEquals('foobar', $r); - } - $this->assertSame([$key], $keys); - } - - /** - * @dataProvider validData - */ - public function testSetValidData($data) - { - if (isset($this->skippedTests[__FUNCTION__])) { - $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - } - - $this->cache->set('key', $data); - $this->assertEquals($data, $this->cache->get('key')); - } - - /** - * @dataProvider validData - */ - public function testSetMultipleValidData($data) - { - if (isset($this->skippedTests[__FUNCTION__])) { - $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - } - - $this->cache->setMultiple(['key' => $data]); - $result = $this->cache->getMultiple(['key']); - $keys = []; - foreach ($result as $i => $r) { - $keys[] = $i; - $this->assertEquals($data, $r); - } - $this->assertSame(['key'], $keys); - } - - public function testObjectAsDefaultValue() - { - if (isset($this->skippedTests[__FUNCTION__])) { - $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - } - - $obj = new \stdClass(); - $obj->foo = 'value'; - $this->assertEquals($obj, $this->cache->get('key', $obj)); - } - - public function testObjectDoesNotChangeInCache() - { - if (isset($this->skippedTests[__FUNCTION__])) { - $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - } - - $obj = new \stdClass(); - $obj->foo = 'value'; - $this->cache->set('key', $obj); - $obj->foo = 'changed'; - - $cacheObject = $this->cache->get('key'); - $this->assertEquals('value', $cacheObject->foo, 'Object in cache should not have their values changed.'); - } -} diff --git a/civicrm/vendor/cache/integration-tests/src/TaggableCachePoolTest.php b/civicrm/vendor/cache/integration-tests/src/TaggableCachePoolTest.php deleted file mode 100644 index 73ed745af6..0000000000 --- a/civicrm/vendor/cache/integration-tests/src/TaggableCachePoolTest.php +++ /dev/null @@ -1,277 +0,0 @@ -<?php - -/* - * This file is part of php-cache organization. - * - * (c) 2015-2015 Aaron Scherer <aequasi@gmail.com>, Tobias Nyholm <tobias.nyholm@gmail.com> - * - * This source file is subject to the MIT license that is bundled - * with this source code in the file LICENSE. - */ - -namespace Cache\IntegrationTests; - -use Cache\TagInterop\TaggableCacheItemPoolInterface; -use PHPUnit\Framework\TestCase; - -/** - * @author Tobias Nyholm <tobias.nyholm@gmail.com> - */ -abstract class TaggableCachePoolTest extends TestCase -{ - /** - * @type array with functionName => reason. - */ - protected $skippedTests = []; - - /** - * @type TaggableCacheItemPoolInterface - */ - protected $cache; - - /** - * @return TaggableCacheItemPoolInterface that is used in the tests - */ - abstract public function createCachePool(); - - /** - * @before - */ - public function setupService() - { - $this->cache = $this->createCachePool(); - } - - /** - * @after - */ - public function tearDownService() - { - if ($this->cache !== null) { - $this->cache->clear(); - } - } - - public function invalidKeys() - { - return CachePoolTest::invalidKeys(); - } - - public function testMultipleTags() - { - if (isset($this->skippedTests[__FUNCTION__])) { - $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - } - - $this->cache->save($this->cache->getItem('key1')->set('value')->setTags(['tag1', 'tag2'])); - $this->cache->save($this->cache->getItem('key2')->set('value')->setTags(['tag1', 'tag3'])); - $this->cache->save($this->cache->getItem('key3')->set('value')->setTags(['tag2', 'tag3'])); - $this->cache->save($this->cache->getItem('key4')->set('value')->setTags(['tag4', 'tag3'])); - - $this->cache->invalidateTags(['tag1']); - $this->assertFalse($this->cache->hasItem('key1')); - $this->assertFalse($this->cache->hasItem('key2')); - $this->assertTrue($this->cache->hasItem('key3')); - $this->assertTrue($this->cache->hasItem('key4')); - - $this->cache->invalidateTags(['tag2']); - $this->assertFalse($this->cache->hasItem('key1')); - $this->assertFalse($this->cache->hasItem('key2')); - $this->assertFalse($this->cache->hasItem('key3')); - $this->assertTrue($this->cache->hasItem('key4')); - } - - public function testPreviousTag() - { - if (isset($this->skippedTests[__FUNCTION__])) { - $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - } - - $item = $this->cache->getItem('key')->set('value'); - $tags = $item->getPreviousTags(); - $this->assertTrue(is_array($tags)); - $this->assertCount(0, $tags); - - $item->setTags(['tag0']); - $this->assertCount(0, $item->getPreviousTags()); - - $this->cache->save($item); - $this->assertCount(0, $item->getPreviousTags()); - - $item = $this->cache->getItem('key'); - $this->assertCount(1, $item->getPreviousTags()); - } - - public function testPreviousTagDeferred() - { - if (isset($this->skippedTests[__FUNCTION__])) { - $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - } - - $item = $this->cache->getItem('key')->set('value'); - $item->setTags(['tag0']); - $this->assertCount(0, $item->getPreviousTags()); - - $this->cache->saveDeferred($item); - $this->assertCount(0, $item->getPreviousTags()); - - $item = $this->cache->getItem('key'); - $this->assertCount(1, $item->getPreviousTags()); - } - - public function testTagAccessorWithEmptyTag() - { - if (isset($this->skippedTests[__FUNCTION__])) { - $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - } - - $item = $this->cache->getItem('key')->set('value'); - $this->expectException('Psr\Cache\InvalidArgumentException'); - $item->setTags(['']); - } - - /** - * @dataProvider invalidKeys - */ - public function testTagAccessorWithInvalidTag($tag) - { - if (isset($this->skippedTests[__FUNCTION__])) { - $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - } - - $item = $this->cache->getItem('key')->set('value'); - $this->expectException('Psr\Cache\InvalidArgumentException'); - $item->setTags([$tag]); - } - - public function testTagAccessorDuplicateTags() - { - if (isset($this->skippedTests[__FUNCTION__])) { - $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - } - - $item = $this->cache->getItem('key')->set('value'); - $item->setTags(['tag', 'tag', 'tag']); - $this->cache->save($item); - $item = $this->cache->getItem('key'); - - $this->assertCount(1, $item->getPreviousTags()); - } - - /** - * The tag must be removed whenever we remove an item. If not, when creating a new item - * with the same key will get the same tags. - */ - public function testRemoveTagWhenItemIsRemoved() - { - if (isset($this->skippedTests[__FUNCTION__])) { - $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - } - - $item = $this->cache->getItem('key')->set('value'); - $item->setTags(['tag1']); - - // Save the item and then delete it - $this->cache->save($item); - $this->cache->deleteItem('key'); - - // Create a new item (same key) (no tags) - $item = $this->cache->getItem('key')->set('value'); - $this->cache->save($item); - - // Clear the tag, The new item should not be cleared - $this->cache->invalidateTags(['tag1']); - $this->assertTrue($this->cache->hasItem('key'), 'Item key should be removed from the tag list when the item is removed'); - } - - public function testClearPool() - { - if (isset($this->skippedTests[__FUNCTION__])) { - $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - } - - $item = $this->cache->getItem('key')->set('value'); - $item->setTags(['tag1']); - $this->cache->save($item); - - // Clear the pool - $this->cache->clear(); - - // Create a new item (no tags) - $item = $this->cache->getItem('key')->set('value'); - $this->cache->save($item); - $this->cache->invalidateTags(['tag1']); - - $this->assertTrue($this->cache->hasItem('key'), 'Tags should be removed when the pool was cleared.'); - } - - public function testInvalidateTag() - { - if (isset($this->skippedTests[__FUNCTION__])) { - $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - } - - $item = $this->cache->getItem('key')->set('value'); - $item->setTags(['tag1', 'tag2']); - $this->cache->save($item); - $item = $this->cache->getItem('key2')->set('value'); - $item->setTags(['tag1']); - $this->cache->save($item); - - $this->cache->invalidateTag('tag2'); - $this->assertFalse($this->cache->hasItem('key'), 'Item should be cleared when tag is invalidated'); - $this->assertTrue($this->cache->hasItem('key2'), 'Item should be cleared when tag is invalidated'); - - // Create a new item (no tags) - $item = $this->cache->getItem('key')->set('value'); - $this->cache->save($item); - $this->cache->invalidateTags(['tag2']); - $this->assertTrue($this->cache->hasItem('key'), 'Item key list should be removed when clearing the tags'); - - $this->cache->invalidateTags(['tag1']); - $this->assertTrue($this->cache->hasItem('key'), 'Item key list should be removed when clearing the tags'); - } - - public function testInvalidateTags() - { - if (isset($this->skippedTests[__FUNCTION__])) { - $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - } - - $item = $this->cache->getItem('key')->set('value'); - $item->setTags(['tag1', 'tag2']); - $this->cache->save($item); - $item = $this->cache->getItem('key2')->set('value'); - $item->setTags(['tag1']); - $this->cache->save($item); - - $this->cache->invalidateTags(['tag1', 'tag2']); - $this->assertFalse($this->cache->hasItem('key'), 'Item should be cleared when tag is invalidated'); - $this->assertFalse($this->cache->hasItem('key2'), 'Item should be cleared when tag is invalidated'); - - // Create a new item (no tags) - $item = $this->cache->getItem('key')->set('value'); - $this->cache->save($item); - $this->cache->invalidateTags(['tag1']); - - $this->assertTrue($this->cache->hasItem('key'), 'Item k list should be removed when clearing the tags'); - } - - /** - * When an item is overwritten we need to clear tags for original item. - */ - public function testTagsAreCleanedOnSave() - { - if (isset($this->skippedTests[__FUNCTION__])) { - $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - } - - $pool = $this->cache; - $i = $pool->getItem('key')->set('value'); - $pool->save($i->setTags(['foo'])); - $i = $pool->getItem('key'); - $pool->save($i->setTags(['bar'])); - $pool->invalidateTags(['foo']); - $this->assertTrue($pool->getItem('key')->isHit()); - } -} diff --git a/civicrm/vendor/cache/tag-interop/.github/PULL_REQUEST_TEMPLATE.md b/civicrm/vendor/cache/tag-interop/.github/PULL_REQUEST_TEMPLATE.md deleted file mode 100644 index 4a339b4c2f..0000000000 --- a/civicrm/vendor/cache/tag-interop/.github/PULL_REQUEST_TEMPLATE.md +++ /dev/null @@ -1,5 +0,0 @@ -This is a READ ONLY repository. - -Please make your pull request to https://github.com/php-cache/cache - -Thank you for contributing. diff --git a/civicrm/vendor/cache/tag-interop/.gitignore b/civicrm/vendor/cache/tag-interop/.gitignore deleted file mode 100644 index 987e2a253c..0000000000 --- a/civicrm/vendor/cache/tag-interop/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -composer.lock -vendor diff --git a/civicrm/vendor/cache/tag-interop/.travis.yml b/civicrm/vendor/cache/tag-interop/.travis.yml deleted file mode 100644 index 942fe27e94..0000000000 --- a/civicrm/vendor/cache/tag-interop/.travis.yml +++ /dev/null @@ -1,22 +0,0 @@ -language: php -sudo: false - -matrix: - include: - - php: 7.0 - -cache: - directories: - - "$HOME/.composer/cache" - -install: - - composer update --prefer-dist --prefer-stable - -script: - - ./vendor/bin/phpunit --coverage-clover=coverage.xml - -after_success: - - pip install --user codecov && codecov - -notifications: - email: false diff --git a/civicrm/vendor/cache/tag-interop/Changelog.md b/civicrm/vendor/cache/tag-interop/Changelog.md deleted file mode 100644 index 1596519c3c..0000000000 --- a/civicrm/vendor/cache/tag-interop/Changelog.md +++ /dev/null @@ -1,9 +0,0 @@ -# Change Log - -The change log describes what is "Added", "Removed", "Changed" or "Fixed" between each release. - -## 1.0.0 - -First release - - diff --git a/civicrm/vendor/cache/tag-interop/LICENSE b/civicrm/vendor/cache/tag-interop/LICENSE deleted file mode 100644 index 82f8feef6b..0000000000 --- a/civicrm/vendor/cache/tag-interop/LICENSE +++ /dev/null @@ -1,22 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2015 Aaron Scherer, Tobias Nyholm - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - diff --git a/civicrm/vendor/cache/tag-interop/README.md b/civicrm/vendor/cache/tag-interop/README.md deleted file mode 100644 index 28511c91db..0000000000 --- a/civicrm/vendor/cache/tag-interop/README.md +++ /dev/null @@ -1,25 +0,0 @@ -# Tag support for PSR-6 Cache -[](https://gitter.im/php-cache/cache?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) -[](https://packagist.org/packages/cache/tag-interop) -[](https://packagist.org/packages/cache/tag-interop) -[](https://packagist.org/packages/cache/tag-interop) -[](LICENSE) - -This repository holds two interfaces for tagging. These interfaces will make their -way into PHP Fig. Representatives from Symfony, PHP-cache and Drupal has worked -together to agree on these interfaces. - -### Install - -```bash -composer require cache/tag-interop -``` - -### Use - -Read the [documentation on usage](http://www.php-cache.com/). - -### Contribute - -Contributions are very welcome! Send a pull request to the [main repository](https://github.com/php-cache/cache) or -report any issues you find on the [issue tracker](http://issues.php-cache.com). diff --git a/civicrm/vendor/cache/tag-interop/TaggableCacheItemInterface.php b/civicrm/vendor/cache/tag-interop/TaggableCacheItemInterface.php deleted file mode 100644 index 5823b0bb2b..0000000000 --- a/civicrm/vendor/cache/tag-interop/TaggableCacheItemInterface.php +++ /dev/null @@ -1,43 +0,0 @@ -<?php - -/* - * This file is part of php-cache organization. - * - * (c) 2015 Aaron Scherer <aequasi@gmail.com>, Tobias Nyholm <tobias.nyholm@gmail.com> - * - * This source file is subject to the MIT license that is bundled - * with this source code in the file LICENSE. - */ - -namespace Cache\TagInterop; - -use Psr\Cache\CacheItemInterface; -use Psr\Cache\InvalidArgumentException; - -/** - * An item that supports tags. This interface is a soon-to-be-PSR. - * - * @author Tobias Nyholm <tobias.nyholm@gmail.com> - * @author Nicolas Grekas <p@tchwork.com> - */ -interface TaggableCacheItemInterface extends CacheItemInterface -{ - /** - * Get all existing tags. These are the tags the item has when the item is - * returned from the pool. - * - * @return array - */ - public function getPreviousTags(); - - /** - * Overwrite all tags with a new set of tags. - * - * @param string[] $tags An array of tags - * - * @throws InvalidArgumentException When a tag is not valid. - * - * @return TaggableCacheItemInterface - */ - public function setTags(array $tags); -} diff --git a/civicrm/vendor/cache/tag-interop/TaggableCacheItemPoolInterface.php b/civicrm/vendor/cache/tag-interop/TaggableCacheItemPoolInterface.php deleted file mode 100644 index 055bf4b09d..0000000000 --- a/civicrm/vendor/cache/tag-interop/TaggableCacheItemPoolInterface.php +++ /dev/null @@ -1,60 +0,0 @@ -<?php - -/* - * This file is part of php-cache organization. - * - * (c) 2015 Aaron Scherer <aequasi@gmail.com>, Tobias Nyholm <tobias.nyholm@gmail.com> - * - * This source file is subject to the MIT license that is bundled - * with this source code in the file LICENSE. - */ - -namespace Cache\TagInterop; - -use Psr\Cache\CacheItemPoolInterface; -use Psr\Cache\InvalidArgumentException; - -/** - * Interface for invalidating cached items using tags. This interface is a soon-to-be-PSR. - * - * @author Tobias Nyholm <tobias.nyholm@gmail.com> - * @author Nicolas Grekas <p@tchwork.com> - */ -interface TaggableCacheItemPoolInterface extends CacheItemPoolInterface -{ - /** - * Invalidates cached items using a tag. - * - * @param string $tag The tag to invalidate - * - * @throws InvalidArgumentException When $tags is not valid - * - * @return bool True on success - */ - public function invalidateTag($tag); - - /** - * Invalidates cached items using tags. - * - * @param string[] $tags An array of tags to invalidate - * - * @throws InvalidArgumentException When $tags is not valid - * - * @return bool True on success - */ - public function invalidateTags(array $tags); - - /** - * {@inheritdoc} - * - * @return TaggableCacheItemInterface - */ - public function getItem($key); - - /** - * {@inheritdoc} - * - * @return array|\Traversable|TaggableCacheItemInterface[] - */ - public function getItems(array $keys = []); -} diff --git a/civicrm/vendor/cache/tag-interop/composer.json b/civicrm/vendor/cache/tag-interop/composer.json deleted file mode 100644 index d0f7467afb..0000000000 --- a/civicrm/vendor/cache/tag-interop/composer.json +++ /dev/null @@ -1,39 +0,0 @@ -{ - "name": "cache/tag-interop", - "type": "library", - "description": "Framework interoperable interfaces for tags", - "keywords": [ - "cache", - "psr6", - "tag", - "psr" - ], - "homepage": "http://www.php-cache.com/en/latest/", - "license": "MIT", - "authors": [ - { - "name": "Tobias Nyholm", - "email": "tobias.nyholm@gmail.com", - "homepage": "https://github.com/nyholm" - }, - { - "name": "Nicolas Grekas ", - "email": "p@tchwork.com", - "homepage": "https://github.com/nicolas-grekas" - } - ], - "require": { - "php": "^5.5 || ^7.0", - "psr/cache": "^1.0" - }, - "autoload": { - "psr-4": { - "Cache\\TagInterop\\": "" - } - }, - "extra": { - "branch-alias": { - "dev-master": "2.0-dev" - } - } -} diff --git a/civicrm/vendor/composer/autoload_psr4.php b/civicrm/vendor/composer/autoload_psr4.php index 707471bcbd..b335f02da7 100644 --- a/civicrm/vendor/composer/autoload_psr4.php +++ b/civicrm/vendor/composer/autoload_psr4.php @@ -41,7 +41,6 @@ return array( 'Psr\\Http\\Message\\' => array($vendorDir . '/psr/http-message/src', $vendorDir . '/psr/http-factory/src'), 'Psr\\Http\\Client\\' => array($vendorDir . '/psr/http-client/src'), 'Psr\\Container\\' => array($vendorDir . '/psr/container/src'), - 'Psr\\Cache\\' => array($vendorDir . '/psr/cache/src'), 'PhpOffice\\PhpWord\\' => array($vendorDir . '/phpoffice/phpword/src/PhpWord'), 'PhpOffice\\PhpSpreadsheet\\' => array($vendorDir . '/phpoffice/phpspreadsheet/src/PhpSpreadsheet'), 'Padaliyajay\\PHPAutoprefixer\\' => array($vendorDir . '/padaliyajay/php-autoprefixer/src'), @@ -67,8 +66,6 @@ return array( 'Civi\\Cxn\\Rpc\\' => array($vendorDir . '/civicrm/civicrm-cxn-rpc/src'), 'Civi\\CompilePlugin\\' => array($vendorDir . '/civicrm/composer-compile-plugin/src'), 'Civi\\' => array($baseDir . '/', $baseDir . '/Civi', $baseDir . '/setup/src'), - 'Cache\\TagInterop\\' => array($vendorDir . '/cache/tag-interop'), - 'Cache\\IntegrationTests\\' => array($vendorDir . '/cache/integration-tests/src'), 'CCL\\' => array($vendorDir . '/civicrm/composer-compile-lib/src'), 'Brick\\Money\\' => array($vendorDir . '/brick/money/src'), 'Brick\\Math\\' => array($vendorDir . '/brick/math/src'), diff --git a/civicrm/vendor/composer/autoload_real.php b/civicrm/vendor/composer/autoload_real.php index 1bd06617e6..e83293bd5c 100644 --- a/civicrm/vendor/composer/autoload_real.php +++ b/civicrm/vendor/composer/autoload_real.php @@ -2,7 +2,7 @@ // autoload_real.php @generated by Composer -class ComposerAutoloaderInit85641ecafad0fd91a9bd9d9f47db5e32 +class ComposerAutoloaderInite1ca47ea801818fa75d60df4388c9f11 { private static $loader; @@ -24,9 +24,9 @@ class ComposerAutoloaderInit85641ecafad0fd91a9bd9d9f47db5e32 require __DIR__ . '/platform_check.php'; - spl_autoload_register(array('ComposerAutoloaderInit85641ecafad0fd91a9bd9d9f47db5e32', 'loadClassLoader'), true, true); + spl_autoload_register(array('ComposerAutoloaderInite1ca47ea801818fa75d60df4388c9f11', 'loadClassLoader'), true, true); self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(\dirname(__FILE__))); - spl_autoload_unregister(array('ComposerAutoloaderInit85641ecafad0fd91a9bd9d9f47db5e32', 'loadClassLoader')); + spl_autoload_unregister(array('ComposerAutoloaderInite1ca47ea801818fa75d60df4388c9f11', 'loadClassLoader')); $includePaths = require __DIR__ . '/include_paths.php'; $includePaths[] = get_include_path(); @@ -36,7 +36,7 @@ class ComposerAutoloaderInit85641ecafad0fd91a9bd9d9f47db5e32 if ($useStaticLoader) { require __DIR__ . '/autoload_static.php'; - call_user_func(\Composer\Autoload\ComposerStaticInit85641ecafad0fd91a9bd9d9f47db5e32::getInitializer($loader)); + call_user_func(\Composer\Autoload\ComposerStaticInite1ca47ea801818fa75d60df4388c9f11::getInitializer($loader)); } else { $map = require __DIR__ . '/autoload_namespaces.php'; foreach ($map as $namespace => $path) { @@ -57,12 +57,12 @@ class ComposerAutoloaderInit85641ecafad0fd91a9bd9d9f47db5e32 $loader->register(true); if ($useStaticLoader) { - $includeFiles = Composer\Autoload\ComposerStaticInit85641ecafad0fd91a9bd9d9f47db5e32::$files; + $includeFiles = Composer\Autoload\ComposerStaticInite1ca47ea801818fa75d60df4388c9f11::$files; } else { $includeFiles = require __DIR__ . '/autoload_files.php'; } foreach ($includeFiles as $fileIdentifier => $file) { - composerRequire85641ecafad0fd91a9bd9d9f47db5e32($fileIdentifier, $file); + composerRequiree1ca47ea801818fa75d60df4388c9f11($fileIdentifier, $file); } return $loader; @@ -74,7 +74,7 @@ class ComposerAutoloaderInit85641ecafad0fd91a9bd9d9f47db5e32 * @param string $file * @return void */ -function composerRequire85641ecafad0fd91a9bd9d9f47db5e32($fileIdentifier, $file) +function composerRequiree1ca47ea801818fa75d60df4388c9f11($fileIdentifier, $file) { if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) { $GLOBALS['__composer_autoload_files'][$fileIdentifier] = true; diff --git a/civicrm/vendor/composer/autoload_static.php b/civicrm/vendor/composer/autoload_static.php index a58958a732..b02011288d 100644 --- a/civicrm/vendor/composer/autoload_static.php +++ b/civicrm/vendor/composer/autoload_static.php @@ -4,7 +4,7 @@ namespace Composer\Autoload; -class ComposerStaticInit85641ecafad0fd91a9bd9d9f47db5e32 +class ComposerStaticInite1ca47ea801818fa75d60df4388c9f11 { public static $files = array ( 'a4a119a56e50fbb293281d9a48007e0e' => __DIR__ . '/..' . '/symfony/polyfill-php80/bootstrap.php', @@ -151,7 +151,6 @@ class ComposerStaticInit85641ecafad0fd91a9bd9d9f47db5e32 'Psr\\Http\\Message\\' => 17, 'Psr\\Http\\Client\\' => 16, 'Psr\\Container\\' => 14, - 'Psr\\Cache\\' => 10, 'PhpOffice\\PhpWord\\' => 18, 'PhpOffice\\PhpSpreadsheet\\' => 25, 'Padaliyajay\\PHPAutoprefixer\\' => 28, @@ -198,8 +197,6 @@ class ComposerStaticInit85641ecafad0fd91a9bd9d9f47db5e32 'Civi\\Cxn\\Rpc\\' => 13, 'Civi\\CompilePlugin\\' => 19, 'Civi\\' => 5, - 'Cache\\TagInterop\\' => 17, - 'Cache\\IntegrationTests\\' => 23, 'CCL\\' => 4, ), 'B' => @@ -351,10 +348,6 @@ class ComposerStaticInit85641ecafad0fd91a9bd9d9f47db5e32 array ( 0 => __DIR__ . '/..' . '/psr/container/src', ), - 'Psr\\Cache\\' => - array ( - 0 => __DIR__ . '/..' . '/psr/cache/src', - ), 'PhpOffice\\PhpWord\\' => array ( 0 => __DIR__ . '/..' . '/phpoffice/phpword/src/PhpWord', @@ -459,14 +452,6 @@ class ComposerStaticInit85641ecafad0fd91a9bd9d9f47db5e32 1 => __DIR__ . '/../..' . '/Civi', 2 => __DIR__ . '/../..' . '/setup/src', ), - 'Cache\\TagInterop\\' => - array ( - 0 => __DIR__ . '/..' . '/cache/tag-interop', - ), - 'Cache\\IntegrationTests\\' => - array ( - 0 => __DIR__ . '/..' . '/cache/integration-tests/src', - ), 'CCL\\' => array ( 0 => __DIR__ . '/..' . '/civicrm/composer-compile-lib/src', @@ -744,11 +729,11 @@ class ComposerStaticInit85641ecafad0fd91a9bd9d9f47db5e32 public static function getInitializer(ClassLoader $loader) { return \Closure::bind(function () use ($loader) { - $loader->prefixLengthsPsr4 = ComposerStaticInit85641ecafad0fd91a9bd9d9f47db5e32::$prefixLengthsPsr4; - $loader->prefixDirsPsr4 = ComposerStaticInit85641ecafad0fd91a9bd9d9f47db5e32::$prefixDirsPsr4; - $loader->prefixesPsr0 = ComposerStaticInit85641ecafad0fd91a9bd9d9f47db5e32::$prefixesPsr0; - $loader->fallbackDirsPsr0 = ComposerStaticInit85641ecafad0fd91a9bd9d9f47db5e32::$fallbackDirsPsr0; - $loader->classMap = ComposerStaticInit85641ecafad0fd91a9bd9d9f47db5e32::$classMap; + $loader->prefixLengthsPsr4 = ComposerStaticInite1ca47ea801818fa75d60df4388c9f11::$prefixLengthsPsr4; + $loader->prefixDirsPsr4 = ComposerStaticInite1ca47ea801818fa75d60df4388c9f11::$prefixDirsPsr4; + $loader->prefixesPsr0 = ComposerStaticInite1ca47ea801818fa75d60df4388c9f11::$prefixesPsr0; + $loader->fallbackDirsPsr0 = ComposerStaticInite1ca47ea801818fa75d60df4388c9f11::$fallbackDirsPsr0; + $loader->classMap = ComposerStaticInite1ca47ea801818fa75d60df4388c9f11::$classMap; }, null, ClassLoader::class); } diff --git a/civicrm/vendor/composer/installed.json b/civicrm/vendor/composer/installed.json index 317e579c0d..c70b2dc690 100644 --- a/civicrm/vendor/composer/installed.json +++ b/civicrm/vendor/composer/installed.json @@ -175,137 +175,6 @@ ], "install-path": "../brick/money" }, - { - "name": "cache/integration-tests", - "version": "0.17.0", - "version_normalized": "0.17.0.0", - "source": { - "type": "git", - "url": "https://github.com/php-cache/integration-tests.git", - "reference": "eda2e6b8bc5abcd623c8047e2345cda38dd6479e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-cache/integration-tests/zipball/eda2e6b8bc5abcd623c8047e2345cda38dd6479e", - "reference": "eda2e6b8bc5abcd623c8047e2345cda38dd6479e", - "shasum": "" - }, - "require": { - "cache/tag-interop": "^1.0", - "php": ">=5.5.9", - "psr/cache": "~1.0" - }, - "conflict": { - "phpunit/phpunit": "<4.8.35|<5.4.3,>=5.0" - }, - "require-dev": { - "cache/cache": "^1.0", - "illuminate/cache": "^5.4|^5.5|^5.6", - "mockery/mockery": "^1.0", - "symfony/cache": "^3.4.31|^4.3.4|^5.0", - "symfony/phpunit-bridge": "^5.1", - "tedivm/stash": "^0.14" - }, - "time": "2020-11-03T12:52:23+00:00", - "type": "library", - "installation-source": "dist", - "autoload": { - "psr-4": { - "Cache\\IntegrationTests\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Aaron Scherer", - "email": "aequasi@gmail.com", - "homepage": "https://github.com/aequasi" - }, - { - "name": "Tobias Nyholm", - "email": "tobias.nyholm@gmail.com", - "homepage": "https://github.com/nyholm" - } - ], - "description": "Integration tests for PSR-6 and PSR-16 cache implementations", - "homepage": "https://github.com/php-cache/integration-tests", - "keywords": [ - "cache", - "psr16", - "psr6", - "test" - ], - "support": { - "issues": "https://github.com/php-cache/integration-tests/issues", - "source": "https://github.com/php-cache/integration-tests/tree/0.17.0" - }, - "install-path": "../cache/integration-tests" - }, - { - "name": "cache/tag-interop", - "version": "1.0.0", - "version_normalized": "1.0.0.0", - "source": { - "type": "git", - "url": "https://github.com/php-cache/tag-interop.git", - "reference": "c7496dd81530f538af27b4f2713cde97bc292832" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-cache/tag-interop/zipball/c7496dd81530f538af27b4f2713cde97bc292832", - "reference": "c7496dd81530f538af27b4f2713cde97bc292832", - "shasum": "" - }, - "require": { - "php": "^5.5 || ^7.0", - "psr/cache": "^1.0" - }, - "time": "2017-03-13T09:14:27+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0-dev" - } - }, - "installation-source": "dist", - "autoload": { - "psr-4": { - "Cache\\TagInterop\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Tobias Nyholm", - "email": "tobias.nyholm@gmail.com", - "homepage": "https://github.com/Nyholm" - }, - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com", - "homepage": "https://github.com/nicolas-grekas" - } - ], - "description": "Framework interoperable interfaces for tags", - "homepage": "http://www.php-cache.com/en/latest/", - "keywords": [ - "cache", - "psr", - "psr6", - "tag" - ], - "support": { - "issues": "https://github.com/php-cache/tag-interop/issues", - "source": "https://github.com/php-cache/tag-interop/tree/master" - }, - "install-path": "../cache/tag-interop" - }, { "name": "civicrm/civicrm-cxn-rpc", "version": "v0.20.12.01", @@ -1607,9 +1476,13 @@ ], "support": { "issues": "https://github.com/maennchen/ZipStream-PHP/issues", - "source": "https://github.com/maennchen/ZipStream-PHP/tree/master" + "source": "https://github.com/maennchen/ZipStream-PHP/tree/2.1.0" }, "funding": [ + { + "url": "https://github.com/maennchen", + "type": "github" + }, { "url": "https://opencollective.com/zipstream", "type": "open_collective" @@ -3195,58 +3068,6 @@ ], "install-path": "../phpseclib/phpseclib" }, - { - "name": "psr/cache", - "version": "1.0.1", - "version_normalized": "1.0.1.0", - "source": { - "type": "git", - "url": "https://github.com/php-fig/cache.git", - "reference": "d11b50ad223250cf17b86e38383413f5a6764bf8" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/cache/zipball/d11b50ad223250cf17b86e38383413f5a6764bf8", - "reference": "d11b50ad223250cf17b86e38383413f5a6764bf8", - "shasum": "" - }, - "require": { - "php": ">=5.3.0" - }, - "time": "2016-08-06T20:24:11+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "installation-source": "dist", - "autoload": { - "psr-4": { - "Psr\\Cache\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" - } - ], - "description": "Common interface for caching libraries", - "keywords": [ - "cache", - "psr", - "psr-6" - ], - "support": { - "source": "https://github.com/php-fig/cache/tree/master" - }, - "install-path": "../psr/cache" - }, { "name": "psr/container", "version": "1.0.0", diff --git a/civicrm/vendor/composer/installed.php b/civicrm/vendor/composer/installed.php index 550f889dcf..59d8827d83 100644 --- a/civicrm/vendor/composer/installed.php +++ b/civicrm/vendor/composer/installed.php @@ -1,11 +1,11 @@ <?php return array( 'root' => array( - 'pretty_version' => '5.59.x-dev', - 'version' => '5.59.9999999.9999999-dev', + 'pretty_version' => '5.60.x-dev', + 'version' => '5.60.9999999.9999999-dev', 'type' => 'library', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), - 'reference' => '5a40b8aac7a5b0cd7b8f432c31deae79c454b9be', + 'reference' => 'fadbe2424f36072c5fa5dc633f11dfaf48942951', 'name' => 'civicrm/civicrm-core', 'dev' => true, ), @@ -37,31 +37,13 @@ 'reference' => '49e6597470da74f6a9f1dd7d5286ea3b4756b7e0', 'dev_requirement' => false, ), - 'cache/integration-tests' => array( - 'pretty_version' => '0.17.0', - 'version' => '0.17.0.0', - 'type' => 'library', - 'install_path' => __DIR__ . '/../cache/integration-tests', - 'aliases' => array(), - 'reference' => 'eda2e6b8bc5abcd623c8047e2345cda38dd6479e', - 'dev_requirement' => false, - ), - 'cache/tag-interop' => array( - 'pretty_version' => '1.0.0', - 'version' => '1.0.0.0', - 'type' => 'library', - 'install_path' => __DIR__ . '/../cache/tag-interop', - 'aliases' => array(), - 'reference' => 'c7496dd81530f538af27b4f2713cde97bc292832', - 'dev_requirement' => false, - ), 'civicrm/civicrm-core' => array( - 'pretty_version' => '5.59.x-dev', - 'version' => '5.59.9999999.9999999-dev', + 'pretty_version' => '5.60.x-dev', + 'version' => '5.60.9999999.9999999-dev', 'type' => 'library', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), - 'reference' => '5a40b8aac7a5b0cd7b8f432c31deae79c454b9be', + 'reference' => 'fadbe2424f36072c5fa5dc633f11dfaf48942951', 'dev_requirement' => false, ), 'civicrm/civicrm-cxn-rpc' => array( @@ -448,15 +430,6 @@ 'reference' => '233a920cb38636a43b18d428f9a8db1f0a1a08f4', 'dev_requirement' => false, ), - 'psr/cache' => array( - 'pretty_version' => '1.0.1', - 'version' => '1.0.1.0', - 'type' => 'library', - 'install_path' => __DIR__ . '/../psr/cache', - 'aliases' => array(), - 'reference' => 'd11b50ad223250cf17b86e38383413f5a6764bf8', - 'dev_requirement' => false, - ), 'psr/container' => array( 'pretty_version' => '1.0.0', 'version' => '1.0.0.0', diff --git a/civicrm/vendor/psr/cache/CHANGELOG.md b/civicrm/vendor/psr/cache/CHANGELOG.md deleted file mode 100644 index 58ddab05aa..0000000000 --- a/civicrm/vendor/psr/cache/CHANGELOG.md +++ /dev/null @@ -1,16 +0,0 @@ -# Changelog - -All notable changes to this project will be documented in this file, in reverse chronological order by release. - -## 1.0.1 - 2016-08-06 - -### Fixed - -- Make spacing consistent in phpdoc annotations php-fig/cache#9 - chalasr -- Fix grammar in phpdoc annotations php-fig/cache#10 - chalasr -- Be more specific in docblocks that `getItems()` and `deleteItems()` take an array of strings (`string[]`) compared to just `array` php-fig/cache#8 - GrahamCampbell -- For `expiresAt()` and `expiresAfter()` in CacheItemInterface fix docblock to specify null as a valid parameters as well as an implementation of DateTimeInterface php-fig/cache#7 - GrahamCampbell - -## 1.0.0 - 2015-12-11 - -Initial stable release; reflects accepted PSR-6 specification diff --git a/civicrm/vendor/psr/cache/LICENSE.txt b/civicrm/vendor/psr/cache/LICENSE.txt deleted file mode 100644 index b1c2c97b9d..0000000000 --- a/civicrm/vendor/psr/cache/LICENSE.txt +++ /dev/null @@ -1,19 +0,0 @@ -Copyright (c) 2015 PHP Framework Interoperability Group - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/civicrm/vendor/psr/cache/README.md b/civicrm/vendor/psr/cache/README.md deleted file mode 100644 index c8706ceea6..0000000000 --- a/civicrm/vendor/psr/cache/README.md +++ /dev/null @@ -1,9 +0,0 @@ -PSR Cache -========= - -This repository holds all interfaces defined by -[PSR-6](http://www.php-fig.org/psr/psr-6/). - -Note that this is not a Cache implementation of its own. It is merely an -interface that describes a Cache implementation. See the specification for more -details. diff --git a/civicrm/vendor/psr/cache/composer.json b/civicrm/vendor/psr/cache/composer.json deleted file mode 100644 index e828fec943..0000000000 --- a/civicrm/vendor/psr/cache/composer.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "name": "psr/cache", - "description": "Common interface for caching libraries", - "keywords": ["psr", "psr-6", "cache"], - "license": "MIT", - "authors": [ - { - "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" - } - ], - "require": { - "php": ">=5.3.0" - }, - "autoload": { - "psr-4": { - "Psr\\Cache\\": "src/" - } - }, - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - } -} diff --git a/civicrm/vendor/psr/cache/src/CacheException.php b/civicrm/vendor/psr/cache/src/CacheException.php deleted file mode 100644 index e27f22f8d6..0000000000 --- a/civicrm/vendor/psr/cache/src/CacheException.php +++ /dev/null @@ -1,10 +0,0 @@ -<?php - -namespace Psr\Cache; - -/** - * Exception interface for all exceptions thrown by an Implementing Library. - */ -interface CacheException -{ -} diff --git a/civicrm/vendor/psr/cache/src/CacheItemInterface.php b/civicrm/vendor/psr/cache/src/CacheItemInterface.php deleted file mode 100644 index 63d05dd1f4..0000000000 --- a/civicrm/vendor/psr/cache/src/CacheItemInterface.php +++ /dev/null @@ -1,105 +0,0 @@ -<?php - -namespace Psr\Cache; - -/** - * CacheItemInterface defines an interface for interacting with objects inside a cache. - * - * Each Item object MUST be associated with a specific key, which can be set - * according to the implementing system and is typically passed by the - * Cache\CacheItemPoolInterface object. - * - * The Cache\CacheItemInterface object encapsulates the storage and retrieval of - * cache items. Each Cache\CacheItemInterface is generated by a - * Cache\CacheItemPoolInterface object, which is responsible for any required - * setup as well as associating the object with a unique Key. - * Cache\CacheItemInterface objects MUST be able to store and retrieve any type - * of PHP value defined in the Data section of the specification. - * - * Calling Libraries MUST NOT instantiate Item objects themselves. They may only - * be requested from a Pool object via the getItem() method. Calling Libraries - * SHOULD NOT assume that an Item created by one Implementing Library is - * compatible with a Pool from another Implementing Library. - */ -interface CacheItemInterface -{ - /** - * Returns the key for the current cache item. - * - * The key is loaded by the Implementing Library, but should be available to - * the higher level callers when needed. - * - * @return string - * The key string for this cache item. - */ - public function getKey(); - - /** - * Retrieves the value of the item from the cache associated with this object's key. - * - * The value returned must be identical to the value originally stored by set(). - * - * If isHit() returns false, this method MUST return null. Note that null - * is a legitimate cached value, so the isHit() method SHOULD be used to - * differentiate between "null value was found" and "no value was found." - * - * @return mixed - * The value corresponding to this cache item's key, or null if not found. - */ - public function get(); - - /** - * Confirms if the cache item lookup resulted in a cache hit. - * - * Note: This method MUST NOT have a race condition between calling isHit() - * and calling get(). - * - * @return bool - * True if the request resulted in a cache hit. False otherwise. - */ - public function isHit(); - - /** - * Sets the value represented by this cache item. - * - * The $value argument may be any item that can be serialized by PHP, - * although the method of serialization is left up to the Implementing - * Library. - * - * @param mixed $value - * The serializable value to be stored. - * - * @return static - * The invoked object. - */ - public function set($value); - - /** - * Sets the expiration time for this cache item. - * - * @param \DateTimeInterface|null $expiration - * The point in time after which the item MUST be considered expired. - * If null is passed explicitly, a default value MAY be used. If none is set, - * the value should be stored permanently or for as long as the - * implementation allows. - * - * @return static - * The called object. - */ - public function expiresAt($expiration); - - /** - * Sets the expiration time for this cache item. - * - * @param int|\DateInterval|null $time - * The period of time from the present after which the item MUST be considered - * expired. An integer parameter is understood to be the time in seconds until - * expiration. If null is passed explicitly, a default value MAY be used. - * If none is set, the value should be stored permanently or for as long as the - * implementation allows. - * - * @return static - * The called object. - */ - public function expiresAfter($time); -} diff --git a/civicrm/vendor/psr/cache/src/CacheItemPoolInterface.php b/civicrm/vendor/psr/cache/src/CacheItemPoolInterface.php deleted file mode 100644 index 0351419671..0000000000 --- a/civicrm/vendor/psr/cache/src/CacheItemPoolInterface.php +++ /dev/null @@ -1,138 +0,0 @@ -<?php - -namespace Psr\Cache; - -/** - * CacheItemPoolInterface generates CacheItemInterface objects. - * - * The primary purpose of Cache\CacheItemPoolInterface is to accept a key from - * the Calling Library and return the associated Cache\CacheItemInterface object. - * It is also the primary point of interaction with the entire cache collection. - * All configuration and initialization of the Pool is left up to an - * Implementing Library. - */ -interface CacheItemPoolInterface -{ - /** - * Returns a Cache Item representing the specified key. - * - * This method must always return a CacheItemInterface object, even in case of - * a cache miss. It MUST NOT return null. - * - * @param string $key - * The key for which to return the corresponding Cache Item. - * - * @throws InvalidArgumentException - * If the $key string is not a legal value a \Psr\Cache\InvalidArgumentException - * MUST be thrown. - * - * @return CacheItemInterface - * The corresponding Cache Item. - */ - public function getItem($key); - - /** - * Returns a traversable set of cache items. - * - * @param string[] $keys - * An indexed array of keys of items to retrieve. - * - * @throws InvalidArgumentException - * If any of the keys in $keys are not a legal value a \Psr\Cache\InvalidArgumentException - * MUST be thrown. - * - * @return array|\Traversable - * A traversable collection of Cache Items keyed by the cache keys of - * each item. A Cache item will be returned for each key, even if that - * key is not found. However, if no keys are specified then an empty - * traversable MUST be returned instead. - */ - public function getItems(array $keys = array()); - - /** - * Confirms if the cache contains specified cache item. - * - * Note: This method MAY avoid retrieving the cached value for performance reasons. - * This could result in a race condition with CacheItemInterface::get(). To avoid - * such situation use CacheItemInterface::isHit() instead. - * - * @param string $key - * The key for which to check existence. - * - * @throws InvalidArgumentException - * If the $key string is not a legal value a \Psr\Cache\InvalidArgumentException - * MUST be thrown. - * - * @return bool - * True if item exists in the cache, false otherwise. - */ - public function hasItem($key); - - /** - * Deletes all items in the pool. - * - * @return bool - * True if the pool was successfully cleared. False if there was an error. - */ - public function clear(); - - /** - * Removes the item from the pool. - * - * @param string $key - * The key to delete. - * - * @throws InvalidArgumentException - * If the $key string is not a legal value a \Psr\Cache\InvalidArgumentException - * MUST be thrown. - * - * @return bool - * True if the item was successfully removed. False if there was an error. - */ - public function deleteItem($key); - - /** - * Removes multiple items from the pool. - * - * @param string[] $keys - * An array of keys that should be removed from the pool. - - * @throws InvalidArgumentException - * If any of the keys in $keys are not a legal value a \Psr\Cache\InvalidArgumentException - * MUST be thrown. - * - * @return bool - * True if the items were successfully removed. False if there was an error. - */ - public function deleteItems(array $keys); - - /** - * Persists a cache item immediately. - * - * @param CacheItemInterface $item - * The cache item to save. - * - * @return bool - * True if the item was successfully persisted. False if there was an error. - */ - public function save(CacheItemInterface $item); - - /** - * Sets a cache item to be persisted later. - * - * @param CacheItemInterface $item - * The cache item to save. - * - * @return bool - * False if the item could not be queued or if a commit was attempted and failed. True otherwise. - */ - public function saveDeferred(CacheItemInterface $item); - - /** - * Persists any deferred cache items. - * - * @return bool - * True if all not-yet-saved items were successfully saved or there were none. False otherwise. - */ - public function commit(); -} diff --git a/civicrm/vendor/psr/cache/src/InvalidArgumentException.php b/civicrm/vendor/psr/cache/src/InvalidArgumentException.php deleted file mode 100644 index be7c6fa0ef..0000000000 --- a/civicrm/vendor/psr/cache/src/InvalidArgumentException.php +++ /dev/null @@ -1,13 +0,0 @@ -<?php - -namespace Psr\Cache; - -/** - * Exception interface for invalid cache arguments. - * - * Any time an invalid argument is passed into a method it must throw an - * exception class which implements Psr\Cache\InvalidArgumentException. - */ -interface InvalidArgumentException extends CacheException -{ -} diff --git a/civicrm/xml/schema/Contact/Relationship.xml b/civicrm/xml/schema/Contact/Relationship.xml index ed9cb1ee36..fd121341d7 100644 --- a/civicrm/xml/schema/Contact/Relationship.xml +++ b/civicrm/xml/schema/Contact/Relationship.xml @@ -177,6 +177,7 @@ <default>NULL</default> <comment>FK to civicrm_case</comment> <html> + <type>EntityRef</type> <label>Case</label> </html> <add>2.2</add> diff --git a/civicrm/xml/schema/Contact/SubscriptionHistory.xml b/civicrm/xml/schema/Contact/SubscriptionHistory.xml index cbf4d68588..7506e9bde3 100644 --- a/civicrm/xml/schema/Contact/SubscriptionHistory.xml +++ b/civicrm/xml/schema/Contact/SubscriptionHistory.xml @@ -70,6 +70,11 @@ <required>true</required> <default>CURRENT_TIMESTAMP</default> <comment>Date of the (un)subscription</comment> + <html> + <label>Group Membership Action Date</label> + <type>Select Date</type> + <formatType>activityDateTime</formatType> + </html> <add>1.1</add> </field> <field> diff --git a/civicrm/xml/schema/Core/CustomField.xml b/civicrm/xml/schema/Core/CustomField.xml index f9fd912d76..01ed1a33ec 100644 --- a/civicrm/xml/schema/Core/CustomField.xml +++ b/civicrm/xml/schema/Core/CustomField.xml @@ -332,6 +332,15 @@ <comment>Should the multi-record custom field values be displayed in tab table listing</comment> <add>4.5</add> </field> + <field> + <name>fk_entity</name> + <type>varchar</type> + <title>Entity</title> + <length>255</length> + <default>NULL</default> + <comment>Name of entity being referenced.</comment> + <add>5.60</add> + </field> <index> <name>UI_label_custom_group_id</name> <fieldName>label</fieldName> diff --git a/civicrm/xml/schema/Core/JobLog.xml b/civicrm/xml/schema/Core/JobLog.xml index 9fb80bfdac..56609faf20 100644 --- a/civicrm/xml/schema/Core/JobLog.xml +++ b/civicrm/xml/schema/Core/JobLog.xml @@ -55,9 +55,19 @@ <name>job_id</name> <title>Job ID</title> <type>int unsigned</type> - <comment>Pointer to job id - not a FK though, just for logging purposes</comment> + <comment>Pointer to job id</comment> + <html> + <type>Number</type> + </html> <add>4.1</add> </field> + <foreignKey> + <name>job_id</name> + <table>civicrm_job</table> + <key>id</key> + <add>5.60</add> + <onDelete>SET NULL</onDelete> + </foreignKey> <field> <name>name</name> <title>Job Name</title> diff --git a/civicrm/xml/templates/message_templates/contribution_online_receipt_html.tpl b/civicrm/xml/templates/message_templates/contribution_online_receipt_html.tpl index 13623e7c15..a3d4ec3f88 100644 --- a/civicrm/xml/templates/message_templates/contribution_online_receipt_html.tpl +++ b/civicrm/xml/templates/message_templates/contribution_online_receipt_html.tpl @@ -391,7 +391,7 @@ </td> </tr> {/if} - {if !empty($is_deductible) AND !empty($price)} + {if $is_deductible AND !empty($price)} <tr> <td colspan="2" {$valueStyle}> <p>{ts 1=$price|crmMoney:$currency}The value of this premium is %1. This may affect the amount of the tax deduction you can claim. Consult your tax advisor for more information.{/ts}</p> diff --git a/civicrm/xml/templates/message_templates/contribution_online_receipt_text.tpl b/civicrm/xml/templates/message_templates/contribution_online_receipt_text.tpl index 3927b5fed8..c59a8976e8 100644 --- a/civicrm/xml/templates/message_templates/contribution_online_receipt_text.tpl +++ b/civicrm/xml/templates/message_templates/contribution_online_receipt_text.tpl @@ -176,7 +176,7 @@ {$contact_phone} {/if} {/if} -{if !empty($is_deductible) AND !empty($price)} +{if $is_deductible AND !empty($price)} {ts 1=$price|crmMoney:$currency}The value of this premium is %1. This may affect the amount of the tax deduction you can claim. Consult your tax advisor for more information.{/ts}{/if} {/if} diff --git a/civicrm/xml/templates/message_templates/membership_online_receipt_html.tpl b/civicrm/xml/templates/message_templates/membership_online_receipt_html.tpl index 3bb4b2f417..efc2fa10a7 100644 --- a/civicrm/xml/templates/message_templates/membership_online_receipt_html.tpl +++ b/civicrm/xml/templates/message_templates/membership_online_receipt_html.tpl @@ -496,7 +496,7 @@ </td> </tr> {/if} - {if !empty($is_deductible) AND !empty($price)} + {if $is_deductible AND !empty($price)} <tr> <td colspan="2" {$valueStyle}> <p>{ts 1=$price|crmMoney}The value of this premium is %1. This may affect the amount of the tax deduction you can claim. Consult your tax advisor for more information.{/ts}</p> diff --git a/civicrm/xml/templates/message_templates/membership_online_receipt_text.tpl b/civicrm/xml/templates/message_templates/membership_online_receipt_text.tpl index 02be9e48f3..ce1b0e7566 100644 --- a/civicrm/xml/templates/message_templates/membership_online_receipt_text.tpl +++ b/civicrm/xml/templates/message_templates/membership_online_receipt_text.tpl @@ -210,7 +210,7 @@ {$contact_phone} {/if} {/if} -{if !empty($is_deductible) AND !empty($price)} +{if $is_deductible AND !empty($price)} {ts 1=$price|crmMoney}The value of this premium is %1. This may affect the amount of the tax deduction you can claim. Consult your tax advisor for more information.{/ts}{/if} {/if} diff --git a/civicrm/xml/version.xml b/civicrm/xml/version.xml index 22e99f7680..35548fbca3 100644 --- a/civicrm/xml/version.xml +++ b/civicrm/xml/version.xml @@ -1,4 +1,4 @@ <?xml version="1.0" encoding="iso-8859-1" ?> <version> - <version_no>5.59.4</version_no> + <version_no>5.60.0</version_no> </version> diff --git a/readme.txt b/readme.txt index 97933e2c29..76557b46db 100644 --- a/readme.txt +++ b/readme.txt @@ -3,7 +3,7 @@ Contributors: needle Tags: civicrm, crm Requires at least: 4.9 Tested up to: 6.1 -Stable tag: 5.59 +Stable tag: 5.60 License: AGPL3 License URI: http://www.gnu.org/licenses/agpl-3.0.html -- GitLab