From eec9a7978ca2f32fc3bcf5c381c7e003b63855ce Mon Sep 17 00:00:00 2001 From: Kevin Cristiano <kcristiano@kcristiano.com> Date: Sun, 7 Apr 2019 15:21:28 -0400 Subject: [PATCH] civicrm 5.12 release Signed-off-by: Kevin Cristiano <kcristiano@kcristiano.com> --- civicrm.php | 2 +- civicrm/CRM/ACL/BAO/ACL.php | 4 + civicrm/CRM/Activity/BAO/Activity.php | 34 +- civicrm/CRM/Activity/BAO/Query.php | 31 +- civicrm/CRM/Activity/Form/Activity.php | 31 +- civicrm/CRM/Activity/Form/Search.php | 54 - civicrm/CRM/Activity/Page/AJAX.php | 4 - civicrm/CRM/Activity/Selector/Activity.php | 11 +- civicrm/CRM/Activity/Selector/Search.php | 6 +- .../CRM/Admin/Form/Preferences/Display.php | 1 + civicrm/CRM/Admin/Form/SettingTrait.php | 6 + civicrm/CRM/Admin/Page/AJAX.php | 81 +- civicrm/CRM/Campaign/BAO/Campaign.php | 43 +- civicrm/CRM/Campaign/BAO/Survey.php | 1 - civicrm/CRM/Campaign/Form/Petition.php | 2 +- civicrm/CRM/Campaign/Form/Survey/Main.php | 2 +- civicrm/CRM/Campaign/Form/Task/Interview.php | 1 - civicrm/CRM/Campaign/Selector/Search.php | 8 +- civicrm/CRM/Case/BAO/Case.php | 64 +- civicrm/CRM/Case/Form/Activity.php | 10 +- .../CRM/Case/Form/Activity/ChangeCaseType.php | 11 +- civicrm/CRM/Case/Form/Activity/OpenCase.php | 2 + civicrm/CRM/Case/Form/AddToCaseAsRole.php | 2 +- civicrm/CRM/Case/Form/Search.php | 1 - civicrm/CRM/Case/Selector/Search.php | 2 +- civicrm/CRM/Case/XMLProcessor/Process.php | 2 +- civicrm/CRM/Case/XMLProcessor/Report.php | 6 +- civicrm/CRM/Contact/BAO/Contact.php | 87 +- civicrm/CRM/Contact/BAO/Group.php | 26 +- civicrm/CRM/Contact/BAO/GroupContact.php | 3 +- civicrm/CRM/Contact/BAO/GroupContactCache.php | 9 +- civicrm/CRM/Contact/BAO/Query.php | 858 ++++-- civicrm/CRM/Contact/Form/Edit/Address.php | 2 +- civicrm/CRM/Contact/Form/Search/Basic.php | 2 +- civicrm/CRM/Contact/Form/Search/Criteria.php | 8 +- civicrm/CRM/Contact/Form/Task.php | 4 +- .../CRM/Contact/Page/View/UserDashBoard.php | 25 +- civicrm/CRM/Contact/Selector.php | 6 +- civicrm/CRM/Contribute/BAO/Contribution.php | 581 ++-- .../CRM/Contribute/BAO/ContributionRecur.php | 28 +- civicrm/CRM/Contribute/BAO/Query.php | 86 +- .../CRM/Contribute/DAO/ContributionRecur.php | 55 +- .../CRM/Contribute/Form/AdditionalPayment.php | 89 +- .../Contribute/Form/Contribution/Confirm.php | 17 +- .../Contribute/Form/Contribution/ThankYou.php | 1 + .../CRM/Contribute/Form/ContributionView.php | 1 - civicrm/CRM/Contribute/Form/Search.php | 2 - civicrm/CRM/Contribute/Form/Task/Invoice.php | 8 +- .../Contribute/Form/Task/PDFLetterCommon.php | 3 + .../CRM/Contribute/Page/ContributionPage.php | 6 +- civicrm/CRM/Contribute/Page/Tab.php | 37 +- civicrm/CRM/Contribute/Page/UserDashboard.php | 61 +- civicrm/CRM/Contribute/Selector/Search.php | 17 +- civicrm/CRM/Core/BAO/Address.php | 5 + civicrm/CRM/Core/BAO/CustomField.php | 2 +- civicrm/CRM/Core/BAO/CustomValueTable.php | 2 +- civicrm/CRM/Core/BAO/FinancialTrxn.php | 77 +- civicrm/CRM/Core/BAO/MessageTemplate.php | 4 +- civicrm/CRM/Core/BAO/Navigation.php | 151 +- civicrm/CRM/Core/BAO/OptionValue.php | 4 +- civicrm/CRM/Core/BAO/UFGroup.php | 57 +- civicrm/CRM/Core/BAO/Website.php | 5 + civicrm/CRM/Core/DAO.php | 53 +- civicrm/CRM/Core/DAO/AllCoreTables.php | 2 +- civicrm/CRM/Core/Form.php | 23 +- civicrm/CRM/Core/Form/EntityFormTrait.php | 37 +- civicrm/CRM/Core/Form/Renderer.php | 8 +- civicrm/CRM/Core/Form/Search.php | 44 +- civicrm/CRM/Core/Form/Tag.php | 2 +- civicrm/CRM/Core/Payment.php | 29 +- civicrm/CRM/Core/Permission.php | 3 +- civicrm/CRM/Core/PseudoConstant.php | 2 +- civicrm/CRM/Core/Resources.php | 211 +- .../plugins/function.crmNavigationMenu.php | 74 - civicrm/CRM/Core/xml/Menu/Activity.xml | 2 +- civicrm/CRM/Core/xml/Menu/Admin.xml | 6 +- civicrm/CRM/Custom/Form/CustomData.php | 17 +- civicrm/CRM/Dedupe/BAO/Rule.php | 24 +- civicrm/CRM/Dedupe/DAO/Exception.php | 4 +- civicrm/CRM/Dedupe/Merger.php | 11 +- civicrm/CRM/Event/BAO/Event.php | 28 + civicrm/CRM/Event/BAO/ParticipantPayment.php | 4 +- civicrm/CRM/Event/BAO/Query.php | 4 +- .../CRM/Event/Form/ManageEvent/Conference.php | 2 +- .../CRM/Event/Form/ManageEvent/Location.php | 4 +- civicrm/CRM/Event/Form/Participant.php | 2 +- .../CRM/Event/Form/Registration/Register.php | 114 +- civicrm/CRM/Event/Form/Search.php | 1 - civicrm/CRM/Event/Selector/Search.php | 2 +- civicrm/CRM/Export/BAO/Export.php | 14 +- civicrm/CRM/Financial/BAO/ExportFormat.php | 2 +- civicrm/CRM/Financial/BAO/FinancialType.php | 23 +- civicrm/CRM/Financial/BAO/Payment.php | 426 ++- civicrm/CRM/Grant/Form/Search.php | 1 - civicrm/CRM/Logging/Schema.php | 47 +- civicrm/CRM/Mailing/Event/BAO/Reply.php | 21 +- civicrm/CRM/Mailing/Selector/Search.php | 2 +- civicrm/CRM/Member/BAO/Membership.php | 12 - civicrm/CRM/Member/BAO/MembershipLog.php | 1 - civicrm/CRM/Member/BAO/MembershipStatus.php | 4 - civicrm/CRM/Member/BAO/MembershipType.php | 2 - civicrm/CRM/Member/Form/Search.php | 2 - civicrm/CRM/Member/Page/DashBoard.php | 105 - civicrm/CRM/Member/Selector/Search.php | 2 +- civicrm/CRM/Pledge/Form/Search.php | 19 - civicrm/CRM/Profile/Form.php | 191 +- civicrm/CRM/Report/Form.php | 56 +- civicrm/CRM/Report/Form/Case/Detail.php | 338 ++- .../Report/Form/Contribute/Bookkeeping.php | 4 +- civicrm/CRM/Report/Form/Contribute/Detail.php | 16 + civicrm/CRM/Report/Form/Contribute/Repeat.php | 108 +- .../CRM/Report/Form/Contribute/SoftCredit.php | 15 +- .../CRM/Report/Form/Contribute/Summary.php | 74 +- civicrm/CRM/Report/Form/Event/Income.php | 2 +- .../Report/Form/Event/IncomeCountSummary.php | 2 +- .../Form/Event/ParticipantListCount.php | 4 +- .../Report/Form/Event/ParticipantListing.php | 17 +- civicrm/CRM/Report/Form/Event/Summary.php | 2 +- civicrm/CRM/Report/Form/Member/Detail.php | 10 + .../civicrm_msg_template.tpl | 67 - .../contribution_online_receipt_html.tpl | 395 --- .../contribution_online_receipt_text.tpl | 179 -- .../contribution_recurring_billing_html.tpl | 65 - ...contribution_recurring_billing_subject.tpl | 1 - .../contribution_recurring_billing_text.tpl | 23 - .../contribution_recurring_cancelled_html.tpl | 33 - ...ntribution_recurring_cancelled_subject.tpl | 1 - .../contribution_recurring_cancelled_text.tpl | 3 - .../contribution_recurring_edit_html.tpl | 36 - .../contribution_recurring_edit_subject.tpl | 1 - .../contribution_recurring_edit_text.tpl | 8 - .../contribution_recurring_notify_html.tpl | 125 - .../contribution_recurring_notify_text.tpl | 50 - .../event_online_receipt_html.tpl | 447 --- .../event_online_receipt_text.tpl | 282 -- .../membership_autorenew_billing_html.tpl | 65 - .../membership_autorenew_billing_subject.tpl | 1 - .../membership_autorenew_billing_text.tpl | 23 - .../membership_autorenew_cancelled_html.tpl | 70 - ...membership_autorenew_cancelled_subject.tpl | 1 - .../membership_autorenew_cancelled_text.tpl | 12 - .../membership_online_receipt_html.tpl | 517 ---- .../membership_online_receipt_text.tpl | 220 -- .../pledge_acknowledge_html.tpl | 132 - .../pledge_acknowledge_text.tpl | 55 - .../pledge_reminder_html.tpl | 107 - .../pledge_reminder_text.tpl | 33 - .../civicrm_msg_template.tpl | 16 - .../event_offline_receipt_html.tpl | 456 --- .../event_offline_receipt_text.tpl | 274 -- .../event_online_receipt_html.tpl | 457 --- .../event_online_receipt_text.tpl | 286 -- .../membership_offline_receipt_text.tpl | 90 - .../civicrm_msg_template.tpl | 16 - .../contribution_online_receipt_text.tpl | 179 -- .../civicrm_msg_template.tpl | 16 - .../event_online_receipt_html.tpl | 450 --- .../event_online_receipt_text.tpl | 277 -- civicrm/CRM/Upgrade/Form.php | 2 +- civicrm/CRM/Upgrade/Incremental/Base.php | 8 +- .../Upgrade/Incremental/MessageTemplates.php | 11 +- .../CRM/Upgrade/Incremental/SmartGroups.php | 156 +- .../Upgrade/Incremental/php/FiveEleven.php | 9 +- .../Upgrade/Incremental/php/FiveTwelve.php | 93 + .../CRM/Upgrade/Incremental/php/FourTwo.php | 948 ------- .../Upgrade/Incremental/sql/4.2.0.mysql.tpl | 34 - .../Upgrade/Incremental/sql/4.2.1.mysql.tpl | 4 - .../Upgrade/Incremental/sql/4.2.2.mysql.tpl | 21 - .../Upgrade/Incremental/sql/4.2.3.mysql.tpl | 49 - .../Upgrade/Incremental/sql/4.2.5.mysql.tpl | 10 - .../Upgrade/Incremental/sql/4.2.6.mysql.tpl | 2 - .../Upgrade/Incremental/sql/4.2.7.mysql.tpl | 15 - .../Upgrade/Incremental/sql/4.2.8.mysql.tpl | 2 - .../Upgrade/Incremental/sql/4.2.9.mysql.tpl | 2 - .../Incremental/sql/4.2.alpha1.mysql.tpl | 409 --- .../Incremental/sql/4.2.alpha2.mysql.tpl | 9 - .../Incremental/sql/4.2.alpha3.mysql.tpl | 2 - .../Incremental/sql/4.2.beta1.mysql.tpl | 37 - .../Incremental/sql/4.2.beta2.mysql.tpl | 1 - .../Incremental/sql/4.2.beta3.mysql.tpl | 2 - .../Incremental/sql/4.2.beta5.mysql.tpl | 1 - .../Incremental/sql/4.2.beta6.mysql.tpl | 23 - .../Upgrade/Incremental/sql/4.7.30.mysql.tpl | 2 +- .../Upgrade/Incremental/sql/4.7.32.mysql.tpl | 2 +- .../Upgrade/Incremental/sql/5.12.0.mysql.tpl | 1 + .../Incremental/sql/5.12.alpha1.mysql.tpl | 396 +++ .../Incremental/sql/5.12.beta1.mysql.tpl | 1 + .../Upgrade/Snapshot/V4p2/Price/BAO/Field.php | 634 ----- .../Snapshot/V4p2/Price/BAO/FieldValue.php | 225 -- .../Snapshot/V4p2/Price/BAO/LineItem.php | 311 --- .../Upgrade/Snapshot/V4p2/Price/BAO/Set.php | 1144 -------- .../Upgrade/Snapshot/V4p2/Price/DAO/Field.php | 444 --- .../Snapshot/V4p2/Price/DAO/FieldValue.php | 332 --- .../Snapshot/V4p2/Price/DAO/LineItem.php | 308 --- .../Upgrade/Snapshot/V4p2/Price/DAO/Set.php | 332 --- .../Snapshot/V4p2/Price/DAO/SetEntity.php | 233 -- civicrm/CRM/Utils/Address/BatchUpdate.php | 13 +- civicrm/CRM/Utils/Cache/ArrayDecorator.php | 3 + .../CRM/Utils/Cache/FastArrayDecorator.php | 2 + civicrm/CRM/Utils/Check/Component/Env.php | 88 +- civicrm/CRM/Utils/PDF/Utils.php | 25 +- civicrm/CRM/Utils/PagerAToZ.php | 2 +- civicrm/CRM/Utils/ReCAPTCHA.php | 9 +- civicrm/CRM/Utils/SQL/TempTable.php | 34 +- civicrm/CRM/Utils/System/DrupalBase.php | 18 +- civicrm/CRM/Utils/System/WordPress.php | 10 +- civicrm/CRM/Utils/Type.php | 10 + .../API/Subscriber/DynamicFKAuthorization.php | 11 +- civicrm/Civi/CCase/Analyzer.php | 3 +- civicrm/Civi/CCase/SequenceListener.php | 2 +- civicrm/Civi/Install/Requirements.php | 62 + civicrm/Civi/Test/Api3TestTrait.php | 7 +- civicrm/Civi/Token/TokenRow.php | 5 + civicrm/ang/crmUtil.js | 12 + civicrm/api/v3/Activity.php | 116 +- civicrm/api/v3/Contact.php | 20 +- .../Form/Event.php => api/v3/Exception.php} | 39 +- civicrm/api/v3/Payment.php | 46 + civicrm/bower.json | 1 + .../bower_components/jquery-ui/.bower.json | 2 +- .../bower_components/smartmenus/.bower.json | 58 + .../bower_components/smartmenus/LICENSE-MIT | 22 + civicrm/bower_components/smartmenus/README.md | 88 + .../bower_components/smartmenus/bower.json | 49 + .../jquery.smartmenus.bootstrap-4.css | 128 + .../jquery.smartmenus.bootstrap-4.js | 166 ++ .../jquery.smartmenus.bootstrap-4.min.js | 3 + .../bootstrap/jquery.smartmenus.bootstrap.css | 122 + .../bootstrap/jquery.smartmenus.bootstrap.js | 159 ++ .../jquery.smartmenus.bootstrap.min.js | 3 + .../keyboard/jquery.smartmenus.keyboard.js | 215 ++ .../jquery.smartmenus.keyboard.min.js | 3 + .../smartmenus/dist/css/sm-blue/_mixins.scss | 2 + .../dist/css/sm-blue/_sm-blue-theme.scss | 586 ++++ .../mixins/_round-corners-last-item.scss | 25 + .../mixins/_sub-items-indentation.scss | 15 + .../smartmenus/dist/css/sm-blue/sm-blue.css | 333 +++ .../dist/css/sm-blue/sm-blue.css.map | 7 + .../smartmenus/dist/css/sm-blue/sm-blue.scss | 4 + .../smartmenus/dist/css/sm-clean/_mixins.scss | 2 + .../dist/css/sm-clean/_sm-clean-theme.scss | 579 ++++ .../mixins/_round-corners-last-item.scss | 25 + .../mixins/_sub-items-indentation.scss | 15 + .../smartmenus/dist/css/sm-clean/sm-clean.css | 327 +++ .../dist/css/sm-clean/sm-clean.css.map | 7 + .../dist/css/sm-clean/sm-clean.scss | 4 + .../smartmenus/dist/css/sm-core-css.css | 14 + .../smartmenus/dist/css/sm-mint/_mixins.scss | 1 + .../dist/css/sm-mint/_sm-mint-theme.scss | 569 ++++ .../mixins/_sub-items-indentation.scss | 15 + .../smartmenus/dist/css/sm-mint/sm-mint.css | 331 +++ .../dist/css/sm-mint/sm-mint.css.map | 7 + .../smartmenus/dist/css/sm-mint/sm-mint.scss | 4 + .../dist/css/sm-simple/_mixins.scss | 1 + .../dist/css/sm-simple/_sm-simple-theme.scss | 446 +++ .../mixins/_sub-items-indentation.scss | 15 + .../dist/css/sm-simple/sm-simple.css | 249 ++ .../dist/css/sm-simple/sm-simple.css.map | 7 + .../dist/css/sm-simple/sm-simple.scss | 4 + .../smartmenus/dist/jquery.smartmenus.js | 1216 ++++++++ .../smartmenus/dist/jquery.smartmenus.min.js | 3 + .../bower_components/smartmenus/package.json | 53 + .../smartmenus/smartmenus.jquery.json | 42 + .../jquery.smartmenus.bootstrap-4.css | 128 + .../jquery.smartmenus.bootstrap-4.js | 167 ++ .../bootstrap/jquery.smartmenus.bootstrap.css | 122 + .../bootstrap/jquery.smartmenus.bootstrap.js | 160 ++ .../keyboard/jquery.smartmenus.keyboard.js | 216 ++ .../smartmenus/src/css/sm-blue/_mixins.scss | 2 + .../src/css/sm-blue/_sm-blue-theme.scss | 586 ++++ .../mixins/_round-corners-last-item.scss | 25 + .../mixins/_sub-items-indentation.scss | 15 + .../smartmenus/src/css/sm-blue/sm-blue.css | 333 +++ .../src/css/sm-blue/sm-blue.css.map | 7 + .../smartmenus/src/css/sm-blue/sm-blue.scss | 4 + .../smartmenus/src/css/sm-clean/_mixins.scss | 2 + .../src/css/sm-clean/_sm-clean-theme.scss | 579 ++++ .../mixins/_round-corners-last-item.scss | 25 + .../mixins/_sub-items-indentation.scss | 15 + .../smartmenus/src/css/sm-clean/sm-clean.css | 327 +++ .../src/css/sm-clean/sm-clean.css.map | 7 + .../smartmenus/src/css/sm-clean/sm-clean.scss | 4 + .../smartmenus/src/css/sm-core-css.css | 14 + .../smartmenus/src/css/sm-mint/_mixins.scss | 1 + .../src/css/sm-mint/_sm-mint-theme.scss | 569 ++++ .../mixins/_sub-items-indentation.scss | 15 + .../smartmenus/src/css/sm-mint/sm-mint.css | 331 +++ .../src/css/sm-mint/sm-mint.css.map | 7 + .../smartmenus/src/css/sm-mint/sm-mint.scss | 4 + .../smartmenus/src/css/sm-simple/_mixins.scss | 1 + .../src/css/sm-simple/_sm-simple-theme.scss | 446 +++ .../mixins/_sub-items-indentation.scss | 15 + .../src/css/sm-simple/sm-simple.css | 249 ++ .../src/css/sm-simple/sm-simple.css.map | 7 + .../src/css/sm-simple/sm-simple.scss | 4 + .../demo/bootstrap-4-navbar-fixed-bottom.html | 377 +++ .../demo/bootstrap-4-navbar-fixed-top.html | 377 +++ .../demo/bootstrap-4-navbar-static-top.html | 377 +++ .../src/demo/bootstrap-4-navbar.html | 373 +++ .../demo/bootstrap-navbar-fixed-bottom.html | 391 +++ .../src/demo/bootstrap-navbar-fixed-top.html | 391 +++ .../src/demo/bootstrap-navbar-static-top.html | 390 +++ .../smartmenus/src/demo/bootstrap-navbar.html | 386 +++ .../smartmenus/src/demo/index.html | 226 ++ .../src/demo/keyboard-navigation.html | 243 ++ .../smartmenus/src/jquery.smartmenus.js | 1217 ++++++++ .../smartmenus/src/libs/demo-assets/demo.css | 209 ++ .../src/libs/demo-assets/readme.txt | 3 + .../src/libs/demo-assets/shjs/shjs.css | 110 + .../src/libs/demo-assets/shjs/shjs.js | 20 + .../src/libs/demo-assets/themes-switcher.js | 246 ++ .../smartmenus/src/libs/jquery/jquery.js | 5 + civicrm/civicrm-version.php | 2 +- civicrm/composer.json | 18 +- civicrm/composer.lock | 258 +- civicrm/css/civicrm.css | 4 +- civicrm/css/civicrmNavigation.css | 181 -- civicrm/css/crm-menubar.css | 347 +++ civicrm/css/joomla.css | 26 +- civicrm/css/menubar-backdrop.css | 44 + civicrm/css/menubar-drupal7.css | 115 + civicrm/css/menubar-drupal8.css | 55 + civicrm/css/menubar-joomla.css | 29 + civicrm/css/menubar-wordpress.css | 59 + civicrm/extension-compatibility.json | 9 + civicrm/install/index.php | 61 + civicrm/js/Common.js | 58 +- civicrm/js/crm.backdrop.js | 14 +- civicrm/js/crm.drupal7.js | 5 - civicrm/js/crm.drupal8.js | 40 +- civicrm/js/crm.menubar.js | 483 ++++ civicrm/js/crm.wordpress.js | 16 + civicrm/package.json | 2 +- civicrm/packages/PEAR/FixPHP5PEARWarnings.php | 7 - civicrm/packages/PEAR5.php | 33 - .../packages/jquery/plugins/jquery.menu.js | 936 ------- .../jquery/plugins/jquery.menu.min.js | 1 - civicrm/release-notes.md | 13 +- civicrm/release-notes/5.12.0.md | 861 ++++++ civicrm/settings/Core.setting.php | 20 + civicrm/settings/Localization.setting.php | 2 +- civicrm/settings/Multisite.setting.php | 2 +- civicrm/sql/civicrm.mysql | 6 +- civicrm/sql/civicrm_data.mysql | 38 +- civicrm/sql/civicrm_generated.mysql | 2 +- .../templates/CRM/Activity/Form/Activity.tpl | 2 - .../CRM/Activity/Form/ActivityJs.tpl | 51 - .../CRM/Activity/Form/Search/Common.tpl | 7 +- .../CRM/Admin/Form/Preferences/Display.tpl | 7 + civicrm/templates/CRM/Case/Form/Activity.tpl | 4 - .../CRM/Case/Form/Activity/ChangeCaseType.tpl | 25 +- .../templates/CRM/Contact/Form/Contact.hlp | 4 +- .../templates/CRM/Contact/Form/Contact.tpl | 2 +- .../CRM/Contribute/Form/Selector.tpl | 7 - .../Contribute/Page/ContributionTotals.tpl | 17 +- .../CRM/Contribute/Page/UserDashboard.tpl | 2 + civicrm/templates/CRM/Core/AgeRange.tpl | 22 +- civicrm/templates/CRM/Core/Form/Field.tpl | 2 +- .../CRM/Event/Form/Registration/Register.tpl | 2 +- civicrm/templates/CRM/Group/Form/Search.tpl | 17 +- civicrm/templates/CRM/common/CMSPrint.tpl | 2 - civicrm/templates/CRM/common/accesskeys.hlp | 39 +- civicrm/templates/CRM/common/accesskeys.tpl | 8 +- civicrm/templates/CRM/common/joomla.tpl | 4 - civicrm/templates/CRM/common/l10n.js.tpl | 2 + civicrm/vendor/autoload.php | 2 +- .../vendor/composer/autoload_namespaces.php | 3 + civicrm/vendor/composer/autoload_psr4.php | 1 + civicrm/vendor/composer/autoload_real.php | 14 +- civicrm/vendor/composer/autoload_static.php | 31 +- civicrm/vendor/composer/include_paths.php | 3 + civicrm/vendor/composer/installed.json | 268 +- .../cweagans/composer-patches/.editorconfig | 11 + .../cweagans/composer-patches/.gitignore | 1 + .../cweagans/composer-patches/LICENSE.md | 9 + .../cweagans/composer-patches/README.md | 161 ++ .../cweagans/composer-patches/composer.json | 30 + .../cweagans/composer-patches/composer.lock | 1564 +++++++++++ .../composer-patches/phpunit.xml.dist | 18 + .../composer-patches/src/PatchEvent.php | 70 + .../composer-patches/src/PatchEvents.php | 30 + .../cweagans/composer-patches/src/Patches.php | 550 ++++ civicrm/vendor/pear/console_getopt/.gitignore | 6 + .../vendor/pear/console_getopt/.travis.yml | 9 + .../pear/console_getopt}/Console/Getopt.php | 216 +- civicrm/vendor/pear/console_getopt/LICENSE | 25 + .../vendor/pear/console_getopt/composer.json | 35 + civicrm/vendor/pear/mail/.gitignore | 4 + civicrm/vendor/pear/mail/.travis.yml | 19 + civicrm/vendor/pear/mail/LICENSE | 29 + .../{packages => vendor/pear/mail}/Mail.php | 59 +- .../pear/mail}/Mail/RFC822.php | 112 +- .../pear/mail}/Mail/mail.php | 49 +- .../pear/mail}/Mail/mock.php | 45 +- .../pear/mail}/Mail/null.php | 35 +- .../pear/mail}/Mail/sendmail.php | 80 +- .../pear/mail}/Mail/smtp.php | 121 +- .../pear/mail}/Mail/smtpmx.php | 40 +- civicrm/vendor/pear/mail/composer.json | 46 + .../pear/pear-core-minimal/composer.json | 32 + .../pear/pear-core-minimal/src/OS/Guess.php | 337 +++ .../pear/pear-core-minimal/src}/PEAR.php | 39 +- .../pear/pear-core-minimal/src/PEAR/Error.php | 14 + .../src}/PEAR/ErrorStack.php | 2 +- .../pear/pear-core-minimal/src}/System.php | 105 +- civicrm/vendor/phpoffice/common/.travis.yml | 6 +- civicrm/vendor/phpoffice/common/CHANGELOG.md | 18 +- civicrm/vendor/phpoffice/common/PATCHES.txt | 7 + civicrm/vendor/phpoffice/common/VERSION | 2 +- civicrm/vendor/phpoffice/common/composer.json | 2 +- .../vendor/phpoffice/common/phpunit.xml.dist | 5 +- .../src/Common/Adapter/Zip/PclZipAdapter.php | 13 - .../Common/Adapter/Zip/ZipArchiveAdapter.php | 20 +- .../src/Common/Adapter/Zip/ZipInterface.php | 20 + .../phpoffice/common/src/Common/File.php | 37 +- .../common/src/Common/Microsoft/OLERead.php | 34 +- .../src/Common}/Microsoft/PasswordEncoder.php | 13 +- .../phpoffice/common/src/Common/Text.php | 8 +- .../phpoffice/common/src/Common/XMLReader.php | 39 +- .../phpoffice/common/src/Common/XMLWriter.php | 20 +- civicrm/vendor/phpoffice/phpword/.gitignore | 23 - .../vendor/phpoffice/phpword/.scrutinizer.yml | 24 - civicrm/vendor/phpoffice/phpword/.travis.yml | 64 - .../phpword/.travis_shell_after_success.sh | 39 - civicrm/vendor/phpoffice/phpword/CHANGELOG.md | 55 +- .../vendor/phpoffice/phpword/CONTRIBUTING.md | 2 +- civicrm/vendor/phpoffice/phpword/PATCHES.txt | 7 + civicrm/vendor/phpoffice/phpword/README.md | 8 +- civicrm/vendor/phpoffice/phpword/VERSION | 1 - .../vendor/phpoffice/phpword/bootstrap.php | 2 +- .../vendor/phpoffice/phpword/composer.json | 42 +- .../vendor/phpoffice/phpword/phpmd.xml.dist | 33 - civicrm/vendor/phpoffice/phpword/phpstan.neon | 13 - .../vendor/phpoffice/phpword/phpunit.xml.dist | 28 - .../PhpWord/Collection/AbstractCollection.php | 12 +- .../src/PhpWord/Collection/Bookmarks.php | 2 +- .../phpword/src/PhpWord/Collection/Charts.php | 2 +- .../src/PhpWord/Collection/Comments.php | 2 +- .../src/PhpWord/Collection/Endnotes.php | 2 +- .../src/PhpWord/Collection/Footnotes.php | 2 +- .../phpword/src/PhpWord/Collection/Titles.php | 2 +- .../ComplexType/FootnoteProperties.php | 2 +- .../src/PhpWord/ComplexType/ProofState.php | 2 +- .../src/PhpWord/ComplexType/TblWidth.php | 59 + .../PhpWord/ComplexType/TrackChangesView.php | 2 +- .../src/PhpWord/Element/AbstractContainer.php | 58 +- .../src/PhpWord/Element/AbstractElement.php | 63 +- .../phpword/src/PhpWord/Element/Bookmark.php | 4 +- .../phpword/src/PhpWord/Element/Cell.php | 2 +- .../phpword/src/PhpWord/Element/Chart.php | 18 +- .../phpword/src/PhpWord/Element/CheckBox.php | 2 +- .../phpword/src/PhpWord/Element/Comment.php | 6 +- .../phpword/src/PhpWord/Element/Endnote.php | 2 +- .../phpword/src/PhpWord/Element/Field.php | 35 +- .../phpword/src/PhpWord/Element/Footer.php | 2 +- .../phpword/src/PhpWord/Element/Footnote.php | 2 +- .../phpword/src/PhpWord/Element/FormField.php | 2 +- .../phpword/src/PhpWord/Element/Header.php | 2 +- .../phpword/src/PhpWord/Element/Image.php | 43 +- .../phpword/src/PhpWord/Element/Line.php | 2 +- .../phpword/src/PhpWord/Element/Link.php | 2 +- .../phpword/src/PhpWord/Element/ListItem.php | 4 +- .../src/PhpWord/Element/ListItemRun.php | 2 +- .../Element/{Object.php => OLEObject.php} | 8 +- .../phpword/src/PhpWord/Element/PageBreak.php | 2 +- .../src/PhpWord/Element/PreserveText.php | 8 +- .../phpword/src/PhpWord/Element/Row.php | 2 +- .../phpword/src/PhpWord/Element/SDT.php | 2 +- .../phpword/src/PhpWord/Element/Section.php | 2 +- .../phpword/src/PhpWord/Element/Shape.php | 2 +- .../phpword/src/PhpWord/Element/TOC.php | 2 +- .../phpword/src/PhpWord/Element/Table.php | 42 +- .../phpword/src/PhpWord/Element/Text.php | 2 +- .../phpword/src/PhpWord/Element/TextBox.php | 2 +- .../phpword/src/PhpWord/Element/TextBreak.php | 2 +- .../phpword/src/PhpWord/Element/TextRun.php | 2 +- .../phpword/src/PhpWord/Element/Title.php | 22 +- .../src/PhpWord/Element/TrackChange.php | 33 +- .../src/PhpWord/Escaper/AbstractEscaper.php | 2 +- .../src/PhpWord/Escaper/EscaperInterface.php | 2 +- .../phpword/src/PhpWord/Escaper/RegExp.php | 2 +- .../phpword/src/PhpWord/Escaper/Rtf.php | 2 +- .../phpword/src/PhpWord/Escaper/Xml.php | 2 +- .../PhpWord/Exception/CopyFileException.php | 2 +- .../CreateTemporaryFileException.php | 2 +- .../src/PhpWord/Exception/Exception.php | 2 +- .../Exception/InvalidImageException.php | 2 +- .../Exception/InvalidObjectException.php | 2 +- .../Exception/InvalidStyleException.php | 2 +- .../UnsupportedImageTypeException.php | 2 +- .../phpword/src/PhpWord/IOFactory.php | 2 +- .../phpoffice/phpword/src/PhpWord/Media.php | 2 +- .../src/PhpWord/Metadata/Compatibility.php | 2 +- .../phpword/src/PhpWord/Metadata/DocInfo.php | 2 +- .../src/PhpWord/Metadata/Protection.php | 10 +- .../phpword/src/PhpWord/Metadata/Settings.php | 92 +- .../phpoffice/phpword/src/PhpWord/PhpWord.php | 45 +- .../src/PhpWord/Reader/AbstractReader.php | 2 +- .../phpword/src/PhpWord/Reader/HTML.php | 2 +- .../phpword/src/PhpWord/Reader/MsDoc.php | 2 +- .../phpword/src/PhpWord/Reader/ODText.php | 2 +- .../PhpWord/Reader/ODText/AbstractPart.php | 2 +- .../src/PhpWord/Reader/ODText/Content.php | 52 +- .../src/PhpWord/Reader/ODText/Meta.php | 2 +- .../phpword/src/PhpWord/Reader/RTF.php | 2 +- .../src/PhpWord/Reader/RTF/Document.php | 2 +- .../src/PhpWord/Reader/ReaderInterface.php | 2 +- .../phpword/src/PhpWord/Reader/Word2007.php | 2 +- .../PhpWord/Reader/Word2007/AbstractPart.php | 356 ++- .../PhpWord/Reader/Word2007/DocPropsApp.php | 2 +- .../PhpWord/Reader/Word2007/DocPropsCore.php | 2 +- .../Reader/Word2007/DocPropsCustom.php | 2 +- .../src/PhpWord/Reader/Word2007/Document.php | 2 +- .../src/PhpWord/Reader/Word2007/Endnotes.php | 2 +- .../src/PhpWord/Reader/Word2007/Footnotes.php | 45 +- .../src/PhpWord/Reader/Word2007/Numbering.php | 2 +- .../src/PhpWord/Reader/Word2007/Settings.php | 61 +- .../src/PhpWord/Reader/Word2007/Styles.php | 25 +- .../phpword/src/PhpWord/Settings.php | 2 +- .../src/PhpWord/Shared/AbstractEnum.php | 2 +- .../phpword/src/PhpWord/Shared/Converter.php | 2 +- .../phpword/src/PhpWord/Shared/Html.php | 269 +- .../phpword/src/PhpWord/Shared/OLERead.php | 2 +- .../phpword/src/PhpWord/Shared/ZipArchive.php | 2 +- .../src/PhpWord/SimpleType/DocProtect.php | 2 +- .../phpword/src/PhpWord/SimpleType/Jc.php | 2 +- .../src/PhpWord/SimpleType/JcTable.php | 2 +- .../PhpWord/SimpleType/LineSpacingRule.php | 2 +- .../src/PhpWord/SimpleType/NumberFormat.php | 2 +- .../src/PhpWord/SimpleType/TblWidth.php | 42 + .../src/PhpWord/SimpleType/TextAlignment.php | 2 +- .../phpword/src/PhpWord/SimpleType/Zoom.php | 2 +- .../phpoffice/phpword/src/PhpWord/Style.php | 28 +- .../src/PhpWord/Style/AbstractStyle.php | 2 +- .../phpword/src/PhpWord/Style/Border.php | 2 +- .../phpword/src/PhpWord/Style/Cell.php | 8 +- .../phpword/src/PhpWord/Style/Chart.php | 304 +- .../phpword/src/PhpWord/Style/Extrusion.php | 2 +- .../phpword/src/PhpWord/Style/Fill.php | 2 +- .../phpword/src/PhpWord/Style/Font.php | 69 +- .../phpword/src/PhpWord/Style/Frame.php | 153 +- .../phpword/src/PhpWord/Style/Image.php | 2 +- .../phpword/src/PhpWord/Style/Indentation.php | 2 +- .../phpword/src/PhpWord/Style/Language.php | 25 +- .../phpword/src/PhpWord/Style/Line.php | 2 +- .../src/PhpWord/Style/LineNumbering.php | 2 +- .../phpword/src/PhpWord/Style/ListItem.php | 2 +- .../phpword/src/PhpWord/Style/Numbering.php | 2 +- .../src/PhpWord/Style/NumberingLevel.php | 2 +- .../phpword/src/PhpWord/Style/Outline.php | 2 +- .../phpword/src/PhpWord/Style/Paper.php | 2 +- .../phpword/src/PhpWord/Style/Paragraph.php | 65 +- .../phpword/src/PhpWord/Style/Row.php | 2 +- .../phpword/src/PhpWord/Style/Section.php | 2 +- .../phpword/src/PhpWord/Style/Shading.php | 2 +- .../phpword/src/PhpWord/Style/Shadow.php | 2 +- .../phpword/src/PhpWord/Style/Shape.php | 2 +- .../phpword/src/PhpWord/Style/Spacing.php | 2 +- .../phpword/src/PhpWord/Style/TOC.php | 2 +- .../phpword/src/PhpWord/Style/Tab.php | 2 +- .../phpword/src/PhpWord/Style/Table.php | 164 +- .../src/PhpWord/Style/TablePosition.php | 410 +++ .../phpword/src/PhpWord/Style/TextBox.php | 2 +- .../phpword/src/PhpWord/Template.php | 2 +- .../phpword/src/PhpWord/TemplateProcessor.php | 11 +- .../src/PhpWord/Writer/AbstractWriter.php | 8 +- .../phpword/src/PhpWord/Writer/HTML.php | 2 +- .../Writer/HTML/Element/AbstractElement.php | 2 +- .../PhpWord/Writer/HTML/Element/Bookmark.php | 45 + .../PhpWord/Writer/HTML/Element/Container.php | 2 +- .../PhpWord/Writer/HTML/Element/Endnote.php | 2 +- .../PhpWord/Writer/HTML/Element/Footnote.php | 2 +- .../src/PhpWord/Writer/HTML/Element/Image.php | 2 +- .../src/PhpWord/Writer/HTML/Element/Link.php | 10 +- .../PhpWord/Writer/HTML/Element/ListItem.php | 2 +- .../PhpWord/Writer/HTML/Element/PageBreak.php | 2 +- .../src/PhpWord/Writer/HTML/Element/Table.php | 60 +- .../src/PhpWord/Writer/HTML/Element/Text.php | 67 +- .../PhpWord/Writer/HTML/Element/TextBreak.php | 2 +- .../PhpWord/Writer/HTML/Element/TextRun.php | 2 +- .../src/PhpWord/Writer/HTML/Element/Title.php | 16 +- .../PhpWord/Writer/HTML/Part/AbstractPart.php | 2 +- .../src/PhpWord/Writer/HTML/Part/Body.php | 2 +- .../src/PhpWord/Writer/HTML/Part/Head.php | 2 +- .../Writer/HTML/Style/AbstractStyle.php | 2 +- .../src/PhpWord/Writer/HTML/Style/Font.php | 2 +- .../src/PhpWord/Writer/HTML/Style/Generic.php | 2 +- .../src/PhpWord/Writer/HTML/Style/Image.php | 2 +- .../PhpWord/Writer/HTML/Style/Paragraph.php | 2 +- .../phpword/src/PhpWord/Writer/ODText.php | 2 +- .../Writer/ODText/Element/AbstractElement.php | 2 +- .../Writer/ODText/Element/Container.php | 2 +- .../PhpWord/Writer/ODText/Element/Image.php | 2 +- .../PhpWord/Writer/ODText/Element/Link.php | 2 +- .../Writer/ODText/Element/PageBreak.php | 2 +- .../PhpWord/Writer/ODText/Element/Table.php | 65 +- .../PhpWord/Writer/ODText/Element/Text.php | 60 +- .../Writer/ODText/Element/TextBreak.php | 2 +- .../PhpWord/Writer/ODText/Element/TextRun.php | 2 +- .../PhpWord/Writer/ODText/Element/Title.php | 10 +- .../Writer/ODText/Part/AbstractPart.php | 2 +- .../PhpWord/Writer/ODText/Part/Content.php | 69 +- .../PhpWord/Writer/ODText/Part/Manifest.php | 2 +- .../src/PhpWord/Writer/ODText/Part/Meta.php | 2 +- .../PhpWord/Writer/ODText/Part/Mimetype.php | 2 +- .../src/PhpWord/Writer/ODText/Part/Styles.php | 2 +- .../Writer/ODText/Style/AbstractStyle.php | 2 +- .../src/PhpWord/Writer/ODText/Style/Font.php | 2 +- .../src/PhpWord/Writer/ODText/Style/Image.php | 2 +- .../PhpWord/Writer/ODText/Style/Paragraph.php | 2 +- .../PhpWord/Writer/ODText/Style/Section.php | 2 +- .../src/PhpWord/Writer/ODText/Style/Table.php | 16 +- .../phpword/src/PhpWord/Writer/PDF.php | 2 +- .../PhpWord/Writer/PDF/AbstractRenderer.php | 2 +- .../phpword/src/PhpWord/Writer/PDF/DomPDF.php | 2 +- .../phpword/src/PhpWord/Writer/PDF/MPDF.php | 34 +- .../phpword/src/PhpWord/Writer/PDF/TCPDF.php | 2 +- .../phpword/src/PhpWord/Writer/RTF.php | 2 +- .../Writer/RTF/Element/AbstractElement.php | 2 +- .../PhpWord/Writer/RTF/Element/Container.php | 2 +- .../src/PhpWord/Writer/RTF/Element/Image.php | 2 +- .../src/PhpWord/Writer/RTF/Element/Link.php | 2 +- .../PhpWord/Writer/RTF/Element/ListItem.php | 2 +- .../PhpWord/Writer/RTF/Element/PageBreak.php | 2 +- .../src/PhpWord/Writer/RTF/Element/Table.php | 2 +- .../src/PhpWord/Writer/RTF/Element/Text.php | 4 +- .../PhpWord/Writer/RTF/Element/TextBreak.php | 2 +- .../PhpWord/Writer/RTF/Element/TextRun.php | 2 +- .../src/PhpWord/Writer/RTF/Element/Title.php | 2 +- .../PhpWord/Writer/RTF/Part/AbstractPart.php | 2 +- .../src/PhpWord/Writer/RTF/Part/Document.php | 2 +- .../src/PhpWord/Writer/RTF/Part/Header.php | 2 +- .../Writer/RTF/Style/AbstractStyle.php | 2 +- .../src/PhpWord/Writer/RTF/Style/Border.php | 2 +- .../src/PhpWord/Writer/RTF/Style/Font.php | 2 +- .../PhpWord/Writer/RTF/Style/Indentation.php | 45 + .../PhpWord/Writer/RTF/Style/Paragraph.php | 42 +- .../src/PhpWord/Writer/RTF/Style/Section.php | 2 +- .../src/PhpWord/Writer/RTF/Style/Tab.php | 49 + .../phpword/src/PhpWord/Writer/Word2007.php | 2 +- .../Word2007/Element/AbstractElement.php | 2 +- .../Writer/Word2007/Element/Bookmark.php | 2 +- .../PhpWord/Writer/Word2007/Element/Chart.php | 2 +- .../Writer/Word2007/Element/CheckBox.php | 2 +- .../Writer/Word2007/Element/Container.php | 4 +- .../Writer/Word2007/Element/Endnote.php | 2 +- .../PhpWord/Writer/Word2007/Element/Field.php | 65 +- .../Writer/Word2007/Element/Footnote.php | 2 +- .../Writer/Word2007/Element/FormField.php | 2 +- .../PhpWord/Writer/Word2007/Element/Image.php | 15 +- .../PhpWord/Writer/Word2007/Element/Line.php | 2 +- .../PhpWord/Writer/Word2007/Element/Link.php | 2 +- .../Writer/Word2007/Element/ListItem.php | 2 +- .../Writer/Word2007/Element/ListItemRun.php | 2 +- .../Element/{Object.php => OLEObject.php} | 8 +- .../Writer/Word2007/Element/PageBreak.php | 2 +- .../Word2007/Element/ParagraphAlignment.php | 2 +- .../Writer/Word2007/Element/PreserveText.php | 2 +- .../PhpWord/Writer/Word2007/Element/SDT.php | 2 +- .../PhpWord/Writer/Word2007/Element/Shape.php | 6 +- .../PhpWord/Writer/Word2007/Element/TOC.php | 2 +- .../PhpWord/Writer/Word2007/Element/Table.php | 18 +- .../Word2007/Element/TableAlignment.php | 2 +- .../PhpWord/Writer/Word2007/Element/Text.php | 56 +- .../Writer/Word2007/Element/TextBox.php | 2 +- .../Writer/Word2007/Element/TextBreak.php | 2 +- .../Writer/Word2007/Element/TextRun.php | 2 +- .../PhpWord/Writer/Word2007/Element/Title.php | 48 +- .../Writer/Word2007/Part/AbstractPart.php | 2 +- .../PhpWord/Writer/Word2007/Part/Chart.php | 140 +- .../PhpWord/Writer/Word2007/Part/Comments.php | 2 +- .../Writer/Word2007/Part/ContentTypes.php | 2 +- .../Writer/Word2007/Part/DocPropsApp.php | 2 +- .../Writer/Word2007/Part/DocPropsCore.php | 2 +- .../Writer/Word2007/Part/DocPropsCustom.php | 2 +- .../PhpWord/Writer/Word2007/Part/Document.php | 2 +- .../PhpWord/Writer/Word2007/Part/Endnotes.php | 2 +- .../Writer/Word2007/Part/FontTable.php | 2 +- .../PhpWord/Writer/Word2007/Part/Footer.php | 2 +- .../Writer/Word2007/Part/Footnotes.php | 2 +- .../PhpWord/Writer/Word2007/Part/Header.php | 2 +- .../Writer/Word2007/Part/Numbering.php | 2 +- .../src/PhpWord/Writer/Word2007/Part/Rels.php | 2 +- .../Writer/Word2007/Part/RelsDocument.php | 2 +- .../PhpWord/Writer/Word2007/Part/RelsPart.php | 2 +- .../PhpWord/Writer/Word2007/Part/Settings.php | 49 +- .../PhpWord/Writer/Word2007/Part/Styles.php | 35 +- .../PhpWord/Writer/Word2007/Part/Theme.php | 2 +- .../Writer/Word2007/Part/WebSettings.php | 2 +- .../Writer/Word2007/Style/AbstractStyle.php | 2 +- .../PhpWord/Writer/Word2007/Style/Cell.php | 2 +- .../Writer/Word2007/Style/Extrusion.php | 2 +- .../PhpWord/Writer/Word2007/Style/Fill.php | 2 +- .../PhpWord/Writer/Word2007/Style/Font.php | 12 +- .../PhpWord/Writer/Word2007/Style/Frame.php | 15 +- .../PhpWord/Writer/Word2007/Style/Image.php | 2 +- .../Writer/Word2007/Style/Indentation.php | 2 +- .../PhpWord/Writer/Word2007/Style/Line.php | 2 +- .../Writer/Word2007/Style/LineNumbering.php | 2 +- .../Writer/Word2007/Style/MarginBorder.php | 2 +- .../PhpWord/Writer/Word2007/Style/Outline.php | 2 +- .../Writer/Word2007/Style/Paragraph.php | 7 +- .../src/PhpWord/Writer/Word2007/Style/Row.php | 2 +- .../PhpWord/Writer/Word2007/Style/Section.php | 2 +- .../PhpWord/Writer/Word2007/Style/Shading.php | 2 +- .../PhpWord/Writer/Word2007/Style/Shadow.php | 2 +- .../PhpWord/Writer/Word2007/Style/Shape.php | 2 +- .../PhpWord/Writer/Word2007/Style/Spacing.php | 2 +- .../src/PhpWord/Writer/Word2007/Style/Tab.php | 2 +- .../PhpWord/Writer/Word2007/Style/Table.php | 63 +- .../Writer/Word2007/Style/TablePosition.php | 65 + .../PhpWord/Writer/Word2007/Style/TextBox.php | 2 +- .../src/PhpWord/Writer/WriterInterface.php | 2 +- .../xml/schema/Contribute/Contribution.xml | 4 +- .../schema/Contribute/ContributionRecur.xml | 51 +- civicrm/xml/schema/Dedupe/Exception.xml | 2 + .../payment_or_refund_notification_html.tpl | 8 +- .../payment_or_refund_notification_text.tpl | 10 +- civicrm/xml/version.xml | 2 +- wp-cli/civicrm.php | 2455 +++++++++-------- 720 files changed, 30863 insertions(+), 17593 deletions(-) delete mode 100644 civicrm/CRM/Core/Smarty/plugins/function.crmNavigationMenu.php delete mode 100644 civicrm/CRM/Upgrade/4.2.alpha1.msg_template/civicrm_msg_template.tpl delete mode 100644 civicrm/CRM/Upgrade/4.2.alpha1.msg_template/message_templates/contribution_online_receipt_html.tpl delete mode 100644 civicrm/CRM/Upgrade/4.2.alpha1.msg_template/message_templates/contribution_online_receipt_text.tpl delete mode 100644 civicrm/CRM/Upgrade/4.2.alpha1.msg_template/message_templates/contribution_recurring_billing_html.tpl delete mode 100644 civicrm/CRM/Upgrade/4.2.alpha1.msg_template/message_templates/contribution_recurring_billing_subject.tpl delete mode 100644 civicrm/CRM/Upgrade/4.2.alpha1.msg_template/message_templates/contribution_recurring_billing_text.tpl delete mode 100644 civicrm/CRM/Upgrade/4.2.alpha1.msg_template/message_templates/contribution_recurring_cancelled_html.tpl delete mode 100644 civicrm/CRM/Upgrade/4.2.alpha1.msg_template/message_templates/contribution_recurring_cancelled_subject.tpl delete mode 100644 civicrm/CRM/Upgrade/4.2.alpha1.msg_template/message_templates/contribution_recurring_cancelled_text.tpl delete mode 100644 civicrm/CRM/Upgrade/4.2.alpha1.msg_template/message_templates/contribution_recurring_edit_html.tpl delete mode 100644 civicrm/CRM/Upgrade/4.2.alpha1.msg_template/message_templates/contribution_recurring_edit_subject.tpl delete mode 100644 civicrm/CRM/Upgrade/4.2.alpha1.msg_template/message_templates/contribution_recurring_edit_text.tpl delete mode 100644 civicrm/CRM/Upgrade/4.2.alpha1.msg_template/message_templates/contribution_recurring_notify_html.tpl delete mode 100644 civicrm/CRM/Upgrade/4.2.alpha1.msg_template/message_templates/contribution_recurring_notify_text.tpl delete mode 100644 civicrm/CRM/Upgrade/4.2.alpha1.msg_template/message_templates/event_online_receipt_html.tpl delete mode 100644 civicrm/CRM/Upgrade/4.2.alpha1.msg_template/message_templates/event_online_receipt_text.tpl delete mode 100644 civicrm/CRM/Upgrade/4.2.alpha1.msg_template/message_templates/membership_autorenew_billing_html.tpl delete mode 100644 civicrm/CRM/Upgrade/4.2.alpha1.msg_template/message_templates/membership_autorenew_billing_subject.tpl delete mode 100644 civicrm/CRM/Upgrade/4.2.alpha1.msg_template/message_templates/membership_autorenew_billing_text.tpl delete mode 100644 civicrm/CRM/Upgrade/4.2.alpha1.msg_template/message_templates/membership_autorenew_cancelled_html.tpl delete mode 100644 civicrm/CRM/Upgrade/4.2.alpha1.msg_template/message_templates/membership_autorenew_cancelled_subject.tpl delete mode 100644 civicrm/CRM/Upgrade/4.2.alpha1.msg_template/message_templates/membership_autorenew_cancelled_text.tpl delete mode 100644 civicrm/CRM/Upgrade/4.2.alpha1.msg_template/message_templates/membership_online_receipt_html.tpl delete mode 100644 civicrm/CRM/Upgrade/4.2.alpha1.msg_template/message_templates/membership_online_receipt_text.tpl delete mode 100644 civicrm/CRM/Upgrade/4.2.alpha1.msg_template/message_templates/pledge_acknowledge_html.tpl delete mode 100644 civicrm/CRM/Upgrade/4.2.alpha1.msg_template/message_templates/pledge_acknowledge_text.tpl delete mode 100644 civicrm/CRM/Upgrade/4.2.alpha1.msg_template/message_templates/pledge_reminder_html.tpl delete mode 100644 civicrm/CRM/Upgrade/4.2.alpha1.msg_template/message_templates/pledge_reminder_text.tpl delete mode 100644 civicrm/CRM/Upgrade/4.2.alpha2.msg_template/civicrm_msg_template.tpl delete mode 100644 civicrm/CRM/Upgrade/4.2.alpha2.msg_template/message_templates/event_offline_receipt_html.tpl delete mode 100644 civicrm/CRM/Upgrade/4.2.alpha2.msg_template/message_templates/event_offline_receipt_text.tpl delete mode 100644 civicrm/CRM/Upgrade/4.2.alpha2.msg_template/message_templates/event_online_receipt_html.tpl delete mode 100644 civicrm/CRM/Upgrade/4.2.alpha2.msg_template/message_templates/event_online_receipt_text.tpl delete mode 100644 civicrm/CRM/Upgrade/4.2.alpha2.msg_template/message_templates/membership_offline_receipt_text.tpl delete mode 100644 civicrm/CRM/Upgrade/4.2.alpha3.msg_template/civicrm_msg_template.tpl delete mode 100644 civicrm/CRM/Upgrade/4.2.alpha3.msg_template/message_templates/contribution_online_receipt_text.tpl delete mode 100644 civicrm/CRM/Upgrade/4.2.beta3.msg_template/civicrm_msg_template.tpl delete mode 100644 civicrm/CRM/Upgrade/4.2.beta3.msg_template/message_templates/event_online_receipt_html.tpl delete mode 100644 civicrm/CRM/Upgrade/4.2.beta3.msg_template/message_templates/event_online_receipt_text.tpl create mode 100644 civicrm/CRM/Upgrade/Incremental/php/FiveTwelve.php delete mode 100644 civicrm/CRM/Upgrade/Incremental/php/FourTwo.php delete mode 100644 civicrm/CRM/Upgrade/Incremental/sql/4.2.0.mysql.tpl delete mode 100644 civicrm/CRM/Upgrade/Incremental/sql/4.2.1.mysql.tpl delete mode 100644 civicrm/CRM/Upgrade/Incremental/sql/4.2.2.mysql.tpl delete mode 100644 civicrm/CRM/Upgrade/Incremental/sql/4.2.3.mysql.tpl delete mode 100644 civicrm/CRM/Upgrade/Incremental/sql/4.2.5.mysql.tpl delete mode 100644 civicrm/CRM/Upgrade/Incremental/sql/4.2.6.mysql.tpl delete mode 100644 civicrm/CRM/Upgrade/Incremental/sql/4.2.7.mysql.tpl delete mode 100644 civicrm/CRM/Upgrade/Incremental/sql/4.2.8.mysql.tpl delete mode 100644 civicrm/CRM/Upgrade/Incremental/sql/4.2.9.mysql.tpl delete mode 100644 civicrm/CRM/Upgrade/Incremental/sql/4.2.alpha1.mysql.tpl delete mode 100644 civicrm/CRM/Upgrade/Incremental/sql/4.2.alpha2.mysql.tpl delete mode 100644 civicrm/CRM/Upgrade/Incremental/sql/4.2.alpha3.mysql.tpl delete mode 100644 civicrm/CRM/Upgrade/Incremental/sql/4.2.beta1.mysql.tpl delete mode 100644 civicrm/CRM/Upgrade/Incremental/sql/4.2.beta2.mysql.tpl delete mode 100644 civicrm/CRM/Upgrade/Incremental/sql/4.2.beta3.mysql.tpl delete mode 100644 civicrm/CRM/Upgrade/Incremental/sql/4.2.beta5.mysql.tpl delete mode 100644 civicrm/CRM/Upgrade/Incremental/sql/4.2.beta6.mysql.tpl create mode 100644 civicrm/CRM/Upgrade/Incremental/sql/5.12.0.mysql.tpl create mode 100644 civicrm/CRM/Upgrade/Incremental/sql/5.12.alpha1.mysql.tpl create mode 100644 civicrm/CRM/Upgrade/Incremental/sql/5.12.beta1.mysql.tpl delete mode 100644 civicrm/CRM/Upgrade/Snapshot/V4p2/Price/BAO/Field.php delete mode 100644 civicrm/CRM/Upgrade/Snapshot/V4p2/Price/BAO/FieldValue.php delete mode 100644 civicrm/CRM/Upgrade/Snapshot/V4p2/Price/BAO/LineItem.php delete mode 100644 civicrm/CRM/Upgrade/Snapshot/V4p2/Price/BAO/Set.php delete mode 100644 civicrm/CRM/Upgrade/Snapshot/V4p2/Price/DAO/Field.php delete mode 100644 civicrm/CRM/Upgrade/Snapshot/V4p2/Price/DAO/FieldValue.php delete mode 100644 civicrm/CRM/Upgrade/Snapshot/V4p2/Price/DAO/LineItem.php delete mode 100644 civicrm/CRM/Upgrade/Snapshot/V4p2/Price/DAO/Set.php delete mode 100644 civicrm/CRM/Upgrade/Snapshot/V4p2/Price/DAO/SetEntity.php rename civicrm/{CRM/Report/Form/Event.php => api/v3/Exception.php} (64%) create mode 100644 civicrm/bower_components/smartmenus/.bower.json create mode 100644 civicrm/bower_components/smartmenus/LICENSE-MIT create mode 100644 civicrm/bower_components/smartmenus/README.md create mode 100644 civicrm/bower_components/smartmenus/bower.json create mode 100644 civicrm/bower_components/smartmenus/dist/addons/bootstrap-4/jquery.smartmenus.bootstrap-4.css create mode 100644 civicrm/bower_components/smartmenus/dist/addons/bootstrap-4/jquery.smartmenus.bootstrap-4.js create mode 100644 civicrm/bower_components/smartmenus/dist/addons/bootstrap-4/jquery.smartmenus.bootstrap-4.min.js create mode 100644 civicrm/bower_components/smartmenus/dist/addons/bootstrap/jquery.smartmenus.bootstrap.css create mode 100644 civicrm/bower_components/smartmenus/dist/addons/bootstrap/jquery.smartmenus.bootstrap.js create mode 100644 civicrm/bower_components/smartmenus/dist/addons/bootstrap/jquery.smartmenus.bootstrap.min.js create mode 100644 civicrm/bower_components/smartmenus/dist/addons/keyboard/jquery.smartmenus.keyboard.js create mode 100644 civicrm/bower_components/smartmenus/dist/addons/keyboard/jquery.smartmenus.keyboard.min.js create mode 100644 civicrm/bower_components/smartmenus/dist/css/sm-blue/_mixins.scss create mode 100644 civicrm/bower_components/smartmenus/dist/css/sm-blue/_sm-blue-theme.scss create mode 100644 civicrm/bower_components/smartmenus/dist/css/sm-blue/mixins/_round-corners-last-item.scss create mode 100644 civicrm/bower_components/smartmenus/dist/css/sm-blue/mixins/_sub-items-indentation.scss create mode 100644 civicrm/bower_components/smartmenus/dist/css/sm-blue/sm-blue.css create mode 100644 civicrm/bower_components/smartmenus/dist/css/sm-blue/sm-blue.css.map create mode 100644 civicrm/bower_components/smartmenus/dist/css/sm-blue/sm-blue.scss create mode 100644 civicrm/bower_components/smartmenus/dist/css/sm-clean/_mixins.scss create mode 100644 civicrm/bower_components/smartmenus/dist/css/sm-clean/_sm-clean-theme.scss create mode 100644 civicrm/bower_components/smartmenus/dist/css/sm-clean/mixins/_round-corners-last-item.scss create mode 100644 civicrm/bower_components/smartmenus/dist/css/sm-clean/mixins/_sub-items-indentation.scss create mode 100644 civicrm/bower_components/smartmenus/dist/css/sm-clean/sm-clean.css create mode 100644 civicrm/bower_components/smartmenus/dist/css/sm-clean/sm-clean.css.map create mode 100644 civicrm/bower_components/smartmenus/dist/css/sm-clean/sm-clean.scss create mode 100644 civicrm/bower_components/smartmenus/dist/css/sm-core-css.css create mode 100644 civicrm/bower_components/smartmenus/dist/css/sm-mint/_mixins.scss create mode 100644 civicrm/bower_components/smartmenus/dist/css/sm-mint/_sm-mint-theme.scss create mode 100644 civicrm/bower_components/smartmenus/dist/css/sm-mint/mixins/_sub-items-indentation.scss create mode 100644 civicrm/bower_components/smartmenus/dist/css/sm-mint/sm-mint.css create mode 100644 civicrm/bower_components/smartmenus/dist/css/sm-mint/sm-mint.css.map create mode 100644 civicrm/bower_components/smartmenus/dist/css/sm-mint/sm-mint.scss create mode 100644 civicrm/bower_components/smartmenus/dist/css/sm-simple/_mixins.scss create mode 100644 civicrm/bower_components/smartmenus/dist/css/sm-simple/_sm-simple-theme.scss create mode 100644 civicrm/bower_components/smartmenus/dist/css/sm-simple/mixins/_sub-items-indentation.scss create mode 100644 civicrm/bower_components/smartmenus/dist/css/sm-simple/sm-simple.css create mode 100644 civicrm/bower_components/smartmenus/dist/css/sm-simple/sm-simple.css.map create mode 100644 civicrm/bower_components/smartmenus/dist/css/sm-simple/sm-simple.scss create mode 100644 civicrm/bower_components/smartmenus/dist/jquery.smartmenus.js create mode 100644 civicrm/bower_components/smartmenus/dist/jquery.smartmenus.min.js create mode 100644 civicrm/bower_components/smartmenus/package.json create mode 100644 civicrm/bower_components/smartmenus/smartmenus.jquery.json create mode 100644 civicrm/bower_components/smartmenus/src/addons/bootstrap-4/jquery.smartmenus.bootstrap-4.css create mode 100644 civicrm/bower_components/smartmenus/src/addons/bootstrap-4/jquery.smartmenus.bootstrap-4.js create mode 100644 civicrm/bower_components/smartmenus/src/addons/bootstrap/jquery.smartmenus.bootstrap.css create mode 100644 civicrm/bower_components/smartmenus/src/addons/bootstrap/jquery.smartmenus.bootstrap.js create mode 100644 civicrm/bower_components/smartmenus/src/addons/keyboard/jquery.smartmenus.keyboard.js create mode 100644 civicrm/bower_components/smartmenus/src/css/sm-blue/_mixins.scss create mode 100644 civicrm/bower_components/smartmenus/src/css/sm-blue/_sm-blue-theme.scss create mode 100644 civicrm/bower_components/smartmenus/src/css/sm-blue/mixins/_round-corners-last-item.scss create mode 100644 civicrm/bower_components/smartmenus/src/css/sm-blue/mixins/_sub-items-indentation.scss create mode 100644 civicrm/bower_components/smartmenus/src/css/sm-blue/sm-blue.css create mode 100644 civicrm/bower_components/smartmenus/src/css/sm-blue/sm-blue.css.map create mode 100644 civicrm/bower_components/smartmenus/src/css/sm-blue/sm-blue.scss create mode 100644 civicrm/bower_components/smartmenus/src/css/sm-clean/_mixins.scss create mode 100644 civicrm/bower_components/smartmenus/src/css/sm-clean/_sm-clean-theme.scss create mode 100644 civicrm/bower_components/smartmenus/src/css/sm-clean/mixins/_round-corners-last-item.scss create mode 100644 civicrm/bower_components/smartmenus/src/css/sm-clean/mixins/_sub-items-indentation.scss create mode 100644 civicrm/bower_components/smartmenus/src/css/sm-clean/sm-clean.css create mode 100644 civicrm/bower_components/smartmenus/src/css/sm-clean/sm-clean.css.map create mode 100644 civicrm/bower_components/smartmenus/src/css/sm-clean/sm-clean.scss create mode 100644 civicrm/bower_components/smartmenus/src/css/sm-core-css.css create mode 100644 civicrm/bower_components/smartmenus/src/css/sm-mint/_mixins.scss create mode 100644 civicrm/bower_components/smartmenus/src/css/sm-mint/_sm-mint-theme.scss create mode 100644 civicrm/bower_components/smartmenus/src/css/sm-mint/mixins/_sub-items-indentation.scss create mode 100644 civicrm/bower_components/smartmenus/src/css/sm-mint/sm-mint.css create mode 100644 civicrm/bower_components/smartmenus/src/css/sm-mint/sm-mint.css.map create mode 100644 civicrm/bower_components/smartmenus/src/css/sm-mint/sm-mint.scss create mode 100644 civicrm/bower_components/smartmenus/src/css/sm-simple/_mixins.scss create mode 100644 civicrm/bower_components/smartmenus/src/css/sm-simple/_sm-simple-theme.scss create mode 100644 civicrm/bower_components/smartmenus/src/css/sm-simple/mixins/_sub-items-indentation.scss create mode 100644 civicrm/bower_components/smartmenus/src/css/sm-simple/sm-simple.css create mode 100644 civicrm/bower_components/smartmenus/src/css/sm-simple/sm-simple.css.map create mode 100644 civicrm/bower_components/smartmenus/src/css/sm-simple/sm-simple.scss create mode 100644 civicrm/bower_components/smartmenus/src/demo/bootstrap-4-navbar-fixed-bottom.html create mode 100644 civicrm/bower_components/smartmenus/src/demo/bootstrap-4-navbar-fixed-top.html create mode 100644 civicrm/bower_components/smartmenus/src/demo/bootstrap-4-navbar-static-top.html create mode 100644 civicrm/bower_components/smartmenus/src/demo/bootstrap-4-navbar.html create mode 100644 civicrm/bower_components/smartmenus/src/demo/bootstrap-navbar-fixed-bottom.html create mode 100644 civicrm/bower_components/smartmenus/src/demo/bootstrap-navbar-fixed-top.html create mode 100644 civicrm/bower_components/smartmenus/src/demo/bootstrap-navbar-static-top.html create mode 100644 civicrm/bower_components/smartmenus/src/demo/bootstrap-navbar.html create mode 100644 civicrm/bower_components/smartmenus/src/demo/index.html create mode 100644 civicrm/bower_components/smartmenus/src/demo/keyboard-navigation.html create mode 100644 civicrm/bower_components/smartmenus/src/jquery.smartmenus.js create mode 100644 civicrm/bower_components/smartmenus/src/libs/demo-assets/demo.css create mode 100644 civicrm/bower_components/smartmenus/src/libs/demo-assets/readme.txt create mode 100644 civicrm/bower_components/smartmenus/src/libs/demo-assets/shjs/shjs.css create mode 100644 civicrm/bower_components/smartmenus/src/libs/demo-assets/shjs/shjs.js create mode 100644 civicrm/bower_components/smartmenus/src/libs/demo-assets/themes-switcher.js create mode 100644 civicrm/bower_components/smartmenus/src/libs/jquery/jquery.js delete mode 100644 civicrm/css/civicrmNavigation.css create mode 100644 civicrm/css/crm-menubar.css create mode 100644 civicrm/css/menubar-backdrop.css create mode 100644 civicrm/css/menubar-drupal7.css create mode 100644 civicrm/css/menubar-drupal8.css create mode 100644 civicrm/css/menubar-joomla.css create mode 100644 civicrm/css/menubar-wordpress.css create mode 100644 civicrm/js/crm.menubar.js delete mode 100644 civicrm/packages/PEAR/FixPHP5PEARWarnings.php delete mode 100644 civicrm/packages/PEAR5.php delete mode 100755 civicrm/packages/jquery/plugins/jquery.menu.js delete mode 100644 civicrm/packages/jquery/plugins/jquery.menu.min.js create mode 100644 civicrm/release-notes/5.12.0.md delete mode 100644 civicrm/templates/CRM/Activity/Form/ActivityJs.tpl create mode 100644 civicrm/vendor/cweagans/composer-patches/.editorconfig create mode 100644 civicrm/vendor/cweagans/composer-patches/.gitignore create mode 100644 civicrm/vendor/cweagans/composer-patches/LICENSE.md create mode 100644 civicrm/vendor/cweagans/composer-patches/README.md create mode 100644 civicrm/vendor/cweagans/composer-patches/composer.json create mode 100644 civicrm/vendor/cweagans/composer-patches/composer.lock create mode 100644 civicrm/vendor/cweagans/composer-patches/phpunit.xml.dist create mode 100644 civicrm/vendor/cweagans/composer-patches/src/PatchEvent.php create mode 100644 civicrm/vendor/cweagans/composer-patches/src/PatchEvents.php create mode 100644 civicrm/vendor/cweagans/composer-patches/src/Patches.php create mode 100644 civicrm/vendor/pear/console_getopt/.gitignore create mode 100644 civicrm/vendor/pear/console_getopt/.travis.yml rename civicrm/{packages => vendor/pear/console_getopt}/Console/Getopt.php (54%) create mode 100644 civicrm/vendor/pear/console_getopt/LICENSE create mode 100644 civicrm/vendor/pear/console_getopt/composer.json create mode 100644 civicrm/vendor/pear/mail/.gitignore create mode 100644 civicrm/vendor/pear/mail/.travis.yml create mode 100644 civicrm/vendor/pear/mail/LICENSE rename civicrm/{packages => vendor/pear/mail}/Mail.php (85%) rename civicrm/{packages => vendor/pear/mail}/Mail/RFC822.php (91%) rename civicrm/{packages => vendor/pear/mail}/Mail/mail.php (80%) rename civicrm/{packages => vendor/pear/mail}/Mail/mock.php (77%) rename civicrm/{packages => vendor/pear/mail}/Mail/null.php (71%) rename civicrm/{packages => vendor/pear/mail}/Mail/sendmail.php (68%) rename civicrm/{packages => vendor/pear/mail}/Mail/smtp.php (82%) rename civicrm/{packages => vendor/pear/mail}/Mail/smtpmx.php (93%) create mode 100644 civicrm/vendor/pear/mail/composer.json create mode 100644 civicrm/vendor/pear/pear-core-minimal/composer.json create mode 100644 civicrm/vendor/pear/pear-core-minimal/src/OS/Guess.php rename civicrm/{packages => vendor/pear/pear-core-minimal/src}/PEAR.php (96%) create mode 100644 civicrm/vendor/pear/pear-core-minimal/src/PEAR/Error.php rename civicrm/{packages => vendor/pear/pear-core-minimal/src}/PEAR/ErrorStack.php (99%) rename civicrm/{packages => vendor/pear/pear-core-minimal/src}/System.php (88%) create mode 100644 civicrm/vendor/phpoffice/common/PATCHES.txt rename civicrm/vendor/phpoffice/{phpword/src/PhpWord/Shared => common/src/Common}/Microsoft/PasswordEncoder.php (95%) delete mode 100644 civicrm/vendor/phpoffice/phpword/.gitignore delete mode 100644 civicrm/vendor/phpoffice/phpword/.scrutinizer.yml delete mode 100644 civicrm/vendor/phpoffice/phpword/.travis.yml delete mode 100644 civicrm/vendor/phpoffice/phpword/.travis_shell_after_success.sh create mode 100644 civicrm/vendor/phpoffice/phpword/PATCHES.txt delete mode 100644 civicrm/vendor/phpoffice/phpword/VERSION delete mode 100644 civicrm/vendor/phpoffice/phpword/phpmd.xml.dist delete mode 100644 civicrm/vendor/phpoffice/phpword/phpstan.neon delete mode 100644 civicrm/vendor/phpoffice/phpword/phpunit.xml.dist create mode 100644 civicrm/vendor/phpoffice/phpword/src/PhpWord/ComplexType/TblWidth.php rename civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/{Object.php => OLEObject.php} (96%) create mode 100644 civicrm/vendor/phpoffice/phpword/src/PhpWord/SimpleType/TblWidth.php create mode 100644 civicrm/vendor/phpoffice/phpword/src/PhpWord/Style/TablePosition.php create mode 100644 civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/HTML/Element/Bookmark.php create mode 100644 civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/RTF/Style/Indentation.php create mode 100644 civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/RTF/Style/Tab.php rename civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Element/{Object.php => OLEObject.php} (93%) create mode 100644 civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Style/TablePosition.php diff --git a/civicrm.php b/civicrm.php index 83de29bece..d69b86f1be 100644 --- a/civicrm.php +++ b/civicrm.php @@ -2,7 +2,7 @@ /* Plugin Name: CiviCRM Description: CiviCRM - Growing and Sustaining Relationships -Version: 5.11.0 +Version: 5.12.0 Author: CiviCRM LLC Author URI: https://civicrm.org/ Plugin URI: https://wiki.civicrm.org/confluence/display/CRMDOC/Installing+CiviCRM+for+WordPress diff --git a/civicrm/CRM/ACL/BAO/ACL.php b/civicrm/CRM/ACL/BAO/ACL.php index 8e6d14ffb1..7c0eb1af7c 100644 --- a/civicrm/CRM/ACL/BAO/ACL.php +++ b/civicrm/CRM/ACL/BAO/ACL.php @@ -840,6 +840,10 @@ SELECT g.* return Civi::$statics[__CLASS__]['permissioned_groups'][$userCacheKey]; } + if ($allGroups == NULL) { + $allGroups = CRM_Contact_BAO_Contact::buildOptions('group_id', NULL, ['onlyActive' => FALSE]); + } + $acls = CRM_ACL_BAO_Cache::build($contactID); $ids = array(); diff --git a/civicrm/CRM/Activity/BAO/Activity.php b/civicrm/CRM/Activity/BAO/Activity.php index 7249a8e6d6..92656c7593 100644 --- a/civicrm/CRM/Activity/BAO/Activity.php +++ b/civicrm/CRM/Activity/BAO/Activity.php @@ -1125,15 +1125,20 @@ ORDER BY fixed_sort_order * @inheritDoc */ public function addSelectWhereClause() { - $clauses = parent::addSelectWhereClause(); - if (!CRM_Core_Permission::check('view all activities')) { - $permittedActivityTypeIDs = self::getPermittedActivityTypes(); - if (empty($permittedActivityTypeIDs)) { - // This just prevents a mysql fail if they have no access - should be extremely edge case. - $permittedActivityTypeIDs = [0]; - } - $clauses['activity_type_id'] = ('IN (' . implode(', ', $permittedActivityTypeIDs) . ')'); + $clauses = []; + $permittedActivityTypeIDs = self::getPermittedActivityTypes(); + if (empty($permittedActivityTypeIDs)) { + // This just prevents a mysql fail if they have no access - should be extremely edge case. + $permittedActivityTypeIDs = [0]; + } + $clauses['activity_type_id'] = ('IN (' . implode(', ', $permittedActivityTypeIDs) . ')'); + + $contactClause = CRM_Utils_SQL::mergeSubquery('Contact'); + if ($contactClause) { + $contactClause = implode(' AND contact_id ', $contactClause); + $clauses['id'][] = "IN (SELECT activity_id FROM civicrm_activity_contact WHERE contact_id $contactClause)"; } + CRM_Utils_Hook::selectWhereClause($this, $clauses); return $clauses; } @@ -2361,7 +2366,6 @@ AND cl.modified_id = c.id $priorActivities[$index][$dao->activityID]['name'] = $dao->name; $priorActivities[$index][$dao->activityID]['date'] = $dao->date; } - $dao->free(); } } return $priorActivities[$index]; @@ -2678,10 +2682,8 @@ AND cl.modified_id = c.id $result = self::deleteActivity($activityParams); } - $activityContactOther->free(); } - $activityContact->free(); $transaction->commit(); return $result; @@ -3231,4 +3233,14 @@ INNER JOIN civicrm_option_group grp ON (grp.id = option_group_id AND grp.name = return FALSE; } + /** + * @return array + */ + public static function getEntityRefFilters() { + return [ + ['key' => 'activity_type_id', 'value' => ts('Activity Type')], + ['key' => 'status_id', 'value' => ts('Activity Status')], + ]; + } + } diff --git a/civicrm/CRM/Activity/BAO/Query.php b/civicrm/CRM/Activity/BAO/Query.php index 1bba431fa2..3477ffef6a 100644 --- a/civicrm/CRM/Activity/BAO/Query.php +++ b/civicrm/CRM/Activity/BAO/Query.php @@ -288,8 +288,10 @@ class CRM_Activity_BAO_Query { case 'activity_date': case 'activity_date_low': case 'activity_date_high': + case 'activity_date_time_low': + case 'activity_date_time_high': $query->dateQueryBuilder($values, - 'civicrm_activity', 'activity_date', 'activity_date_time', ts('Activity Date') + 'civicrm_activity', str_replace(['_high', '_low'], '', $name), 'activity_date_time', ts('Activity Date') ); break; @@ -440,7 +442,7 @@ class CRM_Activity_BAO_Query { * rather than a static function. */ public static function getSearchFieldMetadata() { - $fields = ['activity_type_id']; + $fields = ['activity_type_id', 'activity_date_time']; $metadata = civicrm_api3('Activity', 'getfields', [])['values']; return array_intersect_key($metadata, array_flip($fields)); } @@ -454,10 +456,6 @@ class CRM_Activity_BAO_Query { $form->addSearchFieldMetadata(['Activity' => self::getSearchFieldMetadata()]); $form->addFormFieldsFromMetadata(); - CRM_Core_Form_Date::buildDateRange($form, 'activity_date', 1, '_low', '_high', ts('From'), FALSE, FALSE); - $form->addElement('hidden', 'activity_date_range_error'); - $form->addFormRule(array('CRM_Activity_BAO_Query', 'formRule'), $form); - $followUpActivity = array( 1 => ts('Yes'), 2 => ts('No'), @@ -631,27 +629,6 @@ class CRM_Activity_BAO_Query { return $properties; } - /** - * Custom form rules. - * - * @param array $fields - * @param array $files - * @param CRM_Core_Form $form - * - * @return bool|array - */ - public static function formRule($fields, $files, $form) { - $errors = array(); - - if (empty($fields['activity_date_low']) || empty($fields['activity_date_high'])) { - return TRUE; - } - - CRM_Utils_Rule::validDateRange($fields, 'activity_date', $errors, ts('Activity Date')); - - return empty($errors) ? TRUE : $errors; - } - /** * Where/qill clause for notes * diff --git a/civicrm/CRM/Activity/Form/Activity.php b/civicrm/CRM/Activity/Form/Activity.php index 6e261d0672..94f68c1203 100644 --- a/civicrm/CRM/Activity/Form/Activity.php +++ b/civicrm/CRM/Activity/Form/Activity.php @@ -792,31 +792,26 @@ class CRM_Activity_Form_Activity extends CRM_Contact_Form_Task { // form should be frozen for view mode $this->freeze(); - $buttons = array(); - $buttons[] = array( - 'type' => 'cancel', - 'name' => ts('Done'), - ); - $this->addButtons($buttons); + $this->addButtons([ + [ + 'type' => 'cancel', + 'name' => ts('Done'), + ], + ]); } else { - $message = array( - 'completed' => ts('Are you sure? This is a COMPLETED activity with the DATE in the FUTURE. Click Cancel to change the date / status. Otherwise, click OK to save.'), - 'scheduled' => ts('Are you sure? This is a SCHEDULED activity with the DATE in the PAST. Click Cancel to change the date / status. Otherwise, click OK to save.'), - ); - $js = array('onclick' => "return activityStatus(" . json_encode($message) . ");"); - $this->addButtons(array( - array( + $this->addButtons([ + [ 'type' => 'upload', 'name' => ts('Save'), - 'js' => $js, 'isDefault' => TRUE, - ), - array( + 'submitOnce' => TRUE, + ], + [ 'type' => 'cancel', 'name' => ts('Cancel'), - ), - )); + ], + ]); } if ($this->_activityTypeFile) { diff --git a/civicrm/CRM/Activity/Form/Search.php b/civicrm/CRM/Activity/Form/Search.php index f59e18c13b..d598dab992 100644 --- a/civicrm/CRM/Activity/Form/Search.php +++ b/civicrm/CRM/Activity/Form/Search.php @@ -87,7 +87,6 @@ class CRM_Activity_Form_Search extends CRM_Core_Form_Search { $this->_actionButtonName = $this->getButtonName('next', 'action'); $this->_done = FALSE; - $this->defaults = array(); $this->loadStandardSearchOptionsFromUrl(); @@ -323,59 +322,6 @@ class CRM_Activity_Form_Search extends CRM_Core_Form_Search { } } - // Added for membership search - - $signupType = CRM_Utils_Request::retrieve('signupType', 'Positive'); - - if ($signupType) { - $this->_formValues['activity_role'] = 1; - $this->_defaults['activity_role'] = 1; - $activityTypes = CRM_Core_PseudoConstant::activityType(TRUE, FALSE, FALSE, 'name'); - - $renew = CRM_Utils_Array::key('Membership Renewal', $activityTypes); - $signup = CRM_Utils_Array::key('Membership Signup', $activityTypes); - - switch ($signupType) { - case 3: // signups and renewals - $this->_formValues['activity_type_id'][$renew] = 1; - $this->_defaults['activity_type_id'][$renew] = 1; - case 1: // signups only - $this->_formValues['activity_type_id'][$signup] = 1; - $this->_defaults['activity_type_id'][$signup] = 1; - break; - - case 2: // renewals only - $this->_formValues['activity_type_id'][$renew] = 1; - $this->_defaults['activity_type_id'][$renew] = 1; - break; - } - } - - $dateLow = CRM_Utils_Request::retrieve('dateLow', 'String'); - - if ($dateLow) { - $dateLow = date('m/d/Y', strtotime($dateLow)); - $this->_formValues['activity_date_relative'] = 0; - $this->_defaults['activity_date_relative'] = 0; - $this->_formValues['activity_date_low'] = $dateLow; - $this->_defaults['activity_date_low'] = $dateLow; - } - - $dateHigh = CRM_Utils_Request::retrieve('dateHigh', 'String'); - - if ($dateHigh) { - // Activity date time assumes midnight at the beginning of the date - // This sets it to almost midnight at the end of the date - /* if ($dateHigh <= 99999999) { - $dateHigh = 1000000 * $dateHigh + 235959; - } */ - $dateHigh = date('m/d/Y', strtotime($dateHigh)); - $this->_formValues['activity_date_relative'] = 0; - $this->_defaults['activity_date_relative'] = 0; - $this->_formValues['activity_date_high'] = $dateHigh; - $this->_defaults['activity_date_high'] = $dateHigh; - } - // Enable search activity by custom value // @todo this is not good security practice. Instead define entity fields in metadata & // use getEntity Defaults diff --git a/civicrm/CRM/Activity/Page/AJAX.php b/civicrm/CRM/Activity/Page/AJAX.php index 787c18d26d..e8be4c76e3 100644 --- a/civicrm/CRM/Activity/Page/AJAX.php +++ b/civicrm/CRM/Activity/Page/AJAX.php @@ -309,7 +309,6 @@ class CRM_Activity_Page_AJAX { $mainActivity->save(); $mainActivityId = $mainActivity->id; CRM_Activity_BAO_Activity::logActivityAction($mainActivity); - $mainActivity->free(); // Mark previous activity as deleted. If it was a non-case activity // then just change the subject. @@ -330,9 +329,7 @@ class CRM_Activity_Page_AJAX { } $otherActivity->save(); - $caseActivity->free(); } - $otherActivity->free(); $targetContacts = array(); if (!empty($params['targetContactIds'])) { @@ -385,7 +382,6 @@ class CRM_Activity_Page_AJAX { $params['mainActivityId'] = $mainActivityId; CRM_Activity_BAO_Activity::copyExtendedActivityData($params); CRM_Utils_Hook::post('create', 'CaseActivity', $caseActivity->id, $caseActivity); - $caseActivity->free(); return (array('error_msg' => $error_msg, 'newId' => $mainActivity->id)); } diff --git a/civicrm/CRM/Activity/Selector/Activity.php b/civicrm/CRM/Activity/Selector/Activity.php index bdc1b18550..544724ffde 100644 --- a/civicrm/CRM/Activity/Selector/Activity.php +++ b/civicrm/CRM/Activity/Selector/Activity.php @@ -112,8 +112,8 @@ class CRM_Activity_Selector_Activity extends CRM_Core_Selector_Base implements C $activityId = NULL, $key = NULL, $compContext = NULL) { - static $activityActTypes = NULL; - //CRM-14277 added addtitional param to handle activity search + + //CRM-14277 added additional param to handle activity search $extraParams = "&searchContext=activity"; $extraParams .= ($key) ? "&key={$key}" : NULL; @@ -124,11 +124,10 @@ class CRM_Activity_Selector_Activity extends CRM_Core_Selector_Base implements C $showView = TRUE; $showUpdate = $showDelete = FALSE; $qsUpdate = NULL; + $url = NULL; + $qsView = NULL; - if (!$activityActTypes) { - $activeActTypes = CRM_Core_PseudoConstant::activityType(TRUE, TRUE, FALSE, 'name', TRUE); - } - $activityTypeName = CRM_Utils_Array::value($activityTypeId, $activeActTypes); + $activityTypeName = CRM_Core_PseudoConstant::getName('CRM_Activity_BAO_Activity', 'activity_type_id', $activityTypeId); // CRM-7607 // Lets allow to have normal operation for only activity types. diff --git a/civicrm/CRM/Activity/Selector/Search.php b/civicrm/CRM/Activity/Selector/Search.php index 340dc7588f..0d9e36c5d1 100644 --- a/civicrm/CRM/Activity/Selector/Search.php +++ b/civicrm/CRM/Activity/Selector/Search.php @@ -273,8 +273,7 @@ class CRM_Activity_Selector_Search extends CRM_Core_Selector_Base implements CRM $sourceID = CRM_Utils_Array::key('Activity Source', $activityContacts); $assigneeID = CRM_Utils_Array::key('Activity Assignees', $activityContacts); $targetID = CRM_Utils_Array::key('Activity Targets', $activityContacts); - // Get all activity types - $activityTypes = CRM_Core_PseudoConstant::activityType(TRUE, TRUE, FALSE, 'name', TRUE); + $bulkActivityTypeID = CRM_Core_PseudoConstant::getKey('CRM_Activity_BAO_Activity', 'activity_type_id', 'Bulk Email'); while ($result->fetch()) { $row = array(); @@ -313,7 +312,6 @@ class CRM_Activity_Selector_Search extends CRM_Core_Selector_Base implements CRM if ($row['activity_is_test']) { $row['activity_type'] = $row['activity_type'] . " (test)"; } - $bulkActivityTypeID = CRM_Utils_Array::key('Bulk Email', $activityTypes); $row['mailingId'] = ''; if ( $accessCiviMail && @@ -433,7 +431,7 @@ class CRM_Activity_Selector_Search extends CRM_Core_Selector_Base implements CRM * @return mixed */ public function alphabetQuery() { - return $this->_query->searchQuery(NULL, NULL, NULL, FALSE, FALSE, TRUE); + return $this->_query->alphabetQuery(); } /** diff --git a/civicrm/CRM/Admin/Form/Preferences/Display.php b/civicrm/CRM/Admin/Form/Preferences/Display.php index 2273f25b7f..ea13835328 100644 --- a/civicrm/CRM/Admin/Form/Preferences/Display.php +++ b/civicrm/CRM/Admin/Form/Preferences/Display.php @@ -51,6 +51,7 @@ class CRM_Admin_Form_Preferences_Display extends CRM_Admin_Form_Preferences { 'ajaxPopupsEnabled' => CRM_Core_BAO_Setting::SYSTEM_PREFERENCES_NAME, 'display_name_format' => CRM_Core_BAO_Setting::SYSTEM_PREFERENCES_NAME, 'sort_name_format' => CRM_Core_BAO_Setting::SYSTEM_PREFERENCES_NAME, + 'menubar_position' => CRM_Core_BAO_Setting::SYSTEM_PREFERENCES_NAME, ); /** diff --git a/civicrm/CRM/Admin/Form/SettingTrait.php b/civicrm/CRM/Admin/Form/SettingTrait.php index f124ef72e6..81fb55fa08 100644 --- a/civicrm/CRM/Admin/Form/SettingTrait.php +++ b/civicrm/CRM/Admin/Form/SettingTrait.php @@ -177,6 +177,12 @@ trait CRM_Admin_Form_SettingTrait { $options = civicrm_api3('Setting', 'getoptions', [ 'field' => $setting, ])['values']; + if ($props['html_type'] === 'Select' && isset($props['is_required']) && $props['is_required'] === FALSE && !isset($options[''])) { + // If the spec specifies the field is not required add a null option. + // Why not if empty($props['is_required']) - basically this has been added to the spec & might not be set to TRUE + // when it is true. + $options = ['' => ts('None')] + $options; + } } if ($props['type'] === 'Boolean') { $options = [$props['title'] => $props['name']]; diff --git a/civicrm/CRM/Admin/Page/AJAX.php b/civicrm/CRM/Admin/Page/AJAX.php index 871b6d3e6d..dc1f065896 100644 --- a/civicrm/CRM/Admin/Page/AJAX.php +++ b/civicrm/CRM/Admin/Page/AJAX.php @@ -37,35 +37,76 @@ class CRM_Admin_Page_AJAX { /** - * CRM-12337 Output navigation menu as executable javascript. - * - * @see smarty_function_crmNavigationMenu + * Outputs menubar data (json format) for the current user. */ - public static function getNavigationMenu() { - $contactID = CRM_Core_Session::singleton()->get('userID'); - if ($contactID) { - CRM_Core_Page_AJAX::setJsHeaders(); - $smarty = CRM_Core_Smarty::singleton(); - $smarty->assign('quicksearchOptions', self::getSearchOptions()); - print $smarty->fetchWith('CRM/common/navigation.js.tpl', array( - 'navigation' => CRM_Core_BAO_Navigation::createNavigation(), - )); + public static function navMenu() { + if (CRM_Core_Session::getLoggedInContactID()) { + + $menu = CRM_Core_BAO_Navigation::buildNavigationTree(); + CRM_Core_BAO_Navigation::buildHomeMenu($menu); + CRM_Utils_Hook::navigationMenu($menu); + CRM_Core_BAO_Navigation::fixNavigationMenu($menu); + CRM_Core_BAO_Navigation::orderByWeight($menu); + CRM_Core_BAO_Navigation::filterByPermission($menu); + self::formatMenuItems($menu); + + $output = [ + 'menu' => $menu, + 'search' => CRM_Utils_Array::makeNonAssociative(self::getSearchOptions()), + ]; + // Encourage browsers to cache for a long time - 1 year + $ttl = 60 * 60 * 24 * 364; + CRM_Utils_System::setHttpHeader('Expires', gmdate('D, d M Y H:i:s \G\M\T', time() + $ttl)); + CRM_Utils_System::setHttpHeader('Cache-Control', "max-age=$ttl, public"); + CRM_Utils_System::setHttpHeader('Content-Type', 'application/json'); + print (json_encode($output)); } CRM_Utils_System::civiExit(); } + /** + * @param array $menu + */ + public static function formatMenuItems(&$menu) { + foreach ($menu as $key => &$item) { + $props = $item['attributes']; + unset($item['attributes']); + if (!empty($props['separator'])) { + $item['separator'] = ($props['separator'] == 1 ? 'bottom' : 'top'); + } + if (!empty($props['icon'])) { + $item['icon'] = $props['icon']; + } + if (!empty($props['attr'])) { + $item['attr'] = $props['attr']; + } + if (!empty($props['url'])) { + $item['url'] = CRM_Utils_System::evalUrl(CRM_Core_BAO_Navigation::makeFullyFormedUrl($props['url'])); + } + if (!empty($props['label'])) { + $item['label'] = ts($props['label'], ['context' => 'menu']); + } + $item['name'] = !empty($props['name']) ? $props['name'] : CRM_Utils_String::munge(CRM_Utils_Array::value('label', $props)); + if (!empty($item['child'])) { + self::formatMenuItems($item['child']); + } + } + $menu = array_values($menu); + } + public static function getSearchOptions() { - $searchOptions = Civi::settings()->get('quicksearch_options'); - $searchOptions[] = 'sort_name'; - $searchOptions = array_intersect_key(CRM_Core_SelectValues::quicksearchOptions(), array_flip($searchOptions)); - foreach ($searchOptions as $key => $label) { + $searchOptions = array_merge(['sort_name'], Civi::settings()->get('quicksearch_options')); + $labels = CRM_Core_SelectValues::quicksearchOptions(); + $result = []; + foreach ($searchOptions as $key) { + $label = $labels[$key]; if (strpos($key, 'custom_') === 0) { - unset($searchOptions[$key]); - $id = CRM_Core_DAO::getFieldValue('CRM_Core_DAO_CustomField', substr($key, 7), 'id', 'name'); - $searchOptions["custom_$id"] = $label; + $key = 'custom_' . CRM_Core_DAO::getFieldValue('CRM_Core_DAO_CustomField', substr($key, 7), 'id', 'name'); + $label = array_slice(explode(': ', $label, 2), -1); } + $result[$key] = $label; } - return $searchOptions; + return $result; } /** diff --git a/civicrm/CRM/Campaign/BAO/Campaign.php b/civicrm/CRM/Campaign/BAO/Campaign.php index 6929423cbb..77440fa746 100644 --- a/civicrm/CRM/Campaign/BAO/Campaign.php +++ b/civicrm/CRM/Campaign/BAO/Campaign.php @@ -93,7 +93,6 @@ class CRM_Campaign_BAO_Campaign extends CRM_Campaign_DAO_Campaign { $dao->entity_id = $entityId; $dao->group_type = 'Include'; $dao->save(); - $dao->free(); } } @@ -600,7 +599,7 @@ INNER JOIN civicrm_group grp ON ( grp.id = campgrp.entity_id ) if ($connectedCampaignId || ($isCampaignEnabled && $hasAccessCampaign)) { $showAddCampaign = TRUE; $campaign = $form->addEntityRef('campaign_id', ts('Campaign'), [ - 'entity' => 'campaign', + 'entity' => 'Campaign', 'create' => TRUE, 'select' => ['minimumInputLength' => 0], ]); @@ -666,12 +665,50 @@ INNER JOIN civicrm_group grp ON ( grp.id = campgrp.entity_id ) $form->assign('campaignInfo', $campaignInfo); } + /** + * @return array + */ + public static function getEntityRefFilters() { + return [ + ['key' => 'campaign_type_id', 'value' => ts('Campaign Type')], + ['key' => 'status_id', 'value' => ts('Status')], + [ + 'key' => 'start_date', + 'value' => ts('Start Date'), + 'options' => [ + ['key' => '{">":"now"}', 'value' => ts('Upcoming')], + [ + 'key' => '{"BETWEEN":["now - 3 month","now"]}', + 'value' => ts('Past 3 Months'), + ], + [ + 'key' => '{"BETWEEN":["now - 6 month","now"]}', + 'value' => ts('Past 6 Months'), + ], + [ + 'key' => '{"BETWEEN":["now - 1 year","now"]}', + 'value' => ts('Past Year'), + ], + ], + ], + [ + 'key' => 'end_date', + 'value' => ts('End Date'), + 'options' => [ + ['key' => '{">":"now"}', 'value' => ts('In the future')], + ['key' => '{"<":"now"}', 'value' => ts('In the past')], + ['key' => '{"IS NULL":"1"}', 'value' => ts('Not set')], + ], + ], + ]; + } + /** * Links to create new campaigns from entityRef widget * * @return array|bool */ - public static function entityRefCreateLinks() { + public static function getEntityRefCreateLinks() { if (CRM_Core_Permission::check([['administer CiviCampaign', 'manage campaign']])) { return [ [ diff --git a/civicrm/CRM/Campaign/BAO/Survey.php b/civicrm/CRM/Campaign/BAO/Survey.php index 95987c774a..58c45b25e2 100644 --- a/civicrm/CRM/Campaign/BAO/Survey.php +++ b/civicrm/CRM/Campaign/BAO/Survey.php @@ -504,7 +504,6 @@ SELECT survey.id as id, ); $voterDetails[$contact->contactId]['contact_type'] = $image; } - $contact->free(); } return $voterDetails; diff --git a/civicrm/CRM/Campaign/Form/Petition.php b/civicrm/CRM/Campaign/Form/Petition.php index d04659c297..e1e005eda0 100644 --- a/civicrm/CRM/Campaign/Form/Petition.php +++ b/civicrm/CRM/Campaign/Form/Petition.php @@ -191,7 +191,7 @@ class CRM_Campaign_Form_Petition extends CRM_Core_Form { $this->add('wysiwyg', 'instructions', ts('Introduction'), $attributes['instructions']); $this->addEntityRef('campaign_id', ts('Campaign'), [ - 'entity' => 'campaign', + 'entity' => 'Campaign', 'create' => TRUE, 'select' => ['minimumInputLength' => 0], ]); diff --git a/civicrm/CRM/Campaign/Form/Survey/Main.php b/civicrm/CRM/Campaign/Form/Survey/Main.php index 2ef5899ad9..901981ab07 100644 --- a/civicrm/CRM/Campaign/Form/Survey/Main.php +++ b/civicrm/CRM/Campaign/Form/Survey/Main.php @@ -130,7 +130,7 @@ class CRM_Campaign_Form_Survey_Main extends CRM_Campaign_Form_Survey { $this->addSelect('activity_type_id', array('option_url' => 'civicrm/admin/campaign/surveyType'), TRUE); $this->addEntityRef('campaign_id', ts('Campaign'), [ - 'entity' => 'campaign', + 'entity' => 'Campaign', 'create' => TRUE, 'select' => ['minimumInputLength' => 0], ]); diff --git a/civicrm/CRM/Campaign/Form/Task/Interview.php b/civicrm/CRM/Campaign/Form/Task/Interview.php index 17ffa9cb02..82fdf3b6d3 100644 --- a/civicrm/CRM/Campaign/Form/Task/Interview.php +++ b/civicrm/CRM/Campaign/Form/Task/Interview.php @@ -559,7 +559,6 @@ WHERE {$clause} //really this should use Activity BAO& not be here but refactoring will have to be later //actually the whole ajax call could be done as an api ajax call & post hook would be sorted CRM_Utils_Hook::post('edit', 'Activity', $activity->id, $activity); - $activity->free(); return $activityId; } diff --git a/civicrm/CRM/Campaign/Selector/Search.php b/civicrm/CRM/Campaign/Selector/Search.php index 8d71c4cd1e..f3315a0b00 100644 --- a/civicrm/CRM/Campaign/Selector/Search.php +++ b/civicrm/CRM/Campaign/Selector/Search.php @@ -273,17 +273,17 @@ class CRM_Campaign_Selector_Search extends CRM_Core_Selector_Base implements CRM $cacheKey = "civicrm search {$this->_key}"; Civi::service('prevnext')->deleteItem(NULL, $cacheKey, 'civicrm_contact'); - $sql = $this->_query->searchQuery(0, 0, $sort, + $sql = $this->_query->getSearchSQLParts(0, 0, $sort, FALSE, FALSE, FALSE, FALSE, - TRUE, $this->_campaignWhereClause, + $this->_campaignWhereClause, NULL, $this->_campaignFromClause ); - list($select, $from) = explode(' FROM ', $sql); + $selectSQL = " SELECT %1, contact_a.id, contact_a.display_name -FROM {$from} +FROM {$sql['from']} "; try { diff --git a/civicrm/CRM/Case/BAO/Case.php b/civicrm/CRM/Case/BAO/Case.php index 06102fe28a..fb84b9ce35 100644 --- a/civicrm/CRM/Case/BAO/Case.php +++ b/civicrm/CRM/Case/BAO/Case.php @@ -1061,7 +1061,6 @@ SELECT case_status.label AS case_status, status_id, civicrm_case_type.title AS c $caseCount = CRM_Core_DAO::singleValueQuery('SELECT FOUND_ROWS()'); $activityTypes = CRM_Case_PseudoConstant::caseActivityType(FALSE, TRUE); - $activityStatuses = CRM_Core_PseudoConstant::activityStatus(); $url = CRM_Utils_System::url("civicrm/case/activity", "reset=1&cid={$contactID}&caseid={$caseID}", FALSE, NULL, FALSE @@ -1096,7 +1095,6 @@ SELECT case_status.label AS case_status, status_id, civicrm_case_type.title AS c $caseActivities = array(); while ($dao->fetch()) { - $caseActivity = array(); $caseActivityId = $dao->id; $allowView = self::checkPermission($caseActivityId, 'view', $dao->activity_type_id, $userID); @@ -1175,8 +1173,8 @@ SELECT case_status.label AS case_status, status_id, civicrm_case_type.title AS c } } - //Activity Status - $caseActivities[$caseActivityId]['status_id'] = $activityStatuses[$dao->status]; + // Activity Status Label for Case activities list + $caseActivities[$caseActivityId]['status_id'] = CRM_Core_PseudoConstant::getLabel('CRM_Activity_BAO_Activity', 'activity_status_id', $dao->status); // FIXME: Why are we not using CRM_Core_Action for these links? This is too much manual work and likely to get out-of-sync with core markup. $url = ""; @@ -1977,9 +1975,7 @@ SELECT civicrm_contact.id as casemanager_id, return array(); } - $linkActType = array_search('Link Cases', - CRM_Core_PseudoConstant::activityType(TRUE, TRUE, FALSE, 'name') - ); + $linkActType = CRM_Core_PseudoConstant::getKey('CRM_Activity_BAO_Activity', 'activity_type_id', 'Link Cases'); if (!$linkActType) { return array(); } @@ -2138,8 +2134,8 @@ SELECT civicrm_contact.id as casemanager_id, return $mainCaseIds; } - $activityTypes = CRM_Core_PseudoConstant::activityType(TRUE, TRUE, FALSE, 'name'); - $activityStatuses = CRM_Core_PseudoConstant::activityStatus('name'); + $activityTypes = CRM_Activity_BAO_Activity::buildOptions('activity_type_id', 'validate'); + $completedActivityStatus = CRM_Core_PseudoConstant::getKey('CRM_Activity_BAO_Activity', 'activity_status_id', 'Completed'); $activityContacts = CRM_Activity_BAO_ActivityContact::buildOptions('record_type_id', 'validate'); $sourceID = CRM_Utils_Array::key('Activity Source', $activityContacts); $assigneeID = CRM_Utils_Array::key('Activity Assignees', $activityContacts); @@ -2195,8 +2191,6 @@ SELECT civicrm_contact.id as casemanager_id, } } - $mainCase->free(); - $mainCaseIds[] = $mainCaseId; //insert record for case contact. $otherCaseContact = new CRM_Case_DAO_CaseContact(); @@ -2213,9 +2207,7 @@ SELECT civicrm_contact.id as casemanager_id, if (!$mainCaseContact->find(TRUE)) { $mainCaseContact->save(); } - $mainCaseContact->free(); } - $otherCaseContact->free(); } elseif (!$otherContactId) { $otherContactId = $mainContactId; @@ -2299,8 +2291,6 @@ SELECT id // insert log of all activities CRM_Activity_BAO_Activity::logActivityAction($mainActivity); - $otherActivity->free(); - $mainActivity->free(); $copiedActivityIds[] = $otherActivityId; //create case activity record. @@ -2308,7 +2298,6 @@ SELECT id $mainCaseActivity->case_id = $mainCaseId; $mainCaseActivity->activity_id = $mainActivityId; $mainCaseActivity->save(); - $mainCaseActivity->free(); //migrate source activity. $otherSourceActivity = new CRM_Activity_DAO_ActivityContact(); @@ -2327,9 +2316,7 @@ SELECT id if (!$mainActivitySource->find(TRUE)) { $mainActivitySource->save(); } - $mainActivitySource->free(); } - $otherSourceActivity->free(); //migrate target activities. $otherTargetActivity = new CRM_Activity_DAO_ActivityContact(); @@ -2348,9 +2335,7 @@ SELECT id if (!$mainActivityTarget->find(TRUE)) { $mainActivityTarget->save(); } - $mainActivityTarget->free(); } - $otherTargetActivity->free(); //migrate assignee activities. $otherAssigneeActivity = new CRM_Activity_DAO_ActivityContact(); @@ -2369,9 +2354,7 @@ SELECT id if (!$mainAssigneeActivity->find(TRUE)) { $mainAssigneeActivity->save(); } - $mainAssigneeActivity->free(); } - $otherAssigneeActivity->free(); // copy custom fields and attachments $aparams = array( @@ -2417,14 +2400,12 @@ SELECT id if (!$mainRelationship->find(TRUE)) { $mainRelationship->save(); } - $mainRelationship->free(); //get the other relationship ids to update end date. if ($updateOtherRel) { $otherRelationshipIds[$otherRelationship->id] = $otherRelationship->id; } } - $otherRelationship->free(); //update other relationships end dates if (!empty($otherRelationshipIds)) { @@ -2486,11 +2467,11 @@ WHERE id IN (' . implode(',', $copiedActivityIds) . ')'; } } - //Create merge activity record. Source for merge activity is the logged in user's contact ID ($currentUserId). + // Create merge activity record. Source for merge activity is the logged in user's contact ID ($currentUserId). $activityParams = array( 'subject' => $mergeActSubject, 'details' => $mergeActSubjectDetails, - 'status_id' => array_search('Completed', $activityStatuses), + 'status_id' => $completedActivityStatus, 'activity_type_id' => $mergeActType, 'source_contact_id' => $currentUserId, 'activity_date_time' => date('YmdHis'), @@ -2501,7 +2482,6 @@ WHERE id IN (' . implode(',', $copiedActivityIds) . ')'; if (!$mergeActivityId) { continue; } - $mergeActivity->free(); //connect merge activity to case. $mergeCaseAct = array( @@ -2736,10 +2716,7 @@ WHERE id IN (' . implode(',', $copiedActivityIds) . ')'; //do further only when operation is granted. if ($allow) { - $activityTypes = CRM_Core_PseudoConstant::activityType(TRUE, TRUE, FALSE, 'name'); - - //get the activity type name. - $actTypeName = CRM_Utils_Array::value($actTypeId, $activityTypes); + $actTypeName = CRM_Core_PseudoConstant::getName('CRM_Activity_BAO_Activity', 'activity_type_id', $actTypeId); //do not allow multiple copy / edit action. $singletonNames = array( @@ -3116,7 +3093,6 @@ WHERE id IN (' . implode(',', $copiedActivityIds) . ')'; if (!$newRelationship->find(TRUE)) { $newRelationship->save(); } - $newRelationship->free(); // store relationship type of newly created relationship $relationshipTypes[] = $caseRelationships->relationship_type_id; @@ -3278,4 +3254,28 @@ WHERE id IN (' . implode(',', $copiedActivityIds) . ')'; return "$name <$address>"; } + /** + * @return array + */ + public static function getEntityRefFilters() { + $filters = [ + [ + 'key' => 'case_id.case_type_id', + 'value' => ts('Case Type'), + 'entity' => 'Case', + ], + [ + 'key' => 'case_id.status_id', + 'value' => ts('Case Status'), + 'entity' => 'Case', + ], + ]; + foreach (CRM_Contact_BAO_Contact::getEntityRefFilters() as $filter) { + $filter += ['entity' => 'Contact']; + $filter['key'] = 'contact_id.' . $filter['key']; + $filters[] = $filter; + } + return $filters; + } + } diff --git a/civicrm/CRM/Case/Form/Activity.php b/civicrm/CRM/Case/Form/Activity.php index b027243ff4..7a7b3b92b6 100644 --- a/civicrm/CRM/Case/Form/Activity.php +++ b/civicrm/CRM/Case/Form/Activity.php @@ -70,7 +70,7 @@ class CRM_Case_Form_Activity extends CRM_Activity_Form_Activity { $this->_crmDir = 'Case'; $this->assign('context', $this->_context); - $result = parent::preProcess(); + parent::preProcess(); $scheduleStatusId = CRM_Core_PseudoConstant::getKey('CRM_Activity_BAO_Activity', 'activity_status_id', 'Scheduled'); $this->assign('scheduleStatusId', $scheduleStatusId); @@ -573,7 +573,7 @@ class CRM_Case_Form_Activity extends CRM_Activity_Form_Activity { unset($caseParams['subject'], $caseParams['details'], $caseParams['status_id'], $caseParams['custom'] ); - $case = CRM_Case_BAO_Case::create($caseParams); + CRM_Case_BAO_Case::create($caseParams); // create case activity record $caseParams = array( 'activity_id' => $vval['actId'], @@ -582,10 +582,6 @@ class CRM_Case_Form_Activity extends CRM_Activity_Form_Activity { CRM_Case_BAO_Case::processCaseActivity($caseParams); } - // Insert civicrm_log record for the activity (e.g. store the - // created / edited by contact id and date for the activity) - // Note - civicrm_log is already created by CRM_Activity_BAO_Activity::create() - // send copy to selected contacts. $mailStatus = ''; $mailToContacts = array(); @@ -593,8 +589,6 @@ class CRM_Case_Form_Activity extends CRM_Activity_Form_Activity { //CRM-5695 //check for notification settings for assignee contacts $selectedContacts = array('contact_check'); - $activityContacts = CRM_Activity_BAO_ActivityContact::buildOptions('record_type_id', 'validate'); - $assigneeID = CRM_Utils_Array::key('Activity Assignees', $activityContacts); if (Civi::settings()->get('activity_assignee_notification')) { $selectedContacts[] = 'assignee_contact_id'; } diff --git a/civicrm/CRM/Case/Form/Activity/ChangeCaseType.php b/civicrm/CRM/Case/Form/Activity/ChangeCaseType.php index 42c2f5bc59..53fa4a051b 100644 --- a/civicrm/CRM/Case/Form/Activity/ChangeCaseType.php +++ b/civicrm/CRM/Case/Form/Activity/ChangeCaseType.php @@ -61,8 +61,7 @@ class CRM_Case_Form_Activity_ChangeCaseType { $defaults['is_reset_timeline'] = 1; - $defaults['reset_date_time'] = array(); - list($defaults['reset_date_time'], $defaults['reset_date_time_time']) = CRM_Utils_Date::setDateDefaults(NULL, 'activityDateTime'); + $defaults['reset_date_time'] = date('Y-m-d H:i:s'); $defaults['case_type_id'] = $form->_caseTypeId; return $defaults; @@ -88,8 +87,8 @@ class CRM_Case_Form_Activity_ChangeCaseType { $form->addField('case_type_id', array('context' => 'create', 'entity' => 'Case')); // timeline - $form->addYesNo('is_reset_timeline', ts('Reset Case Timeline?'), NULL, TRUE, array('onclick' => "return showHideByValue('is_reset_timeline','','resetTimeline','table-row','radio',false);")); - $form->addDateTime('reset_date_time', ts('Reset Start Date'), FALSE, array('formatType' => 'activityDateTime')); + $form->addYesNo('is_reset_timeline', ts('Reset Case Timeline?'), NULL, TRUE); + $form->add('datepicker', 'reset_date_time', ts('Reset Start Date'), NULL, FALSE, ['allowClear' => FALSE]); } /** @@ -123,10 +122,6 @@ class CRM_Case_Form_Activity_ChangeCaseType { if (CRM_Utils_Array::value('is_reset_timeline', $params) == 0) { unset($params['reset_date_time']); } - else { - // store the date with proper format - $params['reset_date_time'] = CRM_Utils_Date::processDate($params['reset_date_time'], $params['reset_date_time_time']); - } } /** diff --git a/civicrm/CRM/Case/Form/Activity/OpenCase.php b/civicrm/CRM/Case/Form/Activity/OpenCase.php index 73f6f5a4c4..b2f2c5eaaa 100644 --- a/civicrm/CRM/Case/Form/Activity/OpenCase.php +++ b/civicrm/CRM/Case/Form/Activity/OpenCase.php @@ -197,11 +197,13 @@ class CRM_Case_Form_Activity_OpenCase { 'type' => 'upload', 'name' => ts('Save'), 'isDefault' => TRUE, + 'submitOnce' => TRUE, ), array( 'type' => 'upload', 'name' => ts('Save and New'), 'subName' => 'new', + 'submitOnce' => TRUE, ), array( 'type' => 'cancel', diff --git a/civicrm/CRM/Case/Form/AddToCaseAsRole.php b/civicrm/CRM/Case/Form/AddToCaseAsRole.php index d62dd92ad1..af02512fdd 100644 --- a/civicrm/CRM/Case/Form/AddToCaseAsRole.php +++ b/civicrm/CRM/Case/Form/AddToCaseAsRole.php @@ -23,7 +23,7 @@ class CRM_Case_Form_AddToCaseAsRole extends CRM_Contact_Form_Task { $this->addEntityRef( 'assign_to', ts('Assign to'), - array('entity' => 'case'), + array('entity' => 'Case'), TRUE ); diff --git a/civicrm/CRM/Case/Form/Search.php b/civicrm/CRM/Case/Form/Search.php index df38d23fcf..14ca731cc0 100644 --- a/civicrm/CRM/Case/Form/Search.php +++ b/civicrm/CRM/Case/Form/Search.php @@ -87,7 +87,6 @@ class CRM_Case_Form_Search extends CRM_Core_Form_Search { $this->_actionButtonName = $this->getButtonName('next', 'action'); $this->_done = FALSE; - $this->defaults = array(); $this->loadStandardSearchOptionsFromUrl(); $this->loadFormValues(); diff --git a/civicrm/CRM/Case/Selector/Search.php b/civicrm/CRM/Case/Selector/Search.php index 5bba715cec..d068a128af 100644 --- a/civicrm/CRM/Case/Selector/Search.php +++ b/civicrm/CRM/Case/Selector/Search.php @@ -456,7 +456,7 @@ class CRM_Case_Selector_Search extends CRM_Core_Selector_Base { * @return mixed */ public function alphabetQuery() { - return $this->_query->searchQuery(NULL, NULL, NULL, FALSE, FALSE, TRUE); + return $this->_query->alphabetQuery(); } /** diff --git a/civicrm/CRM/Case/XMLProcessor/Process.php b/civicrm/CRM/Case/XMLProcessor/Process.php index eef735e44a..255c7cc029 100644 --- a/civicrm/CRM/Case/XMLProcessor/Process.php +++ b/civicrm/CRM/Case/XMLProcessor/Process.php @@ -197,7 +197,7 @@ class CRM_Case_XMLProcessor_Process extends CRM_Case_XMLProcessor { if (!$isCaseManager) { $result[$relationshipTypeID] = $relationshipTypeName; } - elseif ($relationshipTypeXML->manager) { + elseif ($relationshipTypeXML->manager == 1) { return $relationshipTypeID; } } diff --git a/civicrm/CRM/Case/XMLProcessor/Report.php b/civicrm/CRM/Case/XMLProcessor/Report.php index 4adab97876..aa0b6c0b52 100644 --- a/civicrm/CRM/Case/XMLProcessor/Report.php +++ b/civicrm/CRM/Case/XMLProcessor/Report.php @@ -581,10 +581,11 @@ WHERE a.id = %1 /** * @param int $activityTypeID * @param null $dateFormat + * @param bool $onlyActive * * @return mixed */ - public function getActivityTypeCustomSQL($activityTypeID, $dateFormat = NULL) { + public function getActivityTypeCustomSQL($activityTypeID, $dateFormat = NULL, $onlyActive = TRUE) { static $cache = array(); if (is_null($activityTypeID)) { @@ -608,6 +609,9 @@ WHERE cf.custom_group_id = cg.id AND cg.extends = 'Activity' AND " . CRM_Core_Permission::customGroupClause(CRM_Core_Permission::VIEW, 'cg.'); + if ($onlyActive) { + $query .= " AND cf.is_active = 1 "; + } if ($activityTypeID) { $query .= "AND ( cg.extends_entity_column_value IS NULL OR cg.extends_entity_column_value LIKE '%" . CRM_Core_DAO::VALUE_SEPARATOR . "%1" . CRM_Core_DAO::VALUE_SEPARATOR . "%' )"; } diff --git a/civicrm/CRM/Contact/BAO/Contact.php b/civicrm/CRM/Contact/BAO/Contact.php index da45da8e39..561f60777f 100644 --- a/civicrm/CRM/Contact/BAO/Contact.php +++ b/civicrm/CRM/Contact/BAO/Contact.php @@ -1201,6 +1201,7 @@ WHERE civicrm_contact.id = " . CRM_Utils_Type::escape($id, 'Integer'); $contact->copyValues($updateParams); $contact->save(); + CRM_Core_BAO_Log::register($contact->id, 'civicrm_contact', $contact->id); CRM_Utils_Hook::post('update', $contact->contact_type, $contact->id, $contact); @@ -2121,11 +2122,17 @@ ORDER BY civicrm_email.is_primary DESC"; ) { // if profile was used, and had any subtype, we obtain it from there //CRM-13596 - add to existing contact types, rather than overwriting - $data_contact_sub_type_arr = CRM_Utils_Array::explodePadded($data['contact_sub_type']); - if (!in_array($params['contact_sub_type_hidden'], $data_contact_sub_type_arr)) { - //CRM-20517 - make sure contact_sub_type gets the correct delimiters - $data['contact_sub_type'] = trim($data['contact_sub_type'], CRM_Core_DAO::VALUE_SEPARATOR); - $data['contact_sub_type'] = CRM_Core_DAO::VALUE_SEPARATOR . $data['contact_sub_type'] . CRM_Utils_Array::implodePadded($params['contact_sub_type_hidden']); + if (empty($data['contact_sub_type'])) { + // If we don't have a contact ID the $data['contact_sub_type'] will not be defined... + $data['contact_sub_type'] = CRM_Utils_Array::implodePadded($params['contact_sub_type_hidden']); + } + else { + $data_contact_sub_type_arr = CRM_Utils_Array::explodePadded($data['contact_sub_type']); + if (!in_array($params['contact_sub_type_hidden'], $data_contact_sub_type_arr)) { + //CRM-20517 - make sure contact_sub_type gets the correct delimiters + $data['contact_sub_type'] = trim($data['contact_sub_type'], CRM_Core_DAO::VALUE_SEPARATOR); + $data['contact_sub_type'] = CRM_Core_DAO::VALUE_SEPARATOR . $data['contact_sub_type'] . CRM_Utils_Array::implodePadded($params['contact_sub_type_hidden']); + } } } @@ -3643,15 +3650,71 @@ LEFT JOIN civicrm_address ON ( civicrm_address.contact_id = civicrm_contact.id ) } /** - * Checks permission to create new contacts from entityRef widget + * @param array $appendProfiles + * Name of profile(s) to append to each link. * - * Note: other components must return an array of links from this function, - * but Contacts are given special treatment - the links are in javascript already. - * - * @return bool + * @return array + */ + public static function getEntityRefCreateLinks($appendProfiles = []) { + // You'd think that "create contacts" would be the permission to check, + // But new contact popups are profile forms and those use their own permissions. + if (!CRM_Core_Permission::check([['profile create', 'profile listings and forms']])) { + return FALSE; + } + $profiles = []; + foreach (CRM_Contact_BAO_ContactType::basicTypes() as $contactType) { + $profiles[] = 'new_' . strtolower($contactType); + } + $retrieved = civicrm_api3('uf_group', 'get', [ + 'name' => ['IN' => array_merge($profiles, (array) $appendProfiles)], + 'is_active' => 1, + ]); + $links = $append = []; + if (!empty($retrieved['values'])) { + $icons = [ + 'individual' => 'fa-user', + 'organization' => 'fa-building', + 'household' => 'fa-home', + ]; + foreach ($retrieved['values'] as $id => $profile) { + if (in_array($profile['name'], $profiles)) { + $links[] = array( + 'label' => $profile['title'], + 'url' => CRM_Utils_System::url('civicrm/profile/create', "reset=1&context=dialog&gid=$id", + NULL, NULL, FALSE, FALSE, TRUE), + 'type' => ucfirst(str_replace('new_', '', $profile['name'])), + 'icon' => CRM_Utils_Array::value(str_replace('new_', '', $profile['name']), $icons), + ); + } + else { + $append[] = $id; + } + } + foreach ($append as $id) { + foreach ($links as &$link) { + $link['url'] .= ",$id"; + } + } + } + return $links; + } + + /** + * @return array */ - public static function entityRefCreateLinks() { - return CRM_Core_Permission::check([['profile create', 'profile listings and forms']]); + public static function getEntityRefFilters() { + return [ + ['key' => 'contact_type', 'value' => ts('Contact Type')], + ['key' => 'group', 'value' => ts('Group'), 'entity' => 'GroupContact'], + ['key' => 'tag', 'value' => ts('Tag'), 'entity' => 'EntityTag'], + ['key' => 'state_province', 'value' => ts('State/Province'), 'entity' => 'Address'], + ['key' => 'country', 'value' => ts('Country'), 'entity' => 'Address'], + ['key' => 'gender_id', 'value' => ts('Gender'), 'condition' => ['contact_type' => 'Individual']], + ['key' => 'is_deceased', 'value' => ts('Deceased'), 'condition' => ['contact_type' => 'Individual']], + ['key' => 'contact_id', 'value' => ts('Contact ID'), 'type' => 'text'], + ['key' => 'external_identifier', 'value' => ts('External ID'), 'type' => 'text'], + ['key' => 'source', 'value' => ts('Contact Source'), 'type' => 'text'], + ]; } } diff --git a/civicrm/CRM/Contact/BAO/Group.php b/civicrm/CRM/Contact/BAO/Group.php index 2c40bcec5c..2b94fe37a4 100644 --- a/civicrm/CRM/Contact/BAO/Group.php +++ b/civicrm/CRM/Contact/BAO/Group.php @@ -966,18 +966,20 @@ class CRM_Contact_BAO_Group extends CRM_Contact_DAO_Group { } $values[$object->id]['group_type'] = implode(', ', $types); } - $values[$object->id]['action'] = CRM_Core_Action::formLink($newLinks, - $action, - array( - 'id' => $object->id, - 'ssid' => $object->saved_search_id, - ), - ts('more'), - FALSE, - 'group.selector.row', - 'Group', - $object->id - ); + if ($action) { + $values[$object->id]['action'] = CRM_Core_Action::formLink($newLinks, + $action, + array( + 'id' => $object->id, + 'ssid' => $object->saved_search_id, + ), + ts('more'), + FALSE, + 'group.selector.row', + 'Group', + $object->id + ); + } // If group has children, add class for link to view children $values[$object->id]['is_parent'] = FALSE; diff --git a/civicrm/CRM/Contact/BAO/GroupContact.php b/civicrm/CRM/Contact/BAO/GroupContact.php index 20290e2c69..9bb1dc439a 100644 --- a/civicrm/CRM/Contact/BAO/GroupContact.php +++ b/civicrm/CRM/Contact/BAO/GroupContact.php @@ -787,9 +787,8 @@ AND contact_id IN ( $contactStr ) * @return array|bool */ public static function buildOptions($fieldName, $context = NULL, $props = array()) { - $params = array(); - $options = CRM_Core_PseudoConstant::get(__CLASS__, $fieldName, $params, $context); + $options = CRM_Core_PseudoConstant::get(__CLASS__, $fieldName, $props, $context); // Sort group list by hierarchy // TODO: This will only work when api.entity is "group_contact". What about others? diff --git a/civicrm/CRM/Contact/BAO/GroupContactCache.php b/civicrm/CRM/Contact/BAO/GroupContactCache.php index e61291cd86..5bad91bed0 100644 --- a/civicrm/CRM/Contact/BAO/GroupContactCache.php +++ b/civicrm/CRM/Contact/BAO/GroupContactCache.php @@ -555,15 +555,12 @@ WHERE id IN ( $groupIDs ) ); $query->_useDistinct = FALSE; $query->_useGroupBy = FALSE; - $searchSQL - = $query->searchQuery( + $sqlParts = $query->getSearchSQLParts( 0, 0, NULL, FALSE, FALSE, - FALSE, TRUE, - TRUE, - NULL, NULL, NULL, - TRUE + FALSE, TRUE ); + $searchSQL = "{$sqlParts['select']} {$sqlParts['from']} {$sqlParts['where']} {$sqlParts['having']} {$sqlParts['group_by']}"; } $groupID = CRM_Utils_Type::escape($groupID, 'Integer'); $sql = $searchSQL . " AND contact_a.id NOT IN ( diff --git a/civicrm/CRM/Contact/BAO/Query.php b/civicrm/CRM/Contact/BAO/Query.php index c8818f4620..1b98afbb00 100644 --- a/civicrm/CRM/Contact/BAO/Query.php +++ b/civicrm/CRM/Contact/BAO/Query.php @@ -413,6 +413,7 @@ class CRM_Contact_BAO_Query { public $_pseudoConstantsSelect = array(); public $_groupUniqueKey = NULL; + public $_groupKeys = []; /** * Class constructor which also does all the work. @@ -538,6 +539,7 @@ class CRM_Contact_BAO_Query { $component = 'membership'; } if (isset($component)) { + // @todo should be if (isset($component && !$this->_skipPermission) CRM_Financial_BAO_FinancialType::buildPermissionedClause($this->_whereClause, $component); } @@ -727,7 +729,7 @@ class CRM_Contact_BAO_Query { if ( !empty($this->_paramLookup[$name]) || !empty($this->_returnProperties[$name]) - || $this->pseudoConstantNameIsInReturnProperties($field) + || $this->pseudoConstantNameIsInReturnProperties($field, $name) || $makeException ) { if ($cfID) { @@ -868,22 +870,10 @@ class CRM_Contact_BAO_Query { $this->_select[$name] = "{$field['where']} as `$name`"; } } + elseif ($this->pseudoConstantNameIsInReturnProperties($field, $name)) { + $this->addPseudoconstantFieldToSelect($name); + } else { - // If we have an option group defined then rather than joining the option value table in - // (which is an unindexed join) we render the option value on output. - // @todo - extend this to other pseudoconstants. - if ($this->pseudoConstantNameIsInReturnProperties($field, $name)) { - $pseudoFieldName = $field['pseudoconstant']['optionGroupName']; - $this->_pseudoConstantsSelect[$pseudoFieldName] = array( - 'pseudoField' => $field['name'], - 'idCol' => $name, - 'field_name' => $field['name'], - 'bao' => $field['bao'], - 'pseudoconstant' => $field['pseudoconstant'], - ); - $this->_tables[$tableName] = 1; - $this->_element[$pseudoFieldName] = 1; - } $this->_select[$name] = str_replace('civicrm_contact.', 'contact_a.', "{$field['where']} as `$name`"); } if (!in_array($tName, array('state_province', 'country', 'county'))) { @@ -1394,7 +1384,7 @@ class CRM_Contact_BAO_Query { } } elseif ($sortByChar) { - $select = 'SELECT DISTINCT UPPER(LEFT(contact_a.sort_name, 1)) as sort_name'; + $select = 'SELECT DISTINCT LEFT(contact_a.sort_name, 1) as sort_name'; $from = $this->_simpleFromClause; } elseif ($groupContacts) { @@ -1794,6 +1784,11 @@ class CRM_Contact_BAO_Query { * @param string $apiEntity */ public function whereClauseSingle(&$values, $apiEntity = NULL) { + if ($this->isARelativeDateField($values[0])) { + $this->buildRelativeDateQuery($values); + return; + } + // do not process custom fields or prefixed contact ids or component params if (CRM_Core_BAO_CustomField::getKeyID($values[0]) || (substr($values[0], 0, CRM_Core_Form::CB_PREFIX_LEN) == CRM_Core_Form::CB_PREFIX) || @@ -1916,6 +1911,8 @@ class CRM_Contact_BAO_Query { case 'activity_date': case 'activity_date_low': case 'activity_date_high': + case 'activity_date_time_low': + case 'activity_date_time_high': case 'activity_role': case 'activity_status_id': case 'activity_status': @@ -2048,6 +2045,18 @@ class CRM_Contact_BAO_Query { // check for both id and contact_id if ($this->_params[$id][0] == 'id' || $this->_params[$id][0] == 'contact_id') { $this->_where[0][] = self::buildClause("contact_a.id", $this->_params[$id][1], $this->_params[$id][2]); + $field = CRM_Utils_Array::value('id', $this->_fields); + list($qillop, $qillVal) = CRM_Contact_BAO_Query::buildQillForFieldValue( + 'CRM_Contact_BAO_Contact', + "contact_a.id", + $this->_params[$id][2], + $this->_params[$id][1] + ); + $this->_qill[0][] = ts("%1 %2 %3", [ + 1 => $field['title'], + 2 => $qillop, + 3 => $qillVal + ]); } else { $this->whereClauseSingle($this->_params[$id], $apiEntity); @@ -3051,6 +3060,7 @@ class CRM_Contact_BAO_Query { $groupContactCacheClause = ''; if (count($smartGroupIDs) || empty($value)) { $this->_groupUniqueKey = uniqid(); + $this->_groupKeys[] = $this->_groupUniqueKey; $gccTableAlias = "civicrm_group_contact_cache_{$this->_groupUniqueKey}"; $groupContactCacheClause = $this->addGroupContactCache($smartGroupIDs, $gccTableAlias, "contact_a", $op); if (!empty($groupContactCacheClause)) { @@ -3082,8 +3092,8 @@ class CRM_Contact_BAO_Query { } } - public function getGroupCacheTableKey() { - return $this->_groupUniqueKey; + public function getGroupCacheTableKeys() { + return $this->_groupKeys; } /** @@ -3916,7 +3926,21 @@ WHERE $smartGroupClause $name = $targetName[4] ? "%$name%" : $name; $this->_where[$grouping][] = "contact_b_log.sort_name LIKE '%$name%'"; $this->_tables['civicrm_log'] = $this->_whereTables['civicrm_log'] = 1; - $this->_qill[$grouping][] = ts('Modified By') . " $name"; + $fieldTitle = ts('Added By'); + foreach ($this->_params as $params) { + if ($params[0] == 'log_date') { + if ($params[2] == 2) { + $fieldTitle = ts('Modified By'); + } + break; + } + } + list($qillop, $qillVal) = self::buildQillForFieldValue(NULL, 'changed_by', $name, 'LIKE'); + $this->_qill[$grouping][] = ts("%1 %2 '%3'", [ + 1 => $fieldTitle, + 2 => $qillop, + 3 => $qillVal, + ]); } /** @@ -4881,97 +4905,7 @@ civicrm_relationship.start_date > {$today} $additionalFromClause = NULL, $skipOrderAndLimit = FALSE ) { - if ($includeContactIds) { - $this->_includeContactIds = TRUE; - $this->_whereClause = $this->whereClause(); - } - - $onlyDeleted = in_array(array('deleted_contacts', '=', '1', '0', '0'), $this->_params); - - // if we’re explicitly looking for a certain contact’s contribs, events, etc. - // and that contact happens to be deleted, set $onlyDeleted to true - foreach ($this->_params as $values) { - $name = CRM_Utils_Array::value(0, $values); - $op = CRM_Utils_Array::value(1, $values); - $value = CRM_Utils_Array::value(2, $values); - if ($name == 'contact_id' and $op == '=') { - if (CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact', $value, 'is_deleted')) { - $onlyDeleted = TRUE; - } - break; - } - } - - // building the query string - $groupBy = $groupByCols = NULL; - if (!$count) { - if (isset($this->_groupByComponentClause)) { - $groupBy = $this->_groupByComponentClause; - $groupByCols = preg_replace('/^GROUP BY /', '', trim($this->_groupByComponentClause)); - $groupByCols = explode(', ', $groupByCols); - } - elseif ($this->_useGroupBy) { - $groupByCols = array('contact_a.id'); - } - } - if ($this->_mode & CRM_Contact_BAO_Query::MODE_ACTIVITY && (!$count)) { - $groupByCols = array('civicrm_activity.id'); - } - - $order = $orderBy = $limit = ''; - if (!$count) { - list($order, $additionalFromClause) = $this->prepareOrderBy($sort, $sortByChar, $sortOrder, $additionalFromClause); - - if ($rowCount > 0 && $offset >= 0) { - $offset = CRM_Utils_Type::escape($offset, 'Int'); - $rowCount = CRM_Utils_Type::escape($rowCount, 'Int'); - $limit = " LIMIT $offset, $rowCount "; - } - } - // Two cases where we are disabling FGB (FULL_GROUP_BY_MODE): - // 1. Expecting the search query to return all the first single letter characters of contacts ONLY, but when FGB is enabled - // MySQL expect the columns present in GROUP BY, must be present in SELECT clause and that results into error, needless to have other columns. - // 2. When GROUP BY columns are present then disable FGB otherwise it demands to add ORDER BY columns in GROUP BY and eventually in SELECT - // clause. This will impact the search query output. - $disableFullGroupByMode = ($sortByChar || !empty($groupByCols) || $groupContacts); - - if ($disableFullGroupByMode) { - CRM_Core_DAO::disableFullGroupByMode(); - } - - // CRM-15231 - $this->_sort = $sort; - - //CRM-15967 - $this->includePseudoFieldsJoin($sort); - - list($select, $from, $where, $having) = $this->query($count, $sortByChar, $groupContacts, $onlyDeleted); - - if (!empty($groupByCols)) { - $groupBy = " GROUP BY " . implode(', ', $groupByCols); - } - - if ($additionalWhereClause) { - $where = $where . ' AND ' . $additionalWhereClause; - } - - //additional from clause should be w/ proper joins. - if ($additionalFromClause) { - $from .= "\n" . $additionalFromClause; - } - - // if we are doing a transform, do it here - // use the $from, $where and $having to get the contact ID - if ($this->_displayRelationshipType) { - $this->filterRelatedContacts($from, $where, $having); - } - - if ($skipOrderAndLimit) { - $query = "$select $from $where $having $groupBy"; - } - else { - $query = "$select $from $where $having $groupBy $order $limit"; - } + $query = $this->getSearchSQL($offset, $rowCount, $sort, $count, $includeContactIds, $sortByChar, $groupContacts, $additionalWhereClause, $sortOrder, $additionalFromClause, $skipOrderAndLimit); if ($returnQuery) { return $query; @@ -4982,9 +4916,8 @@ civicrm_relationship.start_date > {$today} $dao = CRM_Core_DAO::executeQuery($query); - if ($disableFullGroupByMode) { - CRM_Core_DAO::reenableFullGroupByMode(); - } + // We can always call this - it will only re-enable if it was originally enabled. + CRM_Core_DAO::reenableFullGroupByMode(); if ($groupContacts) { $ids = array(); @@ -4997,6 +4930,22 @@ civicrm_relationship.start_date > {$today} return $dao; } + /** + * Create and query the db for a contact search. + * + * @return CRM_Core_DAO + */ + public function alphabetQuery() { + $query = $this->getSearchSQL(NULL, NULL, NULL, FALSE, FALSE, TRUE); + + $dao = CRM_Core_DAO::executeQuery($query); + + // We can always call this - it will only re-enable if it was originally enabled. + CRM_Core_DAO::reenableFullGroupByMode(); + + return $dao; + } + /** * Fetch a list of contacts for displaying a search results page * @@ -5104,15 +5053,8 @@ civicrm_relationship.start_date > {$today} * * @return array */ - public function &summaryContribution($context = NULL) { + public function summaryContribution($context = NULL) { list($innerselect, $from, $where, $having) = $this->query(TRUE); - - // hack $select - $select = " -SELECT COUNT( conts.total_amount ) as total_count, - SUM( conts.total_amount ) as total_amount, - AVG( conts.total_amount ) as total_avg, - conts.currency as currency"; if ($this->_permissionWhereClause) { $where .= " AND " . $this->_permissionWhereClause; } @@ -5120,133 +5062,16 @@ SELECT COUNT( conts.total_amount ) as total_count, $where .= " AND contact_a.is_deleted = 0 "; } - $query = $this->appendFinancialTypeWhereAndFromToQueryStrings($where, $from); - - // make sure contribution is completed - CRM-4989 - $completedWhere = $where . " AND civicrm_contribution.contribution_status_id = 1 "; + $this->appendFinancialTypeWhereAndFromToQueryStrings($where, $from); - $summary = array(); - $summary['total'] = array(); - $summary['total']['count'] = $summary['total']['amount'] = $summary['total']['avg'] = "n/a"; - $innerQuery = "SELECT civicrm_contribution.total_amount, COUNT(civicrm_contribution.total_amount) as civicrm_contribution_total_amount_count, - civicrm_contribution.currency $from $completedWhere"; - $query = "$select FROM ( - $innerQuery GROUP BY civicrm_contribution.id - ) as conts - GROUP BY currency"; - - $dao = CRM_Core_DAO::executeQuery($query); + $summary = ['total' => []]; + $this->addBasicStatsToSummary($summary, $where, $from); - $summary['total']['count'] = 0; - $summary['total']['amount'] = $summary['total']['avg'] = array(); - while ($dao->fetch()) { - $summary['total']['count'] += $dao->total_count; - $summary['total']['amount'][] = CRM_Utils_Money::format($dao->total_amount, $dao->currency); - $summary['total']['avg'][] = CRM_Utils_Money::format($dao->total_avg, $dao->currency); - } - - $orderBy = 'ORDER BY civicrm_contribution_total_amount_count DESC'; - $groupBy = 'GROUP BY currency, civicrm_contribution.total_amount'; - $modeSQL = "$select, SUBSTRING_INDEX(GROUP_CONCAT(conts.total_amount - ORDER BY conts.civicrm_contribution_total_amount_count DESC SEPARATOR ';'), ';', 1) as amount, - MAX(conts.civicrm_contribution_total_amount_count) as civicrm_contribution_total_amount_count - FROM ($innerQuery - $groupBy $orderBy) as conts - GROUP BY currency"; - - $summary['total']['mode'] = CRM_Contribute_BAO_Contribution::computeStats('mode', $modeSQL); - - $medianSQL = "{$from} {$completedWhere}"; - $summary['total']['median'] = CRM_Contribute_BAO_Contribution::computeStats('median', $medianSQL, 'civicrm_contribution'); - $summary['total']['currencyCount'] = count($summary['total']['median']); - - if (!empty($summary['total']['amount'])) { - $summary['total']['amount'] = implode(', ', $summary['total']['amount']); - $summary['total']['avg'] = implode(', ', $summary['total']['avg']); - $summary['total']['mode'] = implode(', ', $summary['total']['mode']); - $summary['total']['median'] = implode(', ', $summary['total']['median']); - } - else { - $summary['total']['amount'] = $summary['total']['avg'] = $summary['total']['median'] = 0; - } - - // soft credit summary if (CRM_Contribute_BAO_Query::isSoftCreditOptionEnabled()) { - $softCreditWhere = "{$completedWhere} AND civicrm_contribution_soft.id IS NOT NULL"; - $query = " - $select FROM ( - SELECT civicrm_contribution_soft.amount as total_amount, civicrm_contribution_soft.currency $from $softCreditWhere - GROUP BY civicrm_contribution_soft.id - ) as conts - GROUP BY currency"; - $dao = CRM_Core_DAO::executeQuery($query); - $summary['soft_credit']['count'] = 0; - $summary['soft_credit']['amount'] = $summary['soft_credit']['avg'] = array(); - while ($dao->fetch()) { - $summary['soft_credit']['count'] += $dao->total_count; - $summary['soft_credit']['amount'][] = CRM_Utils_Money::format($dao->total_amount, $dao->currency); - $summary['soft_credit']['avg'][] = CRM_Utils_Money::format($dao->total_avg, $dao->currency); - } - if (!empty($summary['soft_credit']['amount'])) { - $summary['soft_credit']['amount'] = implode(', ', $summary['soft_credit']['amount']); - $summary['soft_credit']['avg'] = implode(', ', $summary['soft_credit']['avg']); - } - else { - $summary['soft_credit']['amount'] = $summary['soft_credit']['avg'] = 0; - } - } - - // hack $select - //@todo - this could be one query using the IF in mysql - eg - // SELECT sum(total_completed), sum(count_completed), sum(count_cancelled), sum(total_cancelled) FROM ( - // SELECT civicrm_contribution.total_amount, civicrm_contribution.currency , - // IF(civicrm_contribution.contribution_status_id = 1, 1, 0 ) as count_completed, - // IF(civicrm_contribution.contribution_status_id = 1, total_amount, 0 ) as total_completed, - // IF(civicrm_contribution.cancel_date IS NOT NULL = 1, 1, 0 ) as count_cancelled, - // IF(civicrm_contribution.cancel_date IS NOT NULL = 1, total_amount, 0 ) as total_cancelled - // FROM civicrm_contact contact_a - // LEFT JOIN civicrm_contribution ON civicrm_contribution.contact_id = contact_a.id - // WHERE ( ... where clause.... - // AND (civicrm_contribution.cancel_date IS NOT NULL OR civicrm_contribution.contribution_status_id = 1) - // ) as conts - - $select = " -SELECT COUNT( conts.total_amount ) as cancel_count, - SUM( conts.total_amount ) as cancel_amount, - AVG( conts.total_amount ) as cancel_avg, - conts.currency as currency"; - - $where .= " AND civicrm_contribution.cancel_date IS NOT NULL "; - if ($context == 'search') { - $where .= " AND contact_a.is_deleted = 0 "; + $this->addBasicSoftCreditStatsToStats($summary, $where, $from); } - $query = "$select FROM ( - SELECT civicrm_contribution.total_amount, civicrm_contribution.currency $from $where - GROUP BY civicrm_contribution.id - ) as conts - GROUP BY currency"; - - $dao = CRM_Core_DAO::executeQuery($query); - - if ($dao->N <= 1) { - if ($dao->fetch()) { - $summary['cancel']['count'] = $dao->cancel_count; - $summary['cancel']['amount'] = CRM_Utils_Money::format($dao->cancel_amount, $dao->currency); - $summary['cancel']['avg'] = CRM_Utils_Money::format($dao->cancel_avg, $dao->currency); - } - } - else { - $summary['cancel']['count'] = 0; - $summary['cancel']['amount'] = $summary['cancel']['avg'] = array(); - while ($dao->fetch()) { - $summary['cancel']['count'] += $dao->cancel_count; - $summary['cancel']['amount'][] = CRM_Utils_Money::format($dao->cancel_amount, $dao->currency); - $summary['cancel']['avg'][] = CRM_Utils_Money::format($dao->cancel_avg, $dao->currency); - } - $summary['cancel']['amount'] = implode(', ', $summary['cancel']['amount']); - $summary['cancel']['avg'] = implode(', ', $summary['cancel']['avg']); - } + $this->addBasicCancelStatsToSummary($summary, $where, $from); return $summary; } @@ -6438,10 +6263,10 @@ AND displayRelType.is_active = 1 * list(string $orderByClause, string $additionalFromClause). */ protected function prepareOrderBy($sort, $sortByChar, $sortOrder, $additionalFromClause) { - $order = NULL; - $orderByArray = array(); - $config = CRM_Core_Config::singleton(); - if ($config->includeOrderByClause || + $orderByArray = []; + $orderBy = ''; + + if (CRM_Core_Config::singleton()->includeOrderByClause || isset($this->_distinctComponentClause) ) { if ($sort) { @@ -6462,39 +6287,31 @@ AND displayRelType.is_active = 1 $orderBy = str_replace('sort_name', 'contact_a.sort_name', $orderBy); } - $order = " ORDER BY $orderBy"; - if ($sortOrder) { - $order .= " $sortOrder"; + $orderBy .= " $sortOrder"; } // always add contact_a.id to the ORDER clause // so the order is deterministic - if (strpos('contact_a.id', $order) === FALSE) { - $order .= ", contact_a.id"; + if (strpos('contact_a.id', $orderBy) === FALSE) { + $orderBy .= ", contact_a.id"; } } } elseif ($sortByChar) { - $orderByArray = array("UPPER(LEFT(contact_a.sort_name, 1)) asc"); + $orderBy = " sort_name asc"; } else { - $order = " ORDER BY contact_a.sort_name ASC, contact_a.id"; + $orderBy = " contact_a.sort_name ASC, contact_a.id"; } } - if (!$order && empty($orderByArray)) { - return array($order, $additionalFromClause); + if (!$orderBy) { + return [NULL, $additionalFromClause]; } // Remove this here & add it at the end for simplicity. - $order = trim(str_replace('ORDER BY', '', $order)); + $order = trim($orderBy); + $orderByArray = explode(',', $order); - // hack for order clause - if (!empty($orderByArray)) { - $order = implode(', ', $orderByArray); - } - else { - $orderByArray = explode(',', $order); - } foreach ($orderByArray as $orderByClause) { $orderByClauseParts = explode(' ', trim($orderByClause)); $field = $orderByClauseParts[0]; @@ -6531,24 +6348,32 @@ AND displayRelType.is_active = 1 $this->_select = array_merge($this->_select, $this->_customQuery->_select); $this->_tables = array_merge($this->_tables, $this->_customQuery->_tables); } - foreach ($this->_pseudoConstantsSelect as $key => $pseudoConstantMetadata) { - // By replacing the join to the option value table with the mysql construct - // ORDER BY field('contribution_status_id', 2,1,4) - // we can remove a join. In the case of the option value join it is - /// a join known to cause slow queries. - // @todo cover other pseudoconstant types. Limited to option group ones in the - // first instance for scope reasons. They require slightly different handling as the column (label) - // is not declared for them. - // @todo so far only integer fields are being handled. If we add string fields we need to look at - // escaping. - if (isset($pseudoConstantMetadata['pseudoconstant']) - && isset($pseudoConstantMetadata['pseudoconstant']['optionGroupName']) - && $field === CRM_Utils_Array::value('optionGroupName', $pseudoConstantMetadata['pseudoconstant']) + + // By replacing the join to the option value table with the mysql construct + // ORDER BY field('contribution_status_id', 2,1,4) + // we can remove a join. In the case of the option value join it is + /// a join known to cause slow queries. + // @todo cover other pseudoconstant types. Limited to option group ones & Foreign keys + // matching an id+name parrern in the + // first instance for scope reasons. They require slightly different handling as the column (label) + // is not declared for them. + // @todo so far only integer fields are being handled. If we add string fields we need to look at + // escaping. + $fieldSpec = $this->getMetadataForRealField($field); + $pseudoConstantMetadata = CRM_Utils_Array::value('pseudoconstant', $fieldSpec, FALSE); + if (!empty($pseudoConstantMetadata) + ) { + if (!empty($pseudoConstantMetadata['optionGroupName']) + || $this->isPseudoFieldAnFK($fieldSpec) ) { - $sortedOptions = $pseudoConstantMetadata['bao']::buildOptions($pseudoConstantMetadata['pseudoField'], NULL, array( - 'orderColumn' => 'label', - )); - $order = str_replace("$field $direction", "field({$pseudoConstantMetadata['pseudoField']}," . implode(',', array_keys($sortedOptions)) . ") $direction", $order); + $sortedOptions = $fieldSpec['bao']::buildOptions($fieldSpec['name'], NULL, [ + 'orderColumn' => CRM_Utils_Array::value('labelColumn', $pseudoConstantMetadata, 'label'), + ]); + $fieldIDsInOrder = implode(',', array_keys($sortedOptions)); + // Pretty sure this validation ALSO happens in the order clause & this can't be reached but... + // this might give some early warning. + CRM_Utils_Type::validate($fieldIDsInOrder, 'CommaSeparatedIntegers'); + $order = str_replace("$field", "field({$fieldSpec['name']},$fieldIDsInOrder)", $order); } //CRM-12565 add "`" around $field if it is a pseudo constant // This appears to be for 'special' fields like locations with appended numbers or hyphens .. maybe. @@ -6629,18 +6454,26 @@ AND displayRelType.is_active = 1 * @return bool */ private function pseudoConstantNameIsInReturnProperties($field, $fieldName = NULL) { - if (!isset($field['pseudoconstant']['optionGroupName'])) { + $realField = $this->getMetadataForRealField($fieldName); + if (!isset($realField['pseudoconstant'])) { + return FALSE; + } + $pseudoConstant = $realField['pseudoconstant']; + if (empty($pseudoConstant['optionGroupName']) && + CRM_Utils_Array::value('labelColumn', $pseudoConstant) !== 'name') { + // We are increasing our pseudoconstant handling - but still very cautiously, + // hence the check for labelColumn === name return FALSE; } - if (CRM_Utils_Array::value($field['pseudoconstant']['optionGroupName'], $this->_returnProperties)) { + if (!empty($pseudoConstant['optionGroupName']) && CRM_Utils_Array::value($pseudoConstant['optionGroupName'], $this->_returnProperties)) { return TRUE; } if (CRM_Utils_Array::value($fieldName, $this->_returnProperties)) { return TRUE; } // Is this still required - the above goes off the unique name. Test with things like - // communication_prefferences & prefix_id. + // communication_preferences & prefix_id. if (CRM_Utils_Array::value($field['name'], $this->_returnProperties)) { return TRUE; } @@ -6661,4 +6494,459 @@ AND displayRelType.is_active = 1 return $select; } + /** + * Add basic statistics to the summary. + * + * @param array $summary + * @param string $where + * @param string $from + * + * @return array + */ + protected function addBasicStatsToSummary(&$summary, $where, $from) { + $summary['total']['count'] = 0; + $summary['total']['amount'] = $summary['total']['avg'] = []; + + $query = " + SELECT COUNT( conts.total_amount ) as total_count, + SUM( conts.total_amount ) as total_amount, + AVG( conts.total_amount ) as total_avg, + conts.currency as currency + FROM ( + SELECT civicrm_contribution.total_amount, COUNT(civicrm_contribution.total_amount) as civicrm_contribution_total_amount_count, + civicrm_contribution.currency + $from + $where AND civicrm_contribution.contribution_status_id = 1 + GROUP BY civicrm_contribution.id + ) as conts + GROUP BY currency"; + + $dao = CRM_Core_DAO::executeQuery($query); + + while ($dao->fetch()) { + $summary['total']['count'] += $dao->total_count; + $summary['total']['amount'][] = CRM_Utils_Money::format($dao->total_amount, $dao->currency); + $summary['total']['avg'][] = CRM_Utils_Money::format($dao->total_avg, $dao->currency); + } + + if (!empty($summary['total']['amount'])) { + $summary['total']['amount'] = implode(', ', $summary['total']['amount']); + $summary['total']['avg'] = implode(', ', $summary['total']['avg']); + } + else { + $summary['total']['amount'] = $summary['total']['avg'] = 0; + } + return $summary; + } + + /** + * Add basic soft credit statistics to summary array. + * + * @param array $summary + * @param string $where + * @param string $from + */ + protected function addBasicSoftCreditStatsToStats(&$summary, $where, $from) { + $query = " + SELECT COUNT( conts.total_amount ) as total_count, + SUM( conts.total_amount ) as total_amount, + AVG( conts.total_amount ) as total_avg, + conts.currency as currency + FROM ( + SELECT civicrm_contribution_soft.amount as total_amount, civicrm_contribution_soft.currency + $from + $where AND civicrm_contribution.contribution_status_id = 1 AND civicrm_contribution_soft.id IS NOT NULL + GROUP BY civicrm_contribution_soft.id + ) as conts + GROUP BY currency"; + + $dao = CRM_Core_DAO::executeQuery($query); + $summary['soft_credit']['count'] = 0; + $summary['soft_credit']['amount'] = $summary['soft_credit']['avg'] = []; + while ($dao->fetch()) { + $summary['soft_credit']['count'] += $dao->total_count; + $summary['soft_credit']['amount'][] = CRM_Utils_Money::format($dao->total_amount, $dao->currency); + $summary['soft_credit']['avg'][] = CRM_Utils_Money::format($dao->total_avg, $dao->currency); + } + if (!empty($summary['soft_credit']['amount'])) { + $summary['soft_credit']['amount'] = implode(', ', $summary['soft_credit']['amount']); + $summary['soft_credit']['avg'] = implode(', ', $summary['soft_credit']['avg']); + } + else { + $summary['soft_credit']['amount'] = $summary['soft_credit']['avg'] = 0; + } + } + + /** + * Add basic stats about cancelled contributions to the summary. + * + * @param array $summary + * @param string $where + * @param string $from + */ + protected function addBasicCancelStatsToSummary(&$summary, $where, $from) { + $query = " + SELECT COUNT( conts.total_amount ) as cancel_count, + SUM( conts.total_amount ) as cancel_amount, + AVG( conts.total_amount ) as cancel_avg, + conts.currency as currency + FROM ( + SELECT civicrm_contribution.total_amount, civicrm_contribution.currency + $from + $where AND civicrm_contribution.cancel_date IS NOT NULL + GROUP BY civicrm_contribution.id + ) as conts + GROUP BY currency"; + + $dao = CRM_Core_DAO::executeQuery($query); + + if ($dao->N <= 1) { + if ($dao->fetch()) { + $summary['cancel']['count'] = $dao->cancel_count; + $summary['cancel']['amount'] = CRM_Utils_Money::format($dao->cancel_amount, $dao->currency); + $summary['cancel']['avg'] = CRM_Utils_Money::format($dao->cancel_avg, $dao->currency); + } + } + else { + $summary['cancel']['count'] = 0; + $summary['cancel']['amount'] = $summary['cancel']['avg'] = []; + while ($dao->fetch()) { + $summary['cancel']['count'] += $dao->cancel_count; + $summary['cancel']['amount'][] = CRM_Utils_Money::format($dao->cancel_amount, $dao->currency); + $summary['cancel']['avg'][] = CRM_Utils_Money::format($dao->cancel_avg, $dao->currency); + } + $summary['cancel']['amount'] = implode(', ', $summary['cancel']['amount']); + $summary['cancel']['avg'] = implode(', ', $summary['cancel']['avg']); + } + } + + /** + * Create the sql query for an contact search. + * + * @param int $offset + * The offset for the query. + * @param int $rowCount + * The number of rows to return. + * @param string|CRM_Utils_Sort $sort + * The order by string. + * @param bool $count + * Is this a count only query ?. + * @param bool $includeContactIds + * Should we include contact ids?. + * @param bool $sortByChar + * If true returns the distinct array of first characters for search results. + * @param bool $groupContacts + * If true, return only the contact ids. + * @param string $additionalWhereClause + * If the caller wants to further restrict the search (used for components). + * @param null $sortOrder + * @param string $additionalFromClause + * Should be clause with proper joins, effective to reduce where clause load. + * + * @param bool $skipOrderAndLimit + * @return string + */ + public function getSearchSQL( + $offset = 0, $rowCount = 0, $sort = NULL, + $count = FALSE, $includeContactIds = FALSE, + $sortByChar = FALSE, $groupContacts = FALSE, + $additionalWhereClause = NULL, $sortOrder = NULL, + $additionalFromClause = NULL, $skipOrderAndLimit = FALSE) { + + $sqlParts = $this->getSearchSQLParts($offset, $rowCount, $sort, $count, $includeContactIds, $sortByChar, $groupContacts, $additionalWhereClause, $sortOrder, $additionalFromClause); + + if ($skipOrderAndLimit) { + CRM_Core_Error::deprecatedFunctionWarning('skipOrderAndLimit is deprected - call getSearchSQLParts & construct it in the calling function'); + $query = "{$sqlParts['select']} {$sqlParts['from']} {$sqlParts['where']} {$sqlParts['having']} {$sqlParts['group_by']}"; + } + else { + $query = "{$sqlParts['select']} {$sqlParts['from']} {$sqlParts['where']} {$sqlParts['having']} {$sqlParts['group_by']} {$sqlParts['order_by']} {$sqlParts['limit']}"; + } + return $query; + } + + /** + * Get the component parts of the search query as an array. + * + * @param int $offset + * The offset for the query. + * @param int $rowCount + * The number of rows to return. + * @param string|CRM_Utils_Sort $sort + * The order by string. + * @param bool $count + * Is this a count only query ?. + * @param bool $includeContactIds + * Should we include contact ids?. + * @param bool $sortByChar + * If true returns the distinct array of first characters for search results. + * @param bool $groupContacts + * If true, return only the contact ids. + * @param string $additionalWhereClause + * If the caller wants to further restrict the search (used for components). + * @param null $sortOrder + * @param string $additionalFromClause + * Should be clause with proper joins, effective to reduce where clause load. + * + * @return array + */ + public function getSearchSQLParts($offset = 0, $rowCount = 0, $sort = NULL, + $count = FALSE, $includeContactIds = FALSE, + $sortByChar = FALSE, $groupContacts = FALSE, + $additionalWhereClause = NULL, $sortOrder = NULL, + $additionalFromClause = NULL) { + if ($includeContactIds) { + $this->_includeContactIds = TRUE; + $this->_whereClause = $this->whereClause(); + } + $onlyDeleted = in_array([ + 'deleted_contacts', + '=', + '1', + '0', + '0' + ], $this->_params); + + // if we’re explicitly looking for a certain contact’s contribs, events, etc. + // and that contact happens to be deleted, set $onlyDeleted to true + foreach ($this->_params as $values) { + $name = CRM_Utils_Array::value(0, $values); + $op = CRM_Utils_Array::value(1, $values); + $value = CRM_Utils_Array::value(2, $values); + if ($name == 'contact_id' and $op == '=') { + if (CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact', $value, 'is_deleted')) { + $onlyDeleted = TRUE; + } + break; + } + } + + // building the query string + $groupBy = $groupByCols = NULL; + if (!$count) { + if (isset($this->_groupByComponentClause)) { + $groupByCols = preg_replace('/^GROUP BY /', '', trim($this->_groupByComponentClause)); + $groupByCols = explode(', ', $groupByCols); + } + elseif ($this->_useGroupBy) { + $groupByCols = ['contact_a.id']; + } + } + if ($this->_mode & CRM_Contact_BAO_Query::MODE_ACTIVITY && (!$count)) { + $groupByCols = ['civicrm_activity.id']; + } + if (!empty($groupByCols)) { + $groupBy = " GROUP BY " . implode(', ', $groupByCols); + } + + $order = $orderBy = ''; + if (!$count) { + list($order, $additionalFromClause) = $this->prepareOrderBy($sort, $sortByChar, $sortOrder, $additionalFromClause); + } + // Two cases where we are disabling FGB (FULL_GROUP_BY_MODE): + // 1. Expecting the search query to return all the first single letter characters of contacts ONLY, but when FGB is enabled + // MySQL expect the columns present in GROUP BY, must be present in SELECT clause and that results into error, needless to have other columns. + // 2. When GROUP BY columns are present then disable FGB otherwise it demands to add ORDER BY columns in GROUP BY and eventually in SELECT + // clause. This will impact the search query output. + $disableFullGroupByMode = ($sortByChar || !empty($groupBy) || $groupContacts); + + if ($disableFullGroupByMode) { + CRM_Core_DAO::disableFullGroupByMode(); + } + + // CRM-15231 + $this->_sort = $sort; + + //CRM-15967 + $this->includePseudoFieldsJoin($sort); + + list($select, $from, $where, $having) = $this->query($count, $sortByChar, $groupContacts, $onlyDeleted); + + if ($additionalWhereClause) { + $where = $where . ' AND ' . $additionalWhereClause; + } + + //additional from clause should be w/ proper joins. + if ($additionalFromClause) { + $from .= "\n" . $additionalFromClause; + } + + // if we are doing a transform, do it here + // use the $from, $where and $having to get the contact ID + if ($this->_displayRelationshipType) { + $this->filterRelatedContacts($from, $where, $having); + } + $limit = (!$count && $rowCount) ? " LIMIT " . CRM_Utils_Type::escape($offset, 'Int') . ", " . CRM_Utils_Type::escape($rowCount, 'Int') : ''; + + return [ + 'select' => $select, + 'from' => $from, + 'where' => $where, + 'order_by' => $order, + 'group_by' => $groupBy, + 'having' => $having, + 'limit' => $limit, + ]; + } + + /** + * Get the metadata for a given field. + * + * @param string $fieldName + * + * @return array + */ + protected function getMetadataForField($fieldName) { + if ($fieldName === 'contact_a.id') { + // This seems to be the only anomaly. + $fieldName = 'id'; + } + $pseudoField = isset($this->_pseudoConstantsSelect[$fieldName]) ? $this->_pseudoConstantsSelect[$fieldName] : []; + $field = isset($this->_fields[$fieldName]) ? $this->_fields[$fieldName] : $pseudoField; + $field = array_merge($field, $pseudoField); + if (!empty($field) && empty($field['name'])) { + // standardising field formatting here - over time we can phase out variants. + // all paths using this currently unit tested + $field['name'] = CRM_Utils_Array::value('field_name', $field, CRM_Utils_Array::value('idCol', $field, $fieldName)); + } + return $field; + } + + /** + * Get the metadata for a given field, returning the 'real field' if it is a pseudofield. + * + * @param string $fieldName + * + * @return array + */ + protected function getMetadataForRealField($fieldName) { + $field = $this->getMetadataForField($fieldName); + if (!empty($field['is_pseudofield_for'])) { + $field = $this->getMetadataForField($field['is_pseudofield_for']); + $field['pseudofield_name'] = $fieldName; + } + elseif (!empty($field['pseudoconstant'])) { + if (!empty($field['pseudoconstant']['optionGroupName'])) { + $field['pseudofield_name'] = $field['pseudoconstant']['optionGroupName']; + if (empty($field['table_name'])) { + if (!empty($field['where'])) { + $field['table_name'] = explode('.', $field['where'])[0]; + } + else { + $field['table_name'] = 'civicrm_contact'; + } + } + } + } + return $field; + } + + /** + * If we have a field that is better rendered via the pseudoconstant handled them here. + * + * Rather than joining in the additional table we render the option value on output. + * + * @todo - so far this applies to a narrow range of pseudocontants. We are adding them + * carefully with test coverage but aim to extend. + * + * @param string $name + */ + protected function addPseudoconstantFieldToSelect($name) { + $field = $this->getMetadataForRealField($name); + $realFieldName = $field['name']; + $pseudoFieldName = CRM_Utils_Array::value('pseudofield_name', $field); + if ($pseudoFieldName) { + // @todo - we don't really need to build this array now we have metadata more available with getMetadataForField fn. + $this->_pseudoConstantsSelect[$pseudoFieldName] = [ + 'pseudoField' => $pseudoFieldName, + 'idCol' => $realFieldName, + 'field_name' => $field['name'], + 'bao' => $field['bao'], + 'pseudoconstant' => $field['pseudoconstant'], + ]; + } + + $this->_tables[$field['table_name']] = 1; + $this->_element[$realFieldName] = 1; + $this->_select[$field['name']] = str_replace('civicrm_contact.', 'contact_a.', "{$field['where']} as `$realFieldName`"); + } + + /** + * Is this pseudofield a foreign key constraint. + * + * We are trying to cautiously expand our pseudoconstant handling. This check allows us + * to extend to a narrowly defined type (and then only if the pseudofield is in the fields + * array which is done for contributions which are mostly handled as pseudoconstants. + * + * @param $fieldSpec + * + * @return bool + */ + protected function isPseudoFieldAnFK($fieldSpec) { + if (empty($fieldSpec['FKClassName']) + || CRM_Utils_Array::value('keyColumn', $fieldSpec['pseudoconstant']) !== 'id' + || CRM_Utils_Array::value('labelColumn', $fieldSpec['pseudoconstant']) !== 'name') { + return FALSE; + } + return TRUE; + } + + /** + * Is the field a relative date field. + * + * @param string $fieldName + * + * @return bool + */ + protected function isARelativeDateField($fieldName) { + if (substr($fieldName, -9, 9) !== '_relative') { + return FALSE; + } + $realField = substr($fieldName, 0, strlen($fieldName) - 9); + return isset($this->_fields[$realField]); + } + + /** + * @param $values + */ + protected function buildRelativeDateQuery(&$values) { + $value = CRM_Utils_Array::value(2, $values); + if (empty($value)) { + return; + } + $fieldName = substr($values[0], 0, strlen($values[0]) - 9); + $fieldSpec = $this->_fields[$fieldName]; + $tableName = $fieldSpec['table_name']; + $filters = CRM_Core_OptionGroup::values('relative_date_filters'); + $grouping = CRM_Utils_Array::value(3, $values); + $this->_tables[$tableName] = $this->_whereTables[$tableName] = 1; + + $dates = CRM_Utils_Date::getFromTo($value, NULL, NULL); + if (empty($dates[0])) { + // ie. no start date we only have end date + $this->_where[$grouping][] = $fieldSpec['where'] . " <= '{$dates[1]}'"; + + $this->_qill[$grouping][] = ts('%1 is ', [$fieldSpec['title']]) . $filters[$value] . ' (' . ts("to %1", [ + CRM_Utils_Date::customFormat($dates[1]), + ]) . ')'; + } + elseif (empty($dates[1])) { + // ie. no end date we only have start date + $this->_where[$grouping][] = $fieldSpec['where'] . " >= '{$dates[1]}'"; + + $this->_qill[$grouping][] = ts('%1 is ', [$fieldSpec['title']]) . $filters[$value] . ' (' . ts("from %1", [ + CRM_Utils_Date::customFormat($dates[0]), + ]) . ')'; + } + else { + // we have start and end dates. + $this->_where[$grouping][] = $fieldSpec['where'] . " BETWEEN '{$dates[0]}' AND '{$dates[1]}'"; + + $this->_qill[$grouping][] = ts('%1 is ', [$fieldSpec['title']]) . $filters[$value] . ' (' . ts("between %1 and %2", [ + CRM_Utils_Date::customFormat($dates[0]), + CRM_Utils_Date::customFormat($dates[1]), + ]) . ')'; + } + } + } diff --git a/civicrm/CRM/Contact/Form/Edit/Address.php b/civicrm/CRM/Contact/Form/Edit/Address.php index 1f80087afc..9dad5533f5 100644 --- a/civicrm/CRM/Contact/Form/Edit/Address.php +++ b/civicrm/CRM/Contact/Form/Edit/Address.php @@ -165,7 +165,7 @@ class CRM_Contact_Form_Edit_Address { $form->addElement('checkbox', "address[$blockId][use_shared_address]", NULL, ts('Use another contact\'s address')); // Override the default profile links to add address form - $profileLinks = CRM_Contact_BAO_Contact::entityRefCreateLinks() ? CRM_Core_BAO_UFGroup::getCreateLinks('', 'shared_address') : FALSE; + $profileLinks = CRM_Contact_BAO_Contact::getEntityRefCreateLinks('shared_address'); $form->addEntityRef("address[$blockId][master_contact_id]", ts('Share With'), array('create' => $profileLinks)); } } diff --git a/civicrm/CRM/Contact/Form/Search/Basic.php b/civicrm/CRM/Contact/Form/Search/Basic.php index 4aa415d447..c68343686f 100644 --- a/civicrm/CRM/Contact/Form/Search/Basic.php +++ b/civicrm/CRM/Contact/Form/Search/Basic.php @@ -200,7 +200,7 @@ class CRM_Contact_Form_Search_Basic extends CRM_Contact_Form_Search { * * @return array|bool */ - public static function formRule($fields) { + public static function formRule($fields, $files, $form) { // check actionName and if next, then do not repeat a search, since we are going to the next page if (array_key_exists('_qf_Search_next', $fields)) { if (empty($fields['task'])) { diff --git a/civicrm/CRM/Contact/Form/Search/Criteria.php b/civicrm/CRM/Contact/Form/Search/Criteria.php index 019ee5f3da..7862472f7f 100644 --- a/civicrm/CRM/Contact/Form/Search/Criteria.php +++ b/civicrm/CRM/Contact/Form/Search/Criteria.php @@ -494,7 +494,7 @@ class CRM_Contact_Form_Search_Criteria { } /** - * @param $form + * @param CRM_Core_Form_Search $form */ public static function demographics(&$form) { $form->add('hidden', 'hidden_demographics', 1); @@ -509,11 +509,11 @@ class CRM_Contact_Form_Search_Criteria { } $form->addGroup($genderOptions, 'gender_id', ts('Gender'))->setAttribute('allowClear', TRUE); - $form->add('text', 'age_low', ts('Min Age'), array('size' => 6)); + $form->add('number', 'age_low', ts('Min Age'), ['class' => 'four', 'min' => 0]); $form->addRule('age_low', ts('Please enter a positive integer'), 'positiveInteger'); - $form->add('text', 'age_high', ts('Max Age'), array('size' => 6)); + $form->add('number', 'age_high', ts('Max Age'), ['class' => 'four', 'min' => 0]); $form->addRule('age_high', ts('Please enter a positive integer'), 'positiveInteger'); - $form->addDate('age_asof_date', ts('Age as of Date'), FALSE, array('formatType' => 'searchDate')); + $form->add('datepicker', 'age_asof_date', ts('As of'), NULL, FALSE, ['time' => FALSE]); CRM_Core_Form_Date::buildDateRange($form, 'birth_date', 1, '_low', '_high', ts('From'), FALSE, FALSE, 'birth'); diff --git a/civicrm/CRM/Contact/Form/Task.php b/civicrm/CRM/Contact/Form/Task.php index a8b9691776..74a62c32a0 100644 --- a/civicrm/CRM/Contact/Form/Task.php +++ b/civicrm/CRM/Contact/Form/Task.php @@ -544,7 +544,9 @@ class CRM_Contact_Form_Task extends CRM_Core_Form_Task { $ssId = $this->get('ssID'); $hiddenSmartParams = array( 'group_type' => array('2' => 1), - 'form_values' => $this->get('formValues'), + // queryParams have been preprocessed esp WRT any entity reference fields - see + + // https://github.com/civicrm/civicrm-core/pull/13250 + 'form_values' => $this->get('queryParams'), 'saved_search_id' => $ssId, 'search_custom_id' => $this->get('customSearchID'), 'search_context' => $this->get('context'), diff --git a/civicrm/CRM/Contact/Page/View/UserDashBoard.php b/civicrm/CRM/Contact/Page/View/UserDashBoard.php index d446882c7d..b9863de198 100644 --- a/civicrm/CRM/Contact/Page/View/UserDashBoard.php +++ b/civicrm/CRM/Contact/Page/View/UserDashBoard.php @@ -58,16 +58,12 @@ class CRM_Contact_Page_View_UserDashBoard extends CRM_Core_Page { public function __construct() { parent::__construct(); - $check = CRM_Core_Permission::check('access Contact Dashboard'); - - if (!$check) { + if (!CRM_Core_Permission::check('access Contact Dashboard')) { CRM_Utils_System::redirect(CRM_Utils_System::url('civicrm/dashboard', 'reset=1')); } $this->_contactId = CRM_Utils_Request::retrieve('id', 'Positive', $this); - - $session = CRM_Core_Session::singleton(); - $userID = $session->get('userID'); + $userID = CRM_Core_Session::singleton()->getLoggedInContactID(); $userChecksum = $this->getUserChecksum(); $validUser = FALSE; @@ -115,10 +111,9 @@ class CRM_Contact_Page_View_UserDashBoard extends CRM_Core_Page { */ public function buildUserDashBoard() { //build component selectors - $dashboardElements = array(); - $config = CRM_Core_Config::singleton(); + $dashboardElements = []; - $this->_userOptions = CRM_Core_BAO_Setting::valueOptions(CRM_Core_BAO_Setting::SYSTEM_PREFERENCES_NAME, + $dashboardOptions = CRM_Core_BAO_Setting::valueOptions(CRM_Core_BAO_Setting::SYSTEM_PREFERENCES_NAME, 'user_dashboard_options' ); @@ -130,7 +125,7 @@ class CRM_Contact_Page_View_UserDashBoard extends CRM_Core_Page { continue; } - if (!empty($this->_userOptions[$name]) && + if (!empty($dashboardOptions[$name]) && (CRM_Core_Permission::access($component->name) || CRM_Core_Permission::check($elem['perm'][0]) ) @@ -148,7 +143,7 @@ class CRM_Contact_Page_View_UserDashBoard extends CRM_Core_Page { } // CRM-16512 - Hide related contact table if user lacks permission to view self - if (!empty($this->_userOptions['Permissioned Orgs']) && CRM_Core_Permission::check('view my contact')) { + if (!empty($dashboardOptions['Permissioned Orgs']) && CRM_Core_Permission::check('view my contact')) { $dashboardElements[] = array( 'class' => 'crm-dashboard-permissionedOrgs', 'templatePath' => 'CRM/Contact/Page/View/RelationshipSelector.tpl', @@ -158,7 +153,7 @@ class CRM_Contact_Page_View_UserDashBoard extends CRM_Core_Page { } - if (!empty($this->_userOptions['PCP'])) { + if (!empty($dashboardOptions['PCP'])) { $dashboardElements[] = array( 'class' => 'crm-dashboard-pcp', 'templatePath' => 'CRM/Contribute/Page/PcpUserDashboard.tpl', @@ -170,7 +165,7 @@ class CRM_Contact_Page_View_UserDashBoard extends CRM_Core_Page { $this->assign('pcpInfo', $pcpInfo); } - if (!empty($this->_userOptions['Assigned Activities']) && empty($this->_isChecksumUser)) { + if (!empty($dashboardOptions['Assigned Activities']) && empty($this->_isChecksumUser)) { // Assigned Activities section $dashboardElements[] = array( 'class' => 'crm-dashboard-assignedActivities', @@ -186,9 +181,9 @@ class CRM_Contact_Page_View_UserDashBoard extends CRM_Core_Page { $this->assign('dashboardElements', $dashboardElements); // return true when 'Invoices / Credit Notes' checkbox is checked - $this->assign('invoices', $this->_userOptions['Invoices / Credit Notes']); + $this->assign('invoices', $dashboardOptions['Invoices / Credit Notes']); - if (!empty($this->_userOptions['Groups'])) { + if (!empty($dashboardOptions['Groups'])) { $this->assign('showGroup', TRUE); //build group selector $gContact = new CRM_Contact_Page_View_UserDashBoard_GroupContact(); diff --git a/civicrm/CRM/Contact/Selector.php b/civicrm/CRM/Contact/Selector.php index b11e19e6e3..7f3952a169 100644 --- a/civicrm/CRM/Contact/Selector.php +++ b/civicrm/CRM/Contact/Selector.php @@ -1028,8 +1028,8 @@ class CRM_Contact_Selector extends CRM_Core_Selector_Base implements CRM_Core_Se } // For core searches use the searchQuery method else { - $sql = $this->_query->searchQuery($start, $end, $sort, FALSE, $this->_query->_includeContactIds, - FALSE, TRUE, TRUE); + $sql = $this->_query->getSearchSQL($start, $end, $sort, FALSE, $this->_query->_includeContactIds, + FALSE, TRUE); } // CRM-9096 @@ -1192,7 +1192,7 @@ class CRM_Contact_Selector extends CRM_Core_Selector_Base implements CRM_Core_Se * @return CRM_Contact_DAO_Contact */ public function alphabetQuery() { - return $this->_query->searchQuery(NULL, NULL, NULL, FALSE, FALSE, TRUE); + return $this->_query->alphabetQuery(); } /** diff --git a/civicrm/CRM/Contribute/BAO/Contribution.php b/civicrm/CRM/Contribute/BAO/Contribution.php index fb5d87f6fc..b89d304cee 100644 --- a/civicrm/CRM/Contribute/BAO/Contribution.php +++ b/civicrm/CRM/Contribute/BAO/Contribution.php @@ -787,10 +787,24 @@ class CRM_Contribute_BAO_Contribution extends CRM_Contribute_DAO_Contribution { self::$_exportableFields = array(); } - $impFields = CRM_Contribute_DAO_Contribution::export(); - $expFieldProduct = CRM_Contribute_DAO_Product::export(); - $expFieldsContrib = CRM_Contribute_DAO_ContributionProduct::export(); - $typeField = CRM_Financial_DAO_FinancialType::export(); + $fields = CRM_Contribute_DAO_Contribution::export(); + if (CRM_Contribute_BAO_Query::isSiteHasProducts()) { + $fields = array_merge( + $fields, + CRM_Contribute_DAO_Product::export(), + CRM_Contribute_DAO_ContributionProduct::export(), + // CRM-16713 - contribution search by Premiums on 'Find Contribution' form. + [ + 'contribution_product_id' => [ + 'title' => ts('Premium'), + 'name' => 'contribution_product_id', + 'where' => 'civicrm_product.id', + 'data_type' => CRM_Utils_Type::T_INT, + ], + ] + ); + } + $financialAccount = CRM_Financial_DAO_FinancialAccount::export(); $contributionPage = array( @@ -858,18 +872,8 @@ class CRM_Contribute_BAO_Contribution extends CRM_Contribute_DAO_Contribution { ), ); - // CRM-16713 - contribution search by Premiums on 'Find Contribution' form. - $premiums = array( - 'contribution_product_id' => array( - 'title' => ts('Premium'), - 'name' => 'contribution_product_id', - 'where' => 'civicrm_product.id', - 'data_type' => CRM_Utils_Type::T_INT, - ), - ); - - $fields = array_merge($impFields, $typeField, $contributionPage, $expFieldProduct, - $expFieldsContrib, $contributionNote, $extraFields, $softCreditFields, $financialAccount, $premiums, $campaignTitle, + $fields = array_merge($fields, $contributionPage, + $contributionNote, $extraFields, $softCreditFields, $financialAccount, $campaignTitle, CRM_Core_BAO_CustomField::getFieldsForImport('Contribution', FALSE, FALSE, FALSE, $checkPermission) ); @@ -879,6 +883,115 @@ class CRM_Contribute_BAO_Contribution extends CRM_Contribute_DAO_Contribution { return self::$_exportableFields; } + /** + * @param $contributionId + * @param $participantId + * @param array $financialTrxn + * + * @param $financialTrxn + */ + protected static function recordPaymentActivity($contributionId, $participantId, $financialTrxn) { + $activityType = ($financialTrxn->total_amount < 0) ? 'Refund' : 'Payment'; + if ($participantId) { + $inputParams['id'] = $participantId; + $values = []; + $ids = []; + $component = 'event'; + $entityObj = CRM_Event_BAO_Participant::getValues($inputParams, $values, $ids); + $entityObj = $entityObj[$participantId]; + } + else { + $entityObj = new CRM_Contribute_BAO_Contribution(); + $entityObj->id = $contributionId; + $entityObj->find(TRUE); + $component = 'contribution'; + } + + self::addActivityForPayment($entityObj, $financialTrxn, $activityType, $component, $contributionId); + } + + /** + * Get the value for the To Financial Account. + * + * @param $contribution + * @param $params + * + * @return int + */ + protected static function getToFinancialAccount($contribution, $params) { + $contributionStatuses = CRM_Contribute_PseudoConstant::contributionStatus(NULL, 'name'); + CRM_Contribute_PseudoConstant::contributionStatus(NULL, 'name'); + $pendingStatus = [ + array_search('Pending', $contributionStatuses), + array_search('In Progress', $contributionStatuses), + ]; + if (in_array(CRM_Utils_Array::value('contribution_status_id', $contribution), $pendingStatus)) { + return CRM_Contribute_PseudoConstant::getRelationalFinancialAccount($contribution['financial_type_id'], 'Accounts Receivable Account is'); + } + elseif (!empty($params['payment_processor'])) { + return CRM_Contribute_PseudoConstant::getRelationalFinancialAccount($contribution['payment_processor'], NULL, 'civicrm_payment_processor'); + } + elseif (!empty($params['payment_instrument_id'])) { + return CRM_Financial_BAO_FinancialTypeAccount::getInstrumentFinancialAccount($contribution['payment_instrument_id']); + } + else { + $relationTypeId = key(CRM_Core_PseudoConstant::accountOptionValues('financial_account_type', NULL, " AND v.name LIKE 'Asset' ")); + $queryParams = [1 => [$relationTypeId, 'Integer']]; + return CRM_Core_DAO::singleValueQuery("SELECT id FROM civicrm_financial_account WHERE is_default = 1 AND financial_account_type_id = %1", $queryParams); + } + } + + /** + * Get memberships realted to the contribution. + * + * @param int $contributionID + * + * @return array + */ + protected static function getRelatedMemberships($contributionID) { + $contribution = new CRM_Contribute_BAO_Contribution(); + $contribution->id = $contributionID; + $contribution->fetch(TRUE); + $contribution->loadRelatedMembershipObjects(); + $result = CRM_Utils_Array::value('membership', $contribution->_relatedObjects, []); + $memberships = []; + foreach ($result as $membership) { + if (empty($membership)) { + continue; + } + // @todo - remove this again & just call api in the first place. + _civicrm_api3_object_to_array($membership, $memberships[$membership->id]); + } + return $memberships; + } + + /** + * @inheritDoc + */ + public function addSelectWhereClause() { + $whereClauses = parent::addSelectWhereClause(); + if ($whereClauses !== []) { + // In this case permisssions have been applied & we assume the + // financialaclreport is applying these + // https://github.com/JMAConsulting/biz.jmaconsulting.financialaclreport/blob/master/financialaclreport.php#L107 + return $whereClauses; + } + + if (!CRM_Financial_BAO_FinancialType::isACLFinancialTypeStatus()) { + return $whereClauses; + } + $types = CRM_Financial_BAO_FinancialType::getAllEnabledAvailableFinancialTypes(); + if (empty($types)) { + $whereClauses['financial_type_id'] = 'IN (0)'; + } + else { + $whereClauses['financial_type_id'] = [ + 'IN (' . implode(',', array_keys($types)) . ')' + ]; + } + return $whereClauses; + } + /** * @param null $status * @param null $startDate @@ -3084,7 +3197,7 @@ INNER JOIN civicrm_activity ON civicrm_activity_contact.activity_id = civicrm_ac * * @param array $financialTrxnValues * - * @return null|object + * @return null|\CRM_Core_BAO_FinancialTrxn */ public static function recordFinancialAccounts(&$params, $financialTrxnValues = NULL) { $skipRecords = $update = $return = $isRelatedId = FALSE; @@ -3765,154 +3878,15 @@ INNER JOIN civicrm_activity ON civicrm_activity_contact.activity_id = civicrm_ac * @return null|object */ public static function recordAdditionalPayment($contributionId, $trxnsData, $paymentType = 'owed', $participantId = NULL, $updateStatus = TRUE) { - $getInfoOf['id'] = $contributionId; - $defaults = array(); - $contributionDAO = CRM_Contribute_BAO_Contribution::retrieve($getInfoOf, $defaults, CRM_Core_DAO::$_nullArray); - if (!$participantId) { - $participantId = CRM_Core_DAO::getFieldValue('CRM_Event_DAO_ParticipantPayment', $contributionId, 'participant_id', 'contribution_id'); - } - - // load related memberships on basis of $contributionDAO object - $contributionDAO->loadRelatedMembershipObjects(); - - // build params for recording financial trxn entry - $params['contribution'] = $contributionDAO; - $params = array_merge($defaults, $params); - $params['skipLineItem'] = TRUE; - $trxnsData['trxn_date'] = !empty($trxnsData['trxn_date']) ? $trxnsData['trxn_date'] : date('YmdHis'); - $params['payment_instrument_id'] = CRM_Utils_Array::value('payment_instrument_id', $trxnsData, CRM_Utils_Array::value('payment_instrument_id', $params)); - $arAccountId = CRM_Contribute_PseudoConstant::getRelationalFinancialAccount($contributionDAO->financial_type_id, 'Accounts Receivable Account is'); - - $completedStatusId = CRM_Core_PseudoConstant::getKey('CRM_Contribute_BAO_Contribution', 'contribution_status_id', 'Completed'); - $paidStatus = CRM_Core_PseudoConstant::getKey('CRM_Financial_DAO_FinancialItem', 'status_id', 'Paid'); if ($paymentType == 'owed') { - $params['partial_payment_total'] = $contributionDAO->total_amount; - $params['partial_amount_to_pay'] = $trxnsData['total_amount']; - $trxnsData['net_amount'] = !empty($trxnsData['net_amount']) ? $trxnsData['net_amount'] : $trxnsData['total_amount']; - $params['pan_truncation'] = CRM_Utils_Array::value('pan_truncation', $trxnsData); - $params['card_type_id'] = CRM_Utils_Array::value('card_type_id', $trxnsData); - $params['check_number'] = CRM_Utils_Array::value('check_number', $trxnsData); - - // record the entry - $financialTrxn = CRM_Contribute_BAO_Contribution::recordFinancialAccounts($params, $trxnsData); - $toFinancialAccount = $arAccountId; - $trxnId = CRM_Core_BAO_FinancialTrxn::getBalanceTrxnAmt($contributionId, $contributionDAO->financial_type_id); - if (!empty($trxnId)) { - $trxnId = $trxnId['trxn_id']; - } - elseif (!empty($contributionDAO->payment_instrument_id)) { - $trxnId = CRM_Financial_BAO_FinancialTypeAccount::getInstrumentFinancialAccount($contributionDAO->payment_instrument_id); - } - else { - $relationTypeId = key(CRM_Core_PseudoConstant::accountOptionValues('financial_account_type', NULL, " AND v.name LIKE 'Asset' ")); - $queryParams = array(1 => array($relationTypeId, 'Integer')); - $trxnId = CRM_Core_DAO::singleValueQuery("SELECT id FROM civicrm_financial_account WHERE is_default = 1 AND financial_account_type_id = %1", $queryParams); - } - - // update statuses - // criteria for updates contribution total_amount == financial_trxns of partial_payments - $sql = "SELECT SUM(ft.total_amount) as sum_of_payments, SUM(ft.net_amount) as net_amount_total -FROM civicrm_financial_trxn ft -LEFT JOIN civicrm_entity_financial_trxn eft - ON (ft.id = eft.financial_trxn_id) -WHERE eft.entity_table = 'civicrm_contribution' - AND eft.entity_id = {$contributionId} - AND ft.to_financial_account_id != {$toFinancialAccount} - AND ft.status_id = {$completedStatusId} -"; - $query = CRM_Core_DAO::executeQuery($sql); - $query->fetch(); - $sumOfPayments = $query->sum_of_payments; - - // update statuses - if ($contributionDAO->total_amount == $sumOfPayments) { - // update contribution status and - // clean cancel info (if any) if prev. contribution was updated in case of 'Refunded' => 'Completed' - $contributionDAO->contribution_status_id = $completedStatusId; - $contributionDAO->cancel_date = 'null'; - $contributionDAO->cancel_reason = NULL; - $netAmount = !empty($trxnsData['net_amount']) ? NULL : $trxnsData['total_amount']; - $contributionDAO->net_amount = $query->net_amount_total + $netAmount; - $contributionDAO->fee_amount = $contributionDAO->total_amount - $contributionDAO->net_amount; - $contributionDAO->save(); - - //Change status of financial record too - $financialTrxn->status_id = $completedStatusId; - $financialTrxn->save(); - - // note : not using the self::add method, - // the reason because it performs 'status change' related code execution for financial records - // which in 'Partial Paid' => 'Completed' is not useful, instead specific financial record updates - // are coded below i.e. just updating financial_item status to 'Paid' - - if ($participantId) { - // update participant status - $participantStatuses = CRM_Event_PseudoConstant::participantStatus(); - $ids = CRM_Event_BAO_Participant::getParticipantIds($contributionId); - foreach ($ids as $val) { - $participantUpdate['id'] = $val; - $participantUpdate['status_id'] = array_search('Registered', $participantStatuses); - CRM_Event_BAO_Participant::add($participantUpdate); - } - } - - self::updateMembershipBasedOnCompletionOfContribution( - $contributionDAO, - $contributionId, - $trxnsData['trxn_date'] - ); - - // update financial item statuses - $baseTrxnId = CRM_Core_BAO_FinancialTrxn::getFinancialTrxnId($contributionId); - $sqlFinancialItemUpdate = " -UPDATE civicrm_financial_item fi - LEFT JOIN civicrm_entity_financial_trxn eft - ON (eft.entity_id = fi.id AND eft.entity_table = 'civicrm_financial_item') -SET status_id = {$paidStatus} -WHERE eft.financial_trxn_id IN ({$trxnId}, {$baseTrxnId['financialTrxnId']}) -"; - CRM_Core_DAO::executeQuery($sqlFinancialItemUpdate); - } + $financialTrxn = CRM_Financial_BAO_Payment::recordPayment($contributionId, $trxnsData, $participantId); } elseif ($paymentType == 'refund') { - $trxnsData['total_amount'] = $trxnsData['net_amount'] = -$trxnsData['total_amount']; - $trxnsData['from_financial_account_id'] = $arAccountId; - $trxnsData['status_id'] = CRM_Core_PseudoConstant::getKey('CRM_Contribute_BAO_Contribution', 'contribution_status_id', 'Refunded'); - // record the entry - $financialTrxn = CRM_Contribute_BAO_Contribution::recordFinancialAccounts($params, $trxnsData); - - // note : not using the self::add method, - // the reason because it performs 'status change' related code execution for financial records - // which in 'Pending Refund' => 'Completed' is not useful, instead specific financial record updates - // are coded below i.e. just updating financial_item status to 'Paid' - if ($updateStatus) { - CRM_Core_DAO::setFieldValue('CRM_Contribute_BAO_Contribution', $contributionId, 'contribution_status_id', $completedStatusId); - } - // add financial item entry - $lineItems = CRM_Price_BAO_LineItem::getLineItemsByContributionID($contributionDAO->id); - if (!empty($lineItems)) { - foreach ($lineItems as $lineItemId => $lineItemValue) { - // don't record financial item for cancelled line-item - if ($lineItemValue['qty'] == 0) { - continue; - } - $paid = $lineItemValue['line_total'] * ($financialTrxn->total_amount / $contributionDAO->total_amount); - $addFinancialEntry = array( - 'transaction_date' => $financialTrxn->trxn_date, - 'contact_id' => $contributionDAO->contact_id, - 'amount' => round($paid, 2), - 'currency' => $contributionDAO->currency, - 'status_id' => $paidStatus, - 'entity_id' => $lineItemId, - 'entity_table' => 'civicrm_line_item', - ); - $trxnIds['id'] = $financialTrxn->id; - CRM_Financial_BAO_FinancialItem::create($addFinancialEntry, NULL, $trxnIds); - } - } + $financialTrxn = CRM_Financial_BAO_Payment::recordRefundPayment($contributionId, $trxnsData, $updateStatus); if ($participantId) { // update participant status + // @todo this doesn't make sense... $participantStatuses = CRM_Event_PseudoConstant::participantStatus(); $ids = CRM_Event_BAO_Participant::getParticipantIds($contributionId); foreach ($ids as $val) { @@ -3923,23 +3897,8 @@ WHERE eft.financial_trxn_id IN ({$trxnId}, {$baseTrxnId['financialTrxnId']}) } } - // activity creation if (!empty($financialTrxn)) { - if ($participantId) { - $inputParams['id'] = $participantId; - $values = array(); - $ids = array(); - $component = 'event'; - $entityObj = CRM_Event_BAO_Participant::getValues($inputParams, $values, $ids); - $entityObj = $entityObj[$participantId]; - } - else { - $entityObj = $contributionDAO; - $component = 'contribution'; - } - $activityType = ($paymentType == 'refund') ? 'Refund' : 'Payment'; - - self::addActivityForPayment($entityObj, $financialTrxn, $activityType, $component, $contributionId); + self::recordPaymentActivity($contributionId, $participantId, $financialTrxn); return $financialTrxn; } @@ -4000,10 +3959,9 @@ WHERE eft.financial_trxn_id IN ({$trxnId}, {$baseTrxnId['financialTrxnId']}) * * @return mixed */ - public static function getPaymentInfo($id, $component, $getTrxnInfo = FALSE, $usingLineTotal = FALSE) { + public static function getPaymentInfo($id, $component = 'contribution', $getTrxnInfo = FALSE, $usingLineTotal = FALSE) { + // @todo deprecate passing in component - always call with contribution. if ($component == 'event') { - $entity = 'participant'; - $entityTable = 'civicrm_participant'; $contributionId = CRM_Core_DAO::getFieldValue('CRM_Event_BAO_ParticipantPayment', $id, 'contribution_id', 'participant_id'); if (!$contributionId) { @@ -4017,14 +3975,10 @@ WHERE eft.financial_trxn_id IN ({$trxnId}, {$baseTrxnId['financialTrxnId']}) } } elseif ($component == 'membership') { - $entity = $component; - $entityTable = 'civicrm_membership'; $contributionId = CRM_Core_DAO::getFieldValue('CRM_Member_DAO_MembershipPayment', $id, 'contribution_id', 'membership_id'); } else { $contributionId = $id; - $entity = 'contribution'; - $entityTable = 'civicrm_contribution'; } $total = CRM_Core_BAO_FinancialTrxn::getBalanceTrxnAmt($contributionId); @@ -4041,7 +3995,8 @@ WHERE eft.financial_trxn_id IN ({$trxnId}, {$baseTrxnId['financialTrxnId']}) $total = $total['total_amount']; } - $paymentBalance = CRM_Core_BAO_FinancialTrxn::getPartialPaymentWithType($id, $entity, FALSE, $total); + $paymentBalance = CRM_Contribute_BAO_Contribution::getContributionBalance($contributionId, $total); + $contribution = civicrm_api3('Contribution', 'getsingle', array('id' => $contributionId, 'return' => array('currency', 'is_pay_later', 'contribution_status_id', 'financial_type_id'))); $info['payLater'] = $contribution['is_pay_later']; @@ -4156,27 +4111,15 @@ WHERE eft.financial_trxn_id IN ({$trxnId}, {$baseTrxnId['financialTrxnId']}) * @return float */ public static function getContributionBalance($contributionId, $contributionTotal = NULL) { - if ($contributionTotal === NULL) { $contributionTotal = CRM_Price_BAO_LineItem::getLineTotal($contributionId); } - $statusId = CRM_Core_PseudoConstant::getKey('CRM_Contribute_BAO_Contribution', 'contribution_status_id', 'Completed'); - $refundStatusId = CRM_Core_PseudoConstant::getKey('CRM_Contribute_BAO_Contribution', 'contribution_status_id', 'Refunded'); - $sqlFtTotalAmt = " -SELECT SUM(ft.total_amount) -FROM civicrm_financial_trxn ft - INNER JOIN civicrm_entity_financial_trxn eft ON (ft.id = eft.financial_trxn_id AND eft.entity_table = 'civicrm_contribution' AND eft.entity_id = {$contributionId}) -WHERE ft.is_payment = 1 - AND ft.status_id IN ({$statusId}, {$refundStatusId}) -"; - - $ftTotalAmt = CRM_Core_DAO::singleValueQuery($sqlFtTotalAmt); - if (!$ftTotalAmt) { - $ftTotalAmt = 0; - } - $currency = CRM_Core_DAO::getFieldValue('CRM_Contribute_DAO_Contribution', $contributionId, 'currency'); - return CRM_Utils_Money::subtractCurrencies($contributionTotal, $ftTotalAmt, $currency); + return CRM_Utils_Money::subtractCurrencies( + $contributionTotal, + CRM_Core_BAO_FinancialTrxn::getTotalPayments($contributionId, TRUE) ?: 0, + CRM_Core_DAO::getFieldValue('CRM_Contribute_DAO_Contribution', $contributionId, 'currency') + ); } /** @@ -4389,6 +4332,8 @@ WHERE ft.is_payment = 1 /** * Compute the stats values * + * @deprecated + * * @param string $stat either 'mode' or 'median' * @param string $sql * @param string $alias of civicrm_contribution @@ -4396,58 +4341,8 @@ WHERE ft.is_payment = 1 * @return array|null */ public static function computeStats($stat, $sql, $alias = NULL) { - $mode = $median = array(); - switch ($stat) { - case 'mode': - $modeDAO = CRM_Core_DAO::executeQuery($sql); - while ($modeDAO->fetch()) { - if ($modeDAO->civicrm_contribution_total_amount_count > 1) { - $mode[] = CRM_Utils_Money::format($modeDAO->amount, $modeDAO->currency); - } - else { - $mode[] = 'N/A'; - } - } - return $mode; - - case 'median': - $currencies = CRM_Core_OptionGroup::values('currencies_enabled'); - foreach ($currencies as $currency => $val) { - $midValue = 0; - $where = "AND {$alias}.currency = '{$currency}'"; - $rowCount = CRM_Core_DAO::singleValueQuery("SELECT count(*) as count {$sql} {$where}"); - - $even = FALSE; - $offset = 1; - $medianRow = floor($rowCount / 2); - if ($rowCount % 2 == 0 && !empty($medianRow)) { - $even = TRUE; - $offset++; - $medianRow--; - } - - $medianValue = "SELECT {$alias}.total_amount as median - {$sql} {$where} - ORDER BY median LIMIT {$medianRow},{$offset}"; - $medianValDAO = CRM_Core_DAO::executeQuery($medianValue); - while ($medianValDAO->fetch()) { - if ($even) { - $midValue = $midValue + $medianValDAO->median; - } - else { - $median[] = CRM_Utils_Money::format($medianValDAO->median, $currency); - } - } - if ($even) { - $midValue = $midValue / 2; - $median[] = CRM_Utils_Money::format($midValue, $currency); - } - } - return $median; - - default: - return NULL; - } + CRM_Core_Error::deprecatedFunctionWarning('computeStats is now deprecated'); + return []; } /** @@ -4819,43 +4714,31 @@ WHERE ft.is_payment = 1 * @return CRM_Financial_DAO_FinancialTrxn */ public static function recordPartialPayment($contribution, $params) { - $contributionStatuses = CRM_Contribute_PseudoConstant::contributionStatus(NULL, 'name'); - $pendingStatus = array( - array_search('Pending', $contributionStatuses), - array_search('In Progress', $contributionStatuses), - ); - $statusId = array_search('Completed', $contributionStatuses); - if (in_array(CRM_Utils_Array::value('contribution_status_id', $contribution), $pendingStatus)) { - $balanceTrxnParams['to_financial_account_id'] = CRM_Contribute_PseudoConstant::getRelationalFinancialAccount($contribution['financial_type_id'], 'Accounts Receivable Account is'); - } - elseif (!empty($params['payment_processor'])) { - $balanceTrxnParams['to_financial_account_id'] = CRM_Contribute_PseudoConstant::getRelationalFinancialAccount($contribution['payment_processor'], NULL, 'civicrm_payment_processor'); - } - elseif (!empty($params['payment_instrument_id'])) { - $balanceTrxnParams['to_financial_account_id'] = CRM_Financial_BAO_FinancialTypeAccount::getInstrumentFinancialAccount($contribution['payment_instrument_id']); - } - else { - $relationTypeId = key(CRM_Core_PseudoConstant::accountOptionValues('financial_account_type', NULL, " AND v.name LIKE 'Asset' ")); - $queryParams = array(1 => array($relationTypeId, 'Integer')); - $balanceTrxnParams['to_financial_account_id'] = CRM_Core_DAO::singleValueQuery("SELECT id FROM civicrm_financial_account WHERE is_default = 1 AND financial_account_type_id = %1", $queryParams); - } + + $balanceTrxnParams['to_financial_account_id'] = self::getToFinancialAccount($contribution, $params); $fromFinancialAccountId = CRM_Contribute_PseudoConstant::getRelationalFinancialAccount($contribution['financial_type_id'], 'Accounts Receivable Account is'); $balanceTrxnParams['from_financial_account_id'] = $fromFinancialAccountId; $balanceTrxnParams['total_amount'] = $params['total_amount']; $balanceTrxnParams['contribution_id'] = $params['contribution_id']; - $balanceTrxnParams['trxn_date'] = !empty($params['contribution_receive_date']) ? $params['contribution_receive_date'] : date('YmdHis'); + $balanceTrxnParams['trxn_date'] = CRM_Utils_Array::value('trxn_date', $params, CRM_Utils_Array::value('contribution_receive_date', $params, date('YmdHis'))); $balanceTrxnParams['fee_amount'] = CRM_Utils_Array::value('fee_amount', $params); $balanceTrxnParams['net_amount'] = CRM_Utils_Array::value('total_amount', $params); $balanceTrxnParams['currency'] = $contribution['currency']; $balanceTrxnParams['trxn_id'] = CRM_Utils_Array::value('contribution_trxn_id', $params, NULL); - $balanceTrxnParams['status_id'] = $statusId; + $balanceTrxnParams['status_id'] = CRM_Core_PseudoConstant::getKey('CRM_Core_BAO_FinancialTrxn', 'status_id', 'Completed'); $balanceTrxnParams['payment_instrument_id'] = CRM_Utils_Array::value('payment_instrument_id', $params, $contribution['payment_instrument_id']); $balanceTrxnParams['check_number'] = CRM_Utils_Array::value('check_number', $params); + + // @todo the logic of this section seems very wrong. This code is ONLY reached from the Payment.create + // routine so is_payment should ALWAYS be true + $contributionStatuses = CRM_Contribute_PseudoConstant::contributionStatus(NULL, 'name'); + $statusId = array_search('Completed', $contributionStatuses); if ($fromFinancialAccountId != NULL && ($statusId == array_search('Completed', $contributionStatuses) || $statusId == array_search('Partially paid', $contributionStatuses)) ) { $balanceTrxnParams['is_payment'] = 1; } + if (!empty($params['payment_processor'])) { $balanceTrxnParams['payment_processor_id'] = $params['payment_processor']; } @@ -5371,96 +5254,90 @@ LEFT JOIN civicrm_contribution on (civicrm_contribution.contact_id = civicrm_co * @throws \CRM_Core_Exception * @throws \CiviCRM_API3_Exception */ - protected static function updateMembershipBasedOnCompletionOfContribution($contribution, $primaryContributionID, $changeDate) { - $contribution->loadRelatedMembershipObjects(); - if (empty($contribution->_relatedObjects['membership'])) { - return; - } - $memberships = $contribution->_relatedObjects['membership']; - foreach ($memberships as $membershipTypeIdKey => $membership) { - if ($membership) { - $membershipParams = array( - 'id' => $membership->id, - 'contact_id' => $membership->contact_id, - 'is_test' => $membership->is_test, - 'membership_type_id' => $membership->membership_type_id, - 'membership_activity_status' => 'Completed', - ); + public static function updateMembershipBasedOnCompletionOfContribution($contribution, $primaryContributionID, $changeDate) { + $memberships = self::getRelatedMemberships($contribution->id); + foreach ($memberships as $membership) { + $membershipParams = array( + 'id' => $membership['id'], + 'contact_id' => $membership['contact_id'], + 'is_test' => $membership['is_test'], + 'membership_type_id' => $membership['membership_type_id'], + 'membership_activity_status' => 'Completed', + ); - $currentMembership = CRM_Member_BAO_Membership::getContactMembership($membershipParams['contact_id'], - $membershipParams['membership_type_id'], - $membershipParams['is_test'], - $membershipParams['id'] - ); + $currentMembership = CRM_Member_BAO_Membership::getContactMembership($membershipParams['contact_id'], + $membershipParams['membership_type_id'], + $membershipParams['is_test'], + $membershipParams['id'] + ); - // CRM-8141 update the membership type with the value recorded in log when membership created/renewed - // this picks up membership type changes during renewals - // @todo this is almost certainly an obsolete sql call, the pre-change - // membership is accessible via $this->_relatedObjects - $sql = " + // CRM-8141 update the membership type with the value recorded in log when membership created/renewed + // this picks up membership type changes during renewals + // @todo this is almost certainly an obsolete sql call, the pre-change + // membership is accessible via $this->_relatedObjects + $sql = " SELECT membership_type_id FROM civicrm_membership_log WHERE membership_id={$membershipParams['id']} ORDER BY id DESC LIMIT 1;"; - $dao = CRM_Core_DAO::executeQuery($sql); - if ($dao->fetch()) { - if (!empty($dao->membership_type_id)) { - $membershipParams['membership_type_id'] = $dao->membership_type_id; - } - } - $dao->free(); - - $membershipParams['num_terms'] = $contribution->getNumTermsByContributionAndMembershipType( - $membershipParams['membership_type_id'], - $primaryContributionID - ); - // @todo remove all this stuff in favour of letting the api call further down handle in - // (it is a duplication of what the api does). - $dates = array_fill_keys(array( - 'join_date', - 'start_date', - 'end_date', - ), NULL); - if ($currentMembership) { - /* - * Fixed FOR CRM-4433 - * In BAO/Membership.php(renewMembership function), we skip the extend membership date and status - * when Contribution mode is notify and membership is for renewal ) - */ - CRM_Member_BAO_Membership::fixMembershipStatusBeforeRenew($currentMembership, $changeDate); - - // @todo - we should pass membership_type_id instead of null here but not - // adding as not sure of testing - $dates = CRM_Member_BAO_MembershipType::getRenewalDatesForMembershipType($membershipParams['id'], - $changeDate, NULL, $membershipParams['num_terms'] - ); - $dates['join_date'] = $currentMembership['join_date']; + $dao = CRM_Core_DAO::executeQuery($sql); + if ($dao->fetch()) { + if (!empty($dao->membership_type_id)) { + $membershipParams['membership_type_id'] = $dao->membership_type_id; } + } + $dao->free(); - //get the status for membership. - $calcStatus = CRM_Member_BAO_MembershipStatus::getMembershipStatusByDate($dates['start_date'], - $dates['end_date'], - $dates['join_date'], - 'today', - TRUE, - $membershipParams['membership_type_id'], - $membershipParams + $membershipParams['num_terms'] = $contribution->getNumTermsByContributionAndMembershipType( + $membershipParams['membership_type_id'], + $primaryContributionID + ); + // @todo remove all this stuff in favour of letting the api call further down handle in + // (it is a duplication of what the api does). + $dates = array_fill_keys(array( + 'join_date', + 'start_date', + 'end_date', + ), NULL); + if ($currentMembership) { + /* + * Fixed FOR CRM-4433 + * In BAO/Membership.php(renewMembership function), we skip the extend membership date and status + * when Contribution mode is notify and membership is for renewal ) + */ + CRM_Member_BAO_Membership::fixMembershipStatusBeforeRenew($currentMembership, $changeDate); + + // @todo - we should pass membership_type_id instead of null here but not + // adding as not sure of testing + $dates = CRM_Member_BAO_MembershipType::getRenewalDatesForMembershipType($membershipParams['id'], + $changeDate, NULL, $membershipParams['num_terms'] ); + $dates['join_date'] = $currentMembership['join_date']; + } - unset($dates['end_date']); - $membershipParams['status_id'] = CRM_Utils_Array::value('id', $calcStatus, 'New'); - //we might be renewing membership, - //so make status override false. - $membershipParams['is_override'] = FALSE; - $membershipParams['status_override_end_date'] = 'null'; + //get the status for membership. + $calcStatus = CRM_Member_BAO_MembershipStatus::getMembershipStatusByDate($dates['start_date'], + $dates['end_date'], + $dates['join_date'], + 'today', + TRUE, + $membershipParams['membership_type_id'], + $membershipParams + ); - //CRM-17723 - reset static $relatedContactIds array() - // @todo move it to Civi Statics. - $var = TRUE; - CRM_Member_BAO_Membership::createRelatedMemberships($var, $var, TRUE); - civicrm_api3('Membership', 'create', $membershipParams); - } + unset($dates['end_date']); + $membershipParams['status_id'] = CRM_Utils_Array::value('id', $calcStatus, 'New'); + //we might be renewing membership, + //so make status override false. + $membershipParams['is_override'] = FALSE; + $membershipParams['status_override_end_date'] = 'null'; + + //CRM-17723 - reset static $relatedContactIds array() + // @todo move it to Civi Statics. + $var = TRUE; + CRM_Member_BAO_Membership::createRelatedMemberships($var, $var, TRUE); + civicrm_api3('Membership', 'create', $membershipParams); } } diff --git a/civicrm/CRM/Contribute/BAO/ContributionRecur.php b/civicrm/CRM/Contribute/BAO/ContributionRecur.php index 510849b0b9..126cf8f67d 100644 --- a/civicrm/CRM/Contribute/BAO/ContributionRecur.php +++ b/civicrm/CRM/Contribute/BAO/ContributionRecur.php @@ -173,14 +173,7 @@ class CRM_Contribute_BAO_ContributionRecur extends CRM_Contribute_DAO_Contributi * @return array|null */ public static function getPaymentProcessor($id, $mode = NULL) { - $sql = " -SELECT r.payment_processor_id - FROM civicrm_contribution_recur r - WHERE r.id = %1"; - $params = array(1 => array($id, 'Integer')); - $paymentProcessorID = CRM_Core_DAO::singleValueQuery($sql, - $params - ); + $paymentProcessorID = self::getPaymentProcessorID($id); if (!$paymentProcessorID) { return NULL; } @@ -188,6 +181,23 @@ SELECT r.payment_processor_id return CRM_Financial_BAO_PaymentProcessor::getPayment($paymentProcessorID, $mode); } + /** + * Get the payment processor for the given recurring contribution. + * + * @param int $recurID + * + * @return int + * Payment processor id. If none found return 0 which represents the + * pseudo processor used for pay-later. + */ + public static function getPaymentProcessorID($recurID) { + $recur = civicrm_api3('ContributionRecur', 'getsingle', [ + 'id' => $recurID, + 'return' => ['payment_processor_id'] + ]); + return (int) CRM_Utils_Array::value('payment_processor_id', $recur, 0); + } + /** * Get the number of installment done/completed for each recurring contribution. * @@ -954,7 +964,7 @@ INNER JOIN civicrm_contribution con ON ( con.id = mp.contribution_id ) /** * Returns array with statuses that are considered to make a recurring - * contribution inacteve. + * contribution inactive. * * @return array */ diff --git a/civicrm/CRM/Contribute/BAO/Query.php b/civicrm/CRM/Contribute/BAO/Query.php index 0ce9b35864..4be21cd7b7 100644 --- a/civicrm/CRM/Contribute/BAO/Query.php +++ b/civicrm/CRM/Contribute/BAO/Query.php @@ -48,7 +48,8 @@ class CRM_Contribute_BAO_Query extends CRM_Core_BAO_Query { */ public static function getFields($checkPermission = TRUE) { if (!isset(\Civi::$statics[__CLASS__]) || !isset(\Civi::$statics[__CLASS__]['fields']) || !isset(\Civi::$statics[__CLASS__]['contribution'])) { - $fields = CRM_Contribute_BAO_Contribution::exportableFields($checkPermission); + $fields = CRM_Contribute_BAO_Contribution::exportableFields($checkPermission); + CRM_Contribute_BAO_Contribution::appendPseudoConstantsToFields($fields); unset($fields['contribution_contact_id']); \Civi::$statics[__CLASS__]['fields']['contribution'] = $fields; } @@ -68,14 +69,6 @@ class CRM_Contribute_BAO_Query extends CRM_Core_BAO_Query { $query->_tables['civicrm_contribution'] = $query->_whereTables['civicrm_contribution'] = 1; } - // get financial_type - if (!empty($query->_returnProperties['financial_type'])) { - $query->_select['financial_type'] = "civicrm_financial_type.name as financial_type"; - $query->_element['financial_type'] = 1; - $query->_tables['civicrm_contribution'] = 1; - $query->_tables['civicrm_financial_type'] = 1; - } - // get accounting code if (!empty($query->_returnProperties['accounting_code'])) { $query->_select['accounting_code'] = "civicrm_financial_account.accounting_code as accounting_code"; @@ -155,8 +148,6 @@ class CRM_Contribute_BAO_Query extends CRM_Core_BAO_Query { $quoteValue = "\"$value\""; } - $strtolower = function_exists('mb_strtolower') ? 'mb_strtolower' : 'strtolower'; - $recurrringFields = CRM_Contribute_BAO_ContributionRecur::getRecurringFields(); unset($recurrringFields['contribution_recur_payment_made']); foreach ($recurrringFields as $dateField => $dateFieldTitle) { @@ -174,8 +165,12 @@ class CRM_Contribute_BAO_Query extends CRM_Core_BAO_Query { 'contribution_payment_instrument' => 'contribution_payment_instrument_id', 'contribution_status' => 'contribution_status_id', ); + $name = isset($fieldAliases[$name]) ? $fieldAliases[$name] : $name; $qillName = $name; + if (in_array($name, $fieldAliases)) { + $qillName = array_search($name, $fieldAliases); + } $pseudoExtraParam = array(); switch ($name) { @@ -239,9 +234,6 @@ class CRM_Contribute_BAO_Query extends CRM_Core_BAO_Query { return; case 'financial_type_id': - // @todo we need to make this resemble a hook approach. - CRM_Financial_BAO_FinancialType::getAvailableFinancialTypes($financialTypes); - $query->_where[$grouping][] = CRM_Contact_BAO_Query::buildClause("civicrm_contribution.$name", 'IN', array_keys($financialTypes), 'String'); case 'invoice_id': case 'invoice_number': case 'payment_instrument_id': @@ -281,7 +273,9 @@ class CRM_Contribute_BAO_Query extends CRM_Core_BAO_Query { $query->_where[$grouping][] = CRM_Contact_BAO_Query::buildClause("civicrm_contribution.$name", $op, $value, $dataType); list($op, $value) = CRM_Contact_BAO_Query::buildQillForFieldValue('CRM_Contribute_DAO_Contribution', $name, $value, $op, $pseudoExtraParam); - $query->_qill[$grouping][] = ts('%1 %2 %3', array(1 => $fields[$qillName]['title'], 2 => $op, 3 => $value)); + if (!($name == 'id' && $value == 0)) { + $query->_qill[$grouping][] = ts('%1 %2 %3', array(1 => $fields[$qillName]['title'], 2 => $op, 3 => $value)); + } $query->_tables['civicrm_contribution'] = $query->_whereTables['civicrm_contribution'] = 1; return; @@ -418,14 +412,12 @@ class CRM_Contribute_BAO_Query extends CRM_Core_BAO_Query { return; case 'contribution_note': - $value = $strtolower(CRM_Core_DAO::escapeString($value)); + $value = CRM_Core_DAO::escapeString($value); if ($wildcard) { $value = "%$value%"; $op = 'LIKE'; } - // LOWER roughly translates to 'hurt my database without deriving any benefit' See CRM-19811. - $wc = ($op != 'LIKE') ? "LOWER(civicrm_note.note)" : "civicrm_note.note"; - $query->_where[$grouping][] = CRM_Contact_BAO_Query::buildClause($wc, $op, $value, "String"); + $query->_where[$grouping][] = CRM_Contact_BAO_Query::buildClause('civicrm_note.note', $op, $value, "String"); $query->_qill[$grouping][] = ts('Contribution Note %1 %2', array(1 => $op, 2 => $quoteValue)); $query->_tables['civicrm_contribution'] = $query->_whereTables['civicrm_contribution'] = $query->_whereTables['contribution_note'] = 1; return; @@ -777,16 +769,14 @@ class CRM_Contribute_BAO_Query extends CRM_Core_BAO_Query { 'contribution_status_id' => 1, // @todo return this & fix query to do pseudoconstant thing. 'contribution_status' => 1, - // @todo the product field got added because it suited someone's use case. - // ideally we would have some configurability here because I think 90% of sites would - // disagree this is the right field to show - but they wouldn't agree with each other - // on what field to show instead. - 'contribution_product_id' => 1, - 'product_name' => 1, 'currency' => 1, 'cancel_date' => 1, 'contribution_recur_id' => 1, ); + if (self::isSiteHasProducts()) { + $properties['product_name'] = 1; + $properties['contribution_product_id'] = 1; + } if (self::isSoftCreditOptionEnabled($queryParams)) { $properties = array_merge($properties, self::softCreditReturnProperties()); } @@ -794,6 +784,18 @@ class CRM_Contribute_BAO_Query extends CRM_Core_BAO_Query { return $properties; } + /** + * Do any products exist in this site's database. + * + * @return bool + */ + public static function isSiteHasProducts() { + if (!isset(\Civi::$statics[__CLASS__]['has_products'])) { + \Civi::$statics[__CLASS__]['has_products'] = (bool) CRM_Core_DAO::singleValueQuery('SELECT id FROM civicrm_contribution_product LIMIT 1'); + } + return \Civi::$statics[__CLASS__]['has_products']; + } + /** * Function you should avoid. * @@ -858,17 +860,11 @@ class CRM_Contribute_BAO_Query extends CRM_Core_BAO_Query { //every 'receipt_date' => 1, // query - 'product_name' => 1, //whether - 'sku' => 1, // or - 'product_option' => 1, // not - 'fulfilled_date' => 1, // the - 'contribution_start_date' => 1, // field - 'contribution_end_date' => 1, // is 'is_test' => 1, // actually @@ -890,9 +886,17 @@ class CRM_Contribute_BAO_Query extends CRM_Core_BAO_Query { // on 'contribution_campaign_id' => 1, // calling - 'contribution_product_id' => 1, //function ); + if (self::isSiteHasProducts()) { + $properties['fulfilled_date'] = 1; + $properties['product_name'] = 1; + $properties['contribution_product_id'] = 1; + $properties['product_option'] = 1; + $properties['sku'] = 1; + $properties['contribution_start_date'] = 1; + $properties['contribution_end_date'] = 1; + } if (self::isSoftCreditOptionEnabled()) { $properties = array_merge($properties, self::softCreditReturnProperties()); } @@ -1018,12 +1022,18 @@ class CRM_Contribute_BAO_Query extends CRM_Core_BAO_Query { 'autocomplete' => 'off', )); - // CRM-16713 - contribution search by premiums on 'Find Contribution' form. - $form->add('select', 'contribution_product_id', - ts('Premium'), - CRM_Contribute_PseudoConstant::products(), - FALSE, array('class' => 'crm-select2', 'multiple' => 'multiple', 'placeholder' => ts('- any -')) - ); + if (CRM_Contribute_BAO_Query::isSiteHasProducts()) { + // CRM-16713 - contribution search by premiums on 'Find Contribution' form. + $form->add('select', 'contribution_product_id', + ts('Premium'), + CRM_Contribute_PseudoConstant::products(), + FALSE, [ + 'class' => 'crm-select2', + 'multiple' => 'multiple', + 'placeholder' => ts('- any -') + ] + ); + } self::addCustomFormFields($form, array('Contribution')); diff --git a/civicrm/CRM/Contribute/DAO/ContributionRecur.php b/civicrm/CRM/Contribute/DAO/ContributionRecur.php index e2011b92e1..c87f48afa0 100644 --- a/civicrm/CRM/Contribute/DAO/ContributionRecur.php +++ b/civicrm/CRM/Contribute/DAO/ContributionRecur.php @@ -6,7 +6,7 @@ * * Generated from xml/schema/CRM/Contribute/ContributionRecur.xml * DO NOT EDIT. Generated by CRM_Core_CodeGen - * (GenCodeChecksum:d3bbedd50918aaf27f7177cceb6593b4) + * (GenCodeChecksum:e69f645ae471e887f56e95ee10a8678d) */ /** @@ -36,7 +36,7 @@ class CRM_Contribute_DAO_ContributionRecur extends CRM_Core_DAO { public $id; /** - * Foreign key to civicrm_contact.id . + * Foreign key to civicrm_contact.id. * * @var int unsigned */ @@ -269,14 +269,17 @@ class CRM_Contribute_DAO_ContributionRecur extends CRM_Core_DAO { 'contact_id' => [ 'name' => 'contact_id', 'type' => CRM_Utils_Type::T_INT, - 'title' => ts('Contact ID'), - 'description' => ts('Foreign key to civicrm_contact.id .'), + 'title' => ts('Contact'), + 'description' => ts('Foreign key to civicrm_contact.id.'), 'required' => TRUE, 'table_name' => 'civicrm_contribution_recur', 'entity' => 'ContributionRecur', 'bao' => 'CRM_Contribute_BAO_ContributionRecur', 'localizable' => 0, 'FKClassName' => 'CRM_Contact_DAO_Contact', + 'html' => [ + 'type' => 'EntityRef', + ], ], 'amount' => [ 'name' => 'amount', @@ -369,7 +372,7 @@ class CRM_Contribute_DAO_ContributionRecur extends CRM_Core_DAO { 'start_date' => [ 'name' => 'start_date', 'type' => CRM_Utils_Type::T_DATE + CRM_Utils_Type::T_TIME, - 'title' => ts('Recurring Contribution Started Date'), + 'title' => ts('Start Date'), 'description' => ts('The date the first scheduled recurring contribution occurs.'), 'required' => TRUE, 'table_name' => 'civicrm_contribution_recur', @@ -378,13 +381,13 @@ class CRM_Contribute_DAO_ContributionRecur extends CRM_Core_DAO { 'localizable' => 0, 'html' => [ 'type' => 'Select Date', - 'formatType' => 'activityDate', + 'formatType' => 'activityDateTime', ], ], 'create_date' => [ 'name' => 'create_date', 'type' => CRM_Utils_Type::T_DATE + CRM_Utils_Type::T_TIME, - 'title' => ts('Recurring Contribution Created Date'), + 'title' => ts('Created Date'), 'description' => ts('When this recurring contribution record was created.'), 'required' => TRUE, 'table_name' => 'civicrm_contribution_recur', @@ -393,13 +396,13 @@ class CRM_Contribute_DAO_ContributionRecur extends CRM_Core_DAO { 'localizable' => 0, 'html' => [ 'type' => 'Select Date', - 'formatType' => 'activityDate', + 'formatType' => 'activityDateTime', ], ], 'modified_date' => [ 'name' => 'modified_date', 'type' => CRM_Utils_Type::T_DATE + CRM_Utils_Type::T_TIME, - 'title' => ts('Recurring Contribution Modified Date'), + 'title' => ts('Modified Date'), 'description' => ts('Last updated date for this record. mostly the last time a payment was received'), 'table_name' => 'civicrm_contribution_recur', 'entity' => 'ContributionRecur', @@ -407,13 +410,13 @@ class CRM_Contribute_DAO_ContributionRecur extends CRM_Core_DAO { 'localizable' => 0, 'html' => [ 'type' => 'Select Date', - 'formatType' => 'activityDate', + 'formatType' => 'activityDateTime', ], ], 'cancel_date' => [ 'name' => 'cancel_date', 'type' => CRM_Utils_Type::T_DATE + CRM_Utils_Type::T_TIME, - 'title' => ts('Recurring Contribution Cancel Date'), + 'title' => ts('Cancel Date'), 'description' => ts('Date this recurring contribution was cancelled by contributor- if we can get access to it'), 'table_name' => 'civicrm_contribution_recur', 'entity' => 'ContributionRecur', @@ -449,6 +452,9 @@ class CRM_Contribute_DAO_ContributionRecur extends CRM_Core_DAO { 'entity' => 'ContributionRecur', 'bao' => 'CRM_Contribute_BAO_ContributionRecur', 'localizable' => 0, + 'html' => [ + 'type' => 'Text', + ], ], 'payment_token_id' => [ 'name' => 'payment_token_id', @@ -472,6 +478,9 @@ class CRM_Contribute_DAO_ContributionRecur extends CRM_Core_DAO { 'entity' => 'ContributionRecur', 'bao' => 'CRM_Contribute_BAO_ContributionRecur', 'localizable' => 0, + 'html' => [ + 'type' => 'Text', + ], ], 'invoice_id' => [ 'name' => 'invoice_id', @@ -484,11 +493,14 @@ class CRM_Contribute_DAO_ContributionRecur extends CRM_Core_DAO { 'entity' => 'ContributionRecur', 'bao' => 'CRM_Contribute_BAO_ContributionRecur', 'localizable' => 0, + 'html' => [ + 'type' => 'Text', + ], ], 'contribution_status_id' => [ 'name' => 'contribution_status_id', 'type' => CRM_Utils_Type::T_INT, - 'title' => ts('Recurring Contribution Status'), + 'title' => ts('Status'), 'import' => TRUE, 'where' => 'civicrm_contribution_recur.contribution_status_id', 'headerPattern' => '', @@ -499,6 +511,9 @@ class CRM_Contribute_DAO_ContributionRecur extends CRM_Core_DAO { 'entity' => 'ContributionRecur', 'bao' => 'CRM_Contribute_BAO_ContributionRecur', 'localizable' => 0, + 'html' => [ + 'type' => 'Select', + ], 'pseudoconstant' => [ 'optionGroupName' => 'contribution_status', 'optionEditPath' => 'civicrm/admin/options/contribution_status', @@ -525,7 +540,7 @@ class CRM_Contribute_DAO_ContributionRecur extends CRM_Core_DAO { 'cycle_day' => [ 'name' => 'cycle_day', 'type' => CRM_Utils_Type::T_INT, - 'title' => ts('Number of Cycle Day'), + 'title' => ts('Cycle Day'), 'description' => ts('Day in the period when the payment should be charged e.g. 1st of month, 15th etc.'), 'required' => TRUE, 'default' => '1', @@ -604,6 +619,14 @@ class CRM_Contribute_DAO_ContributionRecur extends CRM_Core_DAO { 'bao' => 'CRM_Contribute_BAO_ContributionRecur', 'localizable' => 0, 'FKClassName' => 'CRM_Financial_DAO_PaymentProcessor', + 'html' => [ + 'type' => 'Select', + ], + 'pseudoconstant' => [ + 'table' => 'civicrm_payment_processor', + 'keyColumn' => 'id', + 'labelColumn' => 'name', + ] ], 'financial_type_id' => [ 'name' => 'financial_type_id', @@ -619,6 +642,9 @@ class CRM_Contribute_DAO_ContributionRecur extends CRM_Core_DAO { 'bao' => 'CRM_Contribute_BAO_ContributionRecur', 'localizable' => 0, 'FKClassName' => 'CRM_Financial_DAO_FinancialType', + 'html' => [ + 'type' => 'Select', + ], 'pseudoconstant' => [ 'table' => 'civicrm_financial_type', 'keyColumn' => 'id', @@ -657,6 +683,9 @@ class CRM_Contribute_DAO_ContributionRecur extends CRM_Core_DAO { 'bao' => 'CRM_Contribute_BAO_ContributionRecur', 'localizable' => 0, 'FKClassName' => 'CRM_Campaign_DAO_Campaign', + 'html' => [ + 'type' => 'Select', + ], 'pseudoconstant' => [ 'table' => 'civicrm_campaign', 'keyColumn' => 'id', diff --git a/civicrm/CRM/Contribute/Form/AdditionalPayment.php b/civicrm/CRM/Contribute/Form/AdditionalPayment.php index 16c6ba562b..93cb1e0ee9 100644 --- a/civicrm/CRM/Contribute/Form/AdditionalPayment.php +++ b/civicrm/CRM/Contribute/Form/AdditionalPayment.php @@ -384,11 +384,8 @@ class CRM_Contribute_Form_AdditionalPayment extends CRM_Contribute_Form_Abstract $statusMsg = ts('The payment record has been processed.'); // send email if (!empty($result) && !empty($this->_params['is_email_receipt'])) { - $this->_params['contact_id'] = $this->_contactId; - $this->_params['contribution_id'] = $this->_contributionId; - - $sendReceipt = $this->emailReceipt($this->_params); - if ($sendReceipt) { + $sendResult = civicrm_api3('Payment', 'sendconfirmation', ['id' => $result->id])['values'][$result->id]; + if ($sendResult['is_sent']) { $statusMsg .= ' ' . ts('A receipt has been emailed to the contributor.'); } } @@ -498,88 +495,6 @@ class CRM_Contribute_Form_AdditionalPayment extends CRM_Contribute_Form_Abstract } } - /** - * Function to send email receipt. - * - * @param array $params - * - * @return bool - */ - public function emailReceipt(&$params) { - $templateEngine = CRM_Core_Smarty::singleton(); - // email receipt sending - list($contributorDisplayName, $contributorEmail, $doNotMail) = CRM_Contact_BAO_Contact::getContactDetails($params['contact_id']); - if (!$contributorEmail || $doNotMail) { - return FALSE; - } - $templateEngine->assign('contactDisplayName', $contributorDisplayName); - // send message template - if ($this->_component == 'event') { - - // fetch event information from participant ID using API - $eventId = civicrm_api3('Participant', 'getvalue', array( - 'return' => "event_id", - 'id' => $this->_id, - )); - $event = civicrm_api3('Event', 'getsingle', array('id' => $eventId)); - - $templateEngine->assign('event', $event); - $templateEngine->assign('isShowLocation', $event['is_show_location']); - if (CRM_Utils_Array::value('is_show_location', $event) == 1) { - $locationParams = array( - 'entity_id' => $eventId, - 'entity_table' => 'civicrm_event', - ); - $location = CRM_Core_BAO_Location::getValues($locationParams, TRUE); - $templateEngine->assign('location', $location); - } - } - - // assign payment info here - $paymentConfig['confirm_email_text'] = CRM_Utils_Array::value('confirm_email_text', $params); - $templateEngine->assign('paymentConfig', $paymentConfig); - - $templateEngine->assign('totalAmount', $this->_amtTotal); - - $isRefund = ($this->_paymentType == 'refund') ? TRUE : FALSE; - $templateEngine->assign('isRefund', $isRefund); - if ($isRefund) { - $templateEngine->assign('totalPaid', $this->_amtPaid); - $templateEngine->assign('refundAmount', $params['total_amount']); - } - else { - $balance = $this->_amtTotal - ($this->_amtPaid + $params['total_amount']); - $paymentsComplete = ($balance == 0) ? 1 : 0; - $templateEngine->assign('amountOwed', $balance); - $templateEngine->assign('paymentAmount', $params['total_amount']); - $templateEngine->assign('paymentsComplete', $paymentsComplete); - } - - // assign trxn details - $templateEngine->assign('trxn_id', CRM_Utils_Array::value('trxn_id', $params)); - $templateEngine->assign('receive_date', CRM_Utils_Array::value('trxn_date', $params)); - $templateEngine->assign('paidBy', CRM_Core_PseudoConstant::getLabel( - 'CRM_Contribute_BAO_Contribution', - 'payment_instrument_id', - $params['payment_instrument_id'] - )); - $templateEngine->assign('checkNumber', CRM_Utils_Array::value('check_number', $params)); - - $sendTemplateParams = array( - 'groupName' => 'msg_tpl_workflow_contribution', - 'valueName' => 'payment_or_refund_notification', - 'contactId' => $params['contact_id'], - 'PDFFilename' => ts('notification') . '.pdf', - ); - - $sendTemplateParams['from'] = $params['from_email_address']; - $sendTemplateParams['toName'] = $contributorDisplayName; - $sendTemplateParams['toEmail'] = $contributorEmail; - - list($mailSent) = CRM_Core_BAO_MessageTemplate::sendTemplate($sendTemplateParams); - return $mailSent; - } - /** * Wrapper for unit testing the post process submit function. * diff --git a/civicrm/CRM/Contribute/Form/Contribution/Confirm.php b/civicrm/CRM/Contribute/Form/Contribution/Confirm.php index ba5555f3d1..14b5efbe79 100644 --- a/civicrm/CRM/Contribute/Form/Contribution/Confirm.php +++ b/civicrm/CRM/Contribute/Form/Contribution/Confirm.php @@ -158,7 +158,6 @@ class CRM_Contribute_Form_Contribution_Confirm extends CRM_Contribute_Form_Contr * * @param array $params * @param int $financialTypeID - * @param bool $pending * @param array $paymentProcessorOutcome * @param string $receiptDate * @param int $recurringContributionID @@ -166,7 +165,7 @@ class CRM_Contribute_Form_Contribution_Confirm extends CRM_Contribute_Form_Contr * @return array */ public static function getContributionParams( - $params, $financialTypeID, $pending, + $params, $financialTypeID, $paymentProcessorOutcome, $receiptDate, $recurringContributionID) { $contributionParams = array( 'financial_type_id' => $financialTypeID, @@ -193,22 +192,12 @@ class CRM_Contribute_Form_Contribution_Confirm extends CRM_Contribute_Form_Contr 'receipt_date' => $receiptDate, ); } - if (!$pending && $paymentProcessorOutcome) { - $contributionParams += array( - 'fee_amount' => CRM_Utils_Array::value('fee_amount', $paymentProcessorOutcome), - 'net_amount' => CRM_Utils_Array::value('net_amount', $paymentProcessorOutcome, $params['amount']), - 'trxn_id' => $paymentProcessorOutcome['trxn_id'], - 'receipt_date' => $receiptDate, - // also add financial_trxn details as part of fix for CRM-4724 - 'trxn_result_code' => CRM_Utils_Array::value('trxn_result_code', $paymentProcessorOutcome), - ); - } if ($recurringContributionID) { $contributionParams['contribution_recur_id'] = $recurringContributionID; } - $contributionParams['contribution_status_id'] = $pending ? 2 : 1; + $contributionParams['contribution_status_id'] = CRM_Core_PseudoConstant::getKey('CRM_Contribute_BAO_Contribution', 'contribution_status_id', 'Pending'); if (isset($contributionParams['invoice_id'])) { $contributionParams['id'] = CRM_Core_DAO::getFieldValue( 'CRM_Contribute_DAO_Contribution', @@ -957,7 +946,7 @@ class CRM_Contribute_Form_Contribution_Confirm extends CRM_Contribute_Form_Contr if (isset($params['amount'])) { $contributionParams = array_merge(self::getContributionParams( - $params, $financialType->id, TRUE, + $params, $financialType->id, $result, $receiptDate, $recurringContributionID), $contributionParams ); diff --git a/civicrm/CRM/Contribute/Form/Contribution/ThankYou.php b/civicrm/CRM/Contribute/Form/Contribution/ThankYou.php index 8591f8be32..05efdae226 100644 --- a/civicrm/CRM/Contribute/Form/Contribution/ThankYou.php +++ b/civicrm/CRM/Contribute/Form/Contribution/ThankYou.php @@ -301,6 +301,7 @@ class CRM_Contribute_Form_Contribution_ThankYou extends CRM_Contribute_Form_Cont $contributionStatusID = civicrm_api3('Contribution', 'getvalue', array( 'id' => CRM_Utils_Array::value('contributionID', $params), 'return' => 'contribution_status_id', + 'is_test' => ($this->_mode == 'test') ? 1 : 0, 'invoice_id' => CRM_Utils_Array::value('invoiceID', $params), )); if (CRM_Core_PseudoConstant::getName('CRM_Contribute_BAO_Contribution', 'contribution_status_id', $contributionStatusID) === 'Pending' diff --git a/civicrm/CRM/Contribute/Form/ContributionView.php b/civicrm/CRM/Contribute/Form/ContributionView.php index 5b860d8d94..aee9f0ec37 100644 --- a/civicrm/CRM/Contribute/Form/ContributionView.php +++ b/civicrm/CRM/Contribute/Form/ContributionView.php @@ -256,7 +256,6 @@ class CRM_Contribute_Form_ContributionView extends CRM_Core_Form { * Build the form object. */ public function buildQuickForm() { - $this->addButtons(array( array( 'type' => 'cancel', diff --git a/civicrm/CRM/Contribute/Form/Search.php b/civicrm/CRM/Contribute/Form/Search.php index 9e55c4839a..f00ec96621 100644 --- a/civicrm/CRM/Contribute/Form/Search.php +++ b/civicrm/CRM/Contribute/Form/Search.php @@ -80,8 +80,6 @@ class CRM_Contribute_Form_Search extends CRM_Core_Form_Search { $this->_actionButtonName = $this->getButtonName('next', 'action'); $this->_done = FALSE; - // @todo - is this an error - $this->_defaults is used. - $this->defaults = array(); $this->loadStandardSearchOptionsFromUrl(); diff --git a/civicrm/CRM/Contribute/Form/Task/Invoice.php b/civicrm/CRM/Contribute/Form/Task/Invoice.php index d6e4758d4b..865f91b5a1 100644 --- a/civicrm/CRM/Contribute/Form/Task/Invoice.php +++ b/civicrm/CRM/Contribute/Form/Task/Invoice.php @@ -298,7 +298,13 @@ class CRM_Contribute_Form_Task_Invoice extends CRM_Contribute_Form_Task { $invoiceDate = date("F j, Y"); $dueDate = date('F j, Y', strtotime($contributionReceiveDate . "+" . $prefixValue['due_date'] . "" . $prefixValue['due_date_period'])); - $lineItem = CRM_Price_BAO_LineItem::getLineItemsByContributionID($contribID); + if ($input['component'] == 'contribute') { + $lineItem = CRM_Price_BAO_LineItem::getLineItemsByContributionID($contribID); + } + else { + $eid = $contribution->_relatedObjects['participant']->id; + $lineItem = CRM_Price_BAO_LineItem::getLineItems($eid, 'participant', NULL, TRUE, FALSE, TRUE); + } $resultPayments = civicrm_api3('Payment', 'get', array( 'sequential' => 1, diff --git a/civicrm/CRM/Contribute/Form/Task/PDFLetterCommon.php b/civicrm/CRM/Contribute/Form/Task/PDFLetterCommon.php index f8a9724e25..044d7df56f 100644 --- a/civicrm/CRM/Contribute/Form/Task/PDFLetterCommon.php +++ b/civicrm/CRM/Contribute/Form/Task/PDFLetterCommon.php @@ -39,6 +39,9 @@ class CRM_Contribute_Form_Task_PDFLetterCommon extends CRM_Contact_Form_Task_PDF 'subject' => CRM_Utils_Array::value('subject', $formValues), 'from' => CRM_Utils_Array::value('from_email_address', $formValues), ); + + $emailParams['from'] = CRM_Utils_Mail::formatFromAddress($emailParams['from']); + // We need display_name for emailLetter() so add to returnProperties here $returnProperties['display_name'] = 1; if (stristr($formValues['email_options'], 'pdfemail')) { diff --git a/civicrm/CRM/Contribute/Page/ContributionPage.php b/civicrm/CRM/Contribute/Page/ContributionPage.php index 81a0521cc6..7771184f19 100644 --- a/civicrm/CRM/Contribute/Page/ContributionPage.php +++ b/civicrm/CRM/Contribute/Page/ContributionPage.php @@ -420,8 +420,10 @@ AND cp.page_type = 'contribute' $params = array(); $whereClause = $this->whereClause($params, FALSE); - $this->pagerAToZ($whereClause, $params); - + $config = CRM_Core_Config::singleton(); + if ($config->includeAlphabeticalPager) { + $this->pagerAToZ($whereClause, $params); + } $params = array(); $whereClause = $this->whereClause($params, TRUE); $this->pager($whereClause, $params); diff --git a/civicrm/CRM/Contribute/Page/Tab.php b/civicrm/CRM/Contribute/Page/Tab.php index ed5200a852..2a08ede086 100644 --- a/civicrm/CRM/Contribute/Page/Tab.php +++ b/civicrm/CRM/Contribute/Page/Tab.php @@ -243,9 +243,14 @@ class CRM_Contribute_Page_Tab extends CRM_Core_Page { private function buildRecurringContributionsArray($recurContributions) { $liveRecurringContributionCount = 0; foreach ($recurContributions as $recurId => $recurDetail) { - $action = array_sum(array_keys($this->recurLinks($recurId))); - // no action allowed if it's not active - $recurContributions[$recurId]['is_active'] = (!CRM_Contribute_BAO_Contribution::isContributionStatusNegative($recurDetail['contribution_status_id'])); + // Is recurring contribution active? + $recurContributions[$recurId]['is_active'] = !in_array(CRM_Contribute_PseudoConstant::contributionStatus($recurDetail['contribution_status_id'], 'name'), CRM_Contribute_BAO_ContributionRecur::getInactiveStatuses()); + if ($recurContributions[$recurId]['is_active']) { + $actionMask = array_sum(array_keys(self::recurLinks($recurId))); + } + else { + $actionMask = CRM_Core_Action::mask([CRM_Core_Permission::VIEW]); + } if (empty($recurDetail['is_test'])) { $liveRecurringContributionCount++; @@ -260,20 +265,18 @@ class CRM_Contribute_Page_Tab extends CRM_Core_Page { $recurContributions[$recurId]['contribution_status'] = CRM_Core_PseudoConstant::getLabel('CRM_Contribute_BAO_ContributionRecur', 'contribution_status_id', $recurDetail['contribution_status_id']); } - if ($recurContributions[$recurId]['is_active']) { - $recurContributions[$recurId]['action'] = CRM_Core_Action::formLink(self::recurLinks($recurId), $action, - array( - 'cid' => $this->_contactId, - 'crid' => $recurId, - 'cxt' => 'contribution', - ), - ts('more'), - FALSE, - 'contribution.selector.recurring', - 'Contribution', - $recurId - ); - } + $recurContributions[$recurId]['action'] = CRM_Core_Action::formLink(self::recurLinks($recurId), $actionMask, + array( + 'cid' => $this->_contactId, + 'crid' => $recurId, + 'cxt' => 'contribution', + ), + ts('more'), + FALSE, + 'contribution.selector.recurring', + 'Contribution', + $recurId + ); } return [$recurContributions, $liveRecurringContributionCount]; diff --git a/civicrm/CRM/Contribute/Page/UserDashboard.php b/civicrm/CRM/Contribute/Page/UserDashboard.php index 68af603cf2..1efad9f386 100644 --- a/civicrm/CRM/Contribute/Page/UserDashboard.php +++ b/civicrm/CRM/Contribute/Page/UserDashboard.php @@ -36,20 +36,39 @@ class CRM_Contribute_Page_UserDashboard extends CRM_Contact_Page_View_UserDashBo * called when action is browse. */ public function listContribution() { - $controller = new CRM_Core_Controller_Simple( - 'CRM_Contribute_Form_Search', - ts('Contributions'), - NULL, - FALSE, FALSE, TRUE, FALSE - ); - $controller->setEmbedded(TRUE); - $controller->reset(); - $controller->set('limit', 12); - $controller->set('cid', $this->_contactId); - $controller->set('context', 'user'); - $controller->set('force', 1); - $controller->process(); - $controller->run(); + $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); + + foreach ($rows as $index => $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[0]['contribution_status_name'] = CRM_Core_PseudoConstant::getName('CRM_Contribute_BAO_Contribution', 'contribution_status_id', $row['contribution_status_id']);; + } + + $this->assign('contribute_rows', $rows); + $this->assign('contributionSummary', ['total_amount' => civicrm_api3('Contribution', 'getcount', ['contact_id' => $this->_contactId])]); //add honor block $params = CRM_Contribute_BAO_Contribution::getHonorContacts($this->_contactId); @@ -65,18 +84,14 @@ class CRM_Contribute_Page_UserDashboard extends CRM_Contact_Page_View_UserDashBo $recur->is_test = 0; $recur->find(); - $config = CRM_Core_Config::singleton(); - $recurStatus = CRM_Contribute_PseudoConstant::contributionStatus(); $recurRow = array(); $recurIDs = array(); while ($recur->fetch()) { - $mode = $recur->is_test ? 'test' : 'live'; - $paymentProcessor = CRM_Contribute_BAO_ContributionRecur::getPaymentProcessor($recur->id, - $mode - ); - if (!$paymentProcessor) { + 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; } @@ -110,10 +125,6 @@ class CRM_Contribute_Page_UserDashboard extends CRM_Contact_Page_View_UserDashBo ); $recurIDs[] = $values['id']; - - //reset $paymentObject for checking other paymenet processor - //recurring url - $paymentObject = NULL; } if (is_array($recurIDs) && !empty($recurIDs)) { $getCount = CRM_Contribute_BAO_ContributionRecur::getCount($recurIDs); diff --git a/civicrm/CRM/Contribute/Selector/Search.php b/civicrm/CRM/Contribute/Selector/Search.php index 6bfc54f5ba..e17f043cb7 100644 --- a/civicrm/CRM/Contribute/Selector/Search.php +++ b/civicrm/CRM/Contribute/Selector/Search.php @@ -181,6 +181,7 @@ class CRM_Contribute_Selector_Search extends CRM_Core_Selector_Base implements C $this->_action = $action; $returnProperties = CRM_Contribute_BAO_Query::selectorReturnProperties($this->_queryParams); $this->_includeSoftCredits = CRM_Contribute_BAO_Query::isSoftCreditOptionEnabled($this->_queryParams); + $this->_queryParams[] = ['contribution_id', '!=', 0, 0, 0]; $this->_query = new CRM_Contact_BAO_Query( $this->_queryParams, $returnProperties, @@ -563,14 +564,16 @@ class CRM_Contribute_Selector_Search extends CRM_Core_Selector_Base implements C 'field_name' => 'contribution_status', 'direction' => CRM_Utils_Sort::DONTCARE, ), - array( - 'name' => ts('Premium'), - 'sort' => 'product_name', - 'field_name' => 'product_name', - 'direction' => CRM_Utils_Sort::DONTCARE, - ), ) ); + if (CRM_Contribute_BAO_Query::isSiteHasProducts()) { + self::$_columnHeaders[] = [ + 'name' => ts('Premium'), + 'sort' => 'product_name', + 'field_name' => 'product_name', + 'direction' => CRM_Utils_Sort::DONTCARE, + ]; + } if (!$this->_single) { $pre = array( array( @@ -617,7 +620,7 @@ class CRM_Contribute_Selector_Search extends CRM_Core_Selector_Base implements C * @return mixed */ public function alphabetQuery() { - return $this->_query->searchQuery(NULL, NULL, NULL, FALSE, FALSE, TRUE); + return $this->_query->alphabetQuery(); } /** diff --git a/civicrm/CRM/Core/BAO/Address.php b/civicrm/CRM/Core/BAO/Address.php index 4ada8f0bdf..2ff74bbb37 100644 --- a/civicrm/CRM/Core/BAO/Address.php +++ b/civicrm/CRM/Core/BAO/Address.php @@ -771,6 +771,11 @@ ORDER BY civicrm_address.is_primary DESC, civicrm_address.location_type_id DESC, $streetAddress = trim($streetAddress); } + // If street number is too large, we cannot store it. + if ($parseFields['street_number'] > CRM_Utils_Type::INT_MAX) { + return $emptyParseFields; + } + // suffix might be like 1/2 $matches = array(); if (preg_match('/^\d\/\d/', $streetAddress, $matches)) { diff --git a/civicrm/CRM/Core/BAO/CustomField.php b/civicrm/CRM/Core/BAO/CustomField.php index f110870e63..82038c39e4 100644 --- a/civicrm/CRM/Core/BAO/CustomField.php +++ b/civicrm/CRM/Core/BAO/CustomField.php @@ -1093,7 +1093,7 @@ class CRM_Core_BAO_CustomField extends CRM_Core_DAO_CustomField { else { // FIXME: This won't work with customFieldOptions hook $attributes += array( - 'entity' => 'option_value', + 'entity' => 'OptionValue', 'placeholder' => $placeholder, 'multiple' => $search, 'api' => array( diff --git a/civicrm/CRM/Core/BAO/CustomValueTable.php b/civicrm/CRM/Core/BAO/CustomValueTable.php index 69ea71606e..84417ab6f6 100644 --- a/civicrm/CRM/Core/BAO/CustomValueTable.php +++ b/civicrm/CRM/Core/BAO/CustomValueTable.php @@ -219,7 +219,7 @@ class CRM_Core_BAO_CustomValueTable { default: break; } - if (strtolower($value) === "null") { + if ($value === 'null') { // when unsetting a value to null, we don't need to validate the type // https://projectllr.atlassian.net/browse/VGQBMP-20 $set[$field['column_name']] = $value; diff --git a/civicrm/CRM/Core/BAO/FinancialTrxn.php b/civicrm/CRM/Core/BAO/FinancialTrxn.php index 3eb7aecadc..f6ec9f6c65 100644 --- a/civicrm/CRM/Core/BAO/FinancialTrxn.php +++ b/civicrm/CRM/Core/BAO/FinancialTrxn.php @@ -437,23 +437,27 @@ WHERE ceft.entity_id = %1"; } /** - * get partial payment amount and type of it. + * get partial payment amount. + * + * @deprecated + * + * This function basically calls CRM_Contribute_BAO_Contribution::getContributionBalance + * - just do that. If need be we could have a fn to get the contribution id but + * chances are the calling functions already know it anyway. * * @param int $entityId * @param string $entityName - * @param bool $returnType * @param int $lineItemTotal * - * @return array|int|NULL|string - * [payment type => amount] - * payment type: 'amount_owed' or 'refund_due' + * @return array */ - public static function getPartialPaymentWithType($entityId, $entityName = 'participant', $returnType = TRUE, $lineItemTotal = NULL) { + public static function getPartialPaymentWithType($entityId, $entityName = 'participant', $lineItemTotal = NULL) { $value = NULL; if (empty($entityName)) { return $value; } + // @todo - deprecate passing in entity & type - just figure out contribution id FIRST if ($entityName == 'participant') { $contributionId = CRM_Core_DAO::getFieldValue('CRM_Event_DAO_ParticipantPayment', $entityId, 'contribution_id', 'participant_id'); } @@ -467,60 +471,39 @@ WHERE ceft.entity_id = %1"; if ($contributionId && $financialTypeId) { - $value = CRM_Contribute_BAO_Contribution::getContributionBalance($contributionId, $lineItemTotal); - - $paymentVal = $value; - if ($returnType) { - $value = array(); - if ($paymentVal < 0) { - $value['refund_due'] = $paymentVal; - } - elseif ($paymentVal > 0) { - $value['amount_owed'] = $paymentVal; - } + $paymentVal = CRM_Contribute_BAO_Contribution::getContributionBalance($contributionId, $lineItemTotal); + $value = []; + if ($paymentVal < 0) { + $value['refund_due'] = $paymentVal; + } + elseif ($paymentVal > 0) { + $value['amount_owed'] = $paymentVal; } } return $value; } /** - * @param int $contributionId + * @param int $contributionID + * @param bool $includeRefund * * @return string */ - public static function getTotalPayments($contributionId) { - $statusId = CRM_Core_PseudoConstant::getKey('CRM_Contribute_BAO_Contribution', 'contribution_status_id', 'Completed'); + public static function getTotalPayments($contributionID, $includeRefund = FALSE) { + $statusIDs = [CRM_Core_PseudoConstant::getKey('CRM_Contribute_BAO_Contribution', 'contribution_status_id', 'Completed')]; + + if ($includeRefund) { + $statusIDs[] = CRM_Core_PseudoConstant::getKey('CRM_Contribute_BAO_Contribution', 'contribution_status_id', 'Refunded'); + } $sql = "SELECT SUM(ft.total_amount) FROM civicrm_financial_trxn ft INNER JOIN civicrm_entity_financial_trxn eft ON (eft.financial_trxn_id = ft.id AND eft.entity_table = 'civicrm_contribution') - WHERE eft.entity_id = %1 AND ft.is_payment = 1 AND ft.status_id = %2"; + WHERE eft.entity_id = %1 AND ft.is_payment = 1 AND ft.status_id IN (%2) "; - $params = array( - 1 => array($contributionId, 'Integer'), - 2 => array($statusId, 'Integer'), - ); - - return CRM_Core_DAO::singleValueQuery($sql, $params); - } - - /** - * Function records partial payment, complete's contribution if payment is fully paid - * and returns latest payment ie financial trxn - * - * @param array $contribution - * @param array $params - * - * @return \CRM_Financial_DAO_FinancialTrxn - */ - public static function getPartialPaymentTrxn($contribution, $params) { - $trxn = CRM_Contribute_BAO_Contribution::recordPartialPayment($contribution, $params); - $paid = CRM_Core_BAO_FinancialTrxn::getTotalPayments($params['contribution_id']); - $total = CRM_Core_DAO::getFieldValue('CRM_Contribute_DAO_Contribution', $params['contribution_id'], 'total_amount'); - $cmp = bccomp($total, $paid, 5); - if ($cmp == 0 || $cmp == -1) {// If paid amount is greater or equal to total amount - civicrm_api3('Contribution', 'completetransaction', array('id' => $contribution['id'])); - } - return $trxn; + return CRM_Core_DAO::singleValueQuery($sql, [ + 1 => [$contributionID, 'Integer'], + 2 => [implode(',', $statusIDs), 'CommaSeparatedIntegers'], + ]); } /** diff --git a/civicrm/CRM/Core/BAO/MessageTemplate.php b/civicrm/CRM/Core/BAO/MessageTemplate.php index ff6813e716..d9fa8f2f7c 100644 --- a/civicrm/CRM/Core/BAO/MessageTemplate.php +++ b/civicrm/CRM/Core/BAO/MessageTemplate.php @@ -387,13 +387,13 @@ class CRM_Core_BAO_MessageTemplate extends CRM_Core_DAO_MessageTemplate { ); $params = array_merge($defaults, $params); - CRM_Utils_Hook::alterMailParams($params, 'messageTemplate'); - // Core#644 - handle contact ID passed as "From". if (isset($params['from'])) { $params['from'] = CRM_Utils_Mail::formatFromAddress($params['from']); } + CRM_Utils_Hook::alterMailParams($params, 'messageTemplate'); + if ((!$params['groupName'] || !$params['valueName'] ) && diff --git a/civicrm/CRM/Core/BAO/Navigation.php b/civicrm/CRM/Core/BAO/Navigation.php index 4006a300fe..7e025198b6 100644 --- a/civicrm/CRM/Core/BAO/Navigation.php +++ b/civicrm/CRM/Core/BAO/Navigation.php @@ -299,51 +299,6 @@ FROM civicrm_navigation WHERE domain_id = $domainID"; return $branch; } - /** - * Build menu. - * - * @return string - */ - public static function buildNavigation() { - $navigations = self::buildNavigationTree(); - $navigationString = ''; - - // run the Navigation through a hook so users can modify it - CRM_Utils_Hook::navigationMenu($navigations); - self::fixNavigationMenu($navigations); - - // Hooks have added menu items in an arbitrary order. We need to order by - // weight again. I would put this function directly after - // CRM_Utils_Hook::navigationMenu but for some reason, fixNavigationMenu is - // moving items added by hooks on the end of the menu. Hence I do it - // afterwards - self::orderByWeight($navigations); - - //skip children menu item if user don't have access to parent menu item - $skipMenuItems = array(); - foreach ($navigations as $key => $value) { - // Home is a special case - if ($value['attributes']['name'] != 'Home') { - $name = self::getMenuName($value, $skipMenuItems); - if ($name) { - //separator before - if (isset($value['attributes']['separator']) && $value['attributes']['separator'] == 2) { - $navigationString .= '<li class="menu-separator"></li>'; - } - $removeCharacters = array('/', '!', '&', '*', ' ', '(', ')', '.'); - $navigationString .= '<li class="menumain crm-' . str_replace($removeCharacters, '_', $value['attributes']['label']) . '">' . $name; - } - } - self::recurseNavigation($value, $navigationString, $skipMenuItems); - } - - // clean up - Need to remove empty <ul>'s, this happens when user don't have - // permission to access parent - $navigationString = str_replace('<ul></ul></li>', '', $navigationString); - - return $navigationString; - } - /** * buildNavigationTree retreives items in order. We call this function to * ensure that any items added by the hook are also in the correct order. @@ -560,52 +515,6 @@ FROM civicrm_navigation WHERE domain_id = $domainID"; return TRUE; } - /** - * Create navigation for CiviCRM Admin Menu. - * - * @return string - * returns navigation html - */ - public static function createNavigation() { - $navigation = self::buildNavigation(); - - if ($navigation) { - - //add additional navigation items - $logoutURL = CRM_Utils_System::url('civicrm/logout', 'reset=1'); - - // get home menu from db - $homeParams = array('name' => 'Home'); - $homeNav = array(); - $homeIcon = '<span class="crm-logo-sm" ></span>'; - self::retrieve($homeParams, $homeNav); - if ($homeNav) { - $homeURL = self::makeFullyFormedUrl($homeNav['url']); - $homeLabel = $homeNav['label']; - // CRM-6804 (we need to special-case this as we don’t ts()-tag variables) - if ($homeLabel == 'Home') { - $homeLabel = ts('CiviCRM Home'); - } - } - else { - $homeURL = CRM_Utils_System::url('civicrm/dashboard', 'reset=1'); - $homeLabel = ts('CiviCRM Home'); - } - // Link to hide the menubar - $hideLabel = ts('Hide Menu'); - - $prepandString = " - <li class='menumain crm-link-home'>$homeIcon - <ul id='civicrm-home'> - <li><a href='$homeURL'>$homeLabel</a></li> - <li><a href='#' class='crm-hidemenu'>$hideLabel</a></li> - <li><a href='$logoutURL' class='crm-logout-link'>" . ts('Log out') . "</a></li> - </ul>"; - // <li> tag doesn't need to be closed - } - return $prepandString . $navigation; - } - /** * Turns relative URLs (like civicrm/foo/bar) into fully-formed * ones (i.e. example.com/wp-admin?q=civicrm/dashboard). @@ -1051,4 +960,64 @@ FROM civicrm_navigation WHERE domain_id = $domainID"; return $key; } + /** + * Unset menu items for disabled components and non-permissioned users + * + * @param $menu + */ + public static function filterByPermission(&$menu) { + foreach ($menu as $key => $item) { + if ( + (array_key_exists('active', $item['attributes']) && !$item['attributes']['active']) || + !CRM_Core_BAO_Navigation::checkPermission($item['attributes']) + ) { + unset($menu[$key]); + continue; + } + if (!empty($item['child'])) { + self::filterByPermission($menu[$key]['child']); + } + } + } + + /** + * @param array $menu + */ + public static function buildHomeMenu(&$menu) { + foreach ($menu as &$item) { + if (CRM_Utils_Array::value('name', $item['attributes']) === 'Home') { + unset($item['attributes']['label'], $item['attributes']['url']); + $item['attributes']['icon'] = 'crm-logo-sm'; + $item['attributes']['attr']['accesskey'] = 'm'; + $item['child'] = [ + [ + 'attributes' => [ + 'label' => 'CiviCRM Home', + 'name' => 'CiviCRM Home', + 'url' => 'civicrm/dashboard?reset=1', + 'weight' => 1, + ] + ], + [ + 'attributes' => [ + 'label' => 'Hide Menu', + 'name' => 'Hide Menu', + 'url' => '#hidemenu', + 'weight' => 2, + ] + ], + [ + 'attributes' => [ + 'label' => 'Log out', + 'name' => 'Log out', + 'url' => 'civicrm/logout?reset=1', + 'weight' => 3, + ] + ], + ]; + return; + } + } + } + } diff --git a/civicrm/CRM/Core/BAO/OptionValue.php b/civicrm/CRM/Core/BAO/OptionValue.php index 5cb6a486bf..959b77d5e4 100644 --- a/civicrm/CRM/Core/BAO/OptionValue.php +++ b/civicrm/CRM/Core/BAO/OptionValue.php @@ -244,13 +244,13 @@ class CRM_Core_BAO_OptionValue extends CRM_Core_DAO_OptionValue { $optionValue->save(); CRM_Core_PseudoConstant::flush(); - // Create relationship for payment intrument options + // Create relationship for payment instrument options if (!empty($params['financial_account_id'])) { $optionName = civicrm_api3('OptionGroup', 'getvalue', [ 'return' => 'name', 'id' => $params['option_group_id'], ]); - // Only create relationship for payment intrument options + // Only create relationship for payment instrument options if ($optionName == 'payment_instrument') { $relationTypeId = civicrm_api3('OptionValue', 'getvalue', [ 'return' => 'value', diff --git a/civicrm/CRM/Core/BAO/UFGroup.php b/civicrm/CRM/Core/BAO/UFGroup.php index 952e70aedf..ed8f31cec9 100644 --- a/civicrm/CRM/Core/BAO/UFGroup.php +++ b/civicrm/CRM/Core/BAO/UFGroup.php @@ -993,8 +993,10 @@ class CRM_Core_BAO_UFGroup extends CRM_Core_DAO_UFGroup { $details = $query->searchQuery(0, 0, NULL, FALSE, FALSE, FALSE, FALSE, FALSE, $additionalWhereClause); - if (!$details->fetch()) { - return; + while ($details->fetch()) { + if (!$details) { + return; + } } $query->convertToPseudoNames($details); $config = CRM_Core_Config::singleton(); @@ -3320,57 +3322,6 @@ AND ( entity_id IS NULL OR entity_id <= 0 ) } } - /** - * @param array|string $profiles - name of profile(s) to create links for - * @param array $appendProfiles - * Name of profile(s) to append to each link. - * - * @return array - */ - public static function getCreateLinks($profiles = '', $appendProfiles = array()) { - if (!CRM_Contact_BAO_Contact::entityRefCreateLinks()) { - return []; - } - // Default to contact profiles - if (!$profiles) { - $profiles = array('new_individual', 'new_organization', 'new_household'); - } - $profiles = (array) $profiles; - $toGet = array_merge($profiles, (array) $appendProfiles); - $retrieved = civicrm_api3('uf_group', 'get', array( - 'name' => array('IN' => $toGet), - 'is_active' => 1, - )); - $links = $append = array(); - if (!empty($retrieved['values'])) { - $icons = [ - 'individual' => 'fa-user', - 'organization' => 'fa-building', - 'household' => 'fa-home', - ]; - foreach ($retrieved['values'] as $id => $profile) { - if (in_array($profile['name'], $profiles)) { - $links[] = array( - 'label' => $profile['title'], - 'url' => CRM_Utils_System::url('civicrm/profile/create', "reset=1&context=dialog&gid=$id", - NULL, NULL, FALSE, FALSE, TRUE), - 'type' => ucfirst(str_replace('new_', '', $profile['name'])), - 'icon' => CRM_Utils_Array::value(str_replace('new_', '', $profile['name']), $icons), - ); - } - else { - $append[] = $id; - } - } - foreach ($append as $id) { - foreach ($links as &$link) { - $link['url'] .= ",$id"; - } - } - } - return $links; - } - /** * Retrieve groups of profiles. * diff --git a/civicrm/CRM/Core/BAO/Website.php b/civicrm/CRM/Core/BAO/Website.php index bc82b73da0..29e118b958 100644 --- a/civicrm/CRM/Core/BAO/Website.php +++ b/civicrm/CRM/Core/BAO/Website.php @@ -99,10 +99,15 @@ class CRM_Core_BAO_Website extends CRM_Core_DAO_Website { $ids = self::allWebsites($contactID); foreach ($params as $key => $values) { + $id = CRM_Utils_Array::value('id', $values); + if (array_key_exists($id, $ids)) { + unset($ids[$id]); + } if (empty($values['id']) && is_array($ids) && !empty($ids)) { foreach ($ids as $id => $value) { if (($value['website_type_id'] == $values['website_type_id'])) { $values['id'] = $id; + unset($ids[$id]); } } } diff --git a/civicrm/CRM/Core/DAO.php b/civicrm/CRM/Core/DAO.php index 16a2b31d0c..02b3d3d158 100644 --- a/civicrm/CRM/Core/DAO.php +++ b/civicrm/CRM/Core/DAO.php @@ -2365,19 +2365,47 @@ SELECT contact_id * This is relevant where we want to offer both the ID field and the label field * as an option, e.g. search builder. * - * It is currently limited for optionGroupName for purposes keeping the scope of the + * It is currently limited for optionGroupName & id+ name+ FK combos for purposes keeping the scope of the * change small, but is appropriate for other sorts of pseudoconstants. * * @param array $fields */ - protected static function appendPseudoConstantsToFields(&$fields) { + public static function appendPseudoConstantsToFields(&$fields) { foreach ($fields as $field) { - if (!empty($field['pseudoconstant']) && !empty($field['pseudoconstant']['optionGroupName'])) { - $fields[$field['pseudoconstant']['optionGroupName']] = array( - 'title' => CRM_Core_BAO_OptionGroup::getTitleByName($field['pseudoconstant']['optionGroupName']), - 'name' => $field['pseudoconstant']['optionGroupName'], - 'data_type' => CRM_Utils_Type::T_STRING, - ); + if (!empty($field['pseudoconstant'])) { + $pseudoConstant = $field['pseudoconstant']; + if (!empty($pseudoConstant['optionGroupName'])) { + $fields[$pseudoConstant['optionGroupName']] = [ + 'title' => CRM_Core_BAO_OptionGroup::getTitleByName($pseudoConstant['optionGroupName']), + 'name' => $pseudoConstant['optionGroupName'], + 'data_type' => CRM_Utils_Type::T_STRING, + 'is_pseudofield_for' => $field['name'], + ]; + } + // We restrict to id + name + FK as we are extending this a bit, but cautiously. + elseif ( + !empty($field['FKClassName']) + && CRM_Utils_Array::value('keyColumn', $pseudoConstant) === 'id' + && CRM_Utils_Array::value('labelColumn', $pseudoConstant) === 'name' + ) { + $pseudoFieldName = str_replace('_' . $pseudoConstant['keyColumn'], '', $field['name']); + // This if is just an extra caution when adding change. + if (!isset($fields[$pseudoFieldName])) { + $daoName = $field['FKClassName']; + $fkFields = $daoName::fields(); + foreach ($fkFields as $fkField) { + if ($fkField['name'] === $pseudoConstant['labelColumn']) { + $fields[$pseudoFieldName] = [ + 'name' => $pseudoFieldName, + 'is_pseudofield_for' => $field['name'], + 'title' => $fkField['title'], + 'data_type' => $fkField['type'], + 'where' => $field['where'], + ]; + } + } + } + } } } } @@ -2514,7 +2542,7 @@ SELECT contact_id // ternary operators case 'BETWEEN': case 'NOT BETWEEN': - if (empty($criteria[0]) || empty($criteria[1])) { + if ((empty($criteria[0]) && !in_array($criteria[0], ['0', 0]))|| (empty($criteria[1]) && !in_array($criteria[1], ['0', 0]))) { throw new Exception("invalid criteria for $operator"); } if (!$returnSanitisedArray) { @@ -2813,6 +2841,13 @@ SELECT contact_id } } + /** + * @return array + */ + public static function getEntityRefFilters() { + return []; + } + /** * Get exportable fields with pseudoconstants rendered as an extra field. * diff --git a/civicrm/CRM/Core/DAO/AllCoreTables.php b/civicrm/CRM/Core/DAO/AllCoreTables.php index 4d74ea35d3..03060e11a6 100644 --- a/civicrm/CRM/Core/DAO/AllCoreTables.php +++ b/civicrm/CRM/Core/DAO/AllCoreTables.php @@ -198,7 +198,7 @@ class CRM_Core_DAO_AllCoreTables { * @return bool */ public static function isCoreTable($tableName) { - return FALSE !== array_search($tableName, self::tables()); + return array_key_exists($tableName, self::tables()); } /** diff --git a/civicrm/CRM/Core/Form.php b/civicrm/CRM/Core/Form.php index 7f225f4c6f..a85cbb69dd 100644 --- a/civicrm/CRM/Core/Form.php +++ b/civicrm/CRM/Core/Form.php @@ -641,6 +641,10 @@ class CRM_Core_Form extends HTML_QuickForm_Page { public function addButtons($params) { $prevnext = $spacing = array(); foreach ($params as $button) { + if (!empty($button['submitOnce'])) { + $button['js']['onclick'] = "return submitOnce(this,'{$this->_name}','" . ts('Processing') . "');"; + } + $attrs = array('class' => 'crm-form-submit') + (array) CRM_Utils_Array::value('js', $button); if (!empty($button['class'])) { @@ -1291,11 +1295,13 @@ class CRM_Core_Form extends HTML_QuickForm_Page { * * @param string $fieldName * @param string $label + * @param bool $isDateTime + * Is this a date-time field (not just date). * @param bool $required * @param string $fromLabel * @param string $toLabel */ - public function addDatePickerRange($fieldName, $label, $required = FALSE, $fromLabel = 'From', $toLabel = 'To') { + public function addDatePickerRange($fieldName, $label, $isDateTime = FALSE, $required = FALSE, $fromLabel = 'From', $toLabel = 'To') { $options = array( '' => ts('- any -'), @@ -1310,7 +1316,7 @@ class CRM_Core_Form extends HTML_QuickForm_Page { NULL ); $attributes = ['format' => 'searchDate']; - $extra = ['time' => FALSE]; + $extra = ['time' => $isDateTime]; $this->add('datepicker', $fieldName . '_low', ts($fromLabel), $attributes, $required, $extra); $this->add('datepicker', $fieldName . '_high', ts($toLabel), $attributes, $required, $extra); } @@ -1932,10 +1938,10 @@ class CRM_Core_Form extends HTML_QuickForm_Page { * @param array $props * Mix of html and widget properties, including:. * - select - params to give to select2 widget - * - entity - defaults to contact + * - entity - defaults to Contact * - create - can the user create a new entity on-the-fly? * Set to TRUE if entity is contact and you want the default profiles, - * or pass in your own set of links. @see CRM_Core_BAO_UFGroup::getCreateLinks for format + * or pass in your own set of links. @see CRM_Campaign_BAO_Campaign::getEntityRefCreateLinks for format * note that permissions are checked automatically * - api - array of settings for the getlist api wrapper * note that it accepts a 'params' setting which will be passed to the underlying api @@ -1947,18 +1953,11 @@ class CRM_Core_Form extends HTML_QuickForm_Page { * @return HTML_QuickForm_Element */ public function addEntityRef($name, $label = '', $props = array(), $required = FALSE) { - require_once "api/api.php"; - $config = CRM_Core_Config::singleton(); // Default properties $props['api'] = CRM_Utils_Array::value('api', $props, array()); - $props['entity'] = _civicrm_api_get_entity_name_from_camel(CRM_Utils_Array::value('entity', $props, 'contact')); + $props['entity'] = CRM_Utils_String::convertStringToCamel(CRM_Utils_Array::value('entity', $props, 'Contact')); $props['class'] = ltrim(CRM_Utils_Array::value('class', $props, '') . ' crm-form-entityref'); - if (isset($props['create']) && $props['create'] === TRUE) { - require_once "api/v3/utils.php"; - $baoClass = _civicrm_api3_get_BAO($props['entity']); - $props['create'] = $baoClass && is_callable([$baoClass, 'entityRefCreateLinks']) ? $baoClass::entityRefCreateLinks() : FALSE; - } if (array_key_exists('create', $props) && empty($props['create'])) { unset($props['create']); } diff --git a/civicrm/CRM/Core/Form/EntityFormTrait.php b/civicrm/CRM/Core/Form/EntityFormTrait.php index 6693f88dfa..63e5f781f9 100644 --- a/civicrm/CRM/Core/Form/EntityFormTrait.php +++ b/civicrm/CRM/Core/Form/EntityFormTrait.php @@ -114,6 +114,10 @@ trait CRM_Core_Form_EntityFormTrait { $this->assign('entityTable', CRM_Core_DAO_AllCoreTables::getTableForClass(CRM_Core_DAO_AllCoreTables::getFullName($this->getDefaultEntity()))); $this->addCustomDataToForm(); $this->addFormButtons(); + + if ($this->isViewContext()) { + $this->freeze(); + } } /** @@ -128,7 +132,7 @@ trait CRM_Core_Form_EntityFormTrait { * Add relevant buttons to the form. */ protected function addFormButtons() { - if ($this->_action & CRM_Core_Action::VIEW || $this->_action & CRM_Core_Action::PREVIEW) { + if ($this->isViewContext() || $this->_action & CRM_Core_Action::PREVIEW) { $this->addButtons(array( array( 'type' => 'cancel', @@ -142,7 +146,7 @@ trait CRM_Core_Form_EntityFormTrait { $this->addButtons(array( array( 'type' => 'next', - 'name' => $this->_action & CRM_Core_Action::DELETE ? ts('Delete') : ts('Save'), + 'name' => $this->isDeleteContext() ? ts('Delete') : ts('Save'), 'isDefault' => TRUE, ), array( @@ -158,20 +162,34 @@ trait CRM_Core_Form_EntityFormTrait { * Get the defaults for the entity. */ protected function getEntityDefaults() { - $defaults = []; - if ($this->_action != CRM_Core_Action::DELETE && + $defaults = $moneyFields = []; + + if (!$this->isDeleteContext() && $this->getEntityId() ) { $params = ['id' => $this->getEntityId()]; $baoName = $this->_BAOName; $baoName::retrieve($params, $defaults); } - foreach ($this->entityFields as $fieldSpec) { + foreach ($this->entityFields as $entityFieldName => $fieldSpec) { $value = CRM_Utils_Request::retrieveValue($fieldSpec['name'], $this->getValidationTypeForField($fieldSpec['name'])); if ($value !== FALSE && $value !== NULL) { $defaults[$fieldSpec['name']] = $value; } + // Store a list of fields with money formatters + if (CRM_Utils_Array::value('formatter', $fieldSpec) == 'crmMoney') { + $moneyFields[] = $entityFieldName; + } } + if (!empty($defaults['currency'])) { + // If we have a money formatter we need to pass the specified currency or it will render as the default + foreach ($moneyFields as $entityFieldName) { + $this->entityFields[$entityFieldName]['formatterParam'] = $defaults['currency']; + } + } + + // Assign again as we may have modified above + $this->assign('entityFields', $this->entityFields); return $defaults; } @@ -244,6 +262,15 @@ trait CRM_Core_Form_EntityFormTrait { return ($this->_action & CRM_Core_Action::DELETE); } + /** + * Is the form being used in the context of a view. + * + * @return bool + */ + protected function isViewContext() { + return ($this->_action & CRM_Core_Action::VIEW); + } + protected function setEntityFieldsMetadata() { foreach ($this->entityFields as $field => &$props) { if (!empty($props['not-auto-addable'])) { diff --git a/civicrm/CRM/Core/Form/Renderer.php b/civicrm/CRM/Core/Form/Renderer.php index 8284722026..1eeb9f0b7d 100644 --- a/civicrm/CRM/Core/Form/Renderer.php +++ b/civicrm/CRM/Core/Form/Renderer.php @@ -322,20 +322,20 @@ class CRM_Core_Form_Renderer extends HTML_QuickForm_Renderer_ArraySmarty { * @param HTML_QuickForm_element $field */ public function renderFrozenEntityRef(&$el, $field) { - $entity = strtolower($field->getAttribute('data-api-entity')); + $entity = $field->getAttribute('data-api-entity'); $vals = json_decode($field->getAttribute('data-entity-value'), TRUE); $display = array(); // Custom fields of type contactRef store their data in a slightly different format - if ($field->getAttribute('data-crm-custom') && $entity == 'contact') { + if ($field->getAttribute('data-crm-custom') && $entity == 'Contact') { $vals = array(array('id' => $vals['id'], 'label' => $vals['text'])); } foreach ($vals as $val) { // Format contact as link - if ($entity == 'contact' && CRM_Contact_BAO_Contact_Permission::allow($val['id'], CRM_Core_Permission::VIEW)) { + if ($entity == 'Contact' && CRM_Contact_BAO_Contact_Permission::allow($val['id'], CRM_Core_Permission::VIEW)) { $url = CRM_Utils_System::url("civicrm/contact/view", array('reset' => 1, 'cid' => $val['id'])); - $val['label'] = '<a class="view-' . $entity . ' no-popup" href="' . $url . '" title="' . ts('View Contact') . '">' . CRM_Utils_String::purifyHTML($val['label']) . '</a>'; + $val['label'] = '<a class="view-contact no-popup" href="' . $url . '" title="' . ts('View Contact') . '">' . CRM_Utils_String::purifyHTML($val['label']) . '</a>'; } $display[] = $val['label']; } diff --git a/civicrm/CRM/Core/Form/Search.php b/civicrm/CRM/Core/Form/Search.php index 5d4ed98a0a..c0defa2ac5 100644 --- a/civicrm/CRM/Core/Form/Search.php +++ b/civicrm/CRM/Core/Form/Search.php @@ -151,12 +151,12 @@ class CRM_Core_Form_Search extends CRM_Core_Form { * than existing ad hoc handling. */ public function addFormFieldsFromMetadata() { + $this->addFormRule(['CRM_Core_Form_Search', 'formRule'], $this); $this->_action = CRM_Core_Action::ADVANCED; foreach ($this->getSearchFieldMetadata() as $entity => $fields) { foreach ($fields as $fieldName => $fieldSpec) { - if ($fieldSpec['type'] === CRM_Utils_Type::T_DATE) { - // Assuming time is false for now as we are not checking for date-time fields as yet. - $this->addDatePickerRange($fieldName, $fieldSpec['title'], FALSE); + if ($fieldSpec['type'] === CRM_Utils_Type::T_DATE || $fieldSpec['type'] === (CRM_Utils_Type::T_DATE + CRM_Utils_Type::T_TIME)) { + $this->addDatePickerRange($fieldName, $fieldSpec['title'], ($fieldSpec['type'] === (CRM_Utils_Type::T_DATE + CRM_Utils_Type::T_TIME))); } else { $this->addField($fieldName, ['entity' => $entity]); @@ -165,6 +165,31 @@ class CRM_Core_Form_Search extends CRM_Core_Form { } } + /** + * Global validation rules for the form. + * + * @param array $fields + * Posted values of the form. + * + * @return array + * list of errors to be posted back to the form + */ + public static function formRule($fields, $files, $form) { + $errors = []; + foreach ($form->getSearchFieldMetadata() as $entity => $spec) { + foreach ($spec as $fieldName => $fieldSpec) { + if ($fieldSpec['type'] === CRM_Utils_Type::T_DATE || $fieldSpec['type'] === (CRM_Utils_Type::T_DATE + CRM_Utils_Type::T_TIME)) { + if (isset($fields[$fieldName . '_high']) && isset($fields[$fieldName . '_low']) && empty($fields[$fieldName . '_relative'])) { + if (strtotime($fields[$fieldName . '_low']) > strtotime($fields[$fieldName . '_high'])) { + $errors[$fieldName . '_low'] = ts('%1: Please check that your date range is in correct chronological order.', [1 => $fieldSpec['title']]); + } + } + } + } + } + return $errors; + } + /** * Get the validation rule to apply to a function. * @@ -184,6 +209,10 @@ class CRM_Core_Form_Search extends CRM_Core_Form { case CRM_Utils_Type::T_INT: return 'CommaSeparatedIntegers'; + case CRM_Utils_Type::T_DATE: + case CRM_Utils_Type::T_DATE + CRM_Utils_Type::T_TIME: + return 'Timestamp'; + default: return 'Alphanumeric'; } @@ -204,6 +233,15 @@ class CRM_Core_Form_Search extends CRM_Core_Form { if ($value !== FALSE) { $defaults[$fieldSpec['name']] = $value; } + if ($fieldSpec['type'] === CRM_Utils_Type::T_DATE || ($fieldSpec['type'] === CRM_Utils_Type::T_DATE + CRM_Utils_Type::T_TIME)) { + $low = CRM_Utils_Request::retrieveValue($fieldSpec['name'] . '_low', 'Timestamp', FALSE, NULL, 'GET'); + $high = CRM_Utils_Request::retrieveValue($fieldSpec['name'] . '_high', 'Timestamp', FALSE, NULL, 'GET'); + if ($low !== FALSE || $high !== FALSE) { + $defaults[$fieldSpec['name'] . '_relative'] = 0; + $defaults[$fieldSpec['name'] . '_low'] = $low ? date('Y-m-d H:i:s', strtotime($low)) : NULL; + $defaults[$fieldSpec['name'] . '_high'] = $high ? date('Y-m-d H:i:s', strtotime($high)) : NULL; + } + } } } return $defaults; diff --git a/civicrm/CRM/Core/Form/Tag.php b/civicrm/CRM/Core/Form/Tag.php index 0ff005ca95..b47d0779ca 100644 --- a/civicrm/CRM/Core/Form/Tag.php +++ b/civicrm/CRM/Core/Form/Tag.php @@ -78,7 +78,7 @@ class CRM_Core_Form_Tag { $tagset[$tagsetItem]['tagsetElementName'] = $tagsetElementName; $form->addEntityRef("{$tagsetElementName}[{$parentId}]", $parentNameItem, array( - 'entity' => 'tag', + 'entity' => 'Tag', 'multiple' => TRUE, 'create' => !$skipTagCreate, 'api' => array('params' => array('parent_id' => $parentId)), diff --git a/civicrm/CRM/Core/Payment.php b/civicrm/CRM/Core/Payment.php index 7603137137..95800b7881 100644 --- a/civicrm/CRM/Core/Payment.php +++ b/civicrm/CRM/Core/Payment.php @@ -1288,14 +1288,23 @@ abstract class CRM_Core_Payment { * Page callback for civicrm/payment/ipn */ public static function handleIPN() { - self::handlePaymentMethod( - 'PaymentNotification', - array( - 'processor_name' => @$_GET['processor_name'], - 'processor_id' => @$_GET['processor_id'], - 'mode' => @$_GET['mode'], - ) - ); + try { + self::handlePaymentMethod( + 'PaymentNotification', + [ + 'processor_name' => CRM_Utils_Request::retrieveValue('processor_name', 'String'), + 'processor_id' => CRM_Utils_Request::retrieveValue('processor_id', 'Integer'), + 'mode' => CRM_Utils_Request::retrieveValue('mode', 'Alphanumeric'), + ] + ); + } + catch (CRM_Core_Exception $e) { + Civi::log()->error('ipn_payment_callback_exception', [ + 'context' => [ + 'backtrace' => CRM_Core_Error::formatBacktrace(debug_backtrace()), + ] + ]); + } CRM_Utils_System::civiExit(); } @@ -1357,7 +1366,7 @@ abstract class CRM_Core_Payment { // Check whether we found anything at all. if (!$dao->N) { - CRM_Core_Error::fatal($notFound); + throw new CRM_Core_Exception($notFound); } $method = 'handle' . $method; @@ -1401,7 +1410,7 @@ abstract class CRM_Core_Payment { if (!$extension_instance_found) { $message = "No extension instances of the '%1' payment processor were found.<br />" . "%2 method is unsupported in legacy payment processors."; - CRM_Core_Error::fatal(ts($message, array(1 => $params['processor_name'], 2 => $method))); + throw new CRM_Core_Exception(ts($message, [1 => $params['processor_name'], 2 => $method])); } } diff --git a/civicrm/CRM/Core/Permission.php b/civicrm/CRM/Core/Permission.php index 7b73d6c9d9..74f74c2b78 100644 --- a/civicrm/CRM/Core/Permission.php +++ b/civicrm/CRM/Core/Permission.php @@ -29,8 +29,6 @@ * * @package CRM * @copyright CiviCRM LLC (c) 2004-2019 - * $Id$ - * */ /** @@ -1052,6 +1050,7 @@ class CRM_Core_Permission { 'view all activities', ), ); + $permissions['activity_contact'] = $permissions['activity']; // Case permissions $permissions['case'] = array( diff --git a/civicrm/CRM/Core/PseudoConstant.php b/civicrm/CRM/Core/PseudoConstant.php index 0760680792..fb59a3c5f8 100644 --- a/civicrm/CRM/Core/PseudoConstant.php +++ b/civicrm/CRM/Core/PseudoConstant.php @@ -499,7 +499,7 @@ class CRM_Core_PseudoConstant { } /** - * DEPRECATED generic populate method. + * @deprecated generic populate method. * All pseudoconstant functions that use this method are also @deprecated * * The static array $var is populated from the db diff --git a/civicrm/CRM/Core/Resources.php b/civicrm/CRM/Core/Resources.php index 21401e24e6..0e4e7755ec 100644 --- a/civicrm/CRM/Core/Resources.php +++ b/civicrm/CRM/Core/Resources.php @@ -591,34 +591,24 @@ class CRM_Core_Resources { if (is_array($item)) { $this->addSetting($item); } - elseif (substr($item, -2) == 'js') { + elseif (strpos($item, '.css')) { + $this->isFullyFormedUrl($item) ? $this->addStyleUrl($item, -100, $region) : $this->addStyleFile('civicrm', $item, -100, $region); + } + elseif ($this->isFullyFormedUrl($item)) { + $this->addScriptUrl($item, $jsWeight++, $region); + } + else { // Don't bother looking for ts() calls in packages, there aren't any $translate = (substr($item, 0, 3) == 'js/'); $this->addScriptFile('civicrm', $item, $jsWeight++, $region, $translate); } - else { - $this->addStyleFile('civicrm', $item, -100, $region); - } } - - $tsLocale = CRM_Core_I18n::getLocale(); - // Dynamic localization script - $args = [ - 'r' => $this->getCacheCode(), - 'cid' => CRM_Core_Session::getLoggedInContactID(), - ]; - $this->addScriptUrl(CRM_Utils_System::url('civicrm/ajax/l10n-js/' . $tsLocale, $args, FALSE, NULL, FALSE), $jsWeight++, $region); - // Add global settings $settings = array( 'config' => array( 'isFrontend' => $config->userFrameworkFrontend, ), ); - $contactID = CRM_Core_Session::getLoggedInContactID(); - if ($contactID) { - $settings['config']['menuCacheCode'] = CRM_Core_BAO_Navigation::getCacheKey($contactID); - } // Disable profile creation if user lacks permission if (!CRM_Core_Permission::check('edit all contacts') && !CRM_Core_Permission::check('add contacts')) { $settings['config']['entityRef']['contactCreate'] = FALSE; @@ -687,13 +677,12 @@ class CRM_Core_Resources { 'moneyFormat' => json_encode(CRM_Utils_Money::format(1234.56)), 'contactSearch' => json_encode($config->includeEmailInName ? ts('Start typing a name or email...') : ts('Start typing a name...')), 'otherSearch' => json_encode(ts('Enter search term...')), - 'entityRef' => array( - 'contactCreate' => CRM_Core_BAO_UFGroup::getCreateLinks(), - 'filters' => self::getEntityRefFilters(), - ), + 'entityRef' => self::getEntityRefMetadata(), 'ajaxPopupsEnabled' => self::singleton()->ajaxPopupsEnabled, 'allowAlertAutodismissal' => (bool) Civi::settings()->get('allow_alert_autodismissal'), 'resourceCacheCode' => self::singleton()->getCacheCode(), + 'locale' => CRM_Core_I18n::getLocale(), + 'cid' => (int) CRM_Core_Session::getLoggedInContactID(), ); print CRM_Core_Smarty::singleton()->fetchWith('CRM/common/l10n.js.tpl', $vars); CRM_Utils_System::civiExit(); @@ -733,6 +722,13 @@ class CRM_Core_Resources { "js/crm.ajax.js", "js/wysiwyg/crm.wysiwyg.js", ); + + // Dynamic localization script + $items[] = $this->addCacheCode( + CRM_Utils_System::url('civicrm/ajax/l10n-js/' . CRM_Core_I18n::getLocale(), + ['cid' => CRM_Core_Session::getLoggedInContactID()], FALSE, NULL, FALSE) + ); + // add wysiwyg editor $editor = Civi::settings()->get('editor_id'); if ($editor == "CKEditor") { @@ -748,11 +744,39 @@ class CRM_Core_Resources { // These scripts are only needed by back-office users if (CRM_Core_Permission::check('access CiviCRM')) { $items[] = "packages/jquery/plugins/jquery.tableHeader.js"; - $items[] = "packages/jquery/plugins/jquery.menu.min.js"; - $items[] = "css/civicrmNavigation.css"; $items[] = "packages/jquery/plugins/jquery.notify.min.js"; } + $contactID = CRM_Core_Session::getLoggedInContactID(); + + // Menubar + $position = 'none'; + if ( + $contactID && !$config->userFrameworkFrontend + && CRM_Core_Permission::check('access CiviCRM') + && !@constant('CIVICRM_DISABLE_DEFAULT_MENU') + && !CRM_Core_Config::isUpgradeMode() + ) { + $position = Civi::settings()->get('menubar_position') ?: 'over-cms-menu'; + } + if ($position !== 'none') { + $cms = strtolower($config->userFramework); + $cms = $cms === 'drupal' ? 'drupal7' : $cms; + $items[] = 'bower_components/smartmenus/dist/jquery.smartmenus.min.js'; + $items[] = 'bower_components/smartmenus/dist/addons/keyboard/jquery.smartmenus.keyboard.min.js'; + $items[] = 'js/crm.menubar.js'; + $items[] = 'bower_components/smartmenus/dist/css/sm-core-css.css'; + $items[] = 'css/crm-menubar.css'; + $items[] = "css/menubar-$cms.css"; + $items[] = [ + 'menubar' => [ + 'position' => $position, + 'qfKey' => CRM_Core_Key::get('CRM_Contact_Controller_Search', TRUE), + 'cacheCode' => CRM_Core_BAO_Navigation::getCacheKey($contactID), + ], + ]; + } + // JS for multilingual installations if (!empty($config->languageLimit) && count($config->languageLimit) > 1 && CRM_Core_Permission::check('translate CiviCRM')) { $items[] = "js/crm.multilingual.js"; @@ -803,115 +827,49 @@ class CRM_Core_Resources { /** * Provide a list of available entityRef filters. - * @todo: move component filters into their respective components (e.g. CiviEvent) * * @return array */ - public static function getEntityRefFilters() { - $filters = array(); - $config = CRM_Core_Config::singleton(); - - if (in_array('CiviEvent', $config->enableComponents)) { - $filters['event'] = array( - array('key' => 'event_type_id', 'value' => ts('Event Type')), - array( - 'key' => 'start_date', - 'value' => ts('Start Date'), - 'options' => array( - array('key' => '{">":"now"}', 'value' => ts('Upcoming')), - array( - 'key' => '{"BETWEEN":["now - 3 month","now"]}', - 'value' => ts('Past 3 Months'), - ), - array( - 'key' => '{"BETWEEN":["now - 6 month","now"]}', - 'value' => ts('Past 6 Months'), - ), - array( - 'key' => '{"BETWEEN":["now - 1 year","now"]}', - 'value' => ts('Past Year'), - ), - ), - ), - ); - } - - $filters['activity'] = array( - array('key' => 'activity_type_id', 'value' => ts('Activity Type')), - array('key' => 'status_id', 'value' => ts('Activity Status')), - ); - - $filters['contact'] = [ - ['key' => 'contact_type', 'value' => ts('Contact Type')], - ['key' => 'group', 'value' => ts('Group'), 'entity' => 'group_contact'], - ['key' => 'tag', 'value' => ts('Tag'), 'entity' => 'entity_tag'], - ['key' => 'state_province', 'value' => ts('State/Province'), 'entity' => 'address'], - ['key' => 'country', 'value' => ts('Country'), 'entity' => 'address'], - ['key' => 'gender_id', 'value' => ts('Gender'), 'condition' => ['contact_type' => 'Individual']], - ['key' => 'is_deceased', 'value' => ts('Deceased'), 'condition' => ['contact_type' => 'Individual']], - ['key' => 'contact_id', 'value' => ts('Contact ID'), 'type' => 'text'], - ['key' => 'external_identifier', 'value' => ts('External ID'), 'type' => 'text'], - ['key' => 'source', 'value' => ts('Contact Source'), 'type' => 'text'], + public static function getEntityRefMetadata() { + $data = [ + 'filters' => [], + 'links' => [], ]; + $config = CRM_Core_Config::singleton(); - if (in_array('CiviCase', $config->enableComponents)) { - $filters['case'] = array( - array( - 'key' => 'case_id.case_type_id', - 'value' => ts('Case Type'), - 'entity' => 'Case', - ), - array( - 'key' => 'case_id.status_id', - 'value' => ts('Case Status'), - 'entity' => 'Case', - ), - ); - foreach ($filters['contact'] as $filter) { - $filter += array('entity' => 'contact'); - $filter['key'] = 'contact_id.' . $filter['key']; - $filters['case'][] = $filter; + $disabledComponents = []; + $dao = CRM_Core_DAO::executeQuery("SELECT name, namespace FROM civicrm_component"); + while ($dao->fetch()) { + if (!in_array($dao->name, $config->enableComponents)) { + $disabledComponents[$dao->name] = $dao->namespace; } } - if (in_array('CiviCampaign', $config->enableComponents)) { - $filters['campaign'] = [ - ['key' => 'campaign_type_id', 'value' => ts('Campaign Type')], - ['key' => 'status_id', 'value' => ts('Status')], - [ - 'key' => 'start_date', - 'value' => ts('Start Date'), - 'options' => [ - ['key' => '{">":"now"}', 'value' => ts('Upcoming')], - [ - 'key' => '{"BETWEEN":["now - 3 month","now"]}', - 'value' => ts('Past 3 Months'), - ], - [ - 'key' => '{"BETWEEN":["now - 6 month","now"]}', - 'value' => ts('Past 6 Months'), - ], - [ - 'key' => '{"BETWEEN":["now - 1 year","now"]}', - 'value' => ts('Past Year'), - ], - ], - ], - [ - 'key' => 'end_date', - 'value' => ts('End Date'), - 'options' => [ - ['key' => '{">":"now"}', 'value' => ts('In the future')], - ['key' => '{"<":"now"}', 'value' => ts('In the past')], - ['key' => '{"IS NULL":"1"}', 'value' => ts('Not set')], - ], - ], - ]; + foreach (CRM_Core_DAO_AllCoreTables::daoToClass() as $entity => $daoName) { + // Skip DAOs of disabled components + foreach ($disabledComponents as $nameSpace) { + if (strpos($daoName, $nameSpace) === 0) { + continue 2; + } + } + $baoName = str_replace('_DAO_', '_BAO_', $daoName); + if (class_exists($baoName)) { + $filters = $baoName::getEntityRefFilters(); + if ($filters) { + $data['filters'][$entity] = $filters; + } + if (is_callable([$baoName, 'getEntityRefCreateLinks'])) { + $createLinks = $baoName::getEntityRefCreateLinks(); + if ($createLinks) { + $data['links'][$entity] = $createLinks; + } + } + } } - CRM_Utils_Hook::entityRefFilters($filters); + CRM_Utils_Hook::entityRefFilters($data['filters']); - return $filters; + return $data; } /** @@ -940,4 +898,15 @@ class CRM_Core_Resources { return $url . $operator . 'r=' . $this->cacheCode; } + /** + * Checks if the given URL is fully-formed + * + * @param string $url + * + * @return bool + */ + public static function isFullyFormedUrl($url) { + return (substr($url, 0, 4) === 'http') || (substr($url, 0, 1) === '/'); + } + } diff --git a/civicrm/CRM/Core/Smarty/plugins/function.crmNavigationMenu.php b/civicrm/CRM/Core/Smarty/plugins/function.crmNavigationMenu.php deleted file mode 100644 index de8f873b8e..0000000000 --- a/civicrm/CRM/Core/Smarty/plugins/function.crmNavigationMenu.php +++ /dev/null @@ -1,74 +0,0 @@ -<?php -/* - +--------------------------------------------------------------------+ - | CiviCRM version 5 | - +--------------------------------------------------------------------+ - | Copyright CiviCRM LLC (c) 2004-2019 | - +--------------------------------------------------------------------+ - | This file is a part of CiviCRM. | - | | - | CiviCRM is free software; you can copy, modify, and distribute it | - | under the terms of the GNU Affero General Public License | - | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. | - | | - | CiviCRM is distributed in the hope that it will be useful, but | - | WITHOUT ANY WARRANTY; without even the implied warranty of | - | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | - | See the GNU Affero General Public License for more details. | - | | - | You should have received a copy of the GNU Affero General Public | - | License and the CiviCRM Licensing Exception along | - | with this program; if not, contact CiviCRM LLC | - | at info[AT]civicrm[DOT]org. If you have questions about the | - | GNU Affero General Public License or the licensing of CiviCRM, | - | see the CiviCRM license FAQ at http://civicrm.org/licensing | - +--------------------------------------------------------------------+ - */ - -/** - * - * @package CRM - * @copyright CiviCRM LLC (c) 2004-2019 - * $Id$ - * - */ - -/** - * Output navigation script tag - * - * @param array $params - * - is_default: bool, true if this is normal/default instance of the menu (which may be subject to CIVICRM_DISABLE_DEFAULT_MENU) - * @param CRM_Core_Smarty $smarty - * The Smarty object. - * - * @return string - * HTML - */ -function smarty_function_crmNavigationMenu($params, &$smarty) { - $config = CRM_Core_Config::singleton(); - //check if logged in user has access CiviCRM permission and build menu - $buildNavigation = !CRM_Core_Config::isUpgradeMode() && CRM_Core_Permission::check('access CiviCRM'); - if (defined('CIVICRM_DISABLE_DEFAULT_MENU') && CRM_Utils_Array::value('is_default', $params, FALSE)) { - $buildNavigation = FALSE; - } - if ($config->userFrameworkFrontend) { - $buildNavigation = FALSE; - } - if ($buildNavigation) { - $session = CRM_Core_Session::singleton(); - $contactID = $session->get('userID'); - if ($contactID) { - // These params force the browser to refresh the js file when switching user, domain, or language - // We don't put them as a query string because some browsers will refuse to cache a page with a ? in the url - // @see CRM_Admin_Page_AJAX::getNavigationMenu - $lang = CRM_Core_I18n::getLocale(); - $domain = CRM_Core_Config::domainID(); - $key = CRM_Core_BAO_Navigation::getCacheKey($contactID); - $src = CRM_Utils_System::url("civicrm/ajax/menujs/$contactID/$lang/$domain/$key"); - // CRM-15493 QFkey needed for quicksearch bar - must be unique on each page refresh so adding it directly to markup - $qfKey = CRM_Core_Key::get('CRM_Contact_Controller_Search', TRUE); - return '<script id="civicrm-navigation-menu" type="text/javascript" src="' . $src . '" data-qfkey=' . json_encode($qfKey) . '></script>'; - } - } - return ''; -} diff --git a/civicrm/CRM/Core/xml/Menu/Activity.xml b/civicrm/CRM/Core/xml/Menu/Activity.xml index b453219920..774be6105d 100644 --- a/civicrm/CRM/Core/xml/Menu/Activity.xml +++ b/civicrm/CRM/Core/xml/Menu/Activity.xml @@ -7,7 +7,7 @@ <page_callback>CRM_Activity_Form_Activity</page_callback> <access_arguments>access CiviCRM</access_arguments> <page_arguments>attachUpload=1</page_arguments> - <path_arguments>action=add&context=standalone</path_arguments> + <path_arguments>action=add,context=standalone</path_arguments> </item> <item> <path>civicrm/activity/view</path> diff --git a/civicrm/CRM/Core/xml/Menu/Admin.xml b/civicrm/CRM/Core/xml/Menu/Admin.xml index 918d372cae..d23a10910b 100644 --- a/civicrm/CRM/Core/xml/Menu/Admin.xml +++ b/civicrm/CRM/Core/xml/Menu/Admin.xml @@ -633,9 +633,9 @@ <weight>9000</weight> </item> <item> - <path>civicrm/ajax/menujs</path> - <page_callback>CRM_Admin_Page_AJAX::getNavigationMenu</page_callback> - <access_arguments>access CiviCRM</access_arguments> + <path>civicrm/ajax/navmenu</path> + <page_callback>CRM_Admin_Page_AJAX::navMenu</page_callback> + <access_arguments>access CiviCRM</access_arguments> </item> <item> <path>civicrm/ajax/menutree</path> diff --git a/civicrm/CRM/Custom/Form/CustomData.php b/civicrm/CRM/Custom/Form/CustomData.php index 532a11ef81..d2a644f7ff 100644 --- a/civicrm/CRM/Custom/Form/CustomData.php +++ b/civicrm/CRM/Custom/Form/CustomData.php @@ -63,11 +63,18 @@ class CRM_Custom_Form_CustomData { $entitySubType = $form->getEntitySubTypeId($subType); } - // when custom data is included in this page - if (!empty($_POST['hidden_custom'])) { - self::preProcess($form, $subName, $entitySubType, $groupCount, $entityName, $entityID); - self::buildQuickForm($form); - self::setDefaultValues($form); + if ($form->getAction() == CRM_Core_Action::VIEW) { + // Viewing custom data (Use with {include file="CRM/Custom/Page/CustomDataView.tpl"} in template) + $groupTree = CRM_Core_BAO_CustomGroup::getTree($entityName, NULL, $entityID, 0, $entitySubType); + CRM_Core_BAO_CustomGroup::buildCustomDataView($form, $groupTree, FALSE, NULL, NULL, NULL, $entityID); + } + else { + // Editing custom data (Use with {include file="CRM/common/customDataBlock.tpl"} in template) + if (!empty($_POST['hidden_custom'])) { + self::preProcess($form, $subName, $entitySubType, $groupCount, $entityName, $entityID); + self::buildQuickForm($form); + self::setDefaultValues($form); + } } // need to assign custom data type and subtype to the template $form->assign('customDataType', $entityName); diff --git a/civicrm/CRM/Dedupe/BAO/Rule.php b/civicrm/CRM/Dedupe/BAO/Rule.php index 4a3bbade67..40c6a74448 100644 --- a/civicrm/CRM/Dedupe/BAO/Rule.php +++ b/civicrm/CRM/Dedupe/BAO/Rule.php @@ -72,7 +72,22 @@ class CRM_Dedupe_BAO_Rule extends CRM_Dedupe_DAO_Rule { // full matches, respectively) $where = array(); $on = array("SUBSTR(t1.{$this->rule_field}, 1, {$this->rule_length}) = SUBSTR(t2.{$this->rule_field}, 1, {$this->rule_length})"); - $using = array($this->rule_field); + $entity = CRM_Core_DAO_AllCoreTables::getBriefName(CRM_Core_DAO_AllCoreTables::getClassForTable($this->rule_table)); + $fields = civicrm_api3($entity, 'getfields', ['action' => 'create'])['values']; + + $innerJoinClauses = [ + "t1.{$this->rule_field} IS NOT NULL", + "t2.{$this->rule_field} IS NOT NULL", + "t1.{$this->rule_field} = t2.{$this->rule_field}" + ]; + if ($fields[$this->rule_field]['type'] === CRM_Utils_Type::T_DATE) { + $innerJoinClauses[] = "t1.{$this->rule_field} > '1000-01-01'"; + $innerJoinClauses[] = "t2.{$this->rule_field} > '1000-01-01'"; + } + else { + $innerJoinClauses[] = "t1.{$this->rule_field} <> ''"; + $innerJoinClauses[] = "t2.{$this->rule_field} <> ''"; + } switch ($this->rule_table) { case 'civicrm_contact': @@ -92,7 +107,7 @@ class CRM_Dedupe_BAO_Rule extends CRM_Dedupe_DAO_Rule { case 'civicrm_address': $id = 'contact_id'; $on[] = 't1.location_type_id = t2.location_type_id'; - $using[] = 'location_type_id'; + $innerJoinClauses[] = ['t1.location_type_id = t2.location_type_id']; if ($this->params['civicrm_address']['location_type_id']) { $locTypeId = CRM_Utils_Type::escape($this->params['civicrm_address']['location_type_id'], 'Integer', FALSE); if ($locTypeId) { @@ -152,7 +167,6 @@ class CRM_Dedupe_BAO_Rule extends CRM_Dedupe_DAO_Rule { if ($this->rule_length) { $where[] = "SUBSTR(t1.{$this->rule_field}, 1, {$this->rule_length}) = SUBSTR('$str', 1, {$this->rule_length})"; $where[] = "t1.{$this->rule_field} IS NOT NULL"; - $where[] = "t1.{$this->rule_field} <> ''"; } else { $where[] = "t1.{$this->rule_field} = '$str'"; @@ -163,15 +177,13 @@ class CRM_Dedupe_BAO_Rule extends CRM_Dedupe_DAO_Rule { $from = "{$this->rule_table} t1 JOIN {$this->rule_table} t2 ON (" . implode(' AND ', $on) . ")"; } else { - $from = "{$this->rule_table} t1 JOIN {$this->rule_table} t2 USING (" . implode(', ', $using) . ")"; + $from = "{$this->rule_table} t1 INNER JOIN {$this->rule_table} t2 ON (" . implode(' AND ', $innerJoinClauses) . ")"; } } // finish building WHERE, also limit the results if requested if (!$this->params) { $where[] = "t1.$id < t2.$id"; - $where[] = "t1.{$this->rule_field} IS NOT NULL"; - $where[] = "t1.{$this->rule_field} <> ''"; } $query = "SELECT $select FROM $from WHERE " . implode(' AND ', $where); if ($this->contactIds) { diff --git a/civicrm/CRM/Dedupe/DAO/Exception.php b/civicrm/CRM/Dedupe/DAO/Exception.php index 03dac72f30..3e824fa3e6 100644 --- a/civicrm/CRM/Dedupe/DAO/Exception.php +++ b/civicrm/CRM/Dedupe/DAO/Exception.php @@ -6,7 +6,7 @@ * * Generated from xml/schema/CRM/Dedupe/Exception.xml * DO NOT EDIT. Generated by CRM_Core_CodeGen - * (GenCodeChecksum:8be54351020230bbff872ebf033c811b) + * (GenCodeChecksum:1f39e9ee1f80da1b62c054f6ca4119c5) */ /** @@ -97,6 +97,7 @@ class CRM_Dedupe_DAO_Exception extends CRM_Core_DAO { 'type' => CRM_Utils_Type::T_INT, 'title' => ts('First Dupe Contact ID'), 'description' => ts('FK to Contact ID'), + 'required' => TRUE, 'table_name' => 'civicrm_dedupe_exception', 'entity' => 'Exception', 'bao' => 'CRM_Dedupe_DAO_Exception', @@ -108,6 +109,7 @@ class CRM_Dedupe_DAO_Exception extends CRM_Core_DAO { 'type' => CRM_Utils_Type::T_INT, 'title' => ts('Second Dupe Contact ID'), 'description' => ts('FK to Contact ID'), + 'required' => TRUE, 'table_name' => 'civicrm_dedupe_exception', 'entity' => 'Exception', 'bao' => 'CRM_Dedupe_DAO_Exception', diff --git a/civicrm/CRM/Dedupe/Merger.php b/civicrm/CRM/Dedupe/Merger.php index 8563d3603f..1c82527efb 100644 --- a/civicrm/CRM/Dedupe/Merger.php +++ b/civicrm/CRM/Dedupe/Merger.php @@ -1433,7 +1433,16 @@ INNER JOIN civicrm_membership membership2 ON membership1.membership_type_id = m } } if ($name == 'rel_table_memberships') { - $elements[] = array('checkbox', "operation[move_{$name}][add]", NULL, ts('add new')); + //Enable 'add new' checkbox if main contact does not contain any membership similar to duplicate contact. + $attributes = ['checked' => 'checked']; + $otherContactMemberships = CRM_Member_BAO_Membership::getAllContactMembership($otherId); + foreach ($otherContactMemberships as $membership) { + $mainMembership = CRM_Member_BAO_Membership::getContactMembership($mainId, $membership['membership_type_id'], FALSE); + if ($mainMembership) { + $attributes = []; + } + } + $elements[] = array('checkbox', "operation[move_{$name}][add]", NULL, ts('add new'), $attributes); $migrationInfo["operation"]["move_{$name}"]['add'] = 1; } } diff --git a/civicrm/CRM/Event/BAO/Event.php b/civicrm/CRM/Event/BAO/Event.php index 68216a7e5f..755847c056 100644 --- a/civicrm/CRM/Event/BAO/Event.php +++ b/civicrm/CRM/Event/BAO/Event.php @@ -2370,4 +2370,32 @@ LEFT JOIN civicrm_price_field_value value ON ( value.id = lineItem.price_field return CRM_Core_PseudoConstant::get(__CLASS__, $fieldName, $params, $context); } + /** + * @return array + */ + public static function getEntityRefFilters() { + return [ + ['key' => 'event_type_id', 'value' => ts('Event Type')], + [ + 'key' => 'start_date', + 'value' => ts('Start Date'), + 'options' => [ + ['key' => '{">":"now"}', 'value' => ts('Upcoming')], + [ + 'key' => '{"BETWEEN":["now - 3 month","now"]}', + 'value' => ts('Past 3 Months'), + ], + [ + 'key' => '{"BETWEEN":["now - 6 month","now"]}', + 'value' => ts('Past 6 Months'), + ], + [ + 'key' => '{"BETWEEN":["now - 1 year","now"]}', + 'value' => ts('Past Year'), + ], + ], + ], + ]; + } + } diff --git a/civicrm/CRM/Event/BAO/ParticipantPayment.php b/civicrm/CRM/Event/BAO/ParticipantPayment.php index 0051038aaa..f84e6b15ac 100644 --- a/civicrm/CRM/Event/BAO/ParticipantPayment.php +++ b/civicrm/CRM/Event/BAO/ParticipantPayment.php @@ -71,10 +71,10 @@ class CRM_Event_BAO_ParticipantPayment extends CRM_Event_DAO_ParticipantPayment $participantPayment->find(TRUE); } if ($id) { - CRM_Utils_Hook::post('edit', 'ParticipantPayment', $id, $participantPayment); + CRM_Utils_Hook::post('edit', 'ParticipantPayment', $participantPayment->id, $participantPayment); } else { - CRM_Utils_Hook::post('create', 'ParticipantPayment', NULL, $participantPayment); + CRM_Utils_Hook::post('create', 'ParticipantPayment', $participantPayment->id, $participantPayment); } //generally if people are creating participant_payments via the api they won't be setting the line item correctly - we can't help them if they are doing complex transactions diff --git a/civicrm/CRM/Event/BAO/Query.php b/civicrm/CRM/Event/BAO/Query.php index 1c5c9a0ecf..e43e38377c 100644 --- a/civicrm/CRM/Event/BAO/Query.php +++ b/civicrm/CRM/Event/BAO/Query.php @@ -581,14 +581,14 @@ class CRM_Event_BAO_Query extends CRM_Core_BAO_Query { $form->assign('dataURLEventFee', $dataURLEventFee); $form->addEntityRef('event_id', ts('Event Name'), array( - 'entity' => 'event', + 'entity' => 'Event', 'placeholder' => ts('- any -'), 'multiple' => 1, 'select' => array('minimumInputLength' => 0), ) ); $form->addEntityRef('event_type_id', ts('Event Type'), array( - 'entity' => 'option_value', + 'entity' => 'OptionValue', 'placeholder' => ts('- any -'), 'select' => array('minimumInputLength' => 0), 'api' => array( diff --git a/civicrm/CRM/Event/Form/ManageEvent/Conference.php b/civicrm/CRM/Event/Form/ManageEvent/Conference.php index cf6eee93c0..cd4b3e67e6 100644 --- a/civicrm/CRM/Event/Form/ManageEvent/Conference.php +++ b/civicrm/CRM/Event/Form/ManageEvent/Conference.php @@ -57,7 +57,7 @@ class CRM_Event_Form_ManageEvent_Conference extends CRM_Event_Form_ManageEvent { ); $this->addEntityRef('parent_event_id', ts('Parent Event'), array( - 'entity' => 'event', + 'entity' => 'Event', 'placeholder' => ts('- any -'), 'select' => array('minimumInputLength' => 0), ) diff --git a/civicrm/CRM/Event/Form/ManageEvent/Location.php b/civicrm/CRM/Event/Form/ManageEvent/Location.php index 58d27ed775..50d853972a 100644 --- a/civicrm/CRM/Event/Form/ManageEvent/Location.php +++ b/civicrm/CRM/Event/Form/ManageEvent/Location.php @@ -228,8 +228,8 @@ class CRM_Event_Form_ManageEvent_Location extends CRM_Event_Form_ManageEvent { ); } - $this->_values['address'] = array(); - // if 'create new loc' optioin is selected OR selected new loc is different + $this->_values['address'] = $this->_values['phone'] = $this->_values['email'] = array(); + // if 'create new loc' option is selected OR selected new loc is different // from old one, go ahead and delete the old loc provided thats not being // used by any other event if ($this->_oldLocBlockId && $deleteOldBlock) { diff --git a/civicrm/CRM/Event/Form/Participant.php b/civicrm/CRM/Event/Form/Participant.php index fdb9cacd84..ee2621e601 100644 --- a/civicrm/CRM/Event/Form/Participant.php +++ b/civicrm/CRM/Event/Form/Participant.php @@ -635,7 +635,7 @@ class CRM_Event_Form_Participant extends CRM_Contribute_Form_AbstractEditPayment } $eventFieldParams = array( - 'entity' => 'event', + 'entity' => 'Event', 'select' => array('minimumInputLength' => 0), 'api' => array( 'extra' => array('campaign_id', 'default_role_id', 'event_type_id'), diff --git a/civicrm/CRM/Event/Form/Registration/Register.php b/civicrm/CRM/Event/Form/Registration/Register.php index 6018ce14a8..da54819b40 100644 --- a/civicrm/CRM/Event/Form/Registration/Register.php +++ b/civicrm/CRM/Event/Form/Registration/Register.php @@ -70,6 +70,11 @@ class CRM_Event_Form_Registration_Register extends CRM_Event_Form_Registration { */ public $_noFees; + /** + * @var array Fee Block + */ + public $_feeBlock; + /** * Array of payment related fields to potentially display on this form (generally credit card or debit card fields). * @@ -83,19 +88,18 @@ class CRM_Event_Form_Registration_Register extends CRM_Event_Form_Registration { * Get the contact id for the registration. * * @param array $fields - * @param CRM_Core_Form $self + * @param CRM_Event_Form_Registration $form * @param bool $isAdditional * * @return int|null */ - public static function getRegistrationContactID($fields, $self, $isAdditional) { - + public static function getRegistrationContactID($fields, $form, $isAdditional) { $contactID = NULL; if (!$isAdditional) { - $contactID = $self->getContactID(); + $contactID = $form->getContactID(); } if (!$contactID && is_array($fields) && $fields) { - $contactID = CRM_Contact_BAO_Contact::getFirstDuplicateContact($fields, 'Individual', 'Unsupervised', array(), FALSE, CRM_Utils_Array::value('dedupe_rule_group_id', $self->_values['event'])); + $contactID = CRM_Contact_BAO_Contact::getFirstDuplicateContact($fields, 'Individual', 'Unsupervised', array(), FALSE, CRM_Utils_Array::value('dedupe_rule_group_id', $form->_values['event'])); } return $contactID; } @@ -497,7 +501,7 @@ class CRM_Event_Form_Registration_Register extends CRM_Event_Form_Registration { /** * Build the radio/text form elements for the amount field * - * @param CRM_Core_Form $form + * @param CRM_Event_Form_Registration_Register $form * Form object. * @param bool $required * True if you want to add formRule. @@ -661,7 +665,7 @@ class CRM_Event_Form_Registration_Register extends CRM_Event_Form_Registration { } /** - * @param CRM_Core_Form $form + * @param CRM_Event_Form_Registration $form */ public static function formatFieldsForOptionFull(&$form) { $priceSet = $form->get('priceSet'); @@ -770,40 +774,40 @@ class CRM_Event_Form_Registration_Register extends CRM_Event_Form_Registration { * The input form values. * @param array $files * The uploaded files if any. - * @param $self + * @param CRM_Event_Form_Registration $form * * * @return bool|array * true if no errors, else array of errors */ - public static function formRule($fields, $files, $self) { + public static function formRule($fields, $files, $form) { $errors = array(); //check that either an email or firstname+lastname is included in the form(CRM-9587) - self::checkProfileComplete($fields, $errors, $self->_eventId); + self::checkProfileComplete($fields, $errors, $form->_eventId); //To check if the user is already registered for the event(CRM-2426) - if (!$self->_skipDupeRegistrationCheck) { - self::checkRegistration($fields, $self); + if (!$form->_skipDupeRegistrationCheck) { + self::checkRegistration($fields, $form); } //check for availability of registrations. - if (!$self->_allowConfirmation && empty($fields['bypass_payment']) && - is_numeric($self->_availableRegistrations) && - CRM_Utils_Array::value('additional_participants', $fields) >= $self->_availableRegistrations + if (!$form->_allowConfirmation && empty($fields['bypass_payment']) && + is_numeric($form->_availableRegistrations) && + CRM_Utils_Array::value('additional_participants', $fields) >= $form->_availableRegistrations ) { - $errors['additional_participants'] = ts("There is only enough space left on this event for %1 participant(s).", array(1 => $self->_availableRegistrations)); + $errors['additional_participants'] = ts("There is only enough space left on this event for %1 participant(s).", array(1 => $form->_availableRegistrations)); } // during confirmation don't allow to increase additional participants, CRM-4320 - if ($self->_allowConfirmation && !empty($fields['additional_participants']) && - is_array($self->_additionalParticipantIds) && - $fields['additional_participants'] > count($self->_additionalParticipantIds) + if ($form->_allowConfirmation && !empty($fields['additional_participants']) && + is_array($form->_additionalParticipantIds) && + $fields['additional_participants'] > count($form->_additionalParticipantIds) ) { - $errors['additional_participants'] = ts("Oops. It looks like you are trying to increase the number of additional people you are registering for. You can confirm registration for a maximum of %1 additional people.", array(1 => count($self->_additionalParticipantIds))); + $errors['additional_participants'] = ts("Oops. It looks like you are trying to increase the number of additional people you are registering for. You can confirm registration for a maximum of %1 additional people.", array(1 => count($form->_additionalParticipantIds))); } //don't allow to register w/ waiting if enough spaces available. - if (!empty($fields['bypass_payment']) && $self->_allowConfirmation) { - if (!is_numeric($self->_availableRegistrations) || - (empty($fields['priceSetId']) && CRM_Utils_Array::value('additional_participants', $fields) < $self->_availableRegistrations) + if (!empty($fields['bypass_payment']) && $form->_allowConfirmation) { + if (!is_numeric($form->_availableRegistrations) || + (empty($fields['priceSetId']) && CRM_Utils_Array::value('additional_participants', $fields) < $form->_availableRegistrations) ) { $errors['bypass_payment'] = ts("Oops. There are enough available spaces in this event. You can not add yourself to the waiting list."); } @@ -817,13 +821,13 @@ class CRM_Event_Form_Registration_Register extends CRM_Event_Form_Registration { // priceset validations if (!empty($fields['priceSetId']) && - !$self->_requireApproval && !$self->_allowWaitlist + !$form->_requireApproval && !$form->_allowWaitlist ) { //format params. - $formatted = self::formatPriceSetParams($self, $fields); + $formatted = self::formatPriceSetParams($form, $fields); $ppParams = array($formatted); - $priceSetErrors = self::validatePriceSet($self, $ppParams); - $primaryParticipantCount = self::getParticipantCount($self, $ppParams); + $priceSetErrors = self::validatePriceSet($form, $ppParams); + $primaryParticipantCount = self::getParticipantCount($form, $ppParams); //get price set fields errors in. $errors = array_merge($errors, CRM_Utils_Array::value(0, $priceSetErrors, array())); @@ -834,15 +838,15 @@ class CRM_Event_Form_Registration_Register extends CRM_Event_Form_Registration { } if (empty($fields['bypass_payment']) && - !$self->_allowConfirmation && - is_numeric($self->_availableRegistrations) && - $self->_availableRegistrations < $totalParticipants + !$form->_allowConfirmation && + is_numeric($form->_availableRegistrations) && + $form->_availableRegistrations < $totalParticipants ) { - $errors['_qf_default'] = ts("Only %1 Registrations available.", array(1 => $self->_availableRegistrations)); + $errors['_qf_default'] = ts("Only %1 Registrations available.", array(1 => $form->_availableRegistrations)); } $lineItem = array(); - CRM_Price_BAO_PriceSet::processAmount($self->_values['fee'], $fields, $lineItem); + CRM_Price_BAO_PriceSet::processAmount($form->_values['fee'], $fields, $lineItem); $minAmt = CRM_Core_DAO::getFieldValue('CRM_Price_DAO_PriceSet', $fields['priceSetId'], 'min_amount'); if ($fields['amount'] < 0) { @@ -856,8 +860,8 @@ class CRM_Event_Form_Registration_Register extends CRM_Event_Form_Registration { } // @todo - can we remove the 'is_monetary' concept? - if ($self->_values['event']['is_monetary']) { - if (empty($self->_requireApproval) && !empty($fields['amount']) && $fields['amount'] > 0 && + if ($form->_values['event']['is_monetary']) { + if (empty($form->_requireApproval) && !empty($fields['amount']) && $fields['amount'] > 0 && !isset($fields['payment_processor_id'])) { $errors['payment_processor_id'] = ts('Please select a Payment Method'); } @@ -869,28 +873,28 @@ class CRM_Event_Form_Registration_Register extends CRM_Event_Form_Registration { } } elseif (!empty($fields['amount']) && - (isset($self->_values['discount'][$fields['amount']]) - && CRM_Utils_Array::value('value', $self->_values['discount'][$fields['amount']]) == 0 + (isset($form->_values['discount'][$fields['amount']]) + && CRM_Utils_Array::value('value', $form->_values['discount'][$fields['amount']]) == 0 ) ) { $isZeroAmount = TRUE; } elseif (!empty($fields['amount']) && - (isset($self->_values['fee'][$fields['amount']]) - && CRM_Utils_Array::value('value', $self->_values['fee'][$fields['amount']]) == 0 + (isset($form->_values['fee'][$fields['amount']]) + && CRM_Utils_Array::value('value', $form->_values['fee'][$fields['amount']]) == 0 ) ) { $isZeroAmount = TRUE; } - if ($isZeroAmount && !($self->_forcePayement && !empty($fields['additional_participants']))) { + if ($isZeroAmount && !($form->_forcePayement && !empty($fields['additional_participants']))) { $skipPaymentValidation = TRUE; } // also return if zero fees for valid members if (!empty($fields['bypass_payment']) || $skipPaymentValidation || - (!$self->_allowConfirmation && ($self->_requireApproval || $self->_allowWaitlist)) + (!$form->_allowConfirmation && ($form->_requireApproval || $form->_allowWaitlist)) ) { return empty($errors) ? TRUE : $errors; } @@ -898,7 +902,7 @@ class CRM_Event_Form_Registration_Register extends CRM_Event_Form_Registration { $fields['payment_processor_id'], $fields, $errors, - (!$self->_isBillingAddressRequiredForPayLater ? NULL : 'billing') + (!$form->_isBillingAddressRequiredForPayLater ? NULL : 'billing') ); } @@ -1177,58 +1181,58 @@ class CRM_Event_Form_Registration_Register extends CRM_Event_Form_Registration { * * @param array $fields * The input form values(anonymous user). - * @param CRM_Event_Form_Registration_Register $self + * @param CRM_Event_Form_Registration_Register $form * Event data. * @param bool $isAdditional * Treat isAdditional participants a bit differently. * * @return int */ - public static function checkRegistration($fields, &$self, $isAdditional = FALSE) { + public static function checkRegistration($fields, $form, $isAdditional = FALSE) { // CRM-3907, skip check for preview registrations // CRM-4320 participant need to walk wizard if ( - ($self->_mode == 'test' || $self->_allowConfirmation) + ($form->_mode == 'test' || $form->_allowConfirmation) ) { return FALSE; } - $contactID = self::getRegistrationContactID($fields, $self, $isAdditional); + $contactID = self::getRegistrationContactID($fields, $form, $isAdditional); if ($contactID) { $participant = new CRM_Event_BAO_Participant(); $participant->contact_id = $contactID; - $participant->event_id = $self->_values['event']['id']; + $participant->event_id = $form->_values['event']['id']; if (!empty($fields['participant_role']) && is_numeric($fields['participant_role'])) { $participant->role_id = $fields['participant_role']; } else { - $participant->role_id = $self->_values['event']['default_role_id']; + $participant->role_id = $form->_values['event']['default_role_id']; } $participant->is_test = 0; $participant->find(); $statusTypes = CRM_Event_PseudoConstant::participantStatus(NULL, 'is_counted = 1'); while ($participant->fetch()) { if (array_key_exists($participant->status_id, $statusTypes)) { - if (!$isAdditional && !$self->_values['event']['allow_same_participant_emails']) { + if (!$isAdditional && !$form->_values['event']['allow_same_participant_emails']) { $registerUrl = CRM_Utils_System::url('civicrm/event/register', - "reset=1&id={$self->_values['event']['id']}&cid=0" + "reset=1&id={$form->_values['event']['id']}&cid=0" ); - if ($self->_pcpId) { - $registerUrl .= '&pcpId=' . $self->_pcpId; + if ($form->_pcpId) { + $registerUrl .= '&pcpId=' . $form->_pcpId; } $status = ts("It looks like you are already registered for this event. If you want to change your registration, or you feel that you've received this message in error, please contact the site administrator.") . ' ' . ts('You can also <a href="%1">register another participant</a>.', array(1 => $registerUrl)); CRM_Core_Session::singleton()->setStatus($status, ts('Oops.'), 'alert'); $url = CRM_Utils_System::url('civicrm/event/info', - "reset=1&id={$self->_values['event']['id']}&noFullMsg=true" + "reset=1&id={$form->_values['event']['id']}&noFullMsg=true" ); - if ($self->_action & CRM_Core_Action::PREVIEW) { + if ($form->_action & CRM_Core_Action::PREVIEW) { $url .= '&action=preview'; } - if ($self->_pcpId) { - $url .= '&pcpId=' . $self->_pcpId; + if ($form->_pcpId) { + $url .= '&pcpId=' . $form->_pcpId; } CRM_Utils_System::redirect($url); diff --git a/civicrm/CRM/Event/Form/Search.php b/civicrm/CRM/Event/Form/Search.php index 5b28568a91..0f13d9eb8d 100644 --- a/civicrm/CRM/Event/Form/Search.php +++ b/civicrm/CRM/Event/Form/Search.php @@ -88,7 +88,6 @@ class CRM_Event_Form_Search extends CRM_Core_Form_Search { $this->_actionButtonName = $this->getButtonName('next', 'action'); $this->_done = FALSE; - $this->defaults = array(); $this->loadStandardSearchOptionsFromUrl(); $this->loadFormValues(); diff --git a/civicrm/CRM/Event/Selector/Search.php b/civicrm/CRM/Event/Selector/Search.php index 5a71846be4..cbe2da5182 100644 --- a/civicrm/CRM/Event/Selector/Search.php +++ b/civicrm/CRM/Event/Selector/Search.php @@ -530,7 +530,7 @@ class CRM_Event_Selector_Search extends CRM_Core_Selector_Base implements CRM_Co * @return mixed */ public function alphabetQuery() { - return $this->_query->searchQuery(NULL, NULL, NULL, FALSE, FALSE, TRUE); + return $this->_query->alphabetQuery(); } /** diff --git a/civicrm/CRM/Export/BAO/Export.php b/civicrm/CRM/Export/BAO/Export.php index 5ef3763257..44d8e7ee75 100644 --- a/civicrm/CRM/Export/BAO/Export.php +++ b/civicrm/CRM/Export/BAO/Export.php @@ -652,14 +652,12 @@ VALUES $sqlValueString */ public static function createTempTable($sqlColumns) { //creating a temporary table for the search result that need be exported - $exportTempTable = CRM_Utils_SQL_TempTable::build()->setDurable()->setCategory('export')->getName(); + $exportTempTable = CRM_Utils_SQL_TempTable::build()->setDurable()->setCategory('export')->setUtf8(); // also create the sql table - $sql = "DROP TABLE IF EXISTS {$exportTempTable}"; - CRM_Core_DAO::executeQuery($sql); + $exportTempTable->drop(); $sql = " -CREATE TABLE {$exportTempTable} ( id int unsigned NOT NULL AUTO_INCREMENT, "; $sql .= implode(",\n", array_values($sqlColumns)); @@ -682,12 +680,8 @@ CREATE TABLE {$exportTempTable} ( } } - $sql .= " -) ENGINE=InnoDB DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci -"; - - CRM_Core_DAO::executeQuery($sql); - return $exportTempTable; + $exportTempTable->createWithColumns($sql); + return $exportTempTable->getName(); } /** diff --git a/civicrm/CRM/Financial/BAO/ExportFormat.php b/civicrm/CRM/Financial/BAO/ExportFormat.php index ae05788a40..774fddcef3 100644 --- a/civicrm/CRM/Financial/BAO/ExportFormat.php +++ b/civicrm/CRM/Financial/BAO/ExportFormat.php @@ -251,7 +251,7 @@ abstract class CRM_Financial_BAO_ExportFormat { } if (count($validFiles)) { $zip = new ZipArchive(); - if ($zip->open($destination, $overwrite ? ZIPARCHIVE::OVERWRITE : ZIPARCHIVE::CREATE) !== TRUE) { + if ($zip->open($destination, $overwrite ? ZIPARCHIVE::CREATE | ZIPARCHIVE::OVERWRITE : ZIPARCHIVE::CREATE) !== TRUE) { return FALSE; } foreach ($validFiles as $file) { diff --git a/civicrm/CRM/Financial/BAO/FinancialType.php b/civicrm/CRM/Financial/BAO/FinancialType.php index 1b81f316fc..445475e295 100644 --- a/civicrm/CRM/Financial/BAO/FinancialType.php +++ b/civicrm/CRM/Financial/BAO/FinancialType.php @@ -360,27 +360,9 @@ class CRM_Financial_BAO_FinancialType extends CRM_Financial_DAO_FinancialType { * @param array $whereClauses */ public static function addACLClausesToWhereClauses(&$whereClauses) { - $originalWhereClauses = $whereClauses; - CRM_Utils_Hook::selectWhereClause('Contribution', $whereClauses); - if ($whereClauses !== $originalWhereClauses) { - // In this case permisssions have been applied & we assume the - // financialaclreport is applying these - // https://github.com/JMAConsulting/biz.jmaconsulting.financialaclreport/blob/master/financialaclreport.php#L107 - return; - } + $contributionBAO = new CRM_Contribute_BAO_Contribution(); + $whereClauses = array_merge($whereClauses, $contributionBAO->addSelectWhereClause()); - if (!self::isACLFinancialTypeStatus()) { - return; - } - $types = self::getAllEnabledAvailableFinancialTypes(); - if (empty($types)) { - $whereClauses['financial_type_id'] = 'IN (0)'; - } - else { - $whereClauses['financial_type_id'] = [ - 'IN (' . implode(',', array_keys($types)) . ')' - ]; - } } /** @@ -395,6 +377,7 @@ class CRM_Financial_BAO_FinancialType extends CRM_Financial_DAO_FinancialType { * */ public static function buildPermissionedClause(&$whereClauses, $component = NULL, $alias = NULL) { + // @todo the relevant addSelectWhere clause should be called. if (!self::isACLFinancialTypeStatus()) { return FALSE; } diff --git a/civicrm/CRM/Financial/BAO/Payment.php b/civicrm/CRM/Financial/BAO/Payment.php index 656f2a03e4..e7d3aff4df 100644 --- a/civicrm/CRM/Financial/BAO/Payment.php +++ b/civicrm/CRM/Financial/BAO/Payment.php @@ -56,30 +56,16 @@ class CRM_Financial_BAO_Payment { $contribution = civicrm_api3('Contribution', 'getsingle', ['id' => $params['contribution_id']]); $contributionStatus = CRM_Contribute_PseudoConstant::contributionStatus($contribution['contribution_status_id'], 'name'); - // Check if pending contribution - $fullyPaidPayLater = FALSE; - if ($contributionStatus == 'Pending') { - $cmp = bccomp($contribution['total_amount'], $params['total_amount'], 5); - // Total payment amount is the whole amount paid against pending contribution - if ($cmp == 0 || $cmp == -1) { - civicrm_api3('Contribution', 'completetransaction', ['id' => $contribution['id']]); - // Get the trxn - $trxnId = CRM_Core_BAO_FinancialTrxn::getFinancialTrxnId($contribution['id'], 'DESC'); - $ftParams = ['id' => $trxnId['financialTrxnId']]; - $trxn = CRM_Core_BAO_FinancialTrxn::retrieve($ftParams, CRM_Core_DAO::$_nullArray); - $fullyPaidPayLater = TRUE; - } - else { - civicrm_api3('Contribution', 'create', - [ - 'id' => $contribution['id'], - 'contribution_status_id' => 'Partially paid', - ] - ); - } - } - if (!$fullyPaidPayLater) { - $trxn = CRM_Core_BAO_FinancialTrxn::getPartialPaymentTrxn($contribution, $params); + $isPaymentCompletesContribution = self::isPaymentCompletesContribution($params['contribution_id'], $params['total_amount']); + + // For legacy reasons Pending payments are completed through completetransaction. + // @todo completetransaction should transition components but financial transactions + // should be handled through Payment.create. + $isSkipRecordingPaymentHereForLegacyHandlingReasons = ($contributionStatus == 'Pending' && $isPaymentCompletesContribution); + + if (!$isSkipRecordingPaymentHereForLegacyHandlingReasons) { + $trxn = CRM_Contribute_BAO_Contribution::recordPartialPayment($contribution, $params); + if (CRM_Utils_Array::value('line_item', $params) && !empty($trxn)) { foreach ($params['line_item'] as $values) { foreach ($values as $id => $amount) { @@ -114,7 +100,399 @@ class CRM_Financial_BAO_Payment { } } + if ($isPaymentCompletesContribution) { + civicrm_api3('Contribution', 'completetransaction', array('id' => $contribution['id'])); + // Get the trxn + $trxnId = CRM_Core_BAO_FinancialTrxn::getFinancialTrxnId($contribution['id'], 'DESC'); + $ftParams = ['id' => $trxnId['financialTrxnId']]; + $trxn = CRM_Core_BAO_FinancialTrxn::retrieve($ftParams, CRM_Core_DAO::$_nullArray); + } + elseif ($contributionStatus === 'Pending') { + civicrm_api3('Contribution', 'create', + [ + 'id' => $contribution['id'], + 'contribution_status_id' => 'Partially paid', + ] + ); + } + return $trxn; } + /** + * Send an email confirming a payment that has been received. + * + * @param array $params + * + * @return array + */ + public static function sendConfirmation($params) { + + $entities = self::loadRelatedEntities($params['id']); + $sendTemplateParams = array( + 'groupName' => 'msg_tpl_workflow_contribution', + 'valueName' => 'payment_or_refund_notification', + 'PDFFilename' => ts('notification') . '.pdf', + 'contactId' => $entities['contact']['id'], + 'toName' => $entities['contact']['display_name'], + 'toEmail' => $entities['contact']['email'], + 'tplParams' => self::getConfirmationTemplateParameters($entities), + ); + return CRM_Core_BAO_MessageTemplate::sendTemplate($sendTemplateParams); + } + + /** + * Load entities related to the current payment id. + * + * This gives us all the data we need to send an email confirmation but avoiding + * getting anything not tested for the confirmations. We retrieve the 'full' event as + * it has been traditionally assigned in full. + * + * @param int $id + * + * @return array + * - contact = ['id' => x, 'display_name' => y, 'email' => z] + * - event = [.... full event details......] + * - contribution = ['id' => x], + * - payment = [payment info + payment summary info] + */ + protected static function loadRelatedEntities($id) { + $entities = []; + $contributionID = (int) civicrm_api3('EntityFinancialTrxn', 'getvalue', [ + 'financial_trxn_id' => $id, + 'entity_table' => 'civicrm_contribution', + 'return' => 'entity_id', + ]); + $entities['contribution'] = ['id' => $contributionID]; + $entities['payment'] = array_merge(civicrm_api3('FinancialTrxn', 'getsingle', ['id' => $id]), + CRM_Contribute_BAO_Contribution::getPaymentInfo($contributionID) + ); + + $contactID = self::getPaymentContactID($contributionID); + list($displayName, $email) = CRM_Contact_BAO_Contact_Location::getEmailDetails($contactID); + $entities['contact'] = ['id' => $contactID, 'display_name' => $displayName, 'email' => $email]; + $contact = civicrm_api3('Contact', 'getsingle', ['id' => $contactID, 'return' => 'email_greeting']); + $entities['contact']['email_greeting'] = $contact['email_greeting_display']; + + $participantRecords = civicrm_api3('ParticipantPayment', 'get', [ + 'contribution_id' => $contributionID, + 'api.Participant.get' => ['return' => 'event_id'], + 'sequential' => 1, + ])['values']; + if (!empty($participantRecords)) { + $entities['event'] = civicrm_api3('Event', 'getsingle', ['id' => $participantRecords[0]['api.Participant.get']['values'][0]['event_id']]); + if (!empty($entities['event']['is_show_location'])) { + $locationParams = [ + 'entity_id' => $entities['event']['id'], + 'entity_table' => 'civicrm_event', + ]; + $entities['location'] = CRM_Core_BAO_Location::getValues($locationParams, TRUE); + } + } + + return $entities; + } + + /** + * @param int $contributionID + * + * @return int + */ + public static function getPaymentContactID($contributionID) { + $contribution = civicrm_api3('Contribution', 'getsingle', [ + 'id' => $contributionID , + 'return' => ['contact_id'], + ]); + return (int) $contribution['contact_id']; + } + /** + * @param array $entities + * Related entities as an array keyed by the various entities. + * + * @return array + * Values required for the notification + * - contact_id + * - template_variables + * - event (DAO of event if relevant) + */ + public static function getConfirmationTemplateParameters($entities) { + $templateVariables = [ + 'contactDisplayName' => $entities['contact']['display_name'], + 'emailGreeting' => $entities['contact']['email_greeting'], + 'totalAmount' => $entities['payment']['total'], + 'amountOwed' => $entities['payment']['balance'], + 'totalPaid' => $entities['payment']['paid'], + 'paymentAmount' => $entities['payment']['total_amount'], + 'checkNumber' => CRM_Utils_Array::value('check_number', $entities['payment']), + 'receive_date' => $entities['payment']['trxn_date'], + 'paidBy' => CRM_Core_PseudoConstant::getLabel('CRM_Core_BAO_FinancialTrxn', 'payment_instrument_id', $entities['payment']['payment_instrument_id']), + 'isShowLocation' => (!empty($entities['event']) ? $entities['event']['is_show_location'] : FALSE), + 'location' => CRM_Utils_Array::value('location', $entities), + 'event' => CRM_Utils_Array::value('event', $entities), + 'component' => (!empty($entities['event']) ? 'event' : 'contribution'), + 'isRefund' => $entities['payment']['total_amount'] < 0, + 'isAmountzero' => $entities['payment']['total_amount'] === 0, + 'refundAmount' => ($entities['payment']['total_amount'] < 0 ? $entities['payment']['total_amount'] : NULL), + 'paymentsComplete' => ($entities['payment']['balance'] == 0), + ]; + + return self::filterUntestedTemplateVariables($templateVariables); + } + + /** + * Filter out any untested variables. + * + * This just serves to highlight if any variables are added without a unit test also being added. + * + * (if hit then add a unit test for the param & add to this array). + * + * @param array $params + * + * @return array + */ + public static function filterUntestedTemplateVariables($params) { + $testedTemplateVariables = [ + 'contactDisplayName', + 'totalAmount', + 'amountOwed', + 'paymentAmount', + 'event', + 'component', + 'checkNumber', + 'receive_date', + 'paidBy', + 'isShowLocation', + 'location', + 'isRefund', + 'isAmountzero', + 'refundAmount', + 'totalPaid', + 'paymentsComplete', + 'emailGreeting' + ]; + // These are assigned by the payment form - they still 'get through' from the + // form for now without being in here but we should ideally load + // and assign. Note we should update the tpl to use {if $billingName} + // and ditch contributeMode - although it might need to be deprecated rather than removed. + $todoParams = [ + 'contributeMode', + 'billingName', + 'address', + 'credit_card_type', + 'credit_card_number', + 'credit_card_exp_date', + ]; + $filteredParams = []; + foreach ($testedTemplateVariables as $templateVariable) { + // This will cause an a-notice if any are NOT set - by design. Ensuring + // they are set prevents leakage. + $filteredParams[$templateVariable] = $params[$templateVariable]; + } + return $filteredParams; + } + + /** + * @param $contributionId + * @param $trxnData + * @param $updateStatus + * - deprecate this param + * + * @todo - make this protected once recordAdditionalPayment no longer calls it. + * + * @return CRM_Financial_DAO_FinancialTrxn + */ + public static function recordRefundPayment($contributionId, $trxnData, $updateStatus) { + list($contributionDAO, $params) = self::getContributionAndParamsInFormatForRecordFinancialTransaction($contributionId); + + $params['payment_instrument_id'] = CRM_Utils_Array::value('payment_instrument_id', $trxnData, CRM_Utils_Array::value('payment_instrument_id', $params)); + + $paidStatus = CRM_Core_PseudoConstant::getKey('CRM_Financial_DAO_FinancialItem', 'status_id', 'Paid'); + $arAccountId = CRM_Contribute_PseudoConstant::getRelationalFinancialAccount($contributionDAO->financial_type_id, 'Accounts Receivable Account is'); + $completedStatusId = CRM_Core_PseudoConstant::getKey('CRM_Contribute_BAO_Contribution', 'contribution_status_id', 'Completed'); + + $trxnData['total_amount'] = $trxnData['net_amount'] = -$trxnData['total_amount']; + $trxnData['from_financial_account_id'] = $arAccountId; + $trxnData['status_id'] = CRM_Core_PseudoConstant::getKey('CRM_Contribute_BAO_Contribution', 'contribution_status_id', 'Refunded'); + // record the entry + $financialTrxn = CRM_Contribute_BAO_Contribution::recordFinancialAccounts($params, $trxnData); + + // note : not using the self::add method, + // the reason because it performs 'status change' related code execution for financial records + // which in 'Pending Refund' => 'Completed' is not useful, instead specific financial record updates + // are coded below i.e. just updating financial_item status to 'Paid' + if ($updateStatus) { + CRM_Core_DAO::setFieldValue('CRM_Contribute_BAO_Contribution', $contributionId, 'contribution_status_id', $completedStatusId); + } + // add financial item entry + $lineItems = CRM_Price_BAO_LineItem::getLineItemsByContributionID($contributionDAO->id); + if (!empty($lineItems)) { + foreach ($lineItems as $lineItemId => $lineItemValue) { + // don't record financial item for cancelled line-item + if ($lineItemValue['qty'] == 0) { + continue; + } + $paid = $lineItemValue['line_total'] * ($financialTrxn->total_amount / $contributionDAO->total_amount); + $addFinancialEntry = [ + 'transaction_date' => $financialTrxn->trxn_date, + 'contact_id' => $contributionDAO->contact_id, + 'amount' => round($paid, 2), + 'currency' => $contributionDAO->currency, + 'status_id' => $paidStatus, + 'entity_id' => $lineItemId, + 'entity_table' => 'civicrm_line_item', + ]; + $trxnIds = ['id' => $financialTrxn->id]; + CRM_Financial_BAO_FinancialItem::create($addFinancialEntry, NULL, $trxnIds); + } + } + return $financialTrxn; + } + + /** + * @param int $contributionId + * @param array $trxnData + * @param int $participantId + * + * @return \CRM_Core_BAO_FinancialTrxn + */ + public static function recordPayment($contributionId, $trxnData, $participantId) { + list($contributionDAO, $params) = self::getContributionAndParamsInFormatForRecordFinancialTransaction($contributionId); + + if (!$participantId) { + $participantId = CRM_Core_DAO::getFieldValue('CRM_Event_DAO_ParticipantPayment', $contributionId, 'participant_id', 'contribution_id'); + } + + $trxnData['trxn_date'] = !empty($trxnData['trxn_date']) ? $trxnData['trxn_date'] : date('YmdHis'); + $params['payment_instrument_id'] = CRM_Utils_Array::value('payment_instrument_id', $trxnData, CRM_Utils_Array::value('payment_instrument_id', $params)); + + $paidStatus = CRM_Core_PseudoConstant::getKey('CRM_Financial_DAO_FinancialItem', 'status_id', 'Paid'); + $arAccountId = CRM_Contribute_PseudoConstant::getRelationalFinancialAccount($contributionDAO->financial_type_id, 'Accounts Receivable Account is'); + $completedStatusId = CRM_Core_PseudoConstant::getKey('CRM_Contribute_BAO_Contribution', 'contribution_status_id', 'Completed'); + + $params['partial_payment_total'] = $contributionDAO->total_amount; + $params['partial_amount_to_pay'] = $trxnData['total_amount']; + $trxnData['net_amount'] = !empty($trxnData['net_amount']) ? $trxnData['net_amount'] : $trxnData['total_amount']; + $params['pan_truncation'] = CRM_Utils_Array::value('pan_truncation', $trxnData); + $params['card_type_id'] = CRM_Utils_Array::value('card_type_id', $trxnData); + $params['check_number'] = CRM_Utils_Array::value('check_number', $trxnData); + + // record the entry + $financialTrxn = CRM_Contribute_BAO_Contribution::recordFinancialAccounts($params, $trxnData); + $toFinancialAccount = $arAccountId; + $trxnId = CRM_Core_BAO_FinancialTrxn::getBalanceTrxnAmt($contributionId, $contributionDAO->financial_type_id); + if (!empty($trxnId)) { + $trxnId = $trxnId['trxn_id']; + } + elseif (!empty($contributionDAO->payment_instrument_id)) { + $trxnId = CRM_Financial_BAO_FinancialTypeAccount::getInstrumentFinancialAccount($contributionDAO->payment_instrument_id); + } + else { + $relationTypeId = key(CRM_Core_PseudoConstant::accountOptionValues('financial_account_type', NULL, " AND v.name LIKE 'Asset' ")); + $queryParams = [1 => [$relationTypeId, 'Integer']]; + $trxnId = CRM_Core_DAO::singleValueQuery("SELECT id FROM civicrm_financial_account WHERE is_default = 1 AND financial_account_type_id = %1", $queryParams); + } + + // update statuses + // criteria for updates contribution total_amount == financial_trxns of partial_payments + $sql = "SELECT SUM(ft.total_amount) as sum_of_payments, SUM(ft.net_amount) as net_amount_total +FROM civicrm_financial_trxn ft +LEFT JOIN civicrm_entity_financial_trxn eft + ON (ft.id = eft.financial_trxn_id) +WHERE eft.entity_table = 'civicrm_contribution' + AND eft.entity_id = {$contributionId} + AND ft.to_financial_account_id != {$toFinancialAccount} + AND ft.status_id = {$completedStatusId} +"; + $query = CRM_Core_DAO::executeQuery($sql); + $query->fetch(); + $sumOfPayments = $query->sum_of_payments; + + // update statuses + if ($contributionDAO->total_amount == $sumOfPayments) { + // update contribution status and + // clean cancel info (if any) if prev. contribution was updated in case of 'Refunded' => 'Completed' + $contributionDAO->contribution_status_id = $completedStatusId; + $contributionDAO->cancel_date = 'null'; + $contributionDAO->cancel_reason = NULL; + $netAmount = !empty($trxnData['net_amount']) ? NULL : $trxnData['total_amount']; + $contributionDAO->net_amount = $query->net_amount_total + $netAmount; + $contributionDAO->fee_amount = $contributionDAO->total_amount - $contributionDAO->net_amount; + $contributionDAO->save(); + + //Change status of financial record too + $financialTrxn->status_id = $completedStatusId; + $financialTrxn->save(); + + // note : not using the self::add method, + // the reason because it performs 'status change' related code execution for financial records + // which in 'Partial Paid' => 'Completed' is not useful, instead specific financial record updates + // are coded below i.e. just updating financial_item status to 'Paid' + + if ($participantId) { + // update participant status + $participantStatuses = CRM_Event_PseudoConstant::participantStatus(); + $ids = CRM_Event_BAO_Participant::getParticipantIds($contributionId); + foreach ($ids as $val) { + $participantUpdate['id'] = $val; + $participantUpdate['status_id'] = array_search('Registered', $participantStatuses); + CRM_Event_BAO_Participant::add($participantUpdate); + } + } + + // Remove this - completeOrder does it. + CRM_Contribute_BAO_Contribution::updateMembershipBasedOnCompletionOfContribution( + $contributionDAO, + $contributionId, + $trxnData['trxn_date'] + ); + + // update financial item statuses + $baseTrxnId = CRM_Core_BAO_FinancialTrxn::getFinancialTrxnId($contributionId); + $sqlFinancialItemUpdate = " +UPDATE civicrm_financial_item fi + LEFT JOIN civicrm_entity_financial_trxn eft + ON (eft.entity_id = fi.id AND eft.entity_table = 'civicrm_financial_item') +SET status_id = {$paidStatus} +WHERE eft.financial_trxn_id IN ({$trxnId}, {$baseTrxnId['financialTrxnId']}) +"; + CRM_Core_DAO::executeQuery($sqlFinancialItemUpdate); + } + return $financialTrxn; + } + + /** + * The recordFinancialTransactions function has capricious requirements for input parameters - load them. + * + * The function needs rework but for now we need to give it what it wants. + * + * @param int $contributionId + * + * @return array + */ + protected static function getContributionAndParamsInFormatForRecordFinancialTransaction($contributionId) { + $getInfoOf['id'] = $contributionId; + $defaults = []; + $contributionDAO = CRM_Contribute_BAO_Contribution::retrieve($getInfoOf, $defaults, CRM_Core_DAO::$_nullArray); + + // build params for recording financial trxn entry + $params['contribution'] = $contributionDAO; + $params = array_merge($defaults, $params); + $params['skipLineItem'] = TRUE; + return [$contributionDAO, $params]; + } + + /** + * Does this payment complete the contribution + * + * @param int $contributionID + * @param float $paymentAmount + * + * @return bool + */ + protected static function isPaymentCompletesContribution($contributionID, $paymentAmount) { + $outstandingBalance = CRM_Contribute_BAO_Contribution::getContributionBalance($contributionID); + $cmp = bccomp($paymentAmount, $outstandingBalance, 5); + return ($cmp == 0 || $cmp == 1); + } + } diff --git a/civicrm/CRM/Grant/Form/Search.php b/civicrm/CRM/Grant/Form/Search.php index 2f52f3e3b6..5981f0d213 100644 --- a/civicrm/CRM/Grant/Form/Search.php +++ b/civicrm/CRM/Grant/Form/Search.php @@ -89,7 +89,6 @@ class CRM_Grant_Form_Search extends CRM_Core_Form_Search { $this->_actionButtonName = $this->getButtonName('next', 'action'); $this->_done = FALSE; - $this->defaults = array(); $this->loadStandardSearchOptionsFromUrl(); $this->loadFormValues(); diff --git a/civicrm/CRM/Logging/Schema.php b/civicrm/CRM/Logging/Schema.php index daf6df9a05..c540c93fbf 100644 --- a/civicrm/CRM/Logging/Schema.php +++ b/civicrm/CRM/Logging/Schema.php @@ -363,12 +363,22 @@ AND (TABLE_NAME LIKE 'log_civicrm_%' $nonStandardTableNameString ) * @return array */ public function getIndexesForTable($table) { - return CRM_Core_DAO::executeQuery(" - SELECT constraint_name - FROM information_schema.key_column_usage - WHERE table_schema = %2 AND table_name = %1", + $indexes = []; + $result = CRM_Core_DAO::executeQuery(" + SELECT constraint_name AS index_name + FROM information_schema.key_column_usage + WHERE table_schema = %2 AND table_name = %1 + UNION + SELECT index_name AS index_name + FROM information_schema.statistics + WHERE table_schema = %2 AND table_name = %1 + ", array(1 => array($table, 'String'), 2 => array($this->db, 'String')) - )->fetchAll(); + ); + while ($result->fetch()) { + $indexes[] = $result->index_name; + } + return $indexes; } /** @@ -597,9 +607,20 @@ WHERE table_schema IN ('{$this->db}', '{$civiDB}')"; 'EXTRA' => $dao->EXTRA, ); if (($first = strpos($dao->COLUMN_TYPE, '(')) != 0) { - \Civi::$statics[__CLASS__]['columnSpecs'][$dao->TABLE_NAME][$dao->COLUMN_NAME]['LENGTH'] = substr( - $dao->COLUMN_TYPE, $first, strpos($dao->COLUMN_TYPE, ')') + // this extracts the value between parentheses after the column type. + // it could be the column length, i.e. "int(8)", "decimal(20,2)") + // or the permitted values of an enum (e.g. "enum('A','B')") + $parValue = substr( + $dao->COLUMN_TYPE, $first + 1, strpos($dao->COLUMN_TYPE, ')') - $first - 1 ); + if (strpos($parValue, "'") === FALSE) { + // no quote in value means column length + \Civi::$statics[__CLASS__]['columnSpecs'][$dao->TABLE_NAME][$dao->COLUMN_NAME]['LENGTH'] = $parValue; + } + else { + // single quote means enum permitted values + \Civi::$statics[__CLASS__]['columnSpecs'][$dao->TABLE_NAME][$dao->COLUMN_NAME]['ENUM_VALUES'] = $parValue; + } } } } @@ -639,6 +660,12 @@ WHERE table_schema IN ('{$this->db}', '{$civiDB}')"; // if data-type is different, surely consider the column $diff['MODIFY'][] = $col; } + elseif ($civiTableSpecs[$col]['DATA_TYPE'] == 'enum' && + CRM_Utils_Array::value('ENUM_VALUES', $civiTableSpecs[$col]) != CRM_Utils_Array::value('ENUM_VALUES', $logTableSpecs[$col]) + ) { + // column is enum and the permitted values have changed + $diff['MODIFY'][] = $col; + } elseif ($civiTableSpecs[$col]['IS_NULLABLE'] != CRM_Utils_Array::value('IS_NULLABLE', $logTableSpecs[$col]) && $logTableSpecs[$col]['IS_NULLABLE'] == 'NO' ) { @@ -858,7 +885,11 @@ COLS; foreach ($columns as $column) { $tableExceptions = array_key_exists('exceptions', $this->logTableSpec[$table]) ? $this->logTableSpec[$table]['exceptions'] : array(); // ignore modified_date changes - if ($column != 'modified_date' && !in_array($column, $tableExceptions)) { + $tableExceptions[] = 'modified_date'; + // exceptions may be provided with or without backticks + $excludeColumn = in_array($column, $tableExceptions) || + in_array(str_replace('`', '', $column), $tableExceptions); + if (!$excludeColumn) { $cond[] = "IFNULL(OLD.$column,'') <> IFNULL(NEW.$column,'')"; } } diff --git a/civicrm/CRM/Mailing/Event/BAO/Reply.php b/civicrm/CRM/Mailing/Event/BAO/Reply.php index 31f2bae2c3..3bfc007104 100644 --- a/civicrm/CRM/Mailing/Event/BAO/Reply.php +++ b/civicrm/CRM/Mailing/Event/BAO/Reply.php @@ -119,6 +119,7 @@ class CRM_Mailing_Event_BAO_Reply extends CRM_Mailing_Event_DAO_Reply { $contacts = CRM_Contact_BAO_Contact::getTableName(); $domain_id = CRM_Core_Config::domainID(); $domainValues = civicrm_api3('Domain', 'get', array('sequential' => 1, 'id' => $domain_id)); + $fromEmail = CRM_Core_BAO_Domain::getNoReplyEmailAddress(); $eq = new CRM_Core_DAO(); $eq->query("SELECT $contacts.display_name as display_name, @@ -145,10 +146,16 @@ class CRM_Mailing_Event_BAO_Reply extends CRM_Mailing_Event_DAO_Reply { // to the forward goes to the sender of the reply $parsed->setHeader('Reply-To', $replyto instanceof ezcMailAddress ? $replyto : $parsed->from->__toString()); + // Using the original from address may not be permitted by the mailer. + $fromName = empty($parsed->from->name) ? $parsed->from->email : "{$parsed->from->name} ({$parsed->from->email})"; + $parsed->from = new ezcMailAddress($fromEmail, $fromName); + // CRM-17754 Include re-sent headers to indicate that we have forwarded on the email $domainEmail = $domainValues['values'][0]['from_email']; $parsed->setHeader('Resent-From', $domainEmail); $parsed->setHeader('Resent-Date', date('r')); + // Rewrite any invalid Return-Path headers. + $parsed->setHeader('Return-Path', $fromEmail); // $h must be an array, so we can't use generateHeaders()'s result, // but we have to regenerate the headers because we changed To @@ -156,11 +163,6 @@ class CRM_Mailing_Event_BAO_Reply extends CRM_Mailing_Event_DAO_Reply { $h = $parsed->headers->getCaseSensitiveArray(); $b = $parsed->generateBody(); - // strip Return-Path of possible bounding brackets, CRM-4502 - if (!empty($h['Return-Path'])) { - $h['Return-Path'] = trim($h['Return-Path'], '<>'); - } - // FIXME: ugly hack - find the first MIME boundary in // the body and make the boundary in the header match it $ct = $h['Content-Type']; @@ -173,19 +175,14 @@ class CRM_Mailing_Event_BAO_Reply extends CRM_Mailing_Event_DAO_Reply { } } else { - if (empty($eq->display_name)) { - $from = $eq->email; - } - else { - $from = "\"{$eq->display_name}\" <{$eq->email}>"; - } + $fromName = empty($eq->display_name) ? $eq->email : "{$eq->display_name} ({$eq->email})"; $message = new Mail_mime("\n"); $headers = array( 'Subject' => "Re: {$mailing->subject}", 'To' => $mailing->replyto_email, - 'From' => $from, + 'From' => "\"$fromName\" <$fromEmail>", 'Reply-To' => empty($replyto) ? $eq->email : $replyto, 'Return-Path' => CRM_Core_BAO_Domain::getNoReplyEmailAddress(), // CRM-17754 Include re-sent headers to indicate that we have forwarded on the email diff --git a/civicrm/CRM/Mailing/Selector/Search.php b/civicrm/CRM/Mailing/Selector/Search.php index 5621f89191..51f41f469d 100644 --- a/civicrm/CRM/Mailing/Selector/Search.php +++ b/civicrm/CRM/Mailing/Selector/Search.php @@ -389,7 +389,7 @@ class CRM_Mailing_Selector_Search extends CRM_Core_Selector_Base implements CRM_ * @return mixed */ public function alphabetQuery() { - return $this->_query->searchQuery(NULL, NULL, NULL, FALSE, FALSE, TRUE); + return $this->_query->alphabetQuery(); } /** diff --git a/civicrm/CRM/Member/BAO/Membership.php b/civicrm/CRM/Member/BAO/Membership.php index 00548c146e..cbc07cf2b6 100644 --- a/civicrm/CRM/Member/BAO/Membership.php +++ b/civicrm/CRM/Member/BAO/Membership.php @@ -94,7 +94,6 @@ class CRM_Member_BAO_Membership extends CRM_Member_DAO_Membership { $membership->id = $id; $membership->save(); - $membership->free(); if (empty($membership->contact_id) || empty($membership->status_id)) { // this means we are in renewal mode and are just updating the membership @@ -545,8 +544,6 @@ class CRM_Member_BAO_Membership extends CRM_Member_DAO_Membership { $defaults['active'] = TRUE; } - $membership->free(); - return $membership; } @@ -702,7 +699,6 @@ INNER JOIN civicrm_membership_type type ON ( type.id = membership.membership_ty self::deleteRelatedMemberships($membership->id); self::deleteMembership($membership->id); } - $membership->free(); } /** @@ -1184,7 +1180,6 @@ AND civicrm_membership.is_test = %2"; $memberDAO->end_date = CRM_Utils_Date::isoToMysql($memberDAO->end_date); $memberDAO->save(); CRM_Core_DAO::storeValues($memberDAO, $currentMembership); - $memberDAO->free(); $currentMembership['is_current_member'] = CRM_Core_DAO::getFieldValue( 'CRM_Member_DAO_MembershipStatus', @@ -1277,10 +1272,8 @@ SELECT c.contribution_page_id as pageID $relatedMembership->id = $membership->id; $relatedMembership->copyValues($params); $relatedMembership->save(); - $relatedMembership->free(); } - $membership->free(); } /** @@ -1407,7 +1400,6 @@ WHERE civicrm_membership.contact_id = civicrm_contact.id $nestedRelMembership->id = $membership->owner_membership_id; $nestedRelMembership->contact_id = $cid; $nestedRelationship = $nestedRelMembership->find(TRUE); - $nestedRelMembership->free(); } if (!$nestedRelationship) { $relatedContacts[$cid] = $status; @@ -1610,7 +1602,6 @@ FROM civicrm_membership_type $membershipTypeValues[$dao->id][$mtField] = $dao->$mtField; } } - $dao->free(); CRM_Utils_Hook::membershipTypeValues($form, $membershipTypeValues); @@ -2168,7 +2159,6 @@ INNER JOIN civicrm_contact contact ON ( contact.id = membership.contact_id AND ]); $count++; } - $deceasedDAO->free(); return $count; } @@ -2279,7 +2269,6 @@ WHERE civicrm_membership.is_test = 0 while ($dao1->fetch()) { self::processOverriddenUntilDateMembership($dao1); } - $dao1->free(); $query = $baseQuery . " AND civicrm_membership.is_override IS NULL AND civicrm_membership.status_id NOT IN (%1, %2, %3, %4) @@ -2351,7 +2340,6 @@ WHERE civicrm_membership.is_test = 0 $updateCount++; } } - $dao2->free(); $result['is_error'] = 0; $result['messages'] = ts('Processed %1 membership records. Updated %2 records.', array( 1 => $processCount, diff --git a/civicrm/CRM/Member/BAO/MembershipLog.php b/civicrm/CRM/Member/BAO/MembershipLog.php index 686183c10b..3754427676 100644 --- a/civicrm/CRM/Member/BAO/MembershipLog.php +++ b/civicrm/CRM/Member/BAO/MembershipLog.php @@ -46,7 +46,6 @@ class CRM_Member_BAO_MembershipLog extends CRM_Member_DAO_MembershipLog { $membershipLog = new CRM_Member_DAO_MembershipLog(); $membershipLog->copyValues($params); $membershipLog->save(); - $membershipLog->free(); return $membershipLog; } diff --git a/civicrm/CRM/Member/BAO/MembershipStatus.php b/civicrm/CRM/Member/BAO/MembershipStatus.php index 30e00ec715..0f7f8ae419 100644 --- a/civicrm/CRM/Member/BAO/MembershipStatus.php +++ b/civicrm/CRM/Member/BAO/MembershipStatus.php @@ -212,7 +212,6 @@ class CRM_Member_BAO_MembershipStatus extends CRM_Member_DAO_MembershipStatus { } $membershipStatus->delete(); CRM_Member_PseudoConstant::flush('membershipStatus'); - $membershipStatus->free(); } /** @@ -361,8 +360,6 @@ class CRM_Member_BAO_MembershipStatus extends CRM_Member_DAO_MembershipStatus { } //end fetch - $membershipStatus->free(); - //we bundle the arguments into an array as we can't pass 8 variables to the hook otherwise // the membership array might contain the pre-altered settings so we don't want to merge this $arguments = array( @@ -394,7 +391,6 @@ class CRM_Member_BAO_MembershipStatus extends CRM_Member_DAO_MembershipStatus { while ($membershipStatus->fetch()) { $statusIds[] = $membershipStatus->id; } - $membershipStatus->free(); return $statusIds; } diff --git a/civicrm/CRM/Member/BAO/MembershipType.php b/civicrm/CRM/Member/BAO/MembershipType.php index 1d119d742e..6438cff3c0 100644 --- a/civicrm/CRM/Member/BAO/MembershipType.php +++ b/civicrm/CRM/Member/BAO/MembershipType.php @@ -281,7 +281,6 @@ class CRM_Member_BAO_MembershipType extends CRM_Member_DAO_MembershipType { while ($membershipType->fetch()) { $membershipTypes[$membershipType->id] = $membershipType->name; } - $membershipType->free(); return $membershipTypes; } @@ -300,7 +299,6 @@ class CRM_Member_BAO_MembershipType extends CRM_Member_DAO_MembershipType { $membershipType->id = $membershipTypeId; if ($membershipType->find(TRUE)) { CRM_Core_DAO::storeValues($membershipType, $membershipTypeDetails); - $membershipType->free(); return $membershipTypeDetails; } else { diff --git a/civicrm/CRM/Member/Form/Search.php b/civicrm/CRM/Member/Form/Search.php index ed2894040a..3f98247a5c 100644 --- a/civicrm/CRM/Member/Form/Search.php +++ b/civicrm/CRM/Member/Form/Search.php @@ -82,8 +82,6 @@ class CRM_Member_Form_Search extends CRM_Core_Form_Search { $this->_done = FALSE; - $this->defaults = array(); - $this->loadStandardSearchOptionsFromUrl(); // get user submitted values diff --git a/civicrm/CRM/Member/Page/DashBoard.php b/civicrm/CRM/Member/Page/DashBoard.php index 13510225ec..b9bf7885fd 100644 --- a/civicrm/CRM/Member/Page/DashBoard.php +++ b/civicrm/CRM/Member/Page/DashBoard.php @@ -181,84 +181,6 @@ class CRM_Member_Page_DashBoard extends CRM_Core_Page { $status = CRM_Member_BAO_MembershipStatus::getMembershipStatusCurrent(); $status = implode(',', $status); - /*@codingStandardsIgnoreStart - Disabled for lack of appropriate search - - The Membership search isn't able to properly filter by join or renewal events. - Until that works properly, the subtotals shouldn't get links. - - foreach ($membershipSummary as $typeID => $details) { - foreach ($details as $key => $value) { - switch ($key) { - case 'premonth': - $membershipSummary[$typeID][$key]['new']['url'] = CRM_Utils_System::url('civicrm/member/search', "reset=1&force=1&status=$status&type=$typeID&join=$preMonth&joinEnd=$preMonthEnd&start=$preMonth&end=$preMonthEnd"); - $membershipSummary[$typeID][$key]['renew']['url'] = CRM_Utils_System::url('civicrm/member/search', "reset=1&force=1&status=$status&type=$typeID&joinEnd=$prePreMonthEnd&start=$preMonth&end=$preMonthEnd"); - $membershipSummary[$typeID][$key]['total']['url'] = CRM_Utils_System::url('civicrm/member/search', "reset=1&force=1&status=$status&type=$typeID&start=$preMonth&end=$preMonthEnd"); - break; - - case 'month': - $membershipSummary[$typeID][$key]['new']['url'] = CRM_Utils_System::url('civicrm/member/search', "reset=1&force=1&status=$status&type=$typeID&join=$monthStart&joinEnd=$ymd&start=$monthStart&end=$ymd"); - $membershipSummary[$typeID][$key]['renew']['url'] = CRM_Utils_System::url('civicrm/member/search', "reset=1&force=1&status=$status&type=$typeID&joinEnd=$preMonthStart&start=$monthStart&end=$ymd"); - $membershipSummary[$typeID][$key]['total']['url'] = CRM_Utils_System::url('civicrm/member/search', "reset=1&force=1&status=$status&type=$typeID&start=$monthStart&end=$ymd"); - break; - - case 'year': - $membershipSummary[$typeID][$key]['new']['url'] = CRM_Utils_System::url('civicrm/member/search', "reset=1&force=1&status=$status&type=$typeID&join=$yearStart&joinEnd=$ymd&start=$yearStart&end=$ymd"); - $membershipSummary[$typeID][$key]['renew']['url'] = CRM_Utils_System::url('civicrm/member/search', "reset=1&force=1&status=$status&type=$typeID&joinEnd=$preYearStart&start=$yearStart&end=$ymd"); - $membershipSummary[$typeID][$key]['total']['url'] = CRM_Utils_System::url('civicrm/member/search', "reset=1&force=1&status=$status&type=$typeID&start=$yearStart&end=$ymd"); - break; - - case 'current': - $membershipSummary[$typeID][$key]['total']['url'] = CRM_Utils_System::url('civicrm/member/search', "reset=1&force=1&status=$status&type=$typeID"); - break; - - case 'total': - if (!$isCurrentMonth) { - $membershipSummary[$typeID][$key]['total']['url'] = CRM_Utils_System::url('civicrm/member/search', - "reset=1&force=1&start=&end=$ymd&status=$status&type=$typeID" - ); - } - else { - $membershipSummary[$typeID][$key]['total']['url'] = CRM_Utils_System::url('civicrm/member/search', - "reset=1&force=1&status=$status" - ); - } - break; - - //LCD add owner urls - - case 'premonth_owner': - $membershipSummary[$typeID][$key]['premonth_owner']['url'] = CRM_Utils_System::url('civicrm/member/search', "reset=1&force=1&status=$status&type=$typeID&start=$preMonth&end=$preMonthEnd&owner=1"); - break; - - case 'month_owner': - $membershipSummary[$typeID][$key]['month_owner']['url'] = CRM_Utils_System::url('civicrm/member/search', "reset=1&force=1&status=$status&type=$typeID&start=$monthStart&end=$ymd&owner=1"); - break; - - case 'year_owner': - $membershipSummary[$typeID][$key]['year_owner']['url'] = CRM_Utils_System::url('civicrm/member/search', "reset=1&force=1&status=$status&type=$typeID&start=$yearStart&end=$ymd&owner=1"); - break; - - case 'current_owner': - $membershipSummary[$typeID][$key]['current_owner']['url'] = CRM_Utils_System::url('civicrm/member/search', "reset=1&force=1&status=$status&type=$typeID&owner=1"); - break; - - case 'total_owner': - if (!$isCurrentMonth) { - $membershipSummary[$typeID][$key]['total_owner']['url'] = CRM_Utils_System::url('civicrm/member/search', "reset=1&force=1&start=&end=$ymd&status=$status&type=$typeID&owner=1"); - } - else { - $membershipSummary[$typeID][$key]['total_owner']['url'] = CRM_Utils_System::url('civicrm/member/search', "reset=1&force=1&status=$status&owner=1"); - } - break; - //LCD end - } - } - } - @codingStandardsIgnoreEnd */ - - // Temporary replacement for current totals column - foreach ($membershipSummary as $typeID => $details) { if (!$isCurrentMonth) { $membershipSummary[$typeID]['total']['total']['url'] = CRM_Utils_System::url('civicrm/member/search', @@ -306,65 +228,38 @@ class CRM_Member_Page_DashBoard extends CRM_Core_Page { $totalCount['premonth']['new'] = array( 'count' => $newCountPreMonth, - //'url' => CRM_Utils_System::url('civicrm/activity/search', - // "reset=1&force=1&signupType=1&dateLow=$preMonth&dateHigh=$preMonthEnd" - //), ); $totalCount['premonth']['renew'] = array( 'count' => $renewCountPreMonth, - //'url' => CRM_Utils_System::url('civicrm/activity/search', - // "reset=1&force=1&signupType=2&dateLow=$preMonth&dateHigh=$preMonthEnd" - //), ); $totalCount['premonth']['total'] = array( 'count' => $totalCountPreMonth, - //'url' => CRM_Utils_System::url('civicrm/activity/search', - // "reset=1&force=1&signupType=3&dateLow=$preMonth&dateHigh=$preMonthEnd" - //), ); $totalCount['month']['new'] = array( 'count' => $newCountMonth, - //'url' => CRM_Utils_System::url('civicrm/activity/search', - // "reset=1&force=1&signupType=1&dateLow=$monthStart&dateHigh=$ymd" - //), ); $totalCount['month']['renew'] = array( 'count' => $renewCountMonth, - //'url' => CRM_Utils_System::url('civicrm/activity/search', - // "reset=1&force=1&signupType=2&dateLow=$monthStart&dateHigh=$ymd" - //), ); $totalCount['month']['total'] = array( 'count' => $totalCountMonth, - //'url' => CRM_Utils_System::url('civicrm/activity/search', - // "reset=1&force=1&signupType=3&dateLow=$monthStart&dateHigh=$ymd" - //), ); $totalCount['year']['new'] = array( 'count' => $newCountYear, - //'url' => CRM_Utils_System::url('civicrm/activity/search', - // "reset=1&force=1&signupType=1&dateLow=$yearStart&dateHigh=$ymd" - //), ); $totalCount['year']['renew'] = array( 'count' => $renewCountYear, - //'url' => CRM_Utils_System::url('civicrm/activity/search', - // "reset=1&force=1&signupType=2&dateLow=$yearStart&dateHigh=$ymd" - //), ); $totalCount['year']['total'] = array( 'count' => $totalCountYear, - //'url' => CRM_Utils_System::url('civicrm/activity/search', - // "reset=1&force=1&signupType=3&dateLow=$yearStart&dateHigh=$ymd" - //), ); $totalCount['current']['total'] = array( diff --git a/civicrm/CRM/Member/Selector/Search.php b/civicrm/CRM/Member/Selector/Search.php index a52b96b4c9..f46782627a 100644 --- a/civicrm/CRM/Member/Selector/Search.php +++ b/civicrm/CRM/Member/Selector/Search.php @@ -543,7 +543,7 @@ class CRM_Member_Selector_Search extends CRM_Core_Selector_Base implements CRM_C * @return mixed */ public function alphabetQuery() { - return $this->_query->searchQuery(NULL, NULL, NULL, FALSE, FALSE, TRUE); + return $this->_query->alphabetQuery(); } /** diff --git a/civicrm/CRM/Pledge/Form/Search.php b/civicrm/CRM/Pledge/Form/Search.php index 33291408d4..0073fabcf5 100644 --- a/civicrm/CRM/Pledge/Form/Search.php +++ b/civicrm/CRM/Pledge/Form/Search.php @@ -71,7 +71,6 @@ class CRM_Pledge_Form_Search extends CRM_Core_Form_Search { $this->_actionButtonName = $this->getButtonName('next', 'action'); $this->_done = FALSE; - $this->defaults = array(); $this->loadStandardSearchOptionsFromUrl(); @@ -314,24 +313,6 @@ class CRM_Pledge_Form_Search extends CRM_Core_Form_Search { $this->addFormRule(array('CRM_Pledge_Form_Search', 'formRule')); } - /** - * Global validation rules for the form. - * - * @param array $fields - * Posted values of the form. - * - * @return array|bool - */ - public static function formRule($fields) { - $errors = array(); - - if (!empty($errors)) { - return $errors; - } - - return TRUE; - } - /** * Set the default form values. * diff --git a/civicrm/CRM/Profile/Form.php b/civicrm/CRM/Profile/Form.php index 330b50890a..9b5beb25cf 100644 --- a/civicrm/CRM/Profile/Form.php +++ b/civicrm/CRM/Profile/Form.php @@ -179,6 +179,104 @@ class CRM_Profile_Form extends CRM_Core_Form { protected $_currentUserID = NULL; protected $_session = NULL; + /** + * Check for any duplicates. + * + * Depending on form settings & usage scenario we potentially use the found id, + * create links to found ids or add an error. + * + * @param array $errors + * @param array $fields + * @param CRM_Profile_Form $form + * + * @return array + */ + protected static function handleDuplicateChecking(&$errors, $fields, $form) { + if ($form->_mode == CRM_Profile_Form::MODE_CREATE) { + // fix for CRM-2888 + $exceptions = []; + } + else { + // for edit mode we need to allow our own record to be a dupe match! + $exceptions = [$form->_session->get('userID')]; + } + $contactType = CRM_Core_BAO_UFGroup::getContactType($form->_gid); + // If all profile fields is of Contact Type then consider + // profile is of Individual type(default). + if (!$contactType) { + $contactType = 'Individual'; + } + + $ids = CRM_Contact_BAO_Contact::getDuplicateContacts( + $fields, $contactType, + ($form->_context === 'dialog' ? 'Supervised' : 'Unsupervised'), + $exceptions, + FALSE, + $form->_ruleGroupID + ); + if ($ids) { + if ($form->_isUpdateDupe == 2) { + CRM_Core_Session::setStatus(ts('Note: this contact may be a duplicate of an existing record.'), ts('Possible Duplicate Detected'), 'alert'); + } + elseif ($form->_isUpdateDupe == 1) { + $form->_id = $ids[0]; + } + else { + if ($form->_context == 'dialog') { + $contactLinks = CRM_Contact_BAO_Contact_Utils::formatContactIDSToLinks($ids, TRUE, TRUE); + + $duplicateContactsLinks = '<div class="matching-contacts-found">'; + $duplicateContactsLinks .= ts('One matching contact was found. ', [ + 'count' => count($contactLinks['rows']), + 'plural' => '%count matching contacts were found.<br />', + ]); + if ($contactLinks['msg'] == 'view') { + $duplicateContactsLinks .= ts('You can View the existing contact.', [ + 'count' => count($contactLinks['rows']), + 'plural' => 'You can View the existing contacts.', + ]); + } + else { + $duplicateContactsLinks .= ts('You can View or Edit the existing contact.', [ + 'count' => count($contactLinks['rows']), + 'plural' => 'You can View or Edit the existing contacts.', + ]); + } + $duplicateContactsLinks .= '</div>'; + $duplicateContactsLinks .= '<table class="matching-contacts-actions">'; + $row = ''; + for ($i = 0; $i < count($contactLinks['rows']); $i++) { + $row .= ' <tr> '; + $row .= ' <td class="matching-contacts-name"> '; + $row .= $contactLinks['rows'][$i]['display_name']; + $row .= ' </td>'; + $row .= ' <td class="matching-contacts-email"> '; + $row .= $contactLinks['rows'][$i]['primary_email']; + $row .= ' </td>'; + $row .= ' <td class="action-items"> '; + $row .= $contactLinks['rows'][$i]['view'] . ' '; + $row .= $contactLinks['rows'][$i]['edit']; + $row .= ' </td>'; + $row .= ' </tr> '; + } + + $duplicateContactsLinks .= $row . '</table>'; + $duplicateContactsLinks .= "If you're sure this record is not a duplicate, click the 'Save Matching Contact' button below."; + + $errors['_qf_default'] = $duplicateContactsLinks; + + // let smarty know that there are duplicates + $template = CRM_Core_Smarty::singleton(); + $template->assign('isDuplicate', 1); + } + else { + $errors['_qf_default'] = ts('A record already exists with the same information.'); + } + } + } + return $errors; + } + /** * Explicitly declare the entity api name. */ @@ -895,16 +993,21 @@ class CRM_Profile_Form extends CRM_Core_Form { public static function formRule($fields, $files, $form) { CRM_Utils_Hook::validateProfile($form->_ufGroup['name']); - $errors = array(); // if no values, return if (empty($fields)) { return TRUE; } + $errors = []; $register = NULL; // hack we use a -1 in options to indicate that its registration + // ... and I can't remove that comment because even though it's clear as mud + // perhaps someone will find it helpful in the absence of ANY OTHER EXPLANATION + // as to what it means.... if ($form->_id) { + // @todo - wonder if it ever occurred to someone that if they didn't document this param + // it might not be crystal clear why we have it.... $form->_isUpdateDupe = 1; } @@ -924,90 +1027,8 @@ class CRM_Profile_Form extends CRM_Core_Form { $fields['phone-Primary'] = $fields['phone-Primary-1']; } - $ctype = CRM_Core_BAO_UFGroup::getContactType($form->_gid); - // If all profile fields is of Contact Type then consider - // profile is of Individual type(default). - if (!$ctype) { - $ctype = 'Individual'; - } - - if ($form->_mode == CRM_Profile_Form::MODE_CREATE) { - // fix for CRM-2888 - $exceptions = array(); - } - else { - // for edit mode we need to allow our own record to be a dupe match! - $exceptions = array($form->_session->get('userID')); - } - - $ids = CRM_Contact_BAO_Contact::getDuplicateContacts( - $fields, $ctype, - ($form->_context === 'dialog' ? 'Supervised' : 'Unsupervised'), - $exceptions, - FALSE, - $form->_ruleGroupID - ); - if ($ids) { - if ($form->_isUpdateDupe == 2) { - CRM_Core_Session::setStatus(ts('Note: this contact may be a duplicate of an existing record.'), ts('Possible Duplicate Detected'), 'alert'); - } - elseif ($form->_isUpdateDupe == 1) { - if (!$form->_id) { - $form->_id = $ids[0]; - } - } - else { - if ($form->_context == 'dialog') { - $contactLinks = CRM_Contact_BAO_Contact_Utils::formatContactIDSToLinks($ids, TRUE, TRUE); - - $duplicateContactsLinks = '<div class="matching-contacts-found">'; - $duplicateContactsLinks .= ts('One matching contact was found. ', array( - 'count' => count($contactLinks['rows']), - 'plural' => '%count matching contacts were found.<br />', - )); - if ($contactLinks['msg'] == 'view') { - $duplicateContactsLinks .= ts('You can View the existing contact.', array( - 'count' => count($contactLinks['rows']), - 'plural' => 'You can View the existing contacts.', - )); - } - else { - $duplicateContactsLinks .= ts('You can View or Edit the existing contact.', array( - 'count' => count($contactLinks['rows']), - 'plural' => 'You can View or Edit the existing contacts.', - )); - } - $duplicateContactsLinks .= '</div>'; - $duplicateContactsLinks .= '<table class="matching-contacts-actions">'; - $row = ''; - for ($i = 0; $i < count($contactLinks['rows']); $i++) { - $row .= ' <tr> '; - $row .= ' <td class="matching-contacts-name"> '; - $row .= $contactLinks['rows'][$i]['display_name']; - $row .= ' </td>'; - $row .= ' <td class="matching-contacts-email"> '; - $row .= $contactLinks['rows'][$i]['primary_email']; - $row .= ' </td>'; - $row .= ' <td class="action-items"> '; - $row .= $contactLinks['rows'][$i]['view'] . ' '; - $row .= $contactLinks['rows'][$i]['edit']; - $row .= ' </td>'; - $row .= ' </tr> '; - } - - $duplicateContactsLinks .= $row . '</table>'; - $duplicateContactsLinks .= "If you're sure this record is not a duplicate, click the 'Save Matching Contact' button below."; - - $errors['_qf_default'] = $duplicateContactsLinks; - - // let smarty know that there are duplicates - $template = CRM_Core_Smarty::singleton(); - $template->assign('isDuplicate', 1); - } - else { - $errors['_qf_default'] = ts('A record already exists with the same information.'); - } - } + if (!$form->_id) { + self::handleDuplicateChecking($errors, $fields, $form); } } diff --git a/civicrm/CRM/Report/Form.php b/civicrm/CRM/Report/Form.php index 6fb50c2f6d..900a35d493 100644 --- a/civicrm/CRM/Report/Form.php +++ b/civicrm/CRM/Report/Form.php @@ -1577,7 +1577,7 @@ class CRM_Report_Form extends CRM_Core_Form { // CRM-16274 Determine if user has 'edit all contacts' or equivalent $permission = CRM_Core_Permission::getPermission(); - if ($permission == CRM_Core_Permission::EDIT && + if ($this->_instanceForm && $permission == CRM_Core_Permission::EDIT && $this->_add2groupSupported ) { $this->addElement('select', 'groups', ts('Group'), @@ -4758,7 +4758,7 @@ LEFT JOIN civicrm_contact {$field['alias']} ON {$field['alias']}.id = {$this->_a /** * Get a standard set of contact fields. - * + * @deprecated - use getColumns('Contact') instead * @return array */ public function getBasicContactFields() { @@ -5398,7 +5398,45 @@ LEFT JOIN civicrm_contact {$field['alias']} ON {$field['alias']}.id = {$this->_a 'is_filters' => TRUE, 'is_group_bys' => FALSE, ), + $options['prefix'] . 'external_identifier' => array( + 'title' => $options['prefix_label'] . ts('Contact identifier from external system'), + 'name' => 'external_identifier', + 'is_fields' => TRUE, + 'is_filters' => FALSE, + 'is_group_bys' => FALSE, + 'is_order_bys' => TRUE, + ), + $options['prefix'] . 'preferred_language' => array( + 'title' => $options['prefix_label'] . ts('Preferred Language'), + 'name' => 'preferred_language', + 'is_fields' => TRUE, + 'is_filters' => TRUE, + 'is_group_bys' => TRUE, + 'is_order_bys' => TRUE, + ), ); + foreach ([ + 'postal_greeting_display' => 'Postal Greeting', + 'email_greeting_display' => 'Email Greeting', + 'addressee_display' => 'Addressee', + ] as $field => $title) { + $spec[$options['prefix'] . $field] = array( + 'title' => $options['prefix_label'] . ts($title), + 'name' => $field, + 'is_fields' => TRUE, + 'is_filters' => FALSE, + 'is_group_bys' => FALSE, + ); + } + foreach (['do_not_email', 'do_not_phone', 'do_not_mail', 'do_not_sms', 'is_opt_out'] as $field) { + $spec[$options['prefix'] . $field] = [ + 'name' => $field, + 'type' => CRM_Utils_Type::T_BOOLEAN, + 'is_fields' => TRUE, + 'is_filters' => TRUE, + 'is_group_bys' => FALSE, + ]; + } $individualFields = array( $options['prefix'] . 'first_name' => array( 'name' => 'first_name', @@ -5468,6 +5506,20 @@ LEFT JOIN civicrm_contact {$field['alias']} ON {$field['alias']}.id = {$this->_a 'is_filters' => TRUE, 'is_group_bys' => FALSE, ), + $options['prefix'] . 'job_title' => array( + 'name' => 'job_title', + 'is_fields' => TRUE, + 'is_filters' => FALSE, + 'is_group_bys' => FALSE, + ), + $options['prefix'] . 'employer_id' => array( + 'title' => $options['prefix_label'] . ts('Current Employer'), + 'type' => CRM_Utils_Type::T_INT, + 'name' => 'employer_id', + 'is_fields' => TRUE, + 'is_filters' => FALSE, + 'is_group_bys' => TRUE, + ), ); if (!$options['contact_type'] || $options['contact_type'] === 'Individual') { $spec = array_merge($spec, $individualFields); diff --git a/civicrm/CRM/Report/Form/Case/Detail.php b/civicrm/CRM/Report/Form/Case/Detail.php index cf582f6c72..0a38995fcb 100644 --- a/civicrm/CRM/Report/Form/Case/Detail.php +++ b/civicrm/CRM/Report/Form/Case/Detail.php @@ -44,9 +44,9 @@ class CRM_Report_Form_Case_Detail extends CRM_Report_Form { protected $_includeCaseDetailExtra = FALSE; - protected $_caseDetailExtra = array(); + protected $_caseDetailExtra = []; - protected $_customGroupExtends = array('Case'); + protected $_customGroupExtends = ['Case']; protected $_caseTypeNameOrderBy = FALSE; @@ -60,253 +60,258 @@ class CRM_Report_Form_Case_Detail extends CRM_Report_Form { $this->rel_types[$relid] = $v['label_b_a']; } - $this->deleted_labels = array( + $this->deleted_labels = [ '' => ts('- select -'), 0 => ts('No'), 1 => ts('Yes'), - ); + ]; - $this->caseActivityTypes = array(); + $this->caseActivityTypes = []; foreach (CRM_Case_PseudoConstant::caseActivityType() as $typeDetail) { $this->caseActivityTypes[$typeDetail['id']] = $typeDetail['label']; } - $this->_columns = array( - 'civicrm_case' => array( + $this->_columns = [ + 'civicrm_case' => [ 'dao' => 'CRM_Case_DAO_Case', - 'fields' => array( - 'id' => array( + 'fields' => [ + 'id' => [ 'title' => ts('Case ID'), 'no_display' => TRUE, 'required' => TRUE, - ), - 'subject' => array( + ], + 'subject' => [ 'title' => ts('Subject'), 'required' => TRUE, - ), - 'start_date' => array( + ], + 'start_date' => [ 'title' => ts('Start Date'), 'type' => CRM_Utils_Type::T_DATE, - ), - 'end_date' => array( + ], + 'end_date' => [ 'title' => ts('End Date'), 'type' => CRM_Utils_Type::T_DATE, - ), - 'status_id' => array('title' => ts('Case Status')), - 'case_type_id' => array('title' => ts('Case Type')), - 'is_deleted' => array( + ], + 'status_id' => ['title' => ts('Case Status')], + 'case_type_id' => ['title' => ts('Case Type')], + 'is_deleted' => [ 'title' => ts('Deleted?'), 'default' => FALSE, 'type' => CRM_Utils_Type::T_INT, - ), - ), - 'filters' => array( - 'start_date' => array( + ], + ], + 'filters' => [ + 'start_date' => [ 'title' => ts('Start Date'), 'operatorType' => CRM_Report_Form::OP_DATE, 'type' => CRM_Utils_Type::T_DATE, - ), - 'end_date' => array( + ], + 'end_date' => [ 'title' => ts('End Date'), 'operatorType' => CRM_Report_Form::OP_DATE, 'type' => CRM_Utils_Type::T_DATE, - ), - 'status_id' => array( + ], + 'status_id' => [ 'title' => ts('Case Status'), 'type' => CRM_Utils_Type::T_INT, 'operatorType' => CRM_Report_Form::OP_MULTISELECT, 'options' => CRM_Case_BAO_Case::buildOptions('status_id', 'search'), - ), - 'case_type_id' => array( + ], + 'case_type_id' => [ 'title' => ts('Case Type'), 'type' => CRM_Utils_Type::T_INT, 'operatorType' => CRM_Report_Form::OP_MULTISELECT, 'options' => CRM_Case_BAO_Case::buildOptions('case_type_id', 'search'), - ), - 'is_deleted' => array( + ], + 'is_deleted' => [ 'title' => ts('Deleted?'), 'type' => CRM_Utils_Type::T_INT, 'operatorType' => CRM_Report_Form::OP_SELECT, 'options' => $this->deleted_labels, 'default' => 0, - ), - ), - 'order_bys' => array( - 'start_date' => array( + ], + ], + 'order_bys' => [ + 'start_date' => [ 'title' => ts('Start Date'), 'default_weight' => 1, - ), - 'end_date' => array( + ], + 'end_date' => [ 'title' => ts('End Date'), - ), - 'status_id' => array( + ], + 'status_id' => [ 'title' => ts('Status'), - ), - 'case_type_name' => array( + ], + ], + ], + 'civicrm_case_type' => [ + 'dao' => 'CRM_Case_DAO_Case', + 'order_bys' => [ + 'case_type_title' => [ 'title' => 'Case Type', - ), - ), - ), - 'civicrm_contact' => array( + 'name' => 'title', + ]] + ], + 'civicrm_contact' => [ 'dao' => 'CRM_Contact_DAO_Contact', - 'fields' => array( - 'client_sort_name' => array( + 'fields' => [ + 'client_sort_name' => [ 'name' => 'sort_name', 'title' => ts('Client Name'), 'required' => TRUE, - ), - 'id' => array( + ], + 'id' => [ 'no_display' => TRUE, 'required' => TRUE, - ), - ), - 'filters' => array( - 'sort_name' => array('title' => ts('Client Name')), - ), - ), - 'civicrm_relationship' => array( + ], + ], + 'filters' => [ + 'sort_name' => ['title' => ts('Client Name')], + ], + ], + 'civicrm_relationship' => [ 'dao' => 'CRM_Contact_DAO_Relationship', - 'fields' => array( - 'case_role' => array( + 'fields' => [ + 'case_role' => [ 'name' => 'relationship_type_id', 'title' => ts('Case Role(s)'), - ), - ), - 'filters' => array( - 'case_role' => array( + ], + ], + 'filters' => [ + 'case_role' => [ 'name' => 'relationship_type_id', 'title' => ts('Case Role(s)'), 'type' => CRM_Utils_Type::T_INT, 'operatorType' => CRM_Report_Form::OP_MULTISELECT, 'options' => $this->rel_types, - ), - 'is_active' => array( + ], + 'is_active' => [ 'title' => ts('Active Role?'), 'type' => CRM_Utils_Type::T_BOOLEAN, 'default' => TRUE, 'options' => CRM_Core_SelectValues::boolean(), - ), - ), - ), - 'civicrm_email' => array( + ], + ], + ], + 'civicrm_email' => [ 'dao' => 'CRM_Core_DAO_Email', - 'fields' => array( - 'email' => array( + 'fields' => [ + 'email' => [ 'title' => ts('Email'), 'no_repeat' => TRUE, - ), - ), + ], + ], 'grouping' => 'contact-fields', - ), - 'civicrm_phone' => array( + ], + 'civicrm_phone' => [ 'dao' => 'CRM_Core_DAO_Phone', - 'fields' => array( - 'phone' => array( + 'fields' => [ + 'phone' => [ 'title' => ts('Phone'), 'no_repeat' => TRUE, - ), - ), + ], + ], 'grouping' => 'contact-fields', - ), - 'civicrm_address' => array( + ], + 'civicrm_address' => [ 'dao' => 'CRM_Core_DAO_Address', - 'fields' => array( + 'fields' => [ 'street_address' => NULL, - 'state_province_id' => array( + 'state_province_id' => [ 'title' => ts('State/Province'), - ), - 'country_id' => array('title' => ts('Country')), - ), + ], + 'country_id' => ['title' => ts('Country')], + ], 'grouping' => 'contact-fields', - 'filters' => array( - 'country_id' => array( + 'filters' => [ + 'country_id' => [ 'title' => ts('Country'), 'type' => CRM_Utils_Type::T_INT, 'operatorType' => CRM_Report_Form::OP_MULTISELECT, 'options' => CRM_Core_PseudoConstant::country(), - ), - 'state_province_id' => array( + ], + 'state_province_id' => [ 'title' => ts('State/Province'), 'type' => CRM_Utils_Type::T_INT, 'operatorType' => CRM_Report_Form::OP_MULTISELECT, 'options' => CRM_Core_PseudoConstant::stateProvince(), - ), - ), - ), - 'civicrm_worldregion' => array( + ], + ], + ], + 'civicrm_worldregion' => [ 'dao' => 'CRM_Core_DAO_Worldregion', - 'filters' => array( - 'worldregion_id' => array( + 'filters' => [ + 'worldregion_id' => [ 'name' => 'id', 'title' => ts('World Region'), 'type' => CRM_Utils_Type::T_INT, 'operatorType' => CRM_Report_Form::OP_MULTISELECT, 'options' => CRM_Core_PseudoConstant::worldRegion(), - ), - ), - ), - 'civicrm_country' => array( + ], + ], + ], + 'civicrm_country' => [ 'dao' => 'CRM_Core_DAO_Country', - ), - 'civicrm_activity_last' => array( + ], + 'civicrm_activity_last' => [ 'dao' => 'CRM_Activity_DAO_Activity', - 'fields' => array( - 'last_activity_activity_subject' => array( + 'fields' => [ + 'last_activity_activity_subject' => [ 'name' => 'subject', 'title' => ts('Subject of the last activity in the case'), - ), - 'last_activity_activity_type' => array( + ], + 'last_activity_activity_type' => [ 'name' => 'activity_type_id', 'title' => ts('Activity type of the last activity'), - ), - 'last_activity_date_time' => array( + ], + 'last_activity_date_time' => [ 'name' => 'activity_date_time', 'title' => ts('Last Action Date'), 'operatorType' => CRM_Report_Form::OP_DATE, - ), - ), - 'filters' => array( - 'last_activity_date_time' => array( + ], + ], + 'filters' => [ + 'last_activity_date_time' => [ 'name' => 'activity_date_time', 'title' => ts('Last Action Date'), 'operatorType' => CRM_Report_Form::OP_DATE, - ), - ), + ], + ], 'alias' => 'civireport_activity_last', - ), - 'civicrm_activity_last_completed' => array( + ], + 'civicrm_activity_last_completed' => [ 'dao' => 'CRM_Activity_DAO_Activity', - 'fields' => array( - 'last_completed_activity_subject' => array( + 'fields' => [ + 'last_completed_activity_subject' => [ 'name' => 'subject', 'title' => ts('Subject of the last completed activity in the case'), - ), - 'last_completed_activity_type' => array( + ], + 'last_completed_activity_type' => [ 'name' => 'activity_type_id', 'title' => ts('Activity type of the last completed activity'), - ), - 'last_completed_date_time' => array( + ], + 'last_completed_date_time' => [ 'name' => 'activity_date_time', 'title' => ts('Last Completed Action Date'), 'operatorType' => CRM_Report_Form::OP_DATE, - ), - ), - 'filters' => array( - 'last_completed_date_time' => array( + ], + ], + 'filters' => [ + 'last_completed_date_time' => [ 'name' => 'activity_date_time', 'title' => ts('Last Completed Action Date'), 'operatorType' => CRM_Report_Form::OP_DATE, - ), - ), - ), - ); + ], + ], + ], + ]; - $this->_options = array( - 'my_cases' => array( + $this->_options = [ + 'my_cases' => [ 'title' => ts('My Cases'), 'type' => 'checkbox', - ), - ); + ], + ]; parent::__construct(); } @@ -320,27 +325,29 @@ class CRM_Report_Form_Case_Detail extends CRM_Report_Form { } public function caseDetailSpecialColumnsAdd() { - $elements = array(); + $elements = []; $elements[] = &$this->createElement('select', 'case_activity_all_dates', NULL, - array( + [ '' => ts('- select -'), - ) + $this->caseActivityTypes + ] + $this->caseActivityTypes ); $this->addGroup($elements, 'case_detail_extra'); - $this->_caseDetailExtra = array( - 'case_activity_all_dates' => array( + $this->_caseDetailExtra = [ + 'case_activity_all_dates' => [ 'title' => ts('List of all dates of activities of Type'), 'name' => 'activity_date_time', - ), - ); + ], + ]; $this->assign('caseDetailExtra', $this->_caseDetailExtra); } public function select() { - $select = array(); - $this->_columnHeaders = array(); + // @todo - get rid of this function & use parent. Use selectWhere to setthe clause for the + // few fields that need custom handling. + $select = []; + $this->_columnHeaders = []; foreach ($this->_columns as $tableName => $table) { if (array_key_exists('fields', $table)) { foreach ($table['fields'] as $fieldName => $field) { @@ -375,15 +382,6 @@ class CRM_Report_Form_Case_Detail extends CRM_Report_Form { } } - if ($orderBys = $this->_params['order_bys']) { - foreach ($orderBys as $orderBy) { - if ($orderBy['column'] == 'case_type_name') { - $select[] = "civireport_case_types.title as case_type_name"; - $this->_caseTypeNameOrderBy = TRUE; - } - } - } - $this->_selectClauses = $select; $this->_select = 'SELECT ' . implode(', ', $select) . ' '; @@ -427,17 +425,16 @@ class CRM_Report_Form_Case_Detail extends CRM_Report_Form { $this->_from .= " LEFT JOIN civicrm_activity {$this->_aliases['civicrm_activity_last_completed']} ON ( {$this->_aliases['civicrm_activity_last_completed']}.id = ( SELECT max(activity_id) FROM civicrm_case_activity cca, civicrm_activity ca WHERE ca.id = cca.activity_id AND cca.case_id = {$case}.id AND ca.status_id = 2 ) )"; } - //include case type name - if ($this->_caseTypeNameOrderBy) { + if ($this->isTableSelected('civicrm_case_type')) { $this->_from .= " - LEFT JOIN civicrm_case_type civireport_case_types - ON {$case}.case_type_id = civireport_case_types.id + LEFT JOIN civicrm_case_type {$this->_aliases['civicrm_case_type']} + ON {$this->_aliases['civicrm_case']}.case_type_id = {$this->_aliases['civicrm_case_type']}.id "; } } public function where() { - $clauses = array(); + $clauses = []; $this->_having = ''; foreach ($this->_columns as $tableName => $table) { if (array_key_exists('filters', $table)) { @@ -509,35 +506,24 @@ class CRM_Report_Form_Case_Detail extends CRM_Report_Form { $sql = "{$select} {$this->_from} {$this->_where}"; $countryCount = CRM_Core_DAO::singleValueQuery($sql); - $statistics['counts']['case'] = array( + $statistics['counts']['case'] = [ 'title' => ts('Total Number of Cases '), 'value' => isset($statistics['counts']['rowsFound']) ? $statistics['counts']['rowsFound']['value'] : count($rows), - ); - $statistics['counts']['country'] = array( + ]; + $statistics['counts']['country'] = [ 'title' => ts('Total Number of Countries '), 'value' => $countryCount, - ); + ]; return $statistics; } - public function orderBy() { - parent::orderBy(); - - if ($this->_caseTypeNameOrderBy) { - $this->_orderBy = str_replace('case_civireport.case_type_name', 'civireport_case_types.title', $this->_orderBy); - if (isset($this->_sections['civicrm_case_case_type_name'])) { - $this->_sections['civicrm_case_case_type_name']['dbAlias'] = 'civireport_case_types.title'; - } - } - } - public function caseDetailSpecialColumnProcess() { if (!$this->_includeCaseDetailExtra) { return; } - $from = $select = array(); + $from = $select = []; $case = $this->_aliases['civicrm_case']; if ($activityType = CRM_Utils_Array::value('case_activity_all_dates', $this->_params['case_detail_extra'])) { @@ -546,10 +532,10 @@ class CRM_Report_Form_Case_Detail extends CRM_Report_Form { $from[] = " LEFT JOIN civicrm_case_activity civireport_case_activity_all_{$activityType} ON ( civireport_case_activity_all_{$activityType}.case_id = {$case}.id) LEFT JOIN civicrm_activity civireport_activity_all_{$activityType} ON ( civireport_activity_all_{$activityType}.id = civireport_case_activity_all_{$activityType}.activity_id AND civireport_activity_all_{$activityType}.activity_type_id = {$activityType})"; - $this->_columnHeaders['case_activity_all_dates'] = array( + $this->_columnHeaders['case_activity_all_dates'] = [ 'title' => $this->_caseDetailExtra['case_activity_all_dates']['title'] . ": {$this->caseActivityTypes[$activityType]}", 'type' => CRM_Utils_Array::value('type', $this->_caseDetailExtra['case_activity_all_dates']), - ); + ]; } $this->_select .= ', ' . implode(', ', $select) . ' '; @@ -568,7 +554,7 @@ class CRM_Report_Form_Case_Detail extends CRM_Report_Form { $sql = "{$this->_select} {$this->_from} {$this->_where} {$this->_groupBy} {$this->_having} {$this->_orderBy} {$this->_limit}"; - $rows = $graphRows = array(); + $rows = $graphRows = []; $this->buildRows($sql, $rows); $this->formatDisplay($rows); @@ -580,7 +566,7 @@ class CRM_Report_Form_Case_Detail extends CRM_Report_Form { public function checkEnabledFields() { if ((isset($this->_params['case_role_value']) && !empty($this->_params['case_role_value'])) || - (isset($this->_params['is_active_value'])) + (isset($this->_params['is_active_value'])) ) { $this->_relField = TRUE; } diff --git a/civicrm/CRM/Report/Form/Contribute/Bookkeeping.php b/civicrm/CRM/Report/Form/Contribute/Bookkeeping.php index 240fc1dea8..ee117af7a4 100644 --- a/civicrm/CRM/Report/Form/Contribute/Bookkeeping.php +++ b/civicrm/CRM/Report/Form/Contribute/Bookkeeping.php @@ -354,7 +354,7 @@ class CRM_Report_Form_Contribute_Bookkeeping extends CRM_Report_Form { 'trxn_date' => array( 'title' => ts('Transaction Date'), 'default' => TRUE, - 'type' => CRM_Utils_Type::T_DATE, + 'type' => CRM_Utils_Type::T_DATE + CRM_Utils_Type::T_TIME, ), 'trxn_id' => array( 'title' => ts('Trans #'), @@ -381,7 +381,7 @@ class CRM_Report_Form_Contribute_Bookkeeping extends CRM_Report_Form { 'trxn_date' => array( 'title' => ts('Transaction Date'), 'operatorType' => CRM_Report_Form::OP_DATE, - 'type' => CRM_Utils_Type::T_DATE, + 'type' => CRM_Utils_Type::T_DATE + CRM_Utils_Type::T_TIME, ), 'status_id' => array( 'title' => ts('Financial Transaction Status'), diff --git a/civicrm/CRM/Report/Form/Contribute/Detail.php b/civicrm/CRM/Report/Form/Contribute/Detail.php index 10690896e7..eccb17c26b 100644 --- a/civicrm/CRM/Report/Form/Contribute/Detail.php +++ b/civicrm/CRM/Report/Form/Contribute/Detail.php @@ -156,6 +156,7 @@ class CRM_Report_Form_Contribute_Detail extends CRM_Report_Form { 'trxn_id' => NULL, 'receive_date' => array('default' => TRUE), 'receipt_date' => NULL, + 'thankyou_date' => NULL, 'total_amount' => array( 'title' => ts('Amount'), 'required' => TRUE, @@ -178,6 +179,12 @@ class CRM_Report_Form_Contribute_Detail extends CRM_Report_Form { 'title' => ts('Soft Credit For'), 'dbAlias' => "NULL", ), + 'cancel_date' => array( + 'title' => ts('Cancelled / Refunded Date'), + ), + 'cancel_reason' => array( + 'title' => ts('Cancellation / Refund Reason'), + ), ), 'filters' => array( 'contribution_or_soft' => array( @@ -192,6 +199,7 @@ class CRM_Report_Form_Contribute_Detail extends CRM_Report_Form { ), ), 'receive_date' => array('operatorType' => CRM_Report_Form::OP_DATE), + 'thankyou_date' => array('operatorType' => CRM_Report_Form::OP_DATE), 'contribution_source' => array( 'title' => ts('Source'), 'name' => 'source', @@ -233,12 +241,20 @@ class CRM_Report_Form_Contribute_Detail extends CRM_Report_Form { 'type' => CRM_Utils_Type::T_INT, ), 'total_amount' => array('title' => ts('Contribution Amount')), + 'cancel_date' => array( + 'title' => ts('Cancelled / Refunded Date'), + 'operatorType' => CRM_Report_Form::OP_DATE, + ), + 'cancel_reason' => array( + 'title' => ts('Cancellation / Refund Reason'), + ), ), 'order_bys' => array( 'financial_type_id' => array('title' => ts('Financial Type')), 'contribution_status_id' => array('title' => ts('Contribution Status')), 'payment_instrument_id' => array('title' => ts('Payment Method')), 'receive_date' => array('title' => ts('Date Received')), + 'thankyou_date' => array('title' => ts('Thank-you Date')), ), 'group_bys' => array( 'contribution_id' => array( diff --git a/civicrm/CRM/Report/Form/Contribute/Repeat.php b/civicrm/CRM/Report/Form/Contribute/Repeat.php index c5466dd4b9..e9f0d41821 100644 --- a/civicrm/CRM/Report/Form/Contribute/Repeat.php +++ b/civicrm/CRM/Report/Form/Contribute/Repeat.php @@ -99,41 +99,27 @@ class CRM_Report_Form_Contribute_Repeat extends CRM_Report_Form { 'civicrm_contact' => array( 'dao' => 'CRM_Contact_DAO_Contact', 'grouping' => 'contact-fields', - 'fields' => array( - 'sort_name' => array( - 'title' => ts('Contact Name'), - 'no_repeat' => TRUE, - 'default' => TRUE, - ), - 'display_name' => array( - 'title' => ts('Display Name'), - 'no_repeat' => TRUE, - ), - 'addressee_display' => array( - 'title' => ts('Addressee Name'), - 'no_repeat' => TRUE, - ), - 'id' => array( - 'no_display' => TRUE, - 'required' => TRUE, - ), - 'contact_type' => array( - 'title' => ts('Contact Type'), - 'no_repeat' => TRUE, - ), - 'contact_sub_type' => array( - 'title' => ts('Contact Subtype'), - 'no_repeat' => TRUE, - ), + 'fields' => array_merge( + $this->getBasicContactFields(), + array( + 'sort_name' => array( + 'title' => ts('Contact Name'), + 'no_repeat' => TRUE, + 'default' => TRUE, + ), + ) ), - 'filters' => array( - 'percentage_change' => array( - 'title' => ts('Percentage Change'), - 'type' => CRM_Utils_Type::T_INT, - 'operatorType' => CRM_Report_Form::OP_INT, - 'name' => 'percentage_change', - 'dbAlias' => '( ( contribution_civireport2.total_amount_sum - contribution_civireport1.total_amount_sum ) * 100 / contribution_civireport1.total_amount_sum )', - ), + 'filters' => array_merge( + $this->getBasicContactFilters(array('deceased' => NULL)), + array( + 'percentage_change' => array( + 'title' => ts('Percentage Change'), + 'type' => CRM_Utils_Type::T_INT, + 'operatorType' => CRM_Report_Form::OP_INT, + 'name' => 'percentage_change', + 'dbAlias' => '( ( contribution_civireport2.total_amount_sum - contribution_civireport1.total_amount_sum ) * 100 / contribution_civireport1.total_amount_sum )', + ), + ) ), 'group_bys' => array( 'id' => array( @@ -187,24 +173,6 @@ class CRM_Report_Form_Contribute_Repeat extends CRM_Report_Form { ), 'grouping' => 'contact-fields', ), - 'civicrm_address' => array( - 'dao' => 'CRM_Core_DAO_Address', - 'grouping' => 'contact-fields', - 'fields' => array( - 'street_address' => array('title' => ts('Street Address')), - 'supplemental_address_1' => array('title' => ts('Supplemental Address 1')), - 'city' => array('title' => ts('City')), - 'country_id' => array('title' => ts('Country')), - 'state_province_id' => array('title' => ts('State/Province')), - 'postal_code' => array('title' => ts('Postal Code')), - ), - 'group_bys' => array( - 'country_id' => array('title' => ts('Country')), - 'state_province_id' => array( - 'title' => ts('State/Province'), - ), - ), - ), 'civicrm_financial_type' => array( 'dao' => 'CRM_Financial_DAO_FinancialType', 'fields' => array('financial_type' => array('title' => ts('Financial Type'))), @@ -280,7 +248,7 @@ class CRM_Report_Form_Contribute_Repeat extends CRM_Report_Form { ), 'group_bys' => array('contribution_source' => NULL), ), - ); + ) + $this->addAddressFields(TRUE, FALSE, TRUE, array('country_id' => FALSE)); $this->_groupFilter = TRUE; $this->_tagFilter = TRUE; @@ -531,6 +499,7 @@ LEFT JOIN $this->tempTableRepeat2 {$this->_aliases['civicrm_contribution']}2 $rules = array( 'id' => array( 'sort_name', + 'exposed_id', 'display_name', 'addressee_display', 'contact_type', @@ -540,9 +509,38 @@ LEFT JOIN $this->tempTableRepeat2 {$this->_aliases['civicrm_contribution']}2 'state_province_id', 'country_id', 'city', + 'county_id', 'street_address', 'supplemental_address_1', + 'supplemental_address_2', + 'supplemental_address_3', + 'street_number', + 'street_name', + 'street_unit', 'postal_code', + 'postal_code_suffix', + 'prefix_id', + 'first_name', + 'nick_name', + 'middle_name', + 'last_name', + 'suffix_id', + 'postal_greeting_display', + 'email_greeting_display', + 'addressee_display', + 'gender_id', + 'birth_date', + 'age', + 'job_title', + 'organization_name', + 'external_identifier', + 'do_not_email', + 'do_not_phone', + 'do_not_mail', + 'do_not_sms', + 'is_opt_out', + 'is_deceased', + 'preferred_language', ), 'country_id' => array('country_id'), 'state_province_id' => array('country_id', 'state_province_id'), @@ -1037,7 +1035,7 @@ GROUP BY contribution2.{$this->contributionJoinTableColumn}, currency"; CREATE TEMPORARY TABLE $this->tempTableRepeat1 ( {$create} {$this->contributionJoinTableColumn} int unsigned, -total_amount_sum int, +total_amount_sum decimal(20,2), total_amount_count int ) ENGINE=HEAP {$this->_databaseAttributes}"; $this->executeReportQuery($sql); @@ -1052,7 +1050,7 @@ total_amount_count int CREATE TEMPORARY TABLE $this->tempTableRepeat2 ( {$create} {$this->contributionJoinTableColumn} int unsigned, -total_amount_sum int, +total_amount_sum decimal(20,2), total_amount_count int, currency varchar(3) ) ENGINE=HEAP {$this->_databaseAttributes}"; diff --git a/civicrm/CRM/Report/Form/Contribute/SoftCredit.php b/civicrm/CRM/Report/Form/Contribute/SoftCredit.php index 983d479512..5296451542 100644 --- a/civicrm/CRM/Report/Form/Contribute/SoftCredit.php +++ b/civicrm/CRM/Report/Form/Contribute/SoftCredit.php @@ -535,21 +535,10 @@ GROUP BY {$this->_aliases['civicrm_contribution']}.currency $this->buildACLClause(array('constituentname', 'contact_civireport')); $sql = $this->buildQuery(); - $dao = CRM_Core_DAO::executeQuery($sql); $rows = $graphRows = array(); - $count = 0; - while ($dao->fetch()) { - $row = array(); - foreach ($this->_columnHeaders as $key => $value) { - $row[$key] = $dao->$key; - } - $rows[] = $row; - } - $this->formatDisplay($rows); + $this->buildRows($sql, $rows); - // to hide the contact ID field from getting displayed - unset($this->_columnHeaders['civicrm_contact_id_constituent']); - unset($this->_columnHeaders['civicrm_contact_id_creditor']); + $this->formatDisplay($rows); // assign variables to templates $this->doTemplateAssignment($rows); diff --git a/civicrm/CRM/Report/Form/Contribute/Summary.php b/civicrm/CRM/Report/Form/Contribute/Summary.php index b5f682a987..6e4b238d6f 100644 --- a/civicrm/CRM/Report/Form/Contribute/Summary.php +++ b/civicrm/CRM/Report/Form/Contribute/Summary.php @@ -149,6 +149,7 @@ class CRM_Report_Form_Contribute_Summary extends CRM_Report_Form { 'grouping' => 'contri-fields', 'filters' => array( 'receive_date' => array('operatorType' => CRM_Report_Form::OP_DATE), + 'thankyou_date' => array('operatorType' => CRM_Report_Form::OP_DATE), 'contribution_status_id' => array( 'title' => ts('Contribution Status'), 'operatorType' => CRM_Report_Form::OP_MULTISELECT, @@ -649,10 +650,8 @@ ROUND(AVG({$this->_aliases['civicrm_contribution_soft']}.amount), 2) as civicrm_ FROM (SELECT {$this->_aliases['civicrm_contribution']}.total_amount as amount, {$contriQuery} {$groupBy} {$orderBy}) as mode GROUP BY currency"; - $mode = CRM_Contribute_BAO_Contribution::computeStats('mode', $modeSQL); - - $medianSQL = "{$this->_from} {$this->_where}"; - $median = CRM_Contribute_BAO_Contribution::computeStats('median', $medianSQL, $this->_aliases['civicrm_contribution']); + $mode = $this->calculateMode($modeSQL); + $median = $this->calculateMedian(); if ($softCredit) { $softDAO = CRM_Core_DAO::executeQuery($softSQL); @@ -961,4 +960,71 @@ ROUND(AVG({$this->_aliases['civicrm_contribution_soft']}.amount), 2) as civicrm_ } } + /** + * Calculate mode. + * + * Note this is a slow query. Alternative is extended reports. + * + * @param string $sql + * @return array|null + */ + protected function calculateMode($sql) { + $mode = []; + $modeDAO = CRM_Core_DAO::executeQuery($sql); + while ($modeDAO->fetch()) { + if ($modeDAO->civicrm_contribution_total_amount_count > 1) { + $mode[] = CRM_Utils_Money::format($modeDAO->amount, $modeDAO->currency); + } + else { + $mode[] = 'N/A'; + } + } + return $mode; + } + + /** + * Calculate mode. + * + * Note this is a slow query. Alternative is extended reports. + * + * @return array|null + */ + protected function calculateMedian() { + $sql = "{$this->_from} {$this->_where}"; + $currencies = CRM_Core_OptionGroup::values('currencies_enabled'); + $median = []; + foreach ($currencies as $currency => $val) { + $midValue = 0; + $where = "AND {$this->_aliases['civicrm_contribution']}.currency = '{$currency}'"; + $rowCount = CRM_Core_DAO::singleValueQuery("SELECT count(*) as count {$sql} {$where}"); + + $even = FALSE; + $offset = 1; + $medianRow = floor($rowCount / 2); + if ($rowCount % 2 == 0 && !empty($medianRow)) { + $even = TRUE; + $offset++; + $medianRow--; + } + + $medianValue = "SELECT {$this->_aliases['civicrm_contribution']}.total_amount as median + {$sql} {$where} + ORDER BY median LIMIT {$medianRow},{$offset}"; + $medianValDAO = CRM_Core_DAO::executeQuery($medianValue); + while ($medianValDAO->fetch()) { + if ($even) { + $midValue = $midValue + $medianValDAO->median; + } + else { + $median[] = CRM_Utils_Money::format($medianValDAO->median, $currency); + } + } + if ($even) { + $midValue = $midValue / 2; + $median[] = CRM_Utils_Money::format($midValue, $currency); + } + } + return $median; + } + } diff --git a/civicrm/CRM/Report/Form/Event/Income.php b/civicrm/CRM/Report/Form/Event/Income.php index b22d17e4cc..41bcc46575 100644 --- a/civicrm/CRM/Report/Form/Event/Income.php +++ b/civicrm/CRM/Report/Form/Event/Income.php @@ -32,7 +32,7 @@ * $Id$ * */ -class CRM_Report_Form_Event_Income extends CRM_Report_Form_Event { +class CRM_Report_Form_Event_Income extends CRM_Report_Form { const ROW_COUNT_LIMIT = 2; protected $_summary = NULL; diff --git a/civicrm/CRM/Report/Form/Event/IncomeCountSummary.php b/civicrm/CRM/Report/Form/Event/IncomeCountSummary.php index 7762669298..d8dbeed4f4 100644 --- a/civicrm/CRM/Report/Form/Event/IncomeCountSummary.php +++ b/civicrm/CRM/Report/Form/Event/IncomeCountSummary.php @@ -30,7 +30,7 @@ * @package CRM * @copyright CiviCRM LLC (c) 2004-2019 */ -class CRM_Report_Form_Event_IncomeCountSummary extends CRM_Report_Form_Event { +class CRM_Report_Form_Event_IncomeCountSummary extends CRM_Report_Form { protected $_summary = NULL; diff --git a/civicrm/CRM/Report/Form/Event/ParticipantListCount.php b/civicrm/CRM/Report/Form/Event/ParticipantListCount.php index 1bae9c1341..a03f9c9c3e 100644 --- a/civicrm/CRM/Report/Form/Event/ParticipantListCount.php +++ b/civicrm/CRM/Report/Form/Event/ParticipantListCount.php @@ -30,7 +30,7 @@ * @package CRM * @copyright CiviCRM LLC (c) 2004-2019 */ -class CRM_Report_Form_Event_ParticipantListCount extends CRM_Report_Form_Event { +class CRM_Report_Form_Event_ParticipantListCount extends CRM_Report_Form { protected $_summary = NULL; protected $_groupFilter = TRUE; @@ -238,7 +238,7 @@ class CRM_Report_Form_Event_ParticipantListCount extends CRM_Report_Form_Event { 'operatorType' => CRM_Report_Form::OP_ENTITYREF, 'type' => CRM_Utils_Type::T_INT, 'attributes' => array( - 'entity' => 'event', + 'entity' => 'Event', 'select' => array('minimumInputLength' => 0), ), ), diff --git a/civicrm/CRM/Report/Form/Event/ParticipantListing.php b/civicrm/CRM/Report/Form/Event/ParticipantListing.php index 33a7a17329..c9be9e8143 100644 --- a/civicrm/CRM/Report/Form/Event/ParticipantListing.php +++ b/civicrm/CRM/Report/Form/Event/ParticipantListing.php @@ -30,7 +30,7 @@ * @package CRM * @copyright CiviCRM LLC (c) 2004-2019 */ -class CRM_Report_Form_Event_ParticipantListing extends CRM_Report_Form_Event { +class CRM_Report_Form_Event_ParticipantListing extends CRM_Report_Form { protected $_summary = NULL; @@ -180,7 +180,7 @@ class CRM_Report_Form_Event_ParticipantListing extends CRM_Report_Form_Event { 'operatorType' => CRM_Report_Form::OP_ENTITYREF, 'type' => CRM_Utils_Type::T_INT, 'attributes' => array( - 'entity' => 'event', + 'entity' => 'Event', 'select' => array('minimumInputLength' => 0), ), ), @@ -732,19 +732,6 @@ ORDER BY cv.label $entryFound = TRUE; } - // Handle employer id - if (array_key_exists('civicrm_contact_employer_id', $row)) { - $employerId = $row['civicrm_contact_employer_id']; - if ($employerId) { - $rows[$rowNum]['civicrm_contact_employer_id'] = CRM_Contact_BAO_Contact::displayName($employerId); - $url = CRM_Utils_System::url('civicrm/contact/view', - 'reset=1&cid=' . $employerId, $this->_absoluteUrl - ); - $rows[$rowNum]['civicrm_contact_employer_id_link'] = $url; - $rows[$rowNum]['civicrm_contact_employer_id_hover'] = ts('View Contact Summary for this Contact.'); - } - } - // Convert campaign_id to campaign title $this->_initBasicRow($rows, $entryFound, $row, 'civicrm_participant_campaign_id', $rowNum, $this->campaigns); diff --git a/civicrm/CRM/Report/Form/Event/Summary.php b/civicrm/CRM/Report/Form/Event/Summary.php index 11a3a8c0af..0d689cc848 100644 --- a/civicrm/CRM/Report/Form/Event/Summary.php +++ b/civicrm/CRM/Report/Form/Event/Summary.php @@ -30,7 +30,7 @@ * @package CRM * @copyright CiviCRM LLC (c) 2004-2019 */ -class CRM_Report_Form_Event_Summary extends CRM_Report_Form_Event { +class CRM_Report_Form_Event_Summary extends CRM_Report_Form { protected $_summary = NULL; diff --git a/civicrm/CRM/Report/Form/Member/Detail.php b/civicrm/CRM/Report/Form/Member/Detail.php index 13a286ada4..94afd1f197 100644 --- a/civicrm/CRM/Report/Form/Member/Detail.php +++ b/civicrm/CRM/Report/Form/Member/Detail.php @@ -104,6 +104,10 @@ class CRM_Report_Form_Member_Detail extends CRM_Report_Form { 'title' => ts('End Date'), 'default' => TRUE, ), + 'owner_membership_id' => array( + 'title' => ts('Primary/Inherited?'), + 'default' => TRUE, + ), 'join_date' => array( 'title' => ts('Join Date'), 'default' => TRUE, @@ -363,6 +367,12 @@ class CRM_Report_Form_Member_Detail extends CRM_Report_Form { $entryFound = TRUE; } + if (array_key_exists('civicrm_membership_owner_membership_id', $row)) { + $value = $row['civicrm_membership_owner_membership_id']; + $rows[$rowNum]['civicrm_membership_owner_membership_id'] = ($value != '') ? 'Inherited' : 'Primary'; + $entryFound = TRUE; + } + // Convert campaign_id to campaign title if (array_key_exists('civicrm_membership_campaign_id', $row)) { if ($value = $row['civicrm_membership_campaign_id']) { diff --git a/civicrm/CRM/Upgrade/4.2.alpha1.msg_template/civicrm_msg_template.tpl b/civicrm/CRM/Upgrade/4.2.alpha1.msg_template/civicrm_msg_template.tpl deleted file mode 100644 index 9f7a745490..0000000000 --- a/civicrm/CRM/Upgrade/4.2.alpha1.msg_template/civicrm_msg_template.tpl +++ /dev/null @@ -1,67 +0,0 @@ -{php} - $dir = SMARTY_DIR . '/../../CRM/Upgrade/4.2.alpha1.msg_template/message_templates'; - - $ovNames = array( - 'contribution' => array( - 'contribution_recurring_cancelled' => ts('Contributions - Recurring Cancellation Notification', array('escape' => 'sql')), - 'contribution_recurring_billing' => ts('Contributions - Recurring Billing Updates', array('escape' => 'sql')), - 'contribution_recurring_edit' => ts('Contributions - Recurring Updates', array('escape' => 'sql')), - ), - 'membership' => array( - 'membership_autorenew_cancelled' => ts('Memberships - Auto-renew Cancellation Notification', array('escape' => 'sql')), - 'membership_autorenew_billing' => ts('Memberships - Auto-renew Billing Updates', array('escape' => 'sql')), - ), - ); - - $ignoreTemplate = array_merge(array_keys($ovNames['contribution']), array_keys($ovNames['membership'])); - - $this->assign('ovNames', $ovNames); - $this->assign('dir', $dir); - $templates = array(); - foreach (preg_grep('/\.tpl$/', scandir($dir)) as $filename) { - $parts = explode('_', basename($filename, '.tpl')); - $type = array_pop($parts); - $name = implode('_', $parts); - if (!in_array($name,$ignoreTemplate)) { - $templates[] = array('type' => $type, 'name' => $name, 'filename' => "$dir/$filename"); - } - } - $this->assign('templates', $templates); -{/php} - -{foreach from=$templates item=tpl} - {fetch assign=content file=$tpl.filename} - SELECT @workflow_id := MAX(id) FROM civicrm_option_value WHERE name = '{$tpl.name}'; - SELECT @content := msg_{$tpl.type} FROM civicrm_msg_template WHERE workflow_id = @workflow_id AND is_reserved = 1 LIMIT 1; - UPDATE civicrm_msg_template SET msg_{$tpl.type} = '{$content|escape:"quotes"}' WHERE workflow_id = @workflow_id AND (is_reserved = 1 OR (is_default = 1 AND msg_{$tpl.type} = @content)); -{/foreach} - -{foreach from=$ovNames key=name item=ignore} - SELECT @tpl_ogid_{$name} := MAX(id) FROM civicrm_option_group WHERE name = 'msg_tpl_workflow_{$name}'; -{/foreach} - -INSERT INTO civicrm_option_value - (option_group_id, name, {localize field='label'}label{/localize}, value, weight) VALUES -{foreach from=$ovNames key=gName item=ovs name=for_groups} -{foreach from=$ovs key=vName item=label name=for_values} - (@tpl_ogid_{$gName}, '{$vName}', {localize}'{$label}'{/localize}, {$smarty.foreach.for_values.iteration}, {$smarty.foreach.for_values.iteration}) {if $smarty.foreach.for_groups.last and $smarty.foreach.for_values.last};{else},{/if} -{/foreach} -{/foreach} - -{foreach from=$ovNames key=gName item=ovs} -{foreach from=$ovs key=vName item=label} - SELECT @tpl_ovid_{$vName} := MAX(id) FROM civicrm_option_value WHERE option_group_id = @tpl_ogid_{$gName} AND name = '{$vName}'; -{/foreach} -{/foreach} - -INSERT INTO civicrm_msg_template - (msg_title, msg_subject, msg_text, msg_html, workflow_id, is_default, is_reserved) VALUES -{foreach from=$ovNames key=gName item=ovs name=for_groups} -{foreach from=$ovs key=vName item=title name=for_values} - {fetch assign=subject file="`$smarty.const.SMARTY_DIR`/../../CRM/Upgrade/4.2.alpha1.msg_template/message_templates/`$vName`_subject.tpl"} - {fetch assign=text file="`$smarty.const.SMARTY_DIR`/../../CRM/Upgrade/4.2.alpha1.msg_template/message_templates/`$vName`_text.tpl"} - {fetch assign=html file="`$smarty.const.SMARTY_DIR`/../../CRM/Upgrade/4.2.alpha1.msg_template/message_templates/`$vName`_html.tpl"} - ('{$title}', '{$subject|escape:"quotes"}', '{$text|escape:"quotes"}', '{$html|escape:"quotes"}', @tpl_ovid_{$vName}, 1, 0), - ('{$title}', '{$subject|escape:"quotes"}', '{$text|escape:"quotes"}', '{$html|escape:"quotes"}', @tpl_ovid_{$vName}, 0, 1) {if $smarty.foreach.for_groups.last and $smarty.foreach.for_values.last};{else},{/if} -{/foreach} -{/foreach} diff --git a/civicrm/CRM/Upgrade/4.2.alpha1.msg_template/message_templates/contribution_online_receipt_html.tpl b/civicrm/CRM/Upgrade/4.2.alpha1.msg_template/message_templates/contribution_online_receipt_html.tpl deleted file mode 100644 index a1c91b1088..0000000000 --- a/civicrm/CRM/Upgrade/4.2.alpha1.msg_template/message_templates/contribution_online_receipt_html.tpl +++ /dev/null @@ -1,395 +0,0 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml"> -<head> - <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> - <title></title> -</head> -<body> - -{capture assign=headerStyle}colspan="2" style="text-align: left; padding: 4px; border-bottom: 1px solid #999; background-color: #eee;"{/capture} -{capture assign=labelStyle }style="padding: 4px; border-bottom: 1px solid #999; background-color: #f7f7f7;"{/capture} -{capture assign=valueStyle }style="padding: 4px; border-bottom: 1px solid #999;"{/capture} - -<center> - <table width="500" border="0" cellpadding="0" cellspacing="0" id="crm-event_receipt" style="font-family: Arial, Verdana, sans-serif; text-align: left;"> - - <!-- BEGIN HEADER --> - <!-- You can add table row(s) here with logo or other header elements --> - <!-- END HEADER --> - - <!-- BEGIN CONTENT --> - - <tr> - <td> - - {if $receipt_text} - <p>{$receipt_text|htmlize}</p> - {/if} - - {if $is_pay_later} - <p>{$pay_later_receipt}</p> {* FIXME: this might be text rather than HTML *} - {else} - <p>{ts}Please print this confirmation for your records.{/ts}</p> - {/if} - - </td> - </tr> - </table> - <table width="500" style="border: 1px solid #999; margin: 1em 0em 1em; border-collapse: collapse;"> - - {if $amount} - - - <tr> - <th {$headerStyle}> - {ts}Contribution Information{/ts} - </th> - </tr> - - {if $lineItem and $priceSetID and !$is_quick_config} - - {foreach from=$lineItem item=value key=priceset} - <tr> - <td colspan="2" {$valueStyle}> - <table> {* FIXME: style this table so that it looks like the text version (justification, etc.) *} - <tr> - <th>{ts}Item{/ts}</th> - <th>{ts}Qty{/ts}</th> - <th>{ts}Each{/ts}</th> - <th>{ts}Total{/ts}</th> - </tr> - {foreach from=$value item=line} - <tr> - <td> - {if $line.html_type eq 'Text'}{$line.label}{else}{$line.field_title} - {$line.label}{/if} {if $line.description}<div>{$line.description|truncate:30:"..."}</div>{/if} - </td> - <td> - {$line.qty} - </td> - <td> - {$line.unit_price|crmMoney:$currency} - </td> - <td> - {$line.line_total|crmMoney:$currency} - </td> - </tr> - {/foreach} - </table> - </td> - </tr> - {/foreach} - <tr> - <td {$labelStyle}> - {ts}Total Amount{/ts} - </td> - <td {$valueStyle}> - {$amount|crmMoney:$currency} - </td> - </tr> - - {else} - - <tr> - <td {$labelStyle}> - {ts}Amount{/ts} - </td> - <td {$valueStyle}> - {$amount|crmMoney:$currency} {if $amount_level} - {$amount_level}{/if} - </td> - </tr> - - {/if} - - - {/if} - - - {if $receive_date} - <tr> - <td {$labelStyle}> - {ts}Date{/ts} - </td> - <td {$valueStyle}> - {$receive_date|crmDate} - </td> - </tr> - {/if} - - {if $is_monetary and $trxn_id} - <tr> - <td {$labelStyle}> - {ts}Transaction #{/ts} - </td> - <td {$valueStyle}> - {$trxn_id} - </td> - </tr> - {/if} - - {if $is_recur} - {if $contributeMode eq 'notify' or $contributeMode eq 'directIPN'} - <tr> - <td colspan="2" {$labelStyle}> - {ts 1=$cancelSubscriptionUrl}This is a recurring contribution. You can cancel future contributions by <a href="%1">visiting this web page</a>.{/ts} - </td> - <tr> - </tr> - <td colspan="2" {$labelStyle}> - {ts 1=$updateSubscriptionBillingUrl}You can update billing details for this recurring contribution by <a href="%1">visiting this web page</a>.{/ts} - </td> - <tr> - </tr> - <td colspan="2" {$labelStyle}> - {ts 1=$updateSubscriptionUrl}You can update recurring contribution amount or change the number of installments for this recurring contribution by <a href="%1">visiting this web page</a>.{/ts} - </td> - </tr> - {/if} - {/if} - - {if $honor_block_is_active} - <tr> - <th {$headerStyle}> - {$honor_type} - </th> - </tr> - <tr> - <td colspan="2" {$labelStyle}> - {$honor_prefix} {$honor_first_name} {$honor_last_name} - </td> - </tr> - {if $honor_email} - <tr> - <td {$labelStyle}> - {ts}Honoree Email{/ts} - </td> - <td {$valueStyle}> - {$honor_email} - </td> - </tr> - {/if} - {/if} - - {if $pcpBlock} - <tr> - <th {$headerStyle}> - {ts}Personal Campaign Page{/ts} - </th> - </tr> - <tr> - <td {$labelStyle}> - {ts}Display In Honor Roll{/ts} - </td> - <td {$valueStyle}> - {if $pcp_display_in_roll}{ts}Yes{/ts}{else}{ts}No{/ts}{/if} - </td> - </tr> - {if $pcp_roll_nickname} - <tr> - <td {$labelStyle}> - {ts}Nickname{/ts} - </td> - <td {$valueStyle}> - {$pcp_roll_nickname} - </td> - </tr> - {/if} - {if $pcp_personal_note} - <tr> - <td {$labelStyle}> - {ts}Personal Note{/ts} - </td> - <td {$valueStyle}> - {$pcp_personal_note} - </td> - </tr> - {/if} - {/if} - - {if $onBehalfProfile} - <tr> - <th {$headerStyle}> - {$onBehalfProfile_grouptitle} - </th> - </tr> - {foreach from=$onBehalfProfile item=onBehalfValue key=onBehalfName} - <tr> - <td {$labelStyle}> - {$onBehalfName} - </td> - <td {$valueStyle}> - {$onBehalfValue} - </td> - </tr> - {/foreach} - {/if} - - {if $isShare} - <tr> - <td colspan="2" {$valueStyle}> - {capture assign=contributionUrl}{crmURL p='civicrm/contribute/transact' q="reset=1&id=`$contributionPageId`" a=true fe=1 h=1}{/capture} - {include file="CRM/common/SocialNetwork.tpl" emailMode=true url=$contributionUrl title=$title pageURL=$contributionUrl} - </td> - </tr> - {/if} - - {if ! ($contributeMode eq 'notify' OR $contributeMode eq 'directIPN') and $is_monetary} - {if $is_pay_later} - <tr> - <th {$headerStyle}> - {ts}Registered Email{/ts} - </th> - </tr> - <tr> - <td colspan="2" {$valueStyle}> - {$email} - </td> - </tr> - {elseif $amount GT 0} - <tr> - <th {$headerStyle}> - {ts}Billing Name and Address{/ts} - </th> - </tr> - <tr> - <td colspan="2" {$valueStyle}> - {$billingName}<br /> - {$address|nl2br}<br /> - {$email} - </td> - </tr> - {/if} - {/if} - - {if $contributeMode eq 'direct' AND !$is_pay_later AND $amount GT 0} - <tr> - <th {$headerStyle}> - {ts}Credit Card Information{/ts} - </th> - </tr> - <tr> - <td colspan="2" {$valueStyle}> - {$credit_card_type}<br /> - {$credit_card_number}<br /> - {ts}Expires{/ts}: {$credit_card_exp_date|truncate:7:''|crmDate}<br /> - </td> - </tr> - {/if} - - {if $selectPremium} - <tr> - <th {$headerStyle}> - {ts}Premium Information{/ts} - </th> - </tr> - <tr> - <td colspan="2" {$labelStyle}> - {$product_name} - </td> - </tr> - {if $option} - <tr> - <td {$labelStyle}> - {ts}Option{/ts} - </td> - <td {$valueStyle}> - {$option} - </td> - </tr> - {/if} - {if $sku} - <tr> - <td {$labelStyle}> - {ts}SKU{/ts} - </td> - <td {$valueStyle}> - {$sku} - </td> - </tr> - {/if} - {if $start_date} - <tr> - <td {$labelStyle}> - {ts}Start Date{/ts} - </td> - <td {$valueStyle}> - {$start_date|crmDate} - </td> - </tr> - {/if} - {if $end_date} - <tr> - <td {$labelStyle}> - {ts}End Date{/ts} - </td> - <td {$valueStyle}> - {$end_date|crmDate} - </td> - </tr> - {/if} - {if $contact_email OR $contact_phone} - <tr> - <td colspan="2" {$valueStyle}> - <p>{ts}For information about this premium, contact:{/ts}</p> - {if $contact_email} - <p>{$contact_email}</p> - {/if} - {if $contact_phone} - <p>{$contact_phone}</p> - {/if} - </td> - </tr> - {/if} - {if $is_deductible AND $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> - </td> - </tr> - {/if} - {/if} - - {if $customPre} - <tr> - <th {$headerStyle}> - {$customPre_grouptitle} - </th> - </tr> - {foreach from=$customPre item=customValue key=customName} - {if ($trackingFields and ! in_array($customName, $trackingFields)) or ! $trackingFields} - <tr> - <td {$labelStyle}> - {$customName} - </td> - <td {$valueStyle}> - {$customValue} - </td> - </tr> - {/if} - {/foreach} - {/if} - - {if $customPost} - <tr> - <th {$headerStyle}> - {$customPost_grouptitle} - </th> - </tr> - {foreach from=$customPost item=customValue key=customName} - {if ($trackingFields and ! in_array($customName, $trackingFields)) or ! $trackingFields} - <tr> - <td {$labelStyle}> - {$customName} - </td> - <td {$valueStyle}> - {$customValue} - </td> - </tr> - {/if} - {/foreach} - {/if} - - </table> -</center> - -</body> -</html> diff --git a/civicrm/CRM/Upgrade/4.2.alpha1.msg_template/message_templates/contribution_online_receipt_text.tpl b/civicrm/CRM/Upgrade/4.2.alpha1.msg_template/message_templates/contribution_online_receipt_text.tpl deleted file mode 100644 index 27463ee8f7..0000000000 --- a/civicrm/CRM/Upgrade/4.2.alpha1.msg_template/message_templates/contribution_online_receipt_text.tpl +++ /dev/null @@ -1,179 +0,0 @@ -{if $receipt_text} -{$receipt_text} -{/if} -{if $is_pay_later} - -=========================================================== -{$pay_later_receipt} -=========================================================== -{else} - -{ts}Please print this receipt for your records.{/ts} -{/if} - -{if $amount} -=========================================================== -{ts}Contribution Information{/ts} - -=========================================================== -{if $lineItem and $priceSetID} -{foreach from=$lineItem item=value key=priceset} ---------------------------------------------------------- -{capture assign=ts_item}{ts}Item{/ts}{/capture} -{capture assign=ts_qty}{ts}Qty{/ts}{/capture} -{capture assign=ts_each}{ts}Each{/ts}{/capture} -{capture assign=ts_total}{ts}Total{/ts}{/capture} -{$ts_item|string_format:"%-30s"} {$ts_qty|string_format:"%5s"} {$ts_each|string_format:"%10s"} {$ts_total|string_format:"%10s"} ----------------------------------------------------------- -{foreach from=$value item=line} -{capture assign=ts_item}{if $line.html_type eq 'Text'}{$line.label}{else}{$line.field_title} - {$line.label}{/if} {if $line.description} {$line.description}{/if}{/capture}{$ts_item|truncate:30:"..."|string_format:"%-30s"} {$line.qty|string_format:"%5s"} {$line.unit_price|crmMoney:$currency|string_format:"%10s"} {$line.line_total|crmMoney:$currency|string_format:"%10s"} -{/foreach} -{/foreach} - -{ts}Total Amount{/ts}: {$amount|crmMoney:$currency} -{else} -{ts}Amount{/ts}: {$amount|crmMoney:$currency} {if $amount_level } - {$amount_level} {/if} -{/if} -{/if} -{if $receive_date} - -{ts}Date{/ts}: {$receive_date|crmDate} -{/if} -{if $is_monetary and $trxn_id} -{ts}Transaction #{/ts}: {$trxn_id} -{/if} - -{if $is_recur and ($contributeMode eq 'notify' or $contributeMode eq 'directIPN')} -{ts}This is a recurring contribution. You can cancel future contributions at:{/ts} - -{$cancelSubscriptionUrl} - -{ts}You can update billing details for this recurring contribution at:{/ts} - -{$updateSubscriptionBillingUrl} - -{ts}You can update recurring contribution amount or change the number of installments for this recurring contribution at:{/ts} - -{$updateSubscriptionUrl} - -{/if} - -{if $honor_block_is_active } -=========================================================== -{$honor_type} -=========================================================== -{$honor_prefix} {$honor_first_name} {$honor_last_name} -{if $honor_email} -{ts}Honoree Email{/ts}: {$honor_email} -{/if} - -{/if} -{if $pcpBlock} -=========================================================== -{ts}Personal Campaign Page{/ts} - -=========================================================== -{ts}Display In Honor Roll{/ts}: {if $pcp_display_in_roll}{ts}Yes{/ts}{else}{ts}No{/ts}{/if} - -{if $pcp_roll_nickname}{ts}Nickname{/ts}: {$pcp_roll_nickname}{/if} - -{if $pcp_personal_note}{ts}Personal Note{/ts}: {$pcp_personal_note}{/if} - -{/if} -{if $onBehalfProfile} -=========================================================== -{ts}On Behalf Of{/ts} - -=========================================================== -{foreach from=$onBehalfProfile item=onBehalfValue key=onBehalfName} -{$onBehalfName}: {$onBehalfValue} -{/foreach} -{/if} - -{if !( $contributeMode eq 'notify' OR $contributeMode eq 'directIPN' ) and $is_monetary} -{if $is_pay_later} -=========================================================== -{ts}Registered Email{/ts} - -=========================================================== -{$email} -{elseif $amount GT 0} -=========================================================== -{ts}Billing Name and Address{/ts} - -=========================================================== -{$billingName} -{$address} - -{$email} -{/if} {* End ! is_pay_later condition. *} -{/if} -{if $contributeMode eq 'direct' AND !$is_pay_later AND $amount GT 0} - -=========================================================== -{ts}Credit Card Information{/ts} - -=========================================================== -{$credit_card_type} -{$credit_card_number} -{ts}Expires{/ts}: {$credit_card_exp_date|truncate:7:''|crmDate} -{/if} - -{if $selectPremium } -=========================================================== -{ts}Premium Information{/ts} - -=========================================================== -{$product_name} -{if $option} -{ts}Option{/ts}: {$option} -{/if} -{if $sku} -{ts}SKU{/ts}: {$sku} -{/if} -{if $start_date} -{ts}Start Date{/ts}: {$start_date|crmDate} -{/if} -{if $end_date} -{ts}End Date{/ts}: {$end_date|crmDate} -{/if} -{if $contact_email OR $contact_phone} - -{ts}For information about this premium, contact:{/ts} - -{if $contact_email} - {$contact_email} -{/if} -{if $contact_phone} - {$contact_phone} -{/if} -{/if} -{if $is_deductible AND $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} - -{if $customPre} -=========================================================== -{$customPre_grouptitle} - -=========================================================== -{foreach from=$customPre item=customValue key=customName} -{if ( $trackingFields and ! in_array( $customName, $trackingFields ) ) or ! $trackingFields} - {$customName}: {$customValue} -{/if} -{/foreach} -{/if} - - -{if $customPost} -=========================================================== -{$customPost_grouptitle} - -=========================================================== -{foreach from=$customPost item=customValue key=customName} -{if ( $trackingFields and ! in_array( $customName, $trackingFields ) ) or ! $trackingFields} - {$customName}: {$customValue} -{/if} -{/foreach} -{/if} diff --git a/civicrm/CRM/Upgrade/4.2.alpha1.msg_template/message_templates/contribution_recurring_billing_html.tpl b/civicrm/CRM/Upgrade/4.2.alpha1.msg_template/message_templates/contribution_recurring_billing_html.tpl deleted file mode 100644 index f2b9d48842..0000000000 --- a/civicrm/CRM/Upgrade/4.2.alpha1.msg_template/message_templates/contribution_recurring_billing_html.tpl +++ /dev/null @@ -1,65 +0,0 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml"> -<head> - <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> - <title></title> -</head> -<body> - -{capture assign=headerStyle}colspan="2" style="text-align: left; padding: 4px; border-bottom: 1px solid #999; background-color: #eee;"{/capture} -{capture assign=labelStyle }style="padding: 4px; border-bottom: 1px solid #999; background-color: #f7f7f7;"{/capture} -{capture assign=valueStyle }style="padding: 4px; border-bottom: 1px solid #999;"{/capture} - -<center> - <table width="620" border="0" cellpadding="0" cellspacing="0" id="crm-event_receipt" style="font-family: Arial, Verdana, sans-serif; text-align: left;"> - - <!-- BEGIN HEADER --> - <!-- You can add table row(s) here with logo or other header elements --> - <!-- END HEADER --> - - <!-- BEGIN CONTENT --> - - <tr> - <td> - <p>{ts 1=$contact.display_name}Dear %1{/ts},</p> - <p>{ts 1=$amount 2=$recur_frequency_interval 3=$recur_frequency_unit}Billing details for your recurring contribution of %1, every %2 %3 have been updated.{/ts}</p> - </td> - </tr> - <tr> - </table> - - <table width="500" style="border: 1px solid #999; margin: 1em 0em 1em; border-collapse: collapse;"> -<tr> - <th {$headerStyle}> - {ts}Billing Name and Address{/ts} - </th> - </tr> - <tr> - <td colspan="2" {$valueStyle}> - {$billingName}<br /> - {$address|nl2br}<br /> - {$email} - </td> - </tr> - <tr> - <th {$headerStyle}> - {ts}Credit Card Information{/ts} - </th> - </tr> - <tr> - <td colspan="2" {$valueStyle}> - {$credit_card_type}<br /> - {$credit_card_number}<br /> - {ts}Expires{/ts}: {$credit_card_exp_date|truncate:7:''|crmDate}<br /> - </td> - </tr> - <tr> - <td {$labelStyle}> - {ts 1=$receipt_from_email}If you have questions please contact us at %1{/ts} - </td> - </tr> - </table> -</center> - -</body> -</html> \ No newline at end of file diff --git a/civicrm/CRM/Upgrade/4.2.alpha1.msg_template/message_templates/contribution_recurring_billing_subject.tpl b/civicrm/CRM/Upgrade/4.2.alpha1.msg_template/message_templates/contribution_recurring_billing_subject.tpl deleted file mode 100644 index 32f2c0f83e..0000000000 --- a/civicrm/CRM/Upgrade/4.2.alpha1.msg_template/message_templates/contribution_recurring_billing_subject.tpl +++ /dev/null @@ -1 +0,0 @@ -{ts}Recurring Contribution Updates{/ts} \ No newline at end of file diff --git a/civicrm/CRM/Upgrade/4.2.alpha1.msg_template/message_templates/contribution_recurring_billing_text.tpl b/civicrm/CRM/Upgrade/4.2.alpha1.msg_template/message_templates/contribution_recurring_billing_text.tpl deleted file mode 100644 index 37e7ed7502..0000000000 --- a/civicrm/CRM/Upgrade/4.2.alpha1.msg_template/message_templates/contribution_recurring_billing_text.tpl +++ /dev/null @@ -1,23 +0,0 @@ -{ts 1=$contact.display_name}Dear %1{/ts}, - -{ts 1=$amount 2=$recur_frequency_interval 3=$recur_frequency_unit}Billing details for your recurring contribution of %1, every %2 %3 have been updated.{/ts} - -=========================================================== -{ts}Billing Name and Address{/ts} - -=========================================================== -{$billingName} -{$address} - -{$email} - -=========================================================== -{ts}Credit Card Information{/ts} - -=========================================================== -{$credit_card_type} -{$credit_card_number} -{ts}Expires{/ts}: {$credit_card_exp_date|truncate:7:''|crmDate} - - -{ts 1=$receipt_from_email}If you have questions please contact us at %1{/ts} \ No newline at end of file diff --git a/civicrm/CRM/Upgrade/4.2.alpha1.msg_template/message_templates/contribution_recurring_cancelled_html.tpl b/civicrm/CRM/Upgrade/4.2.alpha1.msg_template/message_templates/contribution_recurring_cancelled_html.tpl deleted file mode 100644 index 606ecda516..0000000000 --- a/civicrm/CRM/Upgrade/4.2.alpha1.msg_template/message_templates/contribution_recurring_cancelled_html.tpl +++ /dev/null @@ -1,33 +0,0 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml"> -<head> - <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> - <title></title> -</head> -<body> - -{capture assign=headerStyle}colspan="2" style="text-align: left; padding: 4px; border-bottom: 1px solid #999; background-color: #eee;"{/capture} -{capture assign=labelStyle }style="padding: 4px; border-bottom: 1px solid #999; background-color: #f7f7f7;"{/capture} -{capture assign=valueStyle }style="padding: 4px; border-bottom: 1px solid #999;"{/capture} - -<center> - <table width="620" border="0" cellpadding="0" cellspacing="0" id="crm-event_receipt" style="font-family: Arial, Verdana, sans-serif; text-align: left;"> - - <!-- BEGIN HEADER --> - <!-- You can add table row(s) here with logo or other header elements --> - <!-- END HEADER --> - - <!-- BEGIN CONTENT --> - - <tr> - <td> - <p>{ts 1=$contact.display_name}Dear %1{/ts},</p> - <p>{ts 1=$amount 2=$recur_frequency_interval 3=$recur_frequency_unit}Your recurring contribution of %1, every %2 %3 has been cancelled.{/ts}</p> - </td> - </tr> - <tr> - </table> -</center> - -</body> -</html> diff --git a/civicrm/CRM/Upgrade/4.2.alpha1.msg_template/message_templates/contribution_recurring_cancelled_subject.tpl b/civicrm/CRM/Upgrade/4.2.alpha1.msg_template/message_templates/contribution_recurring_cancelled_subject.tpl deleted file mode 100644 index d389480e14..0000000000 --- a/civicrm/CRM/Upgrade/4.2.alpha1.msg_template/message_templates/contribution_recurring_cancelled_subject.tpl +++ /dev/null @@ -1 +0,0 @@ -{ts}Recurring Contribution Cancellation Notification{/ts} diff --git a/civicrm/CRM/Upgrade/4.2.alpha1.msg_template/message_templates/contribution_recurring_cancelled_text.tpl b/civicrm/CRM/Upgrade/4.2.alpha1.msg_template/message_templates/contribution_recurring_cancelled_text.tpl deleted file mode 100644 index e9647993dc..0000000000 --- a/civicrm/CRM/Upgrade/4.2.alpha1.msg_template/message_templates/contribution_recurring_cancelled_text.tpl +++ /dev/null @@ -1,3 +0,0 @@ -{ts 1=$contact.display_name}Dear %1{/ts}, - -{ts 1=$amount 2=$recur_frequency_interval 3=$recur_frequency_unit}Your recurring contribution of %1, every %2 %3 has been cancelled.{/ts} diff --git a/civicrm/CRM/Upgrade/4.2.alpha1.msg_template/message_templates/contribution_recurring_edit_html.tpl b/civicrm/CRM/Upgrade/4.2.alpha1.msg_template/message_templates/contribution_recurring_edit_html.tpl deleted file mode 100644 index 7c894beeb0..0000000000 --- a/civicrm/CRM/Upgrade/4.2.alpha1.msg_template/message_templates/contribution_recurring_edit_html.tpl +++ /dev/null @@ -1,36 +0,0 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml"> -<head> - <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> - <title></title> -</head> -<body> - -{capture assign=headerStyle}colspan="2" style="text-align: left; padding: 4px; border-bottom: 1px solid #999; background-color: #eee;"{/capture} -{capture assign=labelStyle }style="padding: 4px; border-bottom: 1px solid #999; background-color: #f7f7f7;"{/capture} -{capture assign=valueStyle }style="padding: 4px; border-bottom: 1px solid #999;"{/capture} - -<center> - <table width="620" border="0" cellpadding="0" cellspacing="0" id="crm-event_receipt" style="font-family: Arial, Verdana, sans-serif; text-align: left;"> - - <!-- BEGIN HEADER --> - <!-- You can add table row(s) here with logo or other header elements --> - <!-- END HEADER --> - - <!-- BEGIN CONTENT --> - - <tr> - <td> - <p>{ts 1=$contact.display_name}Dear %1{/ts},</p> - <p>{ts 1=$amount 2=$recur_frequency_interval 3=$recur_frequency_unit}Recurring contribution is for %1, every %2(s) %3{/ts}</p> - <p>{if $installments}{ts 1=$installments} for %1 installments.{/ts}{/if}</p> - - <p>{ts 1=$receipt_from_email}If you have questions please contact us at %1.{/ts}</p> - </td> - </tr> - <tr> - </table> -</center> - -</body> -</html> diff --git a/civicrm/CRM/Upgrade/4.2.alpha1.msg_template/message_templates/contribution_recurring_edit_subject.tpl b/civicrm/CRM/Upgrade/4.2.alpha1.msg_template/message_templates/contribution_recurring_edit_subject.tpl deleted file mode 100644 index d4a5da1aea..0000000000 --- a/civicrm/CRM/Upgrade/4.2.alpha1.msg_template/message_templates/contribution_recurring_edit_subject.tpl +++ /dev/null @@ -1 +0,0 @@ -{ts}Recurring Contribution Update Notification{/ts} \ No newline at end of file diff --git a/civicrm/CRM/Upgrade/4.2.alpha1.msg_template/message_templates/contribution_recurring_edit_text.tpl b/civicrm/CRM/Upgrade/4.2.alpha1.msg_template/message_templates/contribution_recurring_edit_text.tpl deleted file mode 100644 index 423b00c9cd..0000000000 --- a/civicrm/CRM/Upgrade/4.2.alpha1.msg_template/message_templates/contribution_recurring_edit_text.tpl +++ /dev/null @@ -1,8 +0,0 @@ -{ts 1=$contact.display_name}Dear %1{/ts}, - -{ts}Your recurring contribution has been updated as requested:{/ts} - -{ts 1=$amount 2=$recur_frequency_interval 3=$recur_frequency_unit}Recurring contribution is for %1, every %2(s) %3{/ts} -{if $installments}{ts 1=$installments} for %1 installments.{/ts}{/if} - -{ts 1=$receipt_from_email}If you have questions please contact us at %1.{/ts} \ No newline at end of file diff --git a/civicrm/CRM/Upgrade/4.2.alpha1.msg_template/message_templates/contribution_recurring_notify_html.tpl b/civicrm/CRM/Upgrade/4.2.alpha1.msg_template/message_templates/contribution_recurring_notify_html.tpl deleted file mode 100644 index 3a6b18bac1..0000000000 --- a/civicrm/CRM/Upgrade/4.2.alpha1.msg_template/message_templates/contribution_recurring_notify_html.tpl +++ /dev/null @@ -1,125 +0,0 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml"> -<head> - <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> - <title></title> -</head> -<body> - -{capture assign=headerStyle}colspan="2" style="text-align: left; padding: 4px; border-bottom: 1px solid #999; background-color: #eee;"{/capture} -{capture assign=labelStyle }style="padding: 4px; border-bottom: 1px solid #999; background-color: #f7f7f7;"{/capture} -{capture assign=valueStyle }style="padding: 4px; border-bottom: 1px solid #999;"{/capture} - -<center> - <table width="620" border="0" cellpadding="0" cellspacing="0" id="crm-event_receipt" style="font-family: Arial, Verdana, sans-serif; text-align: left;"> - - <!-- BEGIN HEADER --> - <!-- You can add table row(s) here with logo or other header elements --> - <!-- END HEADER --> - - <!-- BEGIN CONTENT --> - - <tr> - <td> - <p>{ts 1=$displayName}Dear %1{/ts},</p> - </td> - </tr> - - <tr> - <td> </td> - </tr> - - {if $recur_txnType eq 'START'} - {if $auto_renew_membership} - <tr> - <td> - <p>{ts}Thanks for your auto renew membership sign-up.{/ts}</p> - <p>{ts 1=$recur_frequency_interval 2=$recur_frequency_unit}This membership will be automatically renewed every %1 %2(s). {/ts}</p> - </td> - </tr> - <tr> - <td {$labelStyle}> - {ts 1=$cancelSubscriptionUrl}This membership will be renewed automatically. You can cancel the auto-renewal option by <a href="%1">visiting this web page</a>.{/ts} - </td> - </tr> - <tr> - <td {$labelStyle}> - {ts 1=$updateSubscriptionBillingUrl}You can update billing details for this automatically renewed membership by <a href="%1">visiting this web page</a>.{/ts} - </td> - </tr> - {else} - <tr> - <td> - <p>{ts}Thanks for your recurring contribution sign-up.{/ts}</p> - <p>{ts 1=$recur_frequency_interval 2=$recur_frequency_unit 3=$recur_installments}This recurring contribution will be automatically processed every %1 %2(s) for a total of %3 installment(s).{/ts}</p> - <p>{ts}Start Date{/ts}: {$recur_start_date|crmDate}</p> - </td> - </tr> - <tr> - <td {$labelStyle}> - {ts 1=$cancelSubscriptionUrl} You can cancel the recurring contribution option by <a href="%1">visiting this web page</a>.{/ts} - </td> - </tr> - <tr> - <td {$labelStyle}> - {ts 1=$updateSubscriptionBillingUrl}You can update billing details for this recurring contribution by <a href="%1">visiting this web page</a>.{/ts} - </td> - </tr> - <tr> - <td {$labelStyle}> - {ts 1=$updateSubscriptionUrl}You can update recurring contribution amount or change the number of installments details for this recurring contribution by <a href="%1">visiting this web page</a>.{/ts} - </td> - </tr> - {/if} - - {elseif $recur_txnType eq 'END'} - - {if $auto_renew_membership} - <tr> - <td> - <p>{ts}Your auto renew membership sign-up has ended and your membership will not be automatically renewed.{/ts}</p> - </td> - </tr> - {else} - <tr> - <td> - <p>{ts}Your recurring contribution term has ended.{/ts}</p> - <p>{ts 1=$recur_installments}You have successfully completed %1 recurring contributions. Thank you for your support.{/ts}</p> - </td> - </tr> - <tr> - <td> - <table style="border: 1px solid #999; margin: 1em 0em 1em; border-collapse: collapse; width:100%;"> - <tr> - <th {$headerStyle}> - {ts 1=$recur_installments}Interval of Subscription for %1 installment(s){/ts} - </th> - </tr> - <tr> - <td {$labelStyle}> - {ts}Start Date{/ts} - </td> - <td {$valueStyle}> - {$recur_start_date|crmDate} - </td> - </tr> - <tr> - <td {$labelStyle}> - {ts}End Date{/ts} - </td> - <td {$valueStyle}> - {$recur_end_date|crmDate} - </td> - </tr> - </table> - </td> - </tr> - - {/if} - {/if} - - </table> -</center> - -</body> -</html> diff --git a/civicrm/CRM/Upgrade/4.2.alpha1.msg_template/message_templates/contribution_recurring_notify_text.tpl b/civicrm/CRM/Upgrade/4.2.alpha1.msg_template/message_templates/contribution_recurring_notify_text.tpl deleted file mode 100644 index 5f54ca1568..0000000000 --- a/civicrm/CRM/Upgrade/4.2.alpha1.msg_template/message_templates/contribution_recurring_notify_text.tpl +++ /dev/null @@ -1,50 +0,0 @@ -{ts 1=$displayName}Dear %1{/ts}, - -{if $recur_txnType eq 'START'} -{if $auto_renew_membership} -{ts}Thanks for your auto renew membership sign-up.{/ts} - - -{ts 1=$recur_frequency_interval 2=$recur_frequency_unit}This membership will be automatically renewed every %1 %2(s).{/ts} - -{ts 1=$cancelSubscriptionUrl}This membership will be renewed automatically. You can cancel the auto-renewal option by <a href="%1">visiting this web page</a>.{/ts} - -{ts 1=$updateSubscriptionBillingUrl}You can update billing details for this automatically renewed membership by <a href="%1">visiting this web page</a>.{/ts} - -{else} -{ts}Thanks for your recurring contribution sign-up.{/ts} - - -{ts 1=$recur_frequency_interval 2=$recur_frequency_unit 3=$recur_installments}This recurring contribution will be automatically processed every %1 %2(s) for a total of %3 installment(s).{/ts} - -{ts}Start Date{/ts}: {$recur_start_date|crmDate} - -{ts 1=$cancelSubscriptionUrl}You can cancel the recurring contribution option by <a href="%1">visiting this web page</a>.{/ts} - -{ts 1=$updateSubscriptionBillingUrl}You can update billing details for this recurring contribution by <a href="%1">visiting this web page</a>.{/ts} - -{ts 1=$updateSubscriptionUrl}You can update recurring contribution amount or change the number of installments for this recurring contribution by <a href="%1">visiting this web page</a>.{/ts} -{/if} - -{elseif $recur_txnType eq 'END'} -{if $auto_renew_membership} -{ts}Your auto renew membership sign-up has ended and your membership will not be automatically renewed.{/ts} - - -{else} -{ts}Your recurring contribution term has ended.{/ts} - - -{ts 1=$recur_installments}You have successfully completed %1 recurring contributions. Thank you for your support.{/ts} - - -================================================== -{ts 1=$recur_installments}Interval of Subscription for %1 installment(s){/ts} - -================================================== -{ts}Start Date{/ts}: {$recur_start_date|crmDate} - -{ts}End Date{/ts}: {$recur_end_date|crmDate} - -{/if} -{/if} diff --git a/civicrm/CRM/Upgrade/4.2.alpha1.msg_template/message_templates/event_online_receipt_html.tpl b/civicrm/CRM/Upgrade/4.2.alpha1.msg_template/message_templates/event_online_receipt_html.tpl deleted file mode 100644 index 2ee5f29d08..0000000000 --- a/civicrm/CRM/Upgrade/4.2.alpha1.msg_template/message_templates/event_online_receipt_html.tpl +++ /dev/null @@ -1,447 +0,0 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml"> -<head> - <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> - <title></title> -</head> -<body> - -{capture assign=headerStyle}colspan="2" style="text-align: left; padding: 4px; border-bottom: 1px solid #999; background-color: #eee;"{/capture} -{capture assign=labelStyle }style="padding: 4px; border-bottom: 1px solid #999; background-color: #f7f7f7;"{/capture} -{capture assign=valueStyle }style="padding: 4px; border-bottom: 1px solid #999;"{/capture} - -<center> - <table width="500" border="0" cellpadding="0" cellspacing="0" id="crm-event_receipt" style="font-family: Arial, Verdana, sans-serif; text-align: left;"> - - <!-- BEGIN HEADER --> - <!-- You can add table row(s) here with logo or other header elements --> - <!-- END HEADER --> - - <!-- BEGIN CONTENT --> - - <tr> - <td> - <p>Dear {contact.display_name},</p> - - {if $event.confirm_email_text AND (not $isOnWaitlist AND not $isRequireApproval)} - <p>{$event.confirm_email_text|htmlize}</p> - - {else} - <p>Thank you for your participation. This letter is a confirmation that your registration has been received and your status has been updated to <strong>{if $isOnWaitlist}waitlisted{else}registered{/if}</strong> for the following:</p> - - {/if} - - <p> - {if $isOnWaitlist} - <p>{ts}You have been added to the WAIT LIST for this event.{/ts}</p> - {if $isPrimary} - <p>{ts}If space becomes available you will receive an email with a link to a web page where you can complete your registration.{/ts}</p> - {/if} - {elseif $isRequireApproval} - <p>{ts}Your registration has been submitted.{/ts}</p> - {if $isPrimary} - <p>{ts}Once your registration has been reviewed, you will receive an email with a link to a web page where you can complete the registration process.{/ts}</p> - {/if} - {elseif $is_pay_later && !$isAmountzero} - <p>{$pay_later_receipt}</p> {* FIXME: this might be text rather than HTML *} - {else} - <p>{ts}Please print this confirmation for your records.{/ts}</p> - {/if} - - </td> - </tr> - <tr> - <td> - <table width="500" style="border: 1px solid #999; margin: 1em 0em 1em; border-collapse: collapse;"> - <tr> - <th {$headerStyle}> - {ts}Event Information and Location{/ts} - </th> - </tr> - <tr> - <td colspan="2" {$valueStyle}> - {$event.event_title}<br /> - {$event.event_start_date|date_format:"%A"} {$event.event_start_date|crmDate}{if $event.event_end_date}-{if $event.event_end_date|date_format:"%Y%m%d" == $event.event_start_date|date_format:"%Y%m%d"}{$event.event_end_date|crmDate:0:1}{else}{$event.event_end_date|date_format:"%A"} {$event.event_end_date|crmDate}{/if}{/if} - </td> - </tr> - - - {if $conference_sessions} - <tr> - <td colspan="2" {$labelStyle}> - {ts}Your schedule:{/ts} - </td> - </tr> - <tr> - <td colspan="2" {$valueStyle}> - {assign var='group_by_day' value='NA'} - {foreach from=$conference_sessions item=session} - {if $session.start_date|date_format:"%Y/%m/%d" != $group_by_day|date_format:"%Y/%m/%d"} - {assign var='group_by_day' value=$session.start_date} - <em>{$group_by_day|date_format:"%m/%d/%Y"}</em><br /> - {/if} - {$session.start_date|crmDate:0:1}{if $session.end_date}-{$session.end_date|crmDate:0:1}{/if} {$session.title}<br /> - {if $session.location} {$session.location}<br />{/if} - {/foreach} - </td> - </tr> - {/if} - - {if $event.participant_role neq 'Attendee' and $defaultRole} - <tr> - <td {$labelStyle}> - {ts}Participant Role{/ts} - </td> - <td {$valueStyle}> - {$event.participant_role} - </td> - </tr> - {/if} - - {if $isShowLocation} - <tr> - <td colspan="2" {$valueStyle}> - {if $location.address.1.name} - {$location.address.1.name}<br /> - {/if} - {if $location.address.1.street_address} - {$location.address.1.street_address}<br /> - {/if} - {if $location.address.1.supplemental_address_1} - {$location.address.1.supplemental_address_1}<br /> - {/if} - {if $location.address.1.supplemental_address_2} - {$location.address.1.supplemental_address_2}<br /> - {/if} - {if $location.address.1.city} - {$location.address.1.city}, {$location.address.1.state_province} {$location.address.1.postal_code}{if $location.address.1.postal_code_suffix} - {$location.address.1.postal_code_suffix}{/if}<br /> - {/if} - </td> - </tr> - {/if} - - {if $location.phone.1.phone || $location.email.1.email} - <tr> - <td colspan="2" {$labelStyle}> - {ts}Event Contacts:{/ts} - </td> - </tr> - {foreach from=$location.phone item=phone} - {if $phone.phone} - <tr> - <td {$labelStyle}> - {if $phone.phone_type} - {$phone.phone_type_display} - {else} - {ts}Phone{/ts} - {/if} - </td> - <td {$valueStyle}> - {$phone.phone} - </td> - </tr> - {/if} - {/foreach} - {foreach from=$location.email item=eventEmail} - {if $eventEmail.email} - <tr> - <td {$labelStyle}> - {ts}Email{/ts} - </td> - <td {$valueStyle}> - {$eventEmail.email} - </td> - </tr> - {/if} - {/foreach} - {/if} - <tr> - <td colspan="2" {$valueStyle}> - {capture assign=icalFeed}{crmURL p='civicrm/event/ical' q="reset=1&id=`$event.id`" h=0 a=1 fe=1}{/capture} - <a href="{$icalFeed}">{ts}Download iCalendar File{/ts}</a> - </td> - </tr> - {if $event.is_share} - <tr> - <td colspan="2" {$valueStyle}> - {capture assign=eventUrl}{crmURL p='civicrm/event/info' q="id=`$event.id`&reset=1" a=true fe=1 h=1}{/capture} - {include file="CRM/common/SocialNetwork.tpl" emailMode=true url=$eventUrl title=$event.title pageURL=$eventUrl} - </td> - </tr> - {/if} - {if $payer.name} - <tr> - <th {$headerStyle}> - {ts}You were registered by:{/ts} - </th> - </tr> - <tr> - <td colspan="2" {$valueStyle}> - {$payer.name} - </td> - </tr> - {/if} - {if $event.is_monetary} - - <tr> - <th {$headerStyle}> - {$event.fee_label} - </th> - </tr> - - {if $lineItem} - {foreach from=$lineItem item=value key=priceset} - {if $value neq 'skip'} - {if $isPrimary} - {if $lineItem|@count GT 1} {* Header for multi participant registration cases. *} - <tr> - <td colspan="2" {$labelStyle}> - {ts 1=$priceset+1}Participant %1{/ts} {$part.$priceset.info} - </td> - </tr> - {/if} - {/if} - <tr> - <td colspan="2" {$valueStyle}> - <table> {* FIXME: style this table so that it looks like the text version (justification, etc.) *} - <tr> - <th>{ts}Item{/ts}</th> - <th>{ts}Qty{/ts}</th> - <th>{ts}Each{/ts}</th> - <th>{ts}Total{/ts}</th> - {if $pricesetFieldsCount }<th>{ts}Total Participants{/ts}</th>{/if} - </tr> - {foreach from=$value item=line} - <tr> - <td> - {if $line.html_type eq 'Text'}{$line.label}{else}{$line.field_title} - {$line.label}{/if} {if $line.description}<div>{$line.description|truncate:30:"..."}</div>{/if} - </td> - <td> - {$line.qty} - </td> - <td> - {$line.unit_price|crmMoney} - </td> - <td> - {$line.line_total|crmMoney} - </td> - {if $pricesetFieldsCount }<td>{$line.participant_count}</td> {/if} - </tr> - {/foreach} - </table> - </td> - </tr> - {/if} - {/foreach} - {/if} - - - {if $isPrimary} - <tr> - <td {$labelStyle}> - {ts}Total Amount{/ts} - </td> - <td {$valueStyle}> - {$totalAmount|crmMoney} {if $hookDiscount.message}({$hookDiscount.message}){/if} - </td> - </tr> - {if $pricesetFieldsCount } - <tr> - <td {$labelStyle}> - {ts}Total Participants{/ts}</td> - <td {$valueStyle}> - {assign var="count" value= 0} - {foreach from=$lineItem item=pcount} - {assign var="lineItemCount" value=0} - {if $pcount neq 'skip'} - {foreach from=$pcount item=p_count} - {assign var="lineItemCount" value=$lineItemCount+$p_count.participant_count} - {/foreach} - {if $lineItemCount < 1 } - {assign var="lineItemCount" value=1} - {/if} - {assign var="count" value=$count+$lineItemCount} - {/if} - {/foreach} - {$count} - </td> </tr> - {/if} - {if $is_pay_later} - <tr> - <td colspan="2" {$labelStyle}> - {$pay_later_receipt} - </td> - </tr> - {/if} - - {if $register_date} - <tr> - <td {$labelStyle}> - {ts}Registration Date{/ts} - </td> - <td {$valueStyle}> - {$register_date|crmDate} - </td> - </tr> - {/if} - - {if $receive_date} - <tr> - <td {$labelStyle}> - {ts}Transaction Date{/ts} - </td> - <td {$valueStyle}> - {$receive_date|crmDate} - </td> - </tr> - {/if} - - {if $contributionTypeName} - <tr> - <td {$labelStyle}> - {ts}Contribution Type{/ts} - </td> - <td {$valueStyle}> - {$contributionTypeName} - </td> - </tr> - {/if} - - {if $trxn_id} - <tr> - <td {$labelStyle}> - {ts}Transaction #{/ts} - </td> - <td {$valueStyle}> - {$trxn_id} - </td> - </tr> - {/if} - - {if $paidBy} - <tr> - <td {$labelStyle}> - {ts}Paid By{/ts} - </td> - <td {$valueStyle}> - {$paidBy} - </td> - </tr> - {/if} - - {if $checkNumber} - <tr> - <td {$labelStyle}> - {ts}Check Number{/ts} - </td> - <td {$valueStyle}> - {$checkNumber} - </td> - </tr> - {/if} - - {if $contributeMode ne 'notify' and !$isAmountzero and !$is_pay_later and !$isOnWaitlist and !$isRequireApproval} - <tr> - <th {$headerStyle}> - {ts}Billing Name and Address{/ts} - </th> - </tr> - <tr> - <td colspan="2" {$valueStyle}> - {$billingName}<br /> - {$address|nl2br} - </td> - </tr> - {/if} - - {if $contributeMode eq 'direct' and !$isAmountzero and !$is_pay_later and !$isOnWaitlist and !$isRequireApproval} - <tr> - <th {$headerStyle}> - {ts}Credit Card Information{/ts} - </th> - </tr> - <tr> - <td colspan="2" {$valueStyle}> - {$credit_card_type}<br /> - {$credit_card_number}<br /> - {ts}Expires{/ts}: {$credit_card_exp_date|truncate:7:''|crmDate} - </td> - </tr> - {/if} - - {/if} - - {/if} {* End of conditional section for Paid events *} - - -{if $customPre} -{foreach from=$customPre item=customPr key=i} - <tr> <th {$headerStyle}>{$customPre_grouptitle.$i}</th></tr> - {foreach from=$customPr item=customValue key=customName} - {if ( $trackingFields and ! in_array( $customName, $trackingFields ) ) or ! $trackingFields} - <tr> - <td {$labelStyle}>{$customName}</td> - <td {$valueStyle}>{$customValue}</td> - </tr> - {/if} - {/foreach} -{/foreach} -{/if} - -{if $customPost} -{foreach from=$customPost item=customPos key=j} - <tr> <th {$headerStyle}>{$customPost_grouptitle.$j}</th></tr> - {foreach from=$customPos item=customValue key=customName} - {if ( $trackingFields and ! in_array( $customName, $trackingFields ) ) or ! $trackingFields} - <tr> - <td {$labelStyle}>{$customName}</td> - <td {$valueStyle}>{$customValue}</td> - </tr> -{/if} -{/foreach} -{/foreach} -{/if} - -{if $customProfile} -{foreach from=$customProfile.profile item=eachParticipant key=participantID} - <tr><th {$headerStyle}>{ts 1=$participantID+2}Participant %1{/ts} </th></tr> - {foreach from=$eachParticipant item=eachProfile key=pid} - <tr><th {$headerStyle}>{$customProfile.title.$pid}</th></tr> - {foreach from=$eachProfile item=val key=field} - <tr>{foreach from=$val item=v key=f} - <td {$labelStyle}>{$field}</td> - <td {$valueStyle}>{$v}</td> - {/foreach} - </tr> - {/foreach} -{/foreach} -{/foreach} -{/if} - - {if $customGroup} - {foreach from=$customGroup item=value key=customName} - <tr> - <th {$headerStyle}> - {$customName} - </th> - </tr> - {foreach from=$value item=v key=n} - <tr> - <td {$labelStyle}> - {$n} - </td> - <td {$valueStyle}> - {$v} - </td> - </tr> - {/foreach} - {/foreach} - {/if} - </table> - </td> - </tr> - </table> -</center> - -</body> -</html> diff --git a/civicrm/CRM/Upgrade/4.2.alpha1.msg_template/message_templates/event_online_receipt_text.tpl b/civicrm/CRM/Upgrade/4.2.alpha1.msg_template/message_templates/event_online_receipt_text.tpl deleted file mode 100644 index 27c37624d8..0000000000 --- a/civicrm/CRM/Upgrade/4.2.alpha1.msg_template/message_templates/event_online_receipt_text.tpl +++ /dev/null @@ -1,282 +0,0 @@ -Dear {contact.display_name}, - -{if $event.confirm_email_text AND (not $isOnWaitlist AND not $isRequireApproval)} -{$event.confirm_email_text} - -{else} -Thank you for your participation. This letter is a confirmation that your registration has been received and your status has been updated to {if $participant_status}$participant_status{else}{if $isOnWaitlist}waitlisted{else}registered{/if}{/if} for the following: - -{/if} - -{if $isOnWaitlist} -==========================================================={if $pricesetFieldsCount }===================={/if} - -{ts}You have been added to the WAIT LIST for this event.{/ts} - -{if $isPrimary} -{ts}If space becomes available you will receive an email with a link to a web page where you can complete your registration.{/ts} -{/if} -==========================================================={if $pricesetFieldsCount }===================={/if} - -{elseif $isRequireApproval} -==========================================================={if $pricesetFieldsCount }===================={/if} - -{ts}Your registration has been submitted.{/ts} - -{if $isPrimary} -{ts}Once your registration has been reviewed, you will receive an email with a link to a web page where you can complete the registration process.{/ts} - -{/if} -==========================================================={if $pricesetFieldsCount }===================={/if} - -{elseif $is_pay_later && !$isAmountzero} - -==========================================================={if $pricesetFieldsCount }===================={/if} - -{$pay_later_receipt} -==========================================================={if $pricesetFieldsCount }===================={/if} - -{else} - -{ts}Please print this confirmation for your records.{/ts} -{/if} - - -==========================================================={if $pricesetFieldsCount }===================={/if} - -{ts}Event Information and Location{/ts} - -==========================================================={if $pricesetFieldsCount }===================={/if} - -{$event.event_title} -{$event.event_start_date|date_format:"%A"} {$event.event_start_date|crmDate}{if $event.event_end_date}-{if $event.event_end_date|date_format:"%Y%m%d" == $event.event_start_date|date_format:"%Y%m%d"}{$event.event_end_date|crmDate:0:1}{else}{$event.event_end_date|date_format:"%A"} {$event.event_end_date|crmDate}{/if}{/if} -{if $conference_sessions} - - -{ts}Your schedule:{/ts} -{assign var='group_by_day' value='NA'} -{foreach from=$conference_sessions item=session} -{if $session.start_date|date_format:"%Y/%m/%d" != $group_by_day|date_format:"%Y/%m/%d"} -{assign var='group_by_day' value=$session.start_date} - -{$group_by_day|date_format:"%m/%d/%Y"} - - -{/if} -{$session.start_date|crmDate:0:1}{if $session.end_date}-{$session.end_date|crmDate:0:1}{/if} {$session.title} -{if $session.location} {$session.location}{/if} -{/foreach} -{/if} - -{if $event.participant_role neq 'Attendee' and $defaultRole} -{ts}Participant Role{/ts}: {$event.participant_role} -{/if} - -{if $isShowLocation} -{if $location.address.1.name} - -{$location.address.1.name} -{/if} -{if $location.address.1.street_address}{$location.address.1.street_address} -{/if} -{if $location.address.1.supplemental_address_1}{$location.address.1.supplemental_address_1} -{/if} -{if $location.address.1.supplemental_address_2}{$location.address.1.supplemental_address_2} -{/if} -{if $location.address.1.city}{$location.address.1.city}, {$location.address.1.state_province} {$location.address.1.postal_code}{if $location.address.1.postal_code_suffix} - {$location.address.1.postal_code_suffix}{/if} -{/if} - -{/if}{*End of isShowLocation condition*} - -{if $location.phone.1.phone || $location.email.1.email} - -{ts}Event Contacts:{/ts} -{foreach from=$location.phone item=phone} -{if $phone.phone} - -{if $phone.phone_type}{$phone.phone_type_display}{else}{ts}Phone{/ts}{/if}: {$phone.phone}{/if} -{/foreach} -{foreach from=$location.email item=eventEmail} -{if $eventEmail.email} - -{ts}Email{/ts}: {$eventEmail.email}{/if}{/foreach} -{/if} - -{capture assign=icalFeed}{crmURL p='civicrm/event/ical' q="reset=1&id=`$event.id`" h=0 a=1 fe=1}{/capture} -{ts}Download iCalendar File:{/ts} {$icalFeed} - -{if $payer.name} -You were registered by: {$payer.name} -{/if} -{if $event.is_monetary} {* This section for Paid events only.*} - -==========================================================={if $pricesetFieldsCount }===================={/if} - -{$event.fee_label} -==========================================================={if $pricesetFieldsCount }===================={/if} - -{if $lineItem}{foreach from=$lineItem item=value key=priceset} - -{if $value neq 'skip'} -{if $isPrimary} -{if $lineItem|@count GT 1} {* Header for multi participant registration cases. *} -{ts 1=$priceset+1}Participant %1{/ts} {$part.$priceset.info} - -{/if} -{/if} ------------------------------------------------------------{if $pricesetFieldsCount }--------------------{/if} - -{capture assign=ts_item}{ts}Item{/ts}{/capture} -{capture assign=ts_qty}{ts}Qty{/ts}{/capture} -{capture assign=ts_each}{ts}Each{/ts}{/capture} -{capture assign=ts_total}{ts}Total{/ts}{/capture} -{if $pricesetFieldsCount }{capture assign=ts_participant_total}{ts}Total Participants{/ts}{/capture}{/if} -{$ts_item|string_format:"%-30s"} {$ts_qty|string_format:"%5s"} {$ts_each|string_format:"%10s"} {$ts_total|string_format:"%10s"} {$ts_participant_total|string_format:"%10s"} ------------------------------------------------------------{if $pricesetFieldsCount }--------------------{/if} - -{foreach from=$value item=line} -{if $pricesetFieldsCount }{capture assign=ts_participant_count}{$line.participant_count}{/capture}{/if} -{capture assign=ts_item}{if $line.html_type eq 'Text'}{$line.label}{else}{$line.field_title} - {$line.label}{/if} {if $line.description} {$line.description}{/if}{/capture}{$ts_item|truncate:30:"..."|string_format:"%-30s"} {$line.qty|string_format:"%5s"} {$line.unit_price|crmMoney|string_format:"%10s"} {$line.line_total|crmMoney|string_format:"%10s"}{$ts_participant_count|string_format:"%10s"} -{/foreach} -{/if} -{/foreach} -{/if} -{if $isPrimary } - -{ts}Total Amount{/ts}: {$totalAmount|crmMoney} {if $hookDiscount.message}({$hookDiscount.message}){/if} - -{if $pricesetFieldsCount } - {assign var="count" value= 0} - {foreach from=$lineItem item=pcount} - {assign var="lineItemCount" value=0} - {if $pcount neq 'skip'} - {foreach from=$pcount item=p_count} - {assign var="lineItemCount" value=$lineItemCount+$p_count.participant_count} - {/foreach} - {if $lineItemCount < 1 } - {assign var="lineItemCount" value=1} - {/if} - {assign var="count" value=$count+$lineItemCount} - {/if} - {/foreach} - -{ts}Total Participants{/ts}: {$count} -{/if} - -{if $is_pay_later} - -==========================================================={if $pricesetFieldsCount }===================={/if} - -{$pay_later_receipt} -==========================================================={if $pricesetFieldsCount }===================={/if} - -{/if} - -{if $register_date} -{ts}Registration Date{/ts}: {$register_date|crmDate} -{/if} -{if $receive_date} -{ts}Transaction Date{/ts}: {$receive_date|crmDate} -{/if} -{if $contributionTypeName} -{ts}Contribution Type{/ts}: {$contributionTypeName} -{/if} -{if $trxn_id} -{ts}Transaction #{/ts}: {$trxn_id} -{/if} -{if $paidBy} -{ts}Paid By{/ts}: {$paidBy} -{/if} -{if $checkNumber} -{ts}Check Number{/ts}: {$checkNumber} -{/if} -{if $contributeMode ne 'notify' and !$isAmountzero and !$is_pay_later and !$isOnWaitlist and !$isRequireApproval} - -==========================================================={if $pricesetFieldsCount }===================={/if} - -{ts}Billing Name and Address{/ts} - -==========================================================={if $pricesetFieldsCount }===================={/if} - -{$billingName} -{$address} -{/if} - -{if $contributeMode eq 'direct' and !$isAmountzero and !$is_pay_later and !$isOnWaitlist and !$isRequireApproval} -==========================================================={if $pricesetFieldsCount }===================={/if} - -{ts}Credit Card Information{/ts} - -==========================================================={if $pricesetFieldsCount }===================={/if} - -{$credit_card_type} -{$credit_card_number} -{ts}Expires{/ts}: {$credit_card_exp_date|truncate:7:''|crmDate} -{/if} -{/if} -{/if} {* End of conditional section for Paid events *} - -{if $customPre} -{foreach from=$customPre item=customPr key=i} -==========================================================={if $pricesetFieldsCount }===================={/if} - -{$customPre_grouptitle.$i} -==========================================================={if $pricesetFieldsCount }===================={/if} - -{foreach from=$customPr item=customValue key=customName} -{if ( $trackingFields and ! in_array( $customName, $trackingFields ) ) or ! $trackingFields} - {$customName}: {$customValue} -{/if} -{/foreach} -{/foreach} -{/if} - -{if $customPost} -{foreach from=$customPost item=customPos key=j} -==========================================================={if $pricesetFieldsCount }===================={/if} - -{$customPost_grouptitle.$j} -==========================================================={if $pricesetFieldsCount }===================={/if} - -{foreach from=$customPos item=customValue key=customName} -{if ( $trackingFields and ! in_array( $customName, $trackingFields ) ) or ! $trackingFields} - {$customName}: {$customValue} -{/if} -{/foreach} -{/foreach} -{/if} -{if $customProfile} - -{foreach from=$customProfile.profile item=eachParticipant key=participantID} -==========================================================={if $pricesetFieldsCount }===================={/if} - -{ts 1=$participantID+2}Participant Information - Participant %1{/ts} - -==========================================================={if $pricesetFieldsCount }===================={/if} - -{foreach from=$eachParticipant item=eachProfile key=pid} -----------------------------------------------------------{if $pricesetFieldsCount }--------------------{/if} - -{$customProfile.title.$pid} -----------------------------------------------------------{if $pricesetFieldsCount }--------------------{/if} - -{foreach from=$eachProfile item=val key=field} -{foreach from=$val item=v key=f} -{$field}: {$v} -{/foreach} -{/foreach} -{/foreach} -{/foreach} -{/if} -{if $customGroup} -{foreach from=$customGroup item=value key=customName} -=========================================================={if $pricesetFieldsCount }===================={/if} - -{$customName} -=========================================================={if $pricesetFieldsCount }===================={/if} - -{foreach from=$value item=v key=n} -{$n}: {$v} -{/foreach} -{/foreach} -{/if} diff --git a/civicrm/CRM/Upgrade/4.2.alpha1.msg_template/message_templates/membership_autorenew_billing_html.tpl b/civicrm/CRM/Upgrade/4.2.alpha1.msg_template/message_templates/membership_autorenew_billing_html.tpl deleted file mode 100644 index 0277abcb0d..0000000000 --- a/civicrm/CRM/Upgrade/4.2.alpha1.msg_template/message_templates/membership_autorenew_billing_html.tpl +++ /dev/null @@ -1,65 +0,0 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml"> -<head> - <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> - <title></title> -</head> -<body> - -{capture assign=headerStyle}colspan="2" style="text-align: left; padding: 4px; border-bottom: 1px solid #999; background-color: #eee;"{/capture} -{capture assign=labelStyle }style="padding: 4px; border-bottom: 1px solid #999; background-color: #f7f7f7;"{/capture} -{capture assign=valueStyle }style="padding: 4px; border-bottom: 1px solid #999;"{/capture} - -<center> - <table width="620" border="0" cellpadding="0" cellspacing="0" id="crm-event_receipt" style="font-family: Arial, Verdana, sans-serif; text-align: left;"> - - <!-- BEGIN HEADER --> - <!-- You can add table row(s) here with logo or other header elements --> - <!-- END HEADER --> - - <!-- BEGIN CONTENT --> - - <tr> - <td> - <p>{ts 1=$contact.display_name}Dear %1{/ts},</p> - <p>{ts 1=$membershipType}Billing details for your automatically renewed %1 membership have been updated.{/ts}</p> - </td> - </tr> - <tr> - </table> - - <table width="500" style="border: 1px solid #999; margin: 1em 0em 1em; border-collapse: collapse;"> -<tr> - <th {$headerStyle}> - {ts}Billing Name and Address{/ts} - </th> - </tr> - <tr> - <td colspan="2" {$valueStyle}> - {$billingName}<br /> - {$address|nl2br}<br /> - {$email} - </td> - </tr> - <tr> - <th {$headerStyle}> - {ts}Credit Card Information{/ts} - </th> - </tr> - <tr> - <td colspan="2" {$valueStyle}> - {$credit_card_type}<br /> - {$credit_card_number}<br /> - {ts}Expires{/ts}: {$credit_card_exp_date|truncate:7:''|crmDate}<br /> - </td> - </tr> - <tr> - <td {$labelStyle}> - {ts 1=$receipt_from_email}If you have questions please contact us at %1{/ts} - </td> - </tr> - </table> -</center> - -</body> -</html> diff --git a/civicrm/CRM/Upgrade/4.2.alpha1.msg_template/message_templates/membership_autorenew_billing_subject.tpl b/civicrm/CRM/Upgrade/4.2.alpha1.msg_template/message_templates/membership_autorenew_billing_subject.tpl deleted file mode 100644 index ca21f407c0..0000000000 --- a/civicrm/CRM/Upgrade/4.2.alpha1.msg_template/message_templates/membership_autorenew_billing_subject.tpl +++ /dev/null @@ -1 +0,0 @@ -{ts}Membership Autorenewal Updates{/ts} \ No newline at end of file diff --git a/civicrm/CRM/Upgrade/4.2.alpha1.msg_template/message_templates/membership_autorenew_billing_text.tpl b/civicrm/CRM/Upgrade/4.2.alpha1.msg_template/message_templates/membership_autorenew_billing_text.tpl deleted file mode 100644 index 8df337a3a2..0000000000 --- a/civicrm/CRM/Upgrade/4.2.alpha1.msg_template/message_templates/membership_autorenew_billing_text.tpl +++ /dev/null @@ -1,23 +0,0 @@ -{ts 1=$contact.display_name}Dear %1{/ts}, - -{ts 1=$membershipType}Billing details for your automatically renewed %1 membership have been updated.{/ts} - -=========================================================== -{ts}Billing Name and Address{/ts} - -=========================================================== -{$billingName} -{$address} - -{$email} - -=========================================================== -{ts}Credit Card Information{/ts} - -=========================================================== -{$credit_card_type} -{$credit_card_number} -{ts}Expires{/ts}: {$credit_card_exp_date|truncate:7:''|crmDate} - - -{ts 1=$receipt_from_email}If you have questions please contact us at %1{/ts} \ No newline at end of file diff --git a/civicrm/CRM/Upgrade/4.2.alpha1.msg_template/message_templates/membership_autorenew_cancelled_html.tpl b/civicrm/CRM/Upgrade/4.2.alpha1.msg_template/message_templates/membership_autorenew_cancelled_html.tpl deleted file mode 100644 index 77e11ff632..0000000000 --- a/civicrm/CRM/Upgrade/4.2.alpha1.msg_template/message_templates/membership_autorenew_cancelled_html.tpl +++ /dev/null @@ -1,70 +0,0 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml"> -<head> - <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> - <title></title> -</head> -<body> - -{capture assign=headerStyle}colspan="2" style="text-align: left; padding: 4px; border-bottom: 1px solid #999; background-color: #eee;"{/capture} -{capture assign=labelStyle }style="padding: 4px; border-bottom: 1px solid #999; background-color: #f7f7f7;"{/capture} -{capture assign=valueStyle }style="padding: 4px; border-bottom: 1px solid #999;"{/capture} - -<center> - <table width="500" border="0" cellpadding="0" cellspacing="0" id="crm-event_receipt" style="font-family: Arial, Verdana, sans-serif; text-align: left;"> - - <!-- BEGIN HEADER --> - <!-- You can add table row(s) here with logo or other header elements --> - <!-- END HEADER --> - - <!-- BEGIN CONTENT --> - - <tr> - <td> - - <p>{ts 1=$membershipType}The automatic renewal of your %1 membership has been cancelled as requested. This does not affect the status of your membership - you will receive a separate notification when your membership is up for renewal.{/ts}</p> - - </td> - </tr> - </table> - <table width="500" style="border: 1px solid #999; margin: 1em 0em 1em; border-collapse: collapse;"> - - <tr> - <th {$headerStyle}> - {ts}Membership Information{/ts} - </th> - </tr> - <tr> - <td {$labelStyle}> - {ts}Membership Status{/ts} - </td> - <td {$valueStyle}> - {$membership_status} - </td> - </tr> - {if $mem_start_date} - <tr> - <td {$labelStyle}> - {ts}Membership Start Date{/ts} - </td> - <td {$valueStyle}> - {$mem_start_date|crmDate} - </td> - </tr> - {/if} - {if $mem_end_date} - <tr> - <td {$labelStyle}> - {ts}Membership End Date{/ts} - </td> - <td {$valueStyle}> - {$mem_end_date|crmDate} - </td> - </tr> - {/if} - - </table> -</center> - -</body> -</html> diff --git a/civicrm/CRM/Upgrade/4.2.alpha1.msg_template/message_templates/membership_autorenew_cancelled_subject.tpl b/civicrm/CRM/Upgrade/4.2.alpha1.msg_template/message_templates/membership_autorenew_cancelled_subject.tpl deleted file mode 100644 index ccfb0de98f..0000000000 --- a/civicrm/CRM/Upgrade/4.2.alpha1.msg_template/message_templates/membership_autorenew_cancelled_subject.tpl +++ /dev/null @@ -1 +0,0 @@ -{ts}Autorenew Membership Cancellation Notification{/ts} diff --git a/civicrm/CRM/Upgrade/4.2.alpha1.msg_template/message_templates/membership_autorenew_cancelled_text.tpl b/civicrm/CRM/Upgrade/4.2.alpha1.msg_template/message_templates/membership_autorenew_cancelled_text.tpl deleted file mode 100644 index 51cec8cff6..0000000000 --- a/civicrm/CRM/Upgrade/4.2.alpha1.msg_template/message_templates/membership_autorenew_cancelled_text.tpl +++ /dev/null @@ -1,12 +0,0 @@ -{ts 1=$membershipType}The automatic renewal of your %1 membership has been cancelled as requested. This does not affect the status of your membership - you will receive a separate notification when your membership is up for renewal.{/ts} - -=========================================================== -{ts}Membership Information{/ts} - -=========================================================== -{ts}Membership Status{/ts}: {$membership_status} -{if $mem_start_date}{ts}Membership Start Date{/ts}: {$mem_start_date|crmDate} -{/if} -{if $mem_end_date}{ts}Membership End Date{/ts}: {$mem_end_date|crmDate} -{/if} - diff --git a/civicrm/CRM/Upgrade/4.2.alpha1.msg_template/message_templates/membership_online_receipt_html.tpl b/civicrm/CRM/Upgrade/4.2.alpha1.msg_template/message_templates/membership_online_receipt_html.tpl deleted file mode 100644 index 7182d55d9d..0000000000 --- a/civicrm/CRM/Upgrade/4.2.alpha1.msg_template/message_templates/membership_online_receipt_html.tpl +++ /dev/null @@ -1,517 +0,0 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml"> -<head> - <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> - <title></title> -</head> -<body> - -{capture assign=headerStyle}colspan="2" style="text-align: left; padding: 4px; border-bottom: 1px solid #999; background-color: #eee;"{/capture} -{capture assign=labelStyle }style="padding: 4px; border-bottom: 1px solid #999; background-color: #f7f7f7;"{/capture} -{capture assign=valueStyle }style="padding: 4px; border-bottom: 1px solid #999;"{/capture} - -<center> - <table width="500" border="0" cellpadding="0" cellspacing="0" id="crm-event_receipt" style="font-family: Arial, Verdana, sans-serif; text-align: left;"> - - <!-- BEGIN HEADER --> - <!-- You can add table row(s) here with logo or other header elements --> - <!-- END HEADER --> - - <!-- BEGIN CONTENT --> - - <tr> - <td> - - {if $receipt_text} - <p>{$receipt_text|htmlize}</p> - {/if} - - {if $is_pay_later} - <p>{$pay_later_receipt}</p> {* FIXME: this might be text rather than HTML *} - {else} - <p>{ts}Please print this confirmation for your records.{/ts}</p> - {/if} - - </td> - </tr> - </table> - <table width="500" style="border: 1px solid #999; margin: 1em 0em 1em; border-collapse: collapse;"> - - {if $membership_assign} - <tr> - <th {$headerStyle}> - {ts}Membership Information{/ts} - </th> - </tr> - <tr> - <td {$labelStyle}> - {ts}Membership Type{/ts} - </td> - <td {$valueStyle}> - {$membership_name} - </td> - </tr> - {if $mem_start_date} - <tr> - <td {$labelStyle}> - {ts}Membership Start Date{/ts} - </td> - <td {$valueStyle}> - {$mem_start_date|crmDate} - </td> - </tr> - {/if} - {if $mem_end_date} - <tr> - <td {$labelStyle}> - {ts}Membership End Date{/ts} - </td> - <td {$valueStyle}> - {$mem_end_date|crmDate} - </td> - </tr> - {/if} - {/if} - - - {if $amount} - - - <tr> - <th {$headerStyle}> - {ts}Membership Fee{/ts} - </th> - </tr> - - {if $membership_amount and $is_quick_config} - - <tr> - <td {$labelStyle}> - {ts 1=$membership_name}%1 Membership{/ts} - </td> - <td {$valueStyle}> - {$membership_amount|crmMoney} - </td> - </tr> - {if $amount} - {if ! $is_separate_payment } - <tr> - <td {$labelStyle}> - {ts}Contribution Amount{/ts} - </td> - <td {$valueStyle}> - {$amount|crmMoney} - </td> - </tr> - {else} - <tr> - <td {$labelStyle}> - {ts}Additional Contribution{/ts} - </td> - <td {$valueStyle}> - {$amount|crmMoney} - </td> - </tr> - {/if} - {/if} - <tr> - <td {$labelStyle}> - {ts}Total{/ts} - </td> - <td {$valueStyle}> - {$amount+$membership_amount|crmMoney} - </td> - </tr> - - {elseif !$useForMember && $lineItem and $priceSetID and !$is_quick_config} - - {foreach from=$lineItem item=value key=priceset} - <tr> - <td colspan="2" {$valueStyle}> - <table> {* FIXME: style this table so that it looks like the text version (justification, etc.) *} - <tr> - <th>{ts}Item{/ts}</th> - <th>{ts}Qty{/ts}</th> - <th>{ts}Each{/ts}</th> - <th>{ts}Total{/ts}</th> - </tr> - {foreach from=$value item=line} - <tr> - <td> - {$line.description|truncate:30:"..."} - </td> - <td> - {$line.qty} - </td> - <td> - {$line.unit_price|crmMoney} - </td> - <td> - {$line.line_total|crmMoney} - </td> - </tr> - {/foreach} - </table> - </td> - </tr> - {/foreach} - <tr> - <td {$labelStyle}> - {ts}Total Amount{/ts} - </td> - <td {$valueStyle}> - {$amount|crmMoney} - </td> - </tr> - - {else} - {if $useForMember && $lineItem and !$is_quick_config} - {foreach from=$lineItem item=value key=priceset} - <tr> - <td colspan="2" {$valueStyle}> - <table> {* FIXME: style this table so that it looks like the text version (justification, etc.) *} - <tr> - <th>{ts}Item{/ts}</th> - <th>{ts}Fee{/ts}</th> - <th>{ts}Membership Start Date{/ts}</th> - <th>{ts}Membership End Date{/ts}</th> - </tr> - {foreach from=$value item=line} - <tr> - <td> - {if $line.html_type eq 'Text'}{$line.label}{else}{$line.field_title} - {$line.label}{/if} {if $line.description}<div>{$line.description|truncate:30:"..."}</div>{/if} - </td> - <td> - {$line.line_total|crmMoney} - </td> - <td> - {$line.start_date} - </td> - <td> - {$line.end_date} - </td> - </tr> - {/foreach} - </table> - </td> - </tr> - {/foreach} - {/if} - <tr> - <td {$labelStyle}> - {ts}Amount{/ts} - </td> - <td {$valueStyle}> - {$amount|crmMoney} {if $amount_level} - {$amount_level}{/if} - </td> - </tr> - - {/if} - - - {elseif $membership_amount} - - - <tr> - <th {$headerStyle}> - {ts}Membership Fee{/ts} - </th> - </tr> - <tr> - <td {$labelStyle}> - {ts 1=$membership_name}%1 Membership{/ts} - </td> - <td {$valueStyle}> - {$membership_amount|crmMoney} - </td> - </tr> - - - {/if} - - - {if $receive_date} - <tr> - <td {$labelStyle}> - {ts}Date{/ts} - </td> - <td {$valueStyle}> - {$receive_date|crmDate} - </td> - </tr> - {/if} - - {if $is_monetary and $trxn_id} - <tr> - <td {$labelStyle}> - {ts}Transaction #{/ts} - </td> - <td {$valueStyle}> - {$trxn_id} - </td> - </tr> - {/if} - - {if $membership_trx_id} - <tr> - <td {$labelStyle}> - {ts}Membership Transaction #{/ts} - </td> - <td {$valueStyle}> - {$membership_trx_id} - </td> - </tr> - {/if} - {if $is_recur} - {if $contributeMode eq 'notify' or $contributeMode eq 'directIPN'} - <tr> - <td colspan="2" {$labelStyle}> - {ts 1=$cancelSubscriptionUrl}This membership will be renewed automatically. You can cancel the auto-renewal option by <a href="%1">visiting this web page</a>.{/ts} - </td> - </tr> - <tr> - <td colspan="2" {$labelStyle}> - {ts 1=$updateSubscriptionBillingUrl}You can update billing details for this automatically renewed membership by <a href="%1">visiting this web page</a>.{/ts} - </td> - </tr> - {/if} - {/if} - - {if $honor_block_is_active} - <tr> - <th {$headerStyle}> - {$honor_type} - </th> - </tr> - <tr> - <td colspan="2" {$labelStyle}> - {$honor_prefix} {$honor_first_name} {$honor_last_name} - </td> - </tr> - {if $honor_email} - <tr> - <td {$labelStyle}> - {ts}Honoree Email{/ts} - </td> - <td {$valueStyle}> - {$honor_email} - </td> - </tr> - {/if} - {/if} - - {if $pcpBlock} - <tr> - <th {$headerStyle}> - {ts}Personal Campaign Page{/ts} - </th> - </tr> - <tr> - <td {$labelStyle}> - {ts}Display In Honor Roll{/ts} - </td> - <td {$valueStyle}> - {if $pcp_display_in_roll}{ts}Yes{/ts}{else}{ts}No{/ts}{/if} - </td> - </tr> - {if $pcp_roll_nickname} - <tr> - <td {$labelStyle}> - {ts}Nickname{/ts} - </td> - <td {$valueStyle}> - {$pcp_roll_nickname} - </td> - </tr> - {/if} - {if $pcp_personal_note} - <tr> - <td {$labelStyle}> - {ts}Personal Note{/ts} - </td> - <td {$valueStyle}> - {$pcp_personal_note} - </td> - </tr> - {/if} - {/if} - - {if $onBehalfProfile} - <tr> - <th {$headerStyle}> - {$onBehalfProfile_grouptitle} - </th> - </tr> - {foreach from=$onBehalfProfile item=onBehalfValue key=onBehalfName} - <tr> - <td {$labelStyle}> - {$onBehalfName} - </td> - <td {$valueStyle}> - {$onBehalfValue} - </td> - </tr> - {/foreach} - {/if} - - {if ! ($contributeMode eq 'notify' OR $contributeMode eq 'directIPN') and $is_monetary} - {if $is_pay_later} - <tr> - <th {$headerStyle}> - {ts}Registered Email{/ts} - </th> - </tr> - <tr> - <td colspan="2" {$valueStyle}> - {$email} - </td> - </tr> - {elseif $amount GT 0 OR $membership_amount GT 0} - <tr> - <th {$headerStyle}> - {ts}Billing Name and Address{/ts} - </th> - </tr> - <tr> - <td colspan="2" {$valueStyle}> - {$billingName}<br /> - {$address|nl2br}<br /> - {$email} - </td> - </tr> - {/if} - {/if} - - {if $contributeMode eq 'direct' AND !$is_pay_later AND ($amount GT 0 OR $membership_amount GT 0)} - <tr> - <th {$headerStyle}> - {ts}Credit Card Information{/ts} - </th> - </tr> - <tr> - <td colspan="2" {$valueStyle}> - {$credit_card_type}<br /> - {$credit_card_number}<br /> - {ts}Expires{/ts}: {$credit_card_exp_date|truncate:7:''|crmDate}<br /> - </td> - </tr> - {/if} - - {if $selectPremium} - <tr> - <th {$headerStyle}> - {ts}Premium Information{/ts} - </th> - </tr> - <tr> - <td colspan="2" {$labelStyle}> - {$product_name} - </td> - </tr> - {if $option} - <tr> - <td {$labelStyle}> - {ts}Option{/ts} - </td> - <td {$valueStyle}> - {$option} - </td> - </tr> - {/if} - {if $sku} - <tr> - <td {$labelStyle}> - {ts}SKU{/ts} - </td> - <td {$valueStyle}> - {$sku} - </td> - </tr> - {/if} - {if $start_date} - <tr> - <td {$labelStyle}> - {ts}Start Date{/ts} - </td> - <td {$valueStyle}> - {$start_date|crmDate} - </td> - </tr> - {/if} - {if $end_date} - <tr> - <td {$labelStyle}> - {ts}End Date{/ts} - </td> - <td {$valueStyle}> - {$end_date|crmDate} - </td> - </tr> - {/if} - {if $contact_email OR $contact_phone} - <tr> - <td colspan="2" {$valueStyle}> - <p>{ts}For information about this premium, contact:{/ts}</p> - {if $contact_email} - <p>{$contact_email}</p> - {/if} - {if $contact_phone} - <p>{$contact_phone}</p> - {/if} - </td> - </tr> - {/if} - {if $is_deductible AND $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> - </td> - </tr> - {/if} - {/if} - - {if $customPre} - <tr> - <th {$headerStyle}> - {$customPre_grouptitle} - </th> - </tr> - {foreach from=$customPre item=customValue key=customName} - {if ($trackingFields and ! in_array($customName, $trackingFields)) or ! $trackingFields} - <tr> - <td {$labelStyle}> - {$customName} - </td> - <td {$valueStyle}> - {$customValue} - </td> - </tr> - {/if} - {/foreach} - {/if} - - {if $customPost} - <tr> - <th {$headerStyle}> - {$customPost_grouptitle} - </th> - </tr> - {foreach from=$customPost item=customValue key=customName} - {if ($trackingFields and ! in_array($customName, $trackingFields)) or ! $trackingFields} - <tr> - <td {$labelStyle}> - {$customName} - </td> - <td {$valueStyle}> - {$customValue} - </td> - </tr> - {/if} - {/foreach} - {/if} - - </table> -</center> - -</body> -</html> diff --git a/civicrm/CRM/Upgrade/4.2.alpha1.msg_template/message_templates/membership_online_receipt_text.tpl b/civicrm/CRM/Upgrade/4.2.alpha1.msg_template/message_templates/membership_online_receipt_text.tpl deleted file mode 100644 index 4e2427b6c5..0000000000 --- a/civicrm/CRM/Upgrade/4.2.alpha1.msg_template/message_templates/membership_online_receipt_text.tpl +++ /dev/null @@ -1,220 +0,0 @@ -{if $receipt_text} -{$receipt_text} -{/if} -{if $is_pay_later} - -=========================================================== -{$pay_later_receipt} -=========================================================== -{else} - -{ts}Please print this receipt for your records.{/ts} -{/if} - -{if $membership_assign && !$useForMember} -=========================================================== -{ts}Membership Information{/ts} - -=========================================================== -{ts}Membership Type{/ts}: {$membership_name} -{if $mem_start_date}{ts}Membership Start Date{/ts}: {$mem_start_date|crmDate} -{/if} -{if $mem_end_date}{ts}Membership End Date{/ts}: {$mem_end_date|crmDate} -{/if} - -{/if} -{if $amount} -=========================================================== -{ts}Membership Fee{/ts} - -=========================================================== -{if !$useForMember && $membership_amount } -{ts 1=$membership_name}%1 Membership{/ts}: {$membership_amount|crmMoney} -{if $amount} -{if ! $is_separate_payment } -{ts}Contribution Amount{/ts}: {$amount|crmMoney} -{else} -{ts}Additional Contribution{/ts}: {$amount|crmMoney} -{/if} -{/if} -------------------------------------------- -{ts}Total{/ts}: {$amount+$membership_amount|crmMoney} -{elseif !$useForMember && $lineItem and $priceSetID} -{foreach from=$lineItem item=value key=priceset} ---------------------------------------------------------- -{capture assign=ts_item}{ts}Item{/ts}{/capture} -{capture assign=ts_qty}{ts}Qty{/ts}{/capture} -{capture assign=ts_each}{ts}Each{/ts}{/capture} -{capture assign=ts_total}{ts}Total{/ts}{/capture} -{$ts_item|string_format:"%-30s"} {$ts_qty|string_format:"%5s"} {$ts_each|string_format:"%10s"} {$ts_total|string_format:"%10s"} ----------------------------------------------------------- -{foreach from=$value item=line} -{$line.description|truncate:30:"..."|string_format:"%-30s"} {$line.qty|string_format:"%5s"} {$line.unit_price|crmMoney|string_format:"%10s"} {$line.line_total|crmMoney|string_format:"%10s"} -{/foreach} -{/foreach} - -{ts}Total Amount{/ts}: {$amount|crmMoney} -{else} -{if $useForMember && $lineItem} -{foreach from=$lineItem item=value key=priceset} -{capture assign=ts_item}{ts}Item{/ts}{/capture} -{capture assign=ts_total}{ts}Fee{/ts}{/capture} -{capture assign=ts_start_date}{ts}Membership Start Date{/ts}{/capture} -{capture assign=ts_end_date}{ts}Membership End Date{/ts}{/capture} -{$ts_item|string_format:"%-30s"} {$ts_total|string_format:"%10s"} {$ts_start_date|string_format:"%20s"} {$ts_end_date|string_format:"%20s"} --------------------------------------------------------------------------------------------------- - -{foreach from=$value item=line} -{capture assign=ts_item}{if $line.html_type eq 'Text'}{$line.label}{else}{$line.field_title} - {$line.label}{/if} {if $line.description} {$line.description}{/if}{/capture}{$ts_item|truncate:30:"..."|string_format:"%-30s"} {$line.line_total|crmMoney|string_format:"%10s"} {$line.start_date|string_format:"%20s"} {$line.end_date|string_format:"%20s"} -{/foreach} -{/foreach} --------------------------------------------------------------------------------------------------- -{/if} -{ts}Amount{/ts}: {$amount|crmMoney} {if $amount_level } - {$amount_level} {/if} -{/if} -{elseif $membership_amount} -=========================================================== -{ts}Membership Fee{/ts} - -=========================================================== -{ts 1=$membership_name}%1 Membership{/ts}: {$membership_amount|crmMoney} -{/if} -{if $receive_date} - -{ts}Date{/ts}: {$receive_date|crmDate} -{/if} -{if $is_monetary and $trxn_id} -{ts}Transaction #{/ts}: {$trxn_id} - -{/if} -{if $membership_trx_id} -{ts}Membership Transaction #{/ts}: {$membership_trx_id} - -{/if} -{if $is_recur} -{if $contributeMode eq 'notify' or $contributeMode eq 'directIPN'} -{ts 1=$cancelSubscriptionUrl}This membership will be renewed automatically. You can cancel the auto-renewal option by visiting this web page: %1.{/ts} - -{ts 1=$updateSubscriptionBillingUrl}You can update billing details for this automatically renewed membership by <a href="%1">visiting this web page</a>.{/ts} -{/if} -{/if} - -{if $honor_block_is_active } -=========================================================== -{$honor_type} -=========================================================== -{$honor_prefix} {$honor_first_name} {$honor_last_name} -{if $honor_email} -{ts}Honoree Email{/ts}: {$honor_email} -{/if} - -{/if} -{if $pcpBlock} -=========================================================== -{ts}Personal Campaign Page{/ts} - -=========================================================== -{ts}Display In Honor Roll{/ts}: {if $pcp_display_in_roll}{ts}Yes{/ts}{else}{ts}No{/ts}{/if} - -{if $pcp_roll_nickname}{ts}Nickname{/ts}: {$pcp_roll_nickname}{/if} - -{if $pcp_personal_note}{ts}Personal Note{/ts}: {$pcp_personal_note}{/if} - -{/if} -{if $onBehalfProfile} -=========================================================== -{ts}On Behalf Of{/ts} - -=========================================================== -{foreach from=$onBehalfProfile item=onBehalfValue key=onBehalfName} -{$onBehalfName}: {$onBehalfValue} -{/foreach} -{/if} - -{if !( $contributeMode eq 'notify' OR $contributeMode eq 'directIPN' ) and $is_monetary} -{if $is_pay_later} -=========================================================== -{ts}Registered Email{/ts} - -=========================================================== -{$email} -{elseif $amount GT 0 OR $membership_amount GT 0 } -=========================================================== -{ts}Billing Name and Address{/ts} - -=========================================================== -{$billingName} -{$address} - -{$email} -{/if} {* End ! is_pay_later condition. *} -{/if} -{if $contributeMode eq 'direct' AND !$is_pay_later AND ( $amount GT 0 OR $membership_amount GT 0 ) } - -=========================================================== -{ts}Credit Card Information{/ts} - -=========================================================== -{$credit_card_type} -{$credit_card_number} -{ts}Expires{/ts}: {$credit_card_exp_date|truncate:7:''|crmDate} -{/if} - -{if $selectPremium } -=========================================================== -{ts}Premium Information{/ts} - -=========================================================== -{$product_name} -{if $option} -{ts}Option{/ts}: {$option} -{/if} -{if $sku} -{ts}SKU{/ts}: {$sku} -{/if} -{if $start_date} -{ts}Start Date{/ts}: {$start_date|crmDate} -{/if} -{if $end_date} -{ts}End Date{/ts}: {$end_date|crmDate} -{/if} -{if $contact_email OR $contact_phone} - -{ts}For information about this premium, contact:{/ts} - -{if $contact_email} - {$contact_email} -{/if} -{if $contact_phone} - {$contact_phone} -{/if} -{/if} -{if $is_deductible AND $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} - -{if $customPre} -=========================================================== -{$customPre_grouptitle} - -=========================================================== -{foreach from=$customPre item=customValue key=customName} -{if ( $trackingFields and ! in_array( $customName, $trackingFields ) ) or ! $trackingFields} - {$customName}: {$customValue} -{/if} -{/foreach} -{/if} - - -{if $customPost} -=========================================================== -{$customPost_grouptitle} - -=========================================================== -{foreach from=$customPost item=customValue key=customName} -{if ( $trackingFields and ! in_array( $customName, $trackingFields ) ) or ! $trackingFields} - {$customName}: {$customValue} -{/if} -{/foreach} -{/if} diff --git a/civicrm/CRM/Upgrade/4.2.alpha1.msg_template/message_templates/pledge_acknowledge_html.tpl b/civicrm/CRM/Upgrade/4.2.alpha1.msg_template/message_templates/pledge_acknowledge_html.tpl deleted file mode 100644 index b4e42e170f..0000000000 --- a/civicrm/CRM/Upgrade/4.2.alpha1.msg_template/message_templates/pledge_acknowledge_html.tpl +++ /dev/null @@ -1,132 +0,0 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml"> -<head> - <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> - <title></title> -</head> -<body> - -{capture assign=headerStyle}colspan="2" style="text-align: left; padding: 4px; border-bottom: 1px solid #999; background-color: #eee;"{/capture} -{capture assign=labelStyle }style="padding: 4px; border-bottom: 1px solid #999; background-color: #f7f7f7;"{/capture} -{capture assign=valueStyle }style="padding: 4px; border-bottom: 1px solid #999;"{/capture} - -<center> - <table width="620" border="0" cellpadding="0" cellspacing="0" id="crm-event_receipt" style="font-family: Arial, Verdana, sans-serif; text-align: left;"> - - <!-- BEGIN HEADER --> - <!-- You can add table row(s) here with logo or other header elements --> - <!-- END HEADER --> - - <!-- BEGIN CONTENT --> - - <tr> - <td> - <p>{ts 1=$contact.display_name}dear %1{/ts},</p> - <p>{ts}thank you for your generous pledge. please print this acknowledgment for your records.{/ts}</p> - </td> - </tr> - <tr> - <td> - <table style="border: 1px solid #999; margin: 1em 0em 1em; border-collapse: collapse; width:100%;"> - <tr> - <th {$headerStyle}> - {ts}Pledge Information{/ts} - </th> - </tr> - <tr> - <td {$labelStyle}> - {ts}Pledge Received{/ts} - </td> - <td {$valueStyle}> - {$create_date|truncate:10:''|crmDate} - </td> - </tr> - <tr> - <td {$labelStyle}> - {ts}Total Pledge Amount{/ts} - </td> - <td {$valueStyle}> - {$total_pledge_amount|crmMoney:$currency} - </td> - </tr> - <tr> - <th {$headerStyle}> - {ts}Payment Schedule{/ts} - </th> - </tr> - <tr> - <td colspan="2" {$valueStyle}> - <p>{ts 1=$scheduled_amount|crmMoney:$currency 2=$frequency_interval 3=$frequency_unit 4=$installments}%1 every %2 %3 for %4 installments.{/ts}</p> - - {if $frequency_day} - <p>{ts 1=$frequency_day 2=$frequency_unit}Payments are due on day %1 of the %2.{/ts}</p> - {/if} - </td> - </tr> - - {if $payments} - {assign var="count" value="1"} - {foreach from=$payments item=payment} - <tr> - <td {$labelStyle}> - {ts 1=$count}Payment %1{/ts} - </td> - <td {$valueStyle}> - {$payment.amount|crmMoney:$currency} {if $payment.status eq 1}{ts}paid{/ts} {$payment.receive_date|truncate:10:''|crmDate}{else}{ts}due{/ts} {$payment.due_date|truncate:10:''|crmDate}{/if} - </td> - </tr> - {assign var="count" value=`$count+1`} - {/foreach} - {/if} - - <tr> - <td colspan="2" {$valueStyle}> - <p>{ts 1=$domain.phone 2=$domain.email}Please contact us at %1 or send email to %2 if you have questions -or need to modify your payment schedule.{/ts}</p> - </td> - </tr> - {if $honor_block_is_active} - <tr> - <th {$headerStyle}> - {$honor_type} - </th> - </tr> - <tr> - <td colspan="2" {$valueStyle}> - <p>{$honor_prefix} {$honor_first_name} {$honor_last_name}</p> - {if $honor_email} - <p>{ts}Honoree Email{/ts}: {$honor_email}</p> - {/if} - </td> - </tr> - {/if} - - {if $customGroup} - {foreach from=$customGroup item=value key=customName} - <tr> - <th {$headerStyle}> - {$customName} - </th> - </tr> - {foreach from=$value item=v key=n} - <tr> - <td {$labelStyle}> - {$n} - </td> - <td {$valueStyle}> - {$v} - </td> - </tr> - {/foreach} - {/foreach} - {/if} - - </table> - </td> - </tr> - - </table> -</center> - -</body> -</html> diff --git a/civicrm/CRM/Upgrade/4.2.alpha1.msg_template/message_templates/pledge_acknowledge_text.tpl b/civicrm/CRM/Upgrade/4.2.alpha1.msg_template/message_templates/pledge_acknowledge_text.tpl deleted file mode 100644 index f8803f5d3f..0000000000 --- a/civicrm/CRM/Upgrade/4.2.alpha1.msg_template/message_templates/pledge_acknowledge_text.tpl +++ /dev/null @@ -1,55 +0,0 @@ -{ts 1=$contact.display_name}Dear %1{/ts}, - -{ts}Thank you for your generous pledge. Please print this acknowledgment for your records.{/ts} - -=========================================================== -{ts}Pledge Information{/ts} - -=========================================================== -{ts}Pledge Received{/ts}: {$create_date|truncate:10:''|crmDate} -{ts}Total Pledge Amount{/ts}: {$total_pledge_amount|crmMoney:$currency} - -=========================================================== -{ts}Payment Schedule{/ts} - -=========================================================== -{ts 1=$scheduled_amount|crmMoney:$currency 2=$frequency_interval 3=$frequency_unit 4=$installments}%1 every %2 %3 for %4 installments.{/ts} - -{if $frequency_day} - -{ts 1=$frequency_day 2=$frequency_unit}Payments are due on day %1 of the %2.{/ts} -{/if} - -{if $payments} -{assign var="count" value="1"} -{foreach from=$payments item=payment} - -{ts 1=$count}Payment %1{/ts}: {$payment.amount|crmMoney:$currency} {if $payment.status eq 1}{ts}paid{/ts} {$payment.receive_date|truncate:10:''|crmDate}{else}{ts}due{/ts} {$payment.due_date|truncate:10:''|crmDate}{/if} -{assign var="count" value=`$count+1`} -{/foreach} -{/if} - - -{ts 1=$domain.phone 2=$domain.email}Please contact us at %1 or send email to %2 if you have questions -or need to modify your payment schedule.{/ts} - -{if $honor_block_is_active} -=========================================================== -{$honor_type} -=========================================================== -{$honor_prefix} {$honor_first_name} {$honor_last_name} -{if $honor_email} -{ts}Honoree Email{/ts}: {$honor_email} -{/if} -{/if} - -{if $customGroup} -{foreach from=$customGroup item=value key=customName} -=========================================================== -{$customName} -=========================================================== -{foreach from=$value item=v key=n} -{$n}: {$v} -{/foreach} -{/foreach} -{/if} diff --git a/civicrm/CRM/Upgrade/4.2.alpha1.msg_template/message_templates/pledge_reminder_html.tpl b/civicrm/CRM/Upgrade/4.2.alpha1.msg_template/message_templates/pledge_reminder_html.tpl deleted file mode 100644 index c2e42a5774..0000000000 --- a/civicrm/CRM/Upgrade/4.2.alpha1.msg_template/message_templates/pledge_reminder_html.tpl +++ /dev/null @@ -1,107 +0,0 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml"> -<head> - <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> - <title></title> -</head> -<body> - -{capture assign=headerStyle}colspan="2" style="text-align: left; padding: 4px; border-bottom: 1px solid #999; background-color: #eee;"{/capture} -{capture assign=labelStyle }style="padding: 4px; border-bottom: 1px solid #999; background-color: #f7f7f7;"{/capture} -{capture assign=valueStyle }style="padding: 4px; border-bottom: 1px solid #999;"{/capture} - -<center> - <table width="620" border="0" cellpadding="0" cellspacing="0" id="crm-event_receipt" style="font-family: Arial, Verdana, sans-serif; text-align: left;"> - - <!-- BEGIN HEADER --> - <!-- You can add table row(s) here with logo or other header elements --> - <!-- END HEADER --> - - <!-- BEGIN CONTENT --> - - <tr> - <td> - <p>{ts 1=$contact.display_name}Dear %1{/ts},</p> - <p>{ts 1=$next_payment|truncate:10:''|crmDate}This is a reminder that the next payment on your pledge is due on %1.{/ts}</p> - </td> - </tr> - <tr> - <td> - <table style="border: 1px solid #999; margin: 1em 0em 1em; border-collapse: collapse; width:100%;"> - <tr> - <th {$headerStyle}> - {ts}Payment Due{/ts} - </th> - </tr> - <tr> - <td {$labelStyle}> - {ts}Amount Due{/ts} - </td> - <td {$valueStyle}> - {$amount_due|crmMoney:$currency} - </td> - </tr> - </table> - </td> - </tr> - - <tr> - <td> - {if $contribution_page_id} - {capture assign=contributionUrl}{crmURL p='civicrm/contribute/transact' q="reset=1&id=`$contribution_page_id`&cid=`$contact.contact_id`&pledgeId=`$pledge_id`&cs=`$checksumValue`" a=true h=0}{/capture} - <p><a href="{$contributionUrl}">{ts}Go to a web page where you can make your payment online{/ts}</a></p> - {else} - <p>{ts}Please mail your payment to{/ts}: {$domain.address}</p> - {/if} - </td> - </tr> - - <tr> - <td> - <table style="border: 1px solid #999; margin: 1em 0em 1em; border-collapse: collapse; width:100%;"> - <tr> - <th {$headerStyle}> - {ts}Pledge Information{/ts} - </th> - </tr> - <tr> - <td {$labelStyle}> - {ts}Pledge Received{/ts} - </td> - <td {$valueStyle}> - {$create_date|truncate:10:''|crmDate} - </td> - </tr> - <tr> - <td {$labelStyle}> - {ts}Total Pledge Amount{/ts} - </td> - <td {$valueStyle}> - {$amount|crmMoney:$currency} - </td> - </tr> - <tr> - <td {$labelStyle}> - {ts}Total Paid{/ts} - </td> - <td {$valueStyle}> - {$amount_paid|crmMoney:$currency} - </td> - </tr> - </table> - </td> - </tr> - - <tr> - <td> - <p>{ts 1=$domain.phone 2=$domain.email}Please contact us at %1 or send email to %2 if you have questions -or need to modify your payment schedule.{/ts}</p> - <p>{ts}Thank your for your generous support.{/ts}</p> - </td> - </tr> - - </table> -</center> - -</body> -</html> diff --git a/civicrm/CRM/Upgrade/4.2.alpha1.msg_template/message_templates/pledge_reminder_text.tpl b/civicrm/CRM/Upgrade/4.2.alpha1.msg_template/message_templates/pledge_reminder_text.tpl deleted file mode 100644 index 2761c3d36a..0000000000 --- a/civicrm/CRM/Upgrade/4.2.alpha1.msg_template/message_templates/pledge_reminder_text.tpl +++ /dev/null @@ -1,33 +0,0 @@ -{ts 1=$contact.display_name}Dear %1{/ts}, - -{ts 1=$next_payment|truncate:10:''|crmDate}This is a reminder that the next payment on your pledge is due on %1.{/ts} - -=========================================================== -{ts}Payment Due{/ts} - -=========================================================== -{ts}Amount Due{/ts}: {$amount_due|crmMoney:$currency} -{ts}Due Date{/ts}: {$scheduled_payment_date|truncate:10:''|crmDate} - -{if $contribution_page_id} -{capture assign=contributionUrl}{crmURL p='civicrm/contribute/transact' q="reset=1&id=`$contribution_page_id`&cid=`$contact.contact_id`&pledgeId=`$pledge_id`&cs=`$checksumValue`" a=true h=0}{/capture} -Click this link to go to a web page where you can make your payment online: -{$contributionUrl} -{else} -{ts}Please mail your payment to{/ts}: -{$domain.address} -{/if} - -=========================================================== -{ts}Pledge Information{/ts} - -=========================================================== -{ts}Pledge Received{/ts}: {$create_date|truncate:10:''|crmDate} -{ts}Total Pledge Amount{/ts}: {$amount|crmMoney:$currency} -{ts}Total Paid{/ts}: {$amount_paid|crmMoney:$currency} - -{ts 1=$domain.phone 2=$domain.email}Please contact us at %1 or send email to %2 if you have questions -or need to modify your payment schedule.{/ts} - - -{ts}Thank your for your generous support.{/ts} diff --git a/civicrm/CRM/Upgrade/4.2.alpha2.msg_template/civicrm_msg_template.tpl b/civicrm/CRM/Upgrade/4.2.alpha2.msg_template/civicrm_msg_template.tpl deleted file mode 100644 index b9bdf57a71..0000000000 --- a/civicrm/CRM/Upgrade/4.2.alpha2.msg_template/civicrm_msg_template.tpl +++ /dev/null @@ -1,16 +0,0 @@ -{php} - $dir = SMARTY_DIR . '/../../CRM/Upgrade/4.2.alpha2.msg_template/message_templates'; - $templates = array(); - foreach (preg_grep('/\.tpl$/', scandir($dir)) as $filename) { - $parts = explode('_', basename($filename, '.tpl')); - $templates[] = array('type' => array_pop($parts), 'name' => implode('_', $parts), 'filename' => "$dir/$filename"); - } - $this->assign('templates', $templates); -{/php} - -{foreach from=$templates item=tpl} - {fetch assign=content file=$tpl.filename} - SELECT @workflow_id := MAX(id) FROM civicrm_option_value WHERE name = '{$tpl.name}'; - SELECT @content := msg_{$tpl.type} FROM civicrm_msg_template WHERE workflow_id = @workflow_id AND is_reserved = 1 LIMIT 1; - UPDATE civicrm_msg_template SET msg_{$tpl.type} = '{$content|escape:"quotes"}' WHERE workflow_id = @workflow_id AND (is_reserved = 1 OR (is_default = 1 AND msg_{$tpl.type} = @content)); -{/foreach} diff --git a/civicrm/CRM/Upgrade/4.2.alpha2.msg_template/message_templates/event_offline_receipt_html.tpl b/civicrm/CRM/Upgrade/4.2.alpha2.msg_template/message_templates/event_offline_receipt_html.tpl deleted file mode 100644 index 54d770bf62..0000000000 --- a/civicrm/CRM/Upgrade/4.2.alpha2.msg_template/message_templates/event_offline_receipt_html.tpl +++ /dev/null @@ -1,456 +0,0 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml"> -<head> - <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> - <title></title> -</head> -<body> - -{capture assign=headerStyle}colspan="2" style="text-align: left; padding: 4px; border-bottom: 1px solid #999; background-color: #eee;"{/capture} -{capture assign=labelStyle }style="padding: 4px; border-bottom: 1px solid #999; background-color: #f7f7f7;"{/capture} -{capture assign=valueStyle }style="padding: 4px; border-bottom: 1px solid #999;"{/capture} - -<center> - <table width="620" border="0" cellpadding="0" cellspacing="0" id="crm-event_receipt" style="font-family: Arial, Verdana, sans-serif; text-align: left;"> - - <!-- BEGIN HEADER --> - <!-- You can add table row(s) here with logo or other header elements --> - <!-- END HEADER --> - - <!-- BEGIN CONTENT --> - - <tr> - <td> - - {if $event.confirm_email_text AND (not $isOnWaitlist AND not $isRequireApproval)} - <p>{$event.confirm_email_text|htmlize}</p> - {/if} - - {if $isOnWaitlist} - <p>{ts}You have been added to the WAIT LIST for this event.{/ts}</p> - {if $isPrimary} - <p>{ts}If space becomes available you will receive an email with a link to a web page where you can complete your registration.{/ts}</p> - {/if} - {elseif $isRequireApproval} - <p>{ts}Your registration has been submitted.{/ts}</p> - {if $isPrimary} - <p>{ts}Once your registration has been reviewed, you will receive an email with a link to a web page where you can complete the registration process.{/ts}</p> - {/if} - {elseif $is_pay_later} - <p>{$pay_later_receipt}</p> {* FIXME: this might be text rather than HTML *} - {else} - <p>{ts}Please print this confirmation for your records.{/ts}</p> - {/if} - - </td> - </tr> - <tr> - <td> - <table style="border: 1px solid #999; margin: 1em 0em 1em; border-collapse: collapse; width:100%;"> - <tr> - <th {$headerStyle}> - {ts}Event Information and Location{/ts} - </th> - </tr> - <tr> - <td colspan="2" {$valueStyle}> - {$event.event_title}<br /> - {$event.event_start_date|crmDate}{if $event.event_end_date}-{if $event.event_end_date|date_format:"%Y%m%d" == $event.event_start_date|date_format:"%Y%m%d"}{$event.event_end_date|crmDate:0:1}{else}{$event.event_end_date|crmDate}{/if}{/if} - </td> - </tr> - - {if $event.participant_role neq 'Attendee' and $defaultRole} - <tr> - <td {$labelStyle}> - {ts}Participant Role{/ts} - </td> - <td {$valueStyle}> - {$event.participant_role} - </td> - </tr> - {/if} - - {if $isShowLocation} - <tr> - <td colspan="2" {$valueStyle}> - {if $location.address.1.name} - {$location.address.1.name}<br /> - {/if} - {if $location.address.1.street_address} - {$location.address.1.street_address}<br /> - {/if} - {if $location.address.1.supplemental_address_1} - {$location.address.1.supplemental_address_1}<br /> - {/if} - {if $location.address.1.supplemental_address_2} - {$location.address.1.supplemental_address_2}<br /> - {/if} - {if $location.address.1.city} - {$location.address.1.city} {$location.address.1.postal_code}{if $location.address.1.postal_code_suffix} - {$location.address.1.postal_code_suffix}{/if}<br /> - {/if} - </td> - </tr> - {/if} - - {if $location.phone.1.phone || $location.email.1.email} - <tr> - <td colspan="2" {$labelStyle}> - {ts}Event Contacts:{/ts} - </td> - </tr> - {foreach from=$location.phone item=phone} - {if $phone.phone} - <tr> - <td {$labelStyle}> - {if $phone.phone_type} - {$phone.phone_type_display} - {else} - {ts}Phone{/ts} - {/if} - </td> - <td {$valueStyle}> - {$phone.phone} - </td> - </tr> - {/if} - {/foreach} - {foreach from=$location.email item=eventEmail} - {if $eventEmail.email} - <tr> - <td {$labelStyle}> - {ts}Email{/ts} - </td> - <td {$valueStyle}> - {$eventEmail.email} - </td> - </tr> - {/if} - {/foreach} - {/if} - <tr> - <td colspan="2" {$valueStyle}> - {capture assign=icalFeed}{crmURL p='civicrm/event/ical' q="reset=1&id=`$event.id`" h=0 a=1 fe=1}{/capture} - <a href="{$icalFeed}">{ts}Download iCalendar File{/ts}</a> - </td> - </tr> - {if $email} - <tr> - <th {$headerStyle}> - {ts}Registered Email{/ts} - </th> - </tr> - <tr> - <td colspan="2" {$valueStyle}> - {$email} - </td> - </tr> - {/if} - - - {if $event.is_monetary} - - <tr> - <th {$headerStyle}> - {$event.fee_label} - </th> - </tr> - - {if $lineItem} - {foreach from=$lineItem item=value key=priceset} - {if $value neq 'skip'} - {if $isPrimary} - {if $lineItem|@count GT 1} {* Header for multi participant registration cases. *} - <tr> - <td colspan="2" {$labelStyle}> - {ts 1=$priceset+1}Participant %1{/ts} - </td> - </tr> - {/if} - {/if} - <tr> - <td colspan="2" {$valueStyle}> - <table> {* FIXME: style this table so that it looks like the text version (justification, etc.) *} - <tr> - <th>{ts}Item{/ts}</th> - <th>{ts}Qty{/ts}</th> - <th>{ts}Each{/ts}</th> - <th>{ts}Total{/ts}</th> - {if $pricesetFieldsCount }<th>{ts}Total Participants{/ts}</th>{/if} - </tr> - {foreach from=$value item=line} - <tr> - <td> - {if $line.html_type eq 'Text'}{$line.label}{else}{$line.field_title} - {$line.label}{/if} {if $line.description}<div>{$line.description|truncate:30:"..."}</div>{/if} - </td> - <td> - {$line.qty} - </td> - <td> - {$line.unit_price|crmMoney} - </td> - <td> - {$line.line_total|crmMoney} - </td> - {if $pricesetFieldsCount } - <td> - {$line.participant_count} - </td> - {/if} - </tr> - {/foreach} - </table> - </td> - </tr> - {/if} - {/foreach} - {/if} - - {if $amount && !$lineItem} - {foreach from=$amount item=amnt key=level} - <tr> - <td colspan="2" {$valueStyle}> - {$amnt.amount|crmMoney} {$amnt.label} - </td> - </tr> - {/foreach} - {/if} - {if $isPrimary} - <tr> - <td {$labelStyle}> - {ts}Total Amount{/ts} - </td> - <td {$valueStyle}> - {$totalAmount|crmMoney} {if $hookDiscount.message}({$hookDiscount.message}){/if} - </td> - </tr> - {if $pricesetFieldsCount } - <tr> - <td {$labelStyle}> - {ts}Total Participants{/ts}</td> - <td {$valueStyle}> - {assign var="count" value= 0} - {foreach from=$lineItem item=pcount} - {assign var="lineItemCount" value=0} - {if $pcount neq 'skip'} - {foreach from=$pcount item=p_count} - {assign var="lineItemCount" value=$lineItemCount+$p_count.participant_count} - {/foreach} - {if $lineItemCount < 1 } - assign var="lineItemCount" value=1} - {/if} - {assign var="count" value=$count+$lineItemCount} - {/if} - {/foreach} - {$count} - </td> - </tr> - {/if} - {if $is_pay_later} - <tr> - <td colspan="2" {$labelStyle}> - {$pay_later_receipt} - </td> - </tr> - {/if} - - {if $register_date} - <tr> - <td {$labelStyle}> - {ts}Registration Date{/ts} - </td> - <td {$valueStyle}> - {$register_date|crmDate} - </td> - </tr> - {/if} - - {if $receive_date} - <tr> - <td {$labelStyle}> - {ts}Transaction Date{/ts} - </td> - <td {$valueStyle}> - {$receive_date|crmDate} - </td> - </tr> - {/if} - - {if $contributionTypeName} - <tr> - <td {$labelStyle}> - {ts}Contribution Type{/ts} - </td> - <td {$valueStyle}> - {$contributionTypeName} - </td> - </tr> - {/if} - - {if $trxn_id} - <tr> - <td {$labelStyle}> - {ts}Transaction #{/ts} - </td> - <td {$valueStyle}> - {$trxn_id} - </td> - </tr> - {/if} - - {if $paidBy} - <tr> - <td {$labelStyle}> - {ts}Paid By{/ts} - </td> - <td {$valueStyle}> - {$paidBy} - </td> - </tr> - {/if} - - {if $checkNumber} - <tr> - <td {$labelStyle}> - {ts}Check Number{/ts} - </td> - <td {$valueStyle}> - {$checkNumber} - </td> - </tr> - {/if} - - {if $contributeMode ne 'notify' and !$isAmountzero and !$is_pay_later and !$isOnWaitlist and !$isRequireApproval} - <tr> - <th {$headerStyle}> - {ts}Billing Name and Address{/ts} - </th> - </tr> - <tr> - <td colspan="2" {$valueStyle}> - {$billingName}<br /> - {$address|nl2br} - </td> - </tr> - {/if} - - {if $contributeMode eq 'direct' and !$isAmountzero and !$is_pay_later and !$isOnWaitlist and !$isRequireApproval} - <tr> - <th {$headerStyle}> - {ts}Credit Card Information{/ts} - </th> - </tr> - <tr> - <td colspan="2" {$valueStyle}> - {$credit_card_type}<br /> - {$credit_card_number}<br /> - {ts}Expires{/ts}: {$credit_card_exp_date|truncate:7:''|crmDate} - </td> - </tr> - {/if} - - {/if} - - {/if} {* End of conditional section for Paid events *} - - {if $customPre} - <tr> - <th {$headerStyle}> - {$customPre_grouptitle} - </th> - </tr> - {foreach from=$customPre item=value key=customName} - {if ( $trackingFields and ! in_array( $customName, $trackingFields ) ) or ! $trackingFields} - <tr> - <td {$labelStyle}> - {$customName} - </td> - <td {$valueStyle}> - {$value} - </td> - </tr> - {/if} - {/foreach} - {/if} - - {if $customPost} - <tr> - <th {$headerStyle}> - {$customPost_grouptitle} - </th> - </tr> - {foreach from=$customPost item=value key=customName} - {if ( $trackingFields and ! in_array( $customName, $trackingFields ) ) or ! $trackingFields} - <tr> - <td {$labelStyle}> - {$customName} - </td> - <td {$valueStyle}> - {$value} - </td> - </tr> - {/if} - {/foreach} - {/if} - - {if $customProfile} - {foreach from=$customProfile item=value key=customName} - <tr> - <th {$headerStyle}> - {ts 1=$customName+1}Participant Information - Participant %1{/ts} - </th> - </tr> - {foreach from=$value item=val key=field} - {if $field eq 'additionalCustomPre' or $field eq 'additionalCustomPost'} - <tr> - <td colspan="2" {$labelStyle}> - {if $field eq 'additionalCustomPre'} - {$additionalCustomPre_grouptitle} - {else} - {$additionalCustomPost_grouptitle} - {/if} - </td> - </tr> - {foreach from=$val item=v key=f} - <tr> - <td {$labelStyle}> - {$f} - </td> - <td {$valueStyle}> - {$v} - </td> - </tr> - {/foreach} - {/if} - {/foreach} - {/foreach} - {/if} - - {if $customGroup} - {foreach from=$customGroup item=value key=customName} - <tr> - <th {$headerStyle}> - {$customName} - </th> - </tr> - {foreach from=$value item=v key=n} - <tr> - <td {$labelStyle}> - {$n} - </td> - <td {$valueStyle}> - {$v} - </td> - </tr> - {/foreach} - {/foreach} - {/if} - - </table> - </td> - </tr> - - </table> -</center> - -</body> -</html> diff --git a/civicrm/CRM/Upgrade/4.2.alpha2.msg_template/message_templates/event_offline_receipt_text.tpl b/civicrm/CRM/Upgrade/4.2.alpha2.msg_template/message_templates/event_offline_receipt_text.tpl deleted file mode 100644 index 32879bb39f..0000000000 --- a/civicrm/CRM/Upgrade/4.2.alpha2.msg_template/message_templates/event_offline_receipt_text.tpl +++ /dev/null @@ -1,274 +0,0 @@ -{if $event.confirm_email_text AND (not $isOnWaitlist AND not $isRequireApproval)} -{$event.confirm_email_text} -{/if} - -{if $isOnWaitlist} -==========================================================={if $pricesetFieldsCount }===================={/if} - -{ts}You have been added to the WAIT LIST for this event.{/ts} - -{if $isPrimary} -{ts}If space becomes available you will receive an email with a link to a web page where you can complete your registration.{/ts} - -{/if} -==========================================================={if $pricesetFieldsCount }===================={/if} - -{elseif $isRequireApproval} -==========================================================={if $pricesetFieldsCount }===================={/if} - -{ts}Your registration has been submitted.{/ts} - -{if $isPrimary} -{ts}Once your registration has been reviewed, you will receive an email with a link to a web page where you can complete the registration process.{/ts} - -{/if} -==========================================================={if $pricesetFieldsCount }===================={/if} - -{elseif $is_pay_later} - -==========================================================={if $pricesetFieldsCount }===================={/if} - -{$pay_later_receipt} -==========================================================={if $pricesetFieldsCount }===================={/if} - -{else} - -{ts}Please print this confirmation for your records.{/ts} -{/if} - - -==========================================================={if $pricesetFieldsCount }===================={/if} - -{ts}Event Information and Location{/ts} - -==========================================================={if $pricesetFieldsCount }===================={/if} - -{$event.event_title} -{$event.event_start_date|crmDate}{if $event.event_end_date}-{if $event.event_end_date|date_format:"%Y%m%d" == $event.event_start_date|date_format:"%Y%m%d"}{$event.event_end_date|crmDate:0:1}{else}{$event.event_end_date|crmDate}{/if}{/if} - -{if $event.participant_role neq 'Attendee' and $defaultRole} -{ts}Participant Role{/ts}: {$event.participant_role} -{/if} - -{if $isShowLocation} -{if $location.address.1.name} - -{$location.address.1.name} -{/if} -{if $location.address.1.street_address}{$location.address.1.street_address} -{/if} -{if $location.address.1.supplemental_address_1}{$location.address.1.supplemental_address_1} -{/if} -{if $location.address.1.supplemental_address_2}{$location.address.1.supplemental_address_2} -{/if} -{if $location.address.1.city}{$location.address.1.city} {$location.address.1.postal_code}{if $location.address.1.postal_code_suffix} - {$location.address.1.postal_code_suffix}{/if} -{/if} - -{/if}{*End of isShowLocation condition*} - -{if $location.phone.1.phone || $location.email.1.email} - -{ts}Event Contacts:{/ts} -{foreach from=$location.phone item=phone} -{if $phone.phone} - -{if $phone.phone_type}{$phone.phone_type_display}{else}{ts}Phone{/ts}{/if}: {$phone.phone}{/if} -{/foreach} -{foreach from=$location.email item=eventEmail} -{if $eventEmail.email} - -{ts}Email{/ts}: {$eventEmail.email}{/if}{/foreach} -{/if} - -{capture assign=icalFeed}{crmURL p='civicrm/event/ical' q="reset=1&id=`$event.id`" h=0 a=1 fe=1}{/capture} -{ts}Download iCalendar File:{/ts} {$icalFeed} -{if $email} - -==========================================================={if $pricesetFieldsCount }===================={/if} - -{ts}Registered Email{/ts} - -==========================================================={if $pricesetFieldsCount }===================={/if} - -{$email} -{/if} -{if $event.is_monetary} {* This section for Paid events only.*} - -==========================================================={if $pricesetFieldsCount }===================={/if} - -{$event.fee_label} -==========================================================={if $pricesetFieldsCount }===================={/if} - -{if $lineItem}{foreach from=$lineItem item=value key=priceset} - -{if $value neq 'skip'} -{if $isPrimary} -{if $lineItem|@count GT 1} {* Header for multi participant registration cases. *} -{ts 1=$priceset+1}Participant %1{/ts} -{/if} -{/if} ----------------------------------------------------------{if $pricesetFieldsCount }--------------------{/if} - -{capture assign=ts_item}{ts}Item{/ts}{/capture} -{capture assign=ts_qty}{ts}Qty{/ts}{/capture} -{capture assign=ts_each}{ts}Each{/ts}{/capture} -{capture assign=ts_total}{ts}Total{/ts}{/capture} -{capture assign=ts_participant_total}{if $pricesetFieldsCount }{ts}Total Participants{/ts}{/if}{/capture} -{$ts_item|string_format:"%-30s"} {$ts_qty|string_format:"%5s"} {$ts_each|string_format:"%10s"} {$ts_total|string_format:"%10s"} {$ts_participant_total|string_format:"%10s"} -----------------------------------------------------------{if $pricesetFieldsCount }--------------------{/if} - -{foreach from=$value item=line} -{if $pricesetFieldsCount }{capture assign=ts_participant_count}{$line.participant_count}{/capture}{/if} -{capture assign=ts_item}{if $line.html_type eq 'Text'}{$line.label}{else}{$line.field_title} - {$line.label}{/if} {if $line.description} {$line.description}{/if}{/capture}{$ts_item|truncate:30:"..."|string_format:"%-30s"} {$line.qty|string_format:"%5s"} {$line.unit_price|crmMoney|string_format:"%10s"} {$line.line_total|crmMoney|string_format:"%10s"} {$ts_participant_count|string_format:"%10s"} -{/foreach} -{/if} -{/foreach} -{/if} -{if $amount && !$lineItem} -{foreach from=$amount item=amnt key=level}{$amnt.amount|crmMoney} {$amnt.label} -{/foreach} -{/if} -{if $isPrimary } - -{ts}Total Amount{/ts}: {$totalAmount|crmMoney} {if $hookDiscount.message}({$hookDiscount.message}){/if} - -{if $pricesetFieldsCount } - {assign var="count" value= 0} - {foreach from=$lineItem item=pcount} - {assign var="lineItemCount" value=0} - {if $pcount neq 'skip'} - {foreach from=$pcount item=p_count} - {assign var="lineItemCount" value=$lineItemCount+$p_count.participant_count} - {/foreach} - {if $lineItemCount < 1 } - {assign var="lineItemCount" value=1} - {/if} - {assign var="count" value=$count+$lineItemCount} - {/if} - {/foreach} - -{ts}Total Participants{/ts}: {$count} -{/if} - -{if $is_pay_later } - -==========================================================={if $pricesetFieldsCount }===================={/if} - -{$pay_later_receipt} -==========================================================={if $pricesetFieldsCount }===================={/if} - -{/if} - -{if $register_date} -{ts}Registration Date{/ts}: {$register_date|crmDate} -{/if} -{if $receive_date} -{ts}Transaction Date{/ts}: {$receive_date|crmDate} -{/if} -{if $contributionTypeName} -{ts}Contribution Type{/ts}: {$contributionTypeName} -{/if} -{if $trxn_id} -{ts}Transaction #{/ts}: {$trxn_id} -{/if} -{if $paidBy} -{ts}Paid By{/ts}: {$paidBy} -{/if} -{if $checkNumber} -{ts}Check Number{/ts}: {$checkNumber} -{/if} -{if $contributeMode ne 'notify' and !$isAmountzero and !$is_pay_later and !$isOnWaitlist and !$isRequireApproval} - -==========================================================={if $pricesetFieldsCount }===================={/if} - -{ts}Billing Name and Address{/ts} - -==========================================================={if $pricesetFieldsCount }===================={/if} - -{$billingName} -{$address} -{/if} - -{if $contributeMode eq 'direct' and !$isAmountzero and !$is_pay_later and !$isOnWaitlist and !$isRequireApproval} -=========================================================== -{ts}Credit Card Information{/ts} - -==========================================================={if $pricesetFieldsCount }===================={/if} - -{$credit_card_type} -{$credit_card_number} -{ts}Expires{/ts}: {$credit_card_exp_date|truncate:7:''|crmDate} -{/if} -{/if} -{/if} {* End of conditional section for Paid events *} - -{if $customPre} -==========================================================={if $pricesetFieldsCount }===================={/if} - -{$customPre_grouptitle} -==========================================================={if $pricesetFieldsCount }===================={/if} - -{foreach from=$customPre item=value key=customName} -{if ( $trackingFields and ! in_array( $customName, $trackingFields ) ) or ! $trackingFields} -{$customName}: {$value} -{/if} -{/foreach} -{/if} - -{if $customPost} -==========================================================={if $pricesetFieldsCount }===================={/if} - -{$customPost_grouptitle} -==========================================================={if $pricesetFieldsCount }===================={/if} - -{foreach from=$customPost item=value key=customName} -{if ( $trackingFields and ! in_array( $customName, $trackingFields ) ) or ! $trackingFields} -{$customName}: {$value} -{/if} -{/foreach} -{/if} -{if $customProfile} - -{foreach from=$customProfile item=value key=customName} -==========================================================={if $pricesetFieldsCount }===================={/if} - -{ts 1=$customName+1}Participant Information - Participant %1{/ts} - -==========================================================={if $pricesetFieldsCount }===================={/if} - -{foreach from=$value item=val key=field} -{if $field eq 'additionalCustomPre' or $field eq 'additionalCustomPost' } -{if $field eq 'additionalCustomPre' } -----------------------------------------------------------{if $pricesetFieldsCount }--------------------{/if} - -{$additionalCustomPre_grouptitle} -----------------------------------------------------------{if $pricesetFieldsCount }--------------------{/if} - -{else} -----------------------------------------------------------{if $pricesetFieldsCount }--------------------{/if} - -{$additionalCustomPost_grouptitle} -----------------------------------------------------------{if $pricesetFieldsCount }--------------------{/if} - -{/if} -{foreach from=$val item=v key=f} -{$f}: {$v} -{/foreach} -{/if} -{/foreach} -{/foreach} -{/if} -{if $customGroup} -{foreach from=$customGroup item=value key=customName} -=========================================================={if $pricesetFieldsCount }===================={/if} - -{$customName} -=========================================================={if $pricesetFieldsCount }===================={/if} - -{foreach from=$value item=v key=n} -{$n}: {$v} -{/foreach} -{/foreach} -{/if} - - diff --git a/civicrm/CRM/Upgrade/4.2.alpha2.msg_template/message_templates/event_online_receipt_html.tpl b/civicrm/CRM/Upgrade/4.2.alpha2.msg_template/message_templates/event_online_receipt_html.tpl deleted file mode 100644 index f48fc26dce..0000000000 --- a/civicrm/CRM/Upgrade/4.2.alpha2.msg_template/message_templates/event_online_receipt_html.tpl +++ /dev/null @@ -1,457 +0,0 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml"> -<head> - <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> - <title></title> -</head> -<body> - -{capture assign=headerStyle}colspan="2" style="text-align: left; padding: 4px; border-bottom: 1px solid #999; background-color: #eee;"{/capture} -{capture assign=labelStyle }style="padding: 4px; border-bottom: 1px solid #999; background-color: #f7f7f7;"{/capture} -{capture assign=valueStyle }style="padding: 4px; border-bottom: 1px solid #999;"{/capture} - -<center> - <table width="500" border="0" cellpadding="0" cellspacing="0" id="crm-event_receipt" style="font-family: Arial, Verdana, sans-serif; text-align: left;"> - - <!-- BEGIN HEADER --> - <!-- You can add table row(s) here with logo or other header elements --> - <!-- END HEADER --> - - <!-- BEGIN CONTENT --> - - <tr> - <td> - <p>Dear {contact.display_name},</p> - - {if $event.confirm_email_text AND (not $isOnWaitlist AND not $isRequireApproval)} - <p>{$event.confirm_email_text|htmlize}</p> - - {else} - <p>Thank you for your participation. This letter is a confirmation that your registration has been received and your status has been updated to <strong>{if $isOnWaitlist}waitlisted{else}registered{/if}</strong> for the following:</p> - - {/if} - - <p> - {if $isOnWaitlist} - <p>{ts}You have been added to the WAIT LIST for this event.{/ts}</p> - {if $isPrimary} - <p>{ts}If space becomes available you will receive an email with a link to a web page where you can complete your registration.{/ts}</p> - {/if} - {elseif $isRequireApproval} - <p>{ts}Your registration has been submitted.{/ts}</p> - {if $isPrimary} - <p>{ts}Once your registration has been reviewed, you will receive an email with a link to a web page where you can complete the registration process.{/ts}</p> - {/if} - {elseif $is_pay_later && !$isAmountzero} - <p>{$pay_later_receipt}</p> {* FIXME: this might be text rather than HTML *} - {else} - <p>{ts}Please print this confirmation for your records.{/ts}</p> - {/if} - - </td> - </tr> - <tr> - <td> - <table width="500" style="border: 1px solid #999; margin: 1em 0em 1em; border-collapse: collapse;"> - <tr> - <th {$headerStyle}> - {ts}Event Information and Location{/ts} - </th> - </tr> - <tr> - <td colspan="2" {$valueStyle}> - {$event.event_title}<br /> - {$event.event_start_date|date_format:"%A"} {$event.event_start_date|crmDate}{if $event.event_end_date}-{if $event.event_end_date|date_format:"%Y%m%d" == $event.event_start_date|date_format:"%Y%m%d"}{$event.event_end_date|crmDate:0:1}{else}{$event.event_end_date|date_format:"%A"} {$event.event_end_date|crmDate}{/if}{/if} - </td> - </tr> - - - {if $conference_sessions} - <tr> - <td colspan="2" {$labelStyle}> - {ts}Your schedule:{/ts} - </td> - </tr> - <tr> - <td colspan="2" {$valueStyle}> - {assign var='group_by_day' value='NA'} - {foreach from=$conference_sessions item=session} - {if $session.start_date|date_format:"%Y/%m/%d" != $group_by_day|date_format:"%Y/%m/%d"} - {assign var='group_by_day' value=$session.start_date} - <em>{$group_by_day|date_format:"%m/%d/%Y"}</em><br /> - {/if} - {$session.start_date|crmDate:0:1}{if $session.end_date}-{$session.end_date|crmDate:0:1}{/if} {$session.title}<br /> - {if $session.location} {$session.location}<br />{/if} - {/foreach} - </td> - </tr> - {/if} - - {if $event.participant_role neq 'Attendee' and $defaultRole} - <tr> - <td {$labelStyle}> - {ts}Participant Role{/ts} - </td> - <td {$valueStyle}> - {$event.participant_role} - </td> - </tr> - {/if} - - {if $isShowLocation} - <tr> - <td colspan="2" {$valueStyle}> - {if $location.address.1.name} - {$location.address.1.name}<br /> - {/if} - {if $location.address.1.street_address} - {$location.address.1.street_address}<br /> - {/if} - {if $location.address.1.supplemental_address_1} - {$location.address.1.supplemental_address_1}<br /> - {/if} - {if $location.address.1.supplemental_address_2} - {$location.address.1.supplemental_address_2}<br /> - {/if} - {if $location.address.1.city} - {$location.address.1.city}, {$location.address.1.state_province} {$location.address.1.postal_code}{if $location.address.1.postal_code_suffix} - {$location.address.1.postal_code_suffix}{/if}<br /> - {/if} - </td> - </tr> - {/if} - - {if $location.phone.1.phone || $location.email.1.email} - <tr> - <td colspan="2" {$labelStyle}> - {ts}Event Contacts:{/ts} - </td> - </tr> - {foreach from=$location.phone item=phone} - {if $phone.phone} - <tr> - <td {$labelStyle}> - {if $phone.phone_type} - {$phone.phone_type_display} - {else} - {ts}Phone{/ts} - {/if} - </td> - <td {$valueStyle}> - {$phone.phone} - </td> - </tr> - {/if} - {/foreach} - {foreach from=$location.email item=eventEmail} - {if $eventEmail.email} - <tr> - <td {$labelStyle}> - {ts}Email{/ts} - </td> - <td {$valueStyle}> - {$eventEmail.email} - </td> - </tr> - {/if} - {/foreach} - {/if} - <tr> - <td colspan="2" {$valueStyle}> - {capture assign=icalFeed}{crmURL p='civicrm/event/ical' q="reset=1&id=`$event.id`" h=0 a=1 fe=1}{/capture} - <a href="{$icalFeed}">{ts}Download iCalendar File{/ts}</a> - </td> - </tr> - {if $event.is_share} - <tr> - <td colspan="2" {$valueStyle}> - {capture assign=eventUrl}{crmURL p='civicrm/event/info' q="id=`$event.id`&reset=1" a=true fe=1 h=1}{/capture} - {include file="CRM/common/SocialNetwork.tpl" emailMode=true url=$eventUrl title=$event.title pageURL=$eventUrl} - </td> - </tr> - {/if} - {if $payer.name} - <tr> - <th {$headerStyle}> - {ts}You were registered by:{/ts} - </th> - </tr> - <tr> - <td colspan="2" {$valueStyle}> - {$payer.name} - </td> - </tr> - {/if} - {if $event.is_monetary} - - <tr> - <th {$headerStyle}> - {$event.fee_label} - </th> - </tr> - - {if $lineItem} - {foreach from=$lineItem item=value key=priceset} - {if $value neq 'skip'} - {if $isPrimary} - {if $lineItem|@count GT 1} {* Header for multi participant registration cases. *} - <tr> - <td colspan="2" {$labelStyle}> - {ts 1=$priceset+1}Participant %1{/ts} {$part.$priceset.info} - </td> - </tr> - {/if} - {/if} - <tr> - <td colspan="2" {$valueStyle}> - <table> {* FIXME: style this table so that it looks like the text version (justification, etc.) *} - <tr> - <th>{ts}Item{/ts}</th> - <th>{ts}Qty{/ts}</th> - <th>{ts}Each{/ts}</th> - <th>{ts}Total{/ts}</th> - {if $pricesetFieldsCount }<th>{ts}Total Participants{/ts}</th>{/if} - </tr> - {foreach from=$value item=line} - <tr> - <td> - {if $line.html_type eq 'Text'}{$line.label}{else}{$line.field_title} - {$line.label}{/if} {if $line.description}<div>{$line.description|truncate:30:"..."}</div>{/if} - </td> - <td> - {$line.qty} - </td> - <td> - {$line.unit_price|crmMoney} - </td> - <td> - {$line.line_total|crmMoney} - </td> - {if $pricesetFieldsCount }<td>{$line.participant_count}</td> {/if} - </tr> - {/foreach} - </table> - </td> - </tr> - {/if} - {/foreach} - {/if} - - {if $amounts && !$lineItem} - {foreach from=$amounts item=amnt key=level} - <tr> - <td colspan="2" {$valueStyle}> - {$amnt.amount|crmMoney} {$amnt.label} - </td> - </tr> - {/foreach} - {/if} - - {if $isPrimary} - <tr> - <td {$labelStyle}> - {ts}Total Amount{/ts} - </td> - <td {$valueStyle}> - {$totalAmount|crmMoney} {if $hookDiscount.message}({$hookDiscount.message}){/if} - </td> - </tr> - {if $pricesetFieldsCount } - <tr> - <td {$labelStyle}> - {ts}Total Participants{/ts}</td> - <td {$valueStyle}> - {assign var="count" value= 0} - {foreach from=$lineItem item=pcount} - {assign var="lineItemCount" value=0} - {if $pcount neq 'skip'} - {foreach from=$pcount item=p_count} - {assign var="lineItemCount" value=$lineItemCount+$p_count.participant_count} - {/foreach} - {if $lineItemCount < 1 } - {assign var="lineItemCount" value=1} - {/if} - {assign var="count" value=$count+$lineItemCount} - {/if} - {/foreach} - {$count} - </td> </tr> - {/if} - {if $is_pay_later} - <tr> - <td colspan="2" {$labelStyle}> - {$pay_later_receipt} - </td> - </tr> - {/if} - - {if $register_date} - <tr> - <td {$labelStyle}> - {ts}Registration Date{/ts} - </td> - <td {$valueStyle}> - {$register_date|crmDate} - </td> - </tr> - {/if} - - {if $receive_date} - <tr> - <td {$labelStyle}> - {ts}Transaction Date{/ts} - </td> - <td {$valueStyle}> - {$receive_date|crmDate} - </td> - </tr> - {/if} - - {if $contributionTypeName} - <tr> - <td {$labelStyle}> - {ts}Contribution Type{/ts} - </td> - <td {$valueStyle}> - {$contributionTypeName} - </td> - </tr> - {/if} - - {if $trxn_id} - <tr> - <td {$labelStyle}> - {ts}Transaction #{/ts} - </td> - <td {$valueStyle}> - {$trxn_id} - </td> - </tr> - {/if} - - {if $paidBy} - <tr> - <td {$labelStyle}> - {ts}Paid By{/ts} - </td> - <td {$valueStyle}> - {$paidBy} - </td> - </tr> - {/if} - - {if $checkNumber} - <tr> - <td {$labelStyle}> - {ts}Check Number{/ts} - </td> - <td {$valueStyle}> - {$checkNumber} - </td> - </tr> - {/if} - - {if $contributeMode ne 'notify' and !$isAmountzero and !$is_pay_later and !$isOnWaitlist and !$isRequireApproval} - <tr> - <th {$headerStyle}> - {ts}Billing Name and Address{/ts} - </th> - </tr> - <tr> - <td colspan="2" {$valueStyle}> - {$billingName}<br /> - {$address|nl2br} - </td> - </tr> - {/if} - - {if $contributeMode eq 'direct' and !$isAmountzero and !$is_pay_later and !$isOnWaitlist and !$isRequireApproval} - <tr> - <th {$headerStyle}> - {ts}Credit Card Information{/ts} - </th> - </tr> - <tr> - <td colspan="2" {$valueStyle}> - {$credit_card_type}<br /> - {$credit_card_number}<br /> - {ts}Expires{/ts}: {$credit_card_exp_date|truncate:7:''|crmDate} - </td> - </tr> - {/if} - - {/if} - - {/if} {* End of conditional section for Paid events *} - - -{if $customPre} -{foreach from=$customPre item=customPr key=i} - <tr> <th {$headerStyle}>{$customPre_grouptitle.$i}</th></tr> - {foreach from=$customPr item=customValue key=customName} - {if ( $trackingFields and ! in_array( $customName, $trackingFields ) ) or ! $trackingFields} - <tr> - <td {$labelStyle}>{$customName}</td> - <td {$valueStyle}>{$customValue}</td> - </tr> - {/if} - {/foreach} -{/foreach} -{/if} - -{if $customPost} -{foreach from=$customPost item=customPos key=j} - <tr> <th {$headerStyle}>{$customPost_grouptitle.$j}</th></tr> - {foreach from=$customPos item=customValue key=customName} - {if ( $trackingFields and ! in_array( $customName, $trackingFields ) ) or ! $trackingFields} - <tr> - <td {$labelStyle}>{$customName}</td> - <td {$valueStyle}>{$customValue}</td> - </tr> -{/if} -{/foreach} -{/foreach} -{/if} - -{if $customProfile} -{foreach from=$customProfile.profile item=eachParticipant key=participantID} - <tr><th {$headerStyle}>{ts 1=$participantID+2}Participant %1{/ts} </th></tr> - {foreach from=$eachParticipant item=eachProfile key=pid} - <tr><th {$headerStyle}>{$customProfile.title.$pid}</th></tr> - {foreach from=$eachProfile item=val key=field} - <tr>{foreach from=$val item=v key=f} - <td {$labelStyle}>{$field}</td> - <td {$valueStyle}>{$v}</td> - {/foreach} - </tr> - {/foreach} -{/foreach} -{/foreach} -{/if} - - {if $customGroup} - {foreach from=$customGroup item=value key=customName} - <tr> - <th {$headerStyle}> - {$customName} - </th> - </tr> - {foreach from=$value item=v key=n} - <tr> - <td {$labelStyle}> - {$n} - </td> - <td {$valueStyle}> - {$v} - </td> - </tr> - {/foreach} - {/foreach} - {/if} - - </table> - </td> - </tr> - </table> -</center> - -</body> -</html> diff --git a/civicrm/CRM/Upgrade/4.2.alpha2.msg_template/message_templates/event_online_receipt_text.tpl b/civicrm/CRM/Upgrade/4.2.alpha2.msg_template/message_templates/event_online_receipt_text.tpl deleted file mode 100644 index 8696c6d16b..0000000000 --- a/civicrm/CRM/Upgrade/4.2.alpha2.msg_template/message_templates/event_online_receipt_text.tpl +++ /dev/null @@ -1,286 +0,0 @@ -Dear {contact.display_name}, - -{if $event.confirm_email_text AND (not $isOnWaitlist AND not $isRequireApproval)} -{$event.confirm_email_text} - -{else} -Thank you for your participation. This letter is a confirmation that your registration has been received and your status has been updated to {if $participant_status}$participant_status{else}{if $isOnWaitlist}waitlisted{else}registered{/if}{/if} for the following: - -{/if} - -{if $isOnWaitlist} -==========================================================={if $pricesetFieldsCount }===================={/if} - -{ts}You have been added to the WAIT LIST for this event.{/ts} - -{if $isPrimary} -{ts}If space becomes available you will receive an email with a link to a web page where you can complete your registration.{/ts} -{/if} -==========================================================={if $pricesetFieldsCount }===================={/if} - -{elseif $isRequireApproval} -==========================================================={if $pricesetFieldsCount }===================={/if} - -{ts}Your registration has been submitted.{/ts} - -{if $isPrimary} -{ts}Once your registration has been reviewed, you will receive an email with a link to a web page where you can complete the registration process.{/ts} - -{/if} -==========================================================={if $pricesetFieldsCount }===================={/if} - -{elseif $is_pay_later && !$isAmountzero} - -==========================================================={if $pricesetFieldsCount }===================={/if} - -{$pay_later_receipt} -==========================================================={if $pricesetFieldsCount }===================={/if} - -{else} - -{ts}Please print this confirmation for your records.{/ts} -{/if} - - -==========================================================={if $pricesetFieldsCount }===================={/if} - -{ts}Event Information and Location{/ts} - -==========================================================={if $pricesetFieldsCount }===================={/if} - -{$event.event_title} -{$event.event_start_date|date_format:"%A"} {$event.event_start_date|crmDate}{if $event.event_end_date}-{if $event.event_end_date|date_format:"%Y%m%d" == $event.event_start_date|date_format:"%Y%m%d"}{$event.event_end_date|crmDate:0:1}{else}{$event.event_end_date|date_format:"%A"} {$event.event_end_date|crmDate}{/if}{/if} -{if $conference_sessions} - - -{ts}Your schedule:{/ts} -{assign var='group_by_day' value='NA'} -{foreach from=$conference_sessions item=session} -{if $session.start_date|date_format:"%Y/%m/%d" != $group_by_day|date_format:"%Y/%m/%d"} -{assign var='group_by_day' value=$session.start_date} - -{$group_by_day|date_format:"%m/%d/%Y"} - - -{/if} -{$session.start_date|crmDate:0:1}{if $session.end_date}-{$session.end_date|crmDate:0:1}{/if} {$session.title} -{if $session.location} {$session.location}{/if} -{/foreach} -{/if} - -{if $event.participant_role neq 'Attendee' and $defaultRole} -{ts}Participant Role{/ts}: {$event.participant_role} -{/if} - -{if $isShowLocation} -{if $location.address.1.name} - -{$location.address.1.name} -{/if} -{if $location.address.1.street_address}{$location.address.1.street_address} -{/if} -{if $location.address.1.supplemental_address_1}{$location.address.1.supplemental_address_1} -{/if} -{if $location.address.1.supplemental_address_2}{$location.address.1.supplemental_address_2} -{/if} -{if $location.address.1.city}{$location.address.1.city}, {$location.address.1.state_province} {$location.address.1.postal_code}{if $location.address.1.postal_code_suffix} - {$location.address.1.postal_code_suffix}{/if} -{/if} - -{/if}{*End of isShowLocation condition*} - -{if $location.phone.1.phone || $location.email.1.email} - -{ts}Event Contacts:{/ts} -{foreach from=$location.phone item=phone} -{if $phone.phone} - -{if $phone.phone_type}{$phone.phone_type_display}{else}{ts}Phone{/ts}{/if}: {$phone.phone}{/if} -{/foreach} -{foreach from=$location.email item=eventEmail} -{if $eventEmail.email} - -{ts}Email{/ts}: {$eventEmail.email}{/if}{/foreach} -{/if} - -{capture assign=icalFeed}{crmURL p='civicrm/event/ical' q="reset=1&id=`$event.id`" h=0 a=1 fe=1}{/capture} -{ts}Download iCalendar File:{/ts} {$icalFeed} - -{if $payer.name} -You were registered by: {$payer.name} -{/if} -{if $event.is_monetary} {* This section for Paid events only.*} - -==========================================================={if $pricesetFieldsCount }===================={/if} - -{$event.fee_label} -==========================================================={if $pricesetFieldsCount }===================={/if} - -{if $lineItem}{foreach from=$lineItem item=value key=priceset} - -{if $value neq 'skip'} -{if $isPrimary} -{if $lineItem|@count GT 1} {* Header for multi participant registration cases. *} -{ts 1=$priceset+1}Participant %1{/ts} {$part.$priceset.info} - -{/if} -{/if} ------------------------------------------------------------{if $pricesetFieldsCount }--------------------{/if} - -{capture assign=ts_item}{ts}Item{/ts}{/capture} -{capture assign=ts_qty}{ts}Qty{/ts}{/capture} -{capture assign=ts_each}{ts}Each{/ts}{/capture} -{capture assign=ts_total}{ts}Total{/ts}{/capture} -{if $pricesetFieldsCount }{capture assign=ts_participant_total}{ts}Total Participants{/ts}{/capture}{/if} -{$ts_item|string_format:"%-30s"} {$ts_qty|string_format:"%5s"} {$ts_each|string_format:"%10s"} {$ts_total|string_format:"%10s"} {$ts_participant_total|string_format:"%10s"} ------------------------------------------------------------{if $pricesetFieldsCount }--------------------{/if} - -{foreach from=$value item=line} -{if $pricesetFieldsCount }{capture assign=ts_participant_count}{$line.participant_count}{/capture}{/if} -{capture assign=ts_item}{if $line.html_type eq 'Text'}{$line.label}{else}{$line.field_title} - {$line.label}{/if} {if $line.description} {$line.description}{/if}{/capture}{$ts_item|truncate:30:"..."|string_format:"%-30s"} {$line.qty|string_format:"%5s"} {$line.unit_price|crmMoney|string_format:"%10s"} {$line.line_total|crmMoney|string_format:"%10s"}{$ts_participant_count|string_format:"%10s"} -{/foreach} -{/if} -{/foreach} -{/if} -{if $amounts && !$lineItem} -{foreach from=$amounts item=amnt key=level}{$amnt.amount|crmMoney} {$amnt.label} -{/foreach} -{/if} -{if $isPrimary } - -{ts}Total Amount{/ts}: {$totalAmount|crmMoney} {if $hookDiscount.message}({$hookDiscount.message}){/if} - -{if $pricesetFieldsCount } - {assign var="count" value= 0} - {foreach from=$lineItem item=pcount} - {assign var="lineItemCount" value=0} - {if $pcount neq 'skip'} - {foreach from=$pcount item=p_count} - {assign var="lineItemCount" value=$lineItemCount+$p_count.participant_count} - {/foreach} - {if $lineItemCount < 1 } - {assign var="lineItemCount" value=1} - {/if} - {assign var="count" value=$count+$lineItemCount} - {/if} - {/foreach} - -{ts}Total Participants{/ts}: {$count} -{/if} - -{if $is_pay_later} - -==========================================================={if $pricesetFieldsCount }===================={/if} - -{$pay_later_receipt} -==========================================================={if $pricesetFieldsCount }===================={/if} - -{/if} - -{if $register_date} -{ts}Registration Date{/ts}: {$register_date|crmDate} -{/if} -{if $receive_date} -{ts}Transaction Date{/ts}: {$receive_date|crmDate} -{/if} -{if $contributionTypeName} -{ts}Contribution Type{/ts}: {$contributionTypeName} -{/if} -{if $trxn_id} -{ts}Transaction #{/ts}: {$trxn_id} -{/if} -{if $paidBy} -{ts}Paid By{/ts}: {$paidBy} -{/if} -{if $checkNumber} -{ts}Check Number{/ts}: {$checkNumber} -{/if} -{if $contributeMode ne 'notify' and !$isAmountzero and !$is_pay_later and !$isOnWaitlist and !$isRequireApproval} - -==========================================================={if $pricesetFieldsCount }===================={/if} - -{ts}Billing Name and Address{/ts} - -==========================================================={if $pricesetFieldsCount }===================={/if} - -{$billingName} -{$address} -{/if} - -{if $contributeMode eq 'direct' and !$isAmountzero and !$is_pay_later and !$isOnWaitlist and !$isRequireApproval} -==========================================================={if $pricesetFieldsCount }===================={/if} - -{ts}Credit Card Information{/ts} - -==========================================================={if $pricesetFieldsCount }===================={/if} - -{$credit_card_type} -{$credit_card_number} -{ts}Expires{/ts}: {$credit_card_exp_date|truncate:7:''|crmDate} -{/if} -{/if} -{/if} {* End of conditional section for Paid events *} - -{if $customPre} -{foreach from=$customPre item=customPr key=i} -==========================================================={if $pricesetFieldsCount }===================={/if} - -{$customPre_grouptitle.$i} -==========================================================={if $pricesetFieldsCount }===================={/if} - -{foreach from=$customPr item=customValue key=customName} -{if ( $trackingFields and ! in_array( $customName, $trackingFields ) ) or ! $trackingFields} - {$customName}: {$customValue} -{/if} -{/foreach} -{/foreach} -{/if} - -{if $customPost} -{foreach from=$customPost item=customPos key=j} -==========================================================={if $pricesetFieldsCount }===================={/if} - -{$customPost_grouptitle.$j} -==========================================================={if $pricesetFieldsCount }===================={/if} - -{foreach from=$customPos item=customValue key=customName} -{if ( $trackingFields and ! in_array( $customName, $trackingFields ) ) or ! $trackingFields} - {$customName}: {$customValue} -{/if} -{/foreach} -{/foreach} -{/if} -{if $customProfile} - -{foreach from=$customProfile.profile item=eachParticipant key=participantID} -==========================================================={if $pricesetFieldsCount }===================={/if} - -{ts 1=$participantID+2}Participant Information - Participant %1{/ts} - -==========================================================={if $pricesetFieldsCount }===================={/if} - -{foreach from=$eachParticipant item=eachProfile key=pid} -----------------------------------------------------------{if $pricesetFieldsCount }--------------------{/if} - -{$customProfile.title.$pid} -----------------------------------------------------------{if $pricesetFieldsCount }--------------------{/if} - -{foreach from=$eachProfile item=val key=field} -{foreach from=$val item=v key=f} -{$field}: {$v} -{/foreach} -{/foreach} -{/foreach} -{/foreach} -{/if} -{if $customGroup} -{foreach from=$customGroup item=value key=customName} -=========================================================={if $pricesetFieldsCount }===================={/if} - -{$customName} -=========================================================={if $pricesetFieldsCount }===================={/if} - -{foreach from=$value item=v key=n} -{$n}: {$v} -{/foreach} -{/foreach} -{/if} diff --git a/civicrm/CRM/Upgrade/4.2.alpha2.msg_template/message_templates/membership_offline_receipt_text.tpl b/civicrm/CRM/Upgrade/4.2.alpha2.msg_template/message_templates/membership_offline_receipt_text.tpl deleted file mode 100644 index 171fea2a4b..0000000000 --- a/civicrm/CRM/Upgrade/4.2.alpha2.msg_template/message_templates/membership_offline_receipt_text.tpl +++ /dev/null @@ -1,90 +0,0 @@ -{if $formValues.receipt_text_signup} -{$formValues.receipt_text_signup} -{elseif $formValues.receipt_text_renewal} -{$formValues.receipt_text_renewal} -{else}{ts}Thank you for your support.{/ts}{/if} - -{if ! $cancelled}{ts}Please print this receipt for your records.{/ts} - - -{/if} -{if !$lineItem} -=========================================================== -{ts}Membership Information{/ts} - -=========================================================== -{ts}Membership Type{/ts}: {$membership_name} -{/if} -{if ! $cancelled} -{if !$lineItem} -{ts}Membership Start Date{/ts}: {$mem_start_date} -{ts}Membership End Date{/ts}: {$mem_end_date} -{/if} - -{if $formValues.total_amount} -=========================================================== -{ts}Membership Fee{/ts} - -=========================================================== -{if $formValues.contributionType_name} -{ts}Contribution Type{/ts}: {$formValues.contributionType_name} -{/if} -{if $lineItem} -{foreach from=$lineItem item=value key=priceset} -{capture assign=ts_item}{ts}Item{/ts}{/capture} -{capture assign=ts_total}{ts}Fee{/ts}{/capture} -{capture assign=ts_start_date}{ts}Membership Start Date{/ts}{/capture} -{capture assign=ts_end_date}{ts}Membership End Date{/ts}{/capture} -{$ts_item|string_format:"%-30s"} {$ts_total|string_format:"%10s"} {$ts_start_date|string_format:"%20s"} {$ts_end_date|string_format:"%20s"} --------------------------------------------------------------------------------------------------- - -{foreach from=$value item=line} -{capture assign=ts_item}{if $line.html_type eq 'Text'}{$line.label}{else}{$line.field_title} - {$line.label}{/if} {if $line.description} {$line.description}{/if}{/capture}{$ts_item|truncate:30:"..."|string_format:"%-30s"} {$line.line_total|crmMoney|string_format:"%10s"} {$line.start_date|string_format:"%20s"} {$line.end_date|string_format:"%20s"} -{/foreach} -{/foreach} --------------------------------------------------------------------------------------------------- -{/if} -{ts}Amount{/ts}: {$formValues.total_amount|crmMoney} -{if $receive_date} -{ts}Received Date{/ts}: {$receive_date|truncate:10:''|crmDate} -{/if} -{if $formValues.paidBy} -{ts}Paid By{/ts}: {$formValues.paidBy} -{if $formValues.check_number} -{ts}Check Number{/ts}: {$formValues.check_number} -{/if} -{/if} -{/if} -{/if} - -{if $isPrimary } -{if $contributeMode ne 'notify' and !$isAmountzero and !$is_pay_later } - -=========================================================== -{ts}Billing Name and Address{/ts} - -=========================================================== -{$billingName} -{$address} -{/if} - -{if $contributeMode eq 'direct' and !$isAmountzero and !$is_pay_later} -=========================================================== -{ts}Credit Card Information{/ts} - -=========================================================== -{$credit_card_type} -{$credit_card_number} -{ts}Expires{/ts}: {$credit_card_exp_date|truncate:7:''|crmDate} -{/if} -{/if} - -{if $customValues} -=========================================================== -{ts}Membership Options{/ts} - -=========================================================== -{foreach from=$customValues item=value key=customName} - {$customName} : {$value} -{/foreach} -{/if} diff --git a/civicrm/CRM/Upgrade/4.2.alpha3.msg_template/civicrm_msg_template.tpl b/civicrm/CRM/Upgrade/4.2.alpha3.msg_template/civicrm_msg_template.tpl deleted file mode 100644 index 9ae70aad86..0000000000 --- a/civicrm/CRM/Upgrade/4.2.alpha3.msg_template/civicrm_msg_template.tpl +++ /dev/null @@ -1,16 +0,0 @@ -{php} - $dir = SMARTY_DIR . '/../../CRM/Upgrade/4.2.alpha3.msg_template/message_templates'; - $templates = array(); - foreach (preg_grep('/\.tpl$/', scandir($dir)) as $filename) { - $parts = explode('_', basename($filename, '.tpl')); - $templates[] = array('type' => array_pop($parts), 'name' => implode('_', $parts), 'filename' => "$dir/$filename"); - } - $this->assign('templates', $templates); -{/php} - -{foreach from=$templates item=tpl} - {fetch assign=content file=$tpl.filename} - SELECT @workflow_id := MAX(id) FROM civicrm_option_value WHERE name = '{$tpl.name}'; - SELECT @content := msg_{$tpl.type} FROM civicrm_msg_template WHERE workflow_id = @workflow_id AND is_reserved = 1 LIMIT 1; - UPDATE civicrm_msg_template SET msg_{$tpl.type} = '{$content|escape:"quotes"}' WHERE workflow_id = @workflow_id AND (is_reserved = 1 OR (is_default = 1 AND msg_{$tpl.type} = @content)); -{/foreach} diff --git a/civicrm/CRM/Upgrade/4.2.alpha3.msg_template/message_templates/contribution_online_receipt_text.tpl b/civicrm/CRM/Upgrade/4.2.alpha3.msg_template/message_templates/contribution_online_receipt_text.tpl deleted file mode 100644 index bcd6e97283..0000000000 --- a/civicrm/CRM/Upgrade/4.2.alpha3.msg_template/message_templates/contribution_online_receipt_text.tpl +++ /dev/null @@ -1,179 +0,0 @@ -{if $receipt_text} -{$receipt_text} -{/if} -{if $is_pay_later} - -=========================================================== -{$pay_later_receipt} -=========================================================== -{else} - -{ts}Please print this receipt for your records.{/ts} -{/if} - -{if $amount} -=========================================================== -{ts}Contribution Information{/ts} - -=========================================================== -{if $lineItem and $priceSetID and !$is_quick_config} -{foreach from=$lineItem item=value key=priceset} ---------------------------------------------------------- -{capture assign=ts_item}{ts}Item{/ts}{/capture} -{capture assign=ts_qty}{ts}Qty{/ts}{/capture} -{capture assign=ts_each}{ts}Each{/ts}{/capture} -{capture assign=ts_total}{ts}Total{/ts}{/capture} -{$ts_item|string_format:"%-30s"} {$ts_qty|string_format:"%5s"} {$ts_each|string_format:"%10s"} {$ts_total|string_format:"%10s"} ----------------------------------------------------------- -{foreach from=$value item=line} -{capture assign=ts_item}{if $line.html_type eq 'Text'}{$line.label}{else}{$line.field_title} - {$line.label}{/if} {if $line.description} {$line.description}{/if}{/capture}{$ts_item|truncate:30:"..."|string_format:"%-30s"} {$line.qty|string_format:"%5s"} {$line.unit_price|crmMoney:$currency|string_format:"%10s"} {$line.line_total|crmMoney:$currency|string_format:"%10s"} -{/foreach} -{/foreach} - -{ts}Total Amount{/ts}: {$amount|crmMoney:$currency} -{else} -{ts}Amount{/ts}: {$amount|crmMoney:$currency} {if $amount_level } - {$amount_level} {/if} -{/if} -{/if} -{if $receive_date} - -{ts}Date{/ts}: {$receive_date|crmDate} -{/if} -{if $is_monetary and $trxn_id} -{ts}Transaction #{/ts}: {$trxn_id} -{/if} - -{if $is_recur and ($contributeMode eq 'notify' or $contributeMode eq 'directIPN')} -{ts}This is a recurring contribution. You can cancel future contributions at:{/ts} - -{$cancelSubscriptionUrl} - -{ts}You can update billing details for this recurring contribution at:{/ts} - -{$updateSubscriptionBillingUrl} - -{ts}You can update recurring contribution amount or change the number of installments for this recurring contribution at:{/ts} - -{$updateSubscriptionUrl} - -{/if} - -{if $honor_block_is_active } -=========================================================== -{$honor_type} -=========================================================== -{$honor_prefix} {$honor_first_name} {$honor_last_name} -{if $honor_email} -{ts}Honoree Email{/ts}: {$honor_email} -{/if} - -{/if} -{if $pcpBlock} -=========================================================== -{ts}Personal Campaign Page{/ts} - -=========================================================== -{ts}Display In Honor Roll{/ts}: {if $pcp_display_in_roll}{ts}Yes{/ts}{else}{ts}No{/ts}{/if} - -{if $pcp_roll_nickname}{ts}Nickname{/ts}: {$pcp_roll_nickname}{/if} - -{if $pcp_personal_note}{ts}Personal Note{/ts}: {$pcp_personal_note}{/if} - -{/if} -{if $onBehalfProfile} -=========================================================== -{ts}On Behalf Of{/ts} - -=========================================================== -{foreach from=$onBehalfProfile item=onBehalfValue key=onBehalfName} -{$onBehalfName}: {$onBehalfValue} -{/foreach} -{/if} - -{if !( $contributeMode eq 'notify' OR $contributeMode eq 'directIPN' ) and $is_monetary} -{if $is_pay_later} -=========================================================== -{ts}Registered Email{/ts} - -=========================================================== -{$email} -{elseif $amount GT 0} -=========================================================== -{ts}Billing Name and Address{/ts} - -=========================================================== -{$billingName} -{$address} - -{$email} -{/if} {* End ! is_pay_later condition. *} -{/if} -{if $contributeMode eq 'direct' AND !$is_pay_later AND $amount GT 0} - -=========================================================== -{ts}Credit Card Information{/ts} - -=========================================================== -{$credit_card_type} -{$credit_card_number} -{ts}Expires{/ts}: {$credit_card_exp_date|truncate:7:''|crmDate} -{/if} - -{if $selectPremium } -=========================================================== -{ts}Premium Information{/ts} - -=========================================================== -{$product_name} -{if $option} -{ts}Option{/ts}: {$option} -{/if} -{if $sku} -{ts}SKU{/ts}: {$sku} -{/if} -{if $start_date} -{ts}Start Date{/ts}: {$start_date|crmDate} -{/if} -{if $end_date} -{ts}End Date{/ts}: {$end_date|crmDate} -{/if} -{if $contact_email OR $contact_phone} - -{ts}For information about this premium, contact:{/ts} - -{if $contact_email} - {$contact_email} -{/if} -{if $contact_phone} - {$contact_phone} -{/if} -{/if} -{if $is_deductible AND $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} - -{if $customPre} -=========================================================== -{$customPre_grouptitle} - -=========================================================== -{foreach from=$customPre item=customValue key=customName} -{if ( $trackingFields and ! in_array( $customName, $trackingFields ) ) or ! $trackingFields} - {$customName}: {$customValue} -{/if} -{/foreach} -{/if} - - -{if $customPost} -=========================================================== -{$customPost_grouptitle} - -=========================================================== -{foreach from=$customPost item=customValue key=customName} -{if ( $trackingFields and ! in_array( $customName, $trackingFields ) ) or ! $trackingFields} - {$customName}: {$customValue} -{/if} -{/foreach} -{/if} diff --git a/civicrm/CRM/Upgrade/4.2.beta3.msg_template/civicrm_msg_template.tpl b/civicrm/CRM/Upgrade/4.2.beta3.msg_template/civicrm_msg_template.tpl deleted file mode 100644 index 66f5a65df4..0000000000 --- a/civicrm/CRM/Upgrade/4.2.beta3.msg_template/civicrm_msg_template.tpl +++ /dev/null @@ -1,16 +0,0 @@ -{php} - $dir = SMARTY_DIR . '/../../CRM/Upgrade/4.2.beta3.msg_template/message_templates'; - $templates = array(); - foreach (preg_grep('/\.tpl$/', scandir($dir)) as $filename) { - $parts = explode('_', basename($filename, '.tpl')); - $templates[] = array('type' => array_pop($parts), 'name' => implode('_', $parts), 'filename' => "$dir/$filename"); - } - $this->assign('templates', $templates); -{/php} - -{foreach from=$templates item=tpl} - {fetch assign=content file=$tpl.filename} - SELECT @workflow_id := MAX(id) FROM civicrm_option_value WHERE name = '{$tpl.name}'; - SELECT @content := msg_{$tpl.type} FROM civicrm_msg_template WHERE workflow_id = @workflow_id AND is_reserved = 1 LIMIT 1; - UPDATE civicrm_msg_template SET msg_{$tpl.type} = '{$content|escape:"quotes"}' WHERE workflow_id = @workflow_id AND (is_reserved = 1 OR (is_default = 1 AND msg_{$tpl.type} = @content)); -{/foreach} diff --git a/civicrm/CRM/Upgrade/4.2.beta3.msg_template/message_templates/event_online_receipt_html.tpl b/civicrm/CRM/Upgrade/4.2.beta3.msg_template/message_templates/event_online_receipt_html.tpl deleted file mode 100644 index 9b257e55af..0000000000 --- a/civicrm/CRM/Upgrade/4.2.beta3.msg_template/message_templates/event_online_receipt_html.tpl +++ /dev/null @@ -1,450 +0,0 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml"> -<head> - <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> - <title></title> -</head> -<body> - -{capture assign=headerStyle}colspan="2" style="text-align: left; padding: 4px; border-bottom: 1px solid #999; background-color: #eee;"{/capture} -{capture assign=labelStyle }style="padding: 4px; border-bottom: 1px solid #999; background-color: #f7f7f7;"{/capture} -{capture assign=valueStyle }style="padding: 4px; border-bottom: 1px solid #999;"{/capture} - -<center> - <table width="500" border="0" cellpadding="0" cellspacing="0" id="crm-event_receipt" style="font-family: Arial, Verdana, sans-serif; text-align: left;"> - - <!-- BEGIN HEADER --> - <!-- You can add table row(s) here with logo or other header elements --> - <!-- END HEADER --> - - <!-- BEGIN CONTENT --> - - <tr> - <td> - <p>Dear {contact.display_name},</p> - - {if $event.confirm_email_text AND (not $isOnWaitlist AND not $isRequireApproval)} - <p>{$event.confirm_email_text|htmlize}</p> - - {else} - <p>Thank you for your participation. This letter is a confirmation that your registration has been received and your status has been updated to <strong>{if $isOnWaitlist}waitlisted{else}registered{/if}</strong> for the following:</p> - - {/if} - - <p> - {if $isOnWaitlist} - <p>{ts}You have been added to the WAIT LIST for this event.{/ts}</p> - {if $isPrimary} - <p>{ts}If space becomes available you will receive an email with a link to a web page where you can complete your registration.{/ts}</p> - {/if} - {elseif $isRequireApproval} - <p>{ts}Your registration has been submitted.{/ts}</p> - {if $isPrimary} - <p>{ts}Once your registration has been reviewed, you will receive an email with a link to a web page where you can complete the registration process.{/ts}</p> - {/if} - {elseif $is_pay_later && !$isAmountzero} - <p>{$pay_later_receipt}</p> {* FIXME: this might be text rather than HTML *} - {else} - <p>{ts}Please print this confirmation for your records.{/ts}</p> - {/if} - - </td> - </tr> - <tr> - <td> - <table width="500" style="border: 1px solid #999; margin: 1em 0em 1em; border-collapse: collapse;"> - <tr> - <th {$headerStyle}> - {ts}Event Information and Location{/ts} - </th> - </tr> - <tr> - <td colspan="2" {$valueStyle}> - {$event.event_title}<br /> - {$event.event_start_date|date_format:"%A"} {$event.event_start_date|crmDate}{if $event.event_end_date}-{if $event.event_end_date|date_format:"%Y%m%d" == $event.event_start_date|date_format:"%Y%m%d"}{$event.event_end_date|crmDate:0:1}{else}{$event.event_end_date|date_format:"%A"} {$event.event_end_date|crmDate}{/if}{/if} - </td> - </tr> - - - {if $conference_sessions} - <tr> - <td colspan="2" {$labelStyle}> - {ts}Your schedule:{/ts} - </td> - </tr> - <tr> - <td colspan="2" {$valueStyle}> - {assign var='group_by_day' value='NA'} - {foreach from=$conference_sessions item=session} - {if $session.start_date|date_format:"%Y/%m/%d" != $group_by_day|date_format:"%Y/%m/%d"} - {assign var='group_by_day' value=$session.start_date} - <em>{$group_by_day|date_format:"%m/%d/%Y"}</em><br /> - {/if} - {$session.start_date|crmDate:0:1}{if $session.end_date}-{$session.end_date|crmDate:0:1}{/if} {$session.title}<br /> - {if $session.location} {$session.location}<br />{/if} - {/foreach} - </td> - </tr> - {/if} - - {if $event.participant_role neq 'Attendee' and $defaultRole} - <tr> - <td {$labelStyle}> - {ts}Participant Role{/ts} - </td> - <td {$valueStyle}> - {$event.participant_role} - </td> - </tr> - {/if} - - {if $isShowLocation} - <tr> - <td colspan="2" {$valueStyle}> - {if $location.address.1.name} - {$location.address.1.name}<br /> - {/if} - {if $location.address.1.street_address} - {$location.address.1.street_address}<br /> - {/if} - {if $location.address.1.supplemental_address_1} - {$location.address.1.supplemental_address_1}<br /> - {/if} - {if $location.address.1.supplemental_address_2} - {$location.address.1.supplemental_address_2}<br /> - {/if} - {if $location.address.1.city} - {$location.address.1.city}, {$location.address.1.state_province} {$location.address.1.postal_code}{if $location.address.1.postal_code_suffix} - {$location.address.1.postal_code_suffix}{/if}<br /> - {/if} - </td> - </tr> - {/if} - - {if $location.phone.1.phone || $location.email.1.email} - <tr> - <td colspan="2" {$labelStyle}> - {ts}Event Contacts:{/ts} - </td> - </tr> - {foreach from=$location.phone item=phone} - {if $phone.phone} - <tr> - <td {$labelStyle}> - {if $phone.phone_type} - {$phone.phone_type_display} - {else} - {ts}Phone{/ts} - {/if} - </td> - <td {$valueStyle}> - {$phone.phone} - </td> - </tr> - {/if} - {/foreach} - {foreach from=$location.email item=eventEmail} - {if $eventEmail.email} - <tr> - <td {$labelStyle}> - {ts}Email{/ts} - </td> - <td {$valueStyle}> - {$eventEmail.email} - </td> - </tr> - {/if} - {/foreach} - {/if} - <tr> - <td colspan="2" {$valueStyle}> - {capture assign=icalFeed}{crmURL p='civicrm/event/ical' q="reset=1&id=`$event.id`" h=0 a=1 fe=1}{/capture} - <a href="{$icalFeed}">{ts}Download iCalendar File{/ts}</a> - </td> - </tr> - {if $event.is_share} - <tr> - <td colspan="2" {$valueStyle}> - {capture assign=eventUrl}{crmURL p='civicrm/event/info' q="id=`$event.id`&reset=1" a=true fe=1 h=1}{/capture} - {include file="CRM/common/SocialNetwork.tpl" emailMode=true url=$eventUrl title=$event.title pageURL=$eventUrl} - </td> - </tr> - {/if} - {if $payer.name} - <tr> - <th {$headerStyle}> - {ts}You were registered by:{/ts} - </th> - </tr> - <tr> - <td colspan="2" {$valueStyle}> - {$payer.name} - </td> - </tr> - {/if} - {if $event.is_monetary} - - <tr> - <th {$headerStyle}> - {$event.fee_label} - </th> - </tr> - - {if $lineItem} - {foreach from=$lineItem item=value key=priceset} - {if $value neq 'skip'} - {if $isPrimary} - {if $lineItem|@count GT 1} {* Header for multi participant registration cases. *} - <tr> - <td colspan="2" {$labelStyle}> - {ts 1=$priceset+1}Participant %1{/ts} {$part.$priceset.info} - </td> - </tr> - {/if} - {/if} - <tr> - <td colspan="2" {$valueStyle}> - <table> {* FIXME: style this table so that it looks like the text version (justification, etc.) *} - <tr> - <th>{ts}Item{/ts}</th> - <th>{ts}Qty{/ts}</th> - <th>{ts}Each{/ts}</th> - <th>{ts}Total{/ts}</th> - {if $pricesetFieldsCount }<th>{ts}Total Participants{/ts}</th>{/if} - </tr> - {foreach from=$value item=line} - <tr> - <td> - {if $line.html_type eq 'Text'}{$line.label}{else}{$line.field_title} - {$line.label}{/if} {if $line.description}<div>{$line.description|truncate:30:"..."}</div>{/if} - </td> - <td> - {$line.qty} - </td> - <td> - {$line.unit_price|crmMoney} - </td> - <td> - {$line.line_total|crmMoney} - </td> - {if $pricesetFieldsCount }<td>{$line.participant_count}</td> {/if} - </tr> - {/foreach} - </table> - </td> - </tr> - {/if} - {/foreach} - {/if} - - {if $amounts && !$lineItem} - {foreach from=$amounts item=amnt key=level} - <tr> - <td colspan="2" {$valueStyle}> - {$amnt.amount|crmMoney} {$amnt.label} - </td> - </tr> - {/foreach} - {/if} - - {if $isPrimary} - <tr> - <td {$labelStyle}> - {ts}Total Amount{/ts} - </td> - <td {$valueStyle}> - {$totalAmount|crmMoney} {if $hookDiscount.message}({$hookDiscount.message}){/if} - </td> - </tr> - {if $pricesetFieldsCount } - <tr> - <td {$labelStyle}> - {ts}Total Participants{/ts}</td> - <td {$valueStyle}> - {assign var="count" value= 0} - {foreach from=$lineItem item=pcount} - {assign var="lineItemCount" value=0} - {if $pcount neq 'skip'} - {foreach from=$pcount item=p_count} - {assign var="lineItemCount" value=$lineItemCount+$p_count.participant_count} - {/foreach} - {if $lineItemCount < 1 } - {assign var="lineItemCount" value=1} - {/if} - {assign var="count" value=$count+$lineItemCount} - {/if} - {/foreach} - {$count} - </td> </tr> - {/if} - - {if $register_date} - <tr> - <td {$labelStyle}> - {ts}Registration Date{/ts} - </td> - <td {$valueStyle}> - {$register_date|crmDate} - </td> - </tr> - {/if} - - {if $receive_date} - <tr> - <td {$labelStyle}> - {ts}Transaction Date{/ts} - </td> - <td {$valueStyle}> - {$receive_date|crmDate} - </td> - </tr> - {/if} - - {if $contributionTypeName} - <tr> - <td {$labelStyle}> - {ts}Contribution Type{/ts} - </td> - <td {$valueStyle}> - {$contributionTypeName} - </td> - </tr> - {/if} - - {if $trxn_id} - <tr> - <td {$labelStyle}> - {ts}Transaction #{/ts} - </td> - <td {$valueStyle}> - {$trxn_id} - </td> - </tr> - {/if} - - {if $paidBy} - <tr> - <td {$labelStyle}> - {ts}Paid By{/ts} - </td> - <td {$valueStyle}> - {$paidBy} - </td> - </tr> - {/if} - - {if $checkNumber} - <tr> - <td {$labelStyle}> - {ts}Check Number{/ts} - </td> - <td {$valueStyle}> - {$checkNumber} - </td> - </tr> - {/if} - - {if $contributeMode ne 'notify' and !$isAmountzero and !$is_pay_later and !$isOnWaitlist and !$isRequireApproval} - <tr> - <th {$headerStyle}> - {ts}Billing Name and Address{/ts} - </th> - </tr> - <tr> - <td colspan="2" {$valueStyle}> - {$billingName}<br /> - {$address|nl2br} - </td> - </tr> - {/if} - - {if $contributeMode eq 'direct' and !$isAmountzero and !$is_pay_later and !$isOnWaitlist and !$isRequireApproval} - <tr> - <th {$headerStyle}> - {ts}Credit Card Information{/ts} - </th> - </tr> - <tr> - <td colspan="2" {$valueStyle}> - {$credit_card_type}<br /> - {$credit_card_number}<br /> - {ts}Expires{/ts}: {$credit_card_exp_date|truncate:7:''|crmDate} - </td> - </tr> - {/if} - - {/if} - - {/if} {* End of conditional section for Paid events *} - - -{if $customPre} -{foreach from=$customPre item=customPr key=i} - <tr> <th {$headerStyle}>{$customPre_grouptitle.$i}</th></tr> - {foreach from=$customPr item=customValue key=customName} - {if ( $trackingFields and ! in_array( $customName, $trackingFields ) ) or ! $trackingFields} - <tr> - <td {$labelStyle}>{$customName}</td> - <td {$valueStyle}>{$customValue}</td> - </tr> - {/if} - {/foreach} -{/foreach} -{/if} - -{if $customPost} -{foreach from=$customPost item=customPos key=j} - <tr> <th {$headerStyle}>{$customPost_grouptitle.$j}</th></tr> - {foreach from=$customPos item=customValue key=customName} - {if ( $trackingFields and ! in_array( $customName, $trackingFields ) ) or ! $trackingFields} - <tr> - <td {$labelStyle}>{$customName}</td> - <td {$valueStyle}>{$customValue}</td> - </tr> -{/if} -{/foreach} -{/foreach} -{/if} - -{if $customProfile} -{foreach from=$customProfile.profile item=eachParticipant key=participantID} - <tr><th {$headerStyle}>{ts 1=$participantID+2}Participant %1{/ts} </th></tr> - {foreach from=$eachParticipant item=eachProfile key=pid} - <tr><th {$headerStyle}>{$customProfile.title.$pid}</th></tr> - {foreach from=$eachProfile item=val key=field} - <tr>{foreach from=$val item=v key=f} - <td {$labelStyle}>{$field}</td> - <td {$valueStyle}>{$v}</td> - {/foreach} - </tr> - {/foreach} -{/foreach} -{/foreach} -{/if} - - {if $customGroup} - {foreach from=$customGroup item=value key=customName} - <tr> - <th {$headerStyle}> - {$customName} - </th> - </tr> - {foreach from=$value item=v key=n} - <tr> - <td {$labelStyle}> - {$n} - </td> - <td {$valueStyle}> - {$v} - </td> - </tr> - {/foreach} - {/foreach} - {/if} - - </table> - </td> - </tr> - </table> -</center> - -</body> -</html> diff --git a/civicrm/CRM/Upgrade/4.2.beta3.msg_template/message_templates/event_online_receipt_text.tpl b/civicrm/CRM/Upgrade/4.2.beta3.msg_template/message_templates/event_online_receipt_text.tpl deleted file mode 100644 index 56527f51ba..0000000000 --- a/civicrm/CRM/Upgrade/4.2.beta3.msg_template/message_templates/event_online_receipt_text.tpl +++ /dev/null @@ -1,277 +0,0 @@ -Dear {contact.display_name}, - -{if $event.confirm_email_text AND (not $isOnWaitlist AND not $isRequireApproval)} -{$event.confirm_email_text} - -{else} -Thank you for your participation. This letter is a confirmation that your registration has been received and your status has been updated to {if $participant_status}$participant_status{else}{if $isOnWaitlist}waitlisted{else}registered{/if}{/if} for the following: - -{/if} - -{if $isOnWaitlist} -==========================================================={if $pricesetFieldsCount }===================={/if} - -{ts}You have been added to the WAIT LIST for this event.{/ts} - -{if $isPrimary} -{ts}If space becomes available you will receive an email with a link to a web page where you can complete your registration.{/ts} -{/if} -==========================================================={if $pricesetFieldsCount }===================={/if} - -{elseif $isRequireApproval} -==========================================================={if $pricesetFieldsCount }===================={/if} - -{ts}Your registration has been submitted.{/ts} - -{if $isPrimary} -{ts}Once your registration has been reviewed, you will receive an email with a link to a web page where you can complete the registration process.{/ts} - -{/if} -==========================================================={if $pricesetFieldsCount }===================={/if} - -{elseif $is_pay_later && !$isAmountzero} - -==========================================================={if $pricesetFieldsCount }===================={/if} - -{$pay_later_receipt} -==========================================================={if $pricesetFieldsCount }===================={/if} - -{else} - -{ts}Please print this confirmation for your records.{/ts} -{/if} - - -==========================================================={if $pricesetFieldsCount }===================={/if} - -{ts}Event Information and Location{/ts} - -==========================================================={if $pricesetFieldsCount }===================={/if} - -{$event.event_title} -{$event.event_start_date|date_format:"%A"} {$event.event_start_date|crmDate}{if $event.event_end_date}-{if $event.event_end_date|date_format:"%Y%m%d" == $event.event_start_date|date_format:"%Y%m%d"}{$event.event_end_date|crmDate:0:1}{else}{$event.event_end_date|date_format:"%A"} {$event.event_end_date|crmDate}{/if}{/if} -{if $conference_sessions} - - -{ts}Your schedule:{/ts} -{assign var='group_by_day' value='NA'} -{foreach from=$conference_sessions item=session} -{if $session.start_date|date_format:"%Y/%m/%d" != $group_by_day|date_format:"%Y/%m/%d"} -{assign var='group_by_day' value=$session.start_date} - -{$group_by_day|date_format:"%m/%d/%Y"} - - -{/if} -{$session.start_date|crmDate:0:1}{if $session.end_date}-{$session.end_date|crmDate:0:1}{/if} {$session.title} -{if $session.location} {$session.location}{/if} -{/foreach} -{/if} - -{if $event.participant_role neq 'Attendee' and $defaultRole} -{ts}Participant Role{/ts}: {$event.participant_role} -{/if} - -{if $isShowLocation} -{if $location.address.1.name} - -{$location.address.1.name} -{/if} -{if $location.address.1.street_address}{$location.address.1.street_address} -{/if} -{if $location.address.1.supplemental_address_1}{$location.address.1.supplemental_address_1} -{/if} -{if $location.address.1.supplemental_address_2}{$location.address.1.supplemental_address_2} -{/if} -{if $location.address.1.city}{$location.address.1.city}, {$location.address.1.state_province} {$location.address.1.postal_code}{if $location.address.1.postal_code_suffix} - {$location.address.1.postal_code_suffix}{/if} -{/if} - -{/if}{*End of isShowLocation condition*} - -{if $location.phone.1.phone || $location.email.1.email} - -{ts}Event Contacts:{/ts} -{foreach from=$location.phone item=phone} -{if $phone.phone} - -{if $phone.phone_type}{$phone.phone_type_display}{else}{ts}Phone{/ts}{/if}: {$phone.phone}{/if} -{/foreach} -{foreach from=$location.email item=eventEmail} -{if $eventEmail.email} - -{ts}Email{/ts}: {$eventEmail.email}{/if}{/foreach} -{/if} - -{capture assign=icalFeed}{crmURL p='civicrm/event/ical' q="reset=1&id=`$event.id`" h=0 a=1 fe=1}{/capture} -{ts}Download iCalendar File:{/ts} {$icalFeed} - -{if $payer.name} -You were registered by: {$payer.name} -{/if} -{if $event.is_monetary} {* This section for Paid events only.*} - -==========================================================={if $pricesetFieldsCount }===================={/if} - -{$event.fee_label} -==========================================================={if $pricesetFieldsCount }===================={/if} - -{if $lineItem}{foreach from=$lineItem item=value key=priceset} - -{if $value neq 'skip'} -{if $isPrimary} -{if $lineItem|@count GT 1} {* Header for multi participant registration cases. *} -{ts 1=$priceset+1}Participant %1{/ts} {$part.$priceset.info} - -{/if} -{/if} ------------------------------------------------------------{if $pricesetFieldsCount }--------------------{/if} - -{capture assign=ts_item}{ts}Item{/ts}{/capture} -{capture assign=ts_qty}{ts}Qty{/ts}{/capture} -{capture assign=ts_each}{ts}Each{/ts}{/capture} -{capture assign=ts_total}{ts}Total{/ts}{/capture} -{if $pricesetFieldsCount }{capture assign=ts_participant_total}{ts}Total Participants{/ts}{/capture}{/if} -{$ts_item|string_format:"%-30s"} {$ts_qty|string_format:"%5s"} {$ts_each|string_format:"%10s"} {$ts_total|string_format:"%10s"} {$ts_participant_total|string_format:"%10s"} ------------------------------------------------------------{if $pricesetFieldsCount }--------------------{/if} - -{foreach from=$value item=line} -{if $pricesetFieldsCount }{capture assign=ts_participant_count}{$line.participant_count}{/capture}{/if} -{capture assign=ts_item}{if $line.html_type eq 'Text'}{$line.label}{else}{$line.field_title} - {$line.label}{/if} {if $line.description} {$line.description}{/if}{/capture}{$ts_item|truncate:30:"..."|string_format:"%-30s"} {$line.qty|string_format:"%5s"} {$line.unit_price|crmMoney|string_format:"%10s"} {$line.line_total|crmMoney|string_format:"%10s"}{$ts_participant_count|string_format:"%10s"} -{/foreach} -{/if} -{/foreach} -{/if} -{if $amounts && !$lineItem} -{foreach from=$amounts item=amnt key=level}{$amnt.amount|crmMoney} {$amnt.label} -{/foreach} -{/if} -{if $isPrimary } - -{ts}Total Amount{/ts}: {$totalAmount|crmMoney} {if $hookDiscount.message}({$hookDiscount.message}){/if} - -{if $pricesetFieldsCount } - {assign var="count" value= 0} - {foreach from=$lineItem item=pcount} - {assign var="lineItemCount" value=0} - {if $pcount neq 'skip'} - {foreach from=$pcount item=p_count} - {assign var="lineItemCount" value=$lineItemCount+$p_count.participant_count} - {/foreach} - {if $lineItemCount < 1 } - {assign var="lineItemCount" value=1} - {/if} - {assign var="count" value=$count+$lineItemCount} - {/if} - {/foreach} - -{ts}Total Participants{/ts}: {$count} -{/if} - -{if $register_date} -{ts}Registration Date{/ts}: {$register_date|crmDate} -{/if} -{if $receive_date} -{ts}Transaction Date{/ts}: {$receive_date|crmDate} -{/if} -{if $contributionTypeName} -{ts}Contribution Type{/ts}: {$contributionTypeName} -{/if} -{if $trxn_id} -{ts}Transaction #{/ts}: {$trxn_id} -{/if} -{if $paidBy} -{ts}Paid By{/ts}: {$paidBy} -{/if} -{if $checkNumber} -{ts}Check Number{/ts}: {$checkNumber} -{/if} -{if $contributeMode ne 'notify' and !$isAmountzero and !$is_pay_later and !$isOnWaitlist and !$isRequireApproval} - -==========================================================={if $pricesetFieldsCount }===================={/if} - -{ts}Billing Name and Address{/ts} - -==========================================================={if $pricesetFieldsCount }===================={/if} - -{$billingName} -{$address} -{/if} - -{if $contributeMode eq 'direct' and !$isAmountzero and !$is_pay_later and !$isOnWaitlist and !$isRequireApproval} -==========================================================={if $pricesetFieldsCount }===================={/if} - -{ts}Credit Card Information{/ts} - -==========================================================={if $pricesetFieldsCount }===================={/if} - -{$credit_card_type} -{$credit_card_number} -{ts}Expires{/ts}: {$credit_card_exp_date|truncate:7:''|crmDate} -{/if} -{/if} -{/if} {* End of conditional section for Paid events *} - -{if $customPre} -{foreach from=$customPre item=customPr key=i} -==========================================================={if $pricesetFieldsCount }===================={/if} - -{$customPre_grouptitle.$i} -==========================================================={if $pricesetFieldsCount }===================={/if} - -{foreach from=$customPr item=customValue key=customName} -{if ( $trackingFields and ! in_array( $customName, $trackingFields ) ) or ! $trackingFields} - {$customName}: {$customValue} -{/if} -{/foreach} -{/foreach} -{/if} - -{if $customPost} -{foreach from=$customPost item=customPos key=j} -==========================================================={if $pricesetFieldsCount }===================={/if} - -{$customPost_grouptitle.$j} -==========================================================={if $pricesetFieldsCount }===================={/if} - -{foreach from=$customPos item=customValue key=customName} -{if ( $trackingFields and ! in_array( $customName, $trackingFields ) ) or ! $trackingFields} - {$customName}: {$customValue} -{/if} -{/foreach} -{/foreach} -{/if} -{if $customProfile} - -{foreach from=$customProfile.profile item=eachParticipant key=participantID} -==========================================================={if $pricesetFieldsCount }===================={/if} - -{ts 1=$participantID+2}Participant Information - Participant %1{/ts} - -==========================================================={if $pricesetFieldsCount }===================={/if} - -{foreach from=$eachParticipant item=eachProfile key=pid} -----------------------------------------------------------{if $pricesetFieldsCount }--------------------{/if} - -{$customProfile.title.$pid} -----------------------------------------------------------{if $pricesetFieldsCount }--------------------{/if} - -{foreach from=$eachProfile item=val key=field} -{foreach from=$val item=v key=f} -{$field}: {$v} -{/foreach} -{/foreach} -{/foreach} -{/foreach} -{/if} -{if $customGroup} -{foreach from=$customGroup item=value key=customName} -=========================================================={if $pricesetFieldsCount }===================={/if} - -{$customName} -=========================================================={if $pricesetFieldsCount }===================={/if} - -{foreach from=$value item=v key=n} -{$n}: {$v} -{/foreach} -{/foreach} -{/if} diff --git a/civicrm/CRM/Upgrade/Form.php b/civicrm/CRM/Upgrade/Form.php index b13361347c..01bc78a704 100644 --- a/civicrm/CRM/Upgrade/Form.php +++ b/civicrm/CRM/Upgrade/Form.php @@ -45,7 +45,7 @@ class CRM_Upgrade_Form extends CRM_Core_Form { /** * Minimum previous CiviCRM version we can directly upgrade from */ - const MINIMUM_UPGRADABLE_VERSION = '4.1.3'; + const MINIMUM_UPGRADABLE_VERSION = '4.2.9'; /** * Minimum php version required to run (equal to or lower than the minimum install version) diff --git a/civicrm/CRM/Upgrade/Incremental/Base.php b/civicrm/CRM/Upgrade/Incremental/Base.php index 5a7770673b..4d53374bd2 100644 --- a/civicrm/CRM/Upgrade/Incremental/Base.php +++ b/civicrm/CRM/Upgrade/Incremental/Base.php @@ -199,13 +199,13 @@ class CRM_Upgrade_Incremental_Base { * Do any relevant smart group updates. * * @param CRM_Queue_TaskContext $ctx - * @param string $version + * @param array $actions * * @return bool */ - public function updateSmartGroups($ctx, $version) { - $groupUpdateObject = new CRM_Upgrade_Incremental_SmartGroups($version); - $groupUpdateObject->updateGroups(); + public function updateSmartGroups($ctx, $actions) { + $groupUpdateObject = new CRM_Upgrade_Incremental_SmartGroups(); + $groupUpdateObject->updateGroups($actions); return TRUE; } diff --git a/civicrm/CRM/Upgrade/Incremental/MessageTemplates.php b/civicrm/CRM/Upgrade/Incremental/MessageTemplates.php index 407cfa7a2f..ba754a3bb7 100644 --- a/civicrm/CRM/Upgrade/Incremental/MessageTemplates.php +++ b/civicrm/CRM/Upgrade/Incremental/MessageTemplates.php @@ -102,7 +102,16 @@ class CRM_Upgrade_Incremental_MessageTemplates { ['name' => 'membership_online_receipt', 'type' => 'text'], ['name' => 'membership_online_receipt', 'type' => 'html'], ] - ] + ], + [ + 'version' => '5.12.alpha1', + 'upgrade_descriptor' => ts('Update payment notification to remove print text, use email greeting'), + 'label' => ts('Payment notification'), + 'templates' => [ + ['name' => 'payment_or_refund_notification', 'type' => 'text'], + ['name' => 'payment_or_refund_notification', 'type' => 'html'], + ] + ], ]; } diff --git a/civicrm/CRM/Upgrade/Incremental/SmartGroups.php b/civicrm/CRM/Upgrade/Incremental/SmartGroups.php index f4181d8319..64c5ab9dc0 100644 --- a/civicrm/CRM/Upgrade/Incremental/SmartGroups.php +++ b/civicrm/CRM/Upgrade/Incremental/SmartGroups.php @@ -35,56 +35,12 @@ class CRM_Upgrade_Incremental_SmartGroups { /** - * Version we are upgrading to. - * - * @var string - */ - protected $upgradeVersion; - - /** - * @return string - */ - public function getUpgradeVersion() { - return $this->upgradeVersion; - } - - /** - * @param string $upgradeVersion - */ - public function setUpgradeVersion($upgradeVersion) { - $this->upgradeVersion = $upgradeVersion; - } - - /** - * CRM_Upgrade_Incremental_MessageTemplates constructor. - * - * @param string $upgradeVersion + * Perform updates specified by upgrade function. */ - public function __construct($upgradeVersion) { - $this->setUpgradeVersion($upgradeVersion); - } - - /** - * Get any conversions required for saved smart groups. - * - * @return array - */ - public function getSmartGroupConversions() { - return [ - [ - 'version' => '5.11.alpha1', - 'upgrade_descriptors' => [ts('Upgrade grant smart groups to datepicker format')], - 'actions' => [ - 'function' => 'datepickerConversion', - 'fields' => [ - 'grant_application_received_date', - 'grant_decision_date', - 'grant_money_transfer_date', - 'grant_due_date' - ] - ] - ] - ]; + public function updateGroups($actions) { + foreach ($actions as $func => $fields) { + $this->{$func}($fields); + } } /** @@ -92,19 +48,46 @@ class CRM_Upgrade_Incremental_SmartGroups { * @param array $fields */ public function datePickerConversion($fields) { - $fieldPossibilities = []; + $fieldPossibilities = $relativeFieldNames = []; foreach ($fields as $field) { $fieldPossibilities[] = $field; $fieldPossibilities[] = $field . '_high'; $fieldPossibilities[] = $field . '_low'; } + $relativeDateMappings = ['activity_date_time' => 'activity']; foreach ($fields as $field) { foreach ($this->getSearchesWithField($field) as $savedSearch) { $formValues = $savedSearch['form_values']; + $isRelative = $hasRelative = FALSE; + $relativeFieldName = $field . '_relative'; + + if (!empty($relativeDateMappings[$field]) && isset($formValues['relative_dates'])) { + if (!empty($formValues['relative_dates'][$relativeDateMappings[$field]])) { + $formValues[] = [$relativeFieldName, '=', $savedSearch['form_values']['relative_dates'][$relativeDateMappings[$field]]]; + unset($formValues['relative_dates'][$relativeDateMappings[$field]]); + $isRelative = TRUE; + } + } foreach ($formValues as $index => $formValue) { + if (!isset($formValue[0])) { + // Any actual criteria will have this key set but skip any weird lines + continue; + } if (in_array($formValue[0], $fieldPossibilities)) { - $formValues[$index][2] = $this->getConvertedDateValue($formValue[2]); + if ($isRelative) { + unset($formValues[$index]); + } + else { + $isHigh = substr($formValue[0], -5, 5) === '_high'; + $formValues[$index][2] = $this->getConvertedDateValue($formValue[2], $isHigh); + } + } + } + if (!$isRelative) { + if (!in_array($relativeFieldName, $relativeFieldNames)) { + $relativeFieldNames[] = $relativeFieldName; + $formValues[] = [$relativeFieldName, '=', 0]; } } if ($formValues !== $savedSearch['form_values']) { @@ -139,47 +122,65 @@ class CRM_Upgrade_Incremental_SmartGroups { } /** - * Update message templates. + * Get converted date value. + * + * @param string $dateValue + * @param bool $isEndOfDay + * Is this the upper value in a search range? If so alter the time to + * get the end of day if none set. + * + * @return string + * $dateValue */ - public function updateGroups() { - $conversions = $this->getSmartGroupConversionsToApply(); - foreach ($conversions as $conversion) { - $function = $conversion['function']; - $this->{$function}($conversion['fields']); + protected function getConvertedDateValue($dateValue, $isEndOfDay) { + if (date('Y-m-d', strtotime($dateValue)) !== $dateValue + && date('Y-m-d H:i:s', strtotime($dateValue)) !== $dateValue + ) { + $dateValue = date('Y-m-d H:i:s', strtotime(CRM_Utils_Date::processDate($dateValue))); + if ($isEndOfDay) { + $dateValue = str_replace('00:00:00', '23:59:59', $dateValue); + } } + return $dateValue; } /** - * Get any required template updates. + * Rename a smartgroup field. * - * @return array + * @param string $oldName + * @param string $newName */ - public function getSmartGroupConversionsToApply() { - $conversions = $this->getSmartGroupConversions(); - $return = []; - foreach ($conversions as $conversion) { - if ($conversion['version'] === $this->getUpgradeVersion()) { - $return[] = $conversion['actions']; + public function renameField($oldName, $newName) { + foreach ($this->getSearchesWithField($oldName) as $savedSearch) { + $formValues = $savedSearch['form_values']; + foreach ($formValues as $index => $formValue) { + if ($formValue[0] === $oldName) { + $formValues[$index][0] = $newName; + } + } + + if ($formValues !== $savedSearch['form_values']) { + civicrm_api3('SavedSearch', 'create', ['id' => $savedSearch['id'], 'form_values' => $formValues]); } } - return $return; } /** - * Get converted date value. + * Rename pairs of fields * - * @param string $dateValue - * - * @return string - * $dateValue + * @param array $pairs + * Array or arrays of pairs - e.g + * [ + * ['old' => 'activity_date', 'new' => 'activity_date_time'], + * ['old' => 'activity_date_low', 'new' => 'activity_date_time_low'], + * ['old' => 'activity_date_high', 'new' => 'activity_date_time_high'], + * ['old' => 'activity_date_relative', 'new' => 'activity_date_time_relative'], + * ] */ - protected function getConvertedDateValue($dateValue) { - if (date('Y-m-d', strtotime($dateValue)) !== $dateValue - && date('Y-m-d H:i:s', strtotime($dateValue)) !== $dateValue - ) { - $dateValue = date('Y-m-d H:i:s', strtotime(CRM_Utils_Date::processDate($dateValue))); + public function renameFields($pairs) { + foreach ($pairs as $pair) { + $this->renameField($pair['old'], $pair['new']); } - return $dateValue; } /** @@ -192,6 +193,7 @@ class CRM_Upgrade_Incremental_SmartGroups { 'form_values' => ['LIKE' => "%{$field}%"], ])['values']; return $savedSearches; + } } diff --git a/civicrm/CRM/Upgrade/Incremental/php/FiveEleven.php b/civicrm/CRM/Upgrade/Incremental/php/FiveEleven.php index 2f34ba0962..8928d08132 100644 --- a/civicrm/CRM/Upgrade/Incremental/php/FiveEleven.php +++ b/civicrm/CRM/Upgrade/Incremental/php/FiveEleven.php @@ -74,7 +74,14 @@ class CRM_Upgrade_Incremental_php_FiveEleven extends CRM_Upgrade_Incremental_Bas */ public function upgrade_5_11_alpha1($rev) { $this->addTask(ts('Upgrade DB to %1: SQL', array(1 => $rev)), 'runSql', $rev); - $this->addTask('Update smart groups where jcalendar fields have been converted to datepicker', 'updateSmartGroups', $rev); + $this->addTask('Update smart groups where jcalendar fields have been converted to datepicker', 'updateSmartGroups', [ + 'datepickerConversion' => [ + 'grant_application_received_date', + 'grant_decision_date', + 'grant_money_transfer_date', + 'grant_due_date' + ] + ]); if (Civi::settings()->get('civimail_multiple_bulk_emails')) { $this->addTask('Update any on hold groups to reflect field change', 'updateOnHold', $rev); } diff --git a/civicrm/CRM/Upgrade/Incremental/php/FiveTwelve.php b/civicrm/CRM/Upgrade/Incremental/php/FiveTwelve.php new file mode 100644 index 0000000000..8202582bb4 --- /dev/null +++ b/civicrm/CRM/Upgrade/Incremental/php/FiveTwelve.php @@ -0,0 +1,93 @@ +<?php +/* + +--------------------------------------------------------------------+ + | CiviCRM version 5 | + +--------------------------------------------------------------------+ + | Copyright CiviCRM LLC (c) 2004-2019 | + +--------------------------------------------------------------------+ + | This file is a part of CiviCRM. | + | | + | CiviCRM is free software; you can copy, modify, and distribute it | + | under the terms of the GNU Affero General Public License | + | Version 3, 19 November 2007. | + | | + | CiviCRM is distributed in the hope that it will be useful, but | + | WITHOUT ANY WARRANTY; without even the implied warranty of | + | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | + | See the GNU Affero General Public License for more details. | + | | + | You should have received a copy of the GNU Affero General Public | + | License along with this program; if not, contact CiviCRM LLC | + | at info[AT]civicrm[DOT]org. If you have questions about the | + | GNU Affero General Public License or the licensing of CiviCRM, | + | see the CiviCRM license FAQ at http://civicrm.org/licensing | + +--------------------------------------------------------------------+ + */ + +/** + * Upgrade logic for FiveTwelve */ +class CRM_Upgrade_Incremental_php_FiveTwelve extends CRM_Upgrade_Incremental_Base { + + /** + * Compute any messages which should be displayed beforeupgrade. + * + * Note: This function is called iteratively for each upcoming + * revision to the database. + * + * @param string $preUpgradeMessage + * @param string $rev + * a version number, e.g. '4.4.alpha1', '4.4.beta3', '4.4.0'. + * @param null $currentVer + */ + public function setPreUpgradeMessage(&$preUpgradeMessage, $rev, $currentVer = NULL) { + // Example: Generate a pre-upgrade message. + // if ($rev == '5.12.34') { + // $preUpgradeMessage .= '<p>' . ts('A new permission, "%1", has been added. This permission is now used to control access to the Manage Tags screen.', array(1 => ts('manage tags'))) . '</p>'; + // } + } + + /** + * Compute any messages which should be displayed after upgrade. + * + * @param string $postUpgradeMessage + * alterable. + * @param string $rev + * an intermediate version; note that setPostUpgradeMessage is called repeatedly with different $revs. + */ + public function setPostUpgradeMessage(&$postUpgradeMessage, $rev) { + // Example: Generate a post-upgrade message. + // if ($rev == '5.12.34') { + // $postUpgradeMessage .= '<br /><br />' . ts("By default, CiviCRM now disables the ability to import directly from SQL. To use this feature, you must explicitly grant permission 'import SQL datasource'."); + // } + } + + /* + * Important! All upgrade functions MUST add a 'runSql' task. + * Uncomment and use the following template for a new upgrade version + * (change the x in the function name): + */ + + /** + * Upgrade function. + * + * @param string $rev + */ + public function upgrade_5_12_alpha1($rev) { + $this->addTask(ts('Upgrade DB to %1: SQL', [1 => $rev]), 'runSql', $rev); + $this->addTask('Update smart groups to rename filters on activity_date to activity_date_time', 'updateSmartGroups', [ + 'renameFields' => [ + ['old' => 'activity_date', 'new' => 'activity_date_time'], + ['old' => 'activity_date_low', 'new' => 'activity_date_time_low'], + ['old' => 'activity_date_high', 'new' => 'activity_date_time_high'], + ['old' => 'activity_date_relative', 'new' => 'activity_date_time_relative'], + ], + ]); + $this->addTask('Update smart groups where jcalendar fields have been converted to datepicker', 'updateSmartGroups', [ + 'datepickerConversion' => [ + 'age_asof_date', + 'activity_date_time' + ] + ]); + } + +} diff --git a/civicrm/CRM/Upgrade/Incremental/php/FourTwo.php b/civicrm/CRM/Upgrade/Incremental/php/FourTwo.php deleted file mode 100644 index d8b86411b4..0000000000 --- a/civicrm/CRM/Upgrade/Incremental/php/FourTwo.php +++ /dev/null @@ -1,948 +0,0 @@ -<?php -/* - +--------------------------------------------------------------------+ - | CiviCRM version 5 | - +--------------------------------------------------------------------+ - | Copyright CiviCRM LLC (c) 2004-2019 | - +--------------------------------------------------------------------+ - | This file is a part of CiviCRM. | - | | - | CiviCRM is free software; you can copy, modify, and distribute it | - | under the terms of the GNU Affero General Public License | - | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. | - | | - | CiviCRM is distributed in the hope that it will be useful, but | - | WITHOUT ANY WARRANTY; without even the implied warranty of | - | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | - | See the GNU Affero General Public License for more details. | - | | - | You should have received a copy of the GNU Affero General Public | - | License and the CiviCRM Licensing Exception along | - | with this program; if not, contact CiviCRM LLC | - | at info[AT]civicrm[DOT]org. If you have questions about the | - | GNU Affero General Public License or the licensing of CiviCRM, | - | see the CiviCRM license FAQ at http://civicrm.org/licensing | - +--------------------------------------------------------------------+ - */ - -/** - * Upgrade logic for 4.2 - */ -class CRM_Upgrade_Incremental_php_FourTwo extends CRM_Upgrade_Incremental_Base { - const SETTINGS_SNIPPET_PATTERN = '/CRM_Core_ClassLoader::singleton\(\)-\>register/'; - const SETTINGS_SNIPPET = "\nrequire_once 'CRM/Core/ClassLoader.php';\nCRM_Core_ClassLoader::singleton()->register();\n"; - - /** - * Compute any messages which should be displayed beforeupgrade. - * - * Note: This function is called iteratively for each upcoming - * revision to the database. - * - * @param string $preUpgradeMessage - * @param string $rev - * a version number, e.g. '4.2.alpha1', '4.2.beta3', '4.2.0'. - * @param null $currentVer - * - * @return bool - */ - public function setPreUpgradeMessage(&$preUpgradeMessage, $rev, $currentVer = NULL) { - if ($rev == '4.2.alpha1') { - $tables = array('civicrm_contribution_page', 'civicrm_event', 'civicrm_group', 'civicrm_contact'); - if (!CRM_Core_DAO::schemaRequiresRebuilding($tables)) { - $errors = "The upgrade has identified some schema integrity issues in the database. It seems some of your constraints are missing. You will have to rebuild your schema before re-trying the upgrade. Please refer to " . CRM_Utils_System::docURL2("Ensuring Schema Integrity on Upgrades", FALSE, "Ensuring Schema Integrity on Upgrades", NULL, NULL, "wiki"); - CRM_Core_Error::fatal($errors); - return FALSE; - } - - // CRM-10613, CRM-11120 - $query = " -SELECT mp.contribution_id, mp.membership_id, mem.membership_type_id, mem.start_date, mem.end_date, mem.status_id, mem.contact_id -FROM civicrm_membership_payment mp -INNER JOIN ( SELECT cmp.contribution_id - FROM civicrm_membership_payment cmp - LEFT JOIN civicrm_line_item cli ON cmp.contribution_id=cli.entity_id and cli.entity_table = 'civicrm_contribution' - WHERE cli.entity_id IS NULL - GROUP BY cmp.contribution_id - HAVING COUNT(cmp.membership_id) > 1) submp ON submp.contribution_id = mp.contribution_id -INNER JOIN civicrm_membership mem ON mem.id = mp.membership_id -ORDER BY mp.contribution_id, mp.membership_id"; - $invalidData = CRM_Core_DAO::executeQuery($query); - if ($invalidData->N) { - $invalidDataMessage = "<br /><strong>" . 'The upgrade is being aborted due to data integrity issues in your database. There are multiple membership records linked to the same contribution record. This is unexpected, and some of the membership records may be duplicates. The problem record sets are listed below. Refer to <a href="http://wiki.civicrm.org/confluence/display/CRMDOC42/Repair+database+script+for+4.2+upgrades">this wiki page for instructions on repairing your database</a> so that you can run the upgrade successfully.' . "</strong>"; - $membershipType = CRM_Member_PseudoConstant::membershipType(); - $membershipStatus = CRM_Member_PseudoConstant::membershipStatus(); - $invalidDataMessage .= "<table border=1><tr><th>Contact-ID</th><th>Contribution-ID</th><th>Membership-ID</th><th>Membership Type</th><th>Start Date</th><th>End Date</th><th>Membership Status</th></tr>"; - while ($invalidData->fetch()) { - $invalidDataMessage .= "<tr>"; - $invalidDataMessage .= "<td>{$invalidData->contact_id}</td>"; - $invalidDataMessage .= "<td>{$invalidData->contribution_id}</td>"; - $invalidDataMessage .= "<td>{$invalidData->membership_id}</td>"; - $invalidDataMessage .= "<td>" . CRM_Utils_Array::value($invalidData->membership_type_id, $membershipType) . "</td>"; - $invalidDataMessage .= "<td>{$invalidData->start_date}</td>"; - $invalidDataMessage .= "<td>{$invalidData->end_date}</td>"; - $invalidDataMessage .= "<td>" . CRM_Utils_Array::value($invalidData->status_id, $membershipStatus) . "</td>"; - $invalidDataMessage .= "</tr>"; - } - $clickHere = CRM_Utils_System::url('civicrm/upgrade/cleanup425', 'reset=1'); - $invalidDataMessage .= "</table><p>If you have reviewed the cleanup script documentation on the wiki and you are ready to run the cleanup now - <a href='$clickHere'>click here</a>.</p>"; - CRM_Core_Error::fatal($invalidDataMessage); - return FALSE; - } - } - - if ($rev == '4.2.beta2') { - // note: error conditions are also checked in upgrade_4_2_beta2() - if (!defined('CIVICRM_SETTINGS_PATH')) { - $preUpgradeMessage .= '<br />' . ts('Could not determine path to civicrm.settings.php. Please manually locate it and add these lines at the bottom: <pre>%1</pre>', array( - 1 => self::SETTINGS_SNIPPET, - )); - } - elseif (preg_match(self::SETTINGS_SNIPPET_PATTERN, file_get_contents(CIVICRM_SETTINGS_PATH))) { - // OK, nothing to do - } - elseif (!is_writable(CIVICRM_SETTINGS_PATH)) { - $preUpgradeMessage .= '<br />' . ts('The settings file (%1) must be updated. Please make it writable or manually add these lines:<pre>%2</pre>', array( - 1 => CIVICRM_SETTINGS_PATH, - 2 => self::SETTINGS_SNIPPET, - )); - } - } - if ($rev == '4.2.2' && version_compare($currentVer, '3.3.alpha1') >= 0) { - $query = " SELECT cli.id -FROM `civicrm_line_item` cli -INNER JOIN civicrm_membership_payment cmp ON cmp.contribution_id = cli.entity_id AND cli.entity_table = 'civicrm_contribution' -INNER JOIN civicrm_price_field_value cpfv ON cpfv.id = cli.price_field_value_id -INNER JOIN civicrm_price_field cpf ON cpf.id = cpfv.price_field_id and cpf.id != cli.price_field_id -INNER JOIN civicrm_price_set cps ON cps.id = cpf.price_set_id AND cps.name <>'default_membership_type_amount' "; - $dao = CRM_Core_DAO::executeQuery($query); - if ($dao->N) { - $preUpgradeMessage .= "<br /><strong>We have identified extraneous data in your database that a previous upgrade likely introduced. We STRONGLY recommend making a backup of your site before continuing. We also STRONGLY suggest fixing this issue with unneeded records BEFORE you upgrade. You can find more information about this issue and the way to fix it by visiting <a href='http://forum.civicrm.org/index.php/topic,26181.0.html'>http://forum.civicrm.org/index.php/topic,26181.0.html</a>.</strong>"; - } - } - - if (version_compare($rev, '4.2.9') >= 0) { - //CRM-11980 - $sql = "SELECT id FROM civicrm_option_group WHERE name LIKE 'civicrm_price_field.amount.%' LIMIT 1"; - $dao = CRM_Core_DAO::executeQuery($sql); - if ($dao->fetch()) { - $errors = "We found unexpected data values from an older version of CiviCRM in your database. The upgrade can not be run until this condition is corrected.<br /><br />Details: One or more rows are present in the civicrm_option_group with name like 'civicrm_price_field.amount.%'. <a href='http://forum.civicrm.org/index.php/topic,27744.msg118748.html#msg118748'>Check here for information on diagnosing and correcting this problem.</a>"; - CRM_Core_Error::fatal($errors); - return FALSE; - } - } - } - - /** - * Compute any messages which should be displayed after upgrade. - * - * @param string $postUpgradeMessage - * alterable. - * @param string $rev - * an intermediate version; note that setPostUpgradeMessage is called repeatedly with different $revs. - */ - public function setPostUpgradeMessage(&$postUpgradeMessage, $rev) { - if ($rev == '4.2.beta5') { - $config = CRM_Core_Config::singleton(); - if (!empty($config->extensionsDir)) { - $postUpgradeMessage .= '<br />' . ts('Please <a href="%1" target="_blank">configure the Extension Resource URL</a>.', array( - 1 => CRM_Utils_System::url('civicrm/admin/setting/url', 'reset=1'), - )); - } - } - if ($rev == '4.2.7') { - $postUpgradeMessage .= '<br />' . ts('If you have configured a report instance to allow anonymous access, you will need to reset the permission to Everyone for that instance (under the Report Settings pane).'); - } - } - - /** - * @param $rev - */ - public function upgrade_4_2_alpha1($rev) { - //checking whether the foreign key exists before dropping it - //drop foreign key queries of CRM-9850 - $params = array(); - $tables = array( - 'civicrm_contribution_page' => 'FK_civicrm_contribution_page_payment_processor_id', - 'civicrm_event' => 'FK_civicrm_event_payment_processor_id', - 'civicrm_group' => 'FK_civicrm_group_saved_search_id', - ); - foreach ($tables as $tableName => $fKey) { - $foreignKeyExists = CRM_Core_DAO::checkConstraintExists($tableName, $fKey); - if ($foreignKeyExists) { - CRM_Core_DAO::executeQuery("ALTER TABLE {$tableName} DROP FOREIGN KEY {$fKey}", $params, TRUE, NULL, FALSE, FALSE); - CRM_Core_DAO::executeQuery("ALTER TABLE {$tableName} DROP INDEX {$fKey}", $params, TRUE, NULL, FALSE, FALSE); - } - } - // Drop index UI_title for civicrm_price_set - $domain = new CRM_Core_DAO_Domain(); - $domain->find(TRUE); - if ($domain->locales) { - $locales = explode(CRM_Core_DAO::VALUE_SEPARATOR, $domain->locales); - foreach ($locales as $locale) { - $query = "SHOW KEYS FROM `civicrm_price_set` WHERE key_name = 'UI_title_{$locale}'"; - $dao = CRM_Core_DAO::executeQuery($query, $params, TRUE, NULL, FALSE, FALSE); - if ($dao->N) { - CRM_Core_DAO::executeQuery("ALTER TABLE `civicrm_price_set` DROP INDEX `UI_title_{$locale}`", $params, TRUE, NULL, FALSE, FALSE); - } - } - } - else { - $query = "SHOW KEYS FROM `civicrm_price_set` WHERE key_name = 'UI_title'"; - $dao = CRM_Core_DAO::executeQuery($query); - if ($dao->N) { - CRM_Core_DAO::executeQuery("ALTER TABLE `civicrm_price_set` DROP INDEX `UI_title`"); - } - } - - // Some steps take a long time, so we break them up into separate - // tasks and enqueue them separately. - $this->addTask(ts('Upgrade DB to %1: SQL', array(1 => '4.2.alpha1')), 'runSql', $rev); - $this->addTask('Upgrade DB to 4.2.alpha1: Price Sets', 'task_4_2_alpha1_createPriceSets', $rev); - self::convertContribution(); - $this->addTask('Upgrade DB to 4.2.alpha1: Event Profile', 'task_4_2_alpha1_eventProfile'); - } - - /** - * @param $rev - */ - public function upgrade_4_2_beta2($rev) { - // note: error conditions are also checked in setPreUpgradeMessage() - if (defined('CIVICRM_SETTINGS_PATH')) { - if (!preg_match(self::SETTINGS_SNIPPET_PATTERN, file_get_contents(CIVICRM_SETTINGS_PATH))) { - if (is_writable(CIVICRM_SETTINGS_PATH)) { - file_put_contents(CIVICRM_SETTINGS_PATH, self::SETTINGS_SNIPPET, FILE_APPEND); - } - } - } - } - - /** - * @param $rev - */ - public function upgrade_4_2_beta3($rev) { - $this->addTask(ts('Upgrade DB to %1: SQL', array(1 => '4.2.beta3')), 'runSql', $rev); - $minParticipantId = CRM_Core_DAO::singleValueQuery('SELECT coalesce(min(id),0) FROM civicrm_participant'); - $maxParticipantId = CRM_Core_DAO::singleValueQuery('SELECT coalesce(max(id),0) FROM civicrm_participant'); - - for ($startId = $minParticipantId; $startId <= $maxParticipantId; $startId += self::BATCH_SIZE) { - $endId = $startId + self::BATCH_SIZE - 1; - $title = "Upgrade DB to 4.2.alpha1: Participant ($startId => $endId)"; - $this->addTask($title, 'task_4_2_alpha1_convertParticipants', $startId, $endId); - } - } - - /** - * @param $rev - */ - public function upgrade_4_2_beta5($rev) { - // CRM-10629 Create a setting for extension URLs - // For some reason, this isn't working when placed in the .sql file - CRM_Core_DAO::executeQuery(" - INSERT INTO civicrm_setting(group_name,name,value,domain_id,is_domain) - VALUES ('URL Preferences', 'extensionsURL',NULL,1,1); - "); - } - - /** - * @param $rev - */ - public function upgrade_4_2_0($rev) { - $this->addTask(ts('Upgrade DB to %1: SQL', array(1 => '4.2.0')), 'runSql', $rev); - } - - /** - * @param $rev - */ - public function upgrade_4_2_2($rev) { - $this->addTask(ts('Upgrade DB to %1: SQL', array(1 => '4.2.2')), 'runSql', $rev); - //create line items for memberships and participants for api/import - self::convertContribution(); - - // CRM-10937 Fix the title on civicrm_dedupe_rule_group - $upgrade = new CRM_Upgrade_Form(); - if ($upgrade->multilingual) { - // Check if the 'title' field exists - $query = "SELECT column_name - FROM information_schema.COLUMNS - WHERE table_name = 'civicrm_dedupe_rule_group' - AND table_schema = DATABASE() - AND column_name = 'title'"; - - $dao = CRM_Core_DAO::executeQuery($query); - - if (!$dao->N) { - $domain = new CRM_Core_DAO_Domain(); - $domain->find(TRUE); - - if ($domain->locales) { - $locales = explode(CRM_Core_DAO::VALUE_SEPARATOR, $domain->locales); - $locale = array_shift($locales); - - // Use the first language (they should all have the same value) - CRM_Core_DAO::executeQuery("ALTER TABLE `civicrm_dedupe_rule_group` CHANGE `title_{$locale}` `title` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT 'Label of the rule group'", $params, TRUE, NULL, FALSE, FALSE); - - // Drop remaining the column for the remaining languages - foreach ($locales as $locale) { - CRM_Core_DAO::executeQuery("ALTER TABLE `civicrm_dedupe_rule_group` DROP `title_{$locale}`", $params, TRUE, NULL, FALSE, FALSE); - } - } - } - } - } - - /** - * @param $rev - */ - public function upgrade_4_2_3($rev) { - $this->addTask(ts('Upgrade DB to %1: SQL', array(1 => '4.2.3')), 'runSql', $rev); - // CRM-10953 Remove duplicate activity type for 'Reminder Sent' which is mistakenly inserted by 4.2.alpha1 upgrade script - $queryMin = " -SELECT coalesce(min(value),0) from civicrm_option_value ov -WHERE ov.option_group_id = - (SELECT id from civicrm_option_group og WHERE og.name = 'activity_type') AND -ov.name = 'Reminder Sent'"; - - $minReminderSent = CRM_Core_DAO::singleValueQuery($queryMin); - - $queryMax = " -SELECT coalesce(max(value),0) from civicrm_option_value ov -WHERE ov.option_group_id = - (SELECT id from civicrm_option_group og WHERE og.name = 'activity_type') AND -ov.name = 'Reminder Sent'"; - - $maxReminderSent = CRM_Core_DAO::singleValueQuery($queryMax); - - // If we have two different values, replace new value with original in any activities - if ($maxReminderSent > $minReminderSent) { - $query = " -UPDATE civicrm_activity -SET activity_type_id = {$minReminderSent} -WHERE activity_type_id = {$maxReminderSent}"; - - CRM_Core_DAO::executeQuery($query); - - // Then delete the newer (duplicate) option_value row - $query = " -DELETE from civicrm_option_value - WHERE option_group_id = - (SELECT id from civicrm_option_group og WHERE og.name = 'activity_type') AND - value = '{$maxReminderSent}'"; - - CRM_Core_DAO::executeQuery($query); - } - } - - /** - * @param $rev - */ - public function upgrade_4_2_5($rev) { - $this->addTask(ts('Upgrade DB to %1: SQL', array(1 => '4.2.5')), 'runSql', $rev); - //CRM-11077 - $sql = " SELECT cpse.entity_id, cpse.price_set_id -FROM `civicrm_price_set_entity` cpse -LEFT JOIN civicrm_price_set cps ON cps.id = cpse.price_set_id -LEFT JOIN civicrm_price_set_entity cpse1 ON cpse1.price_set_id = cpse.price_set_id -WHERE cpse.entity_table = 'civicrm_event' AND cps.is_quick_config = 1 -GROUP BY cpse.id -HAVING COUNT(cpse.price_set_id) > 1 AND MIN(cpse1.id) <> cpse.id "; - - $dao = CRM_Core_DAO::executeQuery($sql); - while ($dao->fetch()) { - if ($dao->price_set_id) { - $copyPriceSet = &CRM_Upgrade_Snapshot_V4p2_Price_BAO_Set::copy($dao->price_set_id); - CRM_Upgrade_Snapshot_V4p2_Price_BAO_Set::addTo('civicrm_event', $dao->entity_id, $copyPriceSet->id); - } - } - } - - public function convertContribution() { - $minContributionId = CRM_Core_DAO::singleValueQuery('SELECT coalesce(min(id),0) FROM civicrm_contribution'); - $maxContributionId = CRM_Core_DAO::singleValueQuery('SELECT coalesce(max(id),0) FROM civicrm_contribution'); - for ($startId = $minContributionId; $startId <= $maxContributionId; $startId += self::BATCH_SIZE) { - $endId = $startId + self::BATCH_SIZE - 1; - $title = "Upgrade DB to 4.2.alpha1: Contributions ($startId => $endId)"; - $this->addTask($title, 'task_4_2_alpha1_convertContributions', $startId, $endId); - } - $minParticipantId = CRM_Core_DAO::singleValueQuery('SELECT coalesce(min(id),0) FROM civicrm_participant'); - $maxParticipantId = CRM_Core_DAO::singleValueQuery('SELECT coalesce(max(id),0) FROM civicrm_participant'); - - for ($startId = $minParticipantId; $startId <= $maxParticipantId; $startId += self::BATCH_SIZE) { - $endId = $startId + self::BATCH_SIZE - 1; - $title = "Upgrade DB to 4.2.alpha1: Participant ($startId => $endId)"; - $this->addTask($title, 'task_4_2_alpha1_convertParticipants', $startId, $endId); - } - } - - /** - * (Queue Task Callback) - * - * Upgrade code to create priceset for contribution pages and events - * - * @param \CRM_Queue_TaskContext $ctx - * @param string $rev - * - * @return bool - */ - public static function task_4_2_alpha1_createPriceSets(CRM_Queue_TaskContext $ctx, $rev) { - $upgrade = new CRM_Upgrade_Form(); - $daoName = array( - 'civicrm_contribution_page' => array( - 'CRM_Contribute_BAO_ContributionPage', - CRM_Core_Component::getComponentID('CiviContribute'), - ), - 'civicrm_event' => array( - 'CRM_Event_BAO_Event', - CRM_Core_Component::getComponentID('CiviEvent'), - ), - ); - - // get all option group used for event and contribution page - $query = " -SELECT id, name -FROM civicrm_option_group -WHERE name LIKE '%.amount.%' "; - $dao = CRM_Core_DAO::executeQuery($query); - while ($dao->fetch()) { - $addTo = explode('.', $dao->name); - if (!empty($addTo[2])) { - $options = array('optionGroup' => $dao->name); - self::createPriceSet($daoName, $addTo, $options); - } - CRM_Core_OptionGroup::deleteAssoc($dao->name); - } - - //create pricesets for contribution with only other amount - $query = " -SELECT ccp.id as contribution_page_id, ccp.is_allow_other_amount, cmb.id as membership_block_id -FROM civicrm_contribution_page ccp -LEFT JOIN civicrm_membership_block cmb ON cmb.entity_id = ccp.id AND cmb.entity_table = 'civicrm_contribution_page' -LEFT JOIN civicrm_price_set_entity cpse ON cpse.entity_id = ccp.id and cpse.entity_table = 'civicrm_contribution_page' -WHERE cpse.price_set_id IS NULL"; - $dao = CRM_Core_DAO::executeQuery($query); - $addTo = array('civicrm_contribution_page'); - while ($dao->fetch()) { - $addTo[2] = $dao->contribution_page_id; - $options = array( - 'otherAmount' => $dao->is_allow_other_amount, - 'membership' => $dao->membership_block_id, - ); - self::createPriceSet($daoName, $addTo, $options); - } - - return TRUE; - } - - /** - * Create price sets. - * - * @param string $daoName - * @param string $addTo - * @param array $options - */ - public static function createPriceSet($daoName, $addTo, $options = array()) { - $query = "SELECT title FROM {$addTo[0]} where id =%1"; - $setParams['title'] = CRM_Core_DAO::singleValueQuery($query, - array(1 => array($addTo[2], 'Integer')) - ); - $pageTitle = strtolower(CRM_Utils_String::munge($setParams['title'], '_', 245)); - - // an event or contrib page has been deleted but left the option group behind - (this may be fixed in later versions?) - // we should probably delete the option group - but at least early exit here as the code following it does not fatal - // CRM-10298 - if (empty($pageTitle)) { - return; - } - - $optionValue = array(); - if (!empty($options['optionGroup'])) { - CRM_Core_OptionGroup::getAssoc($options['optionGroup'], $optionValue); - if (empty($optionValue)) { - return; - } - } - elseif (empty($options['otherAmount']) && empty($options['membership'])) { - //CRM-12273 - //if options group, otherAmount, membersip is empty then return, contribution should be default price set - return; - } - - if (!CRM_Core_DAO::getFieldValue('CRM_Upgrade_Snapshot_V4p2_Price_BAO_Set', $pageTitle, 'id', 'name', TRUE)) { - $setParams['name'] = $pageTitle; - } - else { - $timeSec = explode(".", microtime(TRUE)); - $setParams['name'] = $pageTitle . '_' . date('is', $timeSec[0]) . $timeSec[1]; - } - $setParams['extends'] = $daoName[$addTo[0]][1]; - $setParams['is_quick_config'] = 1; - $priceSet = CRM_Upgrade_Snapshot_V4p2_Price_BAO_Set::create($setParams); - CRM_Upgrade_Snapshot_V4p2_Price_BAO_Set::addTo($addTo[0], $addTo[2], $priceSet->id, 1); - - $fieldParams['price_set_id'] = $priceSet->id; - if (!empty($options['optionGroup'])) { - $fieldParams['html_type'] = 'Radio'; - $fieldParams['is_required'] = 1; - if ($addTo[0] == 'civicrm_event') { - $query = "SELECT fee_label FROM civicrm_event where id =%1"; - $fieldParams['name'] = $fieldParams['label'] = CRM_Core_DAO::singleValueQuery($query, - array(1 => array($addTo[2], 'Integer')) - ); - $defaultAmountColumn = 'default_fee_id'; - } - else { - $options['membership'] = 1; - $fieldParams['name'] = strtolower(CRM_Utils_String::munge("Contribution Amount", '_', 245)); - $fieldParams['label'] = "Contribution Amount"; - $defaultAmountColumn = 'default_amount_id'; - $options['otherAmount'] = CRM_Core_DAO::getFieldValue('CRM_Contribute_DAO_ContributionPage', $addTo[2], 'is_allow_other_amount'); - if (!empty($options['otherAmount'])) { - $fieldParams['is_required'] = 0; - } - } - $fieldParams['option_label'] = $optionValue['label']; - $fieldParams['option_amount'] = $optionValue['value']; - $fieldParams['option_weight'] = $optionValue['weight']; - $fieldParams['is_quick_config'] = $setParams['is_quick_config']; - if ($defaultAmount = CRM_Core_DAO::getFieldValue($daoName[$addTo[0]][0], $addTo[2], $defaultAmountColumn)) { - $fieldParams['default_option'] = array_search($defaultAmount, $optionValue['amount_id']); - } - $priceField = CRM_Upgrade_Snapshot_V4p2_Price_BAO_Field::create($fieldParams); - - } - if (!empty($options['membership'])) { - $dao = new CRM_Member_DAO_MembershipBlock(); - $dao->entity_table = 'civicrm_contribution_page'; - $dao->entity_id = $addTo[2]; - - if ($dao->find(TRUE)) { - if ($dao->membership_types) { - $fieldParams = array( - 'name' => strtolower(CRM_Utils_String::munge("Membership Amount", '_', 245)), - 'label' => "Membership Amount", - 'is_required' => $dao->is_required, - 'is_display_amounts' => $dao->display_min_fee, - 'is_active' => $dao->is_active, - 'price_set_id' => $priceSet->id, - 'html_type' => 'Radio', - 'weight' => 1, - ); - $membershipTypes = unserialize($dao->membership_types); - $rowcount = 0; - foreach ($membershipTypes as $membershipType => $autoRenew) { - $membershipTypeDetail = CRM_Member_BAO_MembershipType::getMembershipTypeDetails($membershipType); - $rowcount++; - $fieldParams['option_label'][$rowcount] = $membershipTypeDetail['name']; - $fieldParams['option_amount'][$rowcount] = $membershipTypeDetail['minimum_fee']; - $fieldParams['option_weight'][$rowcount] = $rowcount; - $fieldParams['membership_type_id'][$rowcount] = $membershipType; - if ($membershipType == $dao->membership_type_default) { - $fieldParams['default_option'] = $rowcount; - } - } - $priceField = CRM_Upgrade_Snapshot_V4p2_Price_BAO_Field::create($fieldParams); - - $setParams = array( - 'id' => $priceSet->id, - 'extends' => CRM_Core_Component::getComponentID('CiviMember'), - 'contribution_type_id' => CRM_Core_DAO::getFieldValue($daoName[$addTo[0]][0], $addTo[2], 'contribution_type_id'), - ); - CRM_Upgrade_Snapshot_V4p2_Price_BAO_Set::create($setParams); - } - } - } - if (!empty($options['otherAmount'])) { - - $fieldParams = array( - 'name' => strtolower(CRM_Utils_String::munge("Other Amount", '_', 245)), - 'label' => "Other Amount", - 'is_required' => 0, - 'is_display_amounts' => 0, - 'is_active' => 1, - 'price_set_id' => $priceSet->id, - 'html_type' => 'Text', - 'weight' => 3, - ); - $fieldParams['option_label'][1] = "Other Amount"; - $fieldParams['option_amount'][1] = 1; - $fieldParams['option_weight'][1] = 1; - $priceField = CRM_Upgrade_Snapshot_V4p2_Price_BAO_Field::create($fieldParams); - } - } - - /** - * (Queue Task Callback) - * - * Find any contribution records and create corresponding line-item - * records. - * - * @param CRM_Queue_TaskContext $ctx - * @param int $startId - * the first/lowest contribution ID to convert. - * @param int $endId - * the last/highest contribution ID to convert. - * - * @return bool - */ - public static function task_4_2_alpha1_convertContributions(CRM_Queue_TaskContext $ctx, $startId, $endId) { - $upgrade = new CRM_Upgrade_Form(); - $query = " - INSERT INTO civicrm_line_item(`entity_table` ,`entity_id` ,`price_field_id` ,`label` , `qty` ,`unit_price` ,`line_total` ,`participant_count` ,`price_field_value_id`) - SELECT 'civicrm_contribution',cc.id, cpf.id as price_field_id, cpfv.label, 1, cc.total_amount, cc.total_amount line_total, 0, cpfv.id as price_field_value - FROM civicrm_membership_payment cmp - LEFT JOIN `civicrm_contribution` cc ON cc.id = cmp.contribution_id - LEFT JOIN civicrm_line_item cli ON cc.id=cli.entity_id and cli.entity_table = 'civicrm_contribution' - LEFT JOIN civicrm_membership cm ON cm.id=cmp.membership_id - LEFT JOIN civicrm_membership_type cmt ON cmt.id = cm.membership_type_id - LEFT JOIN civicrm_price_field cpf ON BINARY cpf.name = cmt.member_of_contact_id - LEFT JOIN civicrm_price_field_value cpfv ON cpfv.membership_type_id = cm.membership_type_id AND cpf.id = cpfv.price_field_id - WHERE (cc.id BETWEEN %1 AND %2) AND cli.entity_id IS NULL ; - "; - $sqlParams = array( - 1 => array($startId, 'Integer'), - 2 => array($endId, 'Integer'), - ); - CRM_Core_DAO::executeQuery($query, $sqlParams); - - // create lineitems for contribution done for membership - $sql = " -SELECT cc.id, cmp.membership_id, cpse.price_set_id, cc.total_amount -FROM civicrm_contribution cc -LEFT JOIN civicrm_line_item cli ON cc.id=cli.entity_id AND cli.entity_table = 'civicrm_contribution' -LEFT JOIN civicrm_membership_payment cmp ON cc.id = cmp.contribution_id -LEFT JOIN civicrm_participant_payment cpp ON cc.id = cpp.contribution_id -LEFT JOIN civicrm_price_set_entity cpse on cpse.entity_table = 'civicrm_contribution_page' AND cpse.entity_id = cc.contribution_page_id -WHERE (cc.id BETWEEN %1 AND %2) -AND cli.entity_id IS NULL AND cc.contribution_page_id IS NOT NULL AND cpp.contribution_id IS NULL -GROUP BY cc.id, cmp.membership_id -"; - $result = CRM_Core_DAO::executeQuery($sql, $sqlParams); - - while ($result->fetch()) { - $sql = " -SELECT cpf.id, cpfv.id as price_field_value_id, cpfv.label, cpfv.amount, cpfv.count -FROM civicrm_price_field cpf -LEFT JOIN civicrm_price_field_value cpfv ON cpf.id = cpfv.price_field_id -WHERE cpf.price_set_id = %1 -"; - $lineParams = array( - 'entity_table' => 'civicrm_contribution', - 'entity_id' => $result->id, - ); - if ($result->membership_id) { - $sql .= " AND cpf.name = %2 AND cpfv.membership_type_id = %3 "; - $params = array( - '1' => array($result->price_set_id, 'Integer'), - '2' => array('membership_amount', 'String'), - '3' => array( - CRM_Core_DAO::getFieldValue('CRM_Member_DAO_Membership', $result->membership_id, 'membership_type_id'), - 'Integer', - ), - ); - $res = CRM_Core_DAO::executeQuery($sql, $params); - if ($res->fetch()) { - $lineParams += array( - 'price_field_id' => $res->id, - 'label' => $res->label, - 'qty' => 1, - 'unit_price' => $res->amount, - 'line_total' => $res->amount, - 'participant_count' => $res->count ? $res->count : 0, - 'price_field_value_id' => $res->price_field_value_id, - ); - } - else { - $lineParams['price_field_id'] = CRM_Core_DAO::getFieldValue('CRM_Upgrade_Snapshot_V4p2_Price_DAO_Field', $result->price_set_id, 'id', 'price_set_id'); - $lineParams['label'] = 'Membership Amount'; - $lineParams['qty'] = 1; - $lineParams['unit_price'] = $lineParams['line_total'] = $result->total_amount; - $lineParams['participant_count'] = 0; - } - } - else { - $sql .= "AND cpfv.amount = %2"; - - //CRM-12273 - //check if price_set_id is exist, if not use the default contribution amount - if (isset($result->price_set_id)) { - $priceSetId = $result->price_set_id; - } - else { - $defaultPriceSets = CRM_Price_BAO_PriceSet::getDefaultPriceSet(); - foreach ($defaultPriceSets as $key => $pSet) { - if ($pSet['name'] == 'contribution_amount') { - $priceSetId = $pSet['setID']; - } - } - } - - $params = array( - '1' => array($priceSetId, 'Integer'), - '2' => array($result->total_amount, 'String'), - ); - $res = CRM_Core_DAO::executeQuery($sql, $params); - if ($res->fetch()) { - $lineParams += array( - 'price_field_id' => $res->id, - 'label' => $res->label, - 'qty' => 1, - 'unit_price' => $res->amount, - 'line_total' => $res->amount, - 'participant_count' => $res->count ? $res->count : 0, - 'price_field_value_id' => $res->price_field_value_id, - ); - } - else { - $params = array( - 'price_set_id' => $priceSetId, - 'name' => 'other_amount', - ); - $defaults = array(); - CRM_Upgrade_Snapshot_V4p2_Price_BAO_Field::retrieve($params, $defaults); - if (!empty($defaults)) { - $lineParams['price_field_id'] = $defaults['id']; - $lineParams['label'] = $defaults['label']; - $lineParams['price_field_value_id'] - = CRM_Core_DAO::getFieldValue('CRM_Upgrade_Snapshot_V4p2_Price_DAO_FieldValue', $defaults['id'], 'id', 'price_field_id'); - } - else { - $lineParams['price_field_id'] - = CRM_Core_DAO::getFieldValue('CRM_Upgrade_Snapshot_V4p2_Price_DAO_Field', $priceSetId, 'id', 'price_set_id'); - $lineParams['label'] = 'Contribution Amount'; - } - $lineParams['qty'] = 1; - $lineParams['participant_count'] = 0; - $lineParams['unit_price'] = $lineParams['line_total'] = $result->total_amount; - } - } - CRM_Upgrade_Snapshot_V4p2_Price_BAO_LineItem::create($lineParams); - } - - return TRUE; - } - - /** - * (Queue Task Callback) - * - * Find any participant records and create corresponding line-item - * records. - * - * @param CRM_Queue_TaskContext $ctx - * @param int $startId - * the first/lowest participant ID to convert. - * @param int $endId - * the last/highest participant ID to convert. - * - * @return bool - */ - public static function task_4_2_alpha1_convertParticipants(CRM_Queue_TaskContext $ctx, $startId, $endId) { - $upgrade = new CRM_Upgrade_Form(); - //create lineitems for participant in edge cases using default price set for contribution. - $query = " -SELECT cp.id as participant_id, cp.fee_amount, cp.fee_level,ce.is_monetary, - cpse.price_set_id, cpf.id as price_field_id, cpfv.id as price_field_value_id -FROM civicrm_participant cp -LEFT JOIN civicrm_line_item cli ON cli.entity_id=cp.id and cli.entity_table = 'civicrm_participant' -LEFT JOIN civicrm_event ce ON ce.id=cp.event_id -LEFT JOIN civicrm_price_set_entity cpse ON cp.event_id = cpse.entity_id and cpse.entity_table = 'civicrm_event' -LEFT JOIN civicrm_price_field cpf ON cpf.price_set_id = cpse.price_set_id -LEFT JOIN civicrm_price_field_value cpfv ON cpfv.price_field_id = cpf.id AND cpfv.label = cp.fee_level -WHERE (cp.id BETWEEN %1 AND %2) -AND cli.entity_id IS NULL AND cp.fee_amount IS NOT NULL"; - $sqlParams = array( - 1 => array($startId, 'Integer'), - 2 => array($endId, 'Integer'), - ); - $dao = CRM_Core_DAO::executeQuery($query, $sqlParams); - if ($dao->N) { - $defaultPriceSetId = CRM_Core_DAO::getFieldValue('CRM_Upgrade_Snapshot_V4p2_Price_DAO_Set', 'default_contribution_amount', 'id', 'name'); - $priceSets = current(CRM_Upgrade_Snapshot_V4p2_Price_BAO_Set::getSetDetail($defaultPriceSetId)); - $fieldID = key($priceSets['fields']); - } - - while ($dao->fetch()) { - $lineParams = array( - 'entity_table' => 'civicrm_participant', - 'entity_id' => $dao->participant_id, - 'label' => $dao->fee_level ? $dao->fee_level : ts('Default'), - 'qty' => 1, - 'unit_price' => $dao->fee_amount, - 'line_total' => $dao->fee_amount, - 'participant_count' => 1, - ); - if ($dao->is_monetary && $dao->price_field_id) { - $lineParams += array( - 'price_field_id' => $dao->price_field_id, - 'price_field_value_id' => $dao->price_field_value_id, - ); - $priceSetId = $dao->price_set_id; - } - else { - $lineParams['price_field_id'] = $fieldID; - $priceSetId = $defaultPriceSetId; - } - CRM_Upgrade_Snapshot_V4p2_Price_BAO_LineItem::create($lineParams); - } - return TRUE; - } - - /** - * (Queue Task Callback) - * - * Create an event registration profile with a single email field CRM-9587 - * - * @param \CRM_Queue_TaskContext $ctx - * - * @return bool - */ - public static function task_4_2_alpha1_eventProfile(CRM_Queue_TaskContext $ctx) { - $upgrade = new CRM_Upgrade_Form(); - $profileTitle = ts('Your Registration Info'); - - $sql = " -INSERT INTO civicrm_uf_group - (is_active, group_type, title, help_pre, help_post, limit_listings_group_id, post_URL, add_to_group_id, add_captcha, is_map, is_edit_link, is_uf_link, is_update_dupe, cancel_URL, is_cms_user, notify, is_reserved, name, created_id, created_date, is_proximity_search) -VALUES - (1, 'Individual, Contact', %1, NULL, NULL, NULL, NULL, NULL, 0, 0, 0, 0, 0, NULL, 0, NULL, 0, 'event_registration', NULL, NULL, 0); -"; - - $params = array( - 1 => array($profileTitle, 'String'), - ); - - CRM_Core_DAO::executeQuery($sql, $params); - - $eventRegistrationId = CRM_Core_DAO::singleValueQuery('SELECT LAST_INSERT_ID()'); - $sql = " -INSERT INTO civicrm_uf_field - (uf_group_id, field_name, is_active, is_view, is_required, weight, help_post, help_pre, visibility, in_selector, is_searchable, location_type_id, phone_type_id, label, field_type, is_reserved) -VALUES - ({$eventRegistrationId}, 'email', 1, 0, 1, 1, NULL, NULL, 'User and User Admin Only', 0, 0, NULL, NULL, 'Email Address', 'Contact', 0); -"; - CRM_Core_DAO::executeQuery($sql); - - $sql = "SELECT * FROM civicrm_event WHERE is_online_registration = 1;"; - $events = CRM_Core_DAO::executeQuery($sql); - while ($events->fetch()) { - // Get next weights for the event registration profile - $nextMainWeight = $nextAdditionalWeight = 1; - $sql = " -SELECT weight -FROM civicrm_uf_join -WHERE entity_id = {$events->id} AND module = 'CiviEvent' -ORDER BY weight DESC LIMIT 1"; - $weights = CRM_Core_DAO::executeQuery($sql); - $weights->fetch(); - if (isset($weights->weight)) { - $nextMainWeight += $weights->weight; - } - $sql = " -SELECT weight -FROM civicrm_uf_join -WHERE entity_id = {$events->id} AND module = 'CiviEvent_Additional' -ORDER BY weight DESC LIMIT 1"; - $weights = CRM_Core_DAO::executeQuery($sql); - $weights->fetch(); - if (isset($weights->weight)) { - $nextAdditionalWeight += $weights->weight; - } - // Add an event registration profile to the event - $sql = " -INSERT INTO civicrm_uf_join - (is_active, module, entity_table, entity_id, weight, uf_group_id) -VALUES - (1, 'CiviEvent', 'civicrm_event', {$events->id}, {$nextMainWeight}, {$eventRegistrationId}); -"; - CRM_Core_DAO::executeQuery($sql); - $sql = " -INSERT INTO civicrm_uf_join - (is_active, module, entity_table, entity_id, weight, uf_group_id) -VALUES - (1, 'CiviEvent_Additional', 'civicrm_event', {$events->id}, {$nextAdditionalWeight}, {$eventRegistrationId});"; - CRM_Core_DAO::executeQuery($sql); - } - return TRUE; - } - - /** - * @return array - */ - public static function deleteInvalidPairs() { - require_once 'CRM/Member/PseudoConstant.php'; - require_once 'CRM/Contribute/PseudoConstant.php'; - $processedRecords = array(); - - $tempTableName1 = CRM_Core_DAO::createTempTableName(); - // 1. collect all duplicates - $sql = " - CREATE TEMPORARY TABLE {$tempTableName1} SELECT mp.id as payment_id, mp.contribution_id, mp.membership_id, mem.membership_type_id, mem.start_date, mem.end_date, mem.status_id, mem.contact_id, con.contribution_status_id - FROM civicrm_membership_payment mp - INNER JOIN ( SELECT cmp.contribution_id - FROM civicrm_membership_payment cmp - LEFT JOIN civicrm_line_item cli ON cmp.contribution_id=cli.entity_id and cli.entity_table = 'civicrm_contribution' - WHERE cli.entity_id IS NULL - GROUP BY cmp.contribution_id - HAVING COUNT(cmp.membership_id) > 1) submp ON submp.contribution_id = mp.contribution_id - INNER JOIN civicrm_membership mem ON mem.id = mp.membership_id - INNER JOIN civicrm_contribution con ON con.id = mp.contribution_id - ORDER BY mp.contribution_id, mp.membership_id"; - $dao = CRM_Core_DAO::executeQuery($sql); - - $tempTableName2 = CRM_Core_DAO::createTempTableName(); - // 2. collect all records that are going to be retained - $sql = " - CREATE TEMPORARY TABLE {$tempTableName2} - SELECT MAX(payment_id) as payment_id FROM {$tempTableName1} GROUP BY contribution_id HAVING COUNT(*) > 1"; - CRM_Core_DAO::executeQuery($sql); - - // 3. do the un-linking - $sql = " - DELETE cmp.* - FROM civicrm_membership_payment cmp - INNER JOIN $tempTableName1 temp1 ON temp1.payment_id = cmp.id - LEFT JOIN $tempTableName2 temp2 ON temp1.payment_id = temp2.payment_id - WHERE temp2.payment_id IS NULL"; - CRM_Core_DAO::executeQuery($sql); - - // 4. show all records that were Processed, i.e Retained vs Un-linked - $sql = " - SELECT temp1.contact_id, temp1.contribution_id, temp1.contribution_status_id, temp1.membership_id, temp1.membership_type_id, temp1.start_date, temp1.end_date, temp1.status_id, temp2.payment_id as retain_id - FROM $tempTableName1 temp1 - LEFT JOIN $tempTableName2 temp2 ON temp1.payment_id = temp2.payment_id"; - $dao = CRM_Core_DAO::executeQuery($sql); - if ($dao->N) { - $membershipType = CRM_Member_PseudoConstant::membershipType(); - $membershipStatus = CRM_Member_PseudoConstant::membershipStatus(); - $contributionStatus = CRM_Contribute_PseudoConstant::contributionStatus(); - while ($dao->fetch()) { - $status = $dao->retain_id ? 'Retained' : 'Un-linked'; - $memType = CRM_Utils_Array::value($dao->membership_type_id, $membershipType); - $memStatus = CRM_Utils_Array::value($dao->status_id, $membershipStatus); - $contribStatus = CRM_Utils_Array::value($dao->contribution_status_id, $contributionStatus); - $processedRecords[] = array( - $dao->contact_id, - $dao->contribution_id, - $contribStatus, - $dao->membership_id, - $memType, - $dao->start_date, - $dao->end_date, - $memStatus, - $status, - ); - } - } - - if (!empty($processedRecords)) { - CRM_Core_Error::debug_log_message("deleteInvalidPairs() - The following records have been processed. Membership records with action:"); - CRM_Core_Error::debug_log_message("Contact ID, ContributionID, Contribution Status, MembershipID, Membership Type, Start Date, End Date, Membership Status, Action"); - foreach ($processedRecords as $record) { - CRM_Core_Error::debug_log_message(implode(', ', $record)); - } - } - else { - CRM_Core_Error::debug_log_message("deleteInvalidPairs() - Could not find any records to process."); - } - return $processedRecords; - } - -} diff --git a/civicrm/CRM/Upgrade/Incremental/sql/4.2.0.mysql.tpl b/civicrm/CRM/Upgrade/Incremental/sql/4.2.0.mysql.tpl deleted file mode 100644 index ba1ac766c6..0000000000 --- a/civicrm/CRM/Upgrade/Incremental/sql/4.2.0.mysql.tpl +++ /dev/null @@ -1,34 +0,0 @@ --- CRM-10641 (fix duplicate option values) - -SELECT @option_group_id_act := max(id) from civicrm_option_group where name = 'activity_type'; -SELECT @maxValue := MAX(ROUND(value)) FROM civicrm_option_value WHERE option_group_id = @option_group_id_act; -SELECT @clientSMSValue := value FROM civicrm_option_value WHERE name = 'BULK SMS' AND option_group_id = @option_group_id_act; - -SELECT @smsVal := value FROM civicrm_option_value WHERE option_group_id = @option_group_id_act GROUP BY value -HAVING count(value) > 1 AND value = @clientSMSValue; - -UPDATE civicrm_option_value -SET value = @maxValue + 1 -WHERE value = @smsVal -AND name = 'BULK SMS' AND option_group_id = @option_group_id_act; - -SELECT @newClientSMSValue := value FROM civicrm_option_value WHERE name = 'BULK SMS' AND option_group_id = @option_group_id_act; - -UPDATE civicrm_activity -INNER JOIN civicrm_mailing ON civicrm_activity.source_record_id = civicrm_mailing.id -SET civicrm_activity.activity_type_id = @newClientSMSValue -WHERE civicrm_activity.activity_type_id = @clientSMSValue; - --- CRM-10671 remove incomplete price set reports (inserted in 4.2 alpha 1) -SELECT @option_group_id_report := MAX(id) FROM civicrm_option_group WHERE name = 'report_template'; -DELETE from civicrm_option_value -WHERE name = 'CRM_Report_Form_Price_Lineitem' AND -option_group_id = @option_group_id_report; - -DELETE from civicrm_option_value -WHERE name = 'CRM_Report_Form_Price_Contributionbased' AND -option_group_id = @option_group_id_report; - -DELETE from civicrm_option_value -WHERE name = 'CRM_Report_Form_Price_Lineitemparticipant' AND -option_group_id = @option_group_id_report; \ No newline at end of file diff --git a/civicrm/CRM/Upgrade/Incremental/sql/4.2.1.mysql.tpl b/civicrm/CRM/Upgrade/Incremental/sql/4.2.1.mysql.tpl deleted file mode 100644 index 85d51e1677..0000000000 --- a/civicrm/CRM/Upgrade/Incremental/sql/4.2.1.mysql.tpl +++ /dev/null @@ -1,4 +0,0 @@ --- CRM-10794 -DELETE FROM civicrm_payment_processor_type WHERE name = 'ClickAndPledge'; -DELETE FROM civicrm_payment_processor WHERE payment_processor_type = 'ClickAndPledge'; - diff --git a/civicrm/CRM/Upgrade/Incremental/sql/4.2.2.mysql.tpl b/civicrm/CRM/Upgrade/Incremental/sql/4.2.2.mysql.tpl deleted file mode 100644 index 83177959e5..0000000000 --- a/civicrm/CRM/Upgrade/Incremental/sql/4.2.2.mysql.tpl +++ /dev/null @@ -1,21 +0,0 @@ --- CRM-10810 -SELECT @max_strict := max(id), @cnt_strict := count(*) FROM `civicrm_dedupe_rule_group` WHERE `contact_type` = 'Individual' AND `level` = 'Strict' AND `is_default` = 1; -UPDATE `civicrm_dedupe_rule_group` SET `is_default` = 0 WHERE @cnt_strict > 1 AND id = @max_strict; - -SELECT @max_fuzzy := max(id), @cnt_fuzzy := count(*) FROM `civicrm_dedupe_rule_group` WHERE `contact_type` = 'Individual' AND `level` = 'Fuzzy' AND `is_default` = 1; -UPDATE `civicrm_dedupe_rule_group` SET `is_default` = 0 WHERE @cnt_fuzzy > 1 AND id = @max_fuzzy; - --- Insert line items for contribution for api/import -SELECT @fieldID := cpf.id, @fieldValueID := cpfv.id FROM civicrm_price_set cps -LEFT JOIN civicrm_price_field cpf ON cps.id = cpf.price_set_id -LEFT JOIN civicrm_price_field_value cpfv ON cpf.id = cpfv.price_field_id -WHERE cps.name = 'default_contribution_amount'; - -INSERT INTO civicrm_line_item ( entity_table, entity_id, price_field_id,label, qty, unit_price, line_total, participant_count, price_field_value_id ) -SELECT 'civicrm_contribution', cc.id, @fieldID, 'Contribution Amount', 1, total_amount, total_amount , 0, @fieldValueID -FROM `civicrm_contribution` cc -LEFT JOIN civicrm_line_item cli ON cc.id=cli.entity_id and cli.entity_table = 'civicrm_contribution' -LEFT JOIN civicrm_membership_payment cmp ON cc.id = cmp.contribution_id -LEFT JOIN civicrm_participant_payment cpp ON cc.id = cpp.contribution_id -WHERE cli.entity_id IS NULL AND cc.contribution_page_id IS NULL AND cmp.contribution_id IS NULL AND cpp.contribution_id IS NULL -GROUP BY cc.id; diff --git a/civicrm/CRM/Upgrade/Incremental/sql/4.2.3.mysql.tpl b/civicrm/CRM/Upgrade/Incremental/sql/4.2.3.mysql.tpl deleted file mode 100644 index 4721762e1b..0000000000 --- a/civicrm/CRM/Upgrade/Incremental/sql/4.2.3.mysql.tpl +++ /dev/null @@ -1,49 +0,0 @@ --- CRM-10969 -SELECT @mailingsID := MAX(id) FROM civicrm_navigation WHERE name = 'Mailings' AND domain_id = {$domainID}; -SELECT @navWeight := MAX(id) FROM civicrm_navigation WHERE name = 'New SMS' AND parent_id = @mailingsID; - -UPDATE civicrm_navigation SET has_separator = NULL -WHERE name = 'New SMS' AND parent_id = @mailingsID AND has_separator = 1; - -INSERT INTO civicrm_navigation - ( domain_id, url, label, name, permission, permission_operator, parent_id, is_active, has_separator, weight ) -VALUES - ( {$domainID}, 'civicrm/mailing/browse?reset=1&sms=1', '{ts escape="sql" skip="true"}Find Mass SMS{/ts}', 'Find Mass SMS', 'administer CiviCRM', NULL, @mailingsID, '1', 1, @navWeight+1 ); - --- CRM-10980 and CRM-11014 -SELECT @optionID := max(id) FROM civicrm_option_value WHERE name = 'BULK SMS'; -{if $multilingual} - {foreach from=$locales item=locale} - UPDATE `civicrm_option_value` SET label_{$locale} = '{ts escape="sql"}Mass SMS{/ts}',name = 'Mass SMS',description_{$locale} = '{ts escape="sql"}Mass SMS{/ts}' WHERE id = @optionID; - ALTER TABLE `civicrm_price_field_value` CHANGE name name VARCHAR(255) NULL DEFAULT NULL, CHANGE label_{$locale} label_{$locale} VARCHAR(255) NULL DEFAULT NULL; - {/foreach} -{else} - UPDATE `civicrm_option_value` SET label = '{ts escape="sql"}Mass SMS{/ts}',name = 'Mass SMS',description = '{ts escape="sql"}Mass SMS{/ts}' WHERE name = 'BULK SMS'; - ALTER TABLE `civicrm_price_field_value` CHANGE `name` `name` VARCHAR(255) NULL DEFAULT NULL, CHANGE `label` `label` VARCHAR(255) NULL DEFAULT NULL; -{/if} - --- CRM-11014 - ALTER TABLE `civicrm_line_item` CHANGE `label` `label` VARCHAR(255) NULL DEFAULT NULL; - --- CRM-10986: Rename Batches UI elements to Bulk Data Entry --- update reserved profile titles -{if $multilingual} - {foreach from=$locales item=locale} - UPDATE `civicrm_uf_group` SET title_{$locale} = '{ts escape="sql"}Contribution Bulk Entry{/ts}' WHERE name = 'contribution_batch_entry'; - UPDATE `civicrm_uf_group` SET title_{$locale} = '{ts escape="sql"}Membership Bulk Entry{/ts}' WHERE name = 'membership_batch_entry'; - {/foreach} -{else} - UPDATE `civicrm_uf_group` SET title = '{ts escape="sql"}Contribution Bulk Entry{/ts}' WHERE name = 'contribution_batch_entry'; - UPDATE `civicrm_uf_group` SET title = '{ts escape="sql"}Membership Bulk Entry{/ts}' WHERE name = 'membership_batch_entry'; -{/if} - --- update navigation menu items and fix typo in permission column -UPDATE `civicrm_navigation` SET label = '{ts escape="sql"}Bulk Data Entry{/ts}', name = 'Bulk Data Entry', -permission = 'access CiviMember, access CiviContribute' -WHERE url = 'civicrm/batch&reset=1'; - --- CRM-11018 -ALTER TABLE civicrm_discount DROP FOREIGN KEY FK_civicrm_discount_option_group_id; -ALTER TABLE `civicrm_discount` - ADD CONSTRAINT `FK_civicrm_discount_option_group_id` FOREIGN KEY (`option_group_id`) REFERENCES `civicrm_price_set` (`id`) ON DELETE CASCADE; -ALTER TABLE `civicrm_discount` CHANGE `option_group_id` `option_group_id` int(10) unsigned NOT NULL COMMENT 'FK to civicrm_price_set'; \ No newline at end of file diff --git a/civicrm/CRM/Upgrade/Incremental/sql/4.2.5.mysql.tpl b/civicrm/CRM/Upgrade/Incremental/sql/4.2.5.mysql.tpl deleted file mode 100644 index f60a29aeef..0000000000 --- a/civicrm/CRM/Upgrade/Incremental/sql/4.2.5.mysql.tpl +++ /dev/null @@ -1,10 +0,0 @@ --- Placeholder which ensures that PHP upgrade tasks are executed - --- Get domain id -SELECT @domainID := min(id) FROM civicrm_domain; - --- CRM-11060 -INSERT INTO `civicrm_job` - ( domain_id, run_frequency, last_run, name, description, api_prefix, api_entity, api_action, parameters, is_active ) -VALUES - ( @domainID, 'Always' , NULL, '{ts escape="sql" skip="true"}Send Scheduled SMS{/ts}', '{ts escape="sql" skip="true"}Sends out scheduled SMS{/ts}', 'civicrm_api3', 'job', 'process_sms', NULL, 0); diff --git a/civicrm/CRM/Upgrade/Incremental/sql/4.2.6.mysql.tpl b/civicrm/CRM/Upgrade/Incremental/sql/4.2.6.mysql.tpl deleted file mode 100644 index fb658a6afd..0000000000 --- a/civicrm/CRM/Upgrade/Incremental/sql/4.2.6.mysql.tpl +++ /dev/null @@ -1,2 +0,0 @@ --- Placeholder which ensures that PHP upgrade tasks are executed - diff --git a/civicrm/CRM/Upgrade/Incremental/sql/4.2.7.mysql.tpl b/civicrm/CRM/Upgrade/Incremental/sql/4.2.7.mysql.tpl deleted file mode 100644 index f93262a825..0000000000 --- a/civicrm/CRM/Upgrade/Incremental/sql/4.2.7.mysql.tpl +++ /dev/null @@ -1,15 +0,0 @@ --- CRM-11354 Fix empty permissions for report instances -UPDATE civicrm_report_instance SET permission = 'access CiviReport' -WHERE report_id = 'survey/detail' and permission = ''; - -UPDATE civicrm_report_instance SET permission = 'access CiviMail' -WHERE report_id = 'mailing/detail' and permission = ''; - -UPDATE civicrm_report_instance SET permission = 'access CiviMember' -WHERE report_id = 'member/contributionDetail' and permission = ''; - -UPDATE civicrm_report_instance SET permission = 'access CiviGrant' -WHERE report_id = 'grant/statistics' and permission = ''; - -UPDATE civicrm_report_instance SET permission = 'access CiviReport' -WHERE permission = '0' OR permission = '' OR permission IS NULL; \ No newline at end of file diff --git a/civicrm/CRM/Upgrade/Incremental/sql/4.2.8.mysql.tpl b/civicrm/CRM/Upgrade/Incremental/sql/4.2.8.mysql.tpl deleted file mode 100644 index fb658a6afd..0000000000 --- a/civicrm/CRM/Upgrade/Incremental/sql/4.2.8.mysql.tpl +++ /dev/null @@ -1,2 +0,0 @@ --- Placeholder which ensures that PHP upgrade tasks are executed - diff --git a/civicrm/CRM/Upgrade/Incremental/sql/4.2.9.mysql.tpl b/civicrm/CRM/Upgrade/Incremental/sql/4.2.9.mysql.tpl deleted file mode 100644 index fb658a6afd..0000000000 --- a/civicrm/CRM/Upgrade/Incremental/sql/4.2.9.mysql.tpl +++ /dev/null @@ -1,2 +0,0 @@ --- Placeholder which ensures that PHP upgrade tasks are executed - diff --git a/civicrm/CRM/Upgrade/Incremental/sql/4.2.alpha1.mysql.tpl b/civicrm/CRM/Upgrade/Incremental/sql/4.2.alpha1.mysql.tpl deleted file mode 100644 index 8f7c319973..0000000000 --- a/civicrm/CRM/Upgrade/Incremental/sql/4.2.alpha1.mysql.tpl +++ /dev/null @@ -1,409 +0,0 @@ -{include file='../CRM/Upgrade/4.2.alpha1.msg_template/civicrm_msg_template.tpl'} - --- CRM-9542 mailing detail report template -SELECT @option_group_id_report := MAX(id) FROM civicrm_option_group WHERE name = 'report_template'; -SELECT @weight := MAX(weight) FROM civicrm_option_value WHERE option_group_id = @option_group_id_report; -SELECT @mailCompId := MAX(id) FROM civicrm_component where name = 'CiviMail'; -INSERT INTO civicrm_option_value - (option_group_id, {localize field='label'}label{/localize}, value, name, weight, {localize field='description'}description{/localize}, is_active, component_id) VALUES - (@option_group_id_report, {localize}'Mail Detail Report'{/localize}, 'mailing/detail', 'CRM_Report_Form_Mailing_Detail', @weight := @weight + 1, {localize}'Provides reporting on Intended and Successful Deliveries, Unsubscribes and Opt-outs, Replies and Forwards.'{/localize}, 1, @mailCompId); - -INSERT INTO `civicrm_report_instance` - ( `domain_id`, `title`, `report_id`, `description`, `permission`, `form_values`) -VALUES - ( {$domainID}, 'Mailing Detail Report', 'mailing/detail', 'Provides reporting on Intended and Successful Deliveries, Unsubscribes and Opt-outs, Replies and Forwards.', 'access CiviMail', '{literal}a:30:{s:6:"fields";a:6:{s:9:"sort_name";s:1:"1";s:12:"mailing_name";s:1:"1";s:11:"delivery_id";s:1:"1";s:14:"unsubscribe_id";s:1:"1";s:9:"optout_id";s:1:"1";s:5:"email";s:1:"1";}s:12:"sort_name_op";s:3:"has";s:15:"sort_name_value";s:0:"";s:6:"id_min";s:0:"";s:6:"id_max";s:0:"";s:5:"id_op";s:3:"lte";s:8:"id_value";s:0:"";s:13:"mailing_id_op";s:2:"in";s:16:"mailing_id_value";a:0:{}s:18:"delivery_status_op";s:2:"eq";s:21:"delivery_status_value";s:0:"";s:18:"is_unsubscribed_op";s:2:"eq";s:21:"is_unsubscribed_value";s:0:"";s:12:"is_optout_op";s:2:"eq";s:15:"is_optout_value";s:0:"";s:13:"is_replied_op";s:2:"eq";s:16:"is_replied_value";s:0:"";s:15:"is_forwarded_op";s:2:"eq";s:18:"is_forwarded_value";s:0:"";s:6:"gid_op";s:2:"in";s:9:"gid_value";a:0:{}s:9:"order_bys";a:1:{i:1;a:2:{s:6:"column";s:9:"sort_name";s:5:"order";s:3:"ASC";}}s:11:"description";s:21:"Mailing Detail Report";s:13:"email_subject";s:0:"";s:8:"email_to";s:0:"";s:8:"email_cc";s:0:"";s:10:"permission";s:15:"access CiviMail";s:9:"parent_id";s:0:"";s:6:"groups";s:0:"";s:9:"domain_id";i:1;}{/literal}'); - -SELECT @reportlastID := MAX(id) FROM civicrm_navigation where name = 'Reports' AND domain_id = {$domainID}; -SELECT @nav_max_weight := MAX(ROUND(weight)) from civicrm_navigation WHERE parent_id = @reportlastID; - -SET @instanceID:=LAST_INSERT_ID(); -INSERT INTO civicrm_navigation - ( domain_id, url, label, name, permission, permission_operator, parent_id, is_active, has_separator, weight ) -VALUES - ( {$domainID}, CONCAT('civicrm/report/instance/', @instanceID,'&reset=1'), '{ts escape="sql"}Mailing Detail Report{/ts}', 'Mailing Detail Report', 'access CiviMail', 'OR', @reportlastID, '1', NULL, @nav_max_weight+1 ); -UPDATE civicrm_report_instance SET navigation_id = LAST_INSERT_ID() WHERE id = @instanceID; - --- CRM-9600 -ALTER TABLE `civicrm_custom_group` CHANGE `extends_entity_column_value` `extends_entity_column_value` VARCHAR( 255 ) CHARACTER SET utf8 COLLATE utf8_unicode_ci NULL DEFAULT NULL COMMENT 'linking custom group for dynamic object.'; - --- CRM-9534 -ALTER TABLE `civicrm_prevnext_cache` ADD COLUMN is_selected tinyint(4) DEFAULT '0'; - --- CRM-9834 --- civicrm_batch table changes -ALTER TABLE `civicrm_batch` ADD UNIQUE KEY `UI_name` ( name ); - - -ALTER TABLE `civicrm_batch` ADD `saved_search_id` int(10) unsigned DEFAULT NULL COMMENT 'FK to Saved Search ID'; -ALTER TABLE `civicrm_batch` ADD `status_id` int(10) unsigned NOT NULL COMMENT 'fk to Batch Status options in civicrm_option_values'; -ALTER TABLE `civicrm_batch` ADD `type_id` int(10) unsigned NOT NULL COMMENT 'fk to Batch Type options in civicrm_option_values'; -ALTER TABLE `civicrm_batch` ADD `mode_id` int(10) unsigned DEFAULT NULL COMMENT 'fk to Batch mode options in civicrm_option_values'; -ALTER TABLE `civicrm_batch` ADD `total` decimal(20,2) DEFAULT NULL COMMENT 'Total amount for this batch.'; -ALTER TABLE `civicrm_batch` ADD `item_count` int(10) unsigned NOT NULL COMMENT 'Number of items in a batch.'; - -ALTER TABLE `civicrm_batch` ADD CONSTRAINT `FK_civicrm_batch_saved_search_id` FOREIGN KEY (`saved_search_id`) REFERENCES `civicrm_saved_search` (`id`) ON DELETE SET NULL; - ---batch type and batch status option groups -INSERT INTO - `civicrm_option_group` (`name`, {localize field='title'}title{/localize}, `is_reserved`, `is_active`) -VALUES - ('batch_type' , {localize}'Batch Type'{/localize} , 1, 1), - ('batch_status' , {localize}'Batch Status'{/localize} , 1, 1); - -SELECT @option_group_id_batch_type := max(id) from civicrm_option_group where name = 'batch_type'; -SELECT @option_group_id_batch_status := max(id) from civicrm_option_group where name = 'batch_status'; - -INSERT INTO - `civicrm_option_value` (`option_group_id`, {localize field='label'}label{/localize}, `value`, `name`, `grouping`, `filter`, `is_default`, `weight`) -VALUES - (@option_group_id_batch_type, {localize}'Contribution'{/localize}, 1, 'Contribution', NULL, 0, 0, 1), - (@option_group_id_batch_type, {localize}'Membership'{/localize}, 2, 'Membership', NULL, 0, 0, 2), - (@option_group_id_batch_status, {localize}'Open'{/localize}, 1, 'Open', NULL, 0, 0, 1), - (@option_group_id_batch_status, {localize}'Closed'{/localize}, 2, 'Closed', NULL, 0, 0, 2); - ---default profile for contribution and membership batch entry -INSERT INTO civicrm_uf_group - ( name, group_type, {localize field='title'}title{/localize}, is_cms_user, is_reserved) - VALUES - ( 'contribution_batch_entry', 'Contribution', {localize}'Contribution Batch Entry'{/localize} , 0, 1), - ( 'membership_batch_entry', 'Membership', {localize}'Membership Batch Entry'{/localize} , 0, 1); - -SELECT @uf_group_contribution_batch_entry := max(id) FROM civicrm_uf_group WHERE name = 'contribution_batch_entry'; -SELECT @uf_group_membership_batch_entry := max(id) FROM civicrm_uf_group WHERE name = 'membership_batch_entry'; - -INSERT INTO civicrm_uf_join - (is_active, module, entity_table, entity_id, weight, uf_group_id) -VALUES - (1, 'Profile', NULL, NULL, 9, @uf_group_contribution_batch_entry), - (1, 'Profile', NULL, NULL, 9, @uf_group_membership_batch_entry); - -INSERT INTO civicrm_uf_field - ( uf_group_id, field_name, is_required, is_reserved, weight, visibility, in_selector, is_searchable, location_type_id, {localize field='label'}label{/localize}, field_type ) -VALUES - ( @uf_group_contribution_batch_entry, 'contribution_type', 1, 1, 1, 'User and User Admin Only', 0, 0, NULL, {localize}'Type'{/localize}, 'Contribution'), - ( @uf_group_contribution_batch_entry, 'total_amount', 1, 1, 2, 'User and User Admin Only', 0, 0, NULL, {localize}'Amount'{/localize}, 'Contribution' ), - ( @uf_group_contribution_batch_entry, 'contribution_status_id', 1, 1, 3, 'User and User Admin Only', 0, 0, NULL, {localize}'Status'{/localize}, 'Contribution' ), - ( @uf_group_contribution_batch_entry, 'receive_date', 1, 1, 4, 'User and User Admin Only', 0, 0, NULL, {localize}'Received'{/localize}, 'Contribution'), - ( @uf_group_contribution_batch_entry, 'contribution_source', 0, 0, 5, 'User and User Admin Only', 0, 0, NULL, {localize}'Source'{/localize}, 'Contribution' ), - ( @uf_group_contribution_batch_entry, 'payment_instrument', 0, 0, 6, 'User and User Admin Only', 0, 0, NULL, {localize}'Payment Instrument'{/localize}, 'Contribution' ), - ( @uf_group_contribution_batch_entry, 'check_number', 0, 0, 7, 'User and User Admin Only', 0, 0, NULL, {localize}'Check Number'{/localize}, 'Contribution' ), - ( @uf_group_contribution_batch_entry, 'send_receipt', 0, 0, 8, 'User and User Admin Only', 0, 0, NULL, {localize}'Send Receipt'{/localize}, 'Contribution' ), - ( @uf_group_contribution_batch_entry, 'invoice_id', 0, 0, 9, 'User and User Admin Only', 0, 0, NULL, {localize}'Invoice ID'{/localize}, 'Contribution' ), - ( @uf_group_membership_batch_entry, 'membership_type', 1, 1, 1, 'User and User Admin Only', 0, 0, NULL, {localize}'Type'{/localize}, 'Membership' ), - ( @uf_group_membership_batch_entry, 'join_date', 1, 1, 2, 'User and User Admin Only', 0, 0, NULL, {localize}'Member Since'{/localize}, 'Membership' ), - ( @uf_group_membership_batch_entry, 'membership_start_date', 0, 1, 3, 'User and User Admin Only', 0, 0, NULL, {localize}'Start Date'{/localize}, 'Membership' ), - ( @uf_group_membership_batch_entry, 'membership_end_date', 0, 1, 4, 'User and User Admin Only', 0, 0, NULL, {localize}'End Date'{/localize}, 'Membership' ), - ( @uf_group_membership_batch_entry, 'membership_source', 0, 0, 5, 'User and User Admin Only', 0, 0, NULL, {localize}'Source'{/localize}, 'Membership' ), - ( @uf_group_membership_batch_entry, 'send_receipt', 0, 0, 6, 'User and User Admin Only', 0, 0, NULL, {localize}'Send Receipt'{/localize}, 'Membership' ), - ( @uf_group_membership_batch_entry, 'contribution_type', 1, 1, 7, 'User and User Admin Only', 0, 0, NULL, {localize}'Contribution Type'{/localize}, 'Membership' ), - ( @uf_group_membership_batch_entry, 'total_amount', 1, 1, 8, 'User and User Admin Only', 0, 0, NULL, {localize}'Amount'{/localize}, 'Membership' ), - ( @uf_group_membership_batch_entry, 'receive_date', 1, 1, 9, 'User and User Admin Only', 0, 0, NULL, {localize}'Received'{/localize}, 'Membership' ), - ( @uf_group_membership_batch_entry, 'payment_instrument', 0, 0, 10, 'User and User Admin Only', 0, 0, NULL, {localize}'Payment Instrument'{/localize}, 'Membership' ), - ( @uf_group_membership_batch_entry, 'contribution_status_id', 1, 1, 11, 'User and User Admin Only', 0, 0, NULL, {localize}'Payment Status'{/localize}, 'Membership' ); - ---navigation menu entries -SELECT @navContributionsID := MAX(id) FROM civicrm_navigation where name = 'Contributions' AND domain_id = {$domainID}; -SELECT @navMembershipsID := MAX(id) FROM civicrm_navigation where name = 'Memberships' AND domain_id = {$domainID}; - -INSERT INTO civicrm_navigation - ( domain_id, url, label, name, permission, permission_operator, parent_id, is_active, has_separator, weight ) -VALUES - ( {$domainID}, 'civicrm/batch&reset=1', '{ts escape="sql" skip="true"}Batches{/ts}', 'Batches', 'access CiviContribute,access CiviMember', '', @navContributionsID, '1', NULL, 4 ), - ( {$domainID}, 'civicrm/batch&reset=1', '{ts escape="sql" skip="true"}Batches{/ts}', 'Batches', 'access CiviMember,access CiviContribute', '', @navMembershipsID, '1', NULL, 4 ); - --- CRM-9686 -INSERT INTO `civicrm_state_province`(`country_id`, `abbreviation`, `name`) VALUES(1097, "LP", "La Paz"); - --- CRM-9905 -ALTER TABLE civicrm_contribution_page CHANGE COLUMN is_email_receipt is_email_receipt TINYINT(4) DEFAULT 0; - --- CRM-9850 - ALTER TABLE `civicrm_contribution_page` CHANGE `payment_processor_id` `payment_processor` VARCHAR( 128 ) NULL DEFAULT NULL COMMENT 'Payment Processor for this contribution Page '; - - ALTER TABLE `civicrm_event` CHANGE `payment_processor_id` `payment_processor` VARCHAR( 128 ) NULL DEFAULT NULL COMMENT 'Payment Processor for this event '; - --- CRM-9783 -CREATE TABLE `civicrm_sms_provider` ( - `id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT 'SMS Provider ID', - `name` varchar(64) DEFAULT NULL COMMENT 'Provider internal name points to option_value of option_group sms_provider_name', - `title` varchar(64) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT 'Provider name visible to user', - `username` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL, - `password` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL, - `api_type` int(10) unsigned NOT NULL COMMENT 'points to value in civicrm_option_value for group sms_api_type', - `api_url` varchar(128) COLLATE utf8_unicode_ci DEFAULT NULL, - `api_params` text COLLATE utf8_unicode_ci COMMENT 'the api params in xml, http or smtp format', - `is_default` tinyint(4) DEFAULT '0', - `is_active` tinyint(4) DEFAULT '0', - PRIMARY KEY (`id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=1; - -ALTER TABLE `civicrm_mailing` ADD `sms_provider_id` int(10) unsigned NULL COMMENT 'FK to civicrm_sms_provider id '; -ALTER TABLE `civicrm_mailing` ADD CONSTRAINT `FK_civicrm_mailing_sms_provider_id` FOREIGN KEY (`sms_provider_id`) REFERENCES `civicrm_sms_provider` (`id`) ON DELETE SET NULL; - -INSERT INTO - `civicrm_option_group` (`name`, {localize field='title'}`title`{/localize}, `is_reserved`, `is_active`) -VALUES - ('sms_provider_name', {localize}'Sms provider Internal Name'{/localize} , 1, 1); -SELECT @option_group_id_sms_provider_name := max(id) from civicrm_option_group where name = 'sms_provider_name'; - -INSERT INTO civicrm_option_value - (option_group_id, {localize field='label'}label{/localize}, value, name, weight, filter, is_default, component_id) -VALUES - (@option_group_id_sms_provider_name, {localize}'Clickatell'{/localize}, 'Clickatell', 'Clickatell', 1, 0, NULL, NULL); - -INSERT INTO - `civicrm_option_group` (`name`, {localize field='title'}`title`{/localize}, `is_reserved`, `is_active`) -VALUES - ( 'sms_api_type', {localize}'{ts escape="sql"}Api Type{/ts}'{/localize} , 1, 1 ); -SELECT @option_group_id_sms_api_type := max(id) from civicrm_option_group where name = 'sms_api_type'; - -INSERT INTO civicrm_option_value - (option_group_id, {localize field='label'}label{/localize}, value, name, weight, filter, is_default, is_reserved, component_id) -VALUES - (@option_group_id_sms_api_type, {localize}'http'{/localize}, 1, 'http', 1, NULL, 0, 1, NULL), - (@option_group_id_sms_api_type, {localize}'xml'{/localize}, 2, 'xml', 2, NULL, 0, 1, NULL), - (@option_group_id_sms_api_type, {localize}'smtp'{/localize}, 3, 'smtp', 3, NULL, 0, 1, NULL); - --- CRM-9784 -SELECT @adminSystemSettingsID := MAX(id) FROM civicrm_navigation where name = 'System Settings' AND domain_id = {$domainID}; - -INSERT INTO civicrm_navigation - ( domain_id, url, label, name, permission, permission_operator, parent_id, is_active, has_separator, weight ) -VALUES - ( {$domainID}, 'civicrm/admin/sms/provider?reset=1', '{ts escape="sql" skip="true"}SMS Providers{/ts}', 'SMS Providers', 'administer CiviCRM', '', @adminSystemSettingsID, '1', NULL, 16 ); - --- CRM-9799 - -SELECT @mailingsID := MAX(id) FROM civicrm_navigation where name = 'Mailings' AND domain_id = {$domainID}; - -INSERT INTO civicrm_navigation - ( domain_id, url, label, name, permission, permission_operator, parent_id, is_active, has_separator, weight ) -VALUES - ( {$domainID}, 'civicrm/sms/send?reset=1', '{ts escape="sql" skip="true"}New SMS{/ts}', 'New SMS', 'administer CiviCRM', NULL, @mailingsID, '1', 1, 8 ); - -SELECT @fromEmailAddressesID := MAX(id) FROM civicrm_navigation where name = 'From Email Addresses' AND domain_id = {$domainID}; - -UPDATE civicrm_navigation SET has_separator = 1 WHERE parent_id = @mailingsID AND name = 'From Email Addresses'; - -SELECT @option_group_id_act := max(id) from civicrm_option_group where name = 'activity_type'; -SELECT @max_wt := MAX(weight) FROM civicrm_option_value WHERE option_group_id = @option_group_id_act; - -INSERT INTO - `civicrm_option_value` (`option_group_id`, {localize field='label'}`label`{/localize}, `value`, `name`, `grouping`, `filter`, `is_default`, `weight`, {localize field='description'}`description`{/localize}, `is_optgroup`, `is_reserved`, `is_active`, `component_id`, `visibility_id`) -VALUES - (@option_group_id_act, {localize}'BULK SMS'{/localize}, @max_wt, 'BULK SMS', NULL, 1, NULL, @max_wt, {localize}'BULK SMS'{/localize}, 0, 1, 1, NULL, NULL); - -ALTER TABLE `civicrm_mailing_recipients` ADD `phone_id` int(10) unsigned DEFAULT NULL; - -ALTER TABLE `civicrm_mailing_recipients` ADD CONSTRAINT `FK_civicrm_mailing_recipients_phone_id` FOREIGN KEY (`phone_id`) REFERENCES `civicrm_phone` (`id`) ON DELETE CASCADE; - -ALTER TABLE `civicrm_mailing_event_queue` ADD `phone_id` int(10) unsigned DEFAULT NULL; - -ALTER TABLE `civicrm_mailing_event_queue` ADD CONSTRAINT `FK_civicrm_mailing_event_queue_phone_id` FOREIGN KEY (`phone_id`) REFERENCES `civicrm_phone` (`id`) ON DELETE CASCADE; - -ALTER TABLE `civicrm_mailing_event_queue` CHANGE `email_id` `email_id` int(10) unsigned DEFAULT NULL; -ALTER TABLE `civicrm_mailing_recipients` CHANGE `email_id` `email_id` int(10) unsigned DEFAULT NULL; - --- CRM-9982 -ALTER TABLE `civicrm_contribution_page` ADD COLUMN is_confirm_enabled tinyint(4) DEFAULT '1'; - --- CRM-9980 -{if $multilingual} - {foreach from=$locales item=locale} - {if !$loc} - {assign var=loc value="_$locale"} - {/if} - ALTER TABLE civicrm_group ADD title_{$locale} VARCHAR(64); - ALTER TABLE civicrm_group ADD UNIQUE KEY `UI_title_{$locale}` (title_{$locale}); - - ALTER TABLE `civicrm_batch` CHANGE `label_{$locale}` `title_{$locale}` varchar(64) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT 'Friendly Name.'; - UPDATE civicrm_group SET title_{$locale} = title; - - ALTER TABLE civicrm_survey - ADD COLUMN thankyou_title_{$locale} varchar(255) COMMENT 'Title for Thank-you page (header title tag, and display at the top of the page).', - ADD COLUMN thankyou_text_{$locale} text COMMENT 'text and html allowed. displayed above result on success page'; - {/foreach} - - ALTER TABLE civicrm_group DROP INDEX `UI_title`; - ALTER TABLE civicrm_group DROP title; -{else} - ALTER TABLE `civicrm_batch` CHANGE `label` `title` varchar(64) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT 'Friendly Name.'; - ALTER TABLE civicrm_survey - ADD COLUMN thankyou_title varchar(255) COMMENT 'Title for Thank-you page (header title tag, and display at the top of the page).', - ADD COLUMN thankyou_text text COMMENT 'text and html allowed. displayed above result on success page'; -{/if} - --- CRM-9780 -SELECT @country_id := max(id) from civicrm_country where iso_code = "AN"; -DELETE FROM civicrm_state_province WHERE country_id = @country_id; -DELETE FROM civicrm_country WHERE id = @country_id; - -SELECT @region_id := max(id) from civicrm_worldregion where name = "America South, Central, North and Caribbean"; - -INSERT INTO civicrm_country (name,iso_code,region_id,is_province_abbreviated) VALUES("Curaçao", "CW", @region_id, 0); -INSERT INTO civicrm_country (name,iso_code,region_id,is_province_abbreviated) VALUES("Sint Maarten (Dutch Part)", "SX", @region_id, 0); -INSERT INTO civicrm_country (name,iso_code,region_id,is_province_abbreviated) VALUES("Bonaire, Saint Eustatius and Saba", "BQ", @region_id, 0); - --- CRM-12428 -{if $multilingual} - {foreach from=$locales item=locale} - ALTER TABLE `civicrm_price_field_value` CHANGE label_{$locale} label_{$locale} VARCHAR(255) NULL DEFAULT NULL; - {/foreach} -{else} - ALTER TABLE `civicrm_price_field_value` CHANGE `label` `label` VARCHAR(255) NULL DEFAULT NULL; -{/if} - --- CRM-9714 create a default price set for contribution and membership -ALTER TABLE `civicrm_price_set` -ADD `is_quick_config` TINYINT(4) NOT NULL DEFAULT '0' - COMMENT 'Is set if edited on Contribution or Event Page rather than through Manage Price Sets' - AFTER `contribution_type_id`, -ADD `is_reserved` TINYINT(4) DEFAULT '0' - COMMENT 'Is this a predefined system price set (i.e. it can not be deleted, edited)?'; - -SELECT @contribution_type_id := max(id) FROM `civicrm_contribution_type` WHERE `name` = 'Member Dues'; -INSERT INTO `civicrm_price_set` ( `name`, {localize field='title'}`title`{/localize}, `is_active`, `extends`, `is_quick_config`, `is_reserved`, `contribution_type_id`) -VALUES ( 'default_contribution_amount', {localize}'Contribution Amount'{/localize}, '1', '2', '1', '1', null), - ( 'default_membership_type_amount', {localize}'Membership Amount'{/localize}, '1', '3', '1', '1', @contribution_type_id); - -SELECT @setID := max(id) FROM civicrm_price_set WHERE name = 'default_contribution_amount' AND extends = 2 AND is_quick_config = 1 ; - -INSERT INTO `civicrm_price_field` (`price_set_id`, `name`, {localize field='label'}`label`{/localize}, `html_type`,`weight`, `is_display_amounts`, `options_per_line`, `is_active`, `is_required`,`visibility_id` ) -VALUES ( @setID, 'contribution_amount', {localize}'Contribution Amount'{/localize}, 'Text', '1', '1', '1', '1', '1', '1' ); - -SELECT @fieldID := max(id) FROM civicrm_price_field WHERE name = 'contribution_amount' AND price_set_id = @setID; - -INSERT INTO `civicrm_price_field_value` ( `price_field_id`, `name`, {localize field='label'}`label`{/localize}, `amount`, `weight`, `is_default`, `is_active`) -VALUES ( @fieldID, 'contribution_amount', {localize}'Contribution Amount'{/localize}, '1', '1', '0', '1'); -ALTER TABLE `civicrm_custom_group` CHANGE `extends_entity_column_value` `extends_entity_column_value` VARCHAR( 255 ) CHARACTER SET utf8 COLLATE utf8_unicode_ci NULL DEFAULT NULL COMMENT 'linking custom group for dynamic object.'; - --- CRM-9714 create price fields for all membershiptype -SELECT @setID := max(id) FROM civicrm_price_set WHERE name = 'default_membership_type_amount' AND extends = 3 AND is_quick_config = 1 ; - -INSERT INTO civicrm_price_field ( price_set_id, name, {localize field='label'}label{/localize}, html_type, is_display_amounts, is_required ) -SELECT @setID as price_set_id, cmt.member_of_contact_id as name, {localize}'Membership Amount'{/localize}, 'Radio' as html_type, 0 as is_display_amounts, 0 as is_required -FROM `civicrm_membership_type` cmt -GROUP BY cmt.member_of_contact_id; - -INSERT INTO civicrm_price_field_value ( price_field_id, name, {localize field='label'}label{/localize}, {localize field='description'}description{/localize}, amount, membership_type_id) -SELECT -cpf.id, cmt.name{$loc} as label1, {localize field='name'}cmt.name as label2{/localize},{localize field='description'}cmt.description{/localize}, cmt.minimum_fee, cmt.id -FROM `civicrm_membership_type` cmt -LEFT JOIN civicrm_price_field cpf ON cmt.member_of_contact_id = BINARY cpf.name; - --- CRM-9714 -SELECT @fieldID := cpf.id, @fieldValueID := cpfv.id FROM civicrm_price_set cps -LEFT JOIN civicrm_price_field cpf ON cps.id = cpf.price_set_id -LEFT JOIN civicrm_price_field_value cpfv ON cpf.id = cpfv.price_field_id -WHERE cps.name = 'default_contribution_amount'; - -INSERT INTO civicrm_line_item ( entity_table, entity_id, price_field_id, label, qty, unit_price, line_total, participant_count, price_field_value_id ) -SELECT 'civicrm_contribution', cc.id, @fieldID, 'Contribution Amount', 1, total_amount, total_amount , 0, @fieldValueID -FROM `civicrm_contribution` cc -LEFT JOIN civicrm_line_item cli ON cc.id=cli.entity_id and cli.entity_table = 'civicrm_contribution' -LEFT JOIN civicrm_membership_payment cmp ON cc.id = cmp.contribution_id -LEFT JOIN civicrm_participant_payment cpp ON cc.id = cpp.contribution_id -WHERE cli.entity_id IS NULL AND cc.contribution_page_id IS NULL AND cmp.contribution_id IS NULL AND cpp.contribution_id IS NULL -GROUP BY cc.id; - --- CRM-10071 contribution membership detail report template -SELECT @option_group_id_report := MAX(id) FROM civicrm_option_group WHERE name = 'report_template'; -SELECT @weight := MAX(weight) FROM civicrm_option_value WHERE option_group_id = @option_group_id_report; -SELECT @memberCompId := max(id) FROM civicrm_component where name = 'CiviMember'; -INSERT INTO civicrm_option_value - (option_group_id, {localize field='label'}label{/localize}, value, name, weight, {localize field='description'}description{/localize}, is_active, component_id) VALUES - (@option_group_id_report, {localize}'Contribution and Membership Details'{/localize}, 'member/contributionDetail', 'CRM_Report_Form_Member_ContributionDetail', @weight := @weight + 1, {localize}'Contribution details for any type of contribution, plus associated membership information for contributions which are in payment for memberships.'{/localize}, 1, @memberCompId); - -INSERT INTO `civicrm_report_instance` - ( `domain_id`, `title`, `report_id`, `description`, `permission`, `form_values`) -VALUES - ( {$domainID}, 'Contribution and Membership Details', 'member/contributionDetail', 'Contribution details for any type of contribution, plus associated membership information for contributions which are in payment for memberships.', 'access CiviMember', '{literal}a:67:{s:6:"fields";a:12:{s:9:"sort_name";s:1:"1";s:5:"email";s:1:"1";s:5:"phone";s:1:"1";s:20:"contribution_type_id";s:1:"1";s:12:"receive_date";s:1:"1";s:12:"total_amount";s:1:"1";s:18:"membership_type_id";s:1:"1";s:21:"membership_start_date";s:1:"1";s:19:"membership_end_date";s:1:"1";s:9:"join_date";s:1:"1";s:22:"membership_status_name";s:1:"1";s:10:"country_id";s:1:"1";}s:12:"sort_name_op";s:3:"has";s:15:"sort_name_value";s:0:"";s:6:"id_min";s:0:"";s:6:"id_max";s:0:"";s:5:"id_op";s:3:"lte";s:8:"id_value";s:0:"";s:21:"receive_date_relative";s:1:"0";s:17:"receive_date_from";s:0:"";s:15:"receive_date_to";s:0:"";s:23:"contribution_type_id_op";s:2:"in";s:26:"contribution_type_id_value";a:0:{}s:24:"payment_instrument_id_op";s:2:"in";s:27:"payment_instrument_id_value";a:0:{}s:25:"contribution_status_id_op";s:2:"in";s:28:"contribution_status_id_value";a:0:{}s:16:"total_amount_min";s:0:"";s:16:"total_amount_max";s:0:"";s:15:"total_amount_op";s:3:"lte";s:18:"total_amount_value";s:0:"";s:6:"gid_op";s:2:"in";s:9:"gid_value";a:0:{}s:13:"ordinality_op";s:2:"in";s:16:"ordinality_value";a:0:{}s:18:"join_date_relative";s:1:"0";s:14:"join_date_from";s:0:"";s:12:"join_date_to";s:0:"";s:30:"membership_start_date_relative";s:1:"0";s:26:"membership_start_date_from";s:0:"";s:24:"membership_start_date_to";s:0:"";s:28:"membership_end_date_relative";s:1:"0";s:24:"membership_end_date_from";s:0:"";s:22:"membership_end_date_to";s:0:"";s:23:"owner_membership_id_min";s:0:"";s:23:"owner_membership_id_max";s:0:"";s:22:"owner_membership_id_op";s:3:"lte";s:25:"owner_membership_id_value";s:0:"";s:6:"tid_op";s:2:"in";s:9:"tid_value";a:0:{}s:6:"sid_op";s:2:"in";s:9:"sid_value";a: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:12:"county_id_op";s:2:"in";s:15:"county_id_value";a: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:8:"tagid_op";s:2:"in";s:11:"tagid_value";a:0:{}s:11:"description";s:35:"Contribution and Membership Details";s:13:"email_subject";s:0:"";s:8:"email_to";s:0:"";s:8:"email_cc";s:0:"";s:10:"permission";s:17:"access CiviMember";s:9:"domain_id";i:1;}{s:6:"fields";a:12:{s:9:"sort_name";s:1:"1";s:5:"email";s:1:"1";s:5:"phone";s:1:"1";s:20:"contribution_type_id";s:1:"1";s:12:"receive_date";s:1:"1";s:12:"total_amount";s:1:"1";s:18:"membership_type_id";s:1:"1";s:21:"membership_start_date";s:1:"1";s:19:"membership_end_date";s:1:"1";s:9:"join_date";s:1:"1";s:22:"membership_status_name";s:1:"1";s:10:"country_id";s:1:"1";}s:12:"sort_name_op";s:3:"has";s:15:"sort_name_value";s:0:"";s:6:"id_min";s:0:"";s:6:"id_max";s:0:"";s:5:"id_op";s:3:"lte";s:8:"id_value";s:0:"";s:21:"receive_date_relative";s:1:"0";s:17:"receive_date_from";s:0:"";s:15:"receive_date_to";s:0:"";s:23:"contribution_type_id_op";s:2:"in";s:26:"contribution_type_id_value";a:0:{}s:24:"payment_instrument_id_op";s:2:"in";s:27:"payment_instrument_id_value";a:0:{}s:25:"contribution_status_id_op";s:2:"in";s:28:"contribution_status_id_value";a:0:{}s:16:"total_amount_min";s:0:"";s:16:"total_amount_max";s:0:"";s:15:"total_amount_op";s:3:"lte";s:18:"total_amount_value";s:0:"";s:6:"gid_op";s:2:"in";s:9:"gid_value";a:0:{}s:13:"ordinality_op";s:2:"in";s:16:"ordinality_value";a:0:{}s:18:"join_date_relative";s:1:"0";s:14:"join_date_from";s:0:"";s:12:"join_date_to";s:0:"";s:30:"membership_start_date_relative";s:1:"0";s:26:"membership_start_date_from";s:0:"";s:24:"membership_start_date_to";s:0:"";s:28:"membership_end_date_relative";s:1:"0";s:24:"membership_end_date_from";s:0:"";s:22:"membership_end_date_to";s:0:"";s:23:"owner_membership_id_min";s:0:"";s:23:"owner_membership_id_max";s:0:"";s:22:"owner_membership_id_op";s:3:"lte";s:25:"owner_membership_id_value";s:0:"";s:6:"tid_op";s:2:"in";s:9:"tid_value";a:0:{}s:6:"sid_op";s:2:"in";s:9:"sid_value";a: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:12:"county_id_op";s:2:"in";s:15:"county_id_value";a: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:8:"tagid_op";s:2:"in";s:11:"tagid_value";a:0:{}s:11:"description";s:35:"Contribution and Membership Details";s:13:"email_subject";s:0:"";s:8:"email_to";s:0:"";s:8:"email_cc";s:0:"";s:10:"permission";s:1:"0";s:9:"domain_id";i:1;}{/literal}'); - -SELECT @reportlastID := MAX(id) FROM civicrm_navigation where name = 'Reports' AND domain_id = {$domainID}; -SELECT @nav_max_weight := MAX(ROUND(weight)) from civicrm_navigation WHERE parent_id = @reportlastID; - -SET @instanceID:=LAST_INSERT_ID(); -INSERT INTO civicrm_navigation - ( domain_id, url, label, name, permission, permission_operator, parent_id, is_active, has_separator, weight ) -VALUES - ( {$domainID}, CONCAT('civicrm/report/instance/', @instanceID,'&reset=1'), '{ts escape="sql" skip="true"}Contribution and Membership Details{/ts}', 'Contribution and Membership Details', 'access CiviMember', 'AND', @reportlastID, '1', NULL, @instanceID+2 ); -UPDATE civicrm_report_instance SET navigation_id = LAST_INSERT_ID() WHERE id = @instanceID; - --- CRM-9936 -ALTER TABLE civicrm_group ADD is_reserved TINYINT( 4 ) NULL DEFAULT '0' ; - --- CRM-9501 price set report templates -SELECT @option_group_id_report := MAX(id) FROM civicrm_option_group WHERE name = 'report_template'; -SELECT @weight := MAX(weight) FROM civicrm_option_value WHERE option_group_id = @option_group_id_report; -SELECT @CompId := MAX(id) FROM civicrm_component where name = 'CiviContribute'; -INSERT INTO civicrm_option_value - (option_group_id, {localize field='label'}label{/localize}, value, name, weight, {localize field='description'}description{/localize}, is_active, component_id) VALUES - (@option_group_id_report, {localize}'Line Item Report'{/localize}, 'price/lineitem', 'CRM_Report_Form_Price_Lineitem', @weight := @weight + 1, {localize}'Price set report by line item.'{/localize}, 1, @CompId); -SELECT @weight := MAX(weight) FROM civicrm_option_value WHERE option_group_id = @option_group_id_report; -INSERT INTO civicrm_option_value - (option_group_id, {localize field='label'}label{/localize}, value, name, weight, {localize field='description'}description{/localize}, is_active, component_id) VALUES - (@option_group_id_report, {localize}'Contribution Report with Line Item information'{/localize}, 'price/contributionbased', 'CRM_Report_Form_Price_Contributionbased', @weight := @weight + 1, {localize}'Contribution Line Item Report.'{/localize}, 1, @CompId); -SELECT @weight := MAX(weight) FROM civicrm_option_value WHERE option_group_id = @option_group_id_report; -INSERT INTO civicrm_option_value - (option_group_id, {localize field='label'}label{/localize}, value, name, weight, {localize field='description'}description{/localize}, is_active, component_id) VALUES - (@option_group_id_report, {localize}'Participant Report with Line Item information'{/localize}, 'price/lineitemparticipant', 'CRM_Report_Form_Price_Lineitemparticipant', @weight := @weight + 1, {localize}'Participant Line Item Report.'{/localize}, 1, @CompId); - --- CRM-10148 -ALTER TABLE civicrm_report_instance ADD is_reserved TINYINT( 4 ) NULL DEFAULT '0' ; - --- CRM-9438 -SELECT @option_group_id_act := MAX(id) FROM civicrm_option_group WHERE name = 'activity_type'; -SELECT @max_val := MAX(ROUND(op.value)) FROM civicrm_option_value op WHERE op.option_group_id = @option_group_id_act; -SELECT @max_wt := MAX(weight) FROM civicrm_option_value WHERE option_group_id = @option_group_id_act; -SELECT @CompId := MAX(id) FROM civicrm_component where name = 'CiviMember'; -INSERT INTO civicrm_option_value - (option_group_id, {localize field='label'}label{/localize}, value, name, weight, {localize field='description'}description{/localize}, is_active, is_reserved, component_id) -VALUES - (@option_group_id_act, {localize field='label'}'Change Membership Status'{/localize}, (SELECT @max_val := @max_val+1), 'Change Membership Status', (SELECT @max_wt := @max_wt+1), {localize field='description'}'Change Membership Status.'{/localize}, 1, 1, @CompId), - (@option_group_id_act, {localize field='label'}'Change Membership Type'{/localize}, (SELECT @max_val := @max_val+1), 'Change Membership Type', (SELECT @max_wt := @max_wt+1), {localize field='description'}'Change Membership Type.'{/localize}, 1, 1, @CompId); - --- CRM-10084 -INSERT INTO - `civicrm_option_value` (`option_group_id`, {localize field='label'}`label`{/localize}, `value`, `name`, `grouping`, `filter`, `is_default`, `weight`, {localize field='description'}`description`{/localize}, `is_optgroup`, `is_reserved`, `is_active`, `component_id`, `visibility_id`) -VALUES - (@option_group_id_act, {localize}'Cancel Recurring Contribution'{/localize}, (SELECT @max_val := @max_val+1), 'Cancel Recurring Contribution', NULL,1, 0, (SELECT @max_wt := @max_wt+1), {localize}''{/localize}, 0, 1, 1, NULL, NULL); - --- CRM-10090 -INSERT INTO - `civicrm_option_value` (`option_group_id`, {localize field='label'}`label`{/localize}, `value`, `name`, `grouping`, `filter`, `is_default`, `weight`, {localize field='description'}`description`{/localize}, `is_optgroup`, `is_reserved`, `is_active`, `component_id`, `visibility_id`) -VALUES -(@option_group_id_act, {localize}'Update Recurring Contribution Billing Details'{/localize}, (SELECT @max_val := @max_val+1), 'Update Recurring Contribution Billing Details', NULL,1, 0, (SELECT @max_wt := @max_wt+1), {localize}''{/localize}, 0, 1, 1, NULL, NULL), -(@option_group_id_act, {localize}'Update Recurring Contribution'{/localize}, (SELECT @max_val := @max_val+1), 'Update Recurring Contribution', NULL,1, 0, (SELECT @max_wt := @max_wt+1), {localize}''{/localize}, 0, 1, 1, NULL, NULL); - --- CRM-10117 -ALTER TABLE `civicrm_price_field_value` CHANGE `is_active` `is_active` TINYINT( 4 ) NULL DEFAULT '1' COMMENT 'Is this price field value active'; - - --- CRM-8359 -INSERT INTO - `civicrm_action_mapping` (`entity`, `entity_value`, `entity_value_label`, `entity_status`, `entity_status_label`, `entity_date_start`, `entity_date_end`, `entity_recipient`) VALUES - ('civicrm_membership', 'civicrm_membership_type', 'Membership Type', 'auto_renew_options', 'Auto Renew Options', 'membership_join_date', 'membership_end_date', NULL); - -INSERT INTO - `civicrm_option_group` (`name`, {localize field='title'}title{/localize}, `is_reserved`, `is_active`) -VALUES - ('auto_renew_options', {localize}'Auto Renew Options'{/localize}, 1, 1); - -SELECT @option_group_id_aro := max(id) from civicrm_option_group where name = 'auto_renew_options'; - -INSERT INTO - `civicrm_option_value` (`option_group_id`, {localize field='label'}label{/localize}, `value`, `name`, `grouping`, `filter`, `is_default`, `weight`) -VALUES - (@option_group_id_aro, {localize}'Renewal Reminder (non-auto-renew memberships only)'{/localize}, 1, 'Renewal Reminder (non-auto-renew memberships only)', NULL, 0, 0, 1), - (@option_group_id_aro, {localize}'Auto-renew Memberships Only'{/localize}, 2, 'Auto-renew Memberships Only', NULL, 0, 0, 2), - (@option_group_id_aro, {localize}'Reminder for Both'{/localize}, 3, 'Reminder for Both', NULL, 0, 0, 3); - --- CRM-10335, truncate cache to begin to speed the alter table -TRUNCATE civicrm_cache; -ALTER TABLE civicrm_cache - DROP INDEX UI_group_path, - ADD UNIQUE INDEX `UI_group_path_date` (`group_name`, `path`, `created_date`); - --- CRM-10337 -ALTER TABLE civicrm_survey - ADD COLUMN bypass_confirm tinyint(4) DEFAULT '0' COMMENT 'Used to store option group id.'; diff --git a/civicrm/CRM/Upgrade/Incremental/sql/4.2.alpha2.mysql.tpl b/civicrm/CRM/Upgrade/Incremental/sql/4.2.alpha2.mysql.tpl deleted file mode 100644 index a70e5eb7be..0000000000 --- a/civicrm/CRM/Upgrade/Incremental/sql/4.2.alpha2.mysql.tpl +++ /dev/null @@ -1,9 +0,0 @@ -{include file='../CRM/Upgrade/4.2.alpha2.msg_template/civicrm_msg_template.tpl'} - --- CRM-10326 -DELETE FROM `civicrm_price_set_entity` WHERE entity_table = "civicrm_contribution" or entity_table = "civicrm_participant"; - --- When deleting saved searches, null-out references from groups -ALTER TABLE civicrm_group ADD CONSTRAINT `FK_civicrm_group_saved_search_id` - FOREIGN KEY (`saved_search_id`) REFERENCES `civicrm_saved_search` (`id`) - ON DELETE SET NULL; diff --git a/civicrm/CRM/Upgrade/Incremental/sql/4.2.alpha3.mysql.tpl b/civicrm/CRM/Upgrade/Incremental/sql/4.2.alpha3.mysql.tpl deleted file mode 100644 index ab390796cc..0000000000 --- a/civicrm/CRM/Upgrade/Incremental/sql/4.2.alpha3.mysql.tpl +++ /dev/null @@ -1,2 +0,0 @@ -{include file='../CRM/Upgrade/4.2.alpha3.msg_template/civicrm_msg_template.tpl'} - diff --git a/civicrm/CRM/Upgrade/Incremental/sql/4.2.beta1.mysql.tpl b/civicrm/CRM/Upgrade/Incremental/sql/4.2.beta1.mysql.tpl deleted file mode 100644 index 1d461f5f04..0000000000 --- a/civicrm/CRM/Upgrade/Incremental/sql/4.2.beta1.mysql.tpl +++ /dev/null @@ -1,37 +0,0 @@ --- /******************************************************* --- * CRM-10477 - Extensions updates --- *******************************************************/ -CREATE TABLE `civicrm_extension` ( - `id` int unsigned NOT NULL AUTO_INCREMENT COMMENT 'Local Extension ID', - `type` enum('payment', 'search', 'report', 'module') NOT NULL , - `full_name` varchar(255) NOT NULL COMMENT 'Fully qualified extension name', - `name` varchar(255) COMMENT 'Short name', - `label` varchar(255) COMMENT 'Short, printable name', - `file` varchar(255) COMMENT 'Primary PHP file', - `schema_version` varchar(63) COMMENT 'Revision code of the database schema; the format is module-defined', - `is_active` tinyint DEFAULT 1 COMMENT 'Is this extension active?' , - PRIMARY KEY ( `id` ) , - UNIQUE INDEX `UI_extension_full_name`( - `full_name` - ), - INDEX `UI_extension_name`( - `name` - ) -) ENGINE=InnoDB DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci; - --- assuming first value of array $locales is always en_US -{if $multilingual} - INSERT INTO civicrm_extension (label, full_name, name, type, file, is_active) - SELECT ov.label_{$locales.0}, ov.value, ov.name, ov.grouping, ov.description_{$locales.0}, ov.is_active - FROM civicrm_option_group og - INNER JOIN civicrm_option_value ov ON og.id = ov.option_group_id - WHERE og.name = "system_extensions"; -{else} - INSERT INTO civicrm_extension (label, full_name, name, type, file, is_active) - SELECT ov.label, ov.value, ov.name, ov.grouping, ov.description, ov.is_active - FROM civicrm_option_group og - INNER JOIN civicrm_option_value ov ON og.id = ov.option_group_id - WHERE og.name = "system_extensions"; -{/if} -DELETE FROM civicrm_option_group WHERE name = "system_extensions"; --- Note: Deletion cascades to civicrm_option_value diff --git a/civicrm/CRM/Upgrade/Incremental/sql/4.2.beta2.mysql.tpl b/civicrm/CRM/Upgrade/Incremental/sql/4.2.beta2.mysql.tpl deleted file mode 100644 index b7bddf40e9..0000000000 --- a/civicrm/CRM/Upgrade/Incremental/sql/4.2.beta2.mysql.tpl +++ /dev/null @@ -1 +0,0 @@ --- Placeholder which ensures that PHP upgrade tasks are executed diff --git a/civicrm/CRM/Upgrade/Incremental/sql/4.2.beta3.mysql.tpl b/civicrm/CRM/Upgrade/Incremental/sql/4.2.beta3.mysql.tpl deleted file mode 100644 index 47a5a52e39..0000000000 --- a/civicrm/CRM/Upgrade/Incremental/sql/4.2.beta3.mysql.tpl +++ /dev/null @@ -1,2 +0,0 @@ -{include file='../CRM/Upgrade/4.2.beta3.msg_template/civicrm_msg_template.tpl'} - diff --git a/civicrm/CRM/Upgrade/Incremental/sql/4.2.beta5.mysql.tpl b/civicrm/CRM/Upgrade/Incremental/sql/4.2.beta5.mysql.tpl deleted file mode 100644 index b7bddf40e9..0000000000 --- a/civicrm/CRM/Upgrade/Incremental/sql/4.2.beta5.mysql.tpl +++ /dev/null @@ -1 +0,0 @@ --- Placeholder which ensures that PHP upgrade tasks are executed diff --git a/civicrm/CRM/Upgrade/Incremental/sql/4.2.beta6.mysql.tpl b/civicrm/CRM/Upgrade/Incremental/sql/4.2.beta6.mysql.tpl deleted file mode 100644 index 5151adf155..0000000000 --- a/civicrm/CRM/Upgrade/Incremental/sql/4.2.beta6.mysql.tpl +++ /dev/null @@ -1,23 +0,0 @@ --- FIXME: the final release version is uncertain -- could 4.2.0 or 4.2.1; make sure this fixed before merging --- CRM-10660 -CREATE TABLE `civicrm_managed` ( - - - `id` int unsigned NOT NULL AUTO_INCREMENT COMMENT 'Surrogate Key', - `module` varchar(127) NOT NULL COMMENT 'Name of the module which declared this object', - `name` varchar(127) COMMENT 'Symbolic name used by the module to identify the object', - `entity_type` varchar(64) NOT NULL COMMENT 'API entity type', - `entity_id` int unsigned NOT NULL COMMENT 'Foreign key to the referenced item.', - PRIMARY KEY ( `id` ) - - , INDEX `UI_managed_module_name`( - `module` - , `name` - ) - , INDEX `UI_managed_entity`( - `entity_type` - , `entity_id` - ) - - -) ENGINE=InnoDB DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ; diff --git a/civicrm/CRM/Upgrade/Incremental/sql/4.7.30.mysql.tpl b/civicrm/CRM/Upgrade/Incremental/sql/4.7.30.mysql.tpl index bd097d6381..e9a748170c 100644 --- a/civicrm/CRM/Upgrade/Incremental/sql/4.7.30.mysql.tpl +++ b/civicrm/CRM/Upgrade/Incremental/sql/4.7.30.mysql.tpl @@ -12,5 +12,5 @@ INSERT INTO civicrm_mailing_bounce_pattern (bounce_type_id, pattern) VALUES (@bo -- CRM-21532 Add French state/departments SELECT @country_id := id from civicrm_country where name = 'France' AND iso_code = 'FR'; -INSERT INTO `civicrm_state_province` (`id`, `country_id`, `abbreviation`, `name`) VALUES +INSERT IGNORE INTO `civicrm_state_province` (`id`, `country_id`, `abbreviation`, `name`) VALUES (NULL, @country_id, "52", "Haute-Marne"); \ No newline at end of file diff --git a/civicrm/CRM/Upgrade/Incremental/sql/4.7.32.mysql.tpl b/civicrm/CRM/Upgrade/Incremental/sql/4.7.32.mysql.tpl index 08267008b5..b542246f42 100644 --- a/civicrm/CRM/Upgrade/Incremental/sql/4.7.32.mysql.tpl +++ b/civicrm/CRM/Upgrade/Incremental/sql/4.7.32.mysql.tpl @@ -2,7 +2,7 @@ -- CRM-21837 - Missing states for Gabon SELECT @country_id := id from civicrm_country where name = 'Gabon' AND iso_code = 'GA'; -INSERT INTO `civicrm_state_province` (`id`, `country_id`, `abbreviation`, `name`) VALUES +INSERT IGNORE INTO `civicrm_state_province` (`id`, `country_id`, `abbreviation`, `name`) VALUES (NULL, @country_id, "01", "Estuaire"), (NULL, @country_id, "02", "Haut-Ogooué"), (NULL, @country_id, "03", "Moyen-Ogooué"), diff --git a/civicrm/CRM/Upgrade/Incremental/sql/5.12.0.mysql.tpl b/civicrm/CRM/Upgrade/Incremental/sql/5.12.0.mysql.tpl new file mode 100644 index 0000000000..06c6fde0d0 --- /dev/null +++ b/civicrm/CRM/Upgrade/Incremental/sql/5.12.0.mysql.tpl @@ -0,0 +1 @@ +{* file to handle db changes in 5.12.0 during upgrade *} diff --git a/civicrm/CRM/Upgrade/Incremental/sql/5.12.alpha1.mysql.tpl b/civicrm/CRM/Upgrade/Incremental/sql/5.12.alpha1.mysql.tpl new file mode 100644 index 0000000000..7b8066485b --- /dev/null +++ b/civicrm/CRM/Upgrade/Incremental/sql/5.12.alpha1.mysql.tpl @@ -0,0 +1,396 @@ +{* file to handle db changes in 5.12.alpha1 during upgrade *} + +-- dev/core#683 Incorrectly encoded state and country names +UPDATE civicrm_country SET name = 'Ã…land Islands' WHERE iso_code = 'AX'; +UPDATE civicrm_country SET name = 'Côte d’Ivoire' WHERE iso_code = 'CI'; +UPDATE civicrm_country SET name = 'Curaçao' WHERE iso_code = 'CW'; +UPDATE civicrm_country SET name = 'Saint Barthélemy' WHERE iso_code = 'BL'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'dolnoÅ›lÄ…skie' WHERE iso_code = 'PL' AND abbreviation = 'DS'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'łódzkie' WHERE iso_code = 'PL' AND abbreviation = 'LD'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'maÅ‚opolskie' WHERE iso_code = 'PL' AND abbreviation = 'MA'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Å›lÄ…skie' WHERE iso_code = 'PL' AND abbreviation = 'SL'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Å›wiÄ™tokrzyskie' WHERE iso_code = 'PL' AND abbreviation = 'SK'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'warmiÅ„sko-mazurskie' WHERE iso_code = 'PL' AND abbreviation = 'WN'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Bulqizë' WHERE iso_code = 'AL' AND abbreviation = 'BU'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Delvinë' WHERE iso_code = 'AL' AND abbreviation = 'DL'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Dibër' WHERE iso_code = 'AL' AND abbreviation = 'DI'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Durrës' WHERE iso_code = 'AL' AND abbreviation = 'DR'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Gjirokastër' WHERE iso_code = 'AL' AND abbreviation = 'GJ'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Kavajë' WHERE iso_code = 'AL' AND abbreviation = 'KA'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Kolonjë' WHERE iso_code = 'AL' AND abbreviation = 'ER'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Korçë' WHERE iso_code = 'AL' AND abbreviation = 'KO'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Krujë' WHERE iso_code = 'AL' AND abbreviation = 'KR'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Kuçovë' WHERE iso_code = 'AL' AND abbreviation = 'KC'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Kukës' WHERE iso_code = 'AL' AND abbreviation = 'KU'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Lezhë' WHERE iso_code = 'AL' AND abbreviation = 'LE'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Lushnjë' WHERE iso_code = 'AL' AND abbreviation = 'LU'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Malësi e Madhe' WHERE iso_code = 'AL' AND abbreviation = 'MM'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Mallakastër' WHERE iso_code = 'AL' AND abbreviation = 'MK'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Mirditë' WHERE iso_code = 'AL' AND abbreviation = 'MR'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Përmet' WHERE iso_code = 'AL' AND abbreviation = 'PR'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Pukë' WHERE iso_code = 'AL' AND abbreviation = 'PU'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Sarandë' WHERE iso_code = 'AL' AND abbreviation = 'SR'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Shkodër' WHERE iso_code = 'AL' AND abbreviation = 'SH'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Tepelenë' WHERE iso_code = 'AL' AND abbreviation = 'TE'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Tiranë' WHERE iso_code = 'AL' AND abbreviation = 'TR'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Tropojë' WHERE iso_code = 'AL' AND abbreviation = 'TP'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Vlorë' WHERE iso_code = 'AL' AND abbreviation = 'VL'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Kärnten' WHERE iso_code = 'AT' AND abbreviation = '2'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Niederösterreich' WHERE iso_code = 'AT' AND abbreviation = '3'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Oberösterreich' WHERE iso_code = 'AT' AND abbreviation = '4'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Brèsckaja voblasc\'' WHERE iso_code = 'BY' AND abbreviation = 'BR'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Mahilëuskaja voblasc\'' WHERE iso_code = 'BY' AND abbreviation = 'MA'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Distrito Capital de Bogotá' WHERE iso_code = 'CO' AND abbreviation = 'DC'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Atlántico' WHERE iso_code = 'CO' AND abbreviation = 'ATL'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'BolÃvar' WHERE iso_code = 'CO' AND abbreviation = 'BOL'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Boyacá' WHERE iso_code = 'CO' AND abbreviation = 'BOY'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Caquetá' WHERE iso_code = 'CO' AND abbreviation = 'CAQ'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Córdoba' WHERE iso_code = 'CO' AND abbreviation = 'COR'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Chocó' WHERE iso_code = 'CO' AND abbreviation = 'CHO'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'GuainÃa' WHERE iso_code = 'CO' AND abbreviation = 'GUA'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Nariño' WHERE iso_code = 'CO' AND abbreviation = 'NAR'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'San Andrés, Providencia y Santa Catalina' WHERE iso_code = 'CO' AND abbreviation = 'SAP'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Vaupés' WHERE iso_code = 'CO' AND abbreviation = 'VAU'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'JihoÄeský kraj' WHERE iso_code = 'CZ' AND abbreviation = 'JC'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Jihomoravský kraj' WHERE iso_code = 'CZ' AND abbreviation = 'JM'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Karlovarský kraj' WHERE iso_code = 'CZ' AND abbreviation = 'KA'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Královéhradecký kraj' WHERE iso_code = 'CZ' AND abbreviation = 'KR'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Liberecký kraj' WHERE iso_code = 'CZ' AND abbreviation = 'LI'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Moravskoslezský kraj' WHERE iso_code = 'CZ' AND abbreviation = 'MO'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Olomoucký kraj' WHERE iso_code = 'CZ' AND abbreviation = 'OL'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Pardubický kraj' WHERE iso_code = 'CZ' AND abbreviation = 'PA'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Plzeňský kraj' WHERE iso_code = 'CZ' AND abbreviation = 'PL'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Praha, hlavnà mÄ›sto' WHERE iso_code = 'CZ' AND abbreviation = 'PR'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'StÅ™edoÄeský kraj' WHERE iso_code = 'CZ' AND abbreviation = 'ST'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Ústecký kraj' WHERE iso_code = 'CZ' AND abbreviation = 'US'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'VysoÄina' WHERE iso_code = 'CZ' AND abbreviation = 'VY'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'ZlÃnský kraj' WHERE iso_code = 'CZ' AND abbreviation = 'ZL'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Baden-Württemberg' WHERE iso_code = 'DE' AND abbreviation = 'BW'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Thüringen' WHERE iso_code = 'DE' AND abbreviation = 'TH'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Vestsjælland' WHERE iso_code = 'DK' AND abbreviation = '030'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Storstrøm' WHERE iso_code = 'DK' AND abbreviation = '035'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Ringkjøbing' WHERE iso_code = 'DK' AND abbreviation = '065'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Ã…rhus' WHERE iso_code = 'DK' AND abbreviation = '070'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Dajabón' WHERE iso_code = 'DO' AND abbreviation = '05'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Maroia Trinidad Sánchez' WHERE iso_code = 'DO' AND abbreviation = '14'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Monseñor Nouel' WHERE iso_code = 'DO' AND abbreviation = '28'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Samaná' WHERE iso_code = 'DO' AND abbreviation = '20'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'San Cristóbal' WHERE iso_code = 'DO' AND abbreviation = '21'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'San Pedro de MacorÃs' WHERE iso_code = 'DO' AND abbreviation = '23'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Sánchez RamÃrez' WHERE iso_code = 'DO' AND abbreviation = '24'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Santiago RodrÃguez' WHERE iso_code = 'DO' AND abbreviation = '26'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Jõgevamaa' WHERE iso_code = 'EE' AND abbreviation = '49'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Järvamaa' WHERE iso_code = 'EE' AND abbreviation = '51'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Läänemaa' WHERE iso_code = 'EE' AND abbreviation = '57'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Lääne-Virumaa' WHERE iso_code = 'EE' AND abbreviation = '59'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Põlvamaa' WHERE iso_code = 'EE' AND abbreviation = '65'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Pärnumaa' WHERE iso_code = 'EE' AND abbreviation = '67'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Võrumaa' WHERE iso_code = 'EE' AND abbreviation = '86'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Ãlava' WHERE iso_code = 'ES' AND abbreviation = 'VI'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'AlmerÃa' WHERE iso_code = 'ES' AND abbreviation = 'AL'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Ãvila' WHERE iso_code = 'ES' AND abbreviation = 'AV'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Cáceres' WHERE iso_code = 'ES' AND abbreviation = 'CC'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Cádiz' WHERE iso_code = 'ES' AND abbreviation = 'CA'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Castellón' WHERE iso_code = 'ES' AND abbreviation = 'CS'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Guipúzcoa' WHERE iso_code = 'ES' AND abbreviation = 'SS'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Jaén' WHERE iso_code = 'ES' AND abbreviation = 'J'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'La Coruña' WHERE iso_code = 'ES' AND abbreviation = 'C'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'León' WHERE iso_code = 'ES' AND abbreviation = 'LE'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Lleida [Lérida]' WHERE iso_code = 'ES' AND abbreviation = 'L'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Málaga' WHERE iso_code = 'ES' AND abbreviation = 'MA'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Ardèche' WHERE iso_code = 'FR' AND abbreviation = '07'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Ariège' WHERE iso_code = 'FR' AND abbreviation = '09'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Bouches-du-Rhône' WHERE iso_code = 'FR' AND abbreviation = '13'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Corrèze' WHERE iso_code = 'FR' AND abbreviation = '19'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Côte-d\'Or' WHERE iso_code = 'FR' AND abbreviation = '21'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Côtes-d\'Armor' WHERE iso_code = 'FR' AND abbreviation = '22'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Deux-Sèvres' WHERE iso_code = 'FR' AND abbreviation = '79'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Drôme' WHERE iso_code = 'FR' AND abbreviation = '26'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Finistère' WHERE iso_code = 'FR' AND abbreviation = '29'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Haute-Saône' WHERE iso_code = 'FR' AND abbreviation = '70'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Hautes-Pyrénées' WHERE iso_code = 'FR' AND abbreviation = '65'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Hérault' WHERE iso_code = 'FR' AND abbreviation = '34'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Isère' WHERE iso_code = 'FR' AND abbreviation = '38'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Lozère' WHERE iso_code = 'FR' AND abbreviation = '48'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Nièvre' WHERE iso_code = 'FR' AND abbreviation = '58'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Puy-de-Dôme' WHERE iso_code = 'FR' AND abbreviation = '63'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Pyrénées-Atlantiques' WHERE iso_code = 'FR' AND abbreviation = '64'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Pyrénées-Orientales' WHERE iso_code = 'FR' AND abbreviation = '66'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Rhône' WHERE iso_code = 'FR' AND abbreviation = '69'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Saône-et-Loire' WHERE iso_code = 'FR' AND abbreviation = '71'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Vendée' WHERE iso_code = 'FR' AND abbreviation = '85'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Achaïa' WHERE iso_code = 'GR' AND abbreviation = '13'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Sololá' WHERE iso_code = 'GT' AND abbreviation = 'SO'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Bács-Kiskun' WHERE iso_code = 'HU' AND abbreviation = 'BK'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Békés' WHERE iso_code = 'HU' AND abbreviation = 'BE'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Borsod-Abaúj-Zemplén' WHERE iso_code = 'HU' AND abbreviation = 'BZ'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Csongrád' WHERE iso_code = 'HU' AND abbreviation = 'CS'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Fejér' WHERE iso_code = 'HU' AND abbreviation = 'FE'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'GyÅ‘r-Moson-Sopron' WHERE iso_code = 'HU' AND abbreviation = 'GS'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Jász-Nagykun-Szolnok' WHERE iso_code = 'HU' AND abbreviation = 'JN'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Komárom-Esztergom' WHERE iso_code = 'HU' AND abbreviation = 'KE'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Nográd' WHERE iso_code = 'HU' AND abbreviation = 'NO'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Szabolcs-Szatmár-Bereg' WHERE iso_code = 'HU' AND abbreviation = 'SZ'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Veszprém' WHERE iso_code = 'HU' AND abbreviation = 'VE'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Békéscsaba' WHERE iso_code = 'HU' AND abbreviation = 'BC'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Dunaújváros' WHERE iso_code = 'HU' AND abbreviation = 'DU'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'GyÅ‘r' WHERE iso_code = 'HU' AND abbreviation = 'GY'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'HódmezÅ‘vásárhely' WHERE iso_code = 'HU' AND abbreviation = 'HV'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Kaposvár' WHERE iso_code = 'HU' AND abbreviation = 'KV'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Kecskemét' WHERE iso_code = 'HU' AND abbreviation = 'KM'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Nyiregyháza' WHERE iso_code = 'HU' AND abbreviation = 'NY'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Pécs' WHERE iso_code = 'HU' AND abbreviation = 'PS'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Salgótarján' WHERE iso_code = 'HU' AND abbreviation = 'ST'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Székesfehérvár' WHERE iso_code = 'HU' AND abbreviation = 'SF'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Szekszárd' WHERE iso_code = 'HU' AND abbreviation = 'SS'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Tatabánya' WHERE iso_code = 'HU' AND abbreviation = 'TB'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Forlì-Cesena' WHERE iso_code = 'IT' AND abbreviation = 'FC'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'KlaipÄ—dos Apskritis' WHERE iso_code = 'LT' AND abbreviation = 'KL'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'MarijampolÄ—s Apskritis' WHERE iso_code = 'LT' AND abbreviation = 'MR'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Panevėžio Apskritis' WHERE iso_code = 'LT' AND abbreviation = 'PN'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Å iaulių Apskritis' WHERE iso_code = 'LT' AND abbreviation = 'SA'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'TauragÄ—s Apskritis' WHERE iso_code = 'LT' AND abbreviation = 'TA'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'TelÅ¡ių Apskritis' WHERE iso_code = 'LT' AND abbreviation = 'TE'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'JÅ«rmala' WHERE iso_code = 'LV' AND abbreviation = 'JUR'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'LiepÄja' WHERE iso_code = 'LV' AND abbreviation = 'LPX'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'RÄ“zekne' WHERE iso_code = 'LV' AND abbreviation = 'REZ'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'RÄ«ga' WHERE iso_code = 'LV' AND abbreviation = 'RIX'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'AjdÄbiyÄ' WHERE iso_code = 'LY' AND abbreviation = 'AJ'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Al BuÅ£nÄn' WHERE iso_code = 'LY' AND abbreviation = 'BU'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Al HizÄm al Akhdar' WHERE iso_code = 'LY' AND abbreviation = 'HZ'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Al JifÄrah' WHERE iso_code = 'LY' AND abbreviation = 'JI'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Al QaÅ£rÅ«n' WHERE iso_code = 'LY' AND abbreviation = 'QT'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Al WÄhah' WHERE iso_code = 'LY' AND abbreviation = 'WA'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'An NuqaÅ£ al Khams' WHERE iso_code = 'LY' AND abbreviation = 'NQ'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Ash ShÄÅ£i\'' WHERE iso_code = 'LY' AND abbreviation = 'SH'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Az ZÄwiyah' WHERE iso_code = 'LY' AND abbreviation = 'ZA'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'BanghÄzÄ«' WHERE iso_code = 'LY' AND abbreviation = 'BA'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'BanÄ« WalÄ«d' WHERE iso_code = 'LY' AND abbreviation = 'BW'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'GhadÄmis' WHERE iso_code = 'LY' AND abbreviation = 'GD'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'GharyÄn' WHERE iso_code = 'LY' AND abbreviation = 'GR'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'GhÄt' WHERE iso_code = 'LY' AND abbreviation = 'GT'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'JaghbÅ«b' WHERE iso_code = 'LY' AND abbreviation = 'JB'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'MiÅŸrÄtah' WHERE iso_code = 'LY' AND abbreviation = 'MI'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'NÄlÅ«t' WHERE iso_code = 'LY' AND abbreviation = 'NL'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'SabhÄ' WHERE iso_code = 'LY' AND abbreviation = 'SB'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'ÅžabrÄtah ÅžurmÄn' WHERE iso_code = 'LY' AND abbreviation = 'SS'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'TÄjÅ«rÄ\' wa an NawÄhÄ« al ArbÄh' WHERE iso_code = 'LY' AND abbreviation = 'TN'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Å¢arÄbulus' WHERE iso_code = 'LY' AND abbreviation = 'TB'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'TarhÅ«nah-MasallÄtah' WHERE iso_code = 'LY' AND abbreviation = 'TM'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'WÄdÄ« al hayÄt' WHERE iso_code = 'LY' AND abbreviation = 'WD'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Yafran-JÄdÅ«' WHERE iso_code = 'LY' AND abbreviation = 'YJ'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Aït Baha' WHERE iso_code = 'MA' AND abbreviation = 'BAH'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Aït Melloul' WHERE iso_code = 'MA' AND abbreviation = 'MEL'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Al Hoceïma' WHERE iso_code = 'MA' AND abbreviation = 'HOC'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Casablanca [Dar el Beïda]' WHERE iso_code = 'MA' AND abbreviation = 'CAS'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Fès' WHERE iso_code = 'MA' AND abbreviation = 'FES'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Kénitra' WHERE iso_code = 'MA' AND abbreviation = 'KEN'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Laâyoune (EH)' WHERE iso_code = 'MA' AND abbreviation = 'LAA'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Meknsès' WHERE iso_code = 'MA' AND abbreviation = 'MEK'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Rabat-Salé' WHERE iso_code = 'MA' AND abbreviation = 'RBA'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Tétouan' WHERE iso_code = 'MA' AND abbreviation = 'TET'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Møre og Romsdal' WHERE iso_code = 'NO' AND abbreviation = '15'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Nord-Trøndelag' WHERE iso_code = 'NO' AND abbreviation = '17'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Sør-Trøndelag' WHERE iso_code = 'NO' AND abbreviation = '16'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Østfold' WHERE iso_code = 'NO' AND abbreviation = '01'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'ArgeÈ™' WHERE iso_code = 'RO' AND abbreviation = 'AG'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Bacău' WHERE iso_code = 'RO' AND abbreviation = 'BC'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'BistriÈ›a-Năsăud' WHERE iso_code = 'RO' AND abbreviation = 'BN'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'BotoÈ™ani' WHERE iso_code = 'RO' AND abbreviation = 'BT'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'BraÈ™ov' WHERE iso_code = 'RO' AND abbreviation = 'BV'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Brăila' WHERE iso_code = 'RO' AND abbreviation = 'BR'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Buzău' WHERE iso_code = 'RO' AND abbreviation = 'BZ'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'CaraÈ™-Severin' WHERE iso_code = 'RO' AND abbreviation = 'CS'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'CălăraÈ™i' WHERE iso_code = 'RO' AND abbreviation = 'CL'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'ConstanÈ›a' WHERE iso_code = 'RO' AND abbreviation = 'CT'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'DâmboviÈ›a' WHERE iso_code = 'RO' AND abbreviation = 'DB'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'GalaÈ›i' WHERE iso_code = 'RO' AND abbreviation = 'GL'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'IalomiÈ›a' WHERE iso_code = 'RO' AND abbreviation = 'IL'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'IaÈ™i' WHERE iso_code = 'RO' AND abbreviation = 'IS'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'MaramureÈ™' WHERE iso_code = 'RO' AND abbreviation = 'MM'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'MehedinÈ›i' WHERE iso_code = 'RO' AND abbreviation = 'MH'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'MureÈ™' WHERE iso_code = 'RO' AND abbreviation = 'MS'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'NeamÈ›' WHERE iso_code = 'RO' AND abbreviation = 'NT'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Sălaj' WHERE iso_code = 'RO' AND abbreviation = 'SJ'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'TimiÈ™' WHERE iso_code = 'RO' AND abbreviation = 'TM'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Vâlcea' WHERE iso_code = 'RO' AND abbreviation = 'VL'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Blekinge län' WHERE iso_code = 'SE' AND abbreviation = 'K'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Dalarnas län' WHERE iso_code = 'SE' AND abbreviation = 'W'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Gotlands län' WHERE iso_code = 'SE' AND abbreviation = 'I'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Gävleborgs län' WHERE iso_code = 'SE' AND abbreviation = 'X'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Hallands län' WHERE iso_code = 'SE' AND abbreviation = 'N'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Jämtlands län' WHERE iso_code = 'SE' AND abbreviation = 'Z'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Jönkopings län' WHERE iso_code = 'SE' AND abbreviation = 'F'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Kalmar län' WHERE iso_code = 'SE' AND abbreviation = 'H'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Kronobergs län' WHERE iso_code = 'SE' AND abbreviation = 'G'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Norrbottens län' WHERE iso_code = 'SE' AND abbreviation = 'BD'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'SkÃ¥ne län' WHERE iso_code = 'SE' AND abbreviation = 'M'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Stockholms län' WHERE iso_code = 'SE' AND abbreviation = 'AB'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Södermanlands län' WHERE iso_code = 'SE' AND abbreviation = 'D'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Uppsala län' WHERE iso_code = 'SE' AND abbreviation = 'C'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Värmlands län' WHERE iso_code = 'SE' AND abbreviation = 'S'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Västerbottens län' WHERE iso_code = 'SE' AND abbreviation = 'AC'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Västernorrlands län' WHERE iso_code = 'SE' AND abbreviation = 'Y'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Västmanlands län' WHERE iso_code = 'SE' AND abbreviation = 'U'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Västra Götalands län' WHERE iso_code = 'SE' AND abbreviation = 'Q'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Örebro län' WHERE iso_code = 'SE' AND abbreviation = 'T'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Östergötlands län' WHERE iso_code = 'SE' AND abbreviation = 'E'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'AjdovÅ¡Äina' WHERE iso_code = 'SI' AND abbreviation = '001'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'BraslovÄe' WHERE iso_code = 'SI' AND abbreviation = '151'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Brežice' WHERE iso_code = 'SI' AND abbreviation = '009'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'ÄŒrenÅ¡ovci' WHERE iso_code = 'SI' AND abbreviation = '015'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'ÄŒrna na KoroÅ¡kem' WHERE iso_code = 'SI' AND abbreviation = '016'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'ÄŒrnomelj' WHERE iso_code = 'SI' AND abbreviation = '017'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'DivaÄa' WHERE iso_code = 'SI' AND abbreviation = '019'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Domžale' WHERE iso_code = 'SI' AND abbreviation = '023'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'GoriÅ¡nica' WHERE iso_code = 'SI' AND abbreviation = '028'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'HoÄe-Slivnica' WHERE iso_code = 'SI' AND abbreviation = '160'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'HodoÅ¡' WHERE iso_code = 'SI' AND abbreviation = '161'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'IvanÄna Gorica' WHERE iso_code = 'SI' AND abbreviation = '039'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'JurÅ¡inci' WHERE iso_code = 'SI' AND abbreviation = '042'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'KidriÄevo' WHERE iso_code = 'SI' AND abbreviation = '045'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'KoÄevje' WHERE iso_code = 'SI' AND abbreviation = '048'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Križevci' WHERE iso_code = 'SI' AND abbreviation = '166'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'KrÅ¡ko' WHERE iso_code = 'SI' AND abbreviation = '054'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'LaÅ¡ko' WHERE iso_code = 'SI' AND abbreviation = '057'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'LoÅ¡ka dolina' WHERE iso_code = 'SI' AND abbreviation = '065'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'LoÅ¡ki Potok' WHERE iso_code = 'SI' AND abbreviation = '066'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'LuÄe' WHERE iso_code = 'SI' AND abbreviation = '067'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'MajÅ¡perk' WHERE iso_code = 'SI' AND abbreviation = '069'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'MengeÅ¡' WHERE iso_code = 'SI' AND abbreviation = '072'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Mežica' WHERE iso_code = 'SI' AND abbreviation = '074'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Miklavž na Dravskem polju' WHERE iso_code = 'SI' AND abbreviation = '169'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Mirna PeÄ' WHERE iso_code = 'SI' AND abbreviation = '170'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'MoravÄe' WHERE iso_code = 'SI' AND abbreviation = '077'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Sveti Andraž v Slovenskih goricah' WHERE iso_code = 'SI' AND abbreviation = '182'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Å alovci' WHERE iso_code = 'SI' AND abbreviation = '033'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Å empeter-Vrtojba' WHERE iso_code = 'SI' AND abbreviation = '183'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Å enÄur' WHERE iso_code = 'SI' AND abbreviation = '117'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Å entilj' WHERE iso_code = 'SI' AND abbreviation = '118'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Å entjernej' WHERE iso_code = 'SI' AND abbreviation = '119'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Å entjur' WHERE iso_code = 'SI' AND abbreviation = '120'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Å kocjan' WHERE iso_code = 'SI' AND abbreviation = '121'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Å kofja Loka' WHERE iso_code = 'SI' AND abbreviation = '122'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Å kofljica' WHERE iso_code = 'SI' AND abbreviation = '123'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Å marje pri JelÅ¡ah' WHERE iso_code = 'SI' AND abbreviation = '124'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Å martno ob Paki' WHERE iso_code = 'SI' AND abbreviation = '125'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Å martno pri Litiji' WHERE iso_code = 'SI' AND abbreviation = '194'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Å oÅ¡tanj' WHERE iso_code = 'SI' AND abbreviation = '126'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Å tore' WHERE iso_code = 'SI' AND abbreviation = '127'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'TiÅ¡ina' WHERE iso_code = 'SI' AND abbreviation = '010'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'TržiÄ' WHERE iso_code = 'SI' AND abbreviation = '131'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'TurniÅ¡Äe' WHERE iso_code = 'SI' AND abbreviation = '132'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Velike LaÅ¡Äe' WHERE iso_code = 'SI' AND abbreviation = '134'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Veržej' WHERE iso_code = 'SI' AND abbreviation = '188'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'ZavrÄ' WHERE iso_code = 'SI' AND abbreviation = '143'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'ZreÄe' WHERE iso_code = 'SI' AND abbreviation = '144'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Žalec' WHERE iso_code = 'SI' AND abbreviation = '190'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Železniki' WHERE iso_code = 'SI' AND abbreviation = '146'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Žetale' WHERE iso_code = 'SI' AND abbreviation = '191'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Žiri' WHERE iso_code = 'SI' AND abbreviation = '147'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Žirovnica' WHERE iso_code = 'SI' AND abbreviation = '192'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Žužemberk' WHERE iso_code = 'SI' AND abbreviation = '193'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Banskobystrický kraj' WHERE iso_code = 'SK' AND abbreviation = 'BC'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Bratislavský kraj' WHERE iso_code = 'SK' AND abbreviation = 'BL'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'KoÅ¡ický kraj' WHERE iso_code = 'SK' AND abbreviation = 'KI'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'PreÅ¡ovský kraj' WHERE iso_code = 'SK' AND abbreviation = 'PV'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'TrenÄiansky kraj' WHERE iso_code = 'SK' AND abbreviation = 'TC'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Trnavský kraj' WHERE iso_code = 'SK' AND abbreviation = 'TA'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Žilinský kraj' WHERE iso_code = 'SK' AND abbreviation = 'ZI'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Béja' WHERE iso_code = 'TN' AND abbreviation = '31'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Gabès' WHERE iso_code = 'TN' AND abbreviation = '81'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Etelä-Savo' WHERE iso_code = 'FI' AND abbreviation = 'ES'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Häme' WHERE iso_code = 'FI' AND abbreviation = 'HH'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Itä-Uusimaa' WHERE iso_code = 'FI' AND abbreviation = 'IU'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Päijät-Häme' WHERE iso_code = 'FI' AND abbreviation = 'PH'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Ã…land' WHERE iso_code = 'FI' AND abbreviation = 'AL'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Al ManÄmah (Al ‘Āşimah)' WHERE iso_code = 'BH' AND abbreviation = '13'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Al JanÅ«bÄ«yah' WHERE iso_code = 'BH' AND abbreviation = '14'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Al Wusţá' WHERE iso_code = 'BH' AND abbreviation = '16'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Ash ShamÄlÄ«yah' WHERE iso_code = 'BH' AND abbreviation = '17'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Córdoba' WHERE iso_code = 'ES' AND abbreviation = 'CO'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Pļaviņu novads' WHERE iso_code = 'LV' AND abbreviation = '072'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'SkrÄ«veru novads' WHERE iso_code = 'LV' AND abbreviation = '092'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'AlÅ«ksnes novads' WHERE iso_code = 'LV' AND abbreviation = '007'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Viļakas novads' WHERE iso_code = 'LV' AND abbreviation = '108'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'RugÄju novads' WHERE iso_code = 'LV' AND abbreviation = '082'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'RundÄles novads' WHERE iso_code = 'LV' AND abbreviation = '083'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'CÄ“su novads' WHERE iso_code = 'LV' AND abbreviation = '022'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'LÄ«gatnes novads' WHERE iso_code = 'LV' AND abbreviation = '055'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Priekuļu novads' WHERE iso_code = 'LV' AND abbreviation = '075'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'PÄrgaujas novads' WHERE iso_code = 'LV' AND abbreviation = '070'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'IlÅ«kstes novads' WHERE iso_code = 'LV' AND abbreviation = '036'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'TÄ“rvetes novads' WHERE iso_code = 'LV' AND abbreviation = '098'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'JÄ“kabpils novads' WHERE iso_code = 'LV' AND abbreviation = '042'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'AknÄ«stes novads' WHERE iso_code = 'LV' AND abbreviation = '004'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'ViesÄ«tes novads' WHERE iso_code = 'LV' AND abbreviation = '107'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'KrÄslavas novads' WHERE iso_code = 'LV' AND abbreviation = '047'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'KuldÄ«gas novads' WHERE iso_code = 'LV' AND abbreviation = '050'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Grobiņas novads' WHERE iso_code = 'LV' AND abbreviation = '032'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'PÄvilostas novads' WHERE iso_code = 'LV' AND abbreviation = '071'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'NÄ«cas novads' WHERE iso_code = 'LV' AND abbreviation = '066'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Vaiņodes novads' WHERE iso_code = 'LV' AND abbreviation = '100'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Limbažu novads' WHERE iso_code = 'LV' AND abbreviation = '054'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'SalacgrÄ«vas novads' WHERE iso_code = 'LV' AND abbreviation = '086'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'KÄrsavas novads' WHERE iso_code = 'LV' AND abbreviation = '044'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'LubÄnas novads' WHERE iso_code = 'LV' AND abbreviation = '057'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'VarakļÄnu novads' WHERE iso_code = 'LV' AND abbreviation = '102'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Ä’rgļu novads' WHERE iso_code = 'LV' AND abbreviation = '030'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'IkÅ¡Ä·iles novads' WHERE iso_code = 'LV' AND abbreviation = '035'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Ķeguma novads' WHERE iso_code = 'LV' AND abbreviation = '051'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'LielvÄrdes novads' WHERE iso_code = 'LV' AND abbreviation = '053'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Preiļu novads' WHERE iso_code = 'LV' AND abbreviation = '073'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'LÄ«vÄnu novads' WHERE iso_code = 'LV' AND abbreviation = '056'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Riebiņu novads' WHERE iso_code = 'LV' AND abbreviation = '078'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'VÄrkavas novads' WHERE iso_code = 'LV' AND abbreviation = '103'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'RÄ“zeknes novads' WHERE iso_code = 'LV' AND abbreviation = '077'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'ViļÄnu novads' WHERE iso_code = 'LV' AND abbreviation = '109'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Ķekavas novads' WHERE iso_code = 'LV' AND abbreviation = '052'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'InÄukalna novads' WHERE iso_code = 'LV' AND abbreviation = '037'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Ä€dažu novads' WHERE iso_code = 'LV' AND abbreviation = '011'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'BabÄ«tes novads' WHERE iso_code = 'LV' AND abbreviation = '012'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'MÄlpils novads' WHERE iso_code = 'LV' AND abbreviation = '061'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'MÄrupes novads' WHERE iso_code = 'LV' AND abbreviation = '062'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Ropažu novads' WHERE iso_code = 'LV' AND abbreviation = '080'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'SÄ“jas novads' WHERE iso_code = 'LV' AND abbreviation = '090'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Stopiņu novads' WHERE iso_code = 'LV' AND abbreviation = '095'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'BrocÄ“nu novads' WHERE iso_code = 'LV' AND abbreviation = '018'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'MÄ“rsraga novads' WHERE iso_code = 'LV' AND abbreviation = '063'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'StrenÄu novads' WHERE iso_code = 'LV' AND abbreviation = '096'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'KocÄ“nu novads' WHERE iso_code = 'LV' AND abbreviation = '045'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'RÅ«jienas novads' WHERE iso_code = 'LV' AND abbreviation = '084'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'BeverÄ«nas novads' WHERE iso_code = 'LV' AND abbreviation = '017'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'NaukÅ¡Ä“nu novads' WHERE iso_code = 'LV' AND abbreviation = '064'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'JÄ“kabpils' WHERE iso_code = 'LV' AND abbreviation = 'JKB'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'ApaÄe' WHERE iso_code = 'SI' AND abbreviation = '87'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Ormož' WHERE iso_code = 'SI' AND abbreviation = '97'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'PodÄetrtek' WHERE iso_code = 'SI' AND abbreviation = '102'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'PoljÄane' WHERE iso_code = 'SI' AND abbreviation = '105'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'RaÄe-Fram' WHERE iso_code = 'SI' AND abbreviation = '113'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'RadeÄe' WHERE iso_code = 'SI' AND abbreviation = '114'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Ravne na KoroÅ¡kem' WHERE iso_code = 'SI' AND abbreviation = '171'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Razkrižje' WHERE iso_code = 'SI' AND abbreviation = '172'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'ReÄica ob Savinji' WHERE iso_code = 'SI' AND abbreviation = '173'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'RenÄe-Vogrsko' WHERE iso_code = 'SI' AND abbreviation = '174'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'RogaÅ¡ka Slatina' WHERE iso_code = 'SI' AND abbreviation = '177'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'RogaÅ¡ovci' WHERE iso_code = 'SI' AND abbreviation = '178'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'RuÅ¡e' WHERE iso_code = 'SI' AND abbreviation = '180'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'SemiÄ' WHERE iso_code = 'SI' AND abbreviation = '196'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Å entrupert' WHERE iso_code = 'SI' AND abbreviation = '197'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Sežana' WHERE iso_code = 'SI' AND abbreviation = '199'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Å marjeÅ¡ke Toplice' WHERE iso_code = 'SI' AND abbreviation = '203'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Sodražica' WHERE iso_code = 'SI' AND abbreviation = '204'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'SolÄava' WHERE iso_code = 'SI' AND abbreviation = '205'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'SrediÅ¡Äe ob Dravi' WHERE iso_code = 'SI' AND abbreviation = '206'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'StarÅ¡e' WHERE iso_code = 'SI' AND abbreviation = '207'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Straža' WHERE iso_code = 'SI' AND abbreviation = '208'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Sveti Tomaž' WHERE iso_code = 'SI' AND abbreviation = '211'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'La Réunion' WHERE iso_code = 'FR' AND abbreviation = 'RE'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Nohiyahoi Tobei JumhurÃ' WHERE iso_code = 'TJ' AND abbreviation = 'RA'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Nouvelle-Calédonie' WHERE iso_code = 'FR' AND abbreviation = 'NC'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Haut-Ogooué' WHERE iso_code = 'GA' AND abbreviation = '02'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Moyen-Ogooué' WHERE iso_code = 'GA' AND abbreviation = '03'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Ngounié' WHERE iso_code = 'GA' AND abbreviation = '04'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Ogooué-Ivindo' WHERE iso_code = 'GA' AND abbreviation = '06'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Ogooué-Lolo' WHERE iso_code = 'GA' AND abbreviation = '07'; +UPDATE civicrm_state_province INNER JOIN civicrm_country ON civicrm_state_province.country_id = civicrm_country.id SET civicrm_state_province.name = 'Ogooué-Maritime' WHERE iso_code = 'GA' AND abbreviation = '08'; diff --git a/civicrm/CRM/Upgrade/Incremental/sql/5.12.beta1.mysql.tpl b/civicrm/CRM/Upgrade/Incremental/sql/5.12.beta1.mysql.tpl new file mode 100644 index 0000000000..ff319ed9f0 --- /dev/null +++ b/civicrm/CRM/Upgrade/Incremental/sql/5.12.beta1.mysql.tpl @@ -0,0 +1 @@ +{* file to handle db changes in 5.12.beta1 during upgrade *} diff --git a/civicrm/CRM/Upgrade/Snapshot/V4p2/Price/BAO/Field.php b/civicrm/CRM/Upgrade/Snapshot/V4p2/Price/BAO/Field.php deleted file mode 100644 index 0944c4a59e..0000000000 --- a/civicrm/CRM/Upgrade/Snapshot/V4p2/Price/BAO/Field.php +++ /dev/null @@ -1,634 +0,0 @@ -<?php -/* - +--------------------------------------------------------------------+ - | CiviCRM version 5 | - +--------------------------------------------------------------------+ - | Copyright CiviCRM LLC (c) 2004-2019 | - +--------------------------------------------------------------------+ - | This file is a part of CiviCRM. | - | | - | CiviCRM is free software; you can copy, modify, and distribute it | - | under the terms of the GNU Affero General Public License | - | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. | - | | - | CiviCRM is distributed in the hope that it will be useful, but | - | WITHOUT ANY WARRANTY; without even the implied warranty of | - | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | - | See the GNU Affero General Public License for more details. | - | | - | You should have received a copy of the GNU Affero General Public | - | License and the CiviCRM Licensing Exception along | - | with this program; if not, contact CiviCRM LLC | - | at info[AT]civicrm[DOT]org. If you have questions about the | - | GNU Affero General Public License or the licensing of CiviCRM, | - | see the CiviCRM license FAQ at http://civicrm.org/licensing | - +--------------------------------------------------------------------+ - */ - -/** - * - * @package CRM - * @copyright CiviCRM LLC (c) 2004-2019 - */ - -/** - * Business objects for managing price fields. - */ -class CRM_Upgrade_Snapshot_V4p2_Price_BAO_Field extends CRM_Upgrade_Snapshot_V4p2_Price_DAO_Field { - - protected $_options; - - /** - * Takes an associative array and creates a price field object. - * - * the function extract all the params it needs to initialize the create a - * price field object. the params array could contain additional unused name/value - * pairs - * - * @param array $params - * (reference ) an assoc array of name/value pairs. - * - * @return CRM_Upgrade_Snapshot_V4p2_Price_BAO_Field - */ - public static function &add(&$params) { - $priceFieldBAO = new CRM_Upgrade_Snapshot_V4p2_Price_BAO_Field(); - - $priceFieldBAO->copyValues($params); - - if ($id = CRM_Utils_Array::value('id', $params)) { - $priceFieldBAO->id = $id; - } - - $priceFieldBAO->save(); - return $priceFieldBAO; - } - - /** - * Takes an associative array and creates a price field object. - * - * This function is invoked from within the web form layer and also from the api layer - * - * @param array $params - * (reference) an assoc array of name/value pairs. - * - * @return CRM_Upgrade_Snapshot_V4p2_Price_DAO_Field - */ - public static function create(&$params) { - - $transaction = new CRM_Core_Transaction(); - - $priceField = self::add($params); - - if (is_a($priceField, 'CRM_Core_Error')) { - $transaction->rollback(); - return $priceField; - } - - $options = $optionsIds = array(); - $maxIndex = CRM_Price_Form_Field::NUM_OPTION; - - if ($priceField->html_type == 'Text') { - $maxIndex = 1; - - $fieldValue = new CRM_Upgrade_Snapshot_V4p2_Price_DAO_FieldValue(); - $fieldValue->price_field_id = $priceField->id; - - // update previous field values( if any ) - if ($fieldValue->find(TRUE)) { - $optionsIds['id'] = $fieldValue->id; - } - } - $defaultArray = array(); - if ($params['html_type'] == 'CheckBox' && isset($params['default_checkbox_option'])) { - $tempArray = array_keys($params['default_checkbox_option']); - foreach ($tempArray as $v) { - if ($params['option_amount'][$v]) { - $defaultArray[$v] = 1; - } - } - } - else { - if (!empty($params['default_option'])) { - $defaultArray[$params['default_option']] = 1; - } - } - - for ($index = 1; $index <= $maxIndex; $index++) { - - if (array_key_exists('option_amount', $params) && - array_key_exists($index, $params['option_amount']) && - (CRM_Utils_Array::value($index, CRM_Utils_Array::value('option_label', $params)) || !empty($params['is_quick_config'])) && - !CRM_Utils_System::isNull($params['option_amount'][$index]) - ) { - $options = array( - 'price_field_id' => $priceField->id, - 'label' => trim($params['option_label'][$index]), - 'name' => CRM_Utils_String::munge($params['option_label'][$index], '_', 64), - 'amount' => CRM_Utils_Rule::cleanMoney(trim($params['option_amount'][$index])), - 'count' => CRM_Utils_Array::value($index, CRM_Utils_Array::value('option_count', $params), NULL), - 'max_value' => CRM_Utils_Array::value($index, CRM_Utils_Array::value('option_max_value', $params), NULL), - 'description' => CRM_Utils_Array::value($index, CRM_Utils_Array::value('option_description', $params), NULL), - 'membership_type_id' => CRM_Utils_Array::value($index, CRM_Utils_Array::value('membership_type_id', $params), NULL), - 'weight' => $params['option_weight'][$index], - 'is_active' => 1, - 'is_default' => CRM_Utils_Array::value($params['option_weight'][$index], $defaultArray) ? $defaultArray[$params['option_weight'][$index]] : 0, - ); - - if ($opIds = CRM_Utils_Array::value('option_id', $params)) { - if ($opId = CRM_Utils_Array::value($index, $opIds)) { - $optionsIds['id'] = $opId; - } - else { - $optionsIds['id'] = NULL; - } - } - CRM_Upgrade_Snapshot_V4p2_Price_BAO_FieldValue::create($options, $optionsIds); - } - } - - $transaction->commit(); - return $priceField; - } - - /** - * Fetch object based on array of properties. - * - * @param array $params - * (reference ) an assoc array of name/value pairs. - * @param array $defaults - * (reference ) an assoc array to hold the flattened values. - * - * @return CRM_Upgrade_Snapshot_V4p2_Price_DAO_Field - */ - public static function retrieve(&$params, &$defaults) { - return CRM_Core_DAO::commonRetrieve('CRM_Upgrade_Snapshot_V4p2_Price_DAO_Field', $params, $defaults); - } - - /** - * Update the is_active flag in the db. - * - * @param int $id - * Id of the database record. - * @param bool $is_active - * Value we want to set the is_active field. - * - * @return bool - * true if we found and updated the object, else false - */ - public static function setIsActive($id, $is_active) { - return CRM_Core_DAO::setFieldValue('CRM_Upgrade_Snapshot_V4p2_Price_DAO_Field', $id, 'is_active', $is_active); - } - - /** - * Get the field title. - * - * @param int $id - * Id of field. - * - * @return string - * name - */ - public static function getTitle($id) { - return CRM_Core_DAO::getFieldValue('CRM_Upgrade_Snapshot_V4p2_Price_DAO_Field', $id, 'label'); - } - - /** - * This function for building custom fields. - * - * @param CRM_Core_Form $qf - * Form object (reference). - * @param string $elementName - * Name of the custom field. - * @param int $fieldId - * @param bool $inactiveNeeded - * @param bool $useRequired - * True if required else false. - * @param string $label - * Label for custom field. - * @param null $fieldOptions - * @param array $freezeOptions - * - * @return null - */ - public static function addQuickFormElement( - &$qf, - $elementName, - $fieldId, - $inactiveNeeded, - $useRequired = TRUE, - $label = NULL, - $fieldOptions = NULL, - $freezeOptions = array() - ) { - - $field = new CRM_Upgrade_Snapshot_V4p2_Price_DAO_Field(); - $field->id = $fieldId; - if (!$field->find(TRUE)) { - /* FIXME: failure! */ - - return NULL; - } - - $otherAmount = $qf->get('values'); - $config = CRM_Core_Config::singleton(); - $qf->assign('currencySymbol', CRM_Core_DAO::getFieldValue('CRM_Core_DAO_Currency', $config->defaultCurrency, 'symbol', 'name')); - // get currency name for price field and option attributes - $currencyName = $config->defaultCurrency; - - if (!isset($label)) { - $label = (property_exists($qf, '_membershipBlock') && !empty($qf->_membershipBlock['is_separate_payment']) && $field->name == 'contribution_amount' && empty($otherAmount['is_allow_other_amount'])) ? ts('Additional Contribution') : $field->label; - } - - if ($field->name == 'contribution_amount') { - $qf->_contributionAmount = 1; - } - - if (isset($qf->_online) && $qf->_online) { - $useRequired = FALSE; - } - - $customOption = $fieldOptions; - if (!is_array($customOption)) { - $customOption = CRM_Upgrade_Snapshot_V4p2_Price_BAO_Field::getOptions($field->id, $inactiveNeeded); - } - - //use value field. - $valueFieldName = 'amount'; - $seperator = '|'; - switch ($field->html_type) { - case 'Text': - $optionKey = key($customOption); - $count = CRM_Utils_Array::value('count', $customOption[$optionKey], ''); - $max_value = CRM_Utils_Array::value('max_value', $customOption[$optionKey], ''); - $priceVal = implode($seperator, array($customOption[$optionKey][$valueFieldName], $count, $max_value)); - - $extra = array(); - if (property_exists($qf, '_quickConfig') && $qf->_quickConfig && property_exists($qf, '_contributionAmount') && $qf->_contributionAmount) { - $qf->assign('priceset', $elementName); - $extra = array('onclick' => 'useAmountOther();'); - } - - // if separate membership payment is used with quick config priceset then change the other amount label - if (property_exists($qf, '_membershipBlock') && !empty($qf->_membershipBlock['is_separate_payment']) && $qf->_quickConfig && $field->name == 'other_amount' && !property_exists($qf, '_contributionAmount')) { - $label = ts('Additional Contribution'); - $useRequired = 0; - } - elseif (!empty($fieldOptions[$optionKey]['label'])) { - $label = $fieldOptions[$optionKey]['label']; - } - - if ($field->is_display_amounts) { - $label .= ' - '; - $label .= CRM_Utils_Money::format(CRM_Utils_Array::value($valueFieldName, $customOption[$optionKey])); - } - - $element = &$qf->add('text', $elementName, $label, - array_merge($extra, - array( - 'price' => json_encode(array($optionKey, $priceVal)), - 'size' => '4', - ) - ), - $useRequired && $field->is_required - ); - - // CRM-6902 - if (in_array($optionKey, $freezeOptions)) { - $element->freeze(); - } - - //CRM-10117 - if (property_exists($qf, '_quickConfig') && $qf->_quickConfig) { - $message = ts("Please enter a valid amount."); - $type = "money"; - } - else { - $message = ts('%1 must be an integer (whole number).', array(1 => $label)); - $type = "positiveInteger"; - } - // integers will have numeric rule applied to them. - $qf->addRule($elementName, $message, $type); - break; - - case 'Radio': - $choice = array(); - - if (property_exists($qf, '_quickConfig') && $qf->_quickConfig && property_exists($qf, '_contributionAmount') && $qf->_contributionAmount) { - $qf->assign('contriPriceset', $elementName); - } - - foreach ($customOption as $opId => $opt) { - if ($field->is_display_amounts) { - $opt['label'] = !empty($opt['label']) ? $opt['label'] . ' - ' : ''; - $opt['label'] .= CRM_Utils_Money::format($opt[$valueFieldName]); - } - $count = CRM_Utils_Array::value('count', $opt, ''); - $max_value = CRM_Utils_Array::value('max_value', $opt, ''); - $priceVal = implode($seperator, array($opt[$valueFieldName], $count, $max_value)); - $extra = array( - 'price' => json_encode(array($elementName, $priceVal)), - 'data-amount' => $opt[$valueFieldName], - 'data-currency' => $currencyName, - ); - if (property_exists($qf, '_quickConfig') && $qf->_quickConfig && $field->name == 'contribution_amount') { - $extra += array('onclick' => 'clearAmountOther();'); - } - elseif (property_exists($qf, '_quickConfig') && $qf->_quickConfig && $field->name == 'membership_amount') { - $extra += array( - 'onclick' => "return showHideAutoRenew({$opt['membership_type_id']});", - 'membership-type' => $opt['membership_type_id'], - ); - $qf->assign('membershipFieldID', $field->id); - } - $choice[$opId] = $qf->createElement('radio', NULL, '', $opt['label'], $opt['id'], $extra); - - // CRM-6902 - if (in_array($opId, $freezeOptions)) { - $choice[$opId]->freeze(); - } - } - - if (property_exists($qf, '_membershipBlock') && !empty($qf->_membershipBlock['is_separate_payment']) && $field->name == 'contribution_amount') { - $choice[] = $qf->createElement('radio', NULL, '', 'No thank you', '-1', - array( - 'onclick' => 'clearAmountOther();', - ) - ); - } - - if (!$field->is_required) { - // add "none" option - if (!empty($otherAmount['is_allow_other_amount']) && $field->name == 'contribution_amount') { - $none = ts('Other Amount'); - } - elseif (property_exists($qf, '_membershipBlock') && empty($qf->_membershipBlock['is_required']) && $field->name == 'membership_amount') { - $none = ts('No thank you'); - } - else { - $none = ts('-none-'); - } - - $choice[] = $qf->createElement('radio', NULL, '', $none, '0', - array('price' => json_encode(array($elementName, "0"))) - ); - } - - $element = &$qf->addGroup($choice, $elementName, $label); - - // make contribution field required for quick config when membership block is enabled - if (($field->name == 'contribution_amount' || $field->name == 'membership_amount') && property_exists($qf, '_membershipBlock') && !empty($qf->_membershipBlock) && !$field->is_required) { - $useRequired = $field->is_required = TRUE; - } - - if ($useRequired && $field->is_required) { - $qf->addRule($elementName, ts('%1 is a required field.', array(1 => $label)), 'required'); - } - break; - - case 'Select': - $selectOption = $allowedOptions = $priceVal = array(); - - foreach ($customOption as $opt) { - $count = CRM_Utils_Array::value('count', $opt, ''); - $max_value = CRM_Utils_Array::value('max_value', $opt, ''); - $priceVal[$opt['id']] = implode($seperator, array($opt[$valueFieldName], $count, $max_value)); - - if ($field->is_display_amounts) { - $opt['label'] .= ' - '; - $opt['label'] .= CRM_Utils_Money::format($opt[$valueFieldName]); - } - $selectOption[$opt['id']] = $opt['label']; - - if (!in_array($opt['id'], $freezeOptions)) { - $allowedOptions[] = $opt['id']; - } - } - $element = &$qf->add('select', $elementName, $label, - array('' => ts('- select -')) + $selectOption, - $useRequired && $field->is_required, - array('price' => json_encode($priceVal)) - ); - - // CRM-6902 - $button = substr($qf->controller->getButtonName(), -4); - if (!empty($freezeOptions) && $button != 'skip') { - $qf->addRule($elementName, ts('Sorry, this option is currently sold out.'), 'regex', "/" . implode('|', $allowedOptions) . "/"); - } - break; - - case 'CheckBox': - - $check = array(); - foreach ($customOption as $opId => $opt) { - $count = CRM_Utils_Array::value('count', $opt, ''); - $max_value = CRM_Utils_Array::value('max_value', $opt, ''); - $priceVal = implode($seperator, array($opt[$valueFieldName], $count, $max_value)); - - if ($field->is_display_amounts) { - $opt['label'] .= ' - '; - $opt['label'] .= CRM_Utils_Money::format($opt[$valueFieldName]); - } - $check[$opId] = &$qf->createElement('checkbox', $opt['id'], NULL, $opt['label'], - array( - 'price' => json_encode(array($opt['id'], $priceVal)), - 'data-amount' => $opt[$valueFieldName], - 'data-currency' => $currencyName, - ) - ); - - // CRM-6902 - if (in_array($opId, $freezeOptions)) { - $check[$opId]->freeze(); - } - } - $element = &$qf->addGroup($check, $elementName, $label); - if ($useRequired && $field->is_required) { - $qf->addRule($elementName, ts('%1 is a required field.', array(1 => $label)), 'required'); - } - break; - } - if (isset($qf->_online) && $qf->_online) { - $element->freeze(); - } - } - - /** - * Retrieve a list of options for the specified field. - * - * @param int $fieldId - * Price field ID. - * @param bool $inactiveNeeded - * Include inactive options. - * @param bool $reset - * Ignore stored values\. - * - * @return array - * array of options - */ - public static function getOptions($fieldId, $inactiveNeeded = FALSE, $reset = FALSE) { - static $options = array(); - - if ($reset || empty($options[$fieldId])) { - $values = array(); - CRM_Upgrade_Snapshot_V4p2_Price_BAO_FieldValue::getValues($fieldId, $values, 'weight', !$inactiveNeeded); - $options[$fieldId] = $values; - } - - return $options[$fieldId]; - } - - /** - * @param $optionLabel - * @param int $fid - * - * @return mixed - */ - public static function getOptionId($optionLabel, $fid) { - if (!$optionLabel || !$fid) { - return; - } - - $optionGroupName = "civicrm_price_field.amount.{$fid}"; - - $query = " -SELECT - option_value.id as id -FROM - civicrm_option_value option_value, - civicrm_option_group option_group -WHERE - option_group.name = %1 - AND option_group.id = option_value.option_group_id - AND option_value.label = %2"; - - $dao = CRM_Core_DAO::executeQuery($query, array( - 1 => array($optionGroupName, 'String'), - 2 => array($optionLabel, 'String'), - )); - - while ($dao->fetch()) { - return $dao->id; - } - } - - /** - * Delete the price set field. - * - * @param int $id - * Field Id. - * - * @return mixed - * Boolean-ish - */ - public static function deleteField($id) { - $field = new CRM_Upgrade_Snapshot_V4p2_Price_DAO_Field(); - $field->id = $id; - - if ($field->find(TRUE)) { - // delete the options for this field - CRM_Upgrade_Snapshot_V4p2_Price_BAO_FieldValue::deleteValues($id); - - // reorder the weight before delete - $fieldValues = array('price_set_id' => $field->price_set_id); - - CRM_Utils_Weight::delWeight('CRM_Upgrade_Snapshot_V4p2_Price_DAO_Field', $field->id, $fieldValues); - - // now delete the field - return $field->delete(); - } - - return NULL; - } - - /** - * @return array - */ - public static function &htmlTypes() { - static $htmlTypes = NULL; - if (!$htmlTypes) { - $htmlTypes = array( - 'Text' => ts('Text / Numeric Quantity'), - 'Select' => ts('Select'), - 'Radio' => ts('Radio'), - 'CheckBox' => ts('CheckBox'), - ); - } - return $htmlTypes; - } - - /** - * Validate the priceset. - * - * @param int $priceSetId - * @param array $fields - * @param array $error - */ - public static function priceSetValidation($priceSetId, $fields, &$error) { - // check for at least one positive - // amount price field should be selected. - $priceField = new CRM_Upgrade_Snapshot_V4p2_Price_DAO_Field(); - $priceField->price_set_id = $priceSetId; - $priceField->find(); - - $priceFields = array(); - - while ($priceField->fetch()) { - $key = "price_{$priceField->id}"; - if (!empty($fields[$key])) { - $priceFields[$priceField->id] = $fields[$key]; - } - } - - if (!empty($priceFields)) { - // we should has to have positive amount. - $sql = " -SELECT id, html_type -FROM civicrm_price_field -WHERE id IN (" . implode(',', array_keys($priceFields)) . ')'; - $fieldDAO = CRM_Core_DAO::executeQuery($sql); - $htmlTypes = array(); - while ($fieldDAO->fetch()) { - $htmlTypes[$fieldDAO->id] = $fieldDAO->html_type; - } - - $selectedAmounts = array(); - - foreach ($htmlTypes as $fieldId => $type) { - $options = array(); - CRM_Upgrade_Snapshot_V4p2_Price_BAO_FieldValue::getValues($fieldId, $options); - - if (empty($options)) { - - continue; - - } - - if ($type == 'Text') { - foreach ($options as $opId => $option) { - $selectedAmounts[$opId] = $priceFields[$fieldId] * $option['amount']; - break; - } - } - elseif (is_array($fields["price_{$fieldId}"])) { - foreach (array_keys($fields["price_{$fieldId}"]) as $opId) { - $selectedAmounts[$opId] = $options[$opId]['amount']; - } - } - elseif (in_array($fields["price_{$fieldId}"], array_keys($options))) { - $selectedAmounts[$fields["price_{$fieldId}"]] = $options[$fields["price_{$fieldId}"]]['amount']; - } - } - - list($componentName) = explode(':', $fields['_qf_default']); - // now we have all selected amount in hand. - $totalAmount = array_sum($selectedAmounts); - if ($totalAmount < 0) { - $error['_qf_default'] = ts('%1 amount can not be less than zero. Please select the options accordingly.', array(1 => $componentName)); - } - } - else { - $error['_qf_default'] = ts("Please select at least one option from price set."); - } - } - -} diff --git a/civicrm/CRM/Upgrade/Snapshot/V4p2/Price/BAO/FieldValue.php b/civicrm/CRM/Upgrade/Snapshot/V4p2/Price/BAO/FieldValue.php deleted file mode 100644 index 5ca834e2e1..0000000000 --- a/civicrm/CRM/Upgrade/Snapshot/V4p2/Price/BAO/FieldValue.php +++ /dev/null @@ -1,225 +0,0 @@ -<?php -/* - +--------------------------------------------------------------------+ - | CiviCRM version 5 | - +--------------------------------------------------------------------+ - | Copyright CiviCRM LLC (c) 2004-2019 | - +--------------------------------------------------------------------+ - | This file is a part of CiviCRM. | - | | - | CiviCRM is free software; you can copy, modify, and distribute it | - | under the terms of the GNU Affero General Public License | - | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. | - | | - | CiviCRM is distributed in the hope that it will be useful, but | - | WITHOUT ANY WARRANTY; without even the implied warranty of | - | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | - | See the GNU Affero General Public License for more details. | - | | - | You should have received a copy of the GNU Affero General Public | - | License and the CiviCRM Licensing Exception along | - | with this program; if not, contact CiviCRM LLC | - | at info[AT]civicrm[DOT]org. If you have questions about the | - | GNU Affero General Public License or the licensing of CiviCRM, | - | see the CiviCRM license FAQ at http://civicrm.org/licensing | - +--------------------------------------------------------------------+ - */ - -/** - * - * @package CRM - * @copyright CiviCRM LLC (c) 2004-2019 - * $Id$ - * - */ - -/** - * Business objects for managing price fields values. - * - */ -class CRM_Upgrade_Snapshot_V4p2_Price_BAO_FieldValue extends CRM_Upgrade_Snapshot_V4p2_Price_DAO_FieldValue { - - /** - * Insert/update a new entry in the database. - * - * @param array $params - * (reference), array $ids. - * - * @param $ids - * - * @return CRM_Upgrade_Snapshot_V4p2_Price_DAO_FieldValue - */ - public static function &add(&$params, $ids) { - - $fieldValueBAO = new CRM_Upgrade_Snapshot_V4p2_Price_BAO_FieldValue(); - $fieldValueBAO->copyValues($params); - - if ($id = CRM_Utils_Array::value('id', $ids)) { - $fieldValueBAO->id = $id; - } - if (!empty($params['is_default'])) { - $query = 'UPDATE civicrm_price_field_value SET is_default = 0 WHERE price_field_id = %1'; - $p = array(1 => array($params['price_field_id'], 'Integer')); - CRM_Core_DAO::executeQuery($query, $p); - } - - $fieldValueBAO->save(); - return $fieldValueBAO; - } - - /** - * Creates a new entry in the database. - * - * @param array $params - * (reference), array $ids. - * - * @param $ids - * - * @return CRM_Upgrade_Snapshot_V4p2_Price_DAO_FieldValue - */ - public static function create(&$params, $ids) { - - if (!is_array($params) || empty($params)) { - return NULL; - } - - if ($id = CRM_Utils_Array::value('id', $ids)) { - if (isset($params['name'])) { - unset($params['name']); - } - - $oldWeight = NULL; - if ($id) { - $oldWeight = CRM_Core_DAO::getFieldValue('CRM_Upgrade_Snapshot_V4p2_Price_DAO_FieldValue', $id, 'weight', 'id'); - } - - $fieldValues = array('price_field_id' => CRM_Utils_Array::value('price_field_id', $params, 0)); - $params['weight'] = CRM_Utils_Weight::updateOtherWeights('CRM_Upgrade_Snapshot_V4p2_Price_DAO_FieldValue', $oldWeight, $params['weight'], $fieldValues); - } - else { - if (empty($params['name'])) { - $params['name'] = CRM_Utils_String::munge(CRM_Utils_Array::value('label', $params), '_', 64); - } - if (empty($params['weight'])) { - $params['weight'] = 1; - } - } - $params['is_active'] = CRM_Utils_Array::value('is_active', $params, 0); - - return self::add($params, $ids); - } - - /** - * Retrieve DB object based on input parameters. - * - * It also stores all the retrieved values in the default array. - * - * @param array $params - * (reference ) an assoc array. - * @param array $defaults - * (reference ) an assoc array to hold the flattened values. - * - * @return CRM_Upgrade_Snapshot_V4p2_Price_DAO_FieldValue - */ - public static function retrieve(&$params, &$defaults) { - return CRM_Core_DAO::commonRetrieve('CRM_Upgrade_Snapshot_V4p2_Price_DAO_FieldValue', $params, $defaults); - } - - /** - * Retrive the all values for given field id. - * - * @param int $fieldId - * Price_field_id. - * @param array $values - * (reference ) to hold the values. - * @param string $orderBy - * For order by, default weight. - * @param bool|int $isActive is_active, default false - * - * @return array - * - */ - public static function getValues($fieldId, &$values, $orderBy = 'weight', $isActive = FALSE) { - $fieldValueDAO = new CRM_Upgrade_Snapshot_V4p2_Price_DAO_FieldValue(); - $fieldValueDAO->price_field_id = $fieldId; - $fieldValueDAO->orderBy($orderBy, 'label'); - if ($isActive) { - $fieldValueDAO->is_active = 1; - } - $fieldValueDAO->find(); - - while ($fieldValueDAO->fetch()) { - CRM_Core_DAO::storeValues($fieldValueDAO, $values[$fieldValueDAO->id]); - } - - return $values; - } - - /** - * Get the price field option label. - * - * @param int $id - * Id of field option. - * - * @return string - * name - * - */ - public static function getOptionLabel($id) { - return CRM_Core_DAO::getFieldValue('CRM_Upgrade_Snapshot_V4p2_Price_DAO_FieldValue', $id, 'label'); - } - - /** - * Update the is_active flag in the db. - * - * @param int $id - * Id of the database record. - * @param bool $is_active - * Value we want to set the is_active field. - * - * @return bool - * true if we found and updated the object, else false - */ - public static function setIsActive($id, $is_active) { - return CRM_Core_DAO::setFieldValue('CRM_Upgrade_Snapshot_V4p2_Price_DAO_FieldValue', $id, 'is_active', $is_active); - } - - /** - * Delete all values of the given field id. - * - * @param int $fieldId - * Price field id. - * - * @return bool - * - */ - public static function deleteValues($fieldId) { - if (!$fieldId) { - return FALSE; - } - - $fieldValueDAO = new CRM_Upgrade_Snapshot_V4p2_Price_DAO_FieldValue(); - $fieldValueDAO->price_field_id = $fieldId; - $fieldValueDAO->delete(); - } - - /** - * Delete the value. - * - * @param int $id - * Id. - * - * @return bool - * - */ - public static function del($id) { - if (!$id) { - return FALSE; - } - - $fieldValueDAO = new CRM_Upgrade_Snapshot_V4p2_Price_DAO_FieldValue(); - $fieldValueDAO->id = $id; - return $fieldValueDAO->delete(); - } - -} diff --git a/civicrm/CRM/Upgrade/Snapshot/V4p2/Price/BAO/LineItem.php b/civicrm/CRM/Upgrade/Snapshot/V4p2/Price/BAO/LineItem.php deleted file mode 100644 index c406fe5c56..0000000000 --- a/civicrm/CRM/Upgrade/Snapshot/V4p2/Price/BAO/LineItem.php +++ /dev/null @@ -1,311 +0,0 @@ -<?php -/* - +--------------------------------------------------------------------+ - | CiviCRM version 5 | - +--------------------------------------------------------------------+ - | Copyright CiviCRM LLC (c) 2004-2019 | - +--------------------------------------------------------------------+ - | This file is a part of CiviCRM. | - | | - | CiviCRM is free software; you can copy, modify, and distribute it | - | under the terms of the GNU Affero General Public License | - | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. | - | | - | CiviCRM is distributed in the hope that it will be useful, but | - | WITHOUT ANY WARRANTY; without even the implied warranty of | - | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | - | See the GNU Affero General Public License for more details. | - | | - | You should have received a copy of the GNU Affero General Public | - | License and the CiviCRM Licensing Exception along | - | with this program; if not, contact CiviCRM LLC | - | at info[AT]civicrm[DOT]org. If you have questions about the | - | GNU Affero General Public License or the licensing of CiviCRM, | - | see the CiviCRM license FAQ at http://civicrm.org/licensing | - +--------------------------------------------------------------------+ - */ - -/** - * - * @package CRM - * @copyright CiviCRM LLC (c) 2004-2019 - * $Id$ - * - */ - -/** - * - * @package CRM - * @author Marshal Newrock <marshal@idealso.com> - * $Id$ - */ - -/** - * Business objects for Line Items generated by monetary transactions - */ -class CRM_Upgrade_Snapshot_V4p2_Price_BAO_LineItem extends CRM_Upgrade_Snapshot_V4p2_Price_DAO_LineItem { - - /** - * Creates a new entry in the database. - * - * @param array $params - * (reference) an assoc array of name/value pairs. - * - * @return CRM_Upgrade_Snapshot_V4p2_Price_DAO_LineItem - */ - public static function create(&$params) { - //create mode only as we don't support editing line items - - CRM_Utils_Hook::pre('create', 'LineItem', $params['entity_id'], $params); - - $lineItemBAO = new CRM_Upgrade_Snapshot_V4p2_Price_BAO_LineItem(); - $lineItemBAO->copyValues($params); - - $return = $lineItemBAO->save(); - - CRM_Utils_Hook::post('create', 'LineItem', $params['entity_id'], $params); - - return $return; - } - - /** - * Retrieve DB object based on input parameters. - * - * It also stores all the retrieved values in the default array. - * - * @param array $params - * (reference ) an assoc array of name/value pairs. - * @param array $defaults - * (reference ) an assoc array to hold the flattened values. - * - * @return CRM_Upgrade_Snapshot_V4p2_Price_BAO_LineItem - */ - public static function retrieve(&$params, &$defaults) { - $lineItem = new CRM_Upgrade_Snapshot_V4p2_Price_BAO_LineItem(); - $lineItem->copyValues($params); - if ($lineItem->find(TRUE)) { - CRM_Core_DAO::storeValues($lineItem, $defaults); - return $lineItem; - } - return NULL; - } - - /** - * Given a participant id/contribution id, - * return contribution/fee line items - * - * @param int $entityId - * participant/contribution id. - * @param string $entity - * participant/contribution. - * - * @param null $isQuick - * - * @return array - * Array of line items - */ - public static function getLineItems($entityId, $entity = 'participant', $isQuick = NULL) { - $selectClause = $whereClause = $fromClause = NULL; - - $selectClause = " -SELECT li.id, - li.label, - li.qty, - li.unit_price, - li.line_total, - pf.label as field_title, - pf.html_type, - pfv.membership_type_id, - li.price_field_id, - li.participant_count, - li.price_field_value_id, - pfv.description"; - - $fromClause = " -FROM civicrm_%2 as %2 -LEFT JOIN civicrm_line_item li ON ( li.entity_id = %2.id AND li.entity_table = 'civicrm_%2') -LEFT JOIN civicrm_price_field_value pfv ON ( pfv.id = li.price_field_value_id ) -LEFT JOIN civicrm_price_field pf ON (pf.id = li.price_field_id )"; - $whereClause = " -WHERE %2.id = %1"; - - if ($isQuick) { - $fromClause .= " LEFT JOIN civicrm_price_set cps on cps.id = pf.price_set_id "; - $whereClause .= " and cps.is_quick_config = 0"; - } - $lineItems = array(); - - if (!$entityId || !$entity || !$fromClause) { - return $lineItems; - } - - $params = array( - 1 => array($entityId, 'Integer'), - 2 => array($entity, 'Text'), - ); - - $dao = CRM_Core_DAO::executeQuery("$selectClause $fromClause $whereClause", $params); - while ($dao->fetch()) { - if (!$dao->id) { - continue; - } - $lineItems[$dao->id] = array( - 'qty' => $dao->qty, - 'label' => $dao->label, - 'unit_price' => $dao->unit_price, - 'line_total' => $dao->line_total, - 'price_field_id' => $dao->price_field_id, - 'participant_count' => $dao->participant_count, - 'price_field_value_id' => $dao->price_field_value_id, - 'field_title' => $dao->field_title, - 'html_type' => $dao->html_type, - 'description' => $dao->description, - 'entity_id' => $entityId, - 'membership_type_id' => $dao->membership_type_id, - ); - } - return $lineItems; - } - - /** - * This method will create the lineItem array required for. - * processAmount method - * - * @param int $fid - * Price set field id. - * @param array $params - * Reference to form values. - * @param array $fields - * Reference to array of fields belonging. - * to the price set used for particular event - * @param array $values - * Reference to the values array(. - * this is lineItem array) - */ - public static function format($fid, &$params, &$fields, &$values) { - if (empty($params["price_{$fid}"])) { - return; - } - - $optionIDs = implode(',', array_keys($params["price_{$fid}"])); - - //lets first check in fun parameter, - //since user might modified w/ hooks. - $options = array(); - if (array_key_exists('options', $fields)) { - $options = $fields['options']; - } - else { - CRM_Upgrade_Snapshot_V4p2_Price_BAO_FieldValue::getValues($fid, $options, 'weight', TRUE); - } - $fieldTitle = CRM_Utils_Array::value('label', $fields); - if (!$fieldTitle) { - $fieldTitle = CRM_Core_DAO::getFieldValue('CRM_Upgrade_Snapshot_V4p2_Price_DAO_Field', $fid, 'label'); - } - - foreach ($params["price_{$fid}"] as $oid => $qty) { - $price = $options[$oid]['amount']; - - // lets clean the price in case it is not yet cleaned - // CRM-10974 - $price = CRM_Utils_Rule::cleanMoney($price); - - $participantsPerField = CRM_Utils_Array::value('count', $options[$oid], 0); - - $values[$oid] = array( - 'price_field_id' => $fid, - 'price_field_value_id' => $oid, - 'label' => CRM_Utils_Array::value('label', $options[$oid]), - 'field_title' => $fieldTitle, - 'description' => CRM_Utils_Array::value('description', $options[$oid]), - 'qty' => $qty, - 'unit_price' => $price, - 'line_total' => $qty * $price, - 'participant_count' => $qty * $participantsPerField, - 'max_value' => CRM_Utils_Array::value('max_value', $options[$oid]), - 'membership_type_id' => CRM_Utils_Array::value('membership_type_id', $options[$oid]), - 'auto_renew' => CRM_Utils_Array::value('auto_renew', $options[$oid]), - 'html_type' => $fields['html_type'], - ); - } - } - - /** - * Delete line items for given entity. - * - * @param int $entityId - * @param int $entityTable - * - * @return bool - */ - public static function deleteLineItems($entityId, $entityTable) { - $result = FALSE; - if (!$entityId || !$entityTable) { - return $result; - } - - if ($entityId && !is_array($entityId)) { - $entityId = array($entityId); - } - - $query = "DELETE FROM civicrm_line_item where entity_id IN ('" . implode("','", $entityId) . "') AND entity_table = '$entityTable'"; - $dao = CRM_Core_DAO::executeQuery($query); - return $result; - } - - /** - * @param int $entityId - * @param string $entityTable - * @param $amount - * @param array $otherParams - */ - public static function syncLineItems($entityId, $entityTable = 'civicrm_contribution', $amount, $otherParams = NULL) { - if (!$entityId || CRM_Utils_System::isNull($amount)) { - return; - } - - $from = " civicrm_line_item li -LEFT JOIN civicrm_price_field pf ON pf.id = li.price_field_id -LEFT JOIN civicrm_price_set ps ON ps.id = pf.price_set_id "; - - $set = " li.unit_price = %3, - li.line_total = %3 "; - - $where = " li.entity_id = %1 AND - li.entity_table = %2 "; - - $params = array( - 1 => array($entityId, 'Integer'), - 2 => array($entityTable, 'String'), - 3 => array($amount, 'Float'), - ); - - if ($entityTable == 'civicrm_contribution') { - $entityName = 'default_contribution_amount'; - $where .= " AND ps.name = %4 "; - $params[4] = array($entityName, 'String'); - } - elseif ($entityTable == 'civicrm_participant') { - $from .= " -LEFT JOIN civicrm_price_set_entity cpse ON cpse.price_set_id = ps.id -LEFT JOIN civicrm_price_field_value cpfv ON cpfv.price_field_id = pf.id and cpfv.label = %4 "; - $set .= " ,li.label = %4, - li.price_field_value_id = cpfv.id "; - $where .= " AND cpse.entity_table = 'civicrm_event' AND cpse.entity_id = %5 "; - $amount = empty($amount) ? 0 : $amount; - $params += array( - 4 => array($otherParams['fee_label'], 'String'), - 5 => array($otherParams['event_id'], 'String'), - ); - } - - $query = " -UPDATE $from -SET $set -WHERE $where -"; - - CRM_Core_DAO::executeQuery($query, $params); - } - -} diff --git a/civicrm/CRM/Upgrade/Snapshot/V4p2/Price/BAO/Set.php b/civicrm/CRM/Upgrade/Snapshot/V4p2/Price/BAO/Set.php deleted file mode 100644 index e5c1282896..0000000000 --- a/civicrm/CRM/Upgrade/Snapshot/V4p2/Price/BAO/Set.php +++ /dev/null @@ -1,1144 +0,0 @@ -<?php -/* - +--------------------------------------------------------------------+ - | CiviCRM version 5 | - +--------------------------------------------------------------------+ - | Copyright CiviCRM LLC (c) 2004-2019 | - +--------------------------------------------------------------------+ - | This file is a part of CiviCRM. | - | | - | CiviCRM is free software; you can copy, modify, and distribute it | - | under the terms of the GNU Affero General Public License | - | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. | - | | - | CiviCRM is distributed in the hope that it will be useful, but | - | WITHOUT ANY WARRANTY; without even the implied warranty of | - | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | - | See the GNU Affero General Public License for more details. | - | | - | You should have received a copy of the GNU Affero General Public | - | License and the CiviCRM Licensing Exception along | - | with this program; if not, contact CiviCRM LLC | - | at info[AT]civicrm[DOT]org. If you have questions about the | - | GNU Affero General Public License or the licensing of CiviCRM, | - | see the CiviCRM license FAQ at http://civicrm.org/licensing | - +--------------------------------------------------------------------+ - */ - -/** - * - * @package CRM - * @copyright CiviCRM LLC (c) 2004-2019 - */ - -/** - * Business object for managing price sets. - */ -class CRM_Upgrade_Snapshot_V4p2_Price_BAO_Set extends CRM_Upgrade_Snapshot_V4p2_Price_DAO_Set { - - /** - * Class constructor. - */ - public function __construct() { - parent::__construct(); - } - - /** - * Takes an associative array and creates a price set object. - * - * @param array $params - * (reference) an assoc array of name/value pairs. - * - * @return CRM_Upgrade_Snapshot_V4p2_Price_DAO_Set - */ - public static function create(&$params) { - $priceSetBAO = new CRM_Upgrade_Snapshot_V4p2_Price_BAO_Set(); - $priceSetBAO->copyValues($params); - if (self::eventPriceSetDomainID()) { - $priceSetBAO->domain_id = CRM_Core_Config::domainID(); - } - return $priceSetBAO->save(); - } - - /** - * Fetch object based on array of properties. - * - * @param array $params - * (reference ) an assoc array of name/value pairs. - * @param array $defaults - * (reference ) an assoc array to hold the flattened values. - * - * @return CRM_Upgrade_Snapshot_V4p2_Price_DAO_Set - */ - public static function retrieve(&$params, &$defaults) { - return CRM_Core_DAO::commonRetrieve('CRM_Upgrade_Snapshot_V4p2_Price_DAO_Set', $params, $defaults); - } - - /** - * Update the is_active flag in the db. - * - * @param int $id - * Id of the database record. - * @param bool $isActive - * Value we want to set the is_active field. - * - * @return bool - * true if we found and updated the object, else false - */ - public static function setIsActive($id, $isActive) { - return CRM_Core_DAO::setFieldValue('CRM_Upgrade_Snapshot_V4p2_Price_DAO_Set', $id, 'is_active', $isActive); - } - - /** - * Calculate the default price set id assigned to the contribution/membership etc. - * - * @param string $entity - * - * @return int - * priceSetID - */ - public static function getDefaultPriceSet($entity = 'contribution') { - if ($entity == 'contribution') { - $entityName = 'default_contribution_amount'; - } - elseif ($entity == 'membership') { - $entityName = 'default_membership_type_amount'; - } - - $sql = " -SELECT ps.id AS setID, pfv.price_field_id AS priceFieldID, pfv.id AS priceFieldValueID, pfv.name, pfv.label -FROM civicrm_price_set ps -LEFT JOIN civicrm_price_field pf ON pf.`price_set_id` = ps.id -LEFT JOIN civicrm_price_field_value pfv ON pfv.price_field_id = pf.id -WHERE ps.name = '{$entityName}' -"; - - $dao = CRM_Core_DAO::executeQuery($sql); - $defaultPriceSet = array(); - while ($dao->fetch()) { - $defaultPriceSet[$dao->priceFieldValueID]['setID'] = $dao->setID; - $defaultPriceSet[$dao->priceFieldValueID]['priceFieldID'] = $dao->priceFieldID; - $defaultPriceSet[$dao->priceFieldValueID]['name'] = $dao->name; - $defaultPriceSet[$dao->priceFieldValueID]['label'] = $dao->label; - } - - return $defaultPriceSet; - } - - /** - * Get the price set title. - * - * @param int $id - * Id of price set. - * - * @return string - * title - */ - public static function getTitle($id) { - return CRM_Core_DAO::getFieldValue('CRM_Upgrade_Snapshot_V4p2_Price_DAO_Set', $id, 'title'); - } - - /** - * Return a list of all forms which use this price set. - * - * @param int $id - * Id of price set. - * @param bool|\str $simpleReturn - get raw data. Possible values: 'entity', 'table' - * - * @return array - */ - public static function &getUsedBy($id, $simpleReturn = FALSE) { - $usedBy = $forms = $tables = array(); - $queryString = " -SELECT entity_table, entity_id -FROM civicrm_price_set_entity -WHERE price_set_id = %1"; - $params = array(1 => array($id, 'Integer')); - $crmFormDAO = CRM_Core_DAO::executeQuery($queryString, $params); - - while ($crmFormDAO->fetch()) { - $forms[$crmFormDAO->entity_table][] = $crmFormDAO->entity_id; - $tables[] = $crmFormDAO->entity_table; - } - // Return only tables - if ($simpleReturn == 'table') { - return $tables; - } - if (empty($forms)) { - $queryString = " -SELECT cli.entity_table, cli.entity_id -FROM civicrm_line_item cli -LEFT JOIN civicrm_price_field cpf ON cli.price_field_id = cpf.id -WHERE cpf.price_set_id = %1"; - $params = array(1 => array($id, 'Integer')); - $crmFormDAO = CRM_Core_DAO::executeQuery($queryString, $params); - while ($crmFormDAO->fetch()) { - $forms[$crmFormDAO->entity_table][] = $crmFormDAO->entity_id; - $tables[] = $crmFormDAO->entity_table; - } - if (empty($forms)) { - return $usedBy; - } - } - // Return only entity data - if ($simpleReturn == 'entity') { - return $forms; - } - foreach ($forms as $table => $entities) { - switch ($table) { - case 'civicrm_event': - $ids = implode(',', $entities); - $queryString = "SELECT ce.id as id, ce.title as title, ce.is_public as isPublic, ce.start_date as startDate, ce.end_date as endDate, civicrm_option_value.label as eventType -FROM civicrm_event ce -LEFT JOIN civicrm_option_value ON - ( ce.event_type_id = civicrm_option_value.value ) -LEFT JOIN civicrm_option_group ON - ( civicrm_option_group.id = civicrm_option_value.option_group_id ) -WHERE - civicrm_option_group.name = 'event_type' AND - ( ce.is_template IS NULL OR ce.is_template = 0) AND - ce.id IN ($ids) AND - ce.is_active = 1;"; - $crmDAO = CRM_Core_DAO::executeQuery($queryString); - while ($crmDAO->fetch()) { - $usedBy[$table][$crmDAO->id]['title'] = $crmDAO->title; - $usedBy[$table][$crmDAO->id]['eventType'] = $crmDAO->eventType; - $usedBy[$table][$crmDAO->id]['startDate'] = $crmDAO->startDate; - $usedBy[$table][$crmDAO->id]['endDate'] = $crmDAO->endDate; - $usedBy[$table][$crmDAO->id]['isPublic'] = $crmDAO->isPublic; - } - break; - - case 'civicrm_contribution_page': - $ids = implode(',', $entities); - $queryString = "SELECT cp.id as id, cp.title as title, cp.start_date as startDate, cp.end_date as endDate,ct.name as type -FROM civicrm_contribution_page cp, civicrm_contribution_type ct -WHERE ct.id = cp.contribution_type_id AND - cp.id IN ($ids) AND - cp.is_active = 1;"; - $crmDAO = CRM_Core_DAO::executeQuery($queryString); - while ($crmDAO->fetch()) { - $usedBy[$table][$crmDAO->id]['title'] = $crmDAO->title; - $usedBy[$table][$crmDAO->id]['type'] = $crmDAO->type; - $usedBy[$table][$crmDAO->id]['startDate'] = $crmDAO->startDate; - $usedBy[$table][$crmDAO->id]['endDate'] = $crmDAO->endDate; - } - break; - - case 'civicrm_contribution': - case 'civicrm_membership': - case 'civicrm_participant': - $usedBy[$table] = 1; - break; - - default: - CRM_Core_Error::fatal("$table is not supported in PriceSet::usedBy()"); - break; - } - } - - return $usedBy; - } - - /** - * Delete the price set. - * - * @param int $id - * Price Set id. - * - * @return bool - * false if fields exist for this set, true if the - * set could be deleted - */ - public static function deleteSet($id) { - // remove from all inactive forms - $usedBy = self::getUsedBy($id); - if (isset($usedBy['civicrm_event'])) { - foreach ($usedBy['civicrm_event'] as $eventId => $unused) { - $eventDAO = new CRM_Event_DAO_Event(); - $eventDAO->id = $eventId; - $eventDAO->find(); - while ($eventDAO->fetch()) { - self::removeFrom('civicrm_event', $eventDAO->id); - } - } - } - - // delete price fields - $priceField = new CRM_Upgrade_Snapshot_V4p2_Price_DAO_Field(); - $priceField->price_set_id = $id; - $priceField->find(); - while ($priceField->fetch()) { - // delete options first - CRM_Upgrade_Snapshot_V4p2_Price_BAO_Field::deleteField($priceField->id); - } - - $set = new CRM_Upgrade_Snapshot_V4p2_Price_DAO_Set(); - $set->id = $id; - return $set->delete(); - } - - /** - * Link the price set with the specified table and id. - * - * @param string $entityTable - * @param int $entityId - * @param int $priceSetId - * - * @return bool - */ - public static function addTo($entityTable, $entityId, $priceSetId) { - // verify that the price set exists - $dao = new CRM_Upgrade_Snapshot_V4p2_Price_DAO_Set(); - $dao->id = $priceSetId; - if (!$dao->find()) { - return FALSE; - } - unset($dao); - - $dao = new CRM_Upgrade_Snapshot_V4p2_Price_DAO_SetEntity(); - // find if this already exists - $dao->entity_id = $entityId; - $dao->entity_table = $entityTable; - $dao->find(TRUE); - - // add or update price_set_id - $dao->price_set_id = $priceSetId; - return $dao->save(); - } - - /** - * Delete price set for the given entity and id. - * - * @param string $entityTable - * @param int $entityId - * - * @return mixed - */ - public static function removeFrom($entityTable, $entityId) { - $dao = new CRM_Upgrade_Snapshot_V4p2_Price_DAO_SetEntity(); - $dao->entity_table = $entityTable; - $dao->entity_id = $entityId; - return $dao->delete(); - } - - /** - * Find a price_set_id associated with the given details. - * - * Used For value for events:1, contribution:2, membership:3 - * - * @param string $entityTable - * @param int $entityId - * @param int $usedFor - * ( price set that extends/used for particular component ). - * - * @param null $isQuickConfig - * @param null $setName - * - * @return int|false - * price_set_id, or false if none found - */ - public static function getFor($entityTable, $entityId, $usedFor = NULL, $isQuickConfig = NULL, &$setName = NULL) { - if (!$entityTable || !$entityId) { - return FALSE; - } - - $sql = 'SELECT ps.id as price_set_id, ps.name as price_set_name - FROM civicrm_price_set ps - INNER JOIN civicrm_price_set_entity pse ON ps.id = pse.price_set_id - WHERE pse.entity_table = %1 AND pse.entity_id = %2 '; - if ($isQuickConfig) { - $sql .= " AND ps.is_quick_config = 0 "; - } - $params = array( - 1 => array($entityTable, 'String'), - 2 => array($entityId, 'Integer'), - ); - if ($usedFor) { - $sql .= " AND ps.extends LIKE '%%3%' "; - $params[3] = array($usedFor, 'Integer'); - } - - $dao = CRM_Core_DAO::executeQuery($sql, $params); - $dao->fetch(); - $setName = (isset($dao->price_set_name)) ? $dao->price_set_name : FALSE; - return (isset($dao->price_set_id)) ? $dao->price_set_id : FALSE; - } - - /** - * Find a price_set_id associatied with the given option value or field ID. - * - * @param array $params - * (reference) an assoc array of name/value pairs. - * array may contain either option id or - * price field id - * - * @return int|null - * price set id on success, null otherwise - */ - public static function getSetId(&$params) { - $fid = NULL; - - if ($oid = CRM_Utils_Array::value('oid', $params)) { - $fieldValue = new CRM_Upgrade_Snapshot_V4p2_Price_DAO_FieldValue(); - $fieldValue->id = $oid; - if ($fieldValue->find(TRUE)) { - $fid = $fieldValue->price_field_id; - } - } - else { - $fid = CRM_Utils_Array::value('fid', $params); - } - - if (isset($fid)) { - return CRM_Core_DAO::getFieldValue('CRM_Upgrade_Snapshot_V4p2_Price_DAO_Field', $fid, 'price_set_id'); - } - - return NULL; - } - - /** - * Return an associative array of all price sets. - * - * @param bool $withInactive - * Whether or not to include inactive entries. - * @param bool|string $extendComponentName name of the component like 'CiviEvent','CiviContribute' - * - * @return array - * associative array of id => name - */ - public static function getAssoc($withInactive = FALSE, $extendComponentName = FALSE) { - $query = " - SELECT - DISTINCT ( price_set_id ) as id, title - FROM - civicrm_price_field, - civicrm_price_set - WHERE - civicrm_price_set.id = civicrm_price_field.price_set_id AND is_quick_config = 0 "; - - if (!$withInactive) { - $query .= " AND civicrm_price_set.is_active = 1 "; - } - - if (self::eventPriceSetDomainID()) { - $query .= " AND civicrm_price_set.domain_id = " . CRM_Core_Config::domainID(); - } - - $priceSets = array(); - - if ($extendComponentName) { - $componentId = CRM_Core_Component::getComponentID($extendComponentName); - if (!$componentId) { - return $priceSets; - } - $query .= " AND civicrm_price_set.extends LIKE '%$componentId%' "; - } - - $dao = CRM_Core_DAO::executeQuery($query); - while ($dao->fetch()) { - $priceSets[$dao->id] = $dao->title; - } - return $priceSets; - } - - /** - * Get price set details. - * - * An array containing price set details (including price fields) is returned - * - * @param int $setID - * Price set id whose details are needed. - * @param bool $required - * @param bool $validOnly - * - * @return array - * array consisting of field details - */ - public static function getSetDetail($setID, $required = TRUE, $validOnly = FALSE) { - // create a new tree - $setTree = array(); - $select = $from = $where = $orderBy = ''; - - $priceFields = array( - 'id', - 'name', - 'label', - 'html_type', - 'is_enter_qty', - 'help_pre', - 'help_post', - 'weight', - 'is_display_amounts', - 'options_per_line', - 'is_active', - 'active_on', - 'expire_on', - 'javascript', - 'visibility_id', - 'is_required', - ); - if ($required == TRUE) { - $priceFields[] = 'is_required'; - } - - // create select - $select = 'SELECT ' . implode(',', $priceFields); - $from = ' FROM civicrm_price_field'; - - $params = array(); - $params[1] = array($setID, 'Integer'); - $where = ' -WHERE price_set_id = %1 -AND is_active = 1 -'; - $dateSelect = ''; - if ($validOnly) { - $currentTime = date('YmdHis'); - $dateSelect = " -AND ( active_on IS NULL OR active_on <= {$currentTime} ) -AND ( expire_on IS NULL OR expire_on >= {$currentTime} ) -"; - } - - $orderBy = ' ORDER BY weight'; - - $sql = $select . $from . $where . $dateSelect . $orderBy; - - $dao = CRM_Core_DAO::executeQuery($sql, $params); - - $visibility = CRM_Core_PseudoConstant::visibility('name'); - while ($dao->fetch()) { - $fieldID = $dao->id; - - $setTree[$setID]['fields'][$fieldID] = array(); - $setTree[$setID]['fields'][$fieldID]['id'] = $fieldID; - - foreach ($priceFields as $field) { - if ($field == 'id' || is_null($dao->$field)) { - continue; - } - - if ($field == 'visibility_id') { - $setTree[$setID]['fields'][$fieldID]['visibility'] = $visibility[$dao->$field]; - } - $setTree[$setID]['fields'][$fieldID][$field] = $dao->$field; - } - $setTree[$setID]['fields'][$fieldID]['options'] = CRM_Upgrade_Snapshot_V4p2_Price_BAO_Field::getOptions($fieldID, FALSE); - } - - // also get the pre and post help from this price set - $sql = " -SELECT extends, contribution_type_id, help_pre, help_post, is_quick_config -FROM civicrm_price_set -WHERE id = %1"; - $dao = CRM_Core_DAO::executeQuery($sql, $params); - if ($dao->fetch()) { - $setTree[$setID]['extends'] = $dao->extends; - $setTree[$setID]['contribution_type_id'] = $dao->contribution_type_id; - $setTree[$setID]['help_pre'] = $dao->help_pre; - $setTree[$setID]['help_post'] = $dao->help_post; - $setTree[$setID]['is_quick_config'] = $dao->is_quick_config; - } - return $setTree; - } - - /** - * Initialise set. - * - * @param CRM_Core_Form $form - * @param int $id - * @param string $entityTable - * @param bool $validOnly - * @param int $priceSetId - * - * @return bool|false|int|null - */ - public static function initSet(&$form, $id, $entityTable = 'civicrm_event', $validOnly = FALSE, $priceSetId = NULL) { - if (!$priceSetId) { - $priceSetId = self::getFor($entityTable, $id); - } - - //check if priceset is is_config - if (is_numeric($priceSetId)) { - if (CRM_Core_DAO::getFieldValue('CRM_Upgrade_Snapshot_V4p2_Price_DAO_Set', $priceSetId, 'is_quick_config') && $form->getVar('_name') != 'Participant') { - $form->assign('quickConfig', 1); - } - } - // get price info - if ($priceSetId) { - if ($form->_action & CRM_Core_Action::UPDATE) { - $entityId = $entity = NULL; - - switch ($entityTable) { - case 'civicrm_event': - $entity = 'participant'; - if (CRM_Utils_System::getClassName($form) == 'CRM_Event_Form_Participant') { - $entityId = $form->_id; - } - else { - $entityId = $form->_participantId; - } - break; - - case 'civicrm_contribution_page': - case 'civicrm_contribution': - $entity = 'contribution'; - $entityId = $form->_id; - break; - } - - if ($entityId && $entity) { - $form->_values['line_items'] = CRM_Upgrade_Snapshot_V4p2_Price_BAO_LineItem::getLineItems($entityId, $entity); - } - $required = FALSE; - } - else { - $required = TRUE; - } - - $form->_priceSetId = $priceSetId; - $priceSet = self::getSetDetail($priceSetId, $required, $validOnly); - $form->_priceSet = CRM_Utils_Array::value($priceSetId, $priceSet); - $form->_values['fee'] = CRM_Utils_Array::value('fields', $form->_priceSet); - - //get the price set fields participant count. - if ($entityTable == 'civicrm_event') { - //get option count info. - $form->_priceSet['optionsCountTotal'] = self::getPricesetCount($priceSetId); - if ($form->_priceSet['optionsCountTotal']) { - $optionsCountDeails = array(); - if (!empty($form->_priceSet['fields'])) { - foreach ($form->_priceSet['fields'] as $field) { - foreach ($field['options'] as $option) { - $count = CRM_Utils_Array::value('count', $option, 0); - $optionsCountDeails['fields'][$field['id']]['options'][$option['id']] = $count; - } - } - } - $form->_priceSet['optionsCountDetails'] = $optionsCountDeails; - } - - //get option max value info. - $optionsMaxValueTotal = 0; - $optionsMaxValueDetails = array(); - - 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); - - return $priceSetId; - } - return FALSE; - } - - /** - * Process amount. - * - * @param array $fields - * @param array $params - * @param array $lineItem - */ - public static function processAmount(&$fields, &$params, &$lineItem) { - // using price set - $totalPrice = 0; - $radioLevel = $checkboxLevel = $selectLevel = $textLevel = array(); - - foreach ($fields as $id => $field) { - if (empty($params["price_{$id}"]) || - (empty($params["price_{$id}"]) && $params["price_{$id}"] == NULL) - ) { - // skip if nothing was submitted for this field - continue; - } - - switch ($field['html_type']) { - case 'Text': - $params["price_{$id}"] = array(key($field['options']) => $params["price_{$id}"]); - CRM_Upgrade_Snapshot_V4p2_Price_BAO_LineItem::format($id, $params, $field, $lineItem); - $totalPrice += $lineItem[key($field['options'])]['line_total']; - break; - - case 'Radio': - //special case if user select -none- - if ($params["price_{$id}"] <= 0) { - continue; - } - $params["price_{$id}"] = array($params["price_{$id}"] => 1); - $optionValueId = CRM_Utils_Array::key(1, $params["price_{$id}"]); - $optionLabel = CRM_Utils_Array::value('label', $field['options'][$optionValueId]); - $params['amount_priceset_level_radio'] = array(); - $params['amount_priceset_level_radio'][$optionValueId] = $optionLabel; - if (isset($radioLevel)) { - $radioLevel = array_merge($radioLevel, - array_keys($params['amount_priceset_level_radio']) - ); - } - else { - $radioLevel = array_keys($params['amount_priceset_level_radio']); - } - CRM_Upgrade_Snapshot_V4p2_Price_BAO_LineItem::format($id, $params, $field, $lineItem); - $totalPrice += $lineItem[$optionValueId]['line_total']; - break; - - case 'Select': - $params["price_{$id}"] = array($params["price_{$id}"] => 1); - $optionValueId = CRM_Utils_Array::key(1, $params["price_{$id}"]); - $optionLabel = $field['options'][$optionValueId]['label']; - $params['amount_priceset_level_select'] = array(); - $params['amount_priceset_level_select'][CRM_Utils_Array::key(1, $params["price_{$id}"])] = $optionLabel; - if (isset($selectLevel)) { - $selectLevel = array_merge($selectLevel, array_keys($params['amount_priceset_level_select'])); - } - else { - $selectLevel = array_keys($params['amount_priceset_level_select']); - } - CRM_Upgrade_Snapshot_V4p2_Price_BAO_LineItem::format($id, $params, $field, $lineItem); - $totalPrice += $lineItem[$optionValueId]['line_total']; - break; - - case 'CheckBox': - $params['amount_priceset_level_checkbox'] = $optionIds = array(); - foreach ($params["price_{$id}"] as $optionId => $option) { - $optionIds[] = $optionId; - $optionLabel = $field['options'][$optionId]['label']; - $params['amount_priceset_level_checkbox']["{$field['options'][$optionId]['id']}"] = $optionLabel; - if (isset($checkboxLevel)) { - $checkboxLevel = array_unique(array_merge( - $checkboxLevel, - array_keys($params['amount_priceset_level_checkbox']) - ) - ); - } - else { - $checkboxLevel = array_keys($params['amount_priceset_level_checkbox']); - } - } - CRM_Upgrade_Snapshot_V4p2_Price_BAO_LineItem::format($id, $params, $field, $lineItem); - foreach ($optionIds as $optionId) { - $totalPrice += $lineItem[$optionId]['line_total']; - } - break; - } - } - - $amount_level = array(); - $totalParticipant = 0; - if (is_array($lineItem)) { - foreach ($lineItem as $values) { - $totalParticipant += $values['participant_count']; - if ($values['html_type'] == 'Text') { - $amount_level[] = $values['label'] . ' - ' . $values['qty']; - continue; - } - $amount_level[] = $values['label']; - } - } - - $displayParticipantCount = ''; - if ($totalParticipant > 0) { - $displayParticipantCount = ' Participant Count -' . $totalParticipant; - } - - $params['amount_level'] = CRM_Core_DAO::VALUE_SEPARATOR . implode(CRM_Core_DAO::VALUE_SEPARATOR, $amount_level) . $displayParticipantCount . CRM_Core_DAO::VALUE_SEPARATOR; - $params['amount'] = $totalPrice; - } - - /** - * Build the price set form. - * - * @param CRM_Core_Form $form - */ - public static function buildPriceSet(&$form) { - $priceSetId = $form->get('priceSetId'); - $userid = $form->getVar('_userID'); - if (!$priceSetId) { - return; - } - - $validFieldsOnly = TRUE; - $className = CRM_Utils_System::getClassName($form); - if (in_array($className, array( - 'CRM_Contribute_Form_Contribution', - 'CRM_Member_Form_Membership', - ))) { - $validFieldsOnly = FALSE; - } - - $priceSet = self::getSetDetail($priceSetId, TRUE, $validFieldsOnly); - $form->_priceSet = CRM_Utils_Array::value($priceSetId, $priceSet); - $form->_quickConfig = $quickConfig = 0; - if (CRM_Core_DAO::getFieldValue('CRM_Upgrade_Snapshot_V4p2_Price_DAO_Set', $priceSetId, 'is_quick_config')) { - $quickConfig = 1; - } - - $form->assign('quickConfig', $quickConfig); - if ($className == "CRM_Contribute_Form_Contribution_Main") { - $form->_quickConfig = $quickConfig; - } - $form->assign('priceSet', $form->_priceSet); - - $component = 'contribution'; - if ($className == 'CRM_Member_Form_Membership') { - $component = 'membership'; - } - - if ($className == 'CRM_Contribute_Form_Contribution_Main') { - $feeBlock = &$form->_values['fee']; - if (!empty($form->_useForMember)) { - $component = 'membership'; - } - } - else { - $feeBlock = &$form->_priceSet['fields']; - } - - // call the hook. - CRM_Utils_Hook::buildAmount($component, $form, $feeBlock); - - foreach ($feeBlock as $field) { - if (CRM_Utils_Array::value('visibility', $field) == 'public' || - !$validFieldsOnly - ) { - $options = CRM_Utils_Array::value('options', $field); - if ($className == 'CRM_Contribute_Form_Contribution_Main' && $component = 'membership') { - $checklifetime = self::checkCurrentMembership($options, $userid); - if ($checklifetime) { - $form->assign('ispricelifetime', TRUE); - } - } - if (!is_array($options)) { - continue; - } - CRM_Upgrade_Snapshot_V4p2_Price_BAO_Field::addQuickFormElement($form, - 'price_' . $field['id'], - $field['id'], - FALSE, - CRM_Utils_Array::value('is_required', $field, FALSE), - NULL, - $options - ); - } - } - } - - /** - * Check the current Membership. - * - * @param array $options - * @param int $userid - * - * @return bool - */ - public static function checkCurrentMembership(&$options, $userid) { - if (!$userid || empty($options)) { - return FALSE; - } - static $_contact_memberships = array(); - $checklifetime = FALSE; - foreach ($options as $key => $value) { - if (!empty($value['membership_type_id'])) { - if (!isset($_contact_memberships[$userid][$value['membership_type_id']])) { - $_contact_memberships[$userid][$value['membership_type_id']] = CRM_Member_BAO_Membership::getContactMembership($userid, $value['membership_type_id'], FALSE); - } - $currentMembership = $_contact_memberships[$userid][$value['membership_type_id']]; - if (!empty($currentMembership) && empty($currentMembership['end_date'])) { - unset($options[$key]); - $checklifetime = TRUE; - } - } - } - if ($checklifetime) { - return TRUE; - } - else { - return FALSE; - } - } - - /** - * Set default the price set fields. - * - * @param CRM_Core_Form $form - * @param array $defaults - * - * @return array - */ - public static function setDefaultPriceSet(&$form, &$defaults) { - if (!isset($form->_priceSet) || empty($form->_priceSet['fields'])) { - return $defaults; - } - - foreach ($form->_priceSet['fields'] as $key => $val) { - foreach ($val['options'] as $keys => $values) { - if ($values['is_default']) { - if ($val['html_type'] == 'CheckBox') { - $defaults["price_{$key}"][$keys] = 1; - } - else { - $defaults["price_{$key}"] = $keys; - } - } - } - } - return $defaults; - } - - /** - * Get field ids of a price set. - * - * @param int $id Price Set id - * - * @return array - * Array of the field ids - */ - public static function getFieldIds($id) { - $priceField = new CRM_Upgrade_Snapshot_V4p2_Price_DAO_Field(); - $priceField->price_set_id = $id; - $priceField->find(); - while ($priceField->fetch()) { - $var[] = $priceField->id; - } - return $var; - } - - /** - * Copy a price set, including all the fields. - * - * @param int $id - * The price set id to copy. - * - * @return CRM_Upgrade_Snapshot_V4p2_Price_DAO_Field - */ - public static function copy($id) { - $maxId = CRM_Core_DAO::singleValueQuery("SELECT max(id) FROM civicrm_price_set"); - - $title = ts('[Copy id %1]', array(1 => $maxId + 1)); - $fieldsFix = array( - 'suffix' => array( - 'title' => ' ' . $title, - 'name' => '__Copy_id_' . ($maxId + 1) . '_', - ), - ); - - $copy = &CRM_Core_DAO::copyGeneric('CRM_Upgrade_Snapshot_V4p2_Price_DAO_Set', - array('id' => $id), - NULL, - $fieldsFix - ); - - //copying all the blocks pertaining to the price set - $copyPriceField = &CRM_Core_DAO::copyGeneric('CRM_Upgrade_Snapshot_V4p2_Price_DAO_Field', - array('price_set_id' => $id), - array('price_set_id' => $copy->id) - ); - if (!empty($copyPriceField)) { - $price = array_combine(self::getFieldIds($id), self::getFieldIds($copy->id)); - - //copy option group and values - foreach ($price as $originalId => $copyId) { - CRM_Core_DAO::copyGeneric('CRM_Upgrade_Snapshot_V4p2_Price_DAO_FieldValue', - array('price_field_id' => $originalId), - array('price_field_id' => $copyId) - ); - } - } - $copy->save(); - - CRM_Utils_Hook::copy('Set', $copy); - return $copy; - } - - /** - * Check price set permission. - * - * @param int $sid - * The price set id. - * - * @return bool - */ - public function checkPermission($sid) { - if ($sid && - self::eventPriceSetDomainID() - ) { - $domain_id = CRM_Core_DAO::getFieldValue('CRM_Upgrade_Snapshot_V4p2_Price_DAO_Set', $sid, 'domain_id', 'id'); - if (CRM_Core_Config::domainID() != $domain_id) { - CRM_Core_Error::fatal(ts('You do not have permission to access this page.')); - } - } - return TRUE; - } - - /** - * Get the sum of participant count for all fields of given price set. - * - * @param int $sid - * The price set id. - * - * @param bool $onlyActive - * - * @return int|null|string - */ - public static function getPricesetCount($sid, $onlyActive = TRUE) { - $count = 0; - if (!$sid) { - return $count; - } - - $where = NULL; - if ($onlyActive) { - $where = 'AND value.is_active = 1 AND field.is_active = 1'; - } - - static $pricesetFieldCount; - if (!isset($pricesetFieldCount[$sid])) { - $sql = " - SELECT sum(value.count) as totalCount - FROM civicrm_price_field_value value -INNER JOIN civicrm_price_field field ON ( field.id = value.price_field_id ) -INNER JOIN civicrm_price_set pset ON ( pset.id = field.price_set_id ) - WHERE pset.id = %1 - $where"; - - $count = CRM_Core_DAO::singleValueQuery($sql, array(1 => array($sid, 'Positive'))); - $pricesetFieldCount[$sid] = ($count) ? $count : 0; - } - - return $pricesetFieldCount[$sid]; - } - - /** - * Get membership count. - * - * @param array $ids - * - * @return array - */ - public static function getMembershipCount($ids) { - $queryString = " -SELECT count( pfv.id ) AS count, pfv.id AS id -FROM civicrm_price_field_value pfv -INNER JOIN civicrm_membership_type mt ON mt.id = pfv.membership_type_id -WHERE pfv.id IN ( $ids ) -GROUP BY mt.member_of_contact_id"; - - $crmDAO = CRM_Core_DAO::executeQuery($queryString); - $count = array(); - - while ($crmDAO->fetch()) { - $count[$crmDAO->id] = $crmDAO->count; - } - - return $count; - } - - /** - * Function to check if auto renew option should be shown. - * - * @param int $priceSetId - * Price set id. - * - * @return int - * $autoRenewOption ( 0:hide, 1:optional 2:required ) - */ - public static function checkAutoRenewForPriceSet($priceSetId) { - // auto-renew option should be visible if membership types associated with all the fields has - // been set for auto-renew option - // Auto renew checkbox should be frozen if for all the membership type auto renew is required - - // get the membership type auto renew option and check if required or optional - $query = 'SELECT mt.auto_renew, mt.duration_interval, mt.duration_unit - FROM civicrm_price_field_value pfv - INNER JOIN civicrm_membership_type mt ON pfv.membership_type_id = mt.id - INNER JOIN civicrm_price_field pf ON pfv.price_field_id = pf.id - WHERE pf.price_set_id = %1 - AND pf.is_active = 1 - AND pfv.is_active = 1'; - - $params = array(1 => array($priceSetId, 'Integer')); - - $dao = CRM_Core_DAO::executeQuery($query, $params); - $autoRenewOption = 2; - $interval = $unit = array(); - while ($dao->fetch()) { - if (!$dao->auto_renew) { - $autoRenewOption = 0; - break; - } - if ($dao->auto_renew == 1) { - $autoRenewOption = 1; - } - - $interval[$dao->duration_interval] = $dao->duration_interval; - $unit[$dao->duration_unit] = $dao->duration_unit; - } - - if (count($interval) == 1 && count($unit) == 1 && $autoRenewOption > 0) { - return $autoRenewOption; - } - else { - return 0; - } - } - - /** - * Retrieve auto renew frequency and interval. - * - * @param int $priceSetId - * Price set id. - * - * @return array - * associate array of frequency interval and unit - */ - public static function getRecurDetails($priceSetId) { - $query = 'SELECT mt.duration_interval, mt.duration_unit - FROM civicrm_price_field_value pfv - INNER JOIN civicrm_membership_type mt ON pfv.membership_type_id = mt.id - INNER JOIN civicrm_price_field pf ON pfv.price_field_id = pf.id - WHERE pf.price_set_id = %1 LIMIT 1'; - - $params = array(1 => array($priceSetId, 'Integer')); - $dao = CRM_Core_DAO::executeQuery($query, $params); - $dao->fetch(); - return array($dao->duration_interval, $dao->duration_unit); - } - - /** - * Get event price set for domain. - * - * @return object - */ - public static function eventPriceSetDomainID() { - return Civi::settings()->get('event_price_set_domain_id'); - } - - /** - * Update the is_quick_config flag in the db. - * - * @param int $id - * Id of the database record. - * @param bool $isQuickConfig we want to set the is_quick_config field. - * Value we want to set the is_quick_config field. - * - * @return bool - * true if we found and updated the object, else false - */ - public static function setIsQuickConfig($id, $isQuickConfig) { - return CRM_Core_DAO::setFieldValue('CRM_Upgrade_Snapshot_V4p2_Price_DAO_Set', $id, 'is_quick_config', $isQuickConfig); - } - -} diff --git a/civicrm/CRM/Upgrade/Snapshot/V4p2/Price/DAO/Field.php b/civicrm/CRM/Upgrade/Snapshot/V4p2/Price/DAO/Field.php deleted file mode 100644 index 120c4bd254..0000000000 --- a/civicrm/CRM/Upgrade/Snapshot/V4p2/Price/DAO/Field.php +++ /dev/null @@ -1,444 +0,0 @@ -<?php -/* -+--------------------------------------------------------------------+ -| CiviCRM version 5 | -+--------------------------------------------------------------------+ -| Copyright CiviCRM LLC (c) 2004-2019 | -+--------------------------------------------------------------------+ -| This file is a part of CiviCRM. | -| | -| CiviCRM is free software; you can copy, modify, and distribute it | -| under the terms of the GNU Affero General Public License | -| Version 3, 19 November 2007 and the CiviCRM Licensing Exception. | -| | -| CiviCRM is distributed in the hope that it will be useful, but | -| WITHOUT ANY WARRANTY; without even the implied warranty of | -| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | -| See the GNU Affero General Public License for more details. | -| | -| You should have received a copy of the GNU Affero General Public | -| License and the CiviCRM Licensing Exception along | -| with this program; if not, contact CiviCRM LLC | -| at info[AT]civicrm[DOT]org. If you have questions about the | -| GNU Affero General Public License or the licensing of CiviCRM, | -| see the CiviCRM license FAQ at http://civicrm.org/licensing | -+--------------------------------------------------------------------+ - */ -/** - * - * @package CRM - * @copyright CiviCRM LLC (c) 2004-2019 - * $Id$ - * - */ -require_once 'CRM/Core/DAO.php'; -require_once 'CRM/Utils/Type.php'; - -/** - * Class CRM_Upgrade_Snapshot_V4p2_Price_DAO_Field - */ -class CRM_Upgrade_Snapshot_V4p2_Price_DAO_Field extends CRM_Core_DAO { - /** - * static instance to hold the table name - * - * @var string - */ - static $_tableName = 'civicrm_price_field'; - /** - * static instance to hold the field values - * - * @var array - */ - static $_fields = NULL; - /** - * static instance to hold the FK relationships - * - * @var string - */ - static $_links = NULL; - /** - * static instance to hold the values that can - * be imported - * - * @var array - */ - static $_import = NULL; - /** - * static instance to hold the values that can - * be exported - * - * @var array - */ - static $_export = NULL; - /** - * static value to see if we should log any modifications to - * this table in the civicrm_log table - * - * @var bool - */ - static $_log = TRUE; - /** - * Price Field - * - * @var int unsigned - */ - public $id; - /** - * FK to civicrm_price_set - * - * @var int unsigned - */ - public $price_set_id; - /** - * Variable name/programmatic handle for this field. - * - * @var string - */ - public $name; - /** - * Text for form field label (also friendly name for administering this field). - * - * @var string - */ - public $label; - /** - * - * @var enum('Text', 'Select', 'Radio', 'CheckBox') - */ - public $html_type; - /** - * Enter a quantity for this field? - * - * @var bool - */ - public $is_enter_qty; - /** - * Description and/or help text to display before this field. - * - * @var text - */ - public $help_pre; - /** - * Description and/or help text to display after this field. - * - * @var text - */ - public $help_post; - /** - * Order in which the fields should appear - * - * @var int - */ - public $weight; - /** - * Should the price be displayed next to the label for each option? - * - * @var boolean - */ - public $is_display_amounts; - /** - * number of options per line for checkbox and radio - * - * @var int unsigned - */ - public $options_per_line; - /** - * Is this price field active - * - * @var boolean - */ - public $is_active; - /** - * Is this price field required (value must be > 1) - * - * @var boolean - */ - public $is_required; - /** - * If non-zero, do not show this field before the date specified - * - * @var datetime - */ - public $active_on; - /** - * If non-zero, do not show this field after the date specified - * - * @var datetime - */ - public $expire_on; - /** - * Optional scripting attributes for field - * - * @var string - */ - public $javascript; - /** - * Implicit FK to civicrm_option_group with name = \'visibility\' - * - * @var int unsigned - */ - public $visibility_id; - - /** - * Class constructor. - * - * @return \CRM_Upgrade_Snapshot_V4p2_Price_DAO_Field - */ - public function __construct() { - $this->__table = 'civicrm_price_field'; - parent::__construct(); - } - - /** - * Return foreign links. - * - * @return array - */ - public function links() { - if (!(self::$_links)) { - self::$_links = array( - 'price_set_id' => 'civicrm_price_set:id', - ); - } - return self::$_links; - } - - /** - * Returns all the column names of this table. - * - * @return array - */ - public static function &fields() { - if (!(self::$_fields)) { - self::$_fields = array( - 'id' => array( - 'name' => 'id', - 'type' => CRM_Utils_Type::T_INT, - 'required' => TRUE, - ), - 'price_set_id' => array( - 'name' => 'price_set_id', - 'type' => CRM_Utils_Type::T_INT, - 'required' => TRUE, - 'FKClassName' => 'Snapshot_v4p2_Price_DAO_Set', - ), - 'name' => array( - 'name' => 'name', - 'type' => CRM_Utils_Type::T_STRING, - 'title' => ts('Name'), - 'required' => TRUE, - 'maxlength' => 255, - 'size' => CRM_Utils_Type::HUGE, - ), - 'label' => array( - 'name' => 'label', - 'type' => CRM_Utils_Type::T_STRING, - 'title' => ts('Label'), - 'required' => TRUE, - 'maxlength' => 255, - 'size' => CRM_Utils_Type::HUGE, - ), - 'html_type' => array( - 'name' => 'html_type', - 'type' => CRM_Utils_Type::T_ENUM, - 'title' => ts('Html Type'), - 'required' => TRUE, - 'enumValues' => 'Text, Select, Radio, CheckBox', - ), - 'is_enter_qty' => array( - 'name' => 'is_enter_qty', - 'type' => CRM_Utils_Type::T_BOOLEAN, - ), - 'help_pre' => array( - 'name' => 'help_pre', - 'type' => CRM_Utils_Type::T_TEXT, - 'title' => ts('Help Pre'), - 'rows' => 4, - 'cols' => 80, - ), - 'help_post' => array( - 'name' => 'help_post', - 'type' => CRM_Utils_Type::T_TEXT, - 'title' => ts('Help Post'), - 'rows' => 4, - 'cols' => 80, - ), - 'weight' => array( - 'name' => 'weight', - 'type' => CRM_Utils_Type::T_INT, - 'title' => ts('Weight'), - 'default' => '', - ), - 'is_display_amounts' => array( - 'name' => 'is_display_amounts', - 'type' => CRM_Utils_Type::T_BOOLEAN, - 'default' => '', - ), - 'options_per_line' => array( - 'name' => 'options_per_line', - 'type' => CRM_Utils_Type::T_INT, - 'title' => ts('Options Per Line'), - 'default' => '', - ), - 'is_active' => array( - 'name' => 'is_active', - 'type' => CRM_Utils_Type::T_BOOLEAN, - 'default' => '', - ), - 'is_required' => array( - 'name' => 'is_required', - 'type' => CRM_Utils_Type::T_BOOLEAN, - 'default' => '', - ), - 'active_on' => array( - 'name' => 'active_on', - 'type' => CRM_Utils_Type::T_DATE + CRM_Utils_Type::T_TIME, - 'title' => ts('Active On'), - 'default' => 'UL', - ), - 'expire_on' => array( - 'name' => 'expire_on', - 'type' => CRM_Utils_Type::T_DATE + CRM_Utils_Type::T_TIME, - 'title' => ts('Expire On'), - 'default' => 'UL', - ), - 'javascript' => array( - 'name' => 'javascript', - 'type' => CRM_Utils_Type::T_STRING, - 'title' => ts('Javascript'), - 'maxlength' => 255, - 'size' => CRM_Utils_Type::HUGE, - ), - 'visibility_id' => array( - 'name' => 'visibility_id', - 'type' => CRM_Utils_Type::T_INT, - 'default' => '', - ), - ); - } - return self::$_fields; - } - - /** - * returns the names of this table. - * - * @return string - */ - public static function getTableName() { - return CRM_Core_DAO::getLocaleTableName(self::$_tableName); - } - - /** - * returns if this table needs to be logged. - * - * @return bool - */ - public function getLog() { - return self::$_log; - } - - /** - * returns the list of fields that can be imported. - * - * @param bool $prefix - * - * @return array - */ - public static function &import($prefix = FALSE) { - if (!(self::$_import)) { - self::$_import = array(); - $fields = self::fields(); - foreach ($fields as $name => $field) { - if (!empty($field['import'])) { - if ($prefix) { - self::$_import['price_field'] = &$fields[$name]; - } - else { - self::$_import[$name] = &$fields[$name]; - } - } - } - } - return self::$_import; - } - - /** - * Returns the list of fields that can be exported. - * - * @param bool $prefix - * - * @return array - */ - public static function &export($prefix = FALSE) { - if (!(self::$_export)) { - self::$_export = array(); - $fields = self::fields(); - foreach ($fields as $name => $field) { - if (!empty($field['export'])) { - if ($prefix) { - self::$_export['price_field'] = &$fields[$name]; - } - else { - self::$_export[$name] = &$fields[$name]; - } - } - } - } - return self::$_export; - } - - /** - * returns an array containing the enum fields of the civicrm_price_field table. - * - * @return array - * (reference) the array of enum fields - */ - public static function &getEnums() { - static $enums = array( - 'html_type', - ); - return $enums; - } - - /** - * returns a ts()-translated enum value for display purposes - * - * @param string $field - * The enum field in question. - * @param string $value - * The enum value up for translation. - * - * @return string - * the display value of the enum - */ - public static function tsEnum($field, $value) { - static $translations = NULL; - if (!$translations) { - $translations = array( - 'html_type' => array( - 'Text' => ts('Text'), - 'Select' => ts('Select'), - 'Radio' => ts('Radio'), - 'CheckBox' => ts('CheckBox'), - ), - ); - } - return $translations[$field][$value]; - } - - /** - * adds $value['foo_display'] for each $value['foo'] enum from civicrm_price_field - * - * @param array $values - * (reference) the array up for enhancing. - */ - public static function addDisplayEnums(&$values) { - $enumFields = &Snapshot_v4p2_Price_DAO_Field::getEnums(); - foreach ($enumFields as $enum) { - if (isset($values[$enum])) { - $values[$enum . '_display'] = Snapshot_v4p2_Price_DAO_Field::tsEnum($enum, $values[$enum]); - } - } - } - -} diff --git a/civicrm/CRM/Upgrade/Snapshot/V4p2/Price/DAO/FieldValue.php b/civicrm/CRM/Upgrade/Snapshot/V4p2/Price/DAO/FieldValue.php deleted file mode 100644 index a333aa40c8..0000000000 --- a/civicrm/CRM/Upgrade/Snapshot/V4p2/Price/DAO/FieldValue.php +++ /dev/null @@ -1,332 +0,0 @@ -<?php -/* -+--------------------------------------------------------------------+ -| CiviCRM version 5 | -+--------------------------------------------------------------------+ -| Copyright CiviCRM LLC (c) 2004-2019 | -+--------------------------------------------------------------------+ -| This file is a part of CiviCRM. | -| | -| CiviCRM is free software; you can copy, modify, and distribute it | -| under the terms of the GNU Affero General Public License | -| Version 3, 19 November 2007 and the CiviCRM Licensing Exception. | -| | -| CiviCRM is distributed in the hope that it will be useful, but | -| WITHOUT ANY WARRANTY; without even the implied warranty of | -| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | -| See the GNU Affero General Public License for more details. | -| | -| You should have received a copy of the GNU Affero General Public | -| License and the CiviCRM Licensing Exception along | -| with this program; if not, contact CiviCRM LLC | -| at info[AT]civicrm[DOT]org. If you have questions about the | -| GNU Affero General Public License or the licensing of CiviCRM, | -| see the CiviCRM license FAQ at http://civicrm.org/licensing | -+--------------------------------------------------------------------+ -*/ -/** - * - * @package CRM - * @copyright CiviCRM LLC (c) 2004-2019 - * $Id$ - * - */ -require_once 'CRM/Core/DAO.php'; -require_once 'CRM/Utils/Type.php'; - -/** - * Class CRM_Upgrade_Snapshot_V4p2_Price_DAO_FieldValue - */ -class CRM_Upgrade_Snapshot_V4p2_Price_DAO_FieldValue extends CRM_Core_DAO { - /** - * static instance to hold the table name - * - * @var string - */ - static $_tableName = 'civicrm_price_field_value'; - /** - * static instance to hold the field values - * - * @var array - */ - static $_fields = NULL; - /** - * static instance to hold the FK relationships - * - * @var string - */ - static $_links = NULL; - /** - * static instance to hold the values that can - * be imported - * - * @var array - */ - static $_import = NULL; - /** - * static instance to hold the values that can - * be exported - * - * @var array - */ - static $_export = NULL; - /** - * static value to see if we should log any modifications to - * this table in the civicrm_log table - * - * @var boolean - */ - static $_log = FALSE; - /** - * Price Field Value - * - * @var int unsigned - */ - public $id; - /** - * FK to civicrm_price_field - * - * @var int unsigned - */ - public $price_field_id; - /** - * Price field option name - * - * @var string - */ - public $name; - /** - * Price field option label - * - * @var string - */ - public $label; - /** - * >Price field option description. - * - * @var text - */ - public $description; - /** - * Price field option amount - * - * @var string - */ - public $amount; - /** - * Number of participants per field option - * - * @var int unsigned - */ - public $count; - /** - * Max number of participants per field options - * - * @var int unsigned - */ - public $max_value; - /** - * Order in which the field options should appear - * - * @var int - */ - public $weight; - /** - * FK to Membership Type - * - * @var int unsigned - */ - public $membership_type_id; - /** - * Is this default price field option - * - * @var boolean - */ - public $is_default; - /** - * Is this price field value active - * - * @var boolean - */ - public $is_active; - - /** - * Class constructor. - * - * @return \CRM_Upgrade_Snapshot_V4p2_Price_DAO_FieldValue - */ - public function __construct() { - $this->__table = 'civicrm_price_field_value'; - parent::__construct(); - } - - /** - * Return foreign links. - * - * @return array - */ - public function links() { - if (!(self::$_links)) { - self::$_links = array( - 'price_field_id' => 'civicrm_price_field:id', - 'membership_type_id' => 'civicrm_membership_type:id', - ); - } - return self::$_links; - } - - /** - * Returns all the column names of this table. - * - * @return array - */ - public static function &fields() { - if (!(self::$_fields)) { - self::$_fields = array( - 'id' => array( - 'name' => 'id', - 'type' => CRM_Utils_Type::T_INT, - 'required' => TRUE, - ), - 'price_field_id' => array( - 'name' => 'price_field_id', - 'type' => CRM_Utils_Type::T_INT, - 'required' => TRUE, - 'FKClassName' => 'Snapshot_v4p2_Price_DAO_Field', - ), - 'name' => array( - 'name' => 'name', - 'type' => CRM_Utils_Type::T_STRING, - 'title' => ts('Name'), - 'maxlength' => 255, - 'size' => CRM_Utils_Type::HUGE, - ), - 'label' => array( - 'name' => 'label', - 'type' => CRM_Utils_Type::T_STRING, - 'title' => ts('Label'), - 'maxlength' => 255, - 'size' => CRM_Utils_Type::HUGE, - ), - 'description' => array( - 'name' => 'description', - 'type' => CRM_Utils_Type::T_TEXT, - 'title' => ts('Description'), - 'rows' => 2, - 'cols' => 60, - 'default' => 'UL', - ), - 'amount' => array( - 'name' => 'amount', - 'type' => CRM_Utils_Type::T_STRING, - 'title' => ts('Amount'), - 'required' => TRUE, - 'maxlength' => 512, - 'size' => CRM_Utils_Type::HUGE, - ), - 'count' => array( - 'name' => 'count', - 'type' => CRM_Utils_Type::T_INT, - 'title' => ts('Count'), - 'default' => 'UL', - ), - 'max_value' => array( - 'name' => 'max_value', - 'type' => CRM_Utils_Type::T_INT, - 'title' => ts('Max Value'), - 'default' => 'UL', - ), - 'weight' => array( - 'name' => 'weight', - 'type' => CRM_Utils_Type::T_INT, - 'title' => ts('Weight'), - 'default' => '', - ), - 'membership_type_id' => array( - 'name' => 'membership_type_id', - 'type' => CRM_Utils_Type::T_INT, - 'default' => 'UL', - 'FKClassName' => 'CRM_Member_DAO_MembershipType', - ), - 'is_default' => array( - 'name' => 'is_default', - 'type' => CRM_Utils_Type::T_BOOLEAN, - ), - 'is_active' => array( - 'name' => 'is_active', - 'type' => CRM_Utils_Type::T_BOOLEAN, - 'default' => '', - ), - ); - } - return self::$_fields; - } - - /** - * returns the names of this table. - * - * @return string - */ - public static function getTableName() { - return CRM_Core_DAO::getLocaleTableName(self::$_tableName); - } - - /** - * returns if this table needs to be logged. - * - * @return boolean - */ - public function getLog() { - return self::$_log; - } - - /** - * Returns the list of fields that can be imported. - * - * @param bool $prefix - * - * @return array - */ - static function &import($prefix = FALSE) { - if (!(self::$_import)) { - self::$_import = array(); - $fields = self::fields(); - foreach ($fields as $name => $field) { - if (!empty($field['import'])) { - if ($prefix) { - self::$_import['price_field_value'] = &$fields[$name]; - } - else { - self::$_import[$name] = &$fields[$name]; - } - } - } - } - return self::$_import; - } - - /** - * Returns the list of fields that can be exported. - * - * @param bool $prefix - * - * @return array - */ - static function &export($prefix = FALSE) { - if (!(self::$_export)) { - self::$_export = array(); - $fields = self::fields(); - foreach ($fields as $name => $field) { - if (!empty($field['export'])) { - if ($prefix) { - self::$_export['price_field_value'] = &$fields[$name]; - } - else { - self::$_export[$name] = &$fields[$name]; - } - } - } - } - return self::$_export; - } -} diff --git a/civicrm/CRM/Upgrade/Snapshot/V4p2/Price/DAO/LineItem.php b/civicrm/CRM/Upgrade/Snapshot/V4p2/Price/DAO/LineItem.php deleted file mode 100644 index ec0fe23998..0000000000 --- a/civicrm/CRM/Upgrade/Snapshot/V4p2/Price/DAO/LineItem.php +++ /dev/null @@ -1,308 +0,0 @@ -<?php -/* -+--------------------------------------------------------------------+ -| CiviCRM version 5 | -+--------------------------------------------------------------------+ -| Copyright CiviCRM LLC (c) 2004-2019 | -+--------------------------------------------------------------------+ -| This file is a part of CiviCRM. | -| | -| CiviCRM is free software; you can copy, modify, and distribute it | -| under the terms of the GNU Affero General Public License | -| Version 3, 19 November 2007 and the CiviCRM Licensing Exception. | -| | -| CiviCRM is distributed in the hope that it will be useful, but | -| WITHOUT ANY WARRANTY; without even the implied warranty of | -| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | -| See the GNU Affero General Public License for more details. | -| | -| You should have received a copy of the GNU Affero General Public | -| License and the CiviCRM Licensing Exception along | -| with this program; if not, contact CiviCRM LLC | -| at info[AT]civicrm[DOT]org. If you have questions about the | -| GNU Affero General Public License or the licensing of CiviCRM, | -| see the CiviCRM license FAQ at http://civicrm.org/licensing | -+--------------------------------------------------------------------+ -*/ -/** - * - * @package CRM - * @copyright CiviCRM LLC (c) 2004-2019 - * $Id$ - * - */ -require_once 'CRM/Core/DAO.php'; -require_once 'CRM/Utils/Type.php'; - -/** - * Class CRM_Upgrade_Snapshot_V4p2_Price_DAO_LineItem - */ -class CRM_Upgrade_Snapshot_V4p2_Price_DAO_LineItem extends CRM_Core_DAO { - /** - * static instance to hold the table name - * - * @var string - */ - static $_tableName = 'civicrm_line_item'; - /** - * static instance to hold the field values - * - * @var array - */ - static $_fields = NULL; - /** - * static instance to hold the FK relationships - * - * @var string - */ - static $_links = NULL; - /** - * static instance to hold the values that can - * be imported - * - * @var array - */ - static $_import = NULL; - /** - * static instance to hold the values that can - * be exported - * - * @var array - */ - static $_export = NULL; - /** - * static value to see if we should log any modifications to - * this table in the civicrm_log table - * - * @var boolean - */ - static $_log = TRUE; - /** - * Line Item - * - * @var int unsigned - */ - public $id; - /** - * table which has the transaction - * - * @var string - */ - public $entity_table; - /** - * entry in table - * - * @var int unsigned - */ - public $entity_id; - /** - * FK to price_field - * - * @var int unsigned - */ - public $price_field_id; - /** - * descriptive label for item - from price_field_value.label - * - * @var string - */ - public $label; - /** - * How many items ordered - * - * @var int unsigned - */ - public $qty; - /** - * price of each item - * - * @var float - */ - public $unit_price; - /** - * qty * unit_price - * - * @var float - */ - public $line_total; - /** - * Participant count for field - * - * @var int unsigned - */ - public $participant_count; - /** - * Implicit FK to civicrm_option_value - * - * @var int unsigned - */ - public $price_field_value_id; - - /** - * Class constructor. - * - * @return \CRM_Upgrade_Snapshot_V4p2_Price_DAO_LineItem - */ - public function __construct() { - $this->__table = 'civicrm_line_item'; - parent::__construct(); - } - - /** - * Return foreign links. - * - * @return array - */ - public function links() { - if (!(self::$_links)) { - self::$_links = array( - 'price_field_id' => 'civicrm_price_field:id', - 'price_field_value_id' => 'civicrm_price_field_value:id', - ); - } - return self::$_links; - } - - /** - * Returns all the column names of this table. - * - * @return array - */ - public static function &fields() { - if (!(self::$_fields)) { - self::$_fields = array( - 'id' => array( - 'name' => 'id', - 'type' => CRM_Utils_Type::T_INT, - 'required' => TRUE, - ), - 'entity_table' => array( - 'name' => 'entity_table', - 'type' => CRM_Utils_Type::T_STRING, - 'title' => ts('Entity Table'), - 'required' => TRUE, - 'maxlength' => 64, - 'size' => CRM_Utils_Type::BIG, - ), - 'entity_id' => array( - 'name' => 'entity_id', - 'type' => CRM_Utils_Type::T_INT, - 'required' => TRUE, - ), - 'price_field_id' => array( - 'name' => 'price_field_id', - 'type' => CRM_Utils_Type::T_INT, - 'required' => TRUE, - 'FKClassName' => 'Snapshot_v4p2_Price_DAO_Field', - ), - 'label' => array( - 'name' => 'label', - 'type' => CRM_Utils_Type::T_STRING, - 'title' => ts('Label'), - 'maxlength' => 255, - 'size' => CRM_Utils_Type::HUGE, - 'default' => 'UL', - ), - 'qty' => array( - 'name' => 'qty', - 'type' => CRM_Utils_Type::T_INT, - 'title' => ts('Qty'), - 'required' => TRUE, - ), - 'unit_price' => array( - 'name' => 'unit_price', - 'type' => CRM_Utils_Type::T_MONEY, - 'title' => ts('Unit Price'), - 'required' => TRUE, - ), - 'line_total' => array( - 'name' => 'line_total', - 'type' => CRM_Utils_Type::T_MONEY, - 'title' => ts('Line Total'), - 'required' => TRUE, - ), - 'participant_count' => array( - 'name' => 'participant_count', - 'type' => CRM_Utils_Type::T_INT, - 'title' => ts('Participant Count'), - 'default' => 'UL', - ), - 'price_field_value_id' => array( - 'name' => 'price_field_value_id', - 'type' => CRM_Utils_Type::T_INT, - 'default' => 'UL', - 'FKClassName' => 'Snapshot_v4p2_Price_DAO_FieldValue', - ), - ); - } - return self::$_fields; - } - - /** - * returns the names of this table. - * - * @return string - */ - public static function getTableName() { - return self::$_tableName; - } - - /** - * returns if this table needs to be logged. - * - * @return boolean - */ - public function getLog() { - return self::$_log; - } - - /** - * returns the list of fields that can be imported. - * - * @param bool $prefix - * - * @return array - */ - static function &import($prefix = FALSE) { - if (!(self::$_import)) { - self::$_import = array(); - $fields = self::fields(); - foreach ($fields as $name => $field) { - if (!empty($field['import'])) { - if ($prefix) { - self::$_import['line_item'] = &$fields[$name]; - } - else { - self::$_import[$name] = &$fields[$name]; - } - } - } - } - return self::$_import; - } - - /** - * Returns the list of fields that can be exported. - * - * @param bool $prefix - * - * @return array - */ - static function &export($prefix = FALSE) { - if (!(self::$_export)) { - self::$_export = array(); - $fields = self::fields(); - foreach ($fields as $name => $field) { - if (!empty($field['export'])) { - if ($prefix) { - self::$_export['line_item'] = &$fields[$name]; - } - else { - self::$_export[$name] = &$fields[$name]; - } - } - } - } - return self::$_export; - } -} diff --git a/civicrm/CRM/Upgrade/Snapshot/V4p2/Price/DAO/Set.php b/civicrm/CRM/Upgrade/Snapshot/V4p2/Price/DAO/Set.php deleted file mode 100644 index 48e33804a8..0000000000 --- a/civicrm/CRM/Upgrade/Snapshot/V4p2/Price/DAO/Set.php +++ /dev/null @@ -1,332 +0,0 @@ -<?php -/* -+--------------------------------------------------------------------+ -| CiviCRM version 5 | -+--------------------------------------------------------------------+ -| Copyright CiviCRM LLC (c) 2004-2019 | -+--------------------------------------------------------------------+ -| This file is a part of CiviCRM. | -| | -| CiviCRM is free software; you can copy, modify, and distribute it | -| under the terms of the GNU Affero General Public License | -| Version 3, 19 November 2007 and the CiviCRM Licensing Exception. | -| | -| CiviCRM is distributed in the hope that it will be useful, but | -| WITHOUT ANY WARRANTY; without even the implied warranty of | -| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | -| See the GNU Affero General Public License for more details. | -| | -| You should have received a copy of the GNU Affero General Public | -| License and the CiviCRM Licensing Exception along | -| with this program; if not, contact CiviCRM LLC | -| at info[AT]civicrm[DOT]org. If you have questions about the | -| GNU Affero General Public License or the licensing of CiviCRM, | -| see the CiviCRM license FAQ at http://civicrm.org/licensing | -+--------------------------------------------------------------------+ -*/ -/** - * - * @package CRM - * @copyright CiviCRM LLC (c) 2004-2019 - * $Id$ - * - */ -require_once 'CRM/Core/DAO.php'; -require_once 'CRM/Utils/Type.php'; - -/** - * Class CRM_Upgrade_Snapshot_V4p2_Price_DAO_Set - */ -class CRM_Upgrade_Snapshot_V4p2_Price_DAO_Set extends CRM_Core_DAO { - /** - * static instance to hold the table name - * - * @var string - */ - static $_tableName = 'civicrm_price_set'; - /** - * static instance to hold the field values - * - * @var array - */ - static $_fields = NULL; - /** - * static instance to hold the FK relationships - * - * @var string - */ - static $_links = NULL; - /** - * static instance to hold the values that can - * be imported - * - * @var array - */ - static $_import = NULL; - /** - * static instance to hold the values that can - * be exported - * - * @var array - */ - static $_export = NULL; - /** - * static value to see if we should log any modifications to - * this table in the civicrm_log table - * - * @var boolean - */ - static $_log = TRUE; - /** - * Price Set - * - * @var int unsigned - */ - public $id; - /** - * Which Domain is this price-set for - * - * @var int unsigned - */ - public $domain_id; - /** - * Variable name/programmatic handle for this set of price fields. - * - * @var string - */ - public $name; - /** - * Displayed title for the Price Set. - * - * @var string - */ - public $title; - /** - * Is this price set active - * - * @var boolean - */ - public $is_active; - /** - * Description and/or help text to display before fields in form. - * - * @var text - */ - public $help_pre; - /** - * Description and/or help text to display after fields in form. - * - * @var text - */ - public $help_post; - /** - * Optional Javascript script function(s) included on the form with this price_set. Can be used for conditional - * - * @var string - */ - public $javascript; - /** - * What components are using this price set? - * - * @var string - */ - public $extends; - /** - * FK to Contribution Type(for membership price sets only). - * - * @var int unsigned - */ - public $contribution_type_id; - /** - * Is set if edited on Contribution or Event Page rather than through Manage Price Sets - * - * @var boolean - */ - public $is_quick_config; - /** - * Is this a predefined system price set (i.e. it can not be deleted, edited)? - * - * @var boolean - */ - public $is_reserved; - - /** - * Class constructor. - * - * @return \CRM_Upgrade_Snapshot_V4p2_Price_DAO_Set - */ - public function __construct() { - $this->__table = 'civicrm_price_set'; - parent::__construct(); - } - - /** - * Return foreign links. - * - * @return array - */ - public function links() { - if (!(self::$_links)) { - self::$_links = array( - 'domain_id' => 'civicrm_domain:id', - 'contribution_type_id' => 'civicrm_contribution_type:id', - ); - } - return self::$_links; - } - - /** - * Returns all the column names of this table. - * - * @return array - */ - public static function &fields() { - if (!(self::$_fields)) { - self::$_fields = array( - 'id' => array( - 'name' => 'id', - 'type' => CRM_Utils_Type::T_INT, - 'required' => TRUE, - ), - 'domain_id' => array( - 'name' => 'domain_id', - 'type' => CRM_Utils_Type::T_INT, - 'FKClassName' => 'CRM_Core_DAO_Domain', - ), - 'name' => array( - 'name' => 'name', - 'type' => CRM_Utils_Type::T_STRING, - 'title' => ts('Name'), - 'required' => TRUE, - 'maxlength' => 255, - 'size' => CRM_Utils_Type::HUGE, - ), - 'title' => array( - 'name' => 'title', - 'type' => CRM_Utils_Type::T_STRING, - 'title' => ts('Title'), - 'required' => TRUE, - 'maxlength' => 255, - 'size' => CRM_Utils_Type::HUGE, - ), - 'is_active' => array( - 'name' => 'is_active', - 'type' => CRM_Utils_Type::T_BOOLEAN, - 'default' => '', - ), - 'help_pre' => array( - 'name' => 'help_pre', - 'type' => CRM_Utils_Type::T_TEXT, - 'title' => ts('Help Pre'), - 'rows' => 4, - 'cols' => 80, - ), - 'help_post' => array( - 'name' => 'help_post', - 'type' => CRM_Utils_Type::T_TEXT, - 'title' => ts('Help Post'), - 'rows' => 4, - 'cols' => 80, - ), - 'javascript' => array( - 'name' => 'javascript', - 'type' => CRM_Utils_Type::T_STRING, - 'title' => ts('Javascript'), - 'maxlength' => 64, - 'size' => CRM_Utils_Type::BIG, - ), - 'extends' => array( - 'name' => 'extends', - 'type' => CRM_Utils_Type::T_STRING, - 'title' => ts('Extends'), - 'required' => TRUE, - 'maxlength' => 255, - 'size' => CRM_Utils_Type::HUGE, - ), - 'contribution_type_id' => array( - 'name' => 'contribution_type_id', - 'type' => CRM_Utils_Type::T_INT, - 'default' => 'UL', - 'FKClassName' => 'CRM_Contribute_DAO_ContributionType', - ), - 'is_quick_config' => array( - 'name' => 'is_quick_config', - 'type' => CRM_Utils_Type::T_BOOLEAN, - ), - 'is_reserved' => array( - 'name' => 'is_reserved', - 'type' => CRM_Utils_Type::T_BOOLEAN, - ), - ); - } - return self::$_fields; - } - - /** - * returns the names of this table. - * - * @return string - */ - public static function getTableName() { - return CRM_Core_DAO::getLocaleTableName(self::$_tableName); - } - - /** - * returns if this table needs to be logged. - * - * @return boolean - */ - public function getLog() { - return self::$_log; - } - - /** - * Returns the list of fields that can be imported. - * - * @param bool $prefix - * - * @return array - */ - static function &import($prefix = FALSE) { - if (!(self::$_import)) { - self::$_import = array(); - $fields = self::fields(); - foreach ($fields as $name => $field) { - if (!empty($field['import'])) { - if ($prefix) { - self::$_import['price_set'] = &$fields[$name]; - } - else { - self::$_import[$name] = &$fields[$name]; - } - } - } - } - return self::$_import; - } - - /** - * returns the list of fields that can be exported. - * - * @param bool $prefix - * - * @return array - */ - static function &export($prefix = FALSE) { - if (!(self::$_export)) { - self::$_export = array(); - $fields = self::fields(); - foreach ($fields as $name => $field) { - if (!empty($field['export'])) { - if ($prefix) { - self::$_export['price_set'] = &$fields[$name]; - } - else { - self::$_export[$name] = &$fields[$name]; - } - } - } - } - return self::$_export; - } -} diff --git a/civicrm/CRM/Upgrade/Snapshot/V4p2/Price/DAO/SetEntity.php b/civicrm/CRM/Upgrade/Snapshot/V4p2/Price/DAO/SetEntity.php deleted file mode 100644 index f5d46d6e4d..0000000000 --- a/civicrm/CRM/Upgrade/Snapshot/V4p2/Price/DAO/SetEntity.php +++ /dev/null @@ -1,233 +0,0 @@ -<?php -/* -+--------------------------------------------------------------------+ -| CiviCRM version 5 | -+--------------------------------------------------------------------+ -| Copyright CiviCRM LLC (c) 2004-2019 | -+--------------------------------------------------------------------+ -| This file is a part of CiviCRM. | -| | -| CiviCRM is free software; you can copy, modify, and distribute it | -| under the terms of the GNU Affero General Public License | -| Version 3, 19 November 2007 and the CiviCRM Licensing Exception. | -| | -| CiviCRM is distributed in the hope that it will be useful, but | -| WITHOUT ANY WARRANTY; without even the implied warranty of | -| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | -| See the GNU Affero General Public License for more details. | -| | -| You should have received a copy of the GNU Affero General Public | -| License and the CiviCRM Licensing Exception along | -| with this program; if not, contact CiviCRM LLC | -| at info[AT]civicrm[DOT]org. If you have questions about the | -| GNU Affero General Public License or the licensing of CiviCRM, | -| see the CiviCRM license FAQ at http://civicrm.org/licensing | -+--------------------------------------------------------------------+ -*/ -/** - * - * @package CRM - * @copyright CiviCRM LLC (c) 2004-2019 - * $Id$ - * - */ -require_once 'CRM/Core/DAO.php'; -require_once 'CRM/Utils/Type.php'; - -/** - * Class CRM_Upgrade_Snapshot_V4p2_Price_DAO_SetEntity - */ -class CRM_Upgrade_Snapshot_V4p2_Price_DAO_SetEntity extends CRM_Core_DAO { - /** - * static instance to hold the table name - * - * @var string - */ - static $_tableName = 'civicrm_price_set_entity'; - /** - * static instance to hold the field values - * - * @var array - */ - static $_fields = NULL; - /** - * static instance to hold the FK relationships - * - * @var string - */ - static $_links = NULL; - /** - * static instance to hold the values that can - * be imported - * - * @var array - */ - static $_import = NULL; - /** - * static instance to hold the values that can - * be exported - * - * @var array - */ - static $_export = NULL; - /** - * static value to see if we should log any modifications to - * this table in the civicrm_log table - * - * @var boolean - */ - static $_log = TRUE; - /** - * Price Set Entity - * - * @var int unsigned - */ - public $id; - /** - * Table which uses this price set - * - * @var string - */ - public $entity_table; - /** - * Item in table - * - * @var int unsigned - */ - public $entity_id; - /** - * price set being used - * - * @var int unsigned - */ - public $price_set_id; - - /** - * Class constructor. - * - * @return \CRM_Upgrade_Snapshot_V4p2_Price_DAO_SetEntity - */ - public function __construct() { - $this->__table = 'civicrm_price_set_entity'; - parent::__construct(); - } - - /** - * Return foreign links. - * - * @return array - */ - public function links() { - if (!(self::$_links)) { - self::$_links = array( - 'price_set_id' => 'civicrm_price_set:id', - ); - } - return self::$_links; - } - - /** - * Returns all the column names of this table. - * - * @return array - */ - public static function &fields() { - if (!(self::$_fields)) { - self::$_fields = array( - 'id' => array( - 'name' => 'id', - 'type' => CRM_Utils_Type::T_INT, - 'required' => TRUE, - ), - 'entity_table' => array( - 'name' => 'entity_table', - 'type' => CRM_Utils_Type::T_STRING, - 'title' => ts('Entity Table'), - 'required' => TRUE, - 'maxlength' => 64, - 'size' => CRM_Utils_Type::BIG, - ), - 'entity_id' => array( - 'name' => 'entity_id', - 'type' => CRM_Utils_Type::T_INT, - 'required' => TRUE, - ), - 'price_set_id' => array( - 'name' => 'price_set_id', - 'type' => CRM_Utils_Type::T_INT, - 'required' => TRUE, - 'FKClassName' => 'Snapshot_v4p2_Price_DAO_Set', - ), - ); - } - return self::$_fields; - } - - /** - * returns the names of this table. - * - * @return string - */ - public static function getTableName() { - return self::$_tableName; - } - - /** - * returns if this table needs to be logged. - * - * @return boolean - */ - public function getLog() { - return self::$_log; - } - - /** - * Returns the list of fields that can be imported. - * - * @param bool $prefix - * - * @return array - */ - static function &import($prefix = FALSE) { - if (!(self::$_import)) { - self::$_import = array(); - $fields = self::fields(); - foreach ($fields as $name => $field) { - if (!empty($field['import'])) { - if ($prefix) { - self::$_import['price_set_entity'] = &$fields[$name]; - } - else { - self::$_import[$name] = &$fields[$name]; - } - } - } - } - return self::$_import; - } - - /** - * returns the list of fields that can be exported. - * - * @param bool $prefix - * - * @return array - */ - static function &export($prefix = FALSE) { - if (!(self::$_export)) { - self::$_export = array(); - $fields = self::fields(); - foreach ($fields as $name => $field) { - if (!empty($field['export'])) { - if ($prefix) { - self::$_export['price_set_entity'] = &$fields[$name]; - } - else { - self::$_export[$name] = &$fields[$name]; - } - } - } - } - return self::$_export; - } -} diff --git a/civicrm/CRM/Utils/Address/BatchUpdate.php b/civicrm/CRM/Utils/Address/BatchUpdate.php index 0851276ccf..1c421a5e78 100644 --- a/civicrm/CRM/Utils/Address/BatchUpdate.php +++ b/civicrm/CRM/Utils/Address/BatchUpdate.php @@ -289,7 +289,18 @@ class CRM_Utils_Address_BatchUpdate { public function returnResult() { $result = array(); $result['is_error'] = $this->returnError; - $result['messages'] = implode("", $this->returnMessages); + $result['messages'] = ''; + // Pad message size to allow for prefix added by CRM_Core_JobManager. + $messageSize = 255; + // Ensure that each message can fit in the civicrm_job_log.data column. + foreach ($this->returnMessages as $message) { + $messageSize += strlen($message); + if ($messageSize > CRM_Utils_Type::BLOB_SIZE) { + $result['messages'] .= '...'; + break; + } + $result['messages'] .= $message; + } return $result; } diff --git a/civicrm/CRM/Utils/Cache/ArrayDecorator.php b/civicrm/CRM/Utils/Cache/ArrayDecorator.php index b3c7e091c3..c9007070c3 100644 --- a/civicrm/CRM/Utils/Cache/ArrayDecorator.php +++ b/civicrm/CRM/Utils/Cache/ArrayDecorator.php @@ -94,6 +94,7 @@ class CRM_Utils_Cache_ArrayDecorator implements CRM_Utils_Cache_Interface { } public function get($key, $default = NULL) { + CRM_Utils_Cache::assertValidKey($key); if (array_key_exists($key, $this->values) && $this->expires[$key] > CRM_Utils_Time::getTimeRaw()) { return $this->reobjectify($this->values[$key]); } @@ -110,6 +111,7 @@ class CRM_Utils_Cache_ArrayDecorator implements CRM_Utils_Cache_Interface { } public function delete($key) { + CRM_Utils_Cache::assertValidKey($key); unset($this->values[$key]); unset($this->expires[$key]); return $this->delegate->delete($key); @@ -126,6 +128,7 @@ class CRM_Utils_Cache_ArrayDecorator implements CRM_Utils_Cache_Interface { } public function has($key) { + CRM_Utils_Cache::assertValidKey($key); if (array_key_exists($key, $this->values) && $this->expires[$key] > CRM_Utils_Time::getTimeRaw()) { return TRUE; } diff --git a/civicrm/CRM/Utils/Cache/FastArrayDecorator.php b/civicrm/CRM/Utils/Cache/FastArrayDecorator.php index 5926f23354..82ef578d72 100644 --- a/civicrm/CRM/Utils/Cache/FastArrayDecorator.php +++ b/civicrm/CRM/Utils/Cache/FastArrayDecorator.php @@ -99,6 +99,7 @@ class CRM_Utils_Cache_FastArrayDecorator implements CRM_Utils_Cache_Interface { } public function get($key, $default = NULL) { + CRM_Utils_Cache::assertValidKey($key); if (array_key_exists($key, $this->values)) { return $this->values[$key]; } @@ -114,6 +115,7 @@ class CRM_Utils_Cache_FastArrayDecorator implements CRM_Utils_Cache_Interface { } public function delete($key) { + CRM_Utils_Cache::assertValidKey($key); unset($this->values[$key]); return $this->delegate->delete($key); } diff --git a/civicrm/CRM/Utils/Check/Component/Env.php b/civicrm/CRM/Utils/Check/Component/Env.php index 8e13d3e9a2..6ebef2febf 100644 --- a/civicrm/CRM/Utils/Check/Component/Env.php +++ b/civicrm/CRM/Utils/Check/Component/Env.php @@ -120,35 +120,6 @@ class CRM_Utils_Check_Component_Env extends CRM_Utils_Check_Component { return $messages; } - /** - * @return array - */ - public function checkPhpEcrypt() { - $messages = array(); - $mailingBackend = Civi::settings()->get('mailing_backend'); - if (!is_array($mailingBackend) - || !isset($mailingBackend['outBound_option']) - || $mailingBackend['outBound_option'] != CRM_Mailing_Config::OUTBOUND_OPTION_SMTP - || !CRM_Utils_Array::value('smtpAuth', $mailingBackend) - ) { - return $messages; - } - - $test_pass = 'iAmARandomString'; - $encrypted_test_pass = CRM_Utils_Crypt::encrypt($test_pass); - if ($encrypted_test_pass == base64_encode($test_pass)) { - $messages[] = new CRM_Utils_Check_Message( - __FUNCTION__, - ts('Your PHP does not include the mcrypt encryption functions. Your SMTP password will not be stored encrypted, and if you have recently upgraded from a PHP that stored it with encryption, it will not be decrypted correctly.' - ), - ts('PHP Missing Extension "mcrypt"'), - \Psr\Log\LogLevel::WARNING, - 'fa-server' - ); - } - return $messages; - } - /** * Check that the MySQL time settings match the PHP time settings. * @@ -927,4 +898,63 @@ class CRM_Utils_Check_Component_Env extends CRM_Utils_Check_Component { return $messages; } + /** + * Check for utf8mb4 support by MySQL. + * + * @return array<CRM_Utils_Check_Message> an empty array, or a list of warnings + */ + public function checkMysqlUtf8mb4() { + $messages = array(); + + if (CRM_Core_DAO::getConnection()->phptype != 'mysqli') { + return $messages; + } + + // Force utf8mb4 query to throw exception as the check expects. + $errorScope = CRM_Core_TemporaryErrorScope::useException(); + try { + // Create a temporary table to avoid implicit commit. + CRM_Core_DAO::executeQuery('CREATE TEMPORARY TABLE civicrm_utf8mb4_test (id VARCHAR(255), PRIMARY KEY(id(255))) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci ROW_FORMAT=DYNAMIC ENGINE=INNODB'); + CRM_Core_DAO::executeQuery('DROP TEMPORARY TABLE civicrm_utf8mb4_test'); + } + catch (PEAR_Exception $e) { + $messages[] = new CRM_Utils_Check_Message( + __FUNCTION__, + ts('Future versions of CiviCRM may require MySQL utf8mb4 support. It is recommended, though not yet required, to configure your MySQL server for utf8mb4 support. You will need the following MySQL server configuration: innodb_large_prefix=true innodb_file_format=barracuda innodb_file_per_table=true'), + ts('MySQL utf8mb4 Support'), + \Psr\Log\LogLevel::WARNING, + 'fa-database' + ); + } + // Ensure that the MySQL driver supports utf8mb4 encoding. + $version = mysqli_get_client_info(CRM_Core_DAO::getConnection()->connection); + if (strpos($version, 'mysqlnd') !== FALSE) { + // The mysqlnd driver supports utf8mb4 starting at version 5.0.9. + $version = preg_replace('/^\D+([\d.]+).*/', '$1', $version); + if (version_compare($version, '5.0.9', '<')) { + $messages[] = new CRM_Utils_Check_Message( + __FUNCTION__ . 'mysqlnd', + ts('It is recommended, though not yet required, to upgrade your PHP MySQL driver (mysqlnd) to >= 5.0.9 for utf8mb4 support.'), + ts('PHP MySQL Driver (mysqlnd)'), + \Psr\Log\LogLevel::WARNING, + 'fa-server' + ); + } + } + else { + // The libmysqlclient driver supports utf8mb4 starting at version 5.5.3. + if (version_compare($version, '5.5.3', '<')) { + $messages[] = new CRM_Utils_Check_Message( + __FUNCTION__ . 'libmysqlclient', + ts('It is recommended, though not yet required, to upgrade your PHP MySQL driver (libmysqlclient) to >= 5.5.3 for utf8mb4 support.'), + ts('PHP MySQL Driver (libmysqlclient)'), + \Psr\Log\LogLevel::WARNING, + 'fa-server' + ); + } + } + + return $messages; + } + } diff --git a/civicrm/CRM/Utils/PDF/Utils.php b/civicrm/CRM/Utils/PDF/Utils.php index 1a7d449621..f2ac0a3e2f 100644 --- a/civicrm/CRM/Utils/PDF/Utils.php +++ b/civicrm/CRM/Utils/PDF/Utils.php @@ -48,7 +48,7 @@ class CRM_Utils_PDF_Utils { * * @return string|void */ - public static function html2pdf(&$text, $fileName = 'civicrm.pdf', $output = FALSE, $pdfFormat = NULL) { + public static function html2pdf($text, $fileName = 'civicrm.pdf', $output = FALSE, $pdfFormat = NULL) { if (is_array($text)) { $pages = &$text; } @@ -61,7 +61,7 @@ class CRM_Utils_PDF_Utils { // PDF Page Format parameters passed in $format = array_merge($format, $pdfFormat); } - else { + elseif (!empty($pdfFormat)) { // PDF Page Format ID passed in $format = CRM_Core_BAO_PdfFormat::getById($pdfFormat); } @@ -77,18 +77,8 @@ class CRM_Utils_PDF_Utils { $b = CRM_Core_BAO_PdfFormat::getValue('margin_bottom', $format); $l = CRM_Core_BAO_PdfFormat::getValue('margin_left', $format); - $stationery_path_partial = CRM_Core_BAO_PdfFormat::getValue('stationery', $format); - - $stationery_path = NULL; - if (strlen($stationery_path_partial)) { - $doc_root = $_SERVER['DOCUMENT_ROOT']; - $stationery_path = $doc_root . "/" . $stationery_path_partial; - } - $margins = array($metric, $t, $r, $b, $l); - $config = CRM_Core_Config::singleton(); - // Add a special region for the HTML header of PDF files: $pdfHeaderRegion = CRM_Core_Region::instance('export-document-header', FALSE); $htmlHeader = ($pdfHeaderRegion) ? $pdfHeaderRegion->render('', FALSE) : ''; @@ -98,14 +88,14 @@ class CRM_Utils_PDF_Utils { <head> <meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\"/> <style>@page { margin: {$t}{$metric} {$r}{$metric} {$b}{$metric} {$l}{$metric}; }</style> - <style type=\"text/css\">@import url({$config->userFrameworkResourceURL}css/print.css);</style> + <style type=\"text/css\">@import url(" . CRM_Core_Config::singleton()->userFrameworkResourceURL . "css/print.css);</style> {$htmlHeader} </head> <body> <div id=\"crm-container\">\n"; // Strip <html>, <header>, and <body> tags from each page - $htmlElementstoStrip = array( + $htmlElementstoStrip = [ '@<head[^>]*?>.*?</head>@siu', '@<script[^>]*?>.*?</script>@siu', '@<body>@siu', @@ -113,8 +103,8 @@ class CRM_Utils_PDF_Utils { '@<html[^>]*?>@siu', '@</html>@siu', '@<!DOCTYPE[^>]*?>@siu', - ); - $htmlElementsInstead = array('', '', '', '', '', ''); + ]; + $htmlElementsInstead = ['', '', '', '', '', '']; foreach ($pages as & $page) { $page = preg_replace($htmlElementstoStrip, $htmlElementsInstead, @@ -127,12 +117,11 @@ class CRM_Utils_PDF_Utils { </div> </body> </html>"; - if ($config->wkhtmltopdfPath) { + if (CRM_Core_Config::singleton()->wkhtmltopdfPath) { return self::_html2pdf_wkhtmltopdf($paper_size, $orientation, $margins, $html, $output, $fileName); } else { return self::_html2pdf_dompdf($paper_size, $orientation, $html, $output, $fileName); - //return self::_html2pdf_tcpdf($paper_size, $orientation, $margins, $html, $output, $fileName, $stationery_path); } } diff --git a/civicrm/CRM/Utils/PagerAToZ.php b/civicrm/CRM/Utils/PagerAToZ.php index 2176b5b002..e73e46fd48 100644 --- a/civicrm/CRM/Utils/PagerAToZ.php +++ b/civicrm/CRM/Utils/PagerAToZ.php @@ -113,7 +113,7 @@ class CRM_Utils_PagerAToZ { $dynamicAlphabets = array(); while ($result->fetch()) { - $dynamicAlphabets[] = $result->sort_name; + $dynamicAlphabets[] = strtoupper($result->sort_name); } return $dynamicAlphabets; } diff --git a/civicrm/CRM/Utils/ReCAPTCHA.php b/civicrm/CRM/Utils/ReCAPTCHA.php index 4cb2045944..d1afe457a1 100644 --- a/civicrm/CRM/Utils/ReCAPTCHA.php +++ b/civicrm/CRM/Utils/ReCAPTCHA.php @@ -98,11 +98,10 @@ class CRM_Utils_ReCAPTCHA { require_once 'packages/recaptcha/recaptchalib.php'; } - // See if we are using SSL - if (CRM_Utils_System::isSSL()) { - $useSSL = TRUE; - } - $html = recaptcha_get_html($config->recaptchaPublicKey, $error, $useSSL); + // Load the Recaptcha api.js over HTTPS + $useHTTPS = TRUE; + + $html = recaptcha_get_html($config->recaptchaPublicKey, $error, $useHTTPS); $form->assign('recaptchaHTML', $html); $form->assign('recaptchaOptions', $config->recaptchaOptions); diff --git a/civicrm/CRM/Utils/SQL/TempTable.php b/civicrm/CRM/Utils/SQL/TempTable.php index cfcdbac514..7f1955003c 100644 --- a/civicrm/CRM/Utils/SQL/TempTable.php +++ b/civicrm/CRM/Utils/SQL/TempTable.php @@ -72,6 +72,8 @@ class CRM_Utils_SQL_TempTable { const CATEGORY_REGEXP = ';^[a-zA-Z0-9]+$;'; const ID_LENGTH = 37; // MAX{64} - CATEGORY_LENGTH{12} - CONST_LENGHTH{15} = 37 const ID_REGEXP = ';^[a-zA-Z0-9_]+$;'; + const INNODB = 'ENGINE=InnoDB'; + const MEMORY = 'ENGINE=MEMORY'; /** * @var bool @@ -84,6 +86,8 @@ class CRM_Utils_SQL_TempTable { protected $autodrop; + protected $memory; + /** * @return CRM_Utils_SQL_TempTable */ @@ -93,9 +97,10 @@ class CRM_Utils_SQL_TempTable { $t->id = md5(uniqid('', TRUE)); // The constant CIVICRM_TEMP_FORCE_DURABLE is for local debugging. $t->durable = CRM_Utils_Constant::value('CIVICRM_TEMP_FORCE_DURABLE', FALSE); - // I suspect it would be better to just say utf8=true, but a lot of existing queries don't do the utf8 bit. - $t->utf8 = CRM_Utils_Constant::value('CIVICRM_TEMP_FORCE_UTF8', FALSE); + // @deprecated This constant is deprecated and will be removed. + $t->utf8 = CRM_Utils_Constant::value('CIVICRM_TEMP_FORCE_UTF8', TRUE); $t->autodrop = FALSE; + $t->memory = FALSE; return $t; } @@ -126,8 +131,9 @@ class CRM_Utils_SQL_TempTable { * @return CRM_Utils_SQL_TempTable */ public function createWithQuery($selectQuery) { - $sql = sprintf('%s %s AS %s', + $sql = sprintf('%s %s %s AS %s', $this->toSQL('CREATE'), + $this->memory ? self::MEMORY : self::INNODB, $this->utf8 ? self::UTF8 : '', ($selectQuery instanceof CRM_Utils_SQL_Select ? $selectQuery->toSQL() : $selectQuery) ); @@ -144,9 +150,10 @@ class CRM_Utils_SQL_TempTable { * @return CRM_Utils_SQL_TempTable */ public function createWithColumns($columns) { - $sql = sprintf('%s (%s) %s', + $sql = sprintf('%s (%s) %s %s', $this->toSQL('CREATE'), $columns, + $this->memory ? self::MEMORY : self::INNODB, $this->utf8 ? self::UTF8 : '' ); CRM_Core_DAO::executeQuery($sql, array(), TRUE, NULL, TRUE, FALSE); @@ -215,6 +222,13 @@ class CRM_Utils_SQL_TempTable { return $this->durable; } + /** + * @return bool + */ + public function isMemory() { + return $this->memory; + } + /** * @return bool */ @@ -273,6 +287,18 @@ class CRM_Utils_SQL_TempTable { return $this; } + /** + * Set table engine to MEMORY. + * + * @param bool $value + * + * @return $this + */ + public function setMemory($value = TRUE) { + $this->memory = $value; + return $this; + } + /** * Set table collation to UTF8. * diff --git a/civicrm/CRM/Utils/System/DrupalBase.php b/civicrm/CRM/Utils/System/DrupalBase.php index e2b5a29522..a10cd92db9 100644 --- a/civicrm/CRM/Utils/System/DrupalBase.php +++ b/civicrm/CRM/Utils/System/DrupalBase.php @@ -117,26 +117,24 @@ abstract class CRM_Utils_System_DrupalBase extends CRM_Utils_System_Base { $internal = FALSE; $base = CRM_Core_Config::singleton()->resourceBase; global $base_url; + // Strip query string + $q = strpos($url, '?'); + $url_path = $q ? substr($url, 0, $q) : $url; // Handle absolute urls // compares $url (which is some unknown/untrusted value from a third-party dev) to the CMS's base url (which is independent of civi's url) // to see if the url is within our drupal dir, if it is we are able to treated it as an internal url - if (strpos($url, $base_url) === 0) { - $file = trim(str_replace($base_url, '', $url), '/'); + if (strpos($url_path, $base_url) === 0) { + $file = trim(str_replace($base_url, '', $url_path), '/'); // CRM-18130: Custom CSS URL not working if aliased or rewritten - if (file_exists(DRUPAL_ROOT . $file)) { + if (file_exists(DRUPAL_ROOT . '/' . $file)) { $url = $file; $internal = TRUE; } } // Handle relative urls that are within the CiviCRM module directory - elseif (strpos($url, $base) === 0) { + elseif (strpos($url_path, $base) === 0) { $internal = TRUE; - $url = $this->appendCoreDirectoryToResourceBase(dirname(drupal_get_path('module', 'civicrm')) . '/') . trim(substr($url, strlen($base)), '/'); - } - // Strip query string - $q = strpos($url, '?'); - if ($q && $internal) { - $url = substr($url, 0, $q); + $url = $this->appendCoreDirectoryToResourceBase(dirname(drupal_get_path('module', 'civicrm')) . '/') . trim(substr($url_path, strlen($base)), '/'); } return $internal; } diff --git a/civicrm/CRM/Utils/System/WordPress.php b/civicrm/CRM/Utils/System/WordPress.php index 27fffe2af7..f450056bdb 100644 --- a/civicrm/CRM/Utils/System/WordPress.php +++ b/civicrm/CRM/Utils/System/WordPress.php @@ -810,13 +810,11 @@ class CRM_Utils_System_WordPress extends CRM_Utils_System_Base { $contactCreated = 0; $contactMatching = 0; - // previously used $wpdb - which means WordPress *must* be bootstrapped - $wpUsers = get_users(array( - 'blog_id' => get_current_blog_id(), - 'number' => -1, - )); + global $wpdb; + $wpUserIds = $wpdb->get_col("SELECT $wpdb->users.ID FROM $wpdb->users"); - foreach ($wpUsers as $wpUserData) { + foreach ($wpUserIds as $wpUserId) { + $wpUserData = get_userdata($wpUserId); $contactCount++; if ($match = CRM_Core_BAO_UFMatch::synchronizeUFMatch($wpUserData, $wpUserData->$id, diff --git a/civicrm/CRM/Utils/Type.php b/civicrm/CRM/Utils/Type.php index 7b0aeb5133..d45392353d 100644 --- a/civicrm/CRM/Utils/Type.php +++ b/civicrm/CRM/Utils/Type.php @@ -67,6 +67,16 @@ class CRM_Utils_Type { FORTYFIVE = 45, HUGE = 45; + /** + * Maximum size of a MySQL BLOB or TEXT column in bytes. + */ + const BLOB_SIZE = 65535; + + /** + * Maximum value of a MySQL signed INT column. + */ + const INT_MAX = 2147483647; + /** * Gets the string representation for a data type. * diff --git a/civicrm/Civi/API/Subscriber/DynamicFKAuthorization.php b/civicrm/Civi/API/Subscriber/DynamicFKAuthorization.php index a00802e65e..daddd72af9 100644 --- a/civicrm/Civi/API/Subscriber/DynamicFKAuthorization.php +++ b/civicrm/Civi/API/Subscriber/DynamicFKAuthorization.php @@ -179,6 +179,9 @@ class DynamicFKAuthorization implements EventSubscriberInterface { } if (isset($apiRequest['params']['entity_table'])) { + if (!\CRM_Core_DAO_AllCoreTables::isCoreTable($apiRequest['params']['entity_table'])) { + throw new \API_Exception("Unrecognized target entity table {$apiRequest['params']['entity_table']}"); + } $this->authorizeDelegate( $apiRequest['action'], $apiRequest['params']['entity_table'], @@ -206,6 +209,10 @@ class DynamicFKAuthorization implements EventSubscriberInterface { * @throws \Civi\API\Exception\UnauthorizedException */ public function authorizeDelegate($action, $entityTable, $entityId, $apiRequest) { + if ($this->isTrusted($apiRequest)) { + return; + } + $entity = $this->getDelegatedEntityName($entityTable); if (!$entity) { throw new \API_Exception("Failed to run permission check: Unrecognized target entity table ($entityTable)"); @@ -214,10 +221,6 @@ class DynamicFKAuthorization implements EventSubscriberInterface { throw new \Civi\API\Exception\UnauthorizedException("Authorization failed on ($entity): Missing entity_id"); } - if ($this->isTrusted($apiRequest)) { - return; - } - /** * @var \Exception $exception */ diff --git a/civicrm/Civi/CCase/Analyzer.php b/civicrm/Civi/CCase/Analyzer.php index 6789360404..f4d1569bb1 100644 --- a/civicrm/Civi/CCase/Analyzer.php +++ b/civicrm/Civi/CCase/Analyzer.php @@ -132,6 +132,7 @@ class Analyzer { /** * Get a single activity record by type. + * This function is only used by SequenceListenerTest * * @param string $type * @throws \Civi\CCase\Exception\MultipleActivityException @@ -139,7 +140,7 @@ class Analyzer { */ public function getSingleActivity($type) { $idx = $this->getActivityIndex(array('activity_type_id', 'id')); - $actTypes = array_flip(\CRM_Core_PseudoConstant::activityType(TRUE, TRUE, FALSE, 'name')); + $actTypes = array_flip(\CRM_Activity_BAO_Activity::buildOptions('activity_type_id', 'validate')); $typeId = $actTypes[$type]; $count = isset($idx[$typeId]) ? count($idx[$typeId]) : 0; diff --git a/civicrm/Civi/CCase/SequenceListener.php b/civicrm/Civi/CCase/SequenceListener.php index cd60e81575..7135c84b54 100644 --- a/civicrm/Civi/CCase/SequenceListener.php +++ b/civicrm/Civi/CCase/SequenceListener.php @@ -51,7 +51,7 @@ class SequenceListener implements CaseChangeListener { return; } - $actTypes = array_flip(\CRM_Core_PseudoConstant::activityType(TRUE, TRUE, FALSE, 'name')); + $actTypes = array_flip(\CRM_Activity_BAO_Activity::buildOptions('activity_type_id', 'validate')); $actStatuses = array_flip(\CRM_Activity_BAO_Activity::getStatusesByType(\CRM_Activity_BAO_Activity::COMPLETED)); $actIndex = $analyzer->getActivityIndex(array('activity_type_id', 'status_id')); diff --git a/civicrm/Civi/Install/Requirements.php b/civicrm/Civi/Install/Requirements.php index 13506a22b2..4d2d3f72d4 100644 --- a/civicrm/Civi/Install/Requirements.php +++ b/civicrm/Civi/Install/Requirements.php @@ -40,6 +40,7 @@ class Requirements { 'checkMysqlTrigger', 'checkMysqlThreadStack', 'checkMysqlLockTables', + 'checkMysqlUtf8mb4', ); /** @@ -582,4 +583,65 @@ class Requirements { return $results; } + /** + * @param $db_config + * + * @return array + */ + public function checkMysqlUtf8mb4($db_config) { + $results = array( + 'title' => 'CiviCRM MySQL utf8mb4 Support', + 'severity' => $this::REQUIREMENT_OK, + 'details' => 'Your system supports the MySQL utf8mb4 character set.', + ); + + $conn = $this->connect($db_config); + if (!$conn) { + $results['severity'] = $this::REQUIREMENT_ERROR; + $results['details'] = 'Could not connect to database'; + return $results; + } + + if (!@mysqli_select_db($conn, $db_config['database'])) { + $results['severity'] = $this::REQUIREMENT_ERROR; + $results['details'] = 'Could not select the database'; + mysqli_close($conn); + return $results; + } + + $r = mysqli_query($conn, 'CREATE TABLE civicrm_utf8mb4_test (id VARCHAR(255), PRIMARY KEY(id(255))) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci ROW_FORMAT=DYNAMIC ENGINE=INNODB'); + if (!$r) { + $results['severity'] = $this::REQUIREMENT_WARNING; + $results['details'] = 'It is recommended, though not yet required, to configure your MySQL server for utf8mb4 support. You will need the following MySQL server configuration: innodb_large_prefix=true innodb_file_format=barracuda innodb_file_per_table=true'; + mysqli_close($conn); + return $results; + } + mysqli_query('DROP TABLE civicrm_utf8mb4_test'); + + // Ensure that the MySQL driver supports utf8mb4 encoding. + $version = mysqli_get_client_info($conn); + if (strpos($version, 'mysqlnd') !== FALSE) { + // The mysqlnd driver supports utf8mb4 starting at version 5.0.9. + $version = preg_replace('/^\D+([\d.]+).*/', '$1', $version); + if (version_compare($version, '5.0.9', '<')) { + $results['severity'] = $this::REQUIREMENT_WARNING; + $results['details'] = 'It is recommended, though not yet required, to upgrade your PHP MySQL driver (mysqlnd) to >= 5.0.9 for utf8mb4 support.'; + mysqli_close($conn); + return $results; + } + } + else { + // The libmysqlclient driver supports utf8mb4 starting at version 5.5.3. + if (version_compare($version, '5.5.3', '<')) { + $results['severity'] = $this::REQUIREMENT_WARNING; + $results['details'] = 'It is recommended, though not yet required, to upgrade your PHP MySQL driver (libmysqlclient) to >= 5.5.3 for utf8mb4 support.'; + mysqli_close($conn); + return $results; + } + } + + mysqli_close($conn); + return $results; + } + } diff --git a/civicrm/Civi/Test/Api3TestTrait.php b/civicrm/Civi/Test/Api3TestTrait.php index 2a10abf7e7..96e41b9d7a 100644 --- a/civicrm/Civi/Test/Api3TestTrait.php +++ b/civicrm/Civi/Test/Api3TestTrait.php @@ -202,7 +202,12 @@ trait Api3TestTrait { ); $result = $this->civicrm_api($entity, 'getsingle', $params); if (!is_array($result) || !empty($result['is_error']) || isset($result['values'])) { - throw new \Exception('Invalid getsingle result' . print_r($result, TRUE)); + $unfilteredResult = $this->civicrm_api($entity, 'get', $params); + throw new \Exception( + 'Invalid getsingle result' . print_r($result, TRUE) + . "\n entity: $entity . \n params \n " . print_r($params, TRUE) + . "\n entities retrieved with blank params \n" . print_r($unfilteredResult, TRUE) + ); } if ($checkAgainst) { // @todo - have gone with the fn that unsets id? should we check id? diff --git a/civicrm/Civi/Token/TokenRow.php b/civicrm/Civi/Token/TokenRow.php index cb5982f004..883e29089a 100644 --- a/civicrm/Civi/Token/TokenRow.php +++ b/civicrm/Civi/Token/TokenRow.php @@ -218,6 +218,7 @@ class TokenRow { case 'text/html': // Plain => HTML. foreach ($textTokens as $entity => $values) { + $entityFields = civicrm_api3($entity, "getFields", array('api_action' => 'get')); foreach ($values as $field => $value) { if (!isset($htmlTokens[$entity][$field])) { // CRM-18420 - Activity Details Field are enclosed within <p>, @@ -226,6 +227,10 @@ class TokenRow { if ($entity == 'activity' && $field == 'details') { $htmlTokens[$entity][$field] = $value; } + elseif (\CRM_Utils_Array::value('data_type', \CRM_Utils_Array::value($field, $entityFields['values'])) == 'Memo') { + // Memo fields aka custom fields of type Note are html. + $htmlTokens[$entity][$field] = CRM_Utils_String::purifyHTML($value); + } else { $htmlTokens[$entity][$field] = htmlentities($value); } diff --git a/civicrm/ang/crmUtil.js b/civicrm/ang/crmUtil.js index a8b0370ad4..ab460ab7e9 100644 --- a/civicrm/ang/crmUtil.js +++ b/civicrm/ang/crmUtil.js @@ -346,4 +346,16 @@ }; }); + angular.module('crmUtil').factory('crmLoadScript', function($q) { + return function(url) { + var deferred = $q.defer(); + + CRM.loadScript(url).done(function() { + deferred.resolve(true); + }); + + return deferred.promise; + }; + }); + })(angular, CRM.$, CRM._); diff --git a/civicrm/api/v3/Activity.php b/civicrm/api/v3/Activity.php index fc84cc1d73..f7a8e492f1 100644 --- a/civicrm/api/v3/Activity.php +++ b/civicrm/api/v3/Activity.php @@ -302,16 +302,6 @@ function civicrm_api3_activity_get($params) { $options = _civicrm_api3_get_options_from_params($params, FALSE, 'Activity', 'get'); $sql = CRM_Utils_SQL_Select::fragment(); - if (empty($params['target_contact_id']) && empty($params['source_contact_id']) - && empty($params['assignee_contact_id']) && - !empty($params['check_permissions']) && !CRM_Core_Permission::check('view all activities') - && !CRM_Core_Permission::check('view all contacts') - ) { - // Force join on the activity contact table. - // @todo get this & other acl filters to work, remove check further down. - //$params['contact_id'] = array('IS NOT NULL' => TRUE); - } - _civicrm_api3_activity_get_extraFilters($params, $sql); // Handle is_overdue sort @@ -342,15 +332,6 @@ function civicrm_api3_activity_get($params) { return civicrm_api3_create_success($activities, $params, 'Activity', 'get'); } - if (!empty($params['check_permissions']) && !CRM_Core_Permission::check('view all activities')) { - // @todo get this to work at the query level - see contact_id join above. - foreach ($activities as $activity) { - if (!CRM_Activity_BAO_Activity::checkPermission($activity['id'], CRM_Core_Action::VIEW)) { - unset($activities[$activity['id']]); - } - } - } - $activities = _civicrm_api3_activity_get_formatResult($params, $activities, $options); //legacy custom data get - so previous formatted response is still returned too return civicrm_api3_create_success($activities, $params, 'Activity', 'get'); @@ -452,6 +433,8 @@ function _civicrm_api3_activity_get_extraFilters(&$params, &$sql) { * @param array $params * API request parameters. * @param array $activities + * @param array $options + * Options array (pre-processed to extract 'return' from params). * * @return array * new activities list @@ -463,19 +446,14 @@ function _civicrm_api3_activity_get_formatResult($params, $activities, $options) $returns = $options['return']; foreach ($params as $n => $v) { + // @todo - the per-parsing on options should have already done this. if (substr($n, 0, 7) == 'return.') { $returnkey = substr($n, 7); $returns[$returnkey] = $v; } } - $returns['source_contact_id'] = 1; - if (!empty($returns['target_contact_name'])) { - $returns['target_contact_id'] = 1; - } - if (!empty($returns['assignee_contact_name'])) { - $returns['assignee_contact_id'] = 1; - } + _civicrm_api3_activity_fill_activity_contact_names($activities, $params, $returns); $tagGet = array('tag_id', 'entity_id'); $caseGet = $caseIds = array(); @@ -493,34 +471,14 @@ function _civicrm_api3_activity_get_formatResult($params, $activities, $options) foreach ($returns as $n => $v) { switch ($n) { case 'assignee_contact_id': - foreach ($activities as $key => $activityArray) { - $cids = $activities[$key]['assignee_contact_id'] = CRM_Activity_BAO_ActivityAssignment::retrieveAssigneeIdsByActivityId($activityArray['id']); - if ($cids && !empty($returns['assignee_contact_name'])) { - foreach ($cids as $cid) { - $activities[$key]['assignee_contact_name'][$cid] = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact', $cid, 'display_name'); - } - } - } - break; - case 'target_contact_id': - foreach ($activities as $key => $activityArray) { - $cids = $activities[$key]['target_contact_id'] = CRM_Activity_BAO_ActivityTarget::retrieveTargetIdsByActivityId($activityArray['id']); - if ($cids && !empty($returns['target_contact_name'])) { - foreach ($cids as $cid) { - $activities[$key]['target_contact_name'][$cid] = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact', $cid, 'display_name'); - } + foreach ($activities as &$activity) { + if (!isset($activity[$n])) { + $activity[$n] = []; } } - break; case 'source_contact_id': - foreach ($activities as $key => $activityArray) { - $cid = $activities[$key]['source_contact_id'] = CRM_Activity_BAO_Activity::getSourceContactID($activityArray['id']); - if ($cid && !empty($returns['source_contact_name'])) { - $activities[$key]['source_contact_name'] = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact', $cid, 'display_name'); - } - } break; case 'tag_id': @@ -613,6 +571,66 @@ function _civicrm_api3_activity_get_formatResult($params, $activities, $options) return $activities; } +/** + * Append activity contact details to activity results. + * + * Adds id & name of activity contacts to results array if check_permissions + * does not block access to them. + * + * For historical reasons source_contact_id is always added & is not an array. + * The others are added depending on requested return params. + * + * @param array $activities + * @param array $params + * @param array $returns + */ +function _civicrm_api3_activity_fill_activity_contact_names(&$activities, $params, $returns) { + $contactTypes = array_flip(CRM_Activity_BAO_ActivityContact::buildOptions('record_type_id', 'validate')); + $assigneeType = $contactTypes['Activity Assignees']; + $targetType = $contactTypes['Activity Targets']; + $sourceType = $contactTypes['Activity Source']; + $typeMap = [ + $assigneeType => 'assignee', + $sourceType => 'source', + $targetType => 'target' + ]; + + $activityContactTypes = [$sourceType]; + + if (!empty($returns['target_contact_name']) || !empty($returns['target_contact_id'])) { + $activityContactTypes[] = $targetType; + } + if (!empty($returns['assignee_contact_name']) || (!empty($returns['assignee_contact_id']))) { + $activityContactTypes[] = $assigneeType; + } + $activityContactParams = [ + 'activity_id' => ['IN' => array_keys($activities)], + 'return' => [ + 'activity_id', + 'record_type_id', + 'contact_id.display_name', + 'contact_id' + ], + 'check_permissions' => !empty($params['check_permissions']), + ]; + if (count($activityContactTypes) < 3) { + $activityContactParams['record_type_id'] = ['IN' => $activityContactTypes]; + } + $activityContacts = civicrm_api3('ActivityContact', 'get', $activityContactParams)['values']; + foreach ($activityContacts as $activityContact) { + $contactID = $activityContact['contact_id']; + $recordType = $typeMap[$activityContact['record_type_id']]; + if (in_array($recordType, ['target', 'assignee'])) { + $activities[$activityContact['activity_id']][$recordType . '_contact_id'][] = $contactID; + $activities[$activityContact['activity_id']][$recordType . '_contact_name'][$contactID] = isset($activityContact['contact_id.display_name']) ? $activityContact['contact_id.display_name'] : ''; + } + else { + $activities[$activityContact['activity_id']]['source_contact_id'] = $contactID; + $activities[$activityContact['activity_id']]['source_contact_name'] = isset($activityContact['contact_id.display_name']) ? $activityContact['contact_id.display_name'] : ''; + } + } +} + /** * Delete a specified Activity. diff --git a/civicrm/api/v3/Contact.php b/civicrm/api/v3/Contact.php index 07913f9001..e2781de714 100644 --- a/civicrm/api/v3/Contact.php +++ b/civicrm/api/v3/Contact.php @@ -430,13 +430,15 @@ function _civicrm_api3_contact_get_supportanomalies(&$params, &$options) { } if (isset($params['group'])) { $groups = $params['group']; - $allGroups = CRM_Core_PseudoConstant::group(); + $groupsByTitle = CRM_Core_PseudoConstant::group(); + $groupsByName = CRM_Contact_BAO_GroupContact::buildOptions('group_id', 'validate'); + $allGroups = array_merge(array_flip($groupsByTitle), array_flip($groupsByName)); if (is_array($groups) && in_array(key($groups), CRM_Core_DAO::acceptedSQLOperators(), TRUE)) { // Get the groups array. $groupsArray = $groups[key($groups)]; foreach ($groupsArray as &$group) { - if (!is_numeric($group) && array_search($group, $allGroups)) { - $group = array_search($group, $allGroups); + if (!is_numeric($group) && !empty($allGroups[$group])) { + $group = $allGroups[$group]; } } // Now reset the $groups array with the ids not the titles. @@ -445,17 +447,17 @@ function _civicrm_api3_contact_get_supportanomalies(&$params, &$options) { // handle format like 'group' => array('title1', 'title2'). elseif (is_array($groups)) { foreach ($groups as $k => &$group) { - if (!is_numeric($group) && array_search($group, $allGroups)) { - $group = array_search($group, $allGroups); + if (!is_numeric($group) && !empty($allGroups[$group])) { + $group = $allGroups[$group]; } - if (!is_numeric($k) && array_search($k, $allGroups)) { + if (!is_numeric($k) && !empty($allGroups[$k])) { unset($groups[$k]); - $groups[array_search($k, $allGroups)] = $group; + $groups[$allGroups[$k]] = $group; } } } - elseif (!is_numeric($groups) && array_search($groups, $allGroups)) { - $groups = array_search($groups, $allGroups); + elseif (!is_numeric($groups) && !empty($allGroups[$groups])) { + $groups = $allGroups[$groups]; } $params['group'] = $groups; } diff --git a/civicrm/CRM/Report/Form/Event.php b/civicrm/api/v3/Exception.php similarity index 64% rename from civicrm/CRM/Report/Form/Event.php rename to civicrm/api/v3/Exception.php index 4e459783d6..9c50d4a35c 100644 --- a/civicrm/CRM/Report/Form/Event.php +++ b/civicrm/api/v3/Exception.php @@ -24,16 +24,39 @@ | see the CiviCRM license FAQ at http://civicrm.org/licensing | +--------------------------------------------------------------------+ */ - /** + * Get a Dedupe Exception. * - * @package CRM - * @copyright CiviCRM LLC (c) 2004-2019 - * $Id$ + * @param array $params + * Array per getfields metadata. * + * @return array + * Array of all found dedupe exception object property values. */ -class CRM_Report_Form_Event extends CRM_Report_Form { - // Nothing here. - // FIXME: Do these reports really have nothing in common? Really? - +function civicrm_api3_exception_get($params) { + return _civicrm_api3_basic_get(_civicrm_api3_get_BAO(__FUNCTION__), $params); +} +/** + * Create or update an dedupe exception. + * + * @param array $params + * Array per getfields metadata. + * + * @return array api result array + */ +function civicrm_api3_exception_create($params) { + return _civicrm_api3_basic_create(_civicrm_api3_get_BAO(__FUNCTION__), $params, 'Exception'); +} +/** + * Delete an existing Exception. + * + * This method is used to delete any existing Exception given its id. + * + * @param array $params + * [id] + * + * @return array api result array + */ +function civicrm_api3_exception_delete($params) { + return _civicrm_api3_basic_delete(_civicrm_api3_get_BAO(__FUNCTION__), $params); } diff --git a/civicrm/api/v3/Payment.php b/civicrm/api/v3/Payment.php index 355ea7ad50..a4292a5b6b 100644 --- a/civicrm/api/v3/Payment.php +++ b/civicrm/api/v3/Payment.php @@ -235,3 +235,49 @@ function _civicrm_api3_payment_cancel_spec(&$params) { ), ); } + +/** + * Send a payment confirmation. + * + * @param array $params + * Input parameters. + * + * @return array + * @throws Exception + */ +function civicrm_api3_payment_sendconfirmation($params) { + $allowedParams = [ + 'receipt_from_email', + 'receipt_from_name', + 'cc_receipt', + 'bcc_receipt', + 'receipt_text', + 'id', + ]; + $input = array_intersect_key($params, array_flip($allowedParams)); + // use either the contribution or membership receipt, based on whether it’s a membership-related contrib or not + $result = CRM_Financial_BAO_Payment::sendConfirmation($input); + return civicrm_api3_create_success([ + $params['id'] => [ + 'is_sent' => $result[0], + 'subject' => $result[1], + 'message_txt' => $result[2], + 'message_html' => $result[3], + ]]); +} + +/** + * Adjust Metadata for sendconfirmation action. + * + * The metadata is used for setting defaults, documentation & validation. + * + * @param array $params + * Array of parameters determined by getfields. + */ +function _civicrm_api3_payment_sendconfirmation_spec(&$params) { + $params['id'] = array( + 'api.required' => 1, + 'title' => ts('Payment ID'), + 'type' => CRM_Utils_Type::T_INT, + ); +} diff --git a/civicrm/bower.json b/civicrm/bower.json index fbd2229b43..e40429345d 100644 --- a/civicrm/bower.json +++ b/civicrm/bower.json @@ -30,6 +30,7 @@ "font-awesome": "~4", "angular-bootstrap": "^2.5.0", "angular-sanitize": "~1.5.0", + "smartmenus": "~1.1", "phantomjs-polyfill": "^0.0.2" }, "resolutions": { diff --git a/civicrm/bower_components/jquery-ui/.bower.json b/civicrm/bower_components/jquery-ui/.bower.json index a37977e293..d28097dd88 100644 --- a/civicrm/bower_components/jquery-ui/.bower.json +++ b/civicrm/bower_components/jquery-ui/.bower.json @@ -17,6 +17,6 @@ "commit": "44ecf3794cc56b65954cc19737234a3119d036cc" }, "_source": "https://github.com/components/jqueryui.git", - "_target": ">=1.9", + "_target": "~1.12", "_originalSource": "jquery-ui" } \ No newline at end of file diff --git a/civicrm/bower_components/smartmenus/.bower.json b/civicrm/bower_components/smartmenus/.bower.json new file mode 100644 index 0000000000..e655f19ef2 --- /dev/null +++ b/civicrm/bower_components/smartmenus/.bower.json @@ -0,0 +1,58 @@ +{ + "name": "smartmenus", + "title": "SmartMenus", + "description": "Advanced jQuery website menu plugin. Mobile first, responsive and accessible list-based website menus that work on all devices.", + "keywords": [ + "menu", + "navigation", + "accessible", + "responsive", + "mobile", + "ui", + "jquery-plugin", + "bootstrap", + "ecosystem:jquery" + ], + "version": "1.1.0", + "version_keyboard_addon": "0.4.0", + "version_bootstrap_addon": "0.4.0", + "version_bootstrap_4_addon": "0.1.0", + "main": [ + "dist/jquery.smartmenus.js" + ], + "author": { + "name": "Vasil Dinkov", + "email": "vasko.dinkov@gmail.com", + "url": "http://vadikom.com" + }, + "licenses": [ + { + "type": "MIT", + "url": "http://www.opensource.org/licenses/MIT" + } + ], + "repository": { + "type": "git", + "url": "git://github.com/vadikom/smartmenus.git" + }, + "bugs": "https://github.com/vadikom/smartmenus/issues", + "homepage": "http://www.smartmenus.org/", + "docs": "http://www.smartmenus.org/docs/", + "download": "http://www.smartmenus.org/download/", + "dependencies": { + "jquery": ">=1.7.0" + }, + "ignore": [ + ".gitignore", + "Gruntfile.js" + ], + "_release": "1.1.0", + "_resolution": { + "type": "version", + "tag": "1.1.0", + "commit": "9a73dd16049c8ac0b000d0c7b23b47defed61015" + }, + "_source": "https://github.com/vadikom/smartmenus.git", + "_target": "~1.1", + "_originalSource": "smartmenus" +} \ No newline at end of file diff --git a/civicrm/bower_components/smartmenus/LICENSE-MIT b/civicrm/bower_components/smartmenus/LICENSE-MIT new file mode 100644 index 0000000000..314d100f4f --- /dev/null +++ b/civicrm/bower_components/smartmenus/LICENSE-MIT @@ -0,0 +1,22 @@ +Copyright (c) Vasil Dinkov, Vadikom Web Ltd. + +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/bower_components/smartmenus/README.md b/civicrm/bower_components/smartmenus/README.md new file mode 100644 index 0000000000..fce08bef44 --- /dev/null +++ b/civicrm/bower_components/smartmenus/README.md @@ -0,0 +1,88 @@ +# SmartMenus + +Advanced jQuery website menu plugin. Mobile first, responsive and accessible list-based website menus that work on all devices. +Check out [the demo page](http://vadikom.github.io/smartmenus/src/demo/). + +## Quick start + +- [Download the latest release](http://www.smartmenus.org/download/). +- Install with [Bower](http://bower.io): `bower install smartmenus`. +- Install with [npm](https://www.npmjs.com): `npm install smartmenus`. +- Clone the repo: `git clone https://github.com/vadikom/smartmenus.git`. + +Check out the [project documentation](http://www.smartmenus.org/docs/) for quick setup instructions, API reference, tutorials and more. + +## Addons usage as modules +If you need to use any of the addons from the "addons" directory as an AMD or CommonJS module: + +### AMD +Make sure your SmartMenus jQuery plugin module is named `smartmenus` since the addons require that name. For example, in RequireJS you may need to add this in your config: +```javascript +requirejs.config({ + "paths": { + 'smartmenus': 'jquery.smartmenus.min' + } + // ... +``` + +### CommonJS (npm) +The addons are available as separate npm packages so you could properly install/require them in your project in addition to `jquery` and `smartmenus`: + +- Bootstrap 4 Addon: `npm install smartmenus-bootstrap-4` + +- Bootstrap Addon: `npm install smartmenus-bootstrap` + +- Keyboard Addon: `npm install smartmenus-keyboard` + +#### Example with npm + Browserify + +package.json: +```javascript +{ + "name": "myapp-using-smartmenus", + "version": "1.0.0", + "license": "MIT", + "dependencies": { + "jquery": ">=2.1.3", + "smartmenus": ">=1.1.0", + "smartmenus-keyboard": ">=0.4.0" + }, + "devDependencies": { + "browserify": ">=9.0.3" + } +} +``` + +entry.js: +```javascript +var jQuery = require('jquery'); +require('smartmenus'); +require('smartmenus-keyboard'); + +jQuery(function() { + jQuery('#main-menu').smartmenus(); +}); +``` + +Run browserify to create bundle.js: `browserify entry.js > bundle.js` + +## Homepage + +<http://www.smartmenus.org/> + +## Documentation + +<http://www.smartmenus.org/docs/> + +## Community and support + +- Visit the [Community forums](http://www.smartmenus.org/forums/) for free support. +- [Premium support](http://www.smartmenus.org/support/premium-support/) is also available. +- Read and subscribe to [the project blog](http://www.smartmenus.org/blog/). +- Follow [@vadikom on Twitter](http://twitter.com/vadikom). + +## Bugs and issues + +For bugs and issues only please. For support requests please use the [Community forums](http://www.smartmenus.org/forums/) or contact us directly via our [Premium support](http://www.smartmenus.org/support/premium-support/). + +<https://github.com/vadikom/smartmenus/issues> \ No newline at end of file diff --git a/civicrm/bower_components/smartmenus/bower.json b/civicrm/bower_components/smartmenus/bower.json new file mode 100644 index 0000000000..ecac981f16 --- /dev/null +++ b/civicrm/bower_components/smartmenus/bower.json @@ -0,0 +1,49 @@ +{ + "name": "smartmenus", + "title": "SmartMenus", + "description": "Advanced jQuery website menu plugin. Mobile first, responsive and accessible list-based website menus that work on all devices.", + "keywords": [ + "menu", + "navigation", + "accessible", + "responsive", + "mobile", + "ui", + "jquery-plugin", + "bootstrap", + "ecosystem:jquery" + ], + "version": "1.1.0", + "version_keyboard_addon": "0.4.0", + "version_bootstrap_addon": "0.4.0", + "version_bootstrap_4_addon": "0.1.0", + "main": [ + "dist/jquery.smartmenus.js" + ], + "author": { + "name": "Vasil Dinkov", + "email": "vasko.dinkov@gmail.com", + "url": "http://vadikom.com" + }, + "licenses": [ + { + "type": "MIT", + "url": "http://www.opensource.org/licenses/MIT" + } + ], + "repository": { + "type": "git", + "url": "git://github.com/vadikom/smartmenus.git" + }, + "bugs": "https://github.com/vadikom/smartmenus/issues", + "homepage": "http://www.smartmenus.org/", + "docs": "http://www.smartmenus.org/docs/", + "download": "http://www.smartmenus.org/download/", + "dependencies": { + "jquery": ">=1.7.0" + }, + "ignore": [ + ".gitignore", + "Gruntfile.js" + ] +} \ No newline at end of file diff --git a/civicrm/bower_components/smartmenus/dist/addons/bootstrap-4/jquery.smartmenus.bootstrap-4.css b/civicrm/bower_components/smartmenus/dist/addons/bootstrap-4/jquery.smartmenus.bootstrap-4.css new file mode 100644 index 0000000000..f4ae564a1f --- /dev/null +++ b/civicrm/bower_components/smartmenus/dist/addons/bootstrap-4/jquery.smartmenus.bootstrap-4.css @@ -0,0 +1,128 @@ +/* + You probably do not need to edit this at all. + + Add some SmartMenus required styles not covered in Bootstrap 4's default CSS. + These are theme independent and should work with any Bootstrap 4 theme mod. +*/ + + +/* Carets in collapsible mode (make them look like +/- buttons) */ +.navbar-nav.sm-collapsible .sub-arrow { + position: absolute; + top: 50%; + right: 0; + margin: -0.7em 0.5em 0 0; + border: 1px solid rgba(0, 0, 0, .1); + border-radius: .25rem; + padding: 0; + width: 2em; + height: 1.4em; + font-size: 1.25rem; + line-height: 1.2em; + text-align: center; +} +.navbar-nav.sm-collapsible .sub-arrow::before { + content: '+'; +} +.navbar-nav.sm-collapsible .show > a > .sub-arrow::before { + content: '-'; +} +.navbar-dark .navbar-nav.sm-collapsible .nav-link .sub-arrow { + border-color: rgba(255, 255, 255, .1); +} +/* make sure there's room for the carets */ +.navbar-nav.sm-collapsible .has-submenu { + padding-right: 3em; +} +/* keep the carets properly positioned */ +.navbar-nav.sm-collapsible .nav-link, +.navbar-nav.sm-collapsible .dropdown-item { + position: relative; +} + + +/* Nav carets in expanded mode */ +.navbar-nav:not(.sm-collapsible) .nav-link .sub-arrow { + display: inline-block; + width: 0; + height: 0; + margin-left: .255em; + vertical-align: .255em; + border-top: .3em solid; + border-right: .3em solid transparent; + border-left: .3em solid transparent; +} +/* point the arrows up for .fixed-bottom navbars */ +.fixed-bottom .navbar-nav:not(.sm-collapsible) .nav-link .sub-arrow, +.fixed-bottom .navbar-nav:not(.sm-collapsible):not([data-sm-skip]) .dropdown-toggle::after { + border-top: 0; + border-bottom: .3em solid; +} + + +/* Dropdown carets in expanded mode */ +.navbar-nav:not(.sm-collapsible) .dropdown-item .sub-arrow, +.navbar-nav:not(.sm-collapsible):not([data-sm-skip]) .dropdown-menu .dropdown-toggle::after { + position: absolute; + top: 50%; + right: 0; + width: 0; + height: 0; + margin-top: -.3em; + margin-right: 1em; + border-top: .3em solid transparent; + border-bottom: .3em solid transparent; + border-left: .3em solid; +} +/* make sure there's room for the carets */ +.navbar-nav:not(.sm-collapsible) .dropdown-item.has-submenu { + padding-right: 2em; +} + + +/* Scrolling arrows for tall menus */ +.navbar-nav .scroll-up, +.navbar-nav .scroll-down { + position: absolute; + display: none; + visibility: hidden; + height: 20px; + overflow: hidden; + text-align: center; +} +.navbar-nav .scroll-up-arrow, +.navbar-nav .scroll-down-arrow { + position: absolute; + top: -2px; + left: 50%; + margin-left: -8px; + width: 0; + height: 0; + overflow: hidden; + border-top: 7px solid transparent; + border-right: 7px solid transparent; + border-bottom: 7px solid; + border-left: 7px solid transparent; +} +.navbar-nav .scroll-down-arrow { + top: 6px; + border-top: 7px solid; + border-right: 7px solid transparent; + border-bottom: 7px solid transparent; + border-left: 7px solid transparent; +} + + +/* Add some spacing for 2+ level sub menus in collapsible mode */ +.navbar-nav.sm-collapsible .dropdown-menu .dropdown-menu { + margin: .5em; +} + + +/* Fix SmartMenus sub menus auto width (subMenusMinWidth/subMenusMaxWidth options) */ +.navbar-nav:not([data-sm-skip]) .dropdown-item { + white-space: normal; +} +.navbar-nav:not(.sm-collapsible) .sm-nowrap > li > .dropdown-item { + white-space: nowrap; +} \ No newline at end of file diff --git a/civicrm/bower_components/smartmenus/dist/addons/bootstrap-4/jquery.smartmenus.bootstrap-4.js b/civicrm/bower_components/smartmenus/dist/addons/bootstrap-4/jquery.smartmenus.bootstrap-4.js new file mode 100644 index 0000000000..8d507bbbc9 --- /dev/null +++ b/civicrm/bower_components/smartmenus/dist/addons/bootstrap-4/jquery.smartmenus.bootstrap-4.js @@ -0,0 +1,166 @@ +/*! + * SmartMenus jQuery Plugin Bootstrap 4 Addon - v0.1.0 - September 17, 2017 + * http://www.smartmenus.org/ + * + * Copyright Vasil Dinkov, Vadikom Web Ltd. + * http://vadikom.com + * + * Licensed MIT + */ + +(function(factory) { + if (typeof define === 'function' && define.amd) { + // AMD + define(['jquery', 'smartmenus'], factory); + } else if (typeof module === 'object' && typeof module.exports === 'object') { + // CommonJS + module.exports = factory(require('jquery')); + } else { + // Global jQuery + factory(jQuery); + } +} (function($) { + + $.extend($.SmartMenus.Bootstrap = {}, { + keydownFix: false, + init: function() { + // init all navbars that don't have the "data-sm-skip" attribute set + var $navbars = $('ul.navbar-nav:not([data-sm-skip])'); + $navbars.each(function() { + var $this = $(this), + obj = $this.data('smartmenus'); + // if this navbar is not initialized + if (!obj) { + var skipBehavior = $this.is('[data-sm-skip-collapsible-behavior]'), + rightAligned = $this.hasClass('ml-auto') || $this.prevAll('.mr-auto').length > 0; + + $this.smartmenus({ + // these are some good default options that should work for all + subMenusSubOffsetX: 2, + subMenusSubOffsetY: -9, + subIndicators: !skipBehavior, + collapsibleShowFunction: null, + collapsibleHideFunction: null, + rightToLeftSubMenus: rightAligned, + bottomToTopSubMenus: $this.closest('.fixed-bottom').length > 0, + // custom option(s) for the Bootstrap 4 addon + bootstrapHighlightClasses: 'text-dark bg-light' + }) + .on({ + // set/unset proper Bootstrap classes for some menu elements + 'show.smapi': function(e, menu) { + var $menu = $(menu), + $scrollArrows = $menu.dataSM('scroll-arrows'); + if ($scrollArrows) { + $scrollArrows.css('background-color', $menu.css('background-color')); + } + $menu.parent().addClass('show'); + if (obj.opts.keepHighlighted && $menu.dataSM('level') > 2) { + $menu.prevAll('a').addClass(obj.opts.bootstrapHighlightClasses); + } + }, + 'hide.smapi': function(e, menu) { + var $menu = $(menu); + $menu.parent().removeClass('show'); + if (obj.opts.keepHighlighted && $menu.dataSM('level') > 2) { + $menu.prevAll('a').removeClass(obj.opts.bootstrapHighlightClasses); + } + } + }); + + obj = $this.data('smartmenus'); + + function onInit() { + // set Bootstrap's "active" class to SmartMenus "current" items (should someone decide to enable markCurrentItem: true) + $this.find('a.current').each(function() { + var $this = $(this); + // dropdown items require the class to be set to the A's while for nav items it should be set to the parent LI's + ($this.hasClass('dropdown-item') ? $this : $this.parent()).addClass('active'); + }); + // parent items fixes + $this.find('a.has-submenu').each(function() { + var $this = $(this); + // remove Bootstrap required attributes that might cause conflicting issues with the SmartMenus script + if ($this.is('[data-toggle="dropdown"]')) { + $this.dataSM('bs-data-toggle-dropdown', true).removeAttr('data-toggle'); + } + // remove Bootstrap's carets generating class + if (!skipBehavior && $this.hasClass('dropdown-toggle')) { + $this.dataSM('bs-dropdown-toggle', true).removeClass('dropdown-toggle'); + } + }); + } + + onInit(); + + function onBeforeDestroy() { + $this.find('a.current').each(function() { + var $this = $(this); + ($this.hasClass('active') ? $this : $this.parent()).removeClass('active'); + }); + $this.find('a.has-submenu').each(function() { + var $this = $(this); + if ($this.dataSM('bs-dropdown-toggle')) { + $this.addClass('dropdown-toggle').removeDataSM('bs-dropdown-toggle'); + } + if ($this.dataSM('bs-data-toggle-dropdown')) { + $this.attr('data-toggle', 'dropdown').removeDataSM('bs-data-toggle-dropdown'); + } + }); + } + + // custom "refresh" method for Bootstrap + obj.refresh = function() { + $.SmartMenus.prototype.refresh.call(this); + onInit(); + // update collapsible detection + detectCollapsible(true); + }; + + // custom "destroy" method for Bootstrap + obj.destroy = function(refresh) { + onBeforeDestroy(); + $.SmartMenus.prototype.destroy.call(this, refresh); + }; + + // keep Bootstrap's default behavior (i.e. use the whole item area just as a sub menu toggle) + if (skipBehavior) { + obj.opts.collapsibleBehavior = 'toggle'; + } + + // onresize detect when the navbar becomes collapsible and add it the "sm-collapsible" class + var winW; + function detectCollapsible(force) { + var newW = obj.getViewportWidth(); + if (newW != winW || force) { + if (obj.isCollapsible()) { + $this.addClass('sm-collapsible'); + } else { + $this.removeClass('sm-collapsible'); + } + winW = newW; + } + } + detectCollapsible(); + $(window).on('resize.smartmenus' + obj.rootId, detectCollapsible); + } + }); + // keydown fix for Bootstrap 4 conflict + if ($navbars.length && !$.SmartMenus.Bootstrap.keydownFix) { + // unhook BS keydown handler for all dropdowns + $(document).off('keydown.bs.dropdown.data-api', '.dropdown-menu'); + // restore BS keydown handler for dropdowns that are not inside SmartMenus navbars + // SmartMenus won't add the "show" class so it's handy here + if ($.fn.dropdown && $.fn.dropdown.Constructor) { + $(document).on('keydown.bs.dropdown.data-api', '.dropdown-menu.show', $.fn.dropdown.Constructor._dataApiKeydownHandler); + } + $.SmartMenus.Bootstrap.keydownFix = true; + } + } + }); + + // init ondomready + $($.SmartMenus.Bootstrap.init); + + return $; +})); diff --git a/civicrm/bower_components/smartmenus/dist/addons/bootstrap-4/jquery.smartmenus.bootstrap-4.min.js b/civicrm/bower_components/smartmenus/dist/addons/bootstrap-4/jquery.smartmenus.bootstrap-4.min.js new file mode 100644 index 0000000000..504940fc50 --- /dev/null +++ b/civicrm/bower_components/smartmenus/dist/addons/bootstrap-4/jquery.smartmenus.bootstrap-4.min.js @@ -0,0 +1,3 @@ +/*! SmartMenus jQuery Plugin Bootstrap 4 Addon - v0.1.0 - September 17, 2017 + * http://www.smartmenus.org/ + * Copyright Vasil Dinkov, Vadikom Web Ltd. http://vadikom.com; Licensed MIT */(function(t){"function"==typeof define&&define.amd?define(["jquery","smartmenus"],t):"object"==typeof module&&"object"==typeof module.exports?module.exports=t(require("jquery")):t(jQuery)})(function(t){return t.extend(t.SmartMenus.Bootstrap={},{keydownFix:!1,init:function(){var e=t("ul.navbar-nav:not([data-sm-skip])");e.each(function(){function e(){o.find("a.current").each(function(){var e=t(this);(e.hasClass("dropdown-item")?e:e.parent()).addClass("active")}),o.find("a.has-submenu").each(function(){var e=t(this);e.is('[data-toggle="dropdown"]')&&e.dataSM("bs-data-toggle-dropdown",!0).removeAttr("data-toggle"),!n&&e.hasClass("dropdown-toggle")&&e.dataSM("bs-dropdown-toggle",!0).removeClass("dropdown-toggle")})}function s(){o.find("a.current").each(function(){var e=t(this);(e.hasClass("active")?e:e.parent()).removeClass("active")}),o.find("a.has-submenu").each(function(){var e=t(this);e.dataSM("bs-dropdown-toggle")&&e.addClass("dropdown-toggle").removeDataSM("bs-dropdown-toggle"),e.dataSM("bs-data-toggle-dropdown")&&e.attr("data-toggle","dropdown").removeDataSM("bs-data-toggle-dropdown")})}function i(t){var e=a.getViewportWidth();(e!=u||t)&&(a.isCollapsible()?o.addClass("sm-collapsible"):o.removeClass("sm-collapsible"),u=e)}var o=t(this),a=o.data("smartmenus");if(!a){var n=o.is("[data-sm-skip-collapsible-behavior]"),r=o.hasClass("ml-auto")||o.prevAll(".mr-auto").length>0;o.smartmenus({subMenusSubOffsetX:2,subMenusSubOffsetY:-9,subIndicators:!n,collapsibleShowFunction:null,collapsibleHideFunction:null,rightToLeftSubMenus:r,bottomToTopSubMenus:o.closest(".fixed-bottom").length>0,bootstrapHighlightClasses:"text-dark bg-light"}).on({"show.smapi":function(e,s){var i=t(s),o=i.dataSM("scroll-arrows");o&&o.css("background-color",i.css("background-color")),i.parent().addClass("show"),a.opts.keepHighlighted&&i.dataSM("level")>2&&i.prevAll("a").addClass(a.opts.bootstrapHighlightClasses)},"hide.smapi":function(e,s){var i=t(s);i.parent().removeClass("show"),a.opts.keepHighlighted&&i.dataSM("level")>2&&i.prevAll("a").removeClass(a.opts.bootstrapHighlightClasses)}}),a=o.data("smartmenus"),e(),a.refresh=function(){t.SmartMenus.prototype.refresh.call(this),e(),i(!0)},a.destroy=function(e){s(),t.SmartMenus.prototype.destroy.call(this,e)},n&&(a.opts.collapsibleBehavior="toggle");var u;i(),t(window).on("resize.smartmenus"+a.rootId,i)}}),e.length&&!t.SmartMenus.Bootstrap.keydownFix&&(t(document).off("keydown.bs.dropdown.data-api",".dropdown-menu"),t.fn.dropdown&&t.fn.dropdown.Constructor&&t(document).on("keydown.bs.dropdown.data-api",".dropdown-menu.show",t.fn.dropdown.Constructor._dataApiKeydownHandler),t.SmartMenus.Bootstrap.keydownFix=!0)}}),t(t.SmartMenus.Bootstrap.init),t}); \ No newline at end of file diff --git a/civicrm/bower_components/smartmenus/dist/addons/bootstrap/jquery.smartmenus.bootstrap.css b/civicrm/bower_components/smartmenus/dist/addons/bootstrap/jquery.smartmenus.bootstrap.css new file mode 100644 index 0000000000..8407ce1be0 --- /dev/null +++ b/civicrm/bower_components/smartmenus/dist/addons/bootstrap/jquery.smartmenus.bootstrap.css @@ -0,0 +1,122 @@ +/* + You probably do not need to edit this at all. + + Add some SmartMenus required styles not covered in Bootstrap 3's default CSS. + These are theme independent and should work with any Bootstrap 3 theme mod. +*/ +/* sub menus arrows on desktop */ +.navbar-nav:not(.sm-collapsible) ul .caret { + position: absolute; + right: 0; + margin-top: 6px; + margin-right: 15px; + border-top: 4px solid transparent; + border-bottom: 4px solid transparent; + border-left: 4px dashed; +} +.navbar-nav:not(.sm-collapsible) ul a.has-submenu { + padding-right: 30px; +} +/* make sub menu arrows look like +/- buttons in collapsible mode */ +.navbar-nav.sm-collapsible .caret, .navbar-nav.sm-collapsible ul .caret { + position: absolute; + right: 0; + margin: -3px 15px 0 0; + padding: 0; + width: 32px; + height: 26px; + line-height: 24px; + text-align: center; + border-width: 1px; + border-style: solid; +} +.navbar-nav.sm-collapsible .caret:before { + content: '+'; + font-family: monospace; + font-weight: bold; +} +.navbar-nav.sm-collapsible .open > a > .caret:before { + content: '-'; +} +.navbar-nav.sm-collapsible a.has-submenu { + padding-right: 50px; +} +/* revert to Bootstrap's default carets in collapsible mode when the "data-sm-skip-collapsible-behavior" attribute is set to the ul.navbar-nav */ +.navbar-nav.sm-collapsible[data-sm-skip-collapsible-behavior] .caret, .navbar-nav.sm-collapsible[data-sm-skip-collapsible-behavior] ul .caret { + position: static; + margin: 0 0 0 2px; + padding: 0; + width: 0; + height: 0; + border-top: 4px dashed; + border-right: 4px solid transparent; + border-bottom: 0; + border-left: 4px solid transparent; +} +.navbar-nav.sm-collapsible[data-sm-skip-collapsible-behavior] .caret:before { + content: '' !important; +} +.navbar-nav.sm-collapsible[data-sm-skip-collapsible-behavior] a.has-submenu { + padding-right: 15px; +} +/* scrolling arrows for tall menus */ +.navbar-nav span.scroll-up, .navbar-nav span.scroll-down { + position: absolute; + display: none; + visibility: hidden; + height: 20px; + overflow: hidden; + text-align: center; +} +.navbar-nav span.scroll-up-arrow, .navbar-nav span.scroll-down-arrow { + position: absolute; + top: -2px; + left: 50%; + margin-left: -8px; + width: 0; + height: 0; + overflow: hidden; + border-top: 7px dashed transparent; + border-right: 7px dashed transparent; + border-bottom: 7px solid; + border-left: 7px dashed transparent; +} +.navbar-nav span.scroll-down-arrow { + top: 6px; + border-top: 7px solid; + border-right: 7px dashed transparent; + border-bottom: 7px dashed transparent; + border-left: 7px dashed transparent; +} +/* add more indentation for 2+ level sub in collapsible mode - Bootstrap normally supports just 1 level sub menus */ +.navbar-nav.sm-collapsible ul .dropdown-menu > li > a, +.navbar-nav.sm-collapsible ul .dropdown-menu .dropdown-header { + padding-left: 35px; +} +.navbar-nav.sm-collapsible ul ul .dropdown-menu > li > a, +.navbar-nav.sm-collapsible ul ul .dropdown-menu .dropdown-header { + padding-left: 45px; +} +.navbar-nav.sm-collapsible ul ul ul .dropdown-menu > li > a, +.navbar-nav.sm-collapsible ul ul ul .dropdown-menu .dropdown-header { + padding-left: 55px; +} +.navbar-nav.sm-collapsible ul ul ul ul .dropdown-menu > li > a, +.navbar-nav.sm-collapsible ul ul ul ul .dropdown-menu .dropdown-header { + padding-left: 65px; +} +/* fix SmartMenus sub menus auto width (subMenusMinWidth and subMenusMaxWidth options) */ +.navbar-nav .dropdown-menu > li > a { + white-space: normal; +} +.navbar-nav ul.sm-nowrap > li > a { + white-space: nowrap; +} +.navbar-nav.sm-collapsible ul.sm-nowrap > li > a { + white-space: normal; +} +/* fix .navbar-right subs alignment */ +.navbar-right ul.dropdown-menu { + left: 0; + right: auto; +} \ No newline at end of file diff --git a/civicrm/bower_components/smartmenus/dist/addons/bootstrap/jquery.smartmenus.bootstrap.js b/civicrm/bower_components/smartmenus/dist/addons/bootstrap/jquery.smartmenus.bootstrap.js new file mode 100644 index 0000000000..eb77248f66 --- /dev/null +++ b/civicrm/bower_components/smartmenus/dist/addons/bootstrap/jquery.smartmenus.bootstrap.js @@ -0,0 +1,159 @@ +/*! + * SmartMenus jQuery Plugin Bootstrap Addon - v0.4.0 - September 17, 2017 + * http://www.smartmenus.org/ + * + * Copyright Vasil Dinkov, Vadikom Web Ltd. + * http://vadikom.com + * + * Licensed MIT + */ + +(function(factory) { + if (typeof define === 'function' && define.amd) { + // AMD + define(['jquery', 'smartmenus'], factory); + } else if (typeof module === 'object' && typeof module.exports === 'object') { + // CommonJS + module.exports = factory(require('jquery')); + } else { + // Global jQuery + factory(jQuery); + } +} (function($) { + + $.extend($.SmartMenus.Bootstrap = {}, { + keydownFix: false, + init: function() { + // init all navbars that don't have the "data-sm-skip" attribute set + var $navbars = $('ul.navbar-nav:not([data-sm-skip])'); + $navbars.each(function() { + var $this = $(this), + obj = $this.data('smartmenus'); + // if this navbar is not initialized + if (!obj) { + $this.smartmenus({ + // these are some good default options that should work for all + subMenusSubOffsetX: 2, + subMenusSubOffsetY: -6, + subIndicators: false, + collapsibleShowFunction: null, + collapsibleHideFunction: null, + rightToLeftSubMenus: $this.hasClass('navbar-right'), + bottomToTopSubMenus: $this.closest('.navbar').hasClass('navbar-fixed-bottom') + }) + .on({ + // set/unset proper Bootstrap classes for some menu elements + 'show.smapi': function(e, menu) { + var $menu = $(menu), + $scrollArrows = $menu.dataSM('scroll-arrows'); + if ($scrollArrows) { + // they inherit border-color from body, so we can use its background-color too + $scrollArrows.css('background-color', $(document.body).css('background-color')); + } + $menu.parent().addClass('open'); + }, + 'hide.smapi': function(e, menu) { + $(menu).parent().removeClass('open'); + } + }); + + function onInit() { + // set Bootstrap's "active" class to SmartMenus "current" items (should someone decide to enable markCurrentItem: true) + $this.find('a.current').parent().addClass('active'); + // remove any Bootstrap required attributes that might cause conflicting issues with the SmartMenus script + $this.find('a.has-submenu').each(function() { + var $this = $(this); + if ($this.is('[data-toggle="dropdown"]')) { + $this.dataSM('bs-data-toggle-dropdown', true).removeAttr('data-toggle'); + } + if ($this.is('[role="button"]')) { + $this.dataSM('bs-role-button', true).removeAttr('role'); + } + }); + } + + onInit(); + + function onBeforeDestroy() { + $this.find('a.current').parent().removeClass('active'); + $this.find('a.has-submenu').each(function() { + var $this = $(this); + if ($this.dataSM('bs-data-toggle-dropdown')) { + $this.attr('data-toggle', 'dropdown').removeDataSM('bs-data-toggle-dropdown'); + } + if ($this.dataSM('bs-role-button')) { + $this.attr('role', 'button').removeDataSM('bs-role-button'); + } + }); + } + + obj = $this.data('smartmenus'); + + // custom "isCollapsible" method for Bootstrap + obj.isCollapsible = function() { + return !/^(left|right)$/.test(this.$firstLink.parent().css('float')) && this.$root.css('display') == 'block'; + }; + + // custom "refresh" method for Bootstrap + obj.refresh = function() { + $.SmartMenus.prototype.refresh.call(this); + onInit(); + // update collapsible detection + detectCollapsible(true); + }; + + // custom "destroy" method for Bootstrap + obj.destroy = function(refresh) { + onBeforeDestroy(); + $.SmartMenus.prototype.destroy.call(this, refresh); + }; + + // keep Bootstrap's default behavior for parent items when the "data-sm-skip-collapsible-behavior" attribute is set to the ul.navbar-nav + // i.e. use the whole item area just as a sub menu toggle and don't customize the carets + if ($this.is('[data-sm-skip-collapsible-behavior]')) { + obj.opts.collapsibleBehavior = 'toggle'; + } + + // onresize detect when the navbar becomes collapsible and add it the "sm-collapsible" class + var winW; + function detectCollapsible(force) { + var newW = obj.getViewportWidth(); + if (newW != winW || force) { + var $carets = $this.find('.caret'); + if (obj.isCollapsible()) { + $this.addClass('sm-collapsible'); + // set "navbar-toggle" class to carets (so they look like a button) if the "data-sm-skip-collapsible-behavior" attribute is not set to the ul.navbar-nav + if (!$this.is('[data-sm-skip-collapsible-behavior]')) { + $carets.addClass('navbar-toggle sub-arrow'); + } + } else { + $this.removeClass('sm-collapsible'); + if (!$this.is('[data-sm-skip-collapsible-behavior]')) { + $carets.removeClass('navbar-toggle sub-arrow'); + } + } + winW = newW; + } + } + detectCollapsible(); + $(window).on('resize.smartmenus' + obj.rootId, detectCollapsible); + } + }); + // keydown fix for Bootstrap 3.3.5+ conflict + if ($navbars.length && !$.SmartMenus.Bootstrap.keydownFix) { + // unhook BS keydown handler for all dropdowns + $(document).off('keydown.bs.dropdown.data-api', '.dropdown-menu'); + // restore BS keydown handler for dropdowns that are not inside SmartMenus navbars + if ($.fn.dropdown && $.fn.dropdown.Constructor) { + $(document).on('keydown.bs.dropdown.data-api', '.dropdown-menu:not([id^="sm-"])', $.fn.dropdown.Constructor.prototype.keydown); + } + $.SmartMenus.Bootstrap.keydownFix = true; + } + } + }); + + // init ondomready + $($.SmartMenus.Bootstrap.init); + + return $; +})); diff --git a/civicrm/bower_components/smartmenus/dist/addons/bootstrap/jquery.smartmenus.bootstrap.min.js b/civicrm/bower_components/smartmenus/dist/addons/bootstrap/jquery.smartmenus.bootstrap.min.js new file mode 100644 index 0000000000..07fd0a9035 --- /dev/null +++ b/civicrm/bower_components/smartmenus/dist/addons/bootstrap/jquery.smartmenus.bootstrap.min.js @@ -0,0 +1,3 @@ +/*! SmartMenus jQuery Plugin Bootstrap Addon - v0.4.0 - September 17, 2017 + * http://www.smartmenus.org/ + * Copyright Vasil Dinkov, Vadikom Web Ltd. http://vadikom.com; Licensed MIT */(function(t){"function"==typeof define&&define.amd?define(["jquery","smartmenus"],t):"object"==typeof module&&"object"==typeof module.exports?module.exports=t(require("jquery")):t(jQuery)})(function(t){return t.extend(t.SmartMenus.Bootstrap={},{keydownFix:!1,init:function(){var e=t("ul.navbar-nav:not([data-sm-skip])");e.each(function(){function e(){o.find("a.current").parent().addClass("active"),o.find("a.has-submenu").each(function(){var e=t(this);e.is('[data-toggle="dropdown"]')&&e.dataSM("bs-data-toggle-dropdown",!0).removeAttr("data-toggle"),e.is('[role="button"]')&&e.dataSM("bs-role-button",!0).removeAttr("role")})}function s(){o.find("a.current").parent().removeClass("active"),o.find("a.has-submenu").each(function(){var e=t(this);e.dataSM("bs-data-toggle-dropdown")&&e.attr("data-toggle","dropdown").removeDataSM("bs-data-toggle-dropdown"),e.dataSM("bs-role-button")&&e.attr("role","button").removeDataSM("bs-role-button")})}function i(t){var e=a.getViewportWidth();if(e!=n||t){var s=o.find(".caret");a.isCollapsible()?(o.addClass("sm-collapsible"),o.is("[data-sm-skip-collapsible-behavior]")||s.addClass("navbar-toggle sub-arrow")):(o.removeClass("sm-collapsible"),o.is("[data-sm-skip-collapsible-behavior]")||s.removeClass("navbar-toggle sub-arrow")),n=e}}var o=t(this),a=o.data("smartmenus");if(!a){o.smartmenus({subMenusSubOffsetX:2,subMenusSubOffsetY:-6,subIndicators:!1,collapsibleShowFunction:null,collapsibleHideFunction:null,rightToLeftSubMenus:o.hasClass("navbar-right"),bottomToTopSubMenus:o.closest(".navbar").hasClass("navbar-fixed-bottom")}).on({"show.smapi":function(e,s){var i=t(s),o=i.dataSM("scroll-arrows");o&&o.css("background-color",t(document.body).css("background-color")),i.parent().addClass("open")},"hide.smapi":function(e,s){t(s).parent().removeClass("open")}}),e(),a=o.data("smartmenus"),a.isCollapsible=function(){return!/^(left|right)$/.test(this.$firstLink.parent().css("float"))&&"block"==this.$root.css("display")},a.refresh=function(){t.SmartMenus.prototype.refresh.call(this),e(),i(!0)},a.destroy=function(e){s(),t.SmartMenus.prototype.destroy.call(this,e)},o.is("[data-sm-skip-collapsible-behavior]")&&(a.opts.collapsibleBehavior="toggle");var n;i(),t(window).on("resize.smartmenus"+a.rootId,i)}}),e.length&&!t.SmartMenus.Bootstrap.keydownFix&&(t(document).off("keydown.bs.dropdown.data-api",".dropdown-menu"),t.fn.dropdown&&t.fn.dropdown.Constructor&&t(document).on("keydown.bs.dropdown.data-api",'.dropdown-menu:not([id^="sm-"])',t.fn.dropdown.Constructor.prototype.keydown),t.SmartMenus.Bootstrap.keydownFix=!0)}}),t(t.SmartMenus.Bootstrap.init),t}); \ No newline at end of file diff --git a/civicrm/bower_components/smartmenus/dist/addons/keyboard/jquery.smartmenus.keyboard.js b/civicrm/bower_components/smartmenus/dist/addons/keyboard/jquery.smartmenus.keyboard.js new file mode 100644 index 0000000000..03d7098d75 --- /dev/null +++ b/civicrm/bower_components/smartmenus/dist/addons/keyboard/jquery.smartmenus.keyboard.js @@ -0,0 +1,215 @@ +/*! + * SmartMenus jQuery Plugin Keyboard Addon - v0.4.0 - September 17, 2017 + * http://www.smartmenus.org/ + * + * Copyright Vasil Dinkov, Vadikom Web Ltd. + * http://vadikom.com + * + * Licensed MIT + */ + +(function(factory) { + if (typeof define === 'function' && define.amd) { + // AMD + define(['jquery', 'smartmenus'], factory); + } else if (typeof module === 'object' && typeof module.exports === 'object') { + // CommonJS + module.exports = factory(require('jquery')); + } else { + // Global jQuery + factory(jQuery); + } +} (function($) { + + function getFirstItemLink($ul) { + // make sure we also allow the link to be nested deeper inside the LI's (e.g. in a heading) + return $ul.find('> li > a:not(.disabled), > li > :not(ul) a:not(.disabled)').eq(0); + } + function getLastItemLink($ul) { + return $ul.find('> li > a:not(.disabled), > li > :not(ul) a:not(.disabled)').eq(-1); + } + function getNextItemLink($li, noLoop) { + var $a = $li.nextAll('li').find('> a:not(.disabled), > :not(ul) a:not(.disabled)').eq(0); + return noLoop || $a.length ? $a : getFirstItemLink($li.parent()); + } + function getPreviousItemLink($li, noLoop) { + // bug workaround: elements are returned in reverse order just in jQuery 1.8.x + var $a = $li.prevAll('li').find('> a:not(.disabled), > :not(ul) a:not(.disabled)').eq(/^1\.8\./.test($.fn.jquery) ? 0 : -1); + return noLoop || $a.length ? $a : getLastItemLink($li.parent()); + } + + // jQuery's .focus() is unreliable in some versions, so we're going to call the links' native JS focus method + $.fn.focusSM = function() { + if (this.length && this[0].focus) { + this[0].focus(); + } + return this; + }; + + $.extend($.SmartMenus.Keyboard = {}, { + docKeydown: function(e) { + var keyCode = e.keyCode; + if (!/^(37|38|39|40)$/.test(keyCode)) { + return; + } + var $root = $(this), + obj = $root.data('smartmenus'), + $target = $(e.target); + // exit if this is an A inside a mega drop-down + if (!obj || !$target.is('a') || !obj.handleItemEvents($target)) { + return; + } + var $li = $target.closest('li'), + $ul = $li.parent(), + level = $ul.dataSM('level'); + // swap left & right keys + if ($root.hasClass('sm-rtl')) { + if (keyCode == 37) { + keyCode = 39; + } else if (keyCode == 39) { + keyCode = 37; + } + } + switch (keyCode) { + case 37: // Left + if (obj.isCollapsible()) { + break; + } + if (level > 2 || level == 2 && $root.hasClass('sm-vertical')) { + obj.activatedItems[level - 2].focusSM(); + // move to previous non-disabled parent item (make sure we cycle so it might be the last item) + } else if (!$root.hasClass('sm-vertical')) { + getPreviousItemLink((obj.activatedItems[0] || $target).closest('li')).focusSM(); + } + break; + case 38: // Up + if (obj.isCollapsible()) { + var $firstItem; + // if this is the first item of a sub menu, move to the parent item + if (level > 1 && ($firstItem = getFirstItemLink($ul)).length && $target[0] == $firstItem[0]) { + obj.activatedItems[level - 2].focusSM(); + } else { + getPreviousItemLink($li).focusSM(); + } + } else { + if (level == 1 && !$root.hasClass('sm-vertical') && obj.opts.bottomToTopSubMenus) { + if (!obj.activatedItems[0] && $target.dataSM('sub')) { + if (obj.opts.showOnClick) { + obj.clickActivated = true; + } + obj.itemActivate($target); + if ($target.dataSM('sub').is(':visible')) { + obj.focusActivated = true; + } + } + if (obj.activatedItems[0] && obj.activatedItems[0].dataSM('sub') && obj.activatedItems[0].dataSM('sub').is(':visible') && !obj.activatedItems[0].dataSM('sub').hasClass('mega-menu')) { + getLastItemLink(obj.activatedItems[0].dataSM('sub')).focusSM(); + } + } else if (level > 1 || $root.hasClass('sm-vertical')) { + getPreviousItemLink($li).focusSM(); + } + } + break; + case 39: // Right + if (obj.isCollapsible()) { + break; + } + if (level == 1 && $root.hasClass('sm-vertical')) { + if (!obj.activatedItems[0] && $target.dataSM('sub')) { + if (obj.opts.showOnClick) { + obj.clickActivated = true; + } + obj.itemActivate($target); + if ($target.dataSM('sub').is(':visible')) { + obj.focusActivated = true; + } + } + if (obj.activatedItems[0] && obj.activatedItems[0].dataSM('sub') && obj.activatedItems[0].dataSM('sub').is(':visible') && !obj.activatedItems[0].dataSM('sub').hasClass('mega-menu')) { + getFirstItemLink(obj.activatedItems[0].dataSM('sub')).focusSM(); + } + // move to next non-disabled parent item (make sure we cycle so it might be the last item) + } else if ((level == 1 || obj.activatedItems[level - 1] && (!obj.activatedItems[level - 1].dataSM('sub') || !obj.activatedItems[level - 1].dataSM('sub').is(':visible') || obj.activatedItems[level - 1].dataSM('sub').hasClass('mega-menu'))) && !$root.hasClass('sm-vertical')) { + getNextItemLink((obj.activatedItems[0] || $target).closest('li')).focusSM(); + } else if (obj.activatedItems[level - 1] && obj.activatedItems[level - 1].dataSM('sub') && obj.activatedItems[level - 1].dataSM('sub').is(':visible') && !obj.activatedItems[level - 1].dataSM('sub').hasClass('mega-menu')) { + getFirstItemLink(obj.activatedItems[level - 1].dataSM('sub')).focusSM(); + } + break; + case 40: // Down + if (obj.isCollapsible()) { + var $firstSubItem, + $lastItem; + // move to sub menu if appropriate + if (obj.activatedItems[level - 1] && obj.activatedItems[level - 1].dataSM('sub') && obj.activatedItems[level - 1].dataSM('sub').is(':visible') && !obj.activatedItems[level - 1].dataSM('sub').hasClass('mega-menu') && ($firstSubItem = getFirstItemLink(obj.activatedItems[level - 1].dataSM('sub'))).length) { + $firstSubItem.focusSM(); + // if this is the last item of a sub menu, move to the next parent item + } else if (level > 1 && ($lastItem = getLastItemLink($ul)).length && $target[0] == $lastItem[0]) { + var $parentItem = obj.activatedItems[level - 2].closest('li'), + $nextParentItem = null; + while ($parentItem.is('li') && !($nextParentItem = getNextItemLink($parentItem, true)).length) { + $parentItem = $parentItem.parent().parent(); + } + if ($nextParentItem.length) { + $nextParentItem.focusSM(); + } else { + getFirstItemLink($root).focusSM(); + } + } else { + getNextItemLink($li).focusSM(); + } + } else { + if (level == 1 && !$root.hasClass('sm-vertical') && !obj.opts.bottomToTopSubMenus) { + if (!obj.activatedItems[0] && $target.dataSM('sub')) { + if (obj.opts.showOnClick) { + obj.clickActivated = true; + } + obj.itemActivate($target); + if ($target.dataSM('sub').is(':visible')) { + obj.focusActivated = true; + } + } + if (obj.activatedItems[0] && obj.activatedItems[0].dataSM('sub') && obj.activatedItems[0].dataSM('sub').is(':visible') && !obj.activatedItems[0].dataSM('sub').hasClass('mega-menu')) { + getFirstItemLink(obj.activatedItems[0].dataSM('sub')).focusSM(); + } + } else if (level > 1 || $root.hasClass('sm-vertical')) { + getNextItemLink($li).focusSM(); + } + } + break; + } + e.stopPropagation(); + e.preventDefault(); + } + }); + + // hook it + $(document).on('keydown.smartmenus', 'ul.sm, ul.navbar-nav:not([data-sm-skip])', $.SmartMenus.Keyboard.docKeydown); + + $.extend($.SmartMenus.prototype, { + keyboardSetHotkey: function(keyCode, modifiers) { + var self = this; + $(document).on('keydown.smartmenus' + this.rootId, function(e) { + if (keyCode == e.keyCode) { + var procede = true; + if (modifiers) { + if (typeof modifiers == 'string') { + modifiers = [modifiers]; + } + $.each(['ctrlKey', 'shiftKey', 'altKey', 'metaKey'], function(index, value) { + if ($.inArray(value, modifiers) >= 0 && !e[value] || $.inArray(value, modifiers) < 0 && e[value]) { + procede = false; + return false; + } + }); + } + if (procede) { + getFirstItemLink(self.$root).focusSM(); + e.stopPropagation(); + e.preventDefault(); + } + } + }); + } + }); + + return $; +})); \ No newline at end of file diff --git a/civicrm/bower_components/smartmenus/dist/addons/keyboard/jquery.smartmenus.keyboard.min.js b/civicrm/bower_components/smartmenus/dist/addons/keyboard/jquery.smartmenus.keyboard.min.js new file mode 100644 index 0000000000..70edbf1242 --- /dev/null +++ b/civicrm/bower_components/smartmenus/dist/addons/keyboard/jquery.smartmenus.keyboard.min.js @@ -0,0 +1,3 @@ +/*! SmartMenus jQuery Plugin Keyboard Addon - v0.4.0 - September 17, 2017 + * http://www.smartmenus.org/ + * Copyright Vasil Dinkov, Vadikom Web Ltd. http://vadikom.com; Licensed MIT */(function(t){"function"==typeof define&&define.amd?define(["jquery","smartmenus"],t):"object"==typeof module&&"object"==typeof module.exports?module.exports=t(require("jquery")):t(jQuery)})(function(t){function e(t){return t.find("> li > a:not(.disabled), > li > :not(ul) a:not(.disabled)").eq(0)}function s(t){return t.find("> li > a:not(.disabled), > li > :not(ul) a:not(.disabled)").eq(-1)}function i(t,s){var i=t.nextAll("li").find("> a:not(.disabled), > :not(ul) a:not(.disabled)").eq(0);return s||i.length?i:e(t.parent())}function o(e,i){var o=e.prevAll("li").find("> a:not(.disabled), > :not(ul) a:not(.disabled)").eq(/^1\.8\./.test(t.fn.jquery)?0:-1);return i||o.length?o:s(e.parent())}return t.fn.focusSM=function(){return this.length&&this[0].focus&&this[0].focus(),this},t.extend(t.SmartMenus.Keyboard={},{docKeydown:function(a){var n=a.keyCode;if(/^(37|38|39|40)$/.test(n)){var r=t(this),u=r.data("smartmenus"),h=t(a.target);if(u&&h.is("a")&&u.handleItemEvents(h)){var l=h.closest("li"),c=l.parent(),d=c.dataSM("level");switch(r.hasClass("sm-rtl")&&(37==n?n=39:39==n&&(n=37)),n){case 37:if(u.isCollapsible())break;d>2||2==d&&r.hasClass("sm-vertical")?u.activatedItems[d-2].focusSM():r.hasClass("sm-vertical")||o((u.activatedItems[0]||h).closest("li")).focusSM();break;case 38:if(u.isCollapsible()){var m;d>1&&(m=e(c)).length&&h[0]==m[0]?u.activatedItems[d-2].focusSM():o(l).focusSM()}else 1==d&&!r.hasClass("sm-vertical")&&u.opts.bottomToTopSubMenus?(!u.activatedItems[0]&&h.dataSM("sub")&&(u.opts.showOnClick&&(u.clickActivated=!0),u.itemActivate(h),h.dataSM("sub").is(":visible")&&(u.focusActivated=!0)),u.activatedItems[0]&&u.activatedItems[0].dataSM("sub")&&u.activatedItems[0].dataSM("sub").is(":visible")&&!u.activatedItems[0].dataSM("sub").hasClass("mega-menu")&&s(u.activatedItems[0].dataSM("sub")).focusSM()):(d>1||r.hasClass("sm-vertical"))&&o(l).focusSM();break;case 39:if(u.isCollapsible())break;1==d&&r.hasClass("sm-vertical")?(!u.activatedItems[0]&&h.dataSM("sub")&&(u.opts.showOnClick&&(u.clickActivated=!0),u.itemActivate(h),h.dataSM("sub").is(":visible")&&(u.focusActivated=!0)),u.activatedItems[0]&&u.activatedItems[0].dataSM("sub")&&u.activatedItems[0].dataSM("sub").is(":visible")&&!u.activatedItems[0].dataSM("sub").hasClass("mega-menu")&&e(u.activatedItems[0].dataSM("sub")).focusSM()):1!=d&&(!u.activatedItems[d-1]||u.activatedItems[d-1].dataSM("sub")&&u.activatedItems[d-1].dataSM("sub").is(":visible")&&!u.activatedItems[d-1].dataSM("sub").hasClass("mega-menu"))||r.hasClass("sm-vertical")?u.activatedItems[d-1]&&u.activatedItems[d-1].dataSM("sub")&&u.activatedItems[d-1].dataSM("sub").is(":visible")&&!u.activatedItems[d-1].dataSM("sub").hasClass("mega-menu")&&e(u.activatedItems[d-1].dataSM("sub")).focusSM():i((u.activatedItems[0]||h).closest("li")).focusSM();break;case 40:if(u.isCollapsible()){var p,f;if(u.activatedItems[d-1]&&u.activatedItems[d-1].dataSM("sub")&&u.activatedItems[d-1].dataSM("sub").is(":visible")&&!u.activatedItems[d-1].dataSM("sub").hasClass("mega-menu")&&(p=e(u.activatedItems[d-1].dataSM("sub"))).length)p.focusSM();else if(d>1&&(f=s(c)).length&&h[0]==f[0]){for(var v=u.activatedItems[d-2].closest("li"),b=null;v.is("li")&&!(b=i(v,!0)).length;)v=v.parent().parent();b.length?b.focusSM():e(r).focusSM()}else i(l).focusSM()}else 1!=d||r.hasClass("sm-vertical")||u.opts.bottomToTopSubMenus?(d>1||r.hasClass("sm-vertical"))&&i(l).focusSM():(!u.activatedItems[0]&&h.dataSM("sub")&&(u.opts.showOnClick&&(u.clickActivated=!0),u.itemActivate(h),h.dataSM("sub").is(":visible")&&(u.focusActivated=!0)),u.activatedItems[0]&&u.activatedItems[0].dataSM("sub")&&u.activatedItems[0].dataSM("sub").is(":visible")&&!u.activatedItems[0].dataSM("sub").hasClass("mega-menu")&&e(u.activatedItems[0].dataSM("sub")).focusSM())}a.stopPropagation(),a.preventDefault()}}}}),t(document).on("keydown.smartmenus","ul.sm, ul.navbar-nav:not([data-sm-skip])",t.SmartMenus.Keyboard.docKeydown),t.extend(t.SmartMenus.prototype,{keyboardSetHotkey:function(s,i){var o=this;t(document).on("keydown.smartmenus"+this.rootId,function(a){if(s==a.keyCode){var n=!0;i&&("string"==typeof i&&(i=[i]),t.each(["ctrlKey","shiftKey","altKey","metaKey"],function(e,s){return t.inArray(s,i)>=0&&!a[s]||0>t.inArray(s,i)&&a[s]?(n=!1,!1):void 0})),n&&(e(o.$root).focusSM(),a.stopPropagation(),a.preventDefault())}})}}),t}); \ No newline at end of file diff --git a/civicrm/bower_components/smartmenus/dist/css/sm-blue/_mixins.scss b/civicrm/bower_components/smartmenus/dist/css/sm-blue/_mixins.scss new file mode 100644 index 0000000000..0ed06503c8 --- /dev/null +++ b/civicrm/bower_components/smartmenus/dist/css/sm-blue/_mixins.scss @@ -0,0 +1,2 @@ +@import 'mixins/_sub-items-indentation.scss'; +@import 'mixins/_round-corners-last-item.scss'; \ No newline at end of file diff --git a/civicrm/bower_components/smartmenus/dist/css/sm-blue/_sm-blue-theme.scss b/civicrm/bower_components/smartmenus/dist/css/sm-blue/_sm-blue-theme.scss new file mode 100644 index 0000000000..d7c2828432 --- /dev/null +++ b/civicrm/bower_components/smartmenus/dist/css/sm-blue/_sm-blue-theme.scss @@ -0,0 +1,586 @@ +// This file is best viewed with Tab size 4 code indentation + + +// ----------------------------------------------------------------------------------------------------------------- +// 1. Theme Quick Settings (Variables) +// (for further control, you will need to dig into the actual CSS in 2.) +// ----------------------------------------------------------------------------------------------------------------- + + +// ---------------------------------------------------------- +// :: 1.1. Colors +// ---------------------------------------------------------- + +$sm-blue__blue: #3092c0 !default; +$sm-blue__blue-dark: darken($sm-blue__blue, 5%) !default; +$sm-blue__blue-darker: #006892 !default; +$sm-blue__blue-light: lighten($sm-blue__blue, 30%) !default; +$sm-blue__white: #fff !default; +$sm-blue__gray: darken($sm-blue__white, 34%) !default; + +$sm-blue__text-shadow: rgba(0, 0, 0, 0.2) !default; +$sm-blue__box-shadow: rgba(0, 0, 0, 0.2) !default; + +$sm-blue__gradients_amount: 2% !default; + + +// ---------------------------------------------------------- +// :: 1.2. Breakpoints +// ---------------------------------------------------------- + +$sm-blue__desktop-vp: 768px !default; // switch from collapsible to desktop + + +// ---------------------------------------------------------- +// :: 1.3. Typography +// ---------------------------------------------------------- + +// Import "PT Sans Narrow" font from Google fonts +@import url(https://fonts.googleapis.com/css?family=PT+Sans+Narrow:400,700); + +$sm-blue__font-family: "PT Sans Narrow", "Arial Narrow", Arial, Helvetica, sans-serif !default; +$sm-blue__font-size-base: 18px !default; +$sm-blue__font-size-small: 16px !default; +$sm-blue__line-height: 23px !default; + + +// ---------------------------------------------------------- +// :: 1.4. Borders +// ---------------------------------------------------------- + +$sm-blue__border-width: 1px !default; +$sm-blue__border-radius-base: 8px !default; +$sm-blue__border-radius-small: 4px !default; + + +// ---------------------------------------------------------- +// :: 1.5. Collapsible main menu +// ---------------------------------------------------------- + +// Menu box +$sm-blue__collapsible-bg: transparent !default; +$sm-blue__collapsible-border-radius: $sm-blue__border-radius-base !default; +$sm-blue__collapsible-box-shadow: 0 1px 4px $sm-blue__box-shadow !default; + +// Items +$sm-blue__collapsible-item-color: $sm-blue__white !default; +$sm-blue__collapsible-item-bg: $sm-blue__blue !default; +$sm-blue__collapsible-item-current-color: $sm-blue__white !default; +$sm-blue__collapsible-item-current-bg: $sm-blue__blue-darker !default; +$sm-blue__collapsible-item-disabled-color: lighten($sm-blue__blue, 30%) !default; +$sm-blue__collapsible-item-padding-vertical: 10px !default; +$sm-blue__collapsible-item-padding-horizontal: 20px !default; + +// Toggle button (sub menu indicators) +$sm-blue__collapsible-toggle-bg: rgba(0, 0, 0, 0.1) !default; + + +// ---------------------------------------------------------- +// :: 1.6. Collapsible sub menus +// ---------------------------------------------------------- + +// Menu box +$sm-blue__collapsible-sub-bg: $sm-blue__white !default; + +// Items +$sm-blue__collapsible-sub-item-color: $sm-blue__blue-dark !default; +$sm-blue__collapsible-sub-item-bg: transparent !default; +$sm-blue__collapsible-sub-item-current-color: $sm-blue__white !default; +$sm-blue__collapsible-sub-item-current-bg: $sm-blue__blue-darker !default; +$sm-blue__collapsible-sub-item-disabled-color: darken($sm-blue__white, 30%) !default; + +// Items separators +$sm-blue__collapsible-sub-separators-color: rgba(0, 0, 0, 0.05) !default; + +// Items text indentation for deeper levels +$sm-blue__collapsible-sub-item-indentation: 8px !default; + + +// ---------------------------------------------------------- +// :: 1.7. Desktop main menu +// ---------------------------------------------------------- + +// Menu box +$sm-blue__desktop-bg: $sm-blue__blue !default; +$sm-blue__desktop-border-radius: $sm-blue__border-radius-base !default; +$sm-blue__desktop-box-shadow: 0 1px 1px $sm-blue__box-shadow !default; + +// Items +$sm-blue__desktop-item-color: $sm-blue__white !default; +$sm-blue__desktop-item-bg: $sm-blue__blue !default; +$sm-blue__desktop-item-hover-bg: darken($sm-blue__blue, 5%) !default; +$sm-blue__desktop-item-current-color: $sm-blue__white !default; +$sm-blue__desktop-item-current-bg: $sm-blue__blue-darker !default; +$sm-blue__desktop-item-disabled-color: lighten($sm-blue__blue, 30%) !default; +$sm-blue__desktop-item-padding-vertical: 13px !default; +$sm-blue__desktop-item-padding-horizontal: 24px !default; + +// Items separators +$sm-blue__desktop-separators-size: 1px !default; +$sm-blue__desktop-separators-color: darken($sm-blue__blue, 5%) !default; + +// Sub menu indicators +$sm-blue__desktop-arrow-size: 5px !default; // border-width +$sm-blue__desktop-arrow-color: $sm-blue__blue-light !default; + +// Vertical menu box +$sm-blue__desktop-vertical-box-shadow: 0 1px 4px $sm-blue__box-shadow !default; + +// Vertical items +$sm-blue__desktop-vertical-item-padding-vertical: 9px !default; +$sm-blue__desktop-vertical-item-padding-horizontal: 23px !default; + + +// ---------------------------------------------------------- +// :: 1.8. Desktop sub menus +// ---------------------------------------------------------- + +// Menu box +$sm-blue__desktop-sub-bg: $sm-blue__white !default; +$sm-blue__desktop-sub-border-color: $sm-blue__gray !default; +$sm-blue__desktop-sub-border-radius: $sm-blue__border-radius-small !default; +$sm-blue__desktop-sub-box-shadow: 0 5px 12px $sm-blue__box-shadow !default; +$sm-blue__desktop-sub-padding-vertical: 7px !default; +$sm-blue__desktop-sub-padding-horizontal: 0 !default; + +// Items +$sm-blue__desktop-sub-item-color: $sm-blue__blue-dark !default; +$sm-blue__desktop-sub-item-bg: transparent !default; +$sm-blue__desktop-sub-item-hover-color: $sm-blue__white !default; +$sm-blue__desktop-sub-item-hover-bg: $sm-blue__blue !default; +$sm-blue__desktop-sub-item-current-color: $sm-blue__white !default; +$sm-blue__desktop-sub-item-current-bg: $sm-blue__blue-darker !default; +$sm-blue__desktop-sub-item-disabled-color: darken($sm-blue__white, 30%) !default; +$sm-blue__desktop-sub-item-padding-vertical: 9px !default; +$sm-blue__desktop-sub-item-padding-horizontal: 23px !default; + + +// ----------------------------------------------------------------------------------------------------------------- +// 2. Theme CSS +// ----------------------------------------------------------------------------------------------------------------- + + +// ---------------------------------------------------------- +// :: 2.1. Collapsible mode (mobile first) +// ---------------------------------------------------------- + +// calc item height and sub menus toggle button size +$sm-blue__item-height: $sm-blue__line-height + $sm-blue__collapsible-item-padding-vertical * 2; +// set toggle button size to 80% of item height +$sm-blue__toggle-size: floor($sm-blue__item-height * 0.8); +$sm-blue__toggle-spacing: floor($sm-blue__item-height * 0.1); + +// Main menu box +.sm-blue { + background: $sm-blue__collapsible-bg; + border-radius: $sm-blue__collapsible-border-radius; + box-shadow: $sm-blue__collapsible-box-shadow; + + // Main menu items + a { + &, + &:hover, + &:focus, + &:active { + padding: $sm-blue__collapsible-item-padding-vertical $sm-blue__collapsible-item-padding-horizontal; + /* make room for the toggle button (sub indicator) */ + padding-right: $sm-blue__collapsible-item-padding-horizontal + $sm-blue__toggle-size + $sm-blue__toggle-spacing; + background: $sm-blue__collapsible-item-bg; + background-image: linear-gradient(to bottom, lighten($sm-blue__collapsible-item-bg, $sm-blue__gradients_amount), darken($sm-blue__collapsible-item-bg, $sm-blue__gradients_amount)); + color: $sm-blue__collapsible-item-color; + font-family: $sm-blue__font-family; + font-size: $sm-blue__font-size-base; + font-weight: bold; + line-height: $sm-blue__line-height; + text-decoration: none; + text-shadow: 0 1px 0 $sm-blue__text-shadow; + } + + &.current { + background: $sm-blue__collapsible-item-current-bg; + background-image: linear-gradient(to bottom, darken($sm-blue__collapsible-item-current-bg, $sm-blue__gradients_amount), lighten($sm-blue__collapsible-item-current-bg, $sm-blue__gradients_amount)); + color: $sm-blue__collapsible-item-current-color; + } + + &.disabled { + color: $sm-blue__collapsible-item-disabled-color; + } + + // Toggle buttons (sub menu indicators) + .sub-arrow { + position: absolute; + top: 50%; + margin-top: -(ceil($sm-blue__toggle-size / 2)); + left: auto; + right: $sm-blue__toggle-spacing; + width: $sm-blue__toggle-size; + height: $sm-blue__toggle-size; + overflow: hidden; + font: bold #{$sm-blue__font-size-small}/#{$sm-blue__toggle-size} monospace !important; + text-align: center; + text-shadow: none; + background: $sm-blue__collapsible-toggle-bg; + border-radius: $sm-blue__border-radius-small; + } + .sub-arrow::before { + content: '+'; + } + &.highlighted .sub-arrow::before { + content: '-'; + } + } + + // round the corners of the first item + > li:first-child > a, > li:first-child > :not(ul) a { + border-radius: $sm-blue__collapsible-border-radius $sm-blue__collapsible-border-radius 0 0; + } + // round the corners of the last item + @include sm-blue__round-corners-last-item($sm-blue__collapsible-border-radius); + + // Sub menus box + ul { + background: $sm-blue__collapsible-sub-bg; + + // darken the background of the 2+ level sub menus + ul { + background: rgba(darken($sm-blue__collapsible-sub-bg, 60%), 0.1); + } + + // Sub menus items + a { + &, + &:hover, + &:focus, + &:active { + background: $sm-blue__collapsible-sub-item-bg; + color: $sm-blue__collapsible-sub-item-color; + font-size: $sm-blue__font-size-small; + text-shadow: none; + // add indentation for sub menus text + border-left: $sm-blue__collapsible-sub-item-indentation solid transparent; + } + + &.current { + background: $sm-blue__collapsible-sub-item-current-bg; + background-image: linear-gradient(to bottom, darken($sm-blue__collapsible-sub-item-current-bg, $sm-blue__gradients_amount), lighten($sm-blue__collapsible-sub-item-current-bg, $sm-blue__gradients_amount)); + color: $sm-blue__collapsible-sub-item-current-color; + } + + &.disabled { + color: $sm-blue__collapsible-sub-item-disabled-color; + } + } + + // Add indentation for sub menus text for deeper levels + @include sm-blue__sub-items-indentation($sm-blue__collapsible-sub-item-indentation); + + // Sub menus items separators + li { + border-top: 1px solid $sm-blue__collapsible-sub-separators-color; + + &:first-child { + border-top: 0; + } + } + } +} + + +// ---------------------------------------------------------- +// :: 2.2. Desktop mode +// ---------------------------------------------------------- + +@media (min-width: $sm-blue__desktop-vp) { + + /* Switch to desktop layout + ----------------------------------------------- + These transform the menu tree from + collapsible to desktop (navbar + dropdowns) + -----------------------------------------------*/ + /* start... (it's not recommended editing these rules) */ + .sm-blue ul{position:absolute;width:12em;} + .sm-blue li{float:left;} + .sm-blue.sm-rtl li{float:right;} + .sm-blue ul li,.sm-blue.sm-rtl ul li,.sm-blue.sm-vertical li{float:none;} + .sm-blue a{white-space:nowrap;} + .sm-blue ul a,.sm-blue.sm-vertical a{white-space:normal;} + .sm-blue .sm-nowrap > li > a,.sm-blue .sm-nowrap > li > :not(ul) a{white-space:nowrap;} + /* ...end */ + + // Main menu box + .sm-blue { + background: $sm-blue__desktop-bg; + background-image: linear-gradient(to bottom, lighten($sm-blue__desktop-bg, $sm-blue__gradients_amount), darken($sm-blue__desktop-bg, $sm-blue__gradients_amount)); + border-radius: $sm-blue__desktop-border-radius; + box-shadow: $sm-blue__desktop-box-shadow; + + // Main menu items + a { + &, + &:hover, + &:focus, + &:active, + &.highlighted { + padding: $sm-blue__desktop-item-padding-vertical $sm-blue__desktop-item-padding-horizontal; + background: $sm-blue__desktop-item-bg; + background-image: linear-gradient(to bottom, lighten($sm-blue__desktop-item-bg, $sm-blue__gradients_amount), darken($sm-blue__desktop-item-bg, $sm-blue__gradients_amount)); + color: $sm-blue__desktop-item-color; + } + + &:hover, + &:focus, + &:active, + &.highlighted { + background: $sm-blue__desktop-item-hover-bg; + background-image: linear-gradient(to bottom, lighten($sm-blue__desktop-item-hover-bg, $sm-blue__gradients_amount), darken($sm-blue__desktop-item-hover-bg, $sm-blue__gradients_amount)); + } + + &.current { + background: $sm-blue__desktop-item-current-bg; + background-image: linear-gradient(to bottom, darken($sm-blue__desktop-item-current-bg, $sm-blue__gradients_amount), lighten($sm-blue__desktop-item-current-bg, $sm-blue__gradients_amount)); + color: $sm-blue__desktop-item-current-color; + } + + &.disabled { + background: $sm-blue__desktop-item-bg; + background-image: linear-gradient(to bottom, lighten($sm-blue__desktop-item-bg, $sm-blue__gradients_amount), darken($sm-blue__desktop-item-bg, $sm-blue__gradients_amount)); + color: $sm-blue__desktop-item-disabled-color; + } + + // Sub menu indicators + .sub-arrow { + top: auto; + margin-top: 0; + bottom: 2px; + left: 50%; + margin-left: -$sm-blue__desktop-arrow-size; + right: auto; + width: 0; + height: 0; + border-width: $sm-blue__desktop-arrow-size; + border-style: solid dashed dashed dashed; + border-color: $sm-blue__desktop-arrow-color transparent transparent transparent; + background: transparent; + border-radius: 0; + } + // reset mobile first style + .sub-arrow::before { + display: none; + } + } + + // round the corners of the first and last items + > li:first-child > a, > li:first-child > :not(ul) a { + border-radius: $sm-blue__desktop-border-radius 0 0 $sm-blue__desktop-border-radius; + } + > li:last-child > a, > li:last-child > :not(ul) a { + border-radius: 0 $sm-blue__desktop-border-radius $sm-blue__desktop-border-radius 0 !important; + } + + // Main menu items separators + > li { + border-left: $sm-blue__desktop-separators-size solid $sm-blue__desktop-separators-color; + + &:first-child { + border-left: 0; + } + } + + // Sub menus box + ul { + border: $sm-blue__border-width solid $sm-blue__desktop-sub-border-color; + padding: $sm-blue__desktop-sub-padding-vertical $sm-blue__desktop-sub-padding-horizontal; + background: $sm-blue__desktop-sub-bg; + border-radius: 0 0 $sm-blue__desktop-sub-border-radius $sm-blue__desktop-sub-border-radius !important; + box-shadow: $sm-blue__desktop-sub-box-shadow; + + // 2+ sub levels need rounding of all corners + ul { + border-radius: $sm-blue__desktop-sub-border-radius !important; + background: $sm-blue__desktop-sub-bg; + } + + // Sub menus items + a { + &, + &:hover, + &:focus, + &:active, + &.highlighted { + border: 0 !important; + padding: $sm-blue__desktop-sub-item-padding-vertical $sm-blue__desktop-sub-item-padding-horizontal; + background: $sm-blue__desktop-sub-item-bg; + color: $sm-blue__desktop-sub-item-color; + border-radius: 0 !important; + } + + &:hover, + &:focus, + &:active, + &.highlighted { + background: $sm-blue__desktop-sub-item-hover-bg; + background-image: linear-gradient(to bottom, lighten($sm-blue__desktop-sub-item-hover-bg, $sm-blue__gradients_amount), darken($sm-blue__desktop-sub-item-hover-bg, $sm-blue__gradients_amount)); + color: $sm-blue__desktop-sub-item-hover-color; + } + + &.current { + background: $sm-blue__desktop-sub-item-current-bg; + background-image: linear-gradient(to bottom, darken($sm-blue__desktop-sub-item-current-bg, $sm-blue__gradients_amount), lighten($sm-blue__desktop-sub-item-current-bg, $sm-blue__gradients_amount)); + color: $sm-blue__desktop-sub-item-current-color; + } + + &.disabled { + background: $sm-blue__desktop-sub-bg; + color: $sm-blue__desktop-sub-item-disabled-color; + } + + // Sub menu indicators + .sub-arrow { + top: 50%; + margin-top: -$sm-blue__desktop-arrow-size; + bottom: auto; + left: auto; + margin-left: 0; + right: 10px; + border-style: dashed dashed dashed solid; + border-color: transparent transparent transparent $sm-blue__desktop-arrow-color; + } + } + + // No sub menus items separators + li { + border: 0; + } + } + + // Scrolling arrows containers for tall sub menus - test sub menu: "Sub test" -> "more..." in the default download package + .scroll-up, + .scroll-down { + position: absolute; + display: none; + visibility: hidden; + overflow: hidden; + background: $sm-blue__desktop-sub-bg; + height: 20px; + // width and position will be set automatically by the script + } + .scroll-up-arrow, + .scroll-down-arrow { + position: absolute; + top: -2px; + left: 50%; + margin-left: -8px; + // we will use one-side border to create a triangle so that we don't use a real background image, of course, you can use a real image if you like too + width: 0; + height: 0; + overflow: hidden; + border-width: 8px; // tweak size of the arrow + border-style: dashed dashed solid dashed; + border-color: transparent transparent $sm-blue__desktop-sub-item-color transparent; + } + .scroll-down-arrow { + top: 6px; + border-style: solid dashed dashed dashed; + border-color: $sm-blue__desktop-sub-item-color transparent transparent transparent; + } + + + // Rigth-to-left + + // Main menu box + &.sm-rtl { + + // Vertical main menu items + &.sm-vertical { + a { + // Sub menu indicators + .sub-arrow { + right: auto; + left: 10px; + border-style: dashed solid dashed dashed; + border-color: transparent $sm-blue__desktop-arrow-color transparent transparent; + } + } + } + + // round the corners of the first and last items + > li:first-child > a, > li:first-child > :not(ul) a { + border-radius: 0 $sm-blue__desktop-border-radius $sm-blue__desktop-border-radius 0; + } + > li:last-child > a, > li:last-child > :not(ul) a { + border-radius: $sm-blue__desktop-border-radius 0 0 $sm-blue__desktop-border-radius !important; + } + + // Main menu items separators + > li { + &:first-child { + border-left: $sm-blue__desktop-separators-size solid $sm-blue__desktop-separators-color; + } + &:last-child { + border-left: 0; + } + } + + // Sub menus box + ul { + a { + // Sub menu indicators + .sub-arrow { + right: auto; + left: 10px; + border-style: dashed solid dashed dashed; + border-color: transparent $sm-blue__desktop-arrow-color transparent transparent; + } + } + } + } + + + // Vertical main menu + + // Main menu box + &.sm-vertical { + box-shadow: $sm-blue__desktop-vertical-box-shadow; + + // Main menu items + a { + padding: $sm-blue__desktop-vertical-item-padding-vertical $sm-blue__desktop-vertical-item-padding-horizontal; + + // Sub menu indicators + .sub-arrow { + top: 50%; + margin-top: -$sm-blue__desktop-arrow-size; + bottom: auto; + left: auto; + margin-left: 0; + right: 10px; + border-style: dashed dashed dashed solid; + border-color: transparent transparent transparent $sm-blue__desktop-arrow-color; + } + } + + // round the corners of the first and last items + > li:first-child > a, > li:first-child > :not(ul) a { + border-radius: $sm-blue__desktop-border-radius $sm-blue__desktop-border-radius 0 0; + } + > li:last-child > a, > li:last-child > :not(ul) a { + border-radius: 0 0 $sm-blue__desktop-border-radius $sm-blue__desktop-border-radius !important; + } + + // No main menu item separators + > li { + border-left: 0 !important; + } + + // Sub menus box + ul { + border-radius: $sm-blue__desktop-sub-border-radius !important; + + // Sub menus items + a { + padding: $sm-blue__desktop-sub-item-padding-vertical $sm-blue__desktop-sub-item-padding-horizontal; + } + } + } + } +} \ No newline at end of file diff --git a/civicrm/bower_components/smartmenus/dist/css/sm-blue/mixins/_round-corners-last-item.scss b/civicrm/bower_components/smartmenus/dist/css/sm-blue/mixins/_round-corners-last-item.scss new file mode 100644 index 0000000000..9622771c0b --- /dev/null +++ b/civicrm/bower_components/smartmenus/dist/css/sm-blue/mixins/_round-corners-last-item.scss @@ -0,0 +1,25 @@ +// Generate rules to round the corners of the last collapsible item + +@mixin sm-blue__round-corners-last-item($amount, $chainable: 'ul > li:last-child > ', $level: 4, $chain_prefix: '> li:last-child > ', $chain: '', $selector: '') { + $chain: $chain_prefix; + $selector: $chain + 'a, ' + $chain + '*:not(ul) a, ' + $chain + 'ul'; + @for $i from 1 through $level { + $chain: $chain + $chainable; + $selector: $selector + ', +' + $chain + ' a, ' + $chain + '*:not(ul) a, ' + $chain + ' ul'; + } + #{$selector} { + border-radius: 0 0 $amount $amount; + } + // highlighted items, don't need rounding since their sub is open + $chain: $chain_prefix; + $selector: $chain + 'a.highlighted, ' + $chain + '*:not(ul) a.highlighted'; + @for $i from 1 through $level { + $chain: $chain + $chainable; + $selector: $selector + ', +' + $chain + ' a.highlighted, ' + $chain + '*:not(ul) a.highlighted'; + } + #{$selector} { + border-radius: 0; + } +} \ No newline at end of file diff --git a/civicrm/bower_components/smartmenus/dist/css/sm-blue/mixins/_sub-items-indentation.scss b/civicrm/bower_components/smartmenus/dist/css/sm-blue/mixins/_sub-items-indentation.scss new file mode 100644 index 0000000000..30cd01b68a --- /dev/null +++ b/civicrm/bower_components/smartmenus/dist/css/sm-blue/mixins/_sub-items-indentation.scss @@ -0,0 +1,15 @@ +// Generate rules to indent sub menus text +// +// We'll use left border to avoid messing with the padding. + +@mixin sm-blue__sub-items-indentation($amount, $chainable: 'ul ', $level: 4, $chain: '') { + @for $i from 1 through $level { + $chain: $chain + $chainable; + #{$chain} a, + #{$chain} a:hover, + #{$chain} a:focus, + #{$chain} a:active { + border-left: ($amount * ($i + 1)) solid transparent; + } + } +} \ No newline at end of file diff --git a/civicrm/bower_components/smartmenus/dist/css/sm-blue/sm-blue.css b/civicrm/bower_components/smartmenus/dist/css/sm-blue/sm-blue.css new file mode 100644 index 0000000000..4cff3bb543 --- /dev/null +++ b/civicrm/bower_components/smartmenus/dist/css/sm-blue/sm-blue.css @@ -0,0 +1,333 @@ +@import url(https://fonts.googleapis.com/css?family=PT+Sans+Narrow:400,700); +.sm-blue { + background: transparent; + border-radius: 8px; + box-shadow: 0 1px 4px rgba(0, 0, 0, 0.2); +} +.sm-blue a, .sm-blue a:hover, .sm-blue a:focus, .sm-blue a:active { + padding: 10px 20px; + /* make room for the toggle button (sub indicator) */ + padding-right: 58px; + background: #3092c0; + background-image: linear-gradient(to bottom, #3298c8, #2e8cb8); + color: #fff; + font-family: "PT Sans Narrow", "Arial Narrow", Arial, Helvetica, sans-serif; + font-size: 18px; + font-weight: bold; + line-height: 23px; + text-decoration: none; + text-shadow: 0 1px 0 rgba(0, 0, 0, 0.2); +} +.sm-blue a.current { + background: #006892; + background-image: linear-gradient(to bottom, #006188, #006f9c); + color: #fff; +} +.sm-blue a.disabled { + color: #a1d1e8; +} +.sm-blue a .sub-arrow { + position: absolute; + top: 50%; + margin-top: -17px; + left: auto; + right: 4px; + width: 34px; + height: 34px; + overflow: hidden; + font: bold 16px/34px monospace !important; + text-align: center; + text-shadow: none; + background: rgba(0, 0, 0, 0.1); + border-radius: 4px; +} +.sm-blue a .sub-arrow::before { + content: '+'; +} +.sm-blue a.highlighted .sub-arrow::before { + content: '-'; +} +.sm-blue > li:first-child > a, .sm-blue > li:first-child > :not(ul) a { + border-radius: 8px 8px 0 0; +} +.sm-blue > li:last-child > a, .sm-blue > li:last-child > *:not(ul) a, .sm-blue > li:last-child > ul, .sm-blue > li:last-child > ul > li:last-child > a, .sm-blue > li:last-child > ul > li:last-child > *:not(ul) a, .sm-blue > li:last-child > ul > li:last-child > ul, .sm-blue > li:last-child > ul > li:last-child > ul > li:last-child > a, .sm-blue > li:last-child > ul > li:last-child > ul > li:last-child > *:not(ul) a, .sm-blue > li:last-child > ul > li:last-child > ul > li:last-child > ul, .sm-blue > li:last-child > ul > li:last-child > ul > li:last-child > ul > li:last-child > a, .sm-blue > li:last-child > ul > li:last-child > ul > li:last-child > ul > li:last-child > *:not(ul) a, .sm-blue > li:last-child > ul > li:last-child > ul > li:last-child > ul > li:last-child > ul, .sm-blue > li:last-child > ul > li:last-child > ul > li:last-child > ul > li:last-child > ul > li:last-child > a, .sm-blue > li:last-child > ul > li:last-child > ul > li:last-child > ul > li:last-child > ul > li:last-child > *:not(ul) a, .sm-blue > li:last-child > ul > li:last-child > ul > li:last-child > ul > li:last-child > ul > li:last-child > ul { + border-radius: 0 0 8px 8px; +} +.sm-blue > li:last-child > a.highlighted, .sm-blue > li:last-child > *:not(ul) a.highlighted, .sm-blue > li:last-child > ul > li:last-child > a.highlighted, .sm-blue > li:last-child > ul > li:last-child > *:not(ul) a.highlighted, .sm-blue > li:last-child > ul > li:last-child > ul > li:last-child > a.highlighted, .sm-blue > li:last-child > ul > li:last-child > ul > li:last-child > *:not(ul) a.highlighted, .sm-blue > li:last-child > ul > li:last-child > ul > li:last-child > ul > li:last-child > a.highlighted, .sm-blue > li:last-child > ul > li:last-child > ul > li:last-child > ul > li:last-child > *:not(ul) a.highlighted, .sm-blue > li:last-child > ul > li:last-child > ul > li:last-child > ul > li:last-child > ul > li:last-child > a.highlighted, .sm-blue > li:last-child > ul > li:last-child > ul > li:last-child > ul > li:last-child > ul > li:last-child > *:not(ul) a.highlighted { + border-radius: 0; +} +.sm-blue ul { + background: #fff; +} +.sm-blue ul ul { + background: rgba(102, 102, 102, 0.1); +} +.sm-blue ul a, .sm-blue ul a:hover, .sm-blue ul a:focus, .sm-blue ul a:active { + background: transparent; + color: #2b82ac; + font-size: 16px; + text-shadow: none; + border-left: 8px solid transparent; +} +.sm-blue ul a.current { + background: #006892; + background-image: linear-gradient(to bottom, #006188, #006f9c); + color: #fff; +} +.sm-blue ul a.disabled { + color: #b3b3b3; +} +.sm-blue ul ul a, +.sm-blue ul ul a:hover, +.sm-blue ul ul a:focus, +.sm-blue ul ul a:active { + border-left: 16px solid transparent; +} +.sm-blue ul ul ul a, +.sm-blue ul ul ul a:hover, +.sm-blue ul ul ul a:focus, +.sm-blue ul ul ul a:active { + border-left: 24px solid transparent; +} +.sm-blue ul ul ul ul a, +.sm-blue ul ul ul ul a:hover, +.sm-blue ul ul ul ul a:focus, +.sm-blue ul ul ul ul a:active { + border-left: 32px solid transparent; +} +.sm-blue ul ul ul ul ul a, +.sm-blue ul ul ul ul ul a:hover, +.sm-blue ul ul ul ul ul a:focus, +.sm-blue ul ul ul ul ul a:active { + border-left: 40px solid transparent; +} +.sm-blue ul li { + border-top: 1px solid rgba(0, 0, 0, 0.05); +} +.sm-blue ul li:first-child { + border-top: 0; +} + +@media (min-width: 768px) { + /* Switch to desktop layout + ----------------------------------------------- + These transform the menu tree from + collapsible to desktop (navbar + dropdowns) + -----------------------------------------------*/ + /* start... (it's not recommended editing these rules) */ + .sm-blue ul { + position: absolute; + width: 12em; + } + + .sm-blue li { + float: left; + } + + .sm-blue.sm-rtl li { + float: right; + } + + .sm-blue ul li, .sm-blue.sm-rtl ul li, .sm-blue.sm-vertical li { + float: none; + } + + .sm-blue a { + white-space: nowrap; + } + + .sm-blue ul a, .sm-blue.sm-vertical a { + white-space: normal; + } + + .sm-blue .sm-nowrap > li > a, .sm-blue .sm-nowrap > li > :not(ul) a { + white-space: nowrap; + } + + /* ...end */ + .sm-blue { + background: #3092c0; + background-image: linear-gradient(to bottom, #3298c8, #2e8cb8); + border-radius: 8px; + box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2); + } + .sm-blue a, .sm-blue a:hover, .sm-blue a:focus, .sm-blue a:active, .sm-blue a.highlighted { + padding: 13px 24px; + background: #3092c0; + background-image: linear-gradient(to bottom, #3298c8, #2e8cb8); + color: #fff; + } + .sm-blue a:hover, .sm-blue a:focus, .sm-blue a:active, .sm-blue a.highlighted { + background: #2b82ac; + background-image: linear-gradient(to bottom, #2d89b4, #297ca3); + } + .sm-blue a.current { + background: #006892; + background-image: linear-gradient(to bottom, #006188, #006f9c); + color: #fff; + } + .sm-blue a.disabled { + background: #3092c0; + background-image: linear-gradient(to bottom, #3298c8, #2e8cb8); + color: #a1d1e8; + } + .sm-blue a .sub-arrow { + top: auto; + margin-top: 0; + bottom: 2px; + left: 50%; + margin-left: -5px; + right: auto; + width: 0; + height: 0; + border-width: 5px; + border-style: solid dashed dashed dashed; + border-color: #a1d1e8 transparent transparent transparent; + background: transparent; + border-radius: 0; + } + .sm-blue a .sub-arrow::before { + display: none; + } + .sm-blue > li:first-child > a, .sm-blue > li:first-child > :not(ul) a { + border-radius: 8px 0 0 8px; + } + .sm-blue > li:last-child > a, .sm-blue > li:last-child > :not(ul) a { + border-radius: 0 8px 8px 0 !important; + } + .sm-blue > li { + border-left: 1px solid #2b82ac; + } + .sm-blue > li:first-child { + border-left: 0; + } + .sm-blue ul { + border: 1px solid #a8a8a8; + padding: 7px 0; + background: #fff; + border-radius: 0 0 4px 4px !important; + box-shadow: 0 5px 12px rgba(0, 0, 0, 0.2); + } + .sm-blue ul ul { + border-radius: 4px !important; + background: #fff; + } + .sm-blue ul a, .sm-blue ul a:hover, .sm-blue ul a:focus, .sm-blue ul a:active, .sm-blue ul a.highlighted { + border: 0 !important; + padding: 9px 23px; + background: transparent; + color: #2b82ac; + border-radius: 0 !important; + } + .sm-blue ul a:hover, .sm-blue ul a:focus, .sm-blue ul a:active, .sm-blue ul a.highlighted { + background: #3092c0; + background-image: linear-gradient(to bottom, #3298c8, #2e8cb8); + color: #fff; + } + .sm-blue ul a.current { + background: #006892; + background-image: linear-gradient(to bottom, #006188, #006f9c); + color: #fff; + } + .sm-blue ul a.disabled { + background: #fff; + color: #b3b3b3; + } + .sm-blue ul a .sub-arrow { + top: 50%; + margin-top: -5px; + bottom: auto; + left: auto; + margin-left: 0; + right: 10px; + border-style: dashed dashed dashed solid; + border-color: transparent transparent transparent #a1d1e8; + } + .sm-blue ul li { + border: 0; + } + .sm-blue .scroll-up, + .sm-blue .scroll-down { + position: absolute; + display: none; + visibility: hidden; + overflow: hidden; + background: #fff; + height: 20px; + } + .sm-blue .scroll-up-arrow, + .sm-blue .scroll-down-arrow { + position: absolute; + top: -2px; + left: 50%; + margin-left: -8px; + width: 0; + height: 0; + overflow: hidden; + border-width: 8px; + border-style: dashed dashed solid dashed; + border-color: transparent transparent #2b82ac transparent; + } + .sm-blue .scroll-down-arrow { + top: 6px; + border-style: solid dashed dashed dashed; + border-color: #2b82ac transparent transparent transparent; + } + .sm-blue.sm-rtl.sm-vertical a .sub-arrow { + right: auto; + left: 10px; + border-style: dashed solid dashed dashed; + border-color: transparent #a1d1e8 transparent transparent; + } + .sm-blue.sm-rtl > li:first-child > a, .sm-blue.sm-rtl > li:first-child > :not(ul) a { + border-radius: 0 8px 8px 0; + } + .sm-blue.sm-rtl > li:last-child > a, .sm-blue.sm-rtl > li:last-child > :not(ul) a { + border-radius: 8px 0 0 8px !important; + } + .sm-blue.sm-rtl > li:first-child { + border-left: 1px solid #2b82ac; + } + .sm-blue.sm-rtl > li:last-child { + border-left: 0; + } + .sm-blue.sm-rtl ul a .sub-arrow { + right: auto; + left: 10px; + border-style: dashed solid dashed dashed; + border-color: transparent #a1d1e8 transparent transparent; + } + .sm-blue.sm-vertical { + box-shadow: 0 1px 4px rgba(0, 0, 0, 0.2); + } + .sm-blue.sm-vertical a { + padding: 9px 23px; + } + .sm-blue.sm-vertical a .sub-arrow { + top: 50%; + margin-top: -5px; + bottom: auto; + left: auto; + margin-left: 0; + right: 10px; + border-style: dashed dashed dashed solid; + border-color: transparent transparent transparent #a1d1e8; + } + .sm-blue.sm-vertical > li:first-child > a, .sm-blue.sm-vertical > li:first-child > :not(ul) a { + border-radius: 8px 8px 0 0; + } + .sm-blue.sm-vertical > li:last-child > a, .sm-blue.sm-vertical > li:last-child > :not(ul) a { + border-radius: 0 0 8px 8px !important; + } + .sm-blue.sm-vertical > li { + border-left: 0 !important; + } + .sm-blue.sm-vertical ul { + border-radius: 4px !important; + } + .sm-blue.sm-vertical ul a { + padding: 9px 23px; + } +} + +/*# sourceMappingURL=sm-blue.css.map */ diff --git a/civicrm/bower_components/smartmenus/dist/css/sm-blue/sm-blue.css.map b/civicrm/bower_components/smartmenus/dist/css/sm-blue/sm-blue.css.map new file mode 100644 index 0000000000..b9c9d7e5d8 --- /dev/null +++ b/civicrm/bower_components/smartmenus/dist/css/sm-blue/sm-blue.css.map @@ -0,0 +1,7 @@ +{ +"version": 3, +"mappings": "AAsCQ,2EAAmE;AAuI3E,QAAS;EACR,UAAU,EAlHsB,WAAW;EAmH3C,aAAa,EAlH2B,GAA4B;EAmHpE,UAAU,EAlH4B,4BAA+B;;AAsHpE,iEAGS;EACR,OAAO,EAAE,SAAyF;EAClG,qDAAqD;EACrD,aAAa,EAAE,IAAgG;EAC/G,UAAU,EAtC4B,OAAc;EAuCpD,gBAAgB,EAAE,4CAAiK;EACnL,KAAK,EAvCqC,IAAe;EAwCzD,WAAW,EAtJiB,8DAA8D;EAuJ1F,SAAS,EAtJqB,IAAI;EAuJlC,WAAW,EAAE,IAAI;EACjB,WAAW,EAtJiB,IAAI;EAuJhC,eAAe,EAAE,IAAI;EACrB,WAAW,EAAE,0BAA6B;;AAG3C,kBAAU;EACT,UAAU,EAhD8B,OAAqB;EAiD7D,gBAAgB,EAAE,4CAAiL;EACnM,KAAK,EAnDqC,IAAe;;AAsD1D,mBAAW;EACV,KAAK,EAxIsC,OAA4B;;AA4IxE,qBAAW;EACV,QAAQ,EAAE,QAAQ;EAClB,GAAG,EAAE,GAAG;EACR,UAAU,EAAE,KAAkC;EAC9C,IAAI,EAAE,IAAI;EACV,KAAK,EA5CkB,GAAkC;EA6CzD,KAAK,EA9Ce,IAAkC;EA+CtD,MAAM,EA/Cc,IAAkC;EAgDtD,QAAQ,EAAE,MAAM;EAChB,IAAI,EAAE,mCAA+E;EACrF,UAAU,EAAE,MAAM;EAClB,WAAW,EAAE,IAAI;EACjB,UAAU,EAnJyB,kBAAkB;EAoJrD,aAAa,EA1KqB,GAAG;;AA4KtC,6BAAmB;EAClB,OAAO,EAAE,GAAG;;AAEb,yCAAiC;EAChC,OAAO,EAAE,GAAG;;AAKd,qEAAoD;EACnD,aAAa,EAAE,WAA2E;;AChO3F,6mCAAa;EACZ,aAAa,EAAE,WAAmB;;AAUnC,w3BAAa;EACZ,aAAa,EAAE,CAAC;;AD0NjB,WAAG;EACF,UAAU,EA3FiC,IAAe;;AA8F1D,cAAG;EACF,UAAU,EAAE,wBAAoD;;AAKhE,6EAGS;EACR,UAAU,EAxK0B,WAAW;EAyK/C,KAAK,EA7G8B,OAAmB;EA8GtD,SAAS,EAtNqB,IAAI;EAuNlC,WAAW,EAAE,IAAI;EAEjB,WAAW,EAAE,qBAA4D;;AAG1E,qBAAU;EACT,UAAU,EAhH6B,OAAqB;EAiH5D,gBAAgB,EAAE,4CAAyL;EAC3M,KAAK,EAnHoC,IAAe;;AAsHzD,sBAAW;EACV,KAAK,EApLwC,OAA4B;;AElF3E;;;uBAGmB;EAClB,WAAW,EAAE,sBAAsC;;AAJpD;;;0BAGmB;EAClB,WAAW,EAAE,sBAAsC;;AAJpD;;;6BAGmB;EAClB,WAAW,EAAE,sBAAsC;;AAJpD;;;gCAGmB;EAClB,WAAW,EAAE,sBAAsC;;AF0QpD,cAAG;EACF,UAAU,EAAE,6BAAoD;;AAEhE,0BAAc;EACb,UAAU,EAAE,CAAC;;;AAWjB,yBAAyC;EAExC;;;;mDAIiD;EACjD,yDAAyD;EACzD,WAAW;IAAC,QAAQ,EAAC,QAAQ;IAAC,KAAK,EAAC,IAAI;;;EACxC,WAAW;IAAC,KAAK,EAAC,IAAI;;;EACtB,kBAAkB;IAAC,KAAK,EAAC,KAAK;;;EAC9B,8DAA4D;IAAC,KAAK,EAAC,IAAI;;;EACvE,UAAU;IAAC,WAAW,EAAC,MAAM;;;EAC7B,qCAAoC;IAAC,WAAW,EAAC,MAAM;;;EACvD,mEAAkE;IAAC,WAAW,EAAC,MAAM;;;EACrF,YAAY;EAGZ,QAAS;IACR,UAAU,EAlK6B,OAAc;IAmKrD,gBAAgB,EAAE,4CAA+I;IACjK,aAAa,EAjNuB,GAA4B;IAkNhE,UAAU,EAjNwB,4BAA+B;;EAqNhE,yFAIc;IACb,OAAO,EAAE,SAAiF;IAC1F,UAAU,EA/K2B,OAAc;IAgLnD,gBAAgB,EAAE,4CAAyJ;IAC3K,KAAK,EAhLoC,IAAe;;EAmLzD,6EAGc;IACb,UAAU,EA/NwB,OAA0B;IAgO5D,gBAAgB,EAAE,4CAAqK;;EAGxL,kBAAU;IACT,UAAU,EA3L6B,OAAqB;IA4L5D,gBAAgB,EAAE,4CAAyK;IAC3L,KAAK,EA9LoC,IAAe;;EAiMzD,mBAAW;IACV,UAAU,EAnM2B,OAAc;IAoMnD,gBAAgB,EAAE,4CAAyJ;IAC3K,KAAK,EAzOkC,OAA4B;;EA6OpE,qBAAW;IACV,GAAG,EAAE,IAAI;IACT,UAAU,EAAE,CAAC;IACb,MAAM,EAAE,GAAG;IACX,IAAI,EAAE,GAAG;IACT,WAAW,EAAE,IAA6B;IAC1C,KAAK,EAAE,IAAI;IACX,KAAK,EAAE,CAAC;IACR,MAAM,EAAE,CAAC;IACT,YAAY,EA7OoB,GAAG;IA8OnC,YAAY,EAAE,0BAA0B;IACxC,YAAY,EAAE,2CAAiE;IAC/E,UAAU,EAAE,WAAW;IACvB,aAAa,EAAE,CAAC;;EAGjB,6BAAmB;IAClB,OAAO,EAAE,IAAI;;EAKf,qEAAoD;IACnD,aAAa,EAAE,WAAmE;;EAEnF,mEAAkD;IACjD,aAAa,EAAE,sBAA8E;;EAI9F,aAAK;IACJ,WAAW,EAAE,iBAA0E;;EAEvF,yBAAc;IACb,WAAW,EAAE,CAAC;;EAKhB,WAAG;IACF,MAAM,EAAE,iBAA+D;IACvE,OAAO,EAAE,KAA+E;IACxF,UAAU,EAlPgC,IAAe;IAmPzD,aAAa,EAAE,sBAAsF;IACrG,UAAU,EA7P0B,6BAAgC;;EAgQpE,cAAG;IACF,aAAa,EAAE,cAA8C;IAC7D,UAAU,EAzP+B,IAAe;;EA8PxD,wGAIc;IACb,MAAM,EAAE,YAAY;IACpB,OAAO,EAAE,QAAyF;IAClG,UAAU,EAxQsB,WAAW;IAyQ3C,KAAK,EA1Q6B,OAAmB;IA2QrD,aAAa,EAAE,YAAY;;EAG5B,yFAGc;IACb,UAAU,EA/Q0B,OAAc;IAgRlD,gBAAgB,EAAE,4CAA6K;IAC/L,KAAK,EAhRmC,IAAe;;EAmRxD,qBAAU;IACT,UAAU,EAnR4B,OAAqB;IAoR3D,gBAAgB,EAAE,4CAAiL;IACnM,KAAK,EAtRmC,IAAe;;EAyRxD,sBAAW;IACV,UAAU,EA1R8B,IAAe;IA2RvD,KAAK,EAzRoC,OAA4B;;EA6RtE,wBAAW;IACV,GAAG,EAAE,GAAG;IACR,UAAU,EAAE,IAA6B;IACzC,MAAM,EAAE,IAAI;IACZ,IAAI,EAAE,IAAI;IACV,WAAW,EAAE,CAAC;IACd,KAAK,EAAE,IAAI;IACX,YAAY,EAAE,0BAA0B;IACxC,YAAY,EAAE,2CAAiE;;EAKjF,cAAG;IACF,MAAM,EAAE,CAAC;;EAKX;uBACa;IACZ,QAAQ,EAAE,QAAQ;IAClB,OAAO,EAAE,IAAI;IACb,UAAU,EAAE,MAAM;IAClB,QAAQ,EAAE,MAAM;IAChB,UAAU,EAxTgC,IAAe;IAyTzD,MAAM,EAAE,IAAI;;EAGb;6BACmB;IAClB,QAAQ,EAAE,QAAQ;IAClB,GAAG,EAAE,IAAI;IACT,IAAI,EAAE,GAAG;IACT,WAAW,EAAE,IAAI;IAEjB,KAAK,EAAE,CAAC;IACR,MAAM,EAAE,CAAC;IACT,QAAQ,EAAE,MAAM;IAChB,YAAY,EAAE,GAAG;IACjB,YAAY,EAAE,0BAA0B;IACxC,YAAY,EAAE,2CAAoE;;EAEnF,2BAAmB;IAClB,GAAG,EAAE,GAAG;IACR,YAAY,EAAE,0BAA0B;IACxC,YAAY,EAAE,2CAAoE;;EAahF,wCAAW;IACV,KAAK,EAAE,IAAI;IACX,IAAI,EAAE,IAAI;IACV,YAAY,EAAE,0BAA0B;IACxC,YAAY,EAAE,2CAAiE;;EAMlF,mFAAoD;IACnD,aAAa,EAAE,WAAmE;;EAEnF,iFAAkD;IACjD,aAAa,EAAE,sBAA8E;;EAK7F,gCAAc;IACb,WAAW,EAAE,iBAA0E;;EAExF,+BAAa;IACZ,WAAW,EAAE,CAAC;;EAQd,+BAAW;IACV,KAAK,EAAE,IAAI;IACX,IAAI,EAAE,IAAI;IACV,YAAY,EAAE,0BAA0B;IACxC,YAAY,EAAE,2CAAiE;;EAUnF,oBAAc;IACb,UAAU,EAha8B,4BAA+B;;EAmavE,sBAAE;IACD,OAAO,EAAE,QAAmG;;EAG5G,iCAAW;IACV,GAAG,EAAE,GAAG;IACR,UAAU,EAAE,IAA6B;IACzC,MAAM,EAAE,IAAI;IACZ,IAAI,EAAE,IAAI;IACV,WAAW,EAAE,CAAC;IACd,KAAK,EAAE,IAAI;IACX,YAAY,EAAE,0BAA0B;IACxC,YAAY,EAAE,2CAAiE;;EAKjF,6FAAoD;IACnD,aAAa,EAAE,WAAmE;;EAEnF,2FAAkD;IACjD,aAAa,EAAE,sBAA8E;;EAI9F,yBAAK;IACJ,WAAW,EAAE,YAAY;;EAI1B,uBAAG;IACF,aAAa,EAAE,cAA8C;;EAG7D,yBAAE;IACD,OAAO,EAAE,QAAyF", +"sources": ["_sm-blue-theme.scss","mixins/_round-corners-last-item.scss","mixins/_sub-items-indentation.scss"], +"names": [], +"file": "sm-blue.css" +} diff --git a/civicrm/bower_components/smartmenus/dist/css/sm-blue/sm-blue.scss b/civicrm/bower_components/smartmenus/dist/css/sm-blue/sm-blue.scss new file mode 100644 index 0000000000..ddb9f1cc2a --- /dev/null +++ b/civicrm/bower_components/smartmenus/dist/css/sm-blue/sm-blue.scss @@ -0,0 +1,4 @@ +@import '_mixins.scss'; + +// the variables + the CSS +@import '_sm-blue-theme.scss'; \ No newline at end of file diff --git a/civicrm/bower_components/smartmenus/dist/css/sm-clean/_mixins.scss b/civicrm/bower_components/smartmenus/dist/css/sm-clean/_mixins.scss new file mode 100644 index 0000000000..0ed06503c8 --- /dev/null +++ b/civicrm/bower_components/smartmenus/dist/css/sm-clean/_mixins.scss @@ -0,0 +1,2 @@ +@import 'mixins/_sub-items-indentation.scss'; +@import 'mixins/_round-corners-last-item.scss'; \ No newline at end of file diff --git a/civicrm/bower_components/smartmenus/dist/css/sm-clean/_sm-clean-theme.scss b/civicrm/bower_components/smartmenus/dist/css/sm-clean/_sm-clean-theme.scss new file mode 100644 index 0000000000..14bd800b0b --- /dev/null +++ b/civicrm/bower_components/smartmenus/dist/css/sm-clean/_sm-clean-theme.scss @@ -0,0 +1,579 @@ +// This file is best viewed with Tab size 4 code indentation + + +// ----------------------------------------------------------------------------------------------------------------- +// 1. Theme Quick Settings (Variables) +// (for further control, you will need to dig into the actual CSS in 2.) +// ----------------------------------------------------------------------------------------------------------------- + + +// ---------------------------------------------------------- +// :: 1.1. Colors +// ---------------------------------------------------------- + +$sm-clean__white: #fff !default; +$sm-clean__gray: darken($sm-clean__white, 6.5%) !default; +$sm-clean__gray-dark: darken($sm-clean__white, 26.5%) !default; +$sm-clean__gray-darker: darken($sm-clean__white, 66.5%) !default; +$sm-clean__red: #D23600 !default; + +$sm-clean__box-shadow: rgba(0, 0, 0, 0.2) !default; + + +// ---------------------------------------------------------- +// :: 1.2. Breakpoints +// ---------------------------------------------------------- + +$sm-clean__desktop-vp: 768px !default; // switch from collapsible to desktop + + +// ---------------------------------------------------------- +// :: 1.3. Typography +// ---------------------------------------------------------- + +$sm-clean__font-family: "Lucida Sans Unicode", "Lucida Sans", "Lucida Grande", Arial, sans-serif !default; +$sm-clean__font-size-base: 18px !default; +$sm-clean__font-size-small: 16px !default; +$sm-clean__line-height: 17px !default; + + +// ---------------------------------------------------------- +// :: 1.4. Borders +// ---------------------------------------------------------- + +$sm-clean__border-width: 1px !default; +$sm-clean__border-radius: 5px !default; + + +// ---------------------------------------------------------- +// :: 1.5. Collapsible main menu +// ---------------------------------------------------------- + +// Menu box +$sm-clean__collapsible-bg: $sm-clean__gray !default; +$sm-clean__collapsible-border-radius: $sm-clean__border-radius !default; + +// Items +$sm-clean__collapsible-item-color: $sm-clean__gray-darker !default; +$sm-clean__collapsible-item-current-color: $sm-clean__red !default; +$sm-clean__collapsible-item-disabled-color: darken($sm-clean__gray, 20%) !default; +$sm-clean__collapsible-item-padding-vertical: 13px !default; +$sm-clean__collapsible-item-padding-horizontal: 20px !default; + +// Items separators +$sm-clean__collapsible-separators-color: rgba(0, 0, 0, 0.05) !default; + +// Toggle button (sub menu indicators) +$sm-clean__collapsible-toggle-bg: rgba(255, 255, 255, 0.5) !default; + + +// ---------------------------------------------------------- +// :: 1.6. Collapsible sub menus +// ---------------------------------------------------------- + +// Menu box +$sm-clean__collapsible-sub-bg: rgba(darken($sm-clean__collapsible-bg, 30%), 0.1) !default; + +// Items text indentation for deeper levels +$sm-clean__collapsible-sub-item-indentation: 8px !default; + + +// ---------------------------------------------------------- +// :: 1.7. Desktop main menu +// ---------------------------------------------------------- + +// Menu box +$sm-clean__desktop-bg: $sm-clean__gray !default; +$sm-clean__desktop-border-radius: 100px !default; +$sm-clean__desktop-padding-horizontal: 10px !default; + +// Items +$sm-clean__desktop-item-color: $sm-clean__gray-darker !default; +$sm-clean__desktop-item-hover-color: $sm-clean__red !default; +$sm-clean__desktop-item-current-color: $sm-clean__red !default; +$sm-clean__desktop-item-disabled-color: darken($sm-clean__gray, 20%) !default; +$sm-clean__desktop-item-padding-vertical: 12px !default; +$sm-clean__desktop-item-padding-horizontal: 12px !default; + +// Sub menu indicators +$sm-clean__desktop-arrow-size: 4px !default; // border-width +$sm-clean__desktop-arrow-color: $sm-clean__gray-darker !default; +$sm-clean__desktop-arrow-spacing: 4px !default; + +// Vertical menu box +$sm-clean__desktop-vertical-border-radius: $sm-clean__border-radius !default; +$sm-clean__desktop-vertical-padding-vertical: 10px !default; + +// Vertical items +$sm-clean__desktop-vertical-item-hover-bg: $sm-clean__white !default; +$sm-clean__desktop-vertical-item-padding-vertical: 10px !default; +$sm-clean__desktop-vertical-item-padding-horizontal: 20px !default; + + +// ---------------------------------------------------------- +// :: 1.8. Desktop sub menus +// ---------------------------------------------------------- + +// Menu box +$sm-clean__desktop-sub-bg: $sm-clean__white !default; +$sm-clean__desktop-sub-border-color: $sm-clean__gray-dark !default; +$sm-clean__desktop-sub-border-radius: $sm-clean__border-radius !default; +$sm-clean__desktop-sub-box-shadow: 0 5px 9px $sm-clean__box-shadow !default; +$sm-clean__desktop-sub-padding-vertical: 5px !default; +$sm-clean__desktop-sub-padding-horizontal: 0 !default; + +// Items +$sm-clean__desktop-sub-item-color: $sm-clean__gray-darker !default; +$sm-clean__desktop-sub-item-hover-color: $sm-clean__red !default; +$sm-clean__desktop-sub-item-hover-bg: $sm-clean__gray !default; +$sm-clean__desktop-sub-item-current-color: $sm-clean__red !default; +$sm-clean__desktop-sub-item-disabled-color: darken($sm-clean__white, 20%) !default; +$sm-clean__desktop-sub-item-padding-vertical: 10px !default; +$sm-clean__desktop-sub-item-padding-horizontal: 20px !default; + +// Sub menu indicators +$sm-clean__desktop-sub-arrow-size: 5px !default; // border-width + +// Sub menu carets +$sm-clean__desktop-sub-caret-size: 8px !default; // border-width +$sm-clean__desktop-sub-caret-left: 30px !default; + + +// ----------------------------------------------------------------------------------------------------------------- +// 2. Theme CSS +// ----------------------------------------------------------------------------------------------------------------- + + +// ---------------------------------------------------------- +// :: 2.1. Collapsible mode (mobile first) +// ---------------------------------------------------------- + +// calc item height and sub menus toggle button size +$sm-clean__item-height: $sm-clean__line-height + $sm-clean__collapsible-item-padding-vertical * 2; +// set toggle button size to 80% of item height +$sm-clean__toggle-size: floor($sm-clean__item-height * 0.8); +$sm-clean__toggle-spacing: floor($sm-clean__item-height * 0.1); + +// Main menu box +.sm-clean { + background: $sm-clean__collapsible-bg; + border-radius: $sm-clean__collapsible-border-radius; + + // Main menu items + a { + &, + &:hover, + &:focus, + &:active { + padding: $sm-clean__collapsible-item-padding-vertical $sm-clean__collapsible-item-padding-horizontal; + /* make room for the toggle button (sub indicator) */ + padding-right: $sm-clean__collapsible-item-padding-horizontal + $sm-clean__toggle-size + $sm-clean__toggle-spacing; + color: $sm-clean__collapsible-item-color; + font-family: $sm-clean__font-family; + font-size: $sm-clean__font-size-base; + font-weight: normal; + line-height: $sm-clean__line-height; + text-decoration: none; + } + + &.current { + color: $sm-clean__collapsible-item-current-color; + } + + &.disabled { + color: $sm-clean__collapsible-item-disabled-color; + } + + // Toggle buttons (sub menu indicators) + .sub-arrow { + position: absolute; + top: 50%; + margin-top: -(ceil($sm-clean__toggle-size / 2)); + left: auto; + right: $sm-clean__toggle-spacing; + width: $sm-clean__toggle-size; + height: $sm-clean__toggle-size; + overflow: hidden; + font: bold #{$sm-clean__font-size-small}/#{$sm-clean__toggle-size} monospace !important; + text-align: center; + text-shadow: none; + background: $sm-clean__collapsible-toggle-bg; + border-radius: $sm-clean__border-radius; + } + .sub-arrow::before { + content: '+'; + } + &.highlighted .sub-arrow::before { + content: '-'; + } + } + + // round the corners of the first item + > li:first-child > a, > li:first-child > :not(ul) a { + border-radius: $sm-clean__collapsible-border-radius $sm-clean__collapsible-border-radius 0 0; + } + // round the corners of the last item + @include sm-clean__round-corners-last-item($sm-clean__collapsible-border-radius); + + // Main menu items separators + li { + border-top: 1px solid $sm-clean__collapsible-separators-color; + } + > li:first-child { + border-top: 0; + } + + // Sub menus box + ul { + background: $sm-clean__collapsible-sub-bg; + + // Sub menus items + a { + &, + &:hover, + &:focus, + &:active { + font-size: $sm-clean__font-size-small; + // add indentation for sub menus text + border-left: $sm-clean__collapsible-sub-item-indentation solid transparent; + } + } + + // Add indentation for sub menus text for deeper levels + @include sm-clean__sub-items-indentation($sm-clean__collapsible-sub-item-indentation); + } +} + + +// ---------------------------------------------------------- +// :: 2.2. Desktop mode +// ---------------------------------------------------------- + +@media (min-width: $sm-clean__desktop-vp) { + + /* Switch to desktop layout + ----------------------------------------------- + These transform the menu tree from + collapsible to desktop (navbar + dropdowns) + -----------------------------------------------*/ + /* start... (it's not recommended editing these rules) */ + .sm-clean ul{position:absolute;width:12em;} + .sm-clean li{float:left;} + .sm-clean.sm-rtl li{float:right;} + .sm-clean ul li,.sm-clean.sm-rtl ul li,.sm-clean.sm-vertical li{float:none;} + .sm-clean a{white-space:nowrap;} + .sm-clean ul a,.sm-clean.sm-vertical a{white-space:normal;} + .sm-clean .sm-nowrap > li > a,.sm-clean .sm-nowrap > li > :not(ul) a{white-space:nowrap;} + /* ...end */ + + // Main menu box + .sm-clean { + padding: 0 $sm-clean__desktop-padding-horizontal; + background: $sm-clean__desktop-bg; + border-radius: $sm-clean__desktop-border-radius; + + // Main menu items + a { + &, + &:hover, + &:focus, + &:active, + &.highlighted { + padding: $sm-clean__desktop-item-padding-vertical $sm-clean__desktop-item-padding-horizontal; + color: $sm-clean__desktop-item-color; + border-radius: 0 !important; + } + + &:hover, + &:focus, + &:active, + &.highlighted { + color: $sm-clean__desktop-item-hover-color; + } + + &.current { + color: $sm-clean__desktop-item-current-color; + } + + &.disabled { + color: $sm-clean__desktop-item-disabled-color; + } + + // Make room for the sub arrows + &.has-submenu { + padding-right: $sm-clean__desktop-item-padding-horizontal + $sm-clean__desktop-arrow-size * 2 + $sm-clean__desktop-arrow-spacing; + } + + // Sub menu indicators + .sub-arrow { + top: 50%; + margin-top: -(ceil($sm-clean__desktop-arrow-size / 2)); + right: $sm-clean__desktop-item-padding-horizontal; + width: 0; + height: 0; + border-width: $sm-clean__desktop-arrow-size; + border-style: solid dashed dashed dashed; + border-color: $sm-clean__desktop-arrow-color transparent transparent transparent; + background: transparent; + border-radius: 0; + } + // reset mobile first style + .sub-arrow::before { + display: none; + } + } + + // No main menu items separators + li { + border-top: 0; + } + + // First sub level carets + > li > ul::before, + > li > ul::after { + content: ''; + position: absolute; + top: -($sm-clean__desktop-sub-caret-size * 2 + $sm-clean__border-width * 2); + left: $sm-clean__desktop-sub-caret-left; + width: 0; + height: 0; + overflow: hidden; + border-width: ($sm-clean__desktop-sub-caret-size + $sm-clean__border-width); + border-style: dashed dashed solid dashed; + border-color: transparent transparent $sm-clean__desktop-sub-border-color transparent; + } + > li > ul::after { + top: -($sm-clean__desktop-sub-caret-size * 2); + left: ($sm-clean__desktop-sub-caret-left + $sm-clean__border-width); + border-width: $sm-clean__desktop-sub-caret-size; + border-color: transparent transparent $sm-clean__desktop-sub-bg transparent; + } + + // Sub menus box + ul { + border: $sm-clean__border-width solid $sm-clean__desktop-sub-border-color; + padding: $sm-clean__desktop-sub-padding-vertical $sm-clean__desktop-sub-padding-horizontal; + background: $sm-clean__desktop-sub-bg; + border-radius: $sm-clean__desktop-sub-border-radius !important; + box-shadow: $sm-clean__desktop-sub-box-shadow; + + // Sub menus items + a { + &, + &:hover, + &:focus, + &:active, + &.highlighted { + border: 0 !important; + padding: $sm-clean__desktop-sub-item-padding-vertical $sm-clean__desktop-sub-item-padding-horizontal; + color: $sm-clean__desktop-sub-item-color; + } + + &:hover, + &:focus, + &:active, + &.highlighted { + background: $sm-clean__desktop-sub-item-hover-bg; + color: $sm-clean__desktop-sub-item-hover-color; + } + + &.current { + color: $sm-clean__desktop-sub-item-current-color; + } + + &.disabled { + background: $sm-clean__desktop-sub-bg; + color: $sm-clean__desktop-sub-item-disabled-color; + } + + // No need for additional room for the sub arrows + &.has-submenu { + padding-right: $sm-clean__desktop-sub-item-padding-horizontal; + } + + // Sub menu indicators + .sub-arrow { + right: 8px; + top: 50%; + margin-top: -$sm-clean__desktop-sub-arrow-size; + border-width: $sm-clean__desktop-sub-arrow-size; + border-style: dashed dashed dashed solid; + border-color: transparent transparent transparent $sm-clean__desktop-arrow-color; + } + } + } + + // Scrolling arrows containers for tall sub menus - test sub menu: "Sub test" -> "more..." in the default download package + .scroll-up, + .scroll-down { + position: absolute; + display: none; + visibility: hidden; + overflow: hidden; + background: $sm-clean__desktop-sub-bg; + height: 20px; + // width and position will be set automatically by the script + + &:hover { + background: $sm-clean__desktop-sub-item-hover-bg; + } + } + .scroll-up:hover .scroll-up-arrow { + border-color: transparent transparent $sm-clean__desktop-sub-item-hover-color transparent; + } + .scroll-down:hover .scroll-down-arrow { + border-color: $sm-clean__desktop-sub-item-hover-color transparent transparent transparent; + } + .scroll-up-arrow, + .scroll-down-arrow { + position: absolute; + top: 0; + left: 50%; + margin-left: -6px; + // we will use one-side border to create a triangle so that we don't use a real background image, of course, you can use a real image if you like too + width: 0; + height: 0; + overflow: hidden; + border-width: 6px; // tweak size of the arrow + border-style: dashed dashed solid dashed; + border-color: transparent transparent $sm-clean__desktop-sub-item-color transparent; + } + .scroll-down-arrow { + top: 8px; + border-style: solid dashed dashed dashed; + border-color: $sm-clean__desktop-sub-item-color transparent transparent transparent; + } + + + // Rigth-to-left + + // Main menu box + &.sm-rtl { + + // Main menu items + a { + + // Make room for the sub arrows + &.has-submenu { + padding-right: $sm-clean__desktop-item-padding-horizontal; + padding-left: $sm-clean__desktop-item-padding-horizontal + $sm-clean__desktop-arrow-size * 2 + $sm-clean__desktop-arrow-spacing; + } + + // Sub menu indicators + .sub-arrow { + right: auto; + left: $sm-clean__desktop-item-padding-horizontal; + } + } + + // Vertical main menu items + &.sm-vertical { + a { + + // No need for additional room for the sub arrows + &.has-submenu { + padding: $sm-clean__desktop-vertical-item-padding-vertical $sm-clean__desktop-vertical-item-padding-horizontal; + } + + // Sub menu indicators + .sub-arrow { + right: auto; + left: 8px; + border-style: dashed solid dashed dashed; + border-color: transparent $sm-clean__desktop-arrow-color transparent transparent; + } + } + } + + // First sub level carets + > li > ul::before { + left: auto; + right: $sm-clean__desktop-sub-caret-left; + } + > li > ul::after { + left: auto; + right: ($sm-clean__desktop-sub-caret-left + $sm-clean__border-width); + } + + // Sub menus box + ul { + a { + + // No need for additional room for the sub arrows + &.has-submenu { + padding: $sm-clean__desktop-sub-item-padding-vertical $sm-clean__desktop-sub-item-padding-horizontal !important; + } + + // Sub menu indicators + .sub-arrow { + right: auto; + left: 8px; + border-style: dashed solid dashed dashed; + border-color: transparent $sm-clean__desktop-arrow-color transparent transparent; + } + } + } + } + + + // Vertical main menu + + // Main menu box + &.sm-vertical { + padding: $sm-clean__desktop-vertical-padding-vertical 0; + border-radius: $sm-clean__desktop-vertical-border-radius; + + // Main menu items + a { + padding: $sm-clean__desktop-vertical-item-padding-vertical $sm-clean__desktop-vertical-item-padding-horizontal; + + &:hover, + &:focus, + &:active, + &.highlighted { + background: $sm-clean__desktop-vertical-item-hover-bg; + } + + &.disabled { + background: $sm-clean__desktop-bg; + } + + // Sub menu indicators + .sub-arrow { + right: 8px; + top: 50%; + margin-top: -$sm-clean__desktop-sub-arrow-size; + border-width: $sm-clean__desktop-sub-arrow-size; + border-style: dashed dashed dashed solid; + border-color: transparent transparent transparent $sm-clean__desktop-arrow-color; + } + } + + // No sub level carets + > li > ul::before, + > li > ul::after { + display: none; + } + + // Sub menus box + ul { + + // Sub menus items + a { + padding: $sm-clean__desktop-sub-item-padding-vertical $sm-clean__desktop-sub-item-padding-horizontal; + + &:hover, + &:focus, + &:active, + &.highlighted { + background: $sm-clean__desktop-sub-item-hover-bg; + } + + &.disabled { + background: $sm-clean__desktop-sub-bg; + } + } + } + } + } +} \ No newline at end of file diff --git a/civicrm/bower_components/smartmenus/dist/css/sm-clean/mixins/_round-corners-last-item.scss b/civicrm/bower_components/smartmenus/dist/css/sm-clean/mixins/_round-corners-last-item.scss new file mode 100644 index 0000000000..3687ba4c97 --- /dev/null +++ b/civicrm/bower_components/smartmenus/dist/css/sm-clean/mixins/_round-corners-last-item.scss @@ -0,0 +1,25 @@ +// Generate rules to round the corners of the last collapsible item + +@mixin sm-clean__round-corners-last-item($amount, $chainable: 'ul > li:last-child > ', $level: 4, $chain_prefix: '> li:last-child > ', $chain: '', $selector: '') { + $chain: $chain_prefix; + $selector: $chain + 'a, ' + $chain + '*:not(ul) a, ' + $chain + 'ul'; + @for $i from 1 through $level { + $chain: $chain + $chainable; + $selector: $selector + ', +' + $chain + ' a, ' + $chain + '*:not(ul) a, ' + $chain + ' ul'; + } + #{$selector} { + border-radius: 0 0 $amount $amount; + } + // highlighted items, don't need rounding since their sub is open + $chain: $chain_prefix; + $selector: $chain + 'a.highlighted, ' + $chain + '*:not(ul) a.highlighted'; + @for $i from 1 through $level { + $chain: $chain + $chainable; + $selector: $selector + ', +' + $chain + ' a.highlighted, ' + $chain + '*:not(ul) a.highlighted'; + } + #{$selector} { + border-radius: 0; + } +} \ No newline at end of file diff --git a/civicrm/bower_components/smartmenus/dist/css/sm-clean/mixins/_sub-items-indentation.scss b/civicrm/bower_components/smartmenus/dist/css/sm-clean/mixins/_sub-items-indentation.scss new file mode 100644 index 0000000000..0225b65c23 --- /dev/null +++ b/civicrm/bower_components/smartmenus/dist/css/sm-clean/mixins/_sub-items-indentation.scss @@ -0,0 +1,15 @@ +// Generate rules to indent sub menus text +// +// We'll use left border to avoid messing with the padding. + +@mixin sm-clean__sub-items-indentation($amount, $chainable: 'ul ', $level: 4, $chain: '') { + @for $i from 1 through $level { + $chain: $chain + $chainable; + #{$chain} a, + #{$chain} a:hover, + #{$chain} a:focus, + #{$chain} a:active { + border-left: ($amount * ($i + 1)) solid transparent; + } + } +} \ No newline at end of file diff --git a/civicrm/bower_components/smartmenus/dist/css/sm-clean/sm-clean.css b/civicrm/bower_components/smartmenus/dist/css/sm-clean/sm-clean.css new file mode 100644 index 0000000000..4fb39b72f6 --- /dev/null +++ b/civicrm/bower_components/smartmenus/dist/css/sm-clean/sm-clean.css @@ -0,0 +1,327 @@ +.sm-clean { + background: #eeeeee; + border-radius: 5px; +} +.sm-clean a, .sm-clean a:hover, .sm-clean a:focus, .sm-clean a:active { + padding: 13px 20px; + /* make room for the toggle button (sub indicator) */ + padding-right: 58px; + color: #555555; + font-family: "Lucida Sans Unicode", "Lucida Sans", "Lucida Grande", Arial, sans-serif; + font-size: 18px; + font-weight: normal; + line-height: 17px; + text-decoration: none; +} +.sm-clean a.current { + color: #D23600; +} +.sm-clean a.disabled { + color: #bbbbbb; +} +.sm-clean a .sub-arrow { + position: absolute; + top: 50%; + margin-top: -17px; + left: auto; + right: 4px; + width: 34px; + height: 34px; + overflow: hidden; + font: bold 16px/34px monospace !important; + text-align: center; + text-shadow: none; + background: rgba(255, 255, 255, 0.5); + border-radius: 5px; +} +.sm-clean a .sub-arrow::before { + content: '+'; +} +.sm-clean a.highlighted .sub-arrow::before { + content: '-'; +} +.sm-clean > li:first-child > a, .sm-clean > li:first-child > :not(ul) a { + border-radius: 5px 5px 0 0; +} +.sm-clean > li:last-child > a, .sm-clean > li:last-child > *:not(ul) a, .sm-clean > li:last-child > ul, .sm-clean > li:last-child > ul > li:last-child > a, .sm-clean > li:last-child > ul > li:last-child > *:not(ul) a, .sm-clean > li:last-child > ul > li:last-child > ul, .sm-clean > li:last-child > ul > li:last-child > ul > li:last-child > a, .sm-clean > li:last-child > ul > li:last-child > ul > li:last-child > *:not(ul) a, .sm-clean > li:last-child > ul > li:last-child > ul > li:last-child > ul, .sm-clean > li:last-child > ul > li:last-child > ul > li:last-child > ul > li:last-child > a, .sm-clean > li:last-child > ul > li:last-child > ul > li:last-child > ul > li:last-child > *:not(ul) a, .sm-clean > li:last-child > ul > li:last-child > ul > li:last-child > ul > li:last-child > ul, .sm-clean > li:last-child > ul > li:last-child > ul > li:last-child > ul > li:last-child > ul > li:last-child > a, .sm-clean > li:last-child > ul > li:last-child > ul > li:last-child > ul > li:last-child > ul > li:last-child > *:not(ul) a, .sm-clean > li:last-child > ul > li:last-child > ul > li:last-child > ul > li:last-child > ul > li:last-child > ul { + border-radius: 0 0 5px 5px; +} +.sm-clean > li:last-child > a.highlighted, .sm-clean > li:last-child > *:not(ul) a.highlighted, .sm-clean > li:last-child > ul > li:last-child > a.highlighted, .sm-clean > li:last-child > ul > li:last-child > *:not(ul) a.highlighted, .sm-clean > li:last-child > ul > li:last-child > ul > li:last-child > a.highlighted, .sm-clean > li:last-child > ul > li:last-child > ul > li:last-child > *:not(ul) a.highlighted, .sm-clean > li:last-child > ul > li:last-child > ul > li:last-child > ul > li:last-child > a.highlighted, .sm-clean > li:last-child > ul > li:last-child > ul > li:last-child > ul > li:last-child > *:not(ul) a.highlighted, .sm-clean > li:last-child > ul > li:last-child > ul > li:last-child > ul > li:last-child > ul > li:last-child > a.highlighted, .sm-clean > li:last-child > ul > li:last-child > ul > li:last-child > ul > li:last-child > ul > li:last-child > *:not(ul) a.highlighted { + border-radius: 0; +} +.sm-clean li { + border-top: 1px solid rgba(0, 0, 0, 0.05); +} +.sm-clean > li:first-child { + border-top: 0; +} +.sm-clean ul { + background: rgba(162, 162, 162, 0.1); +} +.sm-clean ul a, .sm-clean ul a:hover, .sm-clean ul a:focus, .sm-clean ul a:active { + font-size: 16px; + border-left: 8px solid transparent; +} +.sm-clean ul ul a, +.sm-clean ul ul a:hover, +.sm-clean ul ul a:focus, +.sm-clean ul ul a:active { + border-left: 16px solid transparent; +} +.sm-clean ul ul ul a, +.sm-clean ul ul ul a:hover, +.sm-clean ul ul ul a:focus, +.sm-clean ul ul ul a:active { + border-left: 24px solid transparent; +} +.sm-clean ul ul ul ul a, +.sm-clean ul ul ul ul a:hover, +.sm-clean ul ul ul ul a:focus, +.sm-clean ul ul ul ul a:active { + border-left: 32px solid transparent; +} +.sm-clean ul ul ul ul ul a, +.sm-clean ul ul ul ul ul a:hover, +.sm-clean ul ul ul ul ul a:focus, +.sm-clean ul ul ul ul ul a:active { + border-left: 40px solid transparent; +} + +@media (min-width: 768px) { + /* Switch to desktop layout + ----------------------------------------------- + These transform the menu tree from + collapsible to desktop (navbar + dropdowns) + -----------------------------------------------*/ + /* start... (it's not recommended editing these rules) */ + .sm-clean ul { + position: absolute; + width: 12em; + } + + .sm-clean li { + float: left; + } + + .sm-clean.sm-rtl li { + float: right; + } + + .sm-clean ul li, .sm-clean.sm-rtl ul li, .sm-clean.sm-vertical li { + float: none; + } + + .sm-clean a { + white-space: nowrap; + } + + .sm-clean ul a, .sm-clean.sm-vertical a { + white-space: normal; + } + + .sm-clean .sm-nowrap > li > a, .sm-clean .sm-nowrap > li > :not(ul) a { + white-space: nowrap; + } + + /* ...end */ + .sm-clean { + padding: 0 10px; + background: #eeeeee; + border-radius: 100px; + } + .sm-clean a, .sm-clean a:hover, .sm-clean a:focus, .sm-clean a:active, .sm-clean a.highlighted { + padding: 12px 12px; + color: #555555; + border-radius: 0 !important; + } + .sm-clean a:hover, .sm-clean a:focus, .sm-clean a:active, .sm-clean a.highlighted { + color: #D23600; + } + .sm-clean a.current { + color: #D23600; + } + .sm-clean a.disabled { + color: #bbbbbb; + } + .sm-clean a.has-submenu { + padding-right: 24px; + } + .sm-clean a .sub-arrow { + top: 50%; + margin-top: -2px; + right: 12px; + width: 0; + height: 0; + border-width: 4px; + border-style: solid dashed dashed dashed; + border-color: #555555 transparent transparent transparent; + background: transparent; + border-radius: 0; + } + .sm-clean a .sub-arrow::before { + display: none; + } + .sm-clean li { + border-top: 0; + } + .sm-clean > li > ul::before, + .sm-clean > li > ul::after { + content: ''; + position: absolute; + top: -18px; + left: 30px; + width: 0; + height: 0; + overflow: hidden; + border-width: 9px; + border-style: dashed dashed solid dashed; + border-color: transparent transparent #bbbbbb transparent; + } + .sm-clean > li > ul::after { + top: -16px; + left: 31px; + border-width: 8px; + border-color: transparent transparent #fff transparent; + } + .sm-clean ul { + border: 1px solid #bbbbbb; + padding: 5px 0; + background: #fff; + border-radius: 5px !important; + box-shadow: 0 5px 9px rgba(0, 0, 0, 0.2); + } + .sm-clean ul a, .sm-clean ul a:hover, .sm-clean ul a:focus, .sm-clean ul a:active, .sm-clean ul a.highlighted { + border: 0 !important; + padding: 10px 20px; + color: #555555; + } + .sm-clean ul a:hover, .sm-clean ul a:focus, .sm-clean ul a:active, .sm-clean ul a.highlighted { + background: #eeeeee; + color: #D23600; + } + .sm-clean ul a.current { + color: #D23600; + } + .sm-clean ul a.disabled { + background: #fff; + color: #cccccc; + } + .sm-clean ul a.has-submenu { + padding-right: 20px; + } + .sm-clean ul a .sub-arrow { + right: 8px; + top: 50%; + margin-top: -5px; + border-width: 5px; + border-style: dashed dashed dashed solid; + border-color: transparent transparent transparent #555555; + } + .sm-clean .scroll-up, + .sm-clean .scroll-down { + position: absolute; + display: none; + visibility: hidden; + overflow: hidden; + background: #fff; + height: 20px; + } + .sm-clean .scroll-up:hover, + .sm-clean .scroll-down:hover { + background: #eeeeee; + } + .sm-clean .scroll-up:hover .scroll-up-arrow { + border-color: transparent transparent #D23600 transparent; + } + .sm-clean .scroll-down:hover .scroll-down-arrow { + border-color: #D23600 transparent transparent transparent; + } + .sm-clean .scroll-up-arrow, + .sm-clean .scroll-down-arrow { + position: absolute; + top: 0; + left: 50%; + margin-left: -6px; + width: 0; + height: 0; + overflow: hidden; + border-width: 6px; + border-style: dashed dashed solid dashed; + border-color: transparent transparent #555555 transparent; + } + .sm-clean .scroll-down-arrow { + top: 8px; + border-style: solid dashed dashed dashed; + border-color: #555555 transparent transparent transparent; + } + .sm-clean.sm-rtl a.has-submenu { + padding-right: 12px; + padding-left: 24px; + } + .sm-clean.sm-rtl a .sub-arrow { + right: auto; + left: 12px; + } + .sm-clean.sm-rtl.sm-vertical a.has-submenu { + padding: 10px 20px; + } + .sm-clean.sm-rtl.sm-vertical a .sub-arrow { + right: auto; + left: 8px; + border-style: dashed solid dashed dashed; + border-color: transparent #555555 transparent transparent; + } + .sm-clean.sm-rtl > li > ul::before { + left: auto; + right: 30px; + } + .sm-clean.sm-rtl > li > ul::after { + left: auto; + right: 31px; + } + .sm-clean.sm-rtl ul a.has-submenu { + padding: 10px 20px !important; + } + .sm-clean.sm-rtl ul a .sub-arrow { + right: auto; + left: 8px; + border-style: dashed solid dashed dashed; + border-color: transparent #555555 transparent transparent; + } + .sm-clean.sm-vertical { + padding: 10px 0; + border-radius: 5px; + } + .sm-clean.sm-vertical a { + padding: 10px 20px; + } + .sm-clean.sm-vertical a:hover, .sm-clean.sm-vertical a:focus, .sm-clean.sm-vertical a:active, .sm-clean.sm-vertical a.highlighted { + background: #fff; + } + .sm-clean.sm-vertical a.disabled { + background: #eeeeee; + } + .sm-clean.sm-vertical a .sub-arrow { + right: 8px; + top: 50%; + margin-top: -5px; + border-width: 5px; + border-style: dashed dashed dashed solid; + border-color: transparent transparent transparent #555555; + } + .sm-clean.sm-vertical > li > ul::before, + .sm-clean.sm-vertical > li > ul::after { + display: none; + } + .sm-clean.sm-vertical ul a { + padding: 10px 20px; + } + .sm-clean.sm-vertical ul a:hover, .sm-clean.sm-vertical ul a:focus, .sm-clean.sm-vertical ul a:active, .sm-clean.sm-vertical ul a.highlighted { + background: #eeeeee; + } + .sm-clean.sm-vertical ul a.disabled { + background: #fff; + } +} + +/*# sourceMappingURL=sm-clean.css.map */ diff --git a/civicrm/bower_components/smartmenus/dist/css/sm-clean/sm-clean.css.map b/civicrm/bower_components/smartmenus/dist/css/sm-clean/sm-clean.css.map new file mode 100644 index 0000000000..552d708b90 --- /dev/null +++ b/civicrm/bower_components/smartmenus/dist/css/sm-clean/sm-clean.css.map @@ -0,0 +1,7 @@ +{ +"version": 3, +"mappings": "AA6JA,SAAU;EACT,UAAU,EA/B+B,OAAe;EAgCxD,aAAa,EA1G4B,GAAwB;;AA8GhE,qEAGS;EACR,OAAO,EAAE,SAA2F;EACpG,qDAAqD;EACrD,aAAa,EAAE,IAAmG;EAClH,KAAK,EA7CgC,OAAsB;EA8C3D,WAAW,EA1IkB,wEAAwE;EA2IrG,SAAS,EA1IsB,IAAI;EA2InC,WAAW,EAAE,MAAM;EACnB,WAAW,EA1IkB,IAAI;EA2IjC,eAAe,EAAE,IAAI;;AAGtB,mBAAU;EACT,KAAK,EAnDsC,OAAc;;AAsD1D,oBAAW;EACV,KAAK,EA7HuC,OAA4B;;AAiIzE,sBAAW;EACV,QAAQ,EAAE,QAAQ;EAClB,GAAG,EAAE,GAAG;EACR,UAAU,EAAE,KAAmC;EAC/C,IAAI,EAAE,IAAI;EACV,KAAK,EAtCmB,GAAmC;EAuC3D,KAAK,EAxCgB,IAAmC;EAyCxD,MAAM,EAzCe,IAAmC;EA0CxD,QAAQ,EAAE,MAAM;EAChB,IAAI,EAAE,mCAAiF;EACvF,UAAU,EAAE,MAAM;EAClB,WAAW,EAAE,IAAI;EACjB,UAAU,EArI0B,wBAAwB;EAsI5D,aAAa,EA5JiB,GAAG;;AA8JlC,8BAAmB;EAClB,OAAO,EAAE,GAAG;;AAEb,0CAAiC;EAChC,OAAO,EAAE,GAAG;;AAKd,uEAAoD;EACnD,aAAa,EAAE,WAA6E;;AC1M7F,4nCAAa;EACZ,aAAa,EAAE,WAAmB;;AAUnC,k4BAAa;EACZ,aAAa,EAAE,CAAC;;ADoMjB,YAAG;EACF,UAAU,EAAE,6BAAiD;;AAE9D,0BAAiB;EAChB,UAAU,EAAE,CAAC;;AAId,YAAG;EACF,UAAU,EAzJyB,wBAAiD;;AA6JnF,iFAGS;EACR,SAAS,EAxMsB,IAAI;EA0MnC,WAAW,EAAE,qBAA6D;;AEtO5E;;;wBAGmB;EAClB,WAAW,EAAE,sBAAsC;;AAJpD;;;2BAGmB;EAClB,WAAW,EAAE,sBAAsC;;AAJpD;;;8BAGmB;EAClB,WAAW,EAAE,sBAAsC;;AAJpD;;;iCAGmB;EAClB,WAAW,EAAE,sBAAsC;;;AFgPtD,yBAA0C;EAEzC;;;;mDAIiD;EACjD,yDAAyD;EACzD,YAAY;IAAC,QAAQ,EAAC,QAAQ;IAAC,KAAK,EAAC,IAAI;;;EACzC,YAAY;IAAC,KAAK,EAAC,IAAI;;;EACvB,mBAAmB;IAAC,KAAK,EAAC,KAAK;;;EAC/B,iEAA+D;IAAC,KAAK,EAAC,IAAI;;;EAC1E,WAAW;IAAC,WAAW,EAAC,MAAM;;;EAC9B,uCAAsC;IAAC,WAAW,EAAC,MAAM;;;EACzD,qEAAoE;IAAC,WAAW,EAAC,MAAM;;;EACvF,YAAY;EAGZ,SAAU;IACT,OAAO,EAAE,MAAuC;IAChD,UAAU,EAhJ8B,OAAe;IAiJvD,aAAa,EA1LwB,KAAK;;EA8LzC,8FAIc;IACb,OAAO,EAAE,SAAmF;IAC5F,KAAK,EA7J+B,OAAsB;IA8J1D,aAAa,EAAE,YAAY;;EAG5B,iFAGc;IACb,KAAK,EAlKqC,OAAc;;EAqKzD,mBAAU;IACT,KAAK,EAtKqC,OAAc;;EAyKzD,oBAAW;IACV,KAAK,EA7MmC,OAA4B;;EAiNrE,uBAAc;IACb,aAAa,EAAE,IAAiH;;EAIjI,sBAAW;IACV,GAAG,EAAE,GAAG;IACR,UAAU,EAAE,IAA0C;IACtD,KAAK,EAvNsC,IAAI;IAwN/C,KAAK,EAAE,CAAC;IACR,MAAM,EAAE,CAAC;IACT,YAAY,EAvNqB,GAAG;IAwNpC,YAAY,EAAE,0BAA0B;IACxC,YAAY,EAAE,2CAAkE;IAChF,UAAU,EAAE,WAAW;IACvB,aAAa,EAAE,CAAC;;EAGjB,8BAAmB;IAClB,OAAO,EAAE,IAAI;;EAKf,YAAG;IACF,UAAU,EAAE,CAAC;;EAId;4BACkB;IACjB,OAAO,EAAE,EAAE;IACX,QAAQ,EAAE,QAAQ;IAClB,GAAG,EAAE,KAAsE;IAC3E,IAAI,EAtMiC,IAAI;IAuMzC,KAAK,EAAE,CAAC;IACR,MAAM,EAAE,CAAC;IACT,QAAQ,EAAE,MAAM;IAChB,YAAY,EAAE,GAA6D;IAC3E,YAAY,EAAE,0BAA0B;IACxC,YAAY,EAAE,2CAAuE;;EAEtF,0BAAiB;IAChB,GAAG,EAAE,KAAwC;IAC7C,IAAI,EAAE,IAA6D;IACnE,YAAY,EAlNyB,GAAG;IAmNxC,YAAY,EAAE,wCAA6D;;EAI5E,YAAG;IACF,MAAM,EAAE,iBAAiE;IACzE,OAAO,EAAE,KAAiF;IAC1F,UAAU,EA9OqB,IAAgB;IA+O/C,aAAa,EAAE,cAA+C;IAC9D,UAAU,EA7O2B,4BAAgC;;EAiPpE,6GAIc;IACb,MAAM,EAAE,YAAY;IACpB,OAAO,EAAE,SAA2F;IACpG,KAAK,EAnP8B,OAAsB;;EAsP1D,6FAGc;IACb,UAAU,EAxP2B,OAAe;IAyPpD,KAAK,EAxPoC,OAAc;;EA2PxD,sBAAU;IACT,KAAK,EA5PoC,OAAc;;EA+PxD,uBAAW;IACV,UAAU,EA3QmB,IAAgB;IA4Q7C,KAAK,EAhQqC,OAA6B;;EAoQxE,0BAAc;IACb,aAAa,EAnQgC,IAAI;;EAuQlD,yBAAW;IACV,KAAK,EAAE,GAAG;IACV,GAAG,EAAE,GAAG;IACR,UAAU,EAAE,IAAkC;IAC9C,YAAY,EAxQuB,GAAG;IAyQtC,YAAY,EAAE,0BAA0B;IACxC,YAAY,EAAE,2CAAkE;;EAMnF;wBACc;IACb,QAAQ,EAAE,QAAQ;IAClB,OAAO,EAAE,IAAI;IACb,UAAU,EAAE,MAAM;IAClB,QAAQ,EAAE,MAAM;IAChB,UAAU,EAvSqB,IAAgB;IAwS/C,MAAM,EAAE,IAAI;;EAGZ;8BAAQ;IACP,UAAU,EAlS4B,OAAe;;EAqSvD,2CAAkC;IACjC,YAAY,EAAE,2CAA2E;;EAE1F,+CAAsC;IACrC,YAAY,EAAE,2CAA2E;;EAE1F;8BACmB;IAClB,QAAQ,EAAE,QAAQ;IAClB,GAAG,EAAE,CAAC;IACN,IAAI,EAAE,GAAG;IACT,WAAW,EAAE,IAAI;IAEjB,KAAK,EAAE,CAAC;IACR,MAAM,EAAE,CAAC;IACT,QAAQ,EAAE,MAAM;IAChB,YAAY,EAAE,GAAG;IACjB,YAAY,EAAE,0BAA0B;IACxC,YAAY,EAAE,2CAAqE;;EAEpF,4BAAmB;IAClB,GAAG,EAAE,GAAG;IACR,YAAY,EAAE,0BAA0B;IACxC,YAAY,EAAE,2CAAqE;;EAalF,8BAAc;IACb,aAAa,EA1W6B,IAAI;IA2W9C,YAAY,EAAE,IAAiH;;EAIhI,6BAAW;IACV,KAAK,EAAE,IAAI;IACX,IAAI,EAjXsC,IAAI;;EA0X9C,0CAAc;IACb,OAAO,EAAE,SAAqG;;EAI/G,yCAAW;IACV,KAAK,EAAE,IAAI;IACX,IAAI,EAAE,GAAG;IACT,YAAY,EAAE,0BAA0B;IACxC,YAAY,EAAE,2CAAkE;;EAMnF,kCAAkB;IACjB,IAAI,EAAE,IAAI;IACV,KAAK,EAhW+B,IAAI;;EAkWzC,iCAAiB;IAChB,IAAI,EAAE,IAAI;IACV,KAAK,EAAE,IAA6D;;EAQnE,iCAAc;IACb,OAAO,EAAE,oBAAsG;;EAIhH,gCAAW;IACV,KAAK,EAAE,IAAI;IACX,IAAI,EAAE,GAAG;IACT,YAAY,EAAE,0BAA0B;IACxC,YAAY,EAAE,2CAAkE;;EAUpF,qBAAc;IACb,OAAO,EAAE,MAA8C;IACvD,aAAa,EApa8B,GAAwB;;EAuanE,uBAAE;IACD,OAAO,EAAE,SAAqG;;EAE9G,iIAGc;IACb,UAAU,EAhamB,IAAgB;;EAma9C,gCAAW;IACV,UAAU,EA1Z2B,OAAe;;EA8ZrD,kCAAW;IACV,KAAK,EAAE,GAAG;IACV,GAAG,EAAE,GAAG;IACR,UAAU,EAAE,IAAkC;IAC9C,YAAY,EA3ZuB,GAAG;IA4ZtC,YAAY,EAAE,0BAA0B;IACxC,YAAY,EAAE,2CAAkE;;EAKlF;wCACkB;IACjB,OAAO,EAAE,IAAI;;EAOb,0BAAE;IACD,OAAO,EAAE,SAA2F;;EAEpG,6IAGc;IACb,UAAU,EAzb0B,OAAe;;EA4bpD,mCAAW;IACV,UAAU,EAvckB,IAAgB", +"sources": ["_sm-clean-theme.scss","mixins/_round-corners-last-item.scss","mixins/_sub-items-indentation.scss"], +"names": [], +"file": "sm-clean.css" +} diff --git a/civicrm/bower_components/smartmenus/dist/css/sm-clean/sm-clean.scss b/civicrm/bower_components/smartmenus/dist/css/sm-clean/sm-clean.scss new file mode 100644 index 0000000000..109712cda0 --- /dev/null +++ b/civicrm/bower_components/smartmenus/dist/css/sm-clean/sm-clean.scss @@ -0,0 +1,4 @@ +@import '_mixins.scss'; + +// the variables + the CSS +@import '_sm-clean-theme.scss'; \ No newline at end of file diff --git a/civicrm/bower_components/smartmenus/dist/css/sm-core-css.css b/civicrm/bower_components/smartmenus/dist/css/sm-core-css.css new file mode 100644 index 0000000000..6130ae29f1 --- /dev/null +++ b/civicrm/bower_components/smartmenus/dist/css/sm-core-css.css @@ -0,0 +1,14 @@ +/* Mobile first layout SmartMenus Core CSS (it's not recommended editing these rules) + You need this once per page no matter how many menu trees or different themes you use. +-------------------------------------------------------------------------------------------*/ + +.sm{box-sizing:border-box;position:relative;z-index:9999;-webkit-tap-highlight-color:rgba(0,0,0,0);} +.sm,.sm ul,.sm li{display:block;list-style:none;margin:0;padding:0;line-height:normal;direction:ltr;text-align:left;} +.sm-rtl,.sm-rtl ul,.sm-rtl li{direction:rtl;text-align:right;} +.sm>li>h1,.sm>li>h2,.sm>li>h3,.sm>li>h4,.sm>li>h5,.sm>li>h6{margin:0;padding:0;} +.sm ul{display:none;} +.sm li,.sm a{position:relative;} +.sm a{display:block;} +.sm a.disabled{cursor:default;} +.sm::after{content:"";display:block;height:0;font:0px/0 serif;clear:both;overflow:hidden;} +.sm *,.sm *::before,.sm *::after{box-sizing:inherit;} \ No newline at end of file diff --git a/civicrm/bower_components/smartmenus/dist/css/sm-mint/_mixins.scss b/civicrm/bower_components/smartmenus/dist/css/sm-mint/_mixins.scss new file mode 100644 index 0000000000..dd6ff7cabb --- /dev/null +++ b/civicrm/bower_components/smartmenus/dist/css/sm-mint/_mixins.scss @@ -0,0 +1 @@ +@import 'mixins/_sub-items-indentation.scss'; \ No newline at end of file diff --git a/civicrm/bower_components/smartmenus/dist/css/sm-mint/_sm-mint-theme.scss b/civicrm/bower_components/smartmenus/dist/css/sm-mint/_sm-mint-theme.scss new file mode 100644 index 0000000000..ab8b12078f --- /dev/null +++ b/civicrm/bower_components/smartmenus/dist/css/sm-mint/_sm-mint-theme.scss @@ -0,0 +1,569 @@ +// This file is best viewed with Tab size 4 code indentation + + +// ----------------------------------------------------------------------------------------------------------------- +// 1. Theme Quick Settings (Variables) +// (for further control, you will need to dig into the actual CSS in 2.) +// ----------------------------------------------------------------------------------------------------------------- + + +// ---------------------------------------------------------- +// :: 1.1. Colors +// ---------------------------------------------------------- + +$sm-mint__white: #fff !default; +$sm-mint__black: #333 !default; +$sm-mint__green: #F6FFED !default; +$sm-mint__green-dark: #8db863 !default; + +$sm-mint__box-shadow: rgba(0, 0, 0, 0.25) !default; + + +// ---------------------------------------------------------- +// :: 1.2. Breakpoints +// ---------------------------------------------------------- + +$sm-mint__desktop-vp: 768px !default; // switch from collapsible to desktop + + +// ---------------------------------------------------------- +// :: 1.3. Typography +// ---------------------------------------------------------- + +$sm-mint__font-family: Arial, sans-serif !default; +$sm-mint__font-size-base: 16px !default; +$sm-mint__font-size-small: 14px !default; +$sm-mint__line-height: 17px !default; + + +// ---------------------------------------------------------- +// :: 1.4. Borders +// ---------------------------------------------------------- + +$sm-mint__border-width: 2px !default; +$sm-mint__border-radius-base: 4px !default; + + +// ---------------------------------------------------------- +// :: 1.5. Collapsible main menu +// ---------------------------------------------------------- + +// Menu box +$sm-mint__collapsible-bg: $sm-mint__white !default; +$sm-mint__collapsible-border-color: $sm-mint__green-dark !default; + +// Items +$sm-mint__collapsible-item-color: $sm-mint__black !default; +$sm-mint__collapsible-item-disabled-color: darken($sm-mint__white, 20%) !default; +$sm-mint__collapsible-item-padding-vertical: 13px !default; +$sm-mint__collapsible-item-padding-horizontal: 20px !default; + +// Items separators +$sm-mint__collapsible-separators-color: rgba($sm-mint__green-dark, 0.2) !default; + +// Toggle button (sub menu indicators) +$sm-mint__collapsible-toggle-bg: rgba($sm-mint__green-dark, 0.2) !default; + + +// ---------------------------------------------------------- +// :: 1.6. Collapsible sub menus +// ---------------------------------------------------------- + +// Menu box +$sm-mint__collapsible-sub-bg: rgba($sm-mint__green-dark, 0.2) !default; + +// Items text indentation for deeper levels +$sm-mint__collapsible-sub-item-indentation: 8px !default; + + +// ---------------------------------------------------------- +// :: 1.7. Desktop main menu +// ---------------------------------------------------------- + +// Menu box +$sm-mint__desktop-bg: transparent !default; + +// Items +$sm-mint__desktop-item-color: $sm-mint__black !default; +$sm-mint__desktop-item-hover-color: $sm-mint__white !default; +$sm-mint__desktop-item-hover-bg: $sm-mint__green-dark !default; +$sm-mint__desktop-item-highlighted-color: $sm-mint__black !default; +$sm-mint__desktop-item-highlighted-bg: $sm-mint__green !default; +$sm-mint__desktop-item-highlighted-box-shadow: 0 4px 3px $sm-mint__box-shadow !default; +$sm-mint__desktop-item-disabled-color: darken($sm-mint__white, 20%) !default; +$sm-mint__desktop-item-padding-vertical: 11px !default; +$sm-mint__desktop-item-padding-horizontal: 20px !default; + +// Sub menu indicators +$sm-mint__desktop-arrow-size: 6px !default; // border-width +$sm-mint__desktop-arrow-color: $sm-mint__green-dark !default; +$sm-mint__desktop-arrow-hover-color: $sm-mint__white !default; +$sm-mint__desktop-arrow-highlighted-color: $sm-mint__green-dark !default; +$sm-mint__desktop-arrow-spacing: 6px !default; + +// Vertical items +$sm-mint__desktop-vertical-item-highlighted-color: $sm-mint__desktop-item-hover-color !default; +$sm-mint__desktop-vertical-item-highlighted-bg: $sm-mint__desktop-item-hover-bg !default; +$sm-mint__desktop-vertical-item-padding-vertical: 10px !default; +$sm-mint__desktop-vertical-item-padding-horizontal: 20px !default; + + +// ---------------------------------------------------------- +// :: 1.8. Desktop sub menus +// ---------------------------------------------------------- + +// Menu box +$sm-mint__desktop-sub-bg: $sm-mint__green !default; +$sm-mint__desktop-sub-box-shadow: 0 4px 3px $sm-mint__box-shadow !default; +$sm-mint__desktop-sub-padding-vertical: 8px !default; +$sm-mint__desktop-sub-padding-horizontal: 0 !default; + +// Items +$sm-mint__desktop-sub-item-color: $sm-mint__black !default; +$sm-mint__desktop-sub-item-hover-color: $sm-mint__white !default; +$sm-mint__desktop-sub-item-hover-bg: $sm-mint__green-dark !default; +$sm-mint__desktop-sub-item-disabled-color: lighten($sm-mint__black, 50%) !default; +$sm-mint__desktop-sub-item-padding-vertical: 10px !default; +$sm-mint__desktop-sub-item-padding-horizontal: 20px !default; + + +// ----------------------------------------------------------------------------------------------------------------- +// 2. Theme CSS +// ----------------------------------------------------------------------------------------------------------------- + + +// ---------------------------------------------------------- +// :: 2.1. Collapsible mode (mobile first) +// ---------------------------------------------------------- + +// calc item height and sub menus toggle button size +$sm-mint__item-height: $sm-mint__line-height + $sm-mint__collapsible-item-padding-vertical * 2; +// set toggle button size to 80% of item height +$sm-mint__toggle-size: floor($sm-mint__item-height * 0.8); +$sm-mint__toggle-spacing: floor($sm-mint__item-height * 0.1); + +// Main menu box +.sm-mint { + border-top: $sm-mint__border-width solid $sm-mint__collapsible-border-color; + border-bottom: $sm-mint__border-width solid $sm-mint__collapsible-border-color; + background: $sm-mint__collapsible-bg; + + // Main menu items + a { + &, + &:hover, + &:focus, + &:active { + padding: $sm-mint__collapsible-item-padding-vertical $sm-mint__collapsible-item-padding-horizontal; + /* make room for the toggle button (sub indicator) */ + padding-right: $sm-mint__collapsible-item-padding-horizontal + $sm-mint__toggle-size + $sm-mint__toggle-spacing; + color: $sm-mint__collapsible-item-color; + font-family: $sm-mint__font-family; + font-size: $sm-mint__font-size-base; + font-weight: normal; + line-height: $sm-mint__line-height; + text-decoration: none; + } + + &.current { + font-weight: bold; + } + + &.disabled { + color: $sm-mint__collapsible-item-disabled-color; + } + + // Toggle buttons (sub menu indicators) + .sub-arrow { + position: absolute; + top: 50%; + margin-top: -(ceil($sm-mint__toggle-size / 2)); + left: auto; + right: $sm-mint__toggle-spacing; + width: $sm-mint__toggle-size; + height: $sm-mint__toggle-size; + overflow: hidden; + font: bold #{$sm-mint__font-size-small}/#{$sm-mint__toggle-size} monospace !important; + text-align: center; + text-shadow: none; + background: $sm-mint__collapsible-toggle-bg; + border-radius: $sm-mint__border-radius-base; + } + .sub-arrow::before { + content: '+'; + } + &.highlighted .sub-arrow::before { + content: '-'; + } + } + + // Main menu items separators + li { + border-top: 1px solid $sm-mint__collapsible-separators-color; + } + > li:first-child { + border-top: 0; + } + + // Sub menus box + ul { + background: $sm-mint__collapsible-sub-bg; + + // Sub menus items + a { + &, + &:hover, + &:focus, + &:active { + font-size: $sm-mint__font-size-small; + // add indentation for sub menus text + border-left: $sm-mint__collapsible-sub-item-indentation solid transparent; + } + } + + // Add indentation for sub menus text for deeper levels + @include sm-mint__sub-items-indentation($sm-mint__collapsible-sub-item-indentation); + } +} + + +// ---------------------------------------------------------- +// :: 2.2. Desktop mode +// ---------------------------------------------------------- + +@media (min-width: $sm-mint__desktop-vp) { + + /* Switch to desktop layout + ----------------------------------------------- + These transform the menu tree from + collapsible to desktop (navbar + dropdowns) + -----------------------------------------------*/ + /* start... (it's not recommended editing these rules) */ + .sm-mint ul{position:absolute;width:12em;} + .sm-mint li{float:left;} + .sm-mint.sm-rtl li{float:right;} + .sm-mint ul li,.sm-mint.sm-rtl ul li,.sm-mint.sm-vertical li{float:none;} + .sm-mint a{white-space:nowrap;} + .sm-mint ul a,.sm-mint.sm-vertical a{white-space:normal;} + .sm-mint .sm-nowrap > li > a,.sm-mint .sm-nowrap > li > :not(ul) a{white-space:nowrap;} + /* ...end */ + + // Main menu box + .sm-mint { + border-top: 0; + background: $sm-mint__desktop-bg; + + // Main menu items + a { + &, + &:hover, + &:focus, + &:active, + &.highlighted { + padding: $sm-mint__desktop-item-padding-vertical $sm-mint__desktop-item-padding-horizontal; + color: $sm-mint__desktop-item-color; + border-radius: $sm-mint__border-radius-base $sm-mint__border-radius-base 0 0; + } + + &:hover, + &:focus, + &:active { + background: $sm-mint__desktop-item-hover-bg; + color: $sm-mint__desktop-item-hover-color; + } + + &.highlighted { + background: $sm-mint__desktop-item-highlighted-bg; + color: $sm-mint__desktop-item-highlighted-color; + box-shadow: $sm-mint__desktop-item-highlighted-box-shadow; + } + + &.disabled { + background: transparent; + color: $sm-mint__desktop-item-disabled-color; + box-shadow: none; + } + + // Make room for the sub arrows + &.has-submenu { + padding-right: $sm-mint__desktop-item-padding-horizontal + 8px + $sm-mint__desktop-arrow-spacing; + } + + // Sub menu indicators + .sub-arrow { + top: 50%; + margin-top: -(ceil($sm-mint__desktop-arrow-size / 2)); + right: $sm-mint__desktop-item-padding-horizontal; + width: 0; + height: 0; + border-width: $sm-mint__desktop-arrow-size ($sm-mint__desktop-arrow-size * 0.67) 0 ($sm-mint__desktop-arrow-size * 0.67); + border-style: solid dashed dashed dashed; + border-color: $sm-mint__desktop-arrow-color transparent transparent transparent; + background: transparent; + border-radius: 0; + } + &:hover .sub-arrow, + &:focus .sub-arrow, + &:active .sub-arrow { + border-color: $sm-mint__desktop-arrow-hover-color transparent transparent transparent; + } + &.highlighted .sub-arrow { + border-color: $sm-mint__desktop-arrow-highlighted-color transparent transparent transparent; + } + &.disabled .sub-arrow { + border-color: $sm-mint__desktop-arrow-color transparent transparent transparent; + } + // reset mobile first style + .sub-arrow::before { + display: none; + } + } + + // No main menu items separators + li { + border-top: 0; + } + + // Sub menus box + ul { + border: 0; + padding: $sm-mint__desktop-sub-padding-vertical $sm-mint__desktop-sub-padding-horizontal; + background: $sm-mint__desktop-sub-bg; + border-radius: 0 $sm-mint__border-radius-base $sm-mint__border-radius-base $sm-mint__border-radius-base; + box-shadow: $sm-mint__desktop-sub-box-shadow; + + // 2+ sub levels need rounding of all corners + ul { + border-radius: $sm-mint__border-radius-base; + } + + // Sub menus items + a { + &, + &:hover, + &:focus, + &:active, + &.highlighted { + border: 0 !important; + padding: $sm-mint__desktop-sub-item-padding-vertical $sm-mint__desktop-sub-item-padding-horizontal; + color: $sm-mint__desktop-sub-item-color; + border-radius: 0; + } + + &:hover, + &:focus, + &:active, + &.highlighted { + background: $sm-mint__desktop-sub-item-hover-bg; + color: $sm-mint__desktop-sub-item-hover-color; + box-shadow: none; + } + + &.disabled { + background: transparent; + color: $sm-mint__desktop-sub-item-disabled-color; + } + + // No need for additional room for the sub arrows + &.has-submenu { + padding-right: $sm-mint__desktop-item-padding-horizontal; + } + + // Sub menu indicators + .sub-arrow { + right: 10px; + margin-top: -($sm-mint__desktop-arrow-size * 0.67); + border-width: ($sm-mint__desktop-arrow-size * 0.67) 0 ($sm-mint__desktop-arrow-size * 0.67) $sm-mint__desktop-arrow-size; + border-style: dashed dashed dashed solid; + border-color: transparent transparent transparent $sm-mint__desktop-arrow-color; + } + &:hover .sub-arrow, + &:focus .sub-arrow, + &:active .sub-arrow, + &.highlighted .sub-arrow { + border-color: transparent transparent transparent $sm-mint__desktop-arrow-hover-color; + } + &.disabled .sub-arrow { + border-color: transparent transparent transparent $sm-mint__desktop-arrow-color; + } + } + } + + // Scrolling arrows containers for tall sub menus - test sub menu: "Sub test" -> "more..." in the default download package + .scroll-up, + .scroll-down { + position: absolute; + display: none; + visibility: hidden; + overflow: hidden; + background: $sm-mint__desktop-sub-bg; + height: 20px; + // width and position will be set automatically by the script + } + .scroll-up-arrow, + .scroll-down-arrow { + position: absolute; + top: 6px; + left: 50%; + margin-left: -8px; + // we will use one-side border to create a triangle so that we don't use a real background image, of course, you can use a real image if you like too + width: 0; + height: 0; + overflow: hidden; + border-width: 0 6px 8px 6px; // tweak size of the arrow + border-style: dashed dashed solid dashed; + border-color: transparent transparent $sm-mint__desktop-arrow-color transparent; + } + .scroll-down-arrow { + border-width: 8px 6px 0 6px; + border-style: solid dashed dashed dashed; + border-color: $sm-mint__desktop-arrow-color transparent transparent transparent; + } + + + // Rigth-to-left + + // Main menu box + &.sm-rtl { + + // Main menu items + a { + + // Make room for the sub arrows + &.has-submenu { + padding-right: $sm-mint__desktop-item-padding-horizontal; + padding-left: $sm-mint__desktop-item-padding-horizontal + 8px + $sm-mint__desktop-arrow-spacing; + } + + // Sub menu indicators + .sub-arrow { + right: auto; + left: $sm-mint__desktop-item-padding-horizontal; + } + } + + // Vertical main menu + &.sm-vertical { + border-right: 0; + border-left: $sm-mint__border-width solid $sm-mint__collapsible-border-color; + + // Vertical main menu items + a { + border-radius: 0 $sm-mint__border-radius-base $sm-mint__border-radius-base 0; + + // No need for additional room for the sub arrows + &.has-submenu { + padding: $sm-mint__desktop-vertical-item-padding-vertical $sm-mint__desktop-vertical-item-padding-horizontal; + } + + // Sub menu indicators + .sub-arrow { + right: auto; + left: 10px; + border-width: ($sm-mint__desktop-arrow-size * 0.67) $sm-mint__desktop-arrow-size ($sm-mint__desktop-arrow-size * 0.67) 0; + border-style: dashed solid dashed dashed; + border-color: transparent $sm-mint__desktop-arrow-color transparent transparent; + } + &:hover .sub-arrow, + &:focus .sub-arrow, + &:active .sub-arrow, + &.highlighted .sub-arrow { + border-color: transparent $sm-mint__desktop-arrow-hover-color transparent transparent; + } + &.disabled .sub-arrow { + border-color: transparent $sm-mint__desktop-arrow-color transparent transparent; + } + } + } + + // Sub menus box + ul { + border-radius: $sm-mint__border-radius-base 0 $sm-mint__border-radius-base $sm-mint__border-radius-base; + + a { + border-radius: 0 !important; + + // No need for additional room for the sub arrows + &.has-submenu { + padding: $sm-mint__desktop-sub-item-padding-vertical $sm-mint__desktop-sub-item-padding-horizontal !important; + } + + // Sub menu indicators + .sub-arrow { + right: auto; + left: 10px; + border-width: ($sm-mint__desktop-arrow-size * 0.67) $sm-mint__desktop-arrow-size ($sm-mint__desktop-arrow-size * 0.67) 0; + border-style: dashed solid dashed dashed; + border-color: transparent $sm-mint__desktop-arrow-color transparent transparent; + } + &:hover .sub-arrow, + &:focus .sub-arrow, + &:active .sub-arrow, + &.highlighted .sub-arrow { + border-color: transparent $sm-mint__desktop-arrow-hover-color transparent transparent; + } + &.disabled .sub-arrow { + border-color: transparent $sm-mint__desktop-arrow-color transparent transparent; + } + } + } + } + + + // Vertical main menu + + // Main menu box + &.sm-vertical { + border-bottom: 0; + border-right: $sm-mint__border-width solid $sm-mint__collapsible-border-color; + + // Main menu items + a { + padding: $sm-mint__desktop-vertical-item-padding-vertical $sm-mint__desktop-vertical-item-padding-horizontal; + border-radius: $sm-mint__border-radius-base 0 0 $sm-mint__border-radius-base; + + &:hover, + &:focus, + &:active, + &.highlighted { + background: $sm-mint__desktop-item-hover-bg; + color: $sm-mint__desktop-item-hover-color; + box-shadow: none; + } + + &.disabled { + background: transparent; + color: $sm-mint__desktop-item-disabled-color; + } + + // Sub menu indicators + .sub-arrow { + right: 10px; + margin-top: -($sm-mint__desktop-arrow-size * 0.67); + border-width: ($sm-mint__desktop-arrow-size * 0.67) 0 ($sm-mint__desktop-arrow-size * 0.67) $sm-mint__desktop-arrow-size; + border-style: dashed dashed dashed solid; + border-color: transparent transparent transparent $sm-mint__desktop-arrow-color; + } + &:hover .sub-arrow, + &:focus .sub-arrow, + &:active .sub-arrow, + &.highlighted .sub-arrow { + border-color: transparent transparent transparent $sm-mint__desktop-arrow-hover-color; + } + &.disabled .sub-arrow { + border-color: transparent transparent transparent $sm-mint__desktop-arrow-color; + } + } + + // Sub menus box + ul { + border-radius: $sm-mint__border-radius-base !important; + + // Sub menus items + a { + padding: $sm-mint__desktop-sub-item-padding-vertical $sm-mint__desktop-sub-item-padding-horizontal; + } + } + } + } +} \ No newline at end of file diff --git a/civicrm/bower_components/smartmenus/dist/css/sm-mint/mixins/_sub-items-indentation.scss b/civicrm/bower_components/smartmenus/dist/css/sm-mint/mixins/_sub-items-indentation.scss new file mode 100644 index 0000000000..28731337af --- /dev/null +++ b/civicrm/bower_components/smartmenus/dist/css/sm-mint/mixins/_sub-items-indentation.scss @@ -0,0 +1,15 @@ +// Generate rules to indent sub menus text +// +// We'll use left border to avoid messing with the padding. + +@mixin sm-mint__sub-items-indentation($amount, $chainable: 'ul ', $level: 4, $chain: '') { + @for $i from 1 through $level { + $chain: $chain + $chainable; + #{$chain} a, + #{$chain} a:hover, + #{$chain} a:focus, + #{$chain} a:active { + border-left: ($amount * ($i + 1)) solid transparent; + } + } +} \ No newline at end of file diff --git a/civicrm/bower_components/smartmenus/dist/css/sm-mint/sm-mint.css b/civicrm/bower_components/smartmenus/dist/css/sm-mint/sm-mint.css new file mode 100644 index 0000000000..1ab65555da --- /dev/null +++ b/civicrm/bower_components/smartmenus/dist/css/sm-mint/sm-mint.css @@ -0,0 +1,331 @@ +.sm-mint { + border-top: 2px solid #8db863; + border-bottom: 2px solid #8db863; + background: #fff; +} +.sm-mint a, .sm-mint a:hover, .sm-mint a:focus, .sm-mint a:active { + padding: 13px 20px; + /* make room for the toggle button (sub indicator) */ + padding-right: 58px; + color: #333; + font-family: Arial, sans-serif; + font-size: 16px; + font-weight: normal; + line-height: 17px; + text-decoration: none; +} +.sm-mint a.current { + font-weight: bold; +} +.sm-mint a.disabled { + color: #cccccc; +} +.sm-mint a .sub-arrow { + position: absolute; + top: 50%; + margin-top: -17px; + left: auto; + right: 4px; + width: 34px; + height: 34px; + overflow: hidden; + font: bold 14px/34px monospace !important; + text-align: center; + text-shadow: none; + background: rgba(141, 184, 99, 0.2); + border-radius: 4px; +} +.sm-mint a .sub-arrow::before { + content: '+'; +} +.sm-mint a.highlighted .sub-arrow::before { + content: '-'; +} +.sm-mint li { + border-top: 1px solid rgba(141, 184, 99, 0.2); +} +.sm-mint > li:first-child { + border-top: 0; +} +.sm-mint ul { + background: rgba(141, 184, 99, 0.2); +} +.sm-mint ul a, .sm-mint ul a:hover, .sm-mint ul a:focus, .sm-mint ul a:active { + font-size: 14px; + border-left: 8px solid transparent; +} +.sm-mint ul ul a, +.sm-mint ul ul a:hover, +.sm-mint ul ul a:focus, +.sm-mint ul ul a:active { + border-left: 16px solid transparent; +} +.sm-mint ul ul ul a, +.sm-mint ul ul ul a:hover, +.sm-mint ul ul ul a:focus, +.sm-mint ul ul ul a:active { + border-left: 24px solid transparent; +} +.sm-mint ul ul ul ul a, +.sm-mint ul ul ul ul a:hover, +.sm-mint ul ul ul ul a:focus, +.sm-mint ul ul ul ul a:active { + border-left: 32px solid transparent; +} +.sm-mint ul ul ul ul ul a, +.sm-mint ul ul ul ul ul a:hover, +.sm-mint ul ul ul ul ul a:focus, +.sm-mint ul ul ul ul ul a:active { + border-left: 40px solid transparent; +} + +@media (min-width: 768px) { + /* Switch to desktop layout + ----------------------------------------------- + These transform the menu tree from + collapsible to desktop (navbar + dropdowns) + -----------------------------------------------*/ + /* start... (it's not recommended editing these rules) */ + .sm-mint ul { + position: absolute; + width: 12em; + } + + .sm-mint li { + float: left; + } + + .sm-mint.sm-rtl li { + float: right; + } + + .sm-mint ul li, .sm-mint.sm-rtl ul li, .sm-mint.sm-vertical li { + float: none; + } + + .sm-mint a { + white-space: nowrap; + } + + .sm-mint ul a, .sm-mint.sm-vertical a { + white-space: normal; + } + + .sm-mint .sm-nowrap > li > a, .sm-mint .sm-nowrap > li > :not(ul) a { + white-space: nowrap; + } + + /* ...end */ + .sm-mint { + border-top: 0; + background: transparent; + } + .sm-mint a, .sm-mint a:hover, .sm-mint a:focus, .sm-mint a:active, .sm-mint a.highlighted { + padding: 11px 20px; + color: #333; + border-radius: 4px 4px 0 0; + } + .sm-mint a:hover, .sm-mint a:focus, .sm-mint a:active { + background: #8db863; + color: #fff; + } + .sm-mint a.highlighted { + background: #F6FFED; + color: #333; + box-shadow: 0 4px 3px rgba(0, 0, 0, 0.25); + } + .sm-mint a.disabled { + background: transparent; + color: #cccccc; + box-shadow: none; + } + .sm-mint a.has-submenu { + padding-right: 34px; + } + .sm-mint a .sub-arrow { + top: 50%; + margin-top: -3px; + right: 20px; + width: 0; + height: 0; + border-width: 6px 4.02px 0 4.02px; + border-style: solid dashed dashed dashed; + border-color: #8db863 transparent transparent transparent; + background: transparent; + border-radius: 0; + } + .sm-mint a:hover .sub-arrow, .sm-mint a:focus .sub-arrow, .sm-mint a:active .sub-arrow { + border-color: #fff transparent transparent transparent; + } + .sm-mint a.highlighted .sub-arrow { + border-color: #8db863 transparent transparent transparent; + } + .sm-mint a.disabled .sub-arrow { + border-color: #8db863 transparent transparent transparent; + } + .sm-mint a .sub-arrow::before { + display: none; + } + .sm-mint li { + border-top: 0; + } + .sm-mint ul { + border: 0; + padding: 8px 0; + background: #F6FFED; + border-radius: 0 4px 4px 4px; + box-shadow: 0 4px 3px rgba(0, 0, 0, 0.25); + } + .sm-mint ul ul { + border-radius: 4px; + } + .sm-mint ul a, .sm-mint ul a:hover, .sm-mint ul a:focus, .sm-mint ul a:active, .sm-mint ul a.highlighted { + border: 0 !important; + padding: 10px 20px; + color: #333; + border-radius: 0; + } + .sm-mint ul a:hover, .sm-mint ul a:focus, .sm-mint ul a:active, .sm-mint ul a.highlighted { + background: #8db863; + color: #fff; + box-shadow: none; + } + .sm-mint ul a.disabled { + background: transparent; + color: #b3b3b3; + } + .sm-mint ul a.has-submenu { + padding-right: 20px; + } + .sm-mint ul a .sub-arrow { + right: 10px; + margin-top: -4.02px; + border-width: 4.02px 0 4.02px 6px; + border-style: dashed dashed dashed solid; + border-color: transparent transparent transparent #8db863; + } + .sm-mint ul a:hover .sub-arrow, .sm-mint ul a:focus .sub-arrow, .sm-mint ul a:active .sub-arrow, .sm-mint ul a.highlighted .sub-arrow { + border-color: transparent transparent transparent #fff; + } + .sm-mint ul a.disabled .sub-arrow { + border-color: transparent transparent transparent #8db863; + } + .sm-mint .scroll-up, + .sm-mint .scroll-down { + position: absolute; + display: none; + visibility: hidden; + overflow: hidden; + background: #F6FFED; + height: 20px; + } + .sm-mint .scroll-up-arrow, + .sm-mint .scroll-down-arrow { + position: absolute; + top: 6px; + left: 50%; + margin-left: -8px; + width: 0; + height: 0; + overflow: hidden; + border-width: 0 6px 8px 6px; + border-style: dashed dashed solid dashed; + border-color: transparent transparent #8db863 transparent; + } + .sm-mint .scroll-down-arrow { + border-width: 8px 6px 0 6px; + border-style: solid dashed dashed dashed; + border-color: #8db863 transparent transparent transparent; + } + .sm-mint.sm-rtl a.has-submenu { + padding-right: 20px; + padding-left: 34px; + } + .sm-mint.sm-rtl a .sub-arrow { + right: auto; + left: 20px; + } + .sm-mint.sm-rtl.sm-vertical { + border-right: 0; + border-left: 2px solid #8db863; + } + .sm-mint.sm-rtl.sm-vertical a { + border-radius: 0 4px 4px 0; + } + .sm-mint.sm-rtl.sm-vertical a.has-submenu { + padding: 10px 20px; + } + .sm-mint.sm-rtl.sm-vertical a .sub-arrow { + right: auto; + left: 10px; + border-width: 4.02px 6px 4.02px 0; + border-style: dashed solid dashed dashed; + border-color: transparent #8db863 transparent transparent; + } + .sm-mint.sm-rtl.sm-vertical a:hover .sub-arrow, .sm-mint.sm-rtl.sm-vertical a:focus .sub-arrow, .sm-mint.sm-rtl.sm-vertical a:active .sub-arrow, .sm-mint.sm-rtl.sm-vertical a.highlighted .sub-arrow { + border-color: transparent #fff transparent transparent; + } + .sm-mint.sm-rtl.sm-vertical a.disabled .sub-arrow { + border-color: transparent #8db863 transparent transparent; + } + .sm-mint.sm-rtl ul { + border-radius: 4px 0 4px 4px; + } + .sm-mint.sm-rtl ul a { + border-radius: 0 !important; + } + .sm-mint.sm-rtl ul a.has-submenu { + padding: 10px 20px !important; + } + .sm-mint.sm-rtl ul a .sub-arrow { + right: auto; + left: 10px; + border-width: 4.02px 6px 4.02px 0; + border-style: dashed solid dashed dashed; + border-color: transparent #8db863 transparent transparent; + } + .sm-mint.sm-rtl ul a:hover .sub-arrow, .sm-mint.sm-rtl ul a:focus .sub-arrow, .sm-mint.sm-rtl ul a:active .sub-arrow, .sm-mint.sm-rtl ul a.highlighted .sub-arrow { + border-color: transparent #fff transparent transparent; + } + .sm-mint.sm-rtl ul a.disabled .sub-arrow { + border-color: transparent #8db863 transparent transparent; + } + .sm-mint.sm-vertical { + border-bottom: 0; + border-right: 2px solid #8db863; + } + .sm-mint.sm-vertical a { + padding: 10px 20px; + border-radius: 4px 0 0 4px; + } + .sm-mint.sm-vertical a:hover, .sm-mint.sm-vertical a:focus, .sm-mint.sm-vertical a:active, .sm-mint.sm-vertical a.highlighted { + background: #8db863; + color: #fff; + box-shadow: none; + } + .sm-mint.sm-vertical a.disabled { + background: transparent; + color: #cccccc; + } + .sm-mint.sm-vertical a .sub-arrow { + right: 10px; + margin-top: -4.02px; + border-width: 4.02px 0 4.02px 6px; + border-style: dashed dashed dashed solid; + border-color: transparent transparent transparent #8db863; + } + .sm-mint.sm-vertical a:hover .sub-arrow, .sm-mint.sm-vertical a:focus .sub-arrow, .sm-mint.sm-vertical a:active .sub-arrow, .sm-mint.sm-vertical a.highlighted .sub-arrow { + border-color: transparent transparent transparent #fff; + } + .sm-mint.sm-vertical a.disabled .sub-arrow { + border-color: transparent transparent transparent #8db863; + } + .sm-mint.sm-vertical ul { + border-radius: 4px !important; + } + .sm-mint.sm-vertical ul a { + padding: 10px 20px; + } +} + +/*# sourceMappingURL=sm-mint.css.map */ diff --git a/civicrm/bower_components/smartmenus/dist/css/sm-mint/sm-mint.css.map b/civicrm/bower_components/smartmenus/dist/css/sm-mint/sm-mint.css.map new file mode 100644 index 0000000000..2220dbd2b8 --- /dev/null +++ b/civicrm/bower_components/smartmenus/dist/css/sm-mint/sm-mint.css.map @@ -0,0 +1,7 @@ +{ +"version": 3, +"mappings": "AAiJA,QAAS;EACR,UAAU,EAAE,iBAA+D;EAC3E,aAAa,EAAE,iBAA+D;EAC9E,UAAU,EA1BiC,IAAe;;AA8BzD,iEAGS;EACR,OAAO,EAAE,SAAyF;EAClG,qDAAqD;EACrD,aAAa,EAAE,IAAgG;EAC/G,KAAK,EAtC+B,IAAe;EAuCnD,WAAW,EAhIiB,iBAAiB;EAiI7C,SAAS,EAhIqB,IAAI;EAiIlC,WAAW,EAAE,MAAM;EACnB,WAAW,EAhIiB,IAAI;EAiIhC,eAAe,EAAE,IAAI;;AAGtB,kBAAU;EACT,WAAW,EAAE,IAAI;;AAGlB,mBAAW;EACV,KAAK,EApHsC,OAA4B;;AAwHxE,qBAAW;EACV,QAAQ,EAAE,QAAQ;EAClB,GAAG,EAAE,GAAG;EACR,UAAU,EAAE,KAAkC;EAC9C,IAAI,EAAE,IAAI;EACV,KAAK,EAvCkB,GAAkC;EAwCzD,KAAK,EAzCe,IAAkC;EA0CtD,MAAM,EA1Cc,IAAkC;EA2CtD,QAAQ,EAAE,MAAM;EAChB,IAAI,EAAE,mCAA+E;EACrF,UAAU,EAAE,MAAM;EAClB,WAAW,EAAE,IAAI;EACjB,UAAU,EA5HyB,uBAA+B;EA6HlE,aAAa,EAlJoB,GAAG;;AAoJrC,6BAAmB;EAClB,OAAO,EAAE,GAAG;;AAEb,yCAAiC;EAChC,OAAO,EAAE,GAAG;;AAKd,WAAG;EACF,UAAU,EAAE,iCAAgD;;AAEtD,yBAAiB;EACvB,UAAU,EAAE,CAAC;;AAId,WAAG;EACF,UAAU,EAzIwB,uBAA+B;;AA6IhE,6EAGS;EACR,SAAS,EAvLqB,IAAI;EAyLlC,WAAW,EAAE,qBAA4D;;ACpN3E;;;uBAGmB;EAClB,WAAW,EAAE,sBAAsC;;AAJpD;;;0BAGmB;EAClB,WAAW,EAAE,sBAAsC;;AAJpD;;;6BAGmB;EAClB,WAAW,EAAE,sBAAsC;;AAJpD;;;gCAGmB;EAClB,WAAW,EAAE,sBAAsC;;;AD8NtD,yBAAyC;EAExC;;;;mDAIiD;EACjD,yDAAyD;EACzD,WAAW;IAAC,QAAQ,EAAC,QAAQ;IAAC,KAAK,EAAC,IAAI;;;EACxC,WAAW;IAAC,KAAK,EAAC,IAAI;;;EACtB,kBAAkB;IAAC,KAAK,EAAC,KAAK;;;EAC9B,8DAA4D;IAAC,KAAK,EAAC,IAAI;;;EACvE,UAAU;IAAC,WAAW,EAAC,MAAM;;;EAC7B,qCAAoC;IAAC,WAAW,EAAC,MAAM;;;EACvD,mEAAkE;IAAC,WAAW,EAAC,MAAM;;;EACrF,YAAY;EAGZ,QAAS;IACR,UAAU,EAAE,CAAC;IACb,UAAU,EA1KkB,WAAW;;EA8KtC,yFAIc;IACb,OAAO,EAAE,SAAiF;IAC1F,KAAK,EA9I8B,IAAe;IA+IlD,aAAa,EAAE,WAA6D;;EAG7E,qDAES;IACR,UAAU,EAnJ2B,OAAoB;IAoJzD,KAAK,EArJmC,IAAe;;EAwJxD,sBAAc;IACb,UAAU,EAhKmB,OAAe;IAiK5C,KAAK,EA3J8B,IAAe;IA4JlD,UAAU,EA1LmC,6BAA+B;;EA6L7E,mBAAW;IACV,UAAU,EAAE,WAAW;IACvB,KAAK,EA9LkC,OAA4B;IA+LnE,UAAU,EAAE,IAAI;;EAIjB,sBAAc;IACb,aAAa,EAAE,IAAiF;;EAIjG,qBAAW;IACV,GAAG,EAAE,GAAG;IACR,UAAU,EAAE,IAAyC;IACrD,KAAK,EAzMqC,IAAI;IA0M9C,KAAK,EAAE,CAAC;IACR,MAAM,EAAE,CAAC;IACT,YAAY,EAAE,mBAA0G;IACxH,YAAY,EAAE,0BAA0B;IACxC,YAAY,EAAE,2CAAiE;IAC/E,UAAU,EAAE,WAAW;IACvB,aAAa,EAAE,CAAC;;EAEjB,sFAEoB;IACnB,YAAY,EAAE,wCAAuE;;EAEtF,iCAAyB;IACxB,YAAY,EAAE,2CAA6E;;EAE5F,8BAAsB;IACrB,YAAY,EAAE,2CAAiE;;EAGhF,6BAAmB;IAClB,OAAO,EAAE,IAAI;;EAKf,WAAG;IACF,UAAU,EAAE,CAAC;;EAId,WAAG;IACF,MAAM,EAAE,CAAC;IACT,OAAO,EAAE,KAA+E;IACxF,UAAU,EAvNoB,OAAe;IAwN7C,aAAa,EAAE,aAAwF;IACvG,UAAU,EAxN0B,6BAA+B;;EA2NnE,cAAG;IACF,aAAa,EArSmB,GAAG;;EA0SnC,wGAIc;IACb,MAAM,EAAE,YAAY;IACpB,OAAO,EAAE,SAAyF;IAClG,KAAK,EAnO6B,IAAe;IAoOjD,aAAa,EAAE,CAAC;;EAGjB,yFAGc;IACb,UAAU,EAzO0B,OAAoB;IA0OxD,KAAK,EA3OkC,IAAe;IA4OtD,UAAU,EAAE,IAAI;;EAGjB,sBAAW;IACV,UAAU,EAAE,WAAW;IACvB,KAAK,EA/OoC,OAA6B;;EAmPvE,yBAAc;IACb,aAAa,EAlR4B,IAAI;;EAsR9C,wBAAW;IACV,KAAK,EAAE,IAAI;IACX,UAAU,EAAE,OAAsC;IAClD,YAAY,EAAE,mBAA0G;IACxH,YAAY,EAAE,0BAA0B;IACxC,YAAY,EAAE,2CAAiE;;EAEhF,qIAG0B;IACzB,YAAY,EAAE,wCAAuE;;EAEtF,iCAAsB;IACrB,YAAY,EAAE,2CAAiE;;EAMlF;uBACa;IACZ,QAAQ,EAAE,QAAQ;IAClB,OAAO,EAAE,IAAI;IACb,UAAU,EAAE,MAAM;IAClB,QAAQ,EAAE,MAAM;IAChB,UAAU,EA3RoB,OAAe;IA4R7C,MAAM,EAAE,IAAI;;EAGb;6BACmB;IAClB,QAAQ,EAAE,QAAQ;IAClB,GAAG,EAAE,GAAG;IACR,IAAI,EAAE,GAAG;IACT,WAAW,EAAE,IAAI;IAEjB,KAAK,EAAE,CAAC;IACR,MAAM,EAAE,CAAC;IACT,QAAQ,EAAE,MAAM;IAChB,YAAY,EAAE,aAAa;IAC3B,YAAY,EAAE,0BAA0B;IACxC,YAAY,EAAE,2CAAiE;;EAEhF,2BAAmB;IAClB,YAAY,EAAE,aAAa;IAC3B,YAAY,EAAE,0BAA0B;IACxC,YAAY,EAAE,2CAAiE;;EAa9E,6BAAc;IACb,aAAa,EAnV4B,IAAI;IAoV7C,YAAY,EAAE,IAAiF;;EAIhG,4BAAW;IACV,KAAK,EAAE,IAAI;IACX,IAAI,EA1VqC,IAAI;;EA+V/C,2BAAc;IACb,YAAY,EAAE,CAAC;IACf,WAAW,EAAE,iBAA+D;;EAG5E,6BAAE;IACD,aAAa,EAAE,WAA6D;;EAG5E,yCAAc;IACb,OAAO,EAAE,SAAmG;;EAI7G,wCAAW;IACV,KAAK,EAAE,IAAI;IACX,IAAI,EAAE,IAAI;IACV,YAAY,EAAE,mBAA0G;IACxH,YAAY,EAAE,0BAA0B;IACxC,YAAY,EAAE,2CAAiE;;EAEhF,qMAG0B;IACzB,YAAY,EAAE,wCAAuE;;EAEtF,iDAAsB;IACrB,YAAY,EAAE,2CAAiE;;EAMlF,kBAAG;IACF,aAAa,EAAE,aAAwF;;EAEvG,oBAAE;IACD,aAAa,EAAE,YAAY;;EAG3B,gCAAc;IACb,OAAO,EAAE,oBAAoG;;EAI9G,+BAAW;IACV,KAAK,EAAE,IAAI;IACX,IAAI,EAAE,IAAI;IACV,YAAY,EAAE,mBAA0G;IACxH,YAAY,EAAE,0BAA0B;IACxC,YAAY,EAAE,2CAAiE;;EAEhF,iKAG0B;IACzB,YAAY,EAAE,wCAAuE;;EAEtF,wCAAsB;IACrB,YAAY,EAAE,2CAAiE;;EAUnF,oBAAc;IACb,aAAa,EAAE,CAAC;IAChB,YAAY,EAAE,iBAA+D;;EAG7E,sBAAE;IACD,OAAO,EAAE,SAAmG;IAC5G,aAAa,EAAE,WAA6D;;EAE5E,6HAGc;IACb,UAAU,EArZ0B,OAAoB;IAsZxD,KAAK,EAvZkC,IAAe;IAwZtD,UAAU,EAAE,IAAI;;EAGjB,+BAAW;IACV,UAAU,EAAE,WAAW;IACvB,KAAK,EA3biC,OAA4B;;EA+bnE,iCAAW;IACV,KAAK,EAAE,IAAI;IACX,UAAU,EAAE,OAAsC;IAClD,YAAY,EAAE,mBAA0G;IACxH,YAAY,EAAE,0BAA0B;IACxC,YAAY,EAAE,2CAAiE;;EAEhF,yKAG0B;IACzB,YAAY,EAAE,wCAAuE;;EAEtF,0CAAsB;IACrB,YAAY,EAAE,2CAAiE;;EAKjF,uBAAG;IACF,aAAa,EAAE,cAAuC;;EAGtD,yBAAE;IACD,OAAO,EAAE,SAAyF", +"sources": ["_sm-mint-theme.scss","mixins/_sub-items-indentation.scss"], +"names": [], +"file": "sm-mint.css" +} diff --git a/civicrm/bower_components/smartmenus/dist/css/sm-mint/sm-mint.scss b/civicrm/bower_components/smartmenus/dist/css/sm-mint/sm-mint.scss new file mode 100644 index 0000000000..00dc26762d --- /dev/null +++ b/civicrm/bower_components/smartmenus/dist/css/sm-mint/sm-mint.scss @@ -0,0 +1,4 @@ +@import '_mixins.scss'; + +// the variables + the CSS +@import '_sm-mint-theme.scss'; \ No newline at end of file diff --git a/civicrm/bower_components/smartmenus/dist/css/sm-simple/_mixins.scss b/civicrm/bower_components/smartmenus/dist/css/sm-simple/_mixins.scss new file mode 100644 index 0000000000..dd6ff7cabb --- /dev/null +++ b/civicrm/bower_components/smartmenus/dist/css/sm-simple/_mixins.scss @@ -0,0 +1 @@ +@import 'mixins/_sub-items-indentation.scss'; \ No newline at end of file diff --git a/civicrm/bower_components/smartmenus/dist/css/sm-simple/_sm-simple-theme.scss b/civicrm/bower_components/smartmenus/dist/css/sm-simple/_sm-simple-theme.scss new file mode 100644 index 0000000000..e72e20b1ea --- /dev/null +++ b/civicrm/bower_components/smartmenus/dist/css/sm-simple/_sm-simple-theme.scss @@ -0,0 +1,446 @@ +// This file is best viewed with Tab size 4 code indentation + + +// ----------------------------------------------------------------------------------------------------------------- +// 1. Theme Quick Settings (Variables) +// (for further control, you will need to dig into the actual CSS in 2.) +// ----------------------------------------------------------------------------------------------------------------- + + +// ---------------------------------------------------------- +// :: 1.1. Colors +// ---------------------------------------------------------- + +$sm-simple__white: #fff !default; +$sm-simple__gray: darken($sm-simple__white, 6.5%) !default; +$sm-simple__gray-dark: darken($sm-simple__white, 26.5%) !default; +$sm-simple__gray-darker: darken($sm-simple__white, 66.5%) !default; + +$sm-simple__box-shadow: rgba(0, 0, 0, 0.2) !default; + + +// ---------------------------------------------------------- +// :: 1.2. Breakpoints +// ---------------------------------------------------------- + +$sm-simple__desktop-vp: 768px !default; // switch from collapsible to desktop + + +// ---------------------------------------------------------- +// :: 1.3. Typography +// ---------------------------------------------------------- + +$sm-simple__font-family: "Lucida Sans Unicode", "Lucida Sans", "Lucida Grande", Arial, sans-serif !default; +$sm-simple__font-size-base: 16px !default; +$sm-simple__font-size-small: 14px !default; +$sm-simple__line-height: 17px !default; + + +// ---------------------------------------------------------- +// :: 1.4. Borders +// ---------------------------------------------------------- + +$sm-simple__border-width: 1px !default; + + +// ---------------------------------------------------------- +// :: 1.5. Collapsible main menu +// ---------------------------------------------------------- + +// Menu box +$sm-simple__collapsible-bg: $sm-simple__white !default; +$sm-simple__collapsible-border-color: $sm-simple__gray-dark !default; +$sm-simple__collapsible-box-shadow: 0 1px 1px $sm-simple__box-shadow !default; + +// Items +$sm-simple__collapsible-item-color: $sm-simple__gray-darker !default; +$sm-simple__collapsible-item-current-color: $sm-simple__white !default; +$sm-simple__collapsible-item-current-bg: $sm-simple__gray-darker !default; +$sm-simple__collapsible-item-disabled-color: darken($sm-simple__white, 20%) !default; +$sm-simple__collapsible-item-padding-vertical: 13px !default; +$sm-simple__collapsible-item-padding-horizontal: 20px !default; + +// Items separators +$sm-simple__collapsible-separators-color: rgba(0, 0, 0, 0.05) !default; + +// Toggle button (sub menu indicators) +$sm-simple__collapsible-toggle-bg: rgba(0, 0, 0, 0.08) !default; + + +// ---------------------------------------------------------- +// :: 1.6. Collapsible sub menus +// ---------------------------------------------------------- + +// Menu box +$sm-simple__collapsible-sub-bg: rgba(darken($sm-simple__collapsible-bg, 30%), 0.1) !default; + +// Items text indentation for deeper levels +$sm-simple__collapsible-sub-item-indentation: 8px !default; + + +// ---------------------------------------------------------- +// :: 1.7. Desktop main menu and sub menus +// ---------------------------------------------------------- + +// Menu box +$sm-simple__desktop-bg: $sm-simple__white !default; + +// Items +$sm-simple__desktop-item-color: $sm-simple__gray-darker !default; +$sm-simple__desktop-item-hover-bg: $sm-simple__gray !default; +$sm-simple__desktop-item-current-color: $sm-simple__white !default; +$sm-simple__desktop-item-current-bg: $sm-simple__gray-darker !default; +$sm-simple__desktop-item-disabled-color: darken($sm-simple__white, 20%) !default; +$sm-simple__desktop-item-padding-vertical: 11px !default; +$sm-simple__desktop-item-padding-horizontal: 20px !default; + +// Items separators +$sm-simple__desktop-separators-size: 1px !default; +$sm-simple__desktop-separators-color: $sm-simple__gray !default; + +// Sub menu indicators +$sm-simple__desktop-arrow-spacing: 4px !default; + + +// ----------------------------------------------------------------------------------------------------------------- +// 2. Theme CSS +// ----------------------------------------------------------------------------------------------------------------- + + +// ---------------------------------------------------------- +// :: 2.1. Collapsible mode (mobile first) +// ---------------------------------------------------------- + +// calc item height and sub menus toggle button size +$sm-simple__item-height: $sm-simple__line-height + $sm-simple__collapsible-item-padding-vertical * 2; +// set toggle button size to 80% of item height +$sm-simple__toggle-size: floor($sm-simple__item-height * 0.8); +$sm-simple__toggle-spacing: floor($sm-simple__item-height * 0.1); + +// Main menu box +.sm-simple { + border: $sm-simple__border-width solid $sm-simple__collapsible-border-color; + background: $sm-simple__collapsible-bg; + box-shadow: $sm-simple__collapsible-box-shadow; + + // Main menu items + a { + &, + &:hover, + &:focus, + &:active { + padding: $sm-simple__collapsible-item-padding-vertical $sm-simple__collapsible-item-padding-horizontal; + /* make room for the toggle button (sub indicator) */ + padding-right: $sm-simple__collapsible-item-padding-horizontal + $sm-simple__toggle-size + $sm-simple__toggle-spacing; + color: $sm-simple__collapsible-item-color; + font-family: $sm-simple__font-family; + font-size: $sm-simple__font-size-base; + font-weight: normal; + line-height: $sm-simple__line-height; + text-decoration: none; + } + + &.current { + background: $sm-simple__collapsible-item-current-bg; + color: $sm-simple__collapsible-item-current-color; + } + + &.disabled { + color: $sm-simple__collapsible-item-disabled-color; + } + + // Toggle buttons (sub menu indicators) + .sub-arrow { + position: absolute; + top: 50%; + margin-top: -(ceil($sm-simple__toggle-size / 2)); + left: auto; + right: $sm-simple__toggle-spacing; + width: $sm-simple__toggle-size; + height: $sm-simple__toggle-size; + overflow: hidden; + font: bold #{$sm-simple__font-size-small}/#{$sm-simple__toggle-size} monospace !important; + text-align: center; + text-shadow: none; + background: $sm-simple__collapsible-toggle-bg; + } + .sub-arrow::before { + content: '+'; + } + &.highlighted .sub-arrow::before { + content: '-'; + } + } + + // Main menu items separators + li { + border-top: 1px solid $sm-simple__collapsible-separators-color; + } + > li:first-child { + border-top: 0; + } + + // Sub menus box + ul { + background: $sm-simple__collapsible-sub-bg; + + // Sub menus items + a { + &, + &:hover, + &:focus, + &:active { + font-size: $sm-simple__font-size-small; + // add indentation for sub menus text + border-left: $sm-simple__collapsible-sub-item-indentation solid transparent; + } + } + + // Add indentation for sub menus text for deeper levels + @include sm-simple__sub-items-indentation($sm-simple__collapsible-sub-item-indentation); + } +} + + +// ---------------------------------------------------------- +// :: 2.2. Desktop mode +// ---------------------------------------------------------- + +@media (min-width: $sm-simple__desktop-vp) { + + /* Switch to desktop layout + ----------------------------------------------- + These transform the menu tree from + collapsible to desktop (navbar + dropdowns) + -----------------------------------------------*/ + /* start... (it's not recommended editing these rules) */ + .sm-simple ul{position:absolute;width:12em;} + .sm-simple li{float:left;} + .sm-simple.sm-rtl li{float:right;} + .sm-simple ul li,.sm-simple.sm-rtl ul li,.sm-simple.sm-vertical li{float:none;} + .sm-simple a{white-space:nowrap;} + .sm-simple ul a,.sm-simple.sm-vertical a{white-space:normal;} + .sm-simple .sm-nowrap > li > a,.sm-simple .sm-nowrap > li > :not(ul) a{white-space:nowrap;} + /* ...end */ + + // Main menu box + .sm-simple { + background: $sm-simple__desktop-bg; + + // Main menu items + a { + &, + &:hover, + &:focus, + &:active, + &.highlighted { + padding: $sm-simple__desktop-item-padding-vertical $sm-simple__desktop-item-padding-horizontal; + color: $sm-simple__desktop-item-color; + } + + &:hover, + &:focus, + &:active, + &.highlighted { + background: $sm-simple__desktop-item-hover-bg; + } + + &.current { + background: $sm-simple__desktop-item-current-bg; + color: $sm-simple__desktop-item-current-color; + } + + &.disabled { + background: $sm-simple__desktop-bg; + color: $sm-simple__desktop-item-disabled-color; + } + + // Make room for the sub arrows + &.has-submenu { + padding-right: $sm-simple__desktop-item-padding-horizontal + 8px + $sm-simple__desktop-arrow-spacing; + } + + // Sub menu indicators + .sub-arrow { + top: 50%; + margin-top: -8px; + right: $sm-simple__desktop-item-padding-horizontal; + width: 8px; + height: 16px; + font: #{$sm-simple__font-size-small}/16px monospace !important; + background: transparent; + } + // reset mobile first style + &.highlighted .sub-arrow::before { + content: '+'; + } + } + + // Main menu items separators + > li { + border-top: 0; + border-left: $sm-simple__desktop-separators-size solid $sm-simple__desktop-separators-color; + + &:first-child { + border-left: 0; + } + } + + // Sub menus box + ul { + border: $sm-simple__border-width solid $sm-simple__collapsible-border-color; + background: $sm-simple__desktop-bg; + box-shadow: $sm-simple__collapsible-box-shadow; + + // Sub menus items + a { + border: 0 !important; + + // No need for additional room for the sub arrows + &.has-submenu { + padding-right: $sm-simple__desktop-item-padding-horizontal; + } + + // Sub menu indicators + .sub-arrow { + left: $sm-simple__desktop-item-padding-horizontal - 8px - $sm-simple__desktop-arrow-spacing; + right: auto; + } + } + + // Sub menus items separators + > li { + border-left: 0; + border-top: $sm-simple__desktop-separators-size solid $sm-simple__desktop-separators-color; + + &:first-child { + border-top: 0; + } + } + } + + // Scrolling arrows containers for tall sub menus - test sub menu: "Sub test" -> "more..." in the default download package + .scroll-up, + .scroll-down { + position: absolute; + display: none; + visibility: hidden; + overflow: hidden; + background: $sm-simple__desktop-bg; + height: 20px; + // width and position will be set automatically by the script + } + .scroll-up-arrow, + .scroll-down-arrow { + position: absolute; + top: -2px; + left: 50%; + margin-left: -8px; + // we will use one-side border to create a triangle so that we don't use a real background image, of course, you can use a real image if you like too + width: 0; + height: 0; + overflow: hidden; + border-width: 8px; // tweak size of the arrow + border-style: dashed dashed solid dashed; + border-color: transparent transparent $sm-simple__desktop-item-color transparent; + } + .scroll-down-arrow { + top: 6px; + border-style: solid dashed dashed dashed; + border-color: $sm-simple__desktop-item-color transparent transparent transparent; + } + + + // Rigth-to-left + + // Main menu box + &.sm-rtl { + + // Main menu items + a { + + // Make room for the sub arrows + &.has-submenu { + padding-right: $sm-simple__desktop-item-padding-horizontal; + padding-left: $sm-simple__desktop-item-padding-horizontal + 8px + $sm-simple__desktop-arrow-spacing; + } + + // Sub menu indicators + .sub-arrow { + left: $sm-simple__desktop-item-padding-horizontal; + right: auto; + } + } + + // Vertical main menu items + &.sm-vertical { + a { + + // No need for additional room for the sub arrows + &.has-submenu { + padding: $sm-simple__desktop-item-padding-vertical $sm-simple__desktop-item-padding-horizontal; + } + + // Sub menu indicators + .sub-arrow { + left: auto; + right: $sm-simple__desktop-item-padding-horizontal - 8px - $sm-simple__desktop-arrow-spacing; + } + } + } + + // Main menu items separators + > li { + &:first-child { + border-left: $sm-simple__desktop-separators-size solid $sm-simple__desktop-separators-color; + } + &:last-child { + border-left: 0; + } + } + + // Sub menus box + ul { + a { + + // No need for additional room for the sub arrows + &.has-submenu { + padding: $sm-simple__desktop-item-padding-vertical $sm-simple__desktop-item-padding-horizontal; + } + + // Sub menu indicators + .sub-arrow { + left: auto; + right: $sm-simple__desktop-item-padding-horizontal - 8px - $sm-simple__desktop-arrow-spacing; + } + } + } + } + + + // Vertical main menu + + // Main menu box + &.sm-vertical { + + // Main menu items + a { + + // Sub menu indicators + .sub-arrow { + left: $sm-simple__desktop-item-padding-horizontal - 8px - $sm-simple__desktop-arrow-spacing; + right: auto; + } + } + + // Main menu items separators + li { + border-left: 0; + border-top: $sm-simple__desktop-separators-size solid $sm-simple__desktop-separators-color; + } + > li:first-child { + border-top: 0; + } + } + } +} \ No newline at end of file diff --git a/civicrm/bower_components/smartmenus/dist/css/sm-simple/mixins/_sub-items-indentation.scss b/civicrm/bower_components/smartmenus/dist/css/sm-simple/mixins/_sub-items-indentation.scss new file mode 100644 index 0000000000..966e7c6a27 --- /dev/null +++ b/civicrm/bower_components/smartmenus/dist/css/sm-simple/mixins/_sub-items-indentation.scss @@ -0,0 +1,15 @@ +// Generate rules to indent sub menus text +// +// We'll use left border to avoid messing with the padding. + +@mixin sm-simple__sub-items-indentation($amount, $chainable: 'ul ', $level: 4, $chain: '') { + @for $i from 1 through $level { + $chain: $chain + $chainable; + #{$chain} a, + #{$chain} a:hover, + #{$chain} a:focus, + #{$chain} a:active { + border-left: ($amount * ($i + 1)) solid transparent; + } + } +} \ No newline at end of file diff --git a/civicrm/bower_components/smartmenus/dist/css/sm-simple/sm-simple.css b/civicrm/bower_components/smartmenus/dist/css/sm-simple/sm-simple.css new file mode 100644 index 0000000000..8fcf0c159a --- /dev/null +++ b/civicrm/bower_components/smartmenus/dist/css/sm-simple/sm-simple.css @@ -0,0 +1,249 @@ +.sm-simple { + border: 1px solid #bbbbbb; + background: #fff; + box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2); +} +.sm-simple a, .sm-simple a:hover, .sm-simple a:focus, .sm-simple a:active { + padding: 13px 20px; + /* make room for the toggle button (sub indicator) */ + padding-right: 58px; + color: #555555; + font-family: "Lucida Sans Unicode", "Lucida Sans", "Lucida Grande", Arial, sans-serif; + font-size: 16px; + font-weight: normal; + line-height: 17px; + text-decoration: none; +} +.sm-simple a.current { + background: #555555; + color: #fff; +} +.sm-simple a.disabled { + color: #cccccc; +} +.sm-simple a .sub-arrow { + position: absolute; + top: 50%; + margin-top: -17px; + left: auto; + right: 4px; + width: 34px; + height: 34px; + overflow: hidden; + font: bold 14px/34px monospace !important; + text-align: center; + text-shadow: none; + background: rgba(0, 0, 0, 0.08); +} +.sm-simple a .sub-arrow::before { + content: '+'; +} +.sm-simple a.highlighted .sub-arrow::before { + content: '-'; +} +.sm-simple li { + border-top: 1px solid rgba(0, 0, 0, 0.05); +} +.sm-simple > li:first-child { + border-top: 0; +} +.sm-simple ul { + background: rgba(179, 179, 179, 0.1); +} +.sm-simple ul a, .sm-simple ul a:hover, .sm-simple ul a:focus, .sm-simple ul a:active { + font-size: 14px; + border-left: 8px solid transparent; +} +.sm-simple ul ul a, +.sm-simple ul ul a:hover, +.sm-simple ul ul a:focus, +.sm-simple ul ul a:active { + border-left: 16px solid transparent; +} +.sm-simple ul ul ul a, +.sm-simple ul ul ul a:hover, +.sm-simple ul ul ul a:focus, +.sm-simple ul ul ul a:active { + border-left: 24px solid transparent; +} +.sm-simple ul ul ul ul a, +.sm-simple ul ul ul ul a:hover, +.sm-simple ul ul ul ul a:focus, +.sm-simple ul ul ul ul a:active { + border-left: 32px solid transparent; +} +.sm-simple ul ul ul ul ul a, +.sm-simple ul ul ul ul ul a:hover, +.sm-simple ul ul ul ul ul a:focus, +.sm-simple ul ul ul ul ul a:active { + border-left: 40px solid transparent; +} + +@media (min-width: 768px) { + /* Switch to desktop layout + ----------------------------------------------- + These transform the menu tree from + collapsible to desktop (navbar + dropdowns) + -----------------------------------------------*/ + /* start... (it's not recommended editing these rules) */ + .sm-simple ul { + position: absolute; + width: 12em; + } + + .sm-simple li { + float: left; + } + + .sm-simple.sm-rtl li { + float: right; + } + + .sm-simple ul li, .sm-simple.sm-rtl ul li, .sm-simple.sm-vertical li { + float: none; + } + + .sm-simple a { + white-space: nowrap; + } + + .sm-simple ul a, .sm-simple.sm-vertical a { + white-space: normal; + } + + .sm-simple .sm-nowrap > li > a, .sm-simple .sm-nowrap > li > :not(ul) a { + white-space: nowrap; + } + + /* ...end */ + .sm-simple { + background: #fff; + } + .sm-simple a, .sm-simple a:hover, .sm-simple a:focus, .sm-simple a:active, .sm-simple a.highlighted { + padding: 11px 20px; + color: #555555; + } + .sm-simple a:hover, .sm-simple a:focus, .sm-simple a:active, .sm-simple a.highlighted { + background: #eeeeee; + } + .sm-simple a.current { + background: #555555; + color: #fff; + } + .sm-simple a.disabled { + background: #fff; + color: #cccccc; + } + .sm-simple a.has-submenu { + padding-right: 32px; + } + .sm-simple a .sub-arrow { + top: 50%; + margin-top: -8px; + right: 20px; + width: 8px; + height: 16px; + font: 14px/16px monospace !important; + background: transparent; + } + .sm-simple a.highlighted .sub-arrow::before { + content: '+'; + } + .sm-simple > li { + border-top: 0; + border-left: 1px solid #eeeeee; + } + .sm-simple > li:first-child { + border-left: 0; + } + .sm-simple ul { + border: 1px solid #bbbbbb; + background: #fff; + box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2); + } + .sm-simple ul a { + border: 0 !important; + } + .sm-simple ul a.has-submenu { + padding-right: 20px; + } + .sm-simple ul a .sub-arrow { + left: 8px; + right: auto; + } + .sm-simple ul > li { + border-left: 0; + border-top: 1px solid #eeeeee; + } + .sm-simple ul > li:first-child { + border-top: 0; + } + .sm-simple .scroll-up, + .sm-simple .scroll-down { + position: absolute; + display: none; + visibility: hidden; + overflow: hidden; + background: #fff; + height: 20px; + } + .sm-simple .scroll-up-arrow, + .sm-simple .scroll-down-arrow { + position: absolute; + top: -2px; + left: 50%; + margin-left: -8px; + width: 0; + height: 0; + overflow: hidden; + border-width: 8px; + border-style: dashed dashed solid dashed; + border-color: transparent transparent #555555 transparent; + } + .sm-simple .scroll-down-arrow { + top: 6px; + border-style: solid dashed dashed dashed; + border-color: #555555 transparent transparent transparent; + } + .sm-simple.sm-rtl a.has-submenu { + padding-right: 20px; + padding-left: 32px; + } + .sm-simple.sm-rtl a .sub-arrow { + left: 20px; + right: auto; + } + .sm-simple.sm-rtl.sm-vertical a.has-submenu { + padding: 11px 20px; + } + .sm-simple.sm-rtl.sm-vertical a .sub-arrow { + left: auto; + right: 8px; + } + .sm-simple.sm-rtl > li:first-child { + border-left: 1px solid #eeeeee; + } + .sm-simple.sm-rtl > li:last-child { + border-left: 0; + } + .sm-simple.sm-rtl ul a.has-submenu { + padding: 11px 20px; + } + .sm-simple.sm-rtl ul a .sub-arrow { + left: auto; + right: 8px; + } + .sm-simple.sm-vertical a .sub-arrow { + left: 8px; + right: auto; + } + .sm-simple.sm-vertical li { + border-left: 0; + border-top: 1px solid #eeeeee; + } + .sm-simple.sm-vertical > li:first-child { + border-top: 0; + } +} + +/*# sourceMappingURL=sm-simple.css.map */ diff --git a/civicrm/bower_components/smartmenus/dist/css/sm-simple/sm-simple.css.map b/civicrm/bower_components/smartmenus/dist/css/sm-simple/sm-simple.css.map new file mode 100644 index 0000000000..88f04761bf --- /dev/null +++ b/civicrm/bower_components/smartmenus/dist/css/sm-simple/sm-simple.css.map @@ -0,0 +1,7 @@ +{ +"version": 3, +"mappings": "AAwHA,UAAW;EACV,MAAM,EAAE,iBAAmE;EAC3E,UAAU,EAhCiC,IAAiB;EAiC5D,UAAU,EAvE8B,4BAAiC;;AA2ExE,yEAGS;EACR,OAAO,EAAE,SAA6F;EACtG,qDAAqD;EACrD,aAAa,EAAE,IAAsG;EACrH,KAAK,EA3CiC,OAAuB;EA4C7D,WAAW,EAvGkB,wEAAwE;EAwGrG,SAAS,EAvGuB,IAAI;EAwGpC,WAAW,EAAE,MAAM;EACnB,WAAW,EAvGkB,IAAI;EAwGjC,eAAe,EAAE,IAAI;;AAGtB,oBAAU;EACT,UAAU,EApD4B,OAAuB;EAqD7D,KAAK,EAtDoC,IAAiB;;AAyD3D,qBAAW;EACV,KAAK,EA1FuC,OAA8B;;AA8F3E,uBAAW;EACV,QAAQ,EAAE,QAAQ;EAClB,GAAG,EAAE,GAAG;EACR,UAAU,EAAE,KAAoC;EAChD,IAAI,EAAE,IAAI;EACV,KAAK,EAxCoB,GAAoC;EAyC7D,KAAK,EA1CiB,IAAoC;EA2C1D,MAAM,EA3CgB,IAAoC;EA4C1D,QAAQ,EAAE,MAAM;EAChB,IAAI,EAAE,mCAAmF;EACzF,UAAU,EAAE,MAAM;EAClB,WAAW,EAAE,IAAI;EACjB,UAAU,EAlG2B,mBAAmB;;AAoGzD,+BAAmB;EAClB,OAAO,EAAE,GAAG;;AAEb,2CAAiC;EAChC,OAAO,EAAE,GAAG;;AAKd,aAAG;EACF,UAAU,EAAE,6BAAkD;;AAExD,2BAAiB;EACvB,UAAU,EAAE,CAAC;;AAId,aAAG;EACF,UAAU,EA9G0B,wBAAkD;;AAkHrF,qFAGS;EACR,SAAS,EA9JsB,IAAI;EAgKnC,WAAW,EAAE,qBAA8D;;AC3L7E;;;yBAGmB;EAClB,WAAW,EAAE,sBAAsC;;AAJpD;;;4BAGmB;EAClB,WAAW,EAAE,sBAAsC;;AAJpD;;;+BAGmB;EAClB,WAAW,EAAE,sBAAsC;;AAJpD;;;kCAGmB;EAClB,WAAW,EAAE,sBAAsC;;;ADqMtD,yBAA2C;EAE1C;;;;mDAIiD;EACjD,yDAAyD;EACzD,aAAa;IAAC,QAAQ,EAAC,QAAQ;IAAC,KAAK,EAAC,IAAI;;;EAC1C,aAAa;IAAC,KAAK,EAAC,IAAI;;;EACxB,oBAAoB;IAAC,KAAK,EAAC,KAAK;;;EAChC,oEAAkE;IAAC,KAAK,EAAC,IAAI;;;EAC7E,YAAY;IAAC,WAAW,EAAC,MAAM;;;EAC/B,yCAAwC;IAAC,WAAW,EAAC,MAAM;;;EAC3D,uEAAsE;IAAC,WAAW,EAAC,MAAM;;;EACzF,YAAY;EAGZ,UAAW;IACV,UAAU,EAzIgC,IAAiB;;EA6I1D,mGAIc;IACb,OAAO,EAAE,SAAqF;IAC9F,KAAK,EAlJgC,OAAuB;;EAqJ7D,qFAGc;IACb,UAAU,EAlJ4B,OAAgB;;EAqJvD,oBAAU;IACT,UAAU,EA7J2B,OAAuB;IA8J5D,KAAK,EA/JmC,IAAiB;;EAkK1D,qBAAW;IACV,UAAU,EAnK8B,IAAiB;IAoKzD,KAAK,EAlKmC,OAA8B;;EAsKvE,wBAAc;IACb,aAAa,EAAE,IAAqF;;EAIrG,uBAAW;IACV,GAAG,EAAE,GAAG;IACR,UAAU,EAAE,IAAI;IAChB,KAAK,EA5KsC,IAAI;IA6K/C,KAAK,EAAE,GAAG;IACV,MAAM,EAAE,IAAI;IACZ,IAAI,EAAE,8BAAwD;IAC9D,UAAU,EAAE,WAAW;;EAGxB,2CAAiC;IAChC,OAAO,EAAE,GAAG;;EAKd,eAAK;IACJ,UAAU,EAAE,CAAC;IACb,WAAW,EAAE,iBAA8E;;EAE3F,2BAAc;IACb,WAAW,EAAE,CAAC;;EAKhB,aAAG;IACF,MAAM,EAAE,iBAAmE;IAC3E,UAAU,EAzM+B,IAAiB;IA0M1D,UAAU,EAhP4B,4BAAiC;;EAmPvE,eAAE;IACD,MAAM,EAAE,YAAY;;EAGpB,2BAAc;IACb,aAAa,EA9M6B,IAAI;;EAkN/C,0BAAW;IACV,IAAI,EAAE,GAAqF;IAC3F,KAAK,EAAE,IAAI;;EAKb,kBAAK;IACJ,WAAW,EAAE,CAAC;IACd,UAAU,EAAE,iBAA8E;;EAE1F,8BAAc;IACb,UAAU,EAAE,CAAC;;EAMhB;yBACa;IACZ,QAAQ,EAAE,QAAQ;IAClB,OAAO,EAAE,IAAI;IACb,UAAU,EAAE,MAAM;IAClB,QAAQ,EAAE,MAAM;IAChB,UAAU,EA9O+B,IAAiB;IA+O1D,MAAM,EAAE,IAAI;;EAGb;+BACmB;IAClB,QAAQ,EAAE,QAAQ;IAClB,GAAG,EAAE,IAAI;IACT,IAAI,EAAE,GAAG;IACT,WAAW,EAAE,IAAI;IAEjB,KAAK,EAAE,CAAC;IACR,MAAM,EAAE,CAAC;IACT,QAAQ,EAAE,MAAM;IAChB,YAAY,EAAE,GAAG;IACjB,YAAY,EAAE,0BAA0B;IACxC,YAAY,EAAE,2CAAkE;;EAEjF,6BAAmB;IAClB,GAAG,EAAE,GAAG;IACR,YAAY,EAAE,0BAA0B;IACxC,YAAY,EAAE,2CAAkE;;EAa/E,+BAAc;IACb,aAAa,EA7Q6B,IAAI;IA8Q9C,YAAY,EAAE,IAAqF;;EAIpG,8BAAW;IACV,IAAI,EAnRsC,IAAI;IAoR9C,KAAK,EAAE,IAAI;;EASX,2CAAc;IACb,OAAO,EAAE,SAAqF;;EAI/F,0CAAW;IACV,IAAI,EAAE,IAAI;IACV,KAAK,EAAE,GAAqF;;EAO9F,kCAAc;IACb,WAAW,EAAE,iBAA8E;;EAE5F,iCAAa;IACZ,WAAW,EAAE,CAAC;;EASd,kCAAc;IACb,OAAO,EAAE,SAAqF;;EAI/F,iCAAW;IACV,IAAI,EAAE,IAAI;IACV,KAAK,EAAE,GAAqF;;EAgB9F,mCAAW;IACV,IAAI,EAAE,GAAqF;IAC3F,KAAK,EAAE,IAAI;;EAKb,yBAAG;IACF,WAAW,EAAE,CAAC;IACd,UAAU,EAAE,iBAA8E;;EAE3F,uCAAiB;IAChB,UAAU,EAAE,CAAC", +"sources": ["_sm-simple-theme.scss","mixins/_sub-items-indentation.scss"], +"names": [], +"file": "sm-simple.css" +} diff --git a/civicrm/bower_components/smartmenus/dist/css/sm-simple/sm-simple.scss b/civicrm/bower_components/smartmenus/dist/css/sm-simple/sm-simple.scss new file mode 100644 index 0000000000..5415dbf372 --- /dev/null +++ b/civicrm/bower_components/smartmenus/dist/css/sm-simple/sm-simple.scss @@ -0,0 +1,4 @@ +@import '_mixins.scss'; + +// the variables + the CSS +@import '_sm-simple-theme.scss'; \ No newline at end of file diff --git a/civicrm/bower_components/smartmenus/dist/jquery.smartmenus.js b/civicrm/bower_components/smartmenus/dist/jquery.smartmenus.js new file mode 100644 index 0000000000..d6b7a47c03 --- /dev/null +++ b/civicrm/bower_components/smartmenus/dist/jquery.smartmenus.js @@ -0,0 +1,1216 @@ +/*! + * SmartMenus jQuery Plugin - v1.1.0 - September 17, 2017 + * http://www.smartmenus.org/ + * + * Copyright Vasil Dinkov, Vadikom Web Ltd. + * http://vadikom.com + * + * Licensed MIT + */ + +(function(factory) { + if (typeof define === 'function' && define.amd) { + // AMD + define(['jquery'], factory); + } else if (typeof module === 'object' && typeof module.exports === 'object') { + // CommonJS + module.exports = factory(require('jquery')); + } else { + // Global jQuery + factory(jQuery); + } +} (function($) { + + var menuTrees = [], + mouse = false, // optimize for touch by default - we will detect for mouse input + touchEvents = 'ontouchstart' in window, // we use this just to choose between toucn and pointer events, not for touch screen detection + mouseDetectionEnabled = false, + requestAnimationFrame = window.requestAnimationFrame || function(callback) { return setTimeout(callback, 1000 / 60); }, + cancelAnimationFrame = window.cancelAnimationFrame || function(id) { clearTimeout(id); }, + canAnimate = !!$.fn.animate; + + // Handle detection for mouse input (i.e. desktop browsers, tablets with a mouse, etc.) + function initMouseDetection(disable) { + var eNS = '.smartmenus_mouse'; + if (!mouseDetectionEnabled && !disable) { + // if we get two consecutive mousemoves within 2 pixels from each other and within 300ms, we assume a real mouse/cursor is present + // in practice, this seems like impossible to trick unintentianally with a real mouse and a pretty safe detection on touch devices (even with older browsers that do not support touch events) + var firstTime = true, + lastMove = null, + events = { + 'mousemove': function(e) { + var thisMove = { x: e.pageX, y: e.pageY, timeStamp: new Date().getTime() }; + if (lastMove) { + var deltaX = Math.abs(lastMove.x - thisMove.x), + deltaY = Math.abs(lastMove.y - thisMove.y); + if ((deltaX > 0 || deltaY > 0) && deltaX <= 2 && deltaY <= 2 && thisMove.timeStamp - lastMove.timeStamp <= 300) { + mouse = true; + // if this is the first check after page load, check if we are not over some item by chance and call the mouseenter handler if yes + if (firstTime) { + var $a = $(e.target).closest('a'); + if ($a.is('a')) { + $.each(menuTrees, function() { + if ($.contains(this.$root[0], $a[0])) { + this.itemEnter({ currentTarget: $a[0] }); + return false; + } + }); + } + firstTime = false; + } + } + } + lastMove = thisMove; + } + }; + events[touchEvents ? 'touchstart' : 'pointerover pointermove pointerout MSPointerOver MSPointerMove MSPointerOut'] = function(e) { + if (isTouchEvent(e.originalEvent)) { + mouse = false; + } + }; + $(document).on(getEventsNS(events, eNS)); + mouseDetectionEnabled = true; + } else if (mouseDetectionEnabled && disable) { + $(document).off(eNS); + mouseDetectionEnabled = false; + } + } + + function isTouchEvent(e) { + return !/^(4|mouse)$/.test(e.pointerType); + } + + // returns a jQuery on() ready object + function getEventsNS(events, eNS) { + if (!eNS) { + eNS = ''; + } + var eventsNS = {}; + for (var i in events) { + eventsNS[i.split(' ').join(eNS + ' ') + eNS] = events[i]; + } + return eventsNS; + } + + $.SmartMenus = function(elm, options) { + this.$root = $(elm); + this.opts = options; + this.rootId = ''; // internal + this.accessIdPrefix = ''; + this.$subArrow = null; + this.activatedItems = []; // stores last activated A's for each level + this.visibleSubMenus = []; // stores visible sub menus UL's (might be in no particular order) + this.showTimeout = 0; + this.hideTimeout = 0; + this.scrollTimeout = 0; + this.clickActivated = false; + this.focusActivated = false; + this.zIndexInc = 0; + this.idInc = 0; + this.$firstLink = null; // we'll use these for some tests + this.$firstSub = null; // at runtime so we'll cache them + this.disabled = false; + this.$disableOverlay = null; + this.$touchScrollingSub = null; + this.cssTransforms3d = 'perspective' in elm.style || 'webkitPerspective' in elm.style; + this.wasCollapsible = false; + this.init(); + }; + + $.extend($.SmartMenus, { + hideAll: function() { + $.each(menuTrees, function() { + this.menuHideAll(); + }); + }, + destroy: function() { + while (menuTrees.length) { + menuTrees[0].destroy(); + } + initMouseDetection(true); + }, + prototype: { + init: function(refresh) { + var self = this; + + if (!refresh) { + menuTrees.push(this); + + this.rootId = (new Date().getTime() + Math.random() + '').replace(/\D/g, ''); + this.accessIdPrefix = 'sm-' + this.rootId + '-'; + + if (this.$root.hasClass('sm-rtl')) { + this.opts.rightToLeftSubMenus = true; + } + + // init root (main menu) + var eNS = '.smartmenus'; + this.$root + .data('smartmenus', this) + .attr('data-smartmenus-id', this.rootId) + .dataSM('level', 1) + .on(getEventsNS({ + 'mouseover focusin': $.proxy(this.rootOver, this), + 'mouseout focusout': $.proxy(this.rootOut, this), + 'keydown': $.proxy(this.rootKeyDown, this) + }, eNS)) + .on(getEventsNS({ + 'mouseenter': $.proxy(this.itemEnter, this), + 'mouseleave': $.proxy(this.itemLeave, this), + 'mousedown': $.proxy(this.itemDown, this), + 'focus': $.proxy(this.itemFocus, this), + 'blur': $.proxy(this.itemBlur, this), + 'click': $.proxy(this.itemClick, this) + }, eNS), 'a'); + + // hide menus on tap or click outside the root UL + eNS += this.rootId; + if (this.opts.hideOnClick) { + $(document).on(getEventsNS({ + 'touchstart': $.proxy(this.docTouchStart, this), + 'touchmove': $.proxy(this.docTouchMove, this), + 'touchend': $.proxy(this.docTouchEnd, this), + // for Opera Mobile < 11.5, webOS browser, etc. we'll check click too + 'click': $.proxy(this.docClick, this) + }, eNS)); + } + // hide sub menus on resize + $(window).on(getEventsNS({ 'resize orientationchange': $.proxy(this.winResize, this) }, eNS)); + + if (this.opts.subIndicators) { + this.$subArrow = $('<span/>').addClass('sub-arrow'); + if (this.opts.subIndicatorsText) { + this.$subArrow.html(this.opts.subIndicatorsText); + } + } + + // make sure mouse detection is enabled + initMouseDetection(); + } + + // init sub menus + this.$firstSub = this.$root.find('ul').each(function() { self.menuInit($(this)); }).eq(0); + + this.$firstLink = this.$root.find('a').eq(0); + + // find current item + if (this.opts.markCurrentItem) { + var reDefaultDoc = /(index|default)\.[^#\?\/]*/i, + reHash = /#.*/, + locHref = window.location.href.replace(reDefaultDoc, ''), + locHrefNoHash = locHref.replace(reHash, ''); + this.$root.find('a').each(function() { + var href = this.href.replace(reDefaultDoc, ''), + $this = $(this); + if (href == locHref || href == locHrefNoHash) { + $this.addClass('current'); + if (self.opts.markCurrentTree) { + $this.parentsUntil('[data-smartmenus-id]', 'ul').each(function() { + $(this).dataSM('parent-a').addClass('current'); + }); + } + } + }); + } + + // save initial state + this.wasCollapsible = this.isCollapsible(); + }, + destroy: function(refresh) { + if (!refresh) { + var eNS = '.smartmenus'; + this.$root + .removeData('smartmenus') + .removeAttr('data-smartmenus-id') + .removeDataSM('level') + .off(eNS); + eNS += this.rootId; + $(document).off(eNS); + $(window).off(eNS); + if (this.opts.subIndicators) { + this.$subArrow = null; + } + } + this.menuHideAll(); + var self = this; + this.$root.find('ul').each(function() { + var $this = $(this); + if ($this.dataSM('scroll-arrows')) { + $this.dataSM('scroll-arrows').remove(); + } + if ($this.dataSM('shown-before')) { + if (self.opts.subMenusMinWidth || self.opts.subMenusMaxWidth) { + $this.css({ width: '', minWidth: '', maxWidth: '' }).removeClass('sm-nowrap'); + } + if ($this.dataSM('scroll-arrows')) { + $this.dataSM('scroll-arrows').remove(); + } + $this.css({ zIndex: '', top: '', left: '', marginLeft: '', marginTop: '', display: '' }); + } + if (($this.attr('id') || '').indexOf(self.accessIdPrefix) == 0) { + $this.removeAttr('id'); + } + }) + .removeDataSM('in-mega') + .removeDataSM('shown-before') + .removeDataSM('scroll-arrows') + .removeDataSM('parent-a') + .removeDataSM('level') + .removeDataSM('beforefirstshowfired') + .removeAttr('role') + .removeAttr('aria-hidden') + .removeAttr('aria-labelledby') + .removeAttr('aria-expanded'); + this.$root.find('a.has-submenu').each(function() { + var $this = $(this); + if ($this.attr('id').indexOf(self.accessIdPrefix) == 0) { + $this.removeAttr('id'); + } + }) + .removeClass('has-submenu') + .removeDataSM('sub') + .removeAttr('aria-haspopup') + .removeAttr('aria-controls') + .removeAttr('aria-expanded') + .closest('li').removeDataSM('sub'); + if (this.opts.subIndicators) { + this.$root.find('span.sub-arrow').remove(); + } + if (this.opts.markCurrentItem) { + this.$root.find('a.current').removeClass('current'); + } + if (!refresh) { + this.$root = null; + this.$firstLink = null; + this.$firstSub = null; + if (this.$disableOverlay) { + this.$disableOverlay.remove(); + this.$disableOverlay = null; + } + menuTrees.splice($.inArray(this, menuTrees), 1); + } + }, + disable: function(noOverlay) { + if (!this.disabled) { + this.menuHideAll(); + // display overlay over the menu to prevent interaction + if (!noOverlay && !this.opts.isPopup && this.$root.is(':visible')) { + var pos = this.$root.offset(); + this.$disableOverlay = $('<div class="sm-jquery-disable-overlay"/>').css({ + position: 'absolute', + top: pos.top, + left: pos.left, + width: this.$root.outerWidth(), + height: this.$root.outerHeight(), + zIndex: this.getStartZIndex(true), + opacity: 0 + }).appendTo(document.body); + } + this.disabled = true; + } + }, + docClick: function(e) { + if (this.$touchScrollingSub) { + this.$touchScrollingSub = null; + return; + } + // hide on any click outside the menu or on a menu link + if (this.visibleSubMenus.length && !$.contains(this.$root[0], e.target) || $(e.target).closest('a').length) { + this.menuHideAll(); + } + }, + docTouchEnd: function(e) { + if (!this.lastTouch) { + return; + } + if (this.visibleSubMenus.length && (this.lastTouch.x2 === undefined || this.lastTouch.x1 == this.lastTouch.x2) && (this.lastTouch.y2 === undefined || this.lastTouch.y1 == this.lastTouch.y2) && (!this.lastTouch.target || !$.contains(this.$root[0], this.lastTouch.target))) { + if (this.hideTimeout) { + clearTimeout(this.hideTimeout); + this.hideTimeout = 0; + } + // hide with a delay to prevent triggering accidental unwanted click on some page element + var self = this; + this.hideTimeout = setTimeout(function() { self.menuHideAll(); }, 350); + } + this.lastTouch = null; + }, + docTouchMove: function(e) { + if (!this.lastTouch) { + return; + } + var touchPoint = e.originalEvent.touches[0]; + this.lastTouch.x2 = touchPoint.pageX; + this.lastTouch.y2 = touchPoint.pageY; + }, + docTouchStart: function(e) { + var touchPoint = e.originalEvent.touches[0]; + this.lastTouch = { x1: touchPoint.pageX, y1: touchPoint.pageY, target: touchPoint.target }; + }, + enable: function() { + if (this.disabled) { + if (this.$disableOverlay) { + this.$disableOverlay.remove(); + this.$disableOverlay = null; + } + this.disabled = false; + } + }, + getClosestMenu: function(elm) { + var $closestMenu = $(elm).closest('ul'); + while ($closestMenu.dataSM('in-mega')) { + $closestMenu = $closestMenu.parent().closest('ul'); + } + return $closestMenu[0] || null; + }, + getHeight: function($elm) { + return this.getOffset($elm, true); + }, + // returns precise width/height float values + getOffset: function($elm, height) { + var old; + if ($elm.css('display') == 'none') { + old = { position: $elm[0].style.position, visibility: $elm[0].style.visibility }; + $elm.css({ position: 'absolute', visibility: 'hidden' }).show(); + } + var box = $elm[0].getBoundingClientRect && $elm[0].getBoundingClientRect(), + val = box && (height ? box.height || box.bottom - box.top : box.width || box.right - box.left); + if (!val && val !== 0) { + val = height ? $elm[0].offsetHeight : $elm[0].offsetWidth; + } + if (old) { + $elm.hide().css(old); + } + return val; + }, + getStartZIndex: function(root) { + var zIndex = parseInt(this[root ? '$root' : '$firstSub'].css('z-index')); + if (!root && isNaN(zIndex)) { + zIndex = parseInt(this.$root.css('z-index')); + } + return !isNaN(zIndex) ? zIndex : 1; + }, + getTouchPoint: function(e) { + return e.touches && e.touches[0] || e.changedTouches && e.changedTouches[0] || e; + }, + getViewport: function(height) { + var name = height ? 'Height' : 'Width', + val = document.documentElement['client' + name], + val2 = window['inner' + name]; + if (val2) { + val = Math.min(val, val2); + } + return val; + }, + getViewportHeight: function() { + return this.getViewport(true); + }, + getViewportWidth: function() { + return this.getViewport(); + }, + getWidth: function($elm) { + return this.getOffset($elm); + }, + handleEvents: function() { + return !this.disabled && this.isCSSOn(); + }, + handleItemEvents: function($a) { + return this.handleEvents() && !this.isLinkInMegaMenu($a); + }, + isCollapsible: function() { + return this.$firstSub.css('position') == 'static'; + }, + isCSSOn: function() { + return this.$firstLink.css('display') != 'inline'; + }, + isFixed: function() { + var isFixed = this.$root.css('position') == 'fixed'; + if (!isFixed) { + this.$root.parentsUntil('body').each(function() { + if ($(this).css('position') == 'fixed') { + isFixed = true; + return false; + } + }); + } + return isFixed; + }, + isLinkInMegaMenu: function($a) { + return $(this.getClosestMenu($a[0])).hasClass('mega-menu'); + }, + isTouchMode: function() { + return !mouse || this.opts.noMouseOver || this.isCollapsible(); + }, + itemActivate: function($a, hideDeeperSubs) { + var $ul = $a.closest('ul'), + level = $ul.dataSM('level'); + // if for some reason the parent item is not activated (e.g. this is an API call to activate the item), activate all parent items first + if (level > 1 && (!this.activatedItems[level - 2] || this.activatedItems[level - 2][0] != $ul.dataSM('parent-a')[0])) { + var self = this; + $($ul.parentsUntil('[data-smartmenus-id]', 'ul').get().reverse()).add($ul).each(function() { + self.itemActivate($(this).dataSM('parent-a')); + }); + } + // hide any visible deeper level sub menus + if (!this.isCollapsible() || hideDeeperSubs) { + this.menuHideSubMenus(!this.activatedItems[level - 1] || this.activatedItems[level - 1][0] != $a[0] ? level - 1 : level); + } + // save new active item for this level + this.activatedItems[level - 1] = $a; + if (this.$root.triggerHandler('activate.smapi', $a[0]) === false) { + return; + } + // show the sub menu if this item has one + var $sub = $a.dataSM('sub'); + if ($sub && (this.isTouchMode() || (!this.opts.showOnClick || this.clickActivated))) { + this.menuShow($sub); + } + }, + itemBlur: function(e) { + var $a = $(e.currentTarget); + if (!this.handleItemEvents($a)) { + return; + } + this.$root.triggerHandler('blur.smapi', $a[0]); + }, + itemClick: function(e) { + var $a = $(e.currentTarget); + if (!this.handleItemEvents($a)) { + return; + } + if (this.$touchScrollingSub && this.$touchScrollingSub[0] == $a.closest('ul')[0]) { + this.$touchScrollingSub = null; + e.stopPropagation(); + return false; + } + if (this.$root.triggerHandler('click.smapi', $a[0]) === false) { + return false; + } + var subArrowClicked = $(e.target).is('.sub-arrow'), + $sub = $a.dataSM('sub'), + firstLevelSub = $sub ? $sub.dataSM('level') == 2 : false, + collapsible = this.isCollapsible(), + behaviorToggle = /toggle$/.test(this.opts.collapsibleBehavior), + behaviorLink = /link$/.test(this.opts.collapsibleBehavior), + behaviorAccordion = /^accordion/.test(this.opts.collapsibleBehavior); + // if the sub is hidden, try to show it + if ($sub && !$sub.is(':visible')) { + if (!behaviorLink || !collapsible || subArrowClicked) { + if (this.opts.showOnClick && firstLevelSub) { + this.clickActivated = true; + } + // try to activate the item and show the sub + this.itemActivate($a, behaviorAccordion); + // if "itemActivate" showed the sub, prevent the click so that the link is not loaded + // if it couldn't show it, then the sub menus are disabled with an !important declaration (e.g. via mobile styles) so let the link get loaded + if ($sub.is(':visible')) { + this.focusActivated = true; + return false; + } + } + // if the sub is visible and we are in collapsible mode + } else if (collapsible && (behaviorToggle || subArrowClicked)) { + this.itemActivate($a, behaviorAccordion); + this.menuHide($sub); + if (behaviorToggle) { + this.focusActivated = false; + } + return false; + } + if (this.opts.showOnClick && firstLevelSub || $a.hasClass('disabled') || this.$root.triggerHandler('select.smapi', $a[0]) === false) { + return false; + } + }, + itemDown: function(e) { + var $a = $(e.currentTarget); + if (!this.handleItemEvents($a)) { + return; + } + $a.dataSM('mousedown', true); + }, + itemEnter: function(e) { + var $a = $(e.currentTarget); + if (!this.handleItemEvents($a)) { + return; + } + if (!this.isTouchMode()) { + if (this.showTimeout) { + clearTimeout(this.showTimeout); + this.showTimeout = 0; + } + var self = this; + this.showTimeout = setTimeout(function() { self.itemActivate($a); }, this.opts.showOnClick && $a.closest('ul').dataSM('level') == 1 ? 1 : this.opts.showTimeout); + } + this.$root.triggerHandler('mouseenter.smapi', $a[0]); + }, + itemFocus: function(e) { + var $a = $(e.currentTarget); + if (!this.handleItemEvents($a)) { + return; + } + // fix (the mousedown check): in some browsers a tap/click produces consecutive focus + click events so we don't need to activate the item on focus + if (this.focusActivated && (!this.isTouchMode() || !$a.dataSM('mousedown')) && (!this.activatedItems.length || this.activatedItems[this.activatedItems.length - 1][0] != $a[0])) { + this.itemActivate($a, true); + } + this.$root.triggerHandler('focus.smapi', $a[0]); + }, + itemLeave: function(e) { + var $a = $(e.currentTarget); + if (!this.handleItemEvents($a)) { + return; + } + if (!this.isTouchMode()) { + $a[0].blur(); + if (this.showTimeout) { + clearTimeout(this.showTimeout); + this.showTimeout = 0; + } + } + $a.removeDataSM('mousedown'); + this.$root.triggerHandler('mouseleave.smapi', $a[0]); + }, + menuHide: function($sub) { + if (this.$root.triggerHandler('beforehide.smapi', $sub[0]) === false) { + return; + } + if (canAnimate) { + $sub.stop(true, true); + } + if ($sub.css('display') != 'none') { + var complete = function() { + // unset z-index + $sub.css('z-index', ''); + }; + // if sub is collapsible (mobile view) + if (this.isCollapsible()) { + if (canAnimate && this.opts.collapsibleHideFunction) { + this.opts.collapsibleHideFunction.call(this, $sub, complete); + } else { + $sub.hide(this.opts.collapsibleHideDuration, complete); + } + } else { + if (canAnimate && this.opts.hideFunction) { + this.opts.hideFunction.call(this, $sub, complete); + } else { + $sub.hide(this.opts.hideDuration, complete); + } + } + // deactivate scrolling if it is activated for this sub + if ($sub.dataSM('scroll')) { + this.menuScrollStop($sub); + $sub.css({ 'touch-action': '', '-ms-touch-action': '', '-webkit-transform': '', transform: '' }) + .off('.smartmenus_scroll').removeDataSM('scroll').dataSM('scroll-arrows').hide(); + } + // unhighlight parent item + accessibility + $sub.dataSM('parent-a').removeClass('highlighted').attr('aria-expanded', 'false'); + $sub.attr({ + 'aria-expanded': 'false', + 'aria-hidden': 'true' + }); + var level = $sub.dataSM('level'); + this.activatedItems.splice(level - 1, 1); + this.visibleSubMenus.splice($.inArray($sub, this.visibleSubMenus), 1); + this.$root.triggerHandler('hide.smapi', $sub[0]); + } + }, + menuHideAll: function() { + if (this.showTimeout) { + clearTimeout(this.showTimeout); + this.showTimeout = 0; + } + // hide all subs + // if it's a popup, this.visibleSubMenus[0] is the root UL + var level = this.opts.isPopup ? 1 : 0; + for (var i = this.visibleSubMenus.length - 1; i >= level; i--) { + this.menuHide(this.visibleSubMenus[i]); + } + // hide root if it's popup + if (this.opts.isPopup) { + if (canAnimate) { + this.$root.stop(true, true); + } + if (this.$root.is(':visible')) { + if (canAnimate && this.opts.hideFunction) { + this.opts.hideFunction.call(this, this.$root); + } else { + this.$root.hide(this.opts.hideDuration); + } + } + } + this.activatedItems = []; + this.visibleSubMenus = []; + this.clickActivated = false; + this.focusActivated = false; + // reset z-index increment + this.zIndexInc = 0; + this.$root.triggerHandler('hideAll.smapi'); + }, + menuHideSubMenus: function(level) { + for (var i = this.activatedItems.length - 1; i >= level; i--) { + var $sub = this.activatedItems[i].dataSM('sub'); + if ($sub) { + this.menuHide($sub); + } + } + }, + menuInit: function($ul) { + if (!$ul.dataSM('in-mega')) { + // mark UL's in mega drop downs (if any) so we can neglect them + if ($ul.hasClass('mega-menu')) { + $ul.find('ul').dataSM('in-mega', true); + } + // get level (much faster than, for example, using parentsUntil) + var level = 2, + par = $ul[0]; + while ((par = par.parentNode.parentNode) != this.$root[0]) { + level++; + } + // cache stuff for quick access + var $a = $ul.prevAll('a').eq(-1); + // if the link is nested (e.g. in a heading) + if (!$a.length) { + $a = $ul.prevAll().find('a').eq(-1); + } + $a.addClass('has-submenu').dataSM('sub', $ul); + $ul.dataSM('parent-a', $a) + .dataSM('level', level) + .parent().dataSM('sub', $ul); + // accessibility + var aId = $a.attr('id') || this.accessIdPrefix + (++this.idInc), + ulId = $ul.attr('id') || this.accessIdPrefix + (++this.idInc); + $a.attr({ + id: aId, + 'aria-haspopup': 'true', + 'aria-controls': ulId, + 'aria-expanded': 'false' + }); + $ul.attr({ + id: ulId, + 'role': 'group', + 'aria-hidden': 'true', + 'aria-labelledby': aId, + 'aria-expanded': 'false' + }); + // add sub indicator to parent item + if (this.opts.subIndicators) { + $a[this.opts.subIndicatorsPos](this.$subArrow.clone()); + } + } + }, + menuPosition: function($sub) { + var $a = $sub.dataSM('parent-a'), + $li = $a.closest('li'), + $ul = $li.parent(), + level = $sub.dataSM('level'), + subW = this.getWidth($sub), + subH = this.getHeight($sub), + itemOffset = $a.offset(), + itemX = itemOffset.left, + itemY = itemOffset.top, + itemW = this.getWidth($a), + itemH = this.getHeight($a), + $win = $(window), + winX = $win.scrollLeft(), + winY = $win.scrollTop(), + winW = this.getViewportWidth(), + winH = this.getViewportHeight(), + horizontalParent = $ul.parent().is('[data-sm-horizontal-sub]') || level == 2 && !$ul.hasClass('sm-vertical'), + rightToLeft = this.opts.rightToLeftSubMenus && !$li.is('[data-sm-reverse]') || !this.opts.rightToLeftSubMenus && $li.is('[data-sm-reverse]'), + subOffsetX = level == 2 ? this.opts.mainMenuSubOffsetX : this.opts.subMenusSubOffsetX, + subOffsetY = level == 2 ? this.opts.mainMenuSubOffsetY : this.opts.subMenusSubOffsetY, + x, y; + if (horizontalParent) { + x = rightToLeft ? itemW - subW - subOffsetX : subOffsetX; + y = this.opts.bottomToTopSubMenus ? -subH - subOffsetY : itemH + subOffsetY; + } else { + x = rightToLeft ? subOffsetX - subW : itemW - subOffsetX; + y = this.opts.bottomToTopSubMenus ? itemH - subOffsetY - subH : subOffsetY; + } + if (this.opts.keepInViewport) { + var absX = itemX + x, + absY = itemY + y; + if (rightToLeft && absX < winX) { + x = horizontalParent ? winX - absX + x : itemW - subOffsetX; + } else if (!rightToLeft && absX + subW > winX + winW) { + x = horizontalParent ? winX + winW - subW - absX + x : subOffsetX - subW; + } + if (!horizontalParent) { + if (subH < winH && absY + subH > winY + winH) { + y += winY + winH - subH - absY; + } else if (subH >= winH || absY < winY) { + y += winY - absY; + } + } + // do we need scrolling? + // 0.49 used for better precision when dealing with float values + if (horizontalParent && (absY + subH > winY + winH + 0.49 || absY < winY) || !horizontalParent && subH > winH + 0.49) { + var self = this; + if (!$sub.dataSM('scroll-arrows')) { + $sub.dataSM('scroll-arrows', $([$('<span class="scroll-up"><span class="scroll-up-arrow"></span></span>')[0], $('<span class="scroll-down"><span class="scroll-down-arrow"></span></span>')[0]]) + .on({ + mouseenter: function() { + $sub.dataSM('scroll').up = $(this).hasClass('scroll-up'); + self.menuScroll($sub); + }, + mouseleave: function(e) { + self.menuScrollStop($sub); + self.menuScrollOut($sub, e); + }, + 'mousewheel DOMMouseScroll': function(e) { e.preventDefault(); } + }) + .insertAfter($sub) + ); + } + // bind scroll events and save scroll data for this sub + var eNS = '.smartmenus_scroll'; + $sub.dataSM('scroll', { + y: this.cssTransforms3d ? 0 : y - itemH, + step: 1, + // cache stuff for faster recalcs later + itemH: itemH, + subH: subH, + arrowDownH: this.getHeight($sub.dataSM('scroll-arrows').eq(1)) + }) + .on(getEventsNS({ + 'mouseover': function(e) { self.menuScrollOver($sub, e); }, + 'mouseout': function(e) { self.menuScrollOut($sub, e); }, + 'mousewheel DOMMouseScroll': function(e) { self.menuScrollMousewheel($sub, e); } + }, eNS)) + .dataSM('scroll-arrows').css({ top: 'auto', left: '0', marginLeft: x + (parseInt($sub.css('border-left-width')) || 0), width: subW - (parseInt($sub.css('border-left-width')) || 0) - (parseInt($sub.css('border-right-width')) || 0), zIndex: $sub.css('z-index') }) + .eq(horizontalParent && this.opts.bottomToTopSubMenus ? 0 : 1).show(); + // when a menu tree is fixed positioned we allow scrolling via touch too + // since there is no other way to access such long sub menus if no mouse is present + if (this.isFixed()) { + var events = {}; + events[touchEvents ? 'touchstart touchmove touchend' : 'pointerdown pointermove pointerup MSPointerDown MSPointerMove MSPointerUp'] = function(e) { + self.menuScrollTouch($sub, e); + }; + $sub.css({ 'touch-action': 'none', '-ms-touch-action': 'none' }).on(getEventsNS(events, eNS)); + } + } + } + $sub.css({ top: 'auto', left: '0', marginLeft: x, marginTop: y - itemH }); + }, + menuScroll: function($sub, once, step) { + var data = $sub.dataSM('scroll'), + $arrows = $sub.dataSM('scroll-arrows'), + end = data.up ? data.upEnd : data.downEnd, + diff; + if (!once && data.momentum) { + data.momentum *= 0.92; + diff = data.momentum; + if (diff < 0.5) { + this.menuScrollStop($sub); + return; + } + } else { + diff = step || (once || !this.opts.scrollAccelerate ? this.opts.scrollStep : Math.floor(data.step)); + } + // hide any visible deeper level sub menus + var level = $sub.dataSM('level'); + if (this.activatedItems[level - 1] && this.activatedItems[level - 1].dataSM('sub') && this.activatedItems[level - 1].dataSM('sub').is(':visible')) { + this.menuHideSubMenus(level - 1); + } + data.y = data.up && end <= data.y || !data.up && end >= data.y ? data.y : (Math.abs(end - data.y) > diff ? data.y + (data.up ? diff : -diff) : end); + $sub.css(this.cssTransforms3d ? { '-webkit-transform': 'translate3d(0, ' + data.y + 'px, 0)', transform: 'translate3d(0, ' + data.y + 'px, 0)' } : { marginTop: data.y }); + // show opposite arrow if appropriate + if (mouse && (data.up && data.y > data.downEnd || !data.up && data.y < data.upEnd)) { + $arrows.eq(data.up ? 1 : 0).show(); + } + // if we've reached the end + if (data.y == end) { + if (mouse) { + $arrows.eq(data.up ? 0 : 1).hide(); + } + this.menuScrollStop($sub); + } else if (!once) { + if (this.opts.scrollAccelerate && data.step < this.opts.scrollStep) { + data.step += 0.2; + } + var self = this; + this.scrollTimeout = requestAnimationFrame(function() { self.menuScroll($sub); }); + } + }, + menuScrollMousewheel: function($sub, e) { + if (this.getClosestMenu(e.target) == $sub[0]) { + e = e.originalEvent; + var up = (e.wheelDelta || -e.detail) > 0; + if ($sub.dataSM('scroll-arrows').eq(up ? 0 : 1).is(':visible')) { + $sub.dataSM('scroll').up = up; + this.menuScroll($sub, true); + } + } + e.preventDefault(); + }, + menuScrollOut: function($sub, e) { + if (mouse) { + if (!/^scroll-(up|down)/.test((e.relatedTarget || '').className) && ($sub[0] != e.relatedTarget && !$.contains($sub[0], e.relatedTarget) || this.getClosestMenu(e.relatedTarget) != $sub[0])) { + $sub.dataSM('scroll-arrows').css('visibility', 'hidden'); + } + } + }, + menuScrollOver: function($sub, e) { + if (mouse) { + if (!/^scroll-(up|down)/.test(e.target.className) && this.getClosestMenu(e.target) == $sub[0]) { + this.menuScrollRefreshData($sub); + var data = $sub.dataSM('scroll'), + upEnd = $(window).scrollTop() - $sub.dataSM('parent-a').offset().top - data.itemH; + $sub.dataSM('scroll-arrows').eq(0).css('margin-top', upEnd).end() + .eq(1).css('margin-top', upEnd + this.getViewportHeight() - data.arrowDownH).end() + .css('visibility', 'visible'); + } + } + }, + menuScrollRefreshData: function($sub) { + var data = $sub.dataSM('scroll'), + upEnd = $(window).scrollTop() - $sub.dataSM('parent-a').offset().top - data.itemH; + if (this.cssTransforms3d) { + upEnd = -(parseFloat($sub.css('margin-top')) - upEnd); + } + $.extend(data, { + upEnd: upEnd, + downEnd: upEnd + this.getViewportHeight() - data.subH + }); + }, + menuScrollStop: function($sub) { + if (this.scrollTimeout) { + cancelAnimationFrame(this.scrollTimeout); + this.scrollTimeout = 0; + $sub.dataSM('scroll').step = 1; + return true; + } + }, + menuScrollTouch: function($sub, e) { + e = e.originalEvent; + if (isTouchEvent(e)) { + var touchPoint = this.getTouchPoint(e); + // neglect event if we touched a visible deeper level sub menu + if (this.getClosestMenu(touchPoint.target) == $sub[0]) { + var data = $sub.dataSM('scroll'); + if (/(start|down)$/i.test(e.type)) { + if (this.menuScrollStop($sub)) { + // if we were scrolling, just stop and don't activate any link on the first touch + e.preventDefault(); + this.$touchScrollingSub = $sub; + } else { + this.$touchScrollingSub = null; + } + // update scroll data since the user might have zoomed, etc. + this.menuScrollRefreshData($sub); + // extend it with the touch properties + $.extend(data, { + touchStartY: touchPoint.pageY, + touchStartTime: e.timeStamp + }); + } else if (/move$/i.test(e.type)) { + var prevY = data.touchY !== undefined ? data.touchY : data.touchStartY; + if (prevY !== undefined && prevY != touchPoint.pageY) { + this.$touchScrollingSub = $sub; + var up = prevY < touchPoint.pageY; + // changed direction? reset... + if (data.up !== undefined && data.up != up) { + $.extend(data, { + touchStartY: touchPoint.pageY, + touchStartTime: e.timeStamp + }); + } + $.extend(data, { + up: up, + touchY: touchPoint.pageY + }); + this.menuScroll($sub, true, Math.abs(touchPoint.pageY - prevY)); + } + e.preventDefault(); + } else { // touchend/pointerup + if (data.touchY !== undefined) { + if (data.momentum = Math.pow(Math.abs(touchPoint.pageY - data.touchStartY) / (e.timeStamp - data.touchStartTime), 2) * 15) { + this.menuScrollStop($sub); + this.menuScroll($sub); + e.preventDefault(); + } + delete data.touchY; + } + } + } + } + }, + menuShow: function($sub) { + if (!$sub.dataSM('beforefirstshowfired')) { + $sub.dataSM('beforefirstshowfired', true); + if (this.$root.triggerHandler('beforefirstshow.smapi', $sub[0]) === false) { + return; + } + } + if (this.$root.triggerHandler('beforeshow.smapi', $sub[0]) === false) { + return; + } + $sub.dataSM('shown-before', true); + if (canAnimate) { + $sub.stop(true, true); + } + if (!$sub.is(':visible')) { + // highlight parent item + var $a = $sub.dataSM('parent-a'), + collapsible = this.isCollapsible(); + if (this.opts.keepHighlighted || collapsible) { + $a.addClass('highlighted'); + } + if (collapsible) { + $sub.removeClass('sm-nowrap').css({ zIndex: '', width: 'auto', minWidth: '', maxWidth: '', top: '', left: '', marginLeft: '', marginTop: '' }); + } else { + // set z-index + $sub.css('z-index', this.zIndexInc = (this.zIndexInc || this.getStartZIndex()) + 1); + // min/max-width fix - no way to rely purely on CSS as all UL's are nested + if (this.opts.subMenusMinWidth || this.opts.subMenusMaxWidth) { + $sub.css({ width: 'auto', minWidth: '', maxWidth: '' }).addClass('sm-nowrap'); + if (this.opts.subMenusMinWidth) { + $sub.css('min-width', this.opts.subMenusMinWidth); + } + if (this.opts.subMenusMaxWidth) { + var noMaxWidth = this.getWidth($sub); + $sub.css('max-width', this.opts.subMenusMaxWidth); + if (noMaxWidth > this.getWidth($sub)) { + $sub.removeClass('sm-nowrap').css('width', this.opts.subMenusMaxWidth); + } + } + } + this.menuPosition($sub); + } + var complete = function() { + // fix: "overflow: hidden;" is not reset on animation complete in jQuery < 1.9.0 in Chrome when global "box-sizing: border-box;" is used + $sub.css('overflow', ''); + }; + // if sub is collapsible (mobile view) + if (collapsible) { + if (canAnimate && this.opts.collapsibleShowFunction) { + this.opts.collapsibleShowFunction.call(this, $sub, complete); + } else { + $sub.show(this.opts.collapsibleShowDuration, complete); + } + } else { + if (canAnimate && this.opts.showFunction) { + this.opts.showFunction.call(this, $sub, complete); + } else { + $sub.show(this.opts.showDuration, complete); + } + } + // accessibility + $a.attr('aria-expanded', 'true'); + $sub.attr({ + 'aria-expanded': 'true', + 'aria-hidden': 'false' + }); + // store sub menu in visible array + this.visibleSubMenus.push($sub); + this.$root.triggerHandler('show.smapi', $sub[0]); + } + }, + popupHide: function(noHideTimeout) { + if (this.hideTimeout) { + clearTimeout(this.hideTimeout); + this.hideTimeout = 0; + } + var self = this; + this.hideTimeout = setTimeout(function() { + self.menuHideAll(); + }, noHideTimeout ? 1 : this.opts.hideTimeout); + }, + popupShow: function(left, top) { + if (!this.opts.isPopup) { + alert('SmartMenus jQuery Error:\n\nIf you want to show this menu via the "popupShow" method, set the isPopup:true option.'); + return; + } + if (this.hideTimeout) { + clearTimeout(this.hideTimeout); + this.hideTimeout = 0; + } + this.$root.dataSM('shown-before', true); + if (canAnimate) { + this.$root.stop(true, true); + } + if (!this.$root.is(':visible')) { + this.$root.css({ left: left, top: top }); + // show menu + var self = this, + complete = function() { + self.$root.css('overflow', ''); + }; + if (canAnimate && this.opts.showFunction) { + this.opts.showFunction.call(this, this.$root, complete); + } else { + this.$root.show(this.opts.showDuration, complete); + } + this.visibleSubMenus[0] = this.$root; + } + }, + refresh: function() { + this.destroy(true); + this.init(true); + }, + rootKeyDown: function(e) { + if (!this.handleEvents()) { + return; + } + switch (e.keyCode) { + case 27: // reset on Esc + var $activeTopItem = this.activatedItems[0]; + if ($activeTopItem) { + this.menuHideAll(); + $activeTopItem[0].focus(); + var $sub = $activeTopItem.dataSM('sub'); + if ($sub) { + this.menuHide($sub); + } + } + break; + case 32: // activate item's sub on Space + var $target = $(e.target); + if ($target.is('a') && this.handleItemEvents($target)) { + var $sub = $target.dataSM('sub'); + if ($sub && !$sub.is(':visible')) { + this.itemClick({ currentTarget: e.target }); + e.preventDefault(); + } + } + break; + } + }, + rootOut: function(e) { + if (!this.handleEvents() || this.isTouchMode() || e.target == this.$root[0]) { + return; + } + if (this.hideTimeout) { + clearTimeout(this.hideTimeout); + this.hideTimeout = 0; + } + if (!this.opts.showOnClick || !this.opts.hideOnClick) { + var self = this; + this.hideTimeout = setTimeout(function() { self.menuHideAll(); }, this.opts.hideTimeout); + } + }, + rootOver: function(e) { + if (!this.handleEvents() || this.isTouchMode() || e.target == this.$root[0]) { + return; + } + if (this.hideTimeout) { + clearTimeout(this.hideTimeout); + this.hideTimeout = 0; + } + }, + winResize: function(e) { + if (!this.handleEvents()) { + // we still need to resize the disable overlay if it's visible + if (this.$disableOverlay) { + var pos = this.$root.offset(); + this.$disableOverlay.css({ + top: pos.top, + left: pos.left, + width: this.$root.outerWidth(), + height: this.$root.outerHeight() + }); + } + return; + } + // hide sub menus on resize - on mobile do it only on orientation change + if (!('onorientationchange' in window) || e.type == 'orientationchange') { + var collapsible = this.isCollapsible(); + // if it was collapsible before resize and still is, don't do it + if (!(this.wasCollapsible && collapsible)) { + if (this.activatedItems.length) { + this.activatedItems[this.activatedItems.length - 1][0].blur(); + } + this.menuHideAll(); + } + this.wasCollapsible = collapsible; + } + } + } + }); + + $.fn.dataSM = function(key, val) { + if (val) { + return this.data(key + '_smartmenus', val); + } + return this.data(key + '_smartmenus'); + }; + + $.fn.removeDataSM = function(key) { + return this.removeData(key + '_smartmenus'); + }; + + $.fn.smartmenus = function(options) { + if (typeof options == 'string') { + var args = arguments, + method = options; + Array.prototype.shift.call(args); + return this.each(function() { + var smartmenus = $(this).data('smartmenus'); + if (smartmenus && smartmenus[method]) { + smartmenus[method].apply(smartmenus, args); + } + }); + } + return this.each(function() { + // [data-sm-options] attribute on the root UL + var dataOpts = $(this).data('sm-options') || null; + if (dataOpts) { + try { + dataOpts = eval('(' + dataOpts + ')'); + } catch(e) { + dataOpts = null; + alert('ERROR\n\nSmartMenus jQuery init:\nInvalid "data-sm-options" attribute value syntax.'); + }; + } + new $.SmartMenus(this, $.extend({}, $.fn.smartmenus.defaults, options, dataOpts)); + }); + }; + + // default settings + $.fn.smartmenus.defaults = { + isPopup: false, // is this a popup menu (can be shown via the popupShow/popupHide methods) or a permanent menu bar + mainMenuSubOffsetX: 0, // pixels offset from default position + mainMenuSubOffsetY: 0, // pixels offset from default position + subMenusSubOffsetX: 0, // pixels offset from default position + subMenusSubOffsetY: 0, // pixels offset from default position + subMenusMinWidth: '10em', // min-width for the sub menus (any CSS unit) - if set, the fixed width set in CSS will be ignored + subMenusMaxWidth: '20em', // max-width for the sub menus (any CSS unit) - if set, the fixed width set in CSS will be ignored + subIndicators: true, // create sub menu indicators - creates a SPAN and inserts it in the A + subIndicatorsPos: 'append', // position of the SPAN relative to the menu item content ('append', 'prepend') + subIndicatorsText: '', // [optionally] add text in the SPAN (e.g. '+') (you may want to check the CSS for the sub indicators too) + scrollStep: 30, // pixels step when scrolling long sub menus that do not fit in the viewport height + scrollAccelerate: true, // accelerate scrolling or use a fixed step + showTimeout: 250, // timeout before showing the sub menus + hideTimeout: 500, // timeout before hiding the sub menus + showDuration: 0, // duration for show animation - set to 0 for no animation - matters only if showFunction:null + showFunction: null, // custom function to use when showing a sub menu (the default is the jQuery 'show') + // don't forget to call complete() at the end of whatever you do + // e.g.: function($ul, complete) { $ul.fadeIn(250, complete); } + hideDuration: 0, // duration for hide animation - set to 0 for no animation - matters only if hideFunction:null + hideFunction: function($ul, complete) { $ul.fadeOut(200, complete); }, // custom function to use when hiding a sub menu (the default is the jQuery 'hide') + // don't forget to call complete() at the end of whatever you do + // e.g.: function($ul, complete) { $ul.fadeOut(250, complete); } + collapsibleShowDuration:0, // duration for show animation for collapsible sub menus - matters only if collapsibleShowFunction:null + collapsibleShowFunction:function($ul, complete) { $ul.slideDown(200, complete); }, // custom function to use when showing a collapsible sub menu + // (i.e. when mobile styles are used to make the sub menus collapsible) + collapsibleHideDuration:0, // duration for hide animation for collapsible sub menus - matters only if collapsibleHideFunction:null + collapsibleHideFunction:function($ul, complete) { $ul.slideUp(200, complete); }, // custom function to use when hiding a collapsible sub menu + // (i.e. when mobile styles are used to make the sub menus collapsible) + showOnClick: false, // show the first-level sub menus onclick instead of onmouseover (i.e. mimic desktop app menus) (matters only for mouse input) + hideOnClick: true, // hide the sub menus on click/tap anywhere on the page + noMouseOver: false, // disable sub menus activation onmouseover (i.e. behave like in touch mode - use just mouse clicks) (matters only for mouse input) + keepInViewport: true, // reposition the sub menus if needed to make sure they always appear inside the viewport + keepHighlighted: true, // keep all ancestor items of the current sub menu highlighted (adds the 'highlighted' class to the A's) + markCurrentItem: false, // automatically add the 'current' class to the A element of the item linking to the current URL + markCurrentTree: true, // add the 'current' class also to the A elements of all ancestor items of the current item + rightToLeftSubMenus: false, // right to left display of the sub menus (check the CSS for the sub indicators' position) + bottomToTopSubMenus: false, // bottom to top display of the sub menus + collapsibleBehavior: 'default' // parent items behavior in collapsible (mobile) view ('default', 'toggle', 'link', 'accordion', 'accordion-toggle', 'accordion-link') + // 'default' - first tap on parent item expands sub, second tap loads its link + // 'toggle' - the whole parent item acts just as a toggle button for its sub menu (expands/collapses on each tap) + // 'link' - the parent item acts as a regular item (first tap loads its link), the sub menu can be expanded only via the +/- button + // 'accordion' - like 'default' but on expand also resets any visible sub menus from deeper levels or other branches + // 'accordion-toggle' - like 'toggle' but on expand also resets any visible sub menus from deeper levels or other branches + // 'accordion-link' - like 'link' but on expand also resets any visible sub menus from deeper levels or other branches + }; + + return $; +})); \ No newline at end of file diff --git a/civicrm/bower_components/smartmenus/dist/jquery.smartmenus.min.js b/civicrm/bower_components/smartmenus/dist/jquery.smartmenus.min.js new file mode 100644 index 0000000000..4f98566504 --- /dev/null +++ b/civicrm/bower_components/smartmenus/dist/jquery.smartmenus.min.js @@ -0,0 +1,3 @@ +/*! SmartMenus jQuery Plugin - v1.1.0 - September 17, 2017 + * http://www.smartmenus.org/ + * Copyright Vasil Dinkov, Vadikom Web Ltd. http://vadikom.com; Licensed MIT */(function(t){"function"==typeof define&&define.amd?define(["jquery"],t):"object"==typeof module&&"object"==typeof module.exports?module.exports=t(require("jquery")):t(jQuery)})(function($){function initMouseDetection(t){var e=".smartmenus_mouse";if(mouseDetectionEnabled||t)mouseDetectionEnabled&&t&&($(document).off(e),mouseDetectionEnabled=!1);else{var i=!0,s=null,o={mousemove:function(t){var e={x:t.pageX,y:t.pageY,timeStamp:(new Date).getTime()};if(s){var o=Math.abs(s.x-e.x),a=Math.abs(s.y-e.y);if((o>0||a>0)&&2>=o&&2>=a&&300>=e.timeStamp-s.timeStamp&&(mouse=!0,i)){var n=$(t.target).closest("a");n.is("a")&&$.each(menuTrees,function(){return $.contains(this.$root[0],n[0])?(this.itemEnter({currentTarget:n[0]}),!1):void 0}),i=!1}}s=e}};o[touchEvents?"touchstart":"pointerover pointermove pointerout MSPointerOver MSPointerMove MSPointerOut"]=function(t){isTouchEvent(t.originalEvent)&&(mouse=!1)},$(document).on(getEventsNS(o,e)),mouseDetectionEnabled=!0}}function isTouchEvent(t){return!/^(4|mouse)$/.test(t.pointerType)}function getEventsNS(t,e){e||(e="");var i={};for(var s in t)i[s.split(" ").join(e+" ")+e]=t[s];return i}var menuTrees=[],mouse=!1,touchEvents="ontouchstart"in window,mouseDetectionEnabled=!1,requestAnimationFrame=window.requestAnimationFrame||function(t){return setTimeout(t,1e3/60)},cancelAnimationFrame=window.cancelAnimationFrame||function(t){clearTimeout(t)},canAnimate=!!$.fn.animate;return $.SmartMenus=function(t,e){this.$root=$(t),this.opts=e,this.rootId="",this.accessIdPrefix="",this.$subArrow=null,this.activatedItems=[],this.visibleSubMenus=[],this.showTimeout=0,this.hideTimeout=0,this.scrollTimeout=0,this.clickActivated=!1,this.focusActivated=!1,this.zIndexInc=0,this.idInc=0,this.$firstLink=null,this.$firstSub=null,this.disabled=!1,this.$disableOverlay=null,this.$touchScrollingSub=null,this.cssTransforms3d="perspective"in t.style||"webkitPerspective"in t.style,this.wasCollapsible=!1,this.init()},$.extend($.SmartMenus,{hideAll:function(){$.each(menuTrees,function(){this.menuHideAll()})},destroy:function(){for(;menuTrees.length;)menuTrees[0].destroy();initMouseDetection(!0)},prototype:{init:function(t){var e=this;if(!t){menuTrees.push(this),this.rootId=((new Date).getTime()+Math.random()+"").replace(/\D/g,""),this.accessIdPrefix="sm-"+this.rootId+"-",this.$root.hasClass("sm-rtl")&&(this.opts.rightToLeftSubMenus=!0);var i=".smartmenus";this.$root.data("smartmenus",this).attr("data-smartmenus-id",this.rootId).dataSM("level",1).on(getEventsNS({"mouseover focusin":$.proxy(this.rootOver,this),"mouseout focusout":$.proxy(this.rootOut,this),keydown:$.proxy(this.rootKeyDown,this)},i)).on(getEventsNS({mouseenter:$.proxy(this.itemEnter,this),mouseleave:$.proxy(this.itemLeave,this),mousedown:$.proxy(this.itemDown,this),focus:$.proxy(this.itemFocus,this),blur:$.proxy(this.itemBlur,this),click:$.proxy(this.itemClick,this)},i),"a"),i+=this.rootId,this.opts.hideOnClick&&$(document).on(getEventsNS({touchstart:$.proxy(this.docTouchStart,this),touchmove:$.proxy(this.docTouchMove,this),touchend:$.proxy(this.docTouchEnd,this),click:$.proxy(this.docClick,this)},i)),$(window).on(getEventsNS({"resize orientationchange":$.proxy(this.winResize,this)},i)),this.opts.subIndicators&&(this.$subArrow=$("<span/>").addClass("sub-arrow"),this.opts.subIndicatorsText&&this.$subArrow.html(this.opts.subIndicatorsText)),initMouseDetection()}if(this.$firstSub=this.$root.find("ul").each(function(){e.menuInit($(this))}).eq(0),this.$firstLink=this.$root.find("a").eq(0),this.opts.markCurrentItem){var s=/(index|default)\.[^#\?\/]*/i,o=/#.*/,a=window.location.href.replace(s,""),n=a.replace(o,"");this.$root.find("a").each(function(){var t=this.href.replace(s,""),i=$(this);(t==a||t==n)&&(i.addClass("current"),e.opts.markCurrentTree&&i.parentsUntil("[data-smartmenus-id]","ul").each(function(){$(this).dataSM("parent-a").addClass("current")}))})}this.wasCollapsible=this.isCollapsible()},destroy:function(t){if(!t){var e=".smartmenus";this.$root.removeData("smartmenus").removeAttr("data-smartmenus-id").removeDataSM("level").off(e),e+=this.rootId,$(document).off(e),$(window).off(e),this.opts.subIndicators&&(this.$subArrow=null)}this.menuHideAll();var i=this;this.$root.find("ul").each(function(){var t=$(this);t.dataSM("scroll-arrows")&&t.dataSM("scroll-arrows").remove(),t.dataSM("shown-before")&&((i.opts.subMenusMinWidth||i.opts.subMenusMaxWidth)&&t.css({width:"",minWidth:"",maxWidth:""}).removeClass("sm-nowrap"),t.dataSM("scroll-arrows")&&t.dataSM("scroll-arrows").remove(),t.css({zIndex:"",top:"",left:"",marginLeft:"",marginTop:"",display:""})),0==(t.attr("id")||"").indexOf(i.accessIdPrefix)&&t.removeAttr("id")}).removeDataSM("in-mega").removeDataSM("shown-before").removeDataSM("scroll-arrows").removeDataSM("parent-a").removeDataSM("level").removeDataSM("beforefirstshowfired").removeAttr("role").removeAttr("aria-hidden").removeAttr("aria-labelledby").removeAttr("aria-expanded"),this.$root.find("a.has-submenu").each(function(){var t=$(this);0==t.attr("id").indexOf(i.accessIdPrefix)&&t.removeAttr("id")}).removeClass("has-submenu").removeDataSM("sub").removeAttr("aria-haspopup").removeAttr("aria-controls").removeAttr("aria-expanded").closest("li").removeDataSM("sub"),this.opts.subIndicators&&this.$root.find("span.sub-arrow").remove(),this.opts.markCurrentItem&&this.$root.find("a.current").removeClass("current"),t||(this.$root=null,this.$firstLink=null,this.$firstSub=null,this.$disableOverlay&&(this.$disableOverlay.remove(),this.$disableOverlay=null),menuTrees.splice($.inArray(this,menuTrees),1))},disable:function(t){if(!this.disabled){if(this.menuHideAll(),!t&&!this.opts.isPopup&&this.$root.is(":visible")){var e=this.$root.offset();this.$disableOverlay=$('<div class="sm-jquery-disable-overlay"/>').css({position:"absolute",top:e.top,left:e.left,width:this.$root.outerWidth(),height:this.$root.outerHeight(),zIndex:this.getStartZIndex(!0),opacity:0}).appendTo(document.body)}this.disabled=!0}},docClick:function(t){return this.$touchScrollingSub?(this.$touchScrollingSub=null,void 0):((this.visibleSubMenus.length&&!$.contains(this.$root[0],t.target)||$(t.target).closest("a").length)&&this.menuHideAll(),void 0)},docTouchEnd:function(){if(this.lastTouch){if(!(!this.visibleSubMenus.length||void 0!==this.lastTouch.x2&&this.lastTouch.x1!=this.lastTouch.x2||void 0!==this.lastTouch.y2&&this.lastTouch.y1!=this.lastTouch.y2||this.lastTouch.target&&$.contains(this.$root[0],this.lastTouch.target))){this.hideTimeout&&(clearTimeout(this.hideTimeout),this.hideTimeout=0);var t=this;this.hideTimeout=setTimeout(function(){t.menuHideAll()},350)}this.lastTouch=null}},docTouchMove:function(t){if(this.lastTouch){var e=t.originalEvent.touches[0];this.lastTouch.x2=e.pageX,this.lastTouch.y2=e.pageY}},docTouchStart:function(t){var e=t.originalEvent.touches[0];this.lastTouch={x1:e.pageX,y1:e.pageY,target:e.target}},enable:function(){this.disabled&&(this.$disableOverlay&&(this.$disableOverlay.remove(),this.$disableOverlay=null),this.disabled=!1)},getClosestMenu:function(t){for(var e=$(t).closest("ul");e.dataSM("in-mega");)e=e.parent().closest("ul");return e[0]||null},getHeight:function(t){return this.getOffset(t,!0)},getOffset:function(t,e){var i;"none"==t.css("display")&&(i={position:t[0].style.position,visibility:t[0].style.visibility},t.css({position:"absolute",visibility:"hidden"}).show());var s=t[0].getBoundingClientRect&&t[0].getBoundingClientRect(),o=s&&(e?s.height||s.bottom-s.top:s.width||s.right-s.left);return o||0===o||(o=e?t[0].offsetHeight:t[0].offsetWidth),i&&t.hide().css(i),o},getStartZIndex:function(t){var e=parseInt(this[t?"$root":"$firstSub"].css("z-index"));return!t&&isNaN(e)&&(e=parseInt(this.$root.css("z-index"))),isNaN(e)?1:e},getTouchPoint:function(t){return t.touches&&t.touches[0]||t.changedTouches&&t.changedTouches[0]||t},getViewport:function(t){var e=t?"Height":"Width",i=document.documentElement["client"+e],s=window["inner"+e];return s&&(i=Math.min(i,s)),i},getViewportHeight:function(){return this.getViewport(!0)},getViewportWidth:function(){return this.getViewport()},getWidth:function(t){return this.getOffset(t)},handleEvents:function(){return!this.disabled&&this.isCSSOn()},handleItemEvents:function(t){return this.handleEvents()&&!this.isLinkInMegaMenu(t)},isCollapsible:function(){return"static"==this.$firstSub.css("position")},isCSSOn:function(){return"inline"!=this.$firstLink.css("display")},isFixed:function(){var t="fixed"==this.$root.css("position");return t||this.$root.parentsUntil("body").each(function(){return"fixed"==$(this).css("position")?(t=!0,!1):void 0}),t},isLinkInMegaMenu:function(t){return $(this.getClosestMenu(t[0])).hasClass("mega-menu")},isTouchMode:function(){return!mouse||this.opts.noMouseOver||this.isCollapsible()},itemActivate:function(t,e){var i=t.closest("ul"),s=i.dataSM("level");if(s>1&&(!this.activatedItems[s-2]||this.activatedItems[s-2][0]!=i.dataSM("parent-a")[0])){var o=this;$(i.parentsUntil("[data-smartmenus-id]","ul").get().reverse()).add(i).each(function(){o.itemActivate($(this).dataSM("parent-a"))})}if((!this.isCollapsible()||e)&&this.menuHideSubMenus(this.activatedItems[s-1]&&this.activatedItems[s-1][0]==t[0]?s:s-1),this.activatedItems[s-1]=t,this.$root.triggerHandler("activate.smapi",t[0])!==!1){var a=t.dataSM("sub");a&&(this.isTouchMode()||!this.opts.showOnClick||this.clickActivated)&&this.menuShow(a)}},itemBlur:function(t){var e=$(t.currentTarget);this.handleItemEvents(e)&&this.$root.triggerHandler("blur.smapi",e[0])},itemClick:function(t){var e=$(t.currentTarget);if(this.handleItemEvents(e)){if(this.$touchScrollingSub&&this.$touchScrollingSub[0]==e.closest("ul")[0])return this.$touchScrollingSub=null,t.stopPropagation(),!1;if(this.$root.triggerHandler("click.smapi",e[0])===!1)return!1;var i=$(t.target).is(".sub-arrow"),s=e.dataSM("sub"),o=s?2==s.dataSM("level"):!1,a=this.isCollapsible(),n=/toggle$/.test(this.opts.collapsibleBehavior),r=/link$/.test(this.opts.collapsibleBehavior),h=/^accordion/.test(this.opts.collapsibleBehavior);if(s&&!s.is(":visible")){if((!r||!a||i)&&(this.opts.showOnClick&&o&&(this.clickActivated=!0),this.itemActivate(e,h),s.is(":visible")))return this.focusActivated=!0,!1}else if(a&&(n||i))return this.itemActivate(e,h),this.menuHide(s),n&&(this.focusActivated=!1),!1;return this.opts.showOnClick&&o||e.hasClass("disabled")||this.$root.triggerHandler("select.smapi",e[0])===!1?!1:void 0}},itemDown:function(t){var e=$(t.currentTarget);this.handleItemEvents(e)&&e.dataSM("mousedown",!0)},itemEnter:function(t){var e=$(t.currentTarget);if(this.handleItemEvents(e)){if(!this.isTouchMode()){this.showTimeout&&(clearTimeout(this.showTimeout),this.showTimeout=0);var i=this;this.showTimeout=setTimeout(function(){i.itemActivate(e)},this.opts.showOnClick&&1==e.closest("ul").dataSM("level")?1:this.opts.showTimeout)}this.$root.triggerHandler("mouseenter.smapi",e[0])}},itemFocus:function(t){var e=$(t.currentTarget);this.handleItemEvents(e)&&(!this.focusActivated||this.isTouchMode()&&e.dataSM("mousedown")||this.activatedItems.length&&this.activatedItems[this.activatedItems.length-1][0]==e[0]||this.itemActivate(e,!0),this.$root.triggerHandler("focus.smapi",e[0]))},itemLeave:function(t){var e=$(t.currentTarget);this.handleItemEvents(e)&&(this.isTouchMode()||(e[0].blur(),this.showTimeout&&(clearTimeout(this.showTimeout),this.showTimeout=0)),e.removeDataSM("mousedown"),this.$root.triggerHandler("mouseleave.smapi",e[0]))},menuHide:function(t){if(this.$root.triggerHandler("beforehide.smapi",t[0])!==!1&&(canAnimate&&t.stop(!0,!0),"none"!=t.css("display"))){var e=function(){t.css("z-index","")};this.isCollapsible()?canAnimate&&this.opts.collapsibleHideFunction?this.opts.collapsibleHideFunction.call(this,t,e):t.hide(this.opts.collapsibleHideDuration,e):canAnimate&&this.opts.hideFunction?this.opts.hideFunction.call(this,t,e):t.hide(this.opts.hideDuration,e),t.dataSM("scroll")&&(this.menuScrollStop(t),t.css({"touch-action":"","-ms-touch-action":"","-webkit-transform":"",transform:""}).off(".smartmenus_scroll").removeDataSM("scroll").dataSM("scroll-arrows").hide()),t.dataSM("parent-a").removeClass("highlighted").attr("aria-expanded","false"),t.attr({"aria-expanded":"false","aria-hidden":"true"});var i=t.dataSM("level");this.activatedItems.splice(i-1,1),this.visibleSubMenus.splice($.inArray(t,this.visibleSubMenus),1),this.$root.triggerHandler("hide.smapi",t[0])}},menuHideAll:function(){this.showTimeout&&(clearTimeout(this.showTimeout),this.showTimeout=0);for(var t=this.opts.isPopup?1:0,e=this.visibleSubMenus.length-1;e>=t;e--)this.menuHide(this.visibleSubMenus[e]);this.opts.isPopup&&(canAnimate&&this.$root.stop(!0,!0),this.$root.is(":visible")&&(canAnimate&&this.opts.hideFunction?this.opts.hideFunction.call(this,this.$root):this.$root.hide(this.opts.hideDuration))),this.activatedItems=[],this.visibleSubMenus=[],this.clickActivated=!1,this.focusActivated=!1,this.zIndexInc=0,this.$root.triggerHandler("hideAll.smapi")},menuHideSubMenus:function(t){for(var e=this.activatedItems.length-1;e>=t;e--){var i=this.activatedItems[e].dataSM("sub");i&&this.menuHide(i)}},menuInit:function(t){if(!t.dataSM("in-mega")){t.hasClass("mega-menu")&&t.find("ul").dataSM("in-mega",!0);for(var e=2,i=t[0];(i=i.parentNode.parentNode)!=this.$root[0];)e++;var s=t.prevAll("a").eq(-1);s.length||(s=t.prevAll().find("a").eq(-1)),s.addClass("has-submenu").dataSM("sub",t),t.dataSM("parent-a",s).dataSM("level",e).parent().dataSM("sub",t);var o=s.attr("id")||this.accessIdPrefix+ ++this.idInc,a=t.attr("id")||this.accessIdPrefix+ ++this.idInc;s.attr({id:o,"aria-haspopup":"true","aria-controls":a,"aria-expanded":"false"}),t.attr({id:a,role:"group","aria-hidden":"true","aria-labelledby":o,"aria-expanded":"false"}),this.opts.subIndicators&&s[this.opts.subIndicatorsPos](this.$subArrow.clone())}},menuPosition:function(t){var e,i,s=t.dataSM("parent-a"),o=s.closest("li"),a=o.parent(),n=t.dataSM("level"),r=this.getWidth(t),h=this.getHeight(t),u=s.offset(),l=u.left,c=u.top,d=this.getWidth(s),m=this.getHeight(s),p=$(window),f=p.scrollLeft(),v=p.scrollTop(),b=this.getViewportWidth(),S=this.getViewportHeight(),g=a.parent().is("[data-sm-horizontal-sub]")||2==n&&!a.hasClass("sm-vertical"),M=this.opts.rightToLeftSubMenus&&!o.is("[data-sm-reverse]")||!this.opts.rightToLeftSubMenus&&o.is("[data-sm-reverse]"),w=2==n?this.opts.mainMenuSubOffsetX:this.opts.subMenusSubOffsetX,T=2==n?this.opts.mainMenuSubOffsetY:this.opts.subMenusSubOffsetY;if(g?(e=M?d-r-w:w,i=this.opts.bottomToTopSubMenus?-h-T:m+T):(e=M?w-r:d-w,i=this.opts.bottomToTopSubMenus?m-T-h:T),this.opts.keepInViewport){var y=l+e,I=c+i;if(M&&f>y?e=g?f-y+e:d-w:!M&&y+r>f+b&&(e=g?f+b-r-y+e:w-r),g||(S>h&&I+h>v+S?i+=v+S-h-I:(h>=S||v>I)&&(i+=v-I)),g&&(I+h>v+S+.49||v>I)||!g&&h>S+.49){var x=this;t.dataSM("scroll-arrows")||t.dataSM("scroll-arrows",$([$('<span class="scroll-up"><span class="scroll-up-arrow"></span></span>')[0],$('<span class="scroll-down"><span class="scroll-down-arrow"></span></span>')[0]]).on({mouseenter:function(){t.dataSM("scroll").up=$(this).hasClass("scroll-up"),x.menuScroll(t)},mouseleave:function(e){x.menuScrollStop(t),x.menuScrollOut(t,e)},"mousewheel DOMMouseScroll":function(t){t.preventDefault()}}).insertAfter(t));var A=".smartmenus_scroll";if(t.dataSM("scroll",{y:this.cssTransforms3d?0:i-m,step:1,itemH:m,subH:h,arrowDownH:this.getHeight(t.dataSM("scroll-arrows").eq(1))}).on(getEventsNS({mouseover:function(e){x.menuScrollOver(t,e)},mouseout:function(e){x.menuScrollOut(t,e)},"mousewheel DOMMouseScroll":function(e){x.menuScrollMousewheel(t,e)}},A)).dataSM("scroll-arrows").css({top:"auto",left:"0",marginLeft:e+(parseInt(t.css("border-left-width"))||0),width:r-(parseInt(t.css("border-left-width"))||0)-(parseInt(t.css("border-right-width"))||0),zIndex:t.css("z-index")}).eq(g&&this.opts.bottomToTopSubMenus?0:1).show(),this.isFixed()){var C={};C[touchEvents?"touchstart touchmove touchend":"pointerdown pointermove pointerup MSPointerDown MSPointerMove MSPointerUp"]=function(e){x.menuScrollTouch(t,e)},t.css({"touch-action":"none","-ms-touch-action":"none"}).on(getEventsNS(C,A))}}}t.css({top:"auto",left:"0",marginLeft:e,marginTop:i-m})},menuScroll:function(t,e,i){var s,o=t.dataSM("scroll"),a=t.dataSM("scroll-arrows"),n=o.up?o.upEnd:o.downEnd;if(!e&&o.momentum){if(o.momentum*=.92,s=o.momentum,.5>s)return this.menuScrollStop(t),void 0}else s=i||(e||!this.opts.scrollAccelerate?this.opts.scrollStep:Math.floor(o.step));var r=t.dataSM("level");if(this.activatedItems[r-1]&&this.activatedItems[r-1].dataSM("sub")&&this.activatedItems[r-1].dataSM("sub").is(":visible")&&this.menuHideSubMenus(r-1),o.y=o.up&&o.y>=n||!o.up&&n>=o.y?o.y:Math.abs(n-o.y)>s?o.y+(o.up?s:-s):n,t.css(this.cssTransforms3d?{"-webkit-transform":"translate3d(0, "+o.y+"px, 0)",transform:"translate3d(0, "+o.y+"px, 0)"}:{marginTop:o.y}),mouse&&(o.up&&o.y>o.downEnd||!o.up&&o.y<o.upEnd)&&a.eq(o.up?1:0).show(),o.y==n)mouse&&a.eq(o.up?0:1).hide(),this.menuScrollStop(t);else if(!e){this.opts.scrollAccelerate&&o.step<this.opts.scrollStep&&(o.step+=.2);var h=this;this.scrollTimeout=requestAnimationFrame(function(){h.menuScroll(t)})}},menuScrollMousewheel:function(t,e){if(this.getClosestMenu(e.target)==t[0]){e=e.originalEvent;var i=(e.wheelDelta||-e.detail)>0;t.dataSM("scroll-arrows").eq(i?0:1).is(":visible")&&(t.dataSM("scroll").up=i,this.menuScroll(t,!0))}e.preventDefault()},menuScrollOut:function(t,e){mouse&&(/^scroll-(up|down)/.test((e.relatedTarget||"").className)||(t[0]==e.relatedTarget||$.contains(t[0],e.relatedTarget))&&this.getClosestMenu(e.relatedTarget)==t[0]||t.dataSM("scroll-arrows").css("visibility","hidden"))},menuScrollOver:function(t,e){if(mouse&&!/^scroll-(up|down)/.test(e.target.className)&&this.getClosestMenu(e.target)==t[0]){this.menuScrollRefreshData(t);var i=t.dataSM("scroll"),s=$(window).scrollTop()-t.dataSM("parent-a").offset().top-i.itemH;t.dataSM("scroll-arrows").eq(0).css("margin-top",s).end().eq(1).css("margin-top",s+this.getViewportHeight()-i.arrowDownH).end().css("visibility","visible")}},menuScrollRefreshData:function(t){var e=t.dataSM("scroll"),i=$(window).scrollTop()-t.dataSM("parent-a").offset().top-e.itemH;this.cssTransforms3d&&(i=-(parseFloat(t.css("margin-top"))-i)),$.extend(e,{upEnd:i,downEnd:i+this.getViewportHeight()-e.subH})},menuScrollStop:function(t){return this.scrollTimeout?(cancelAnimationFrame(this.scrollTimeout),this.scrollTimeout=0,t.dataSM("scroll").step=1,!0):void 0},menuScrollTouch:function(t,e){if(e=e.originalEvent,isTouchEvent(e)){var i=this.getTouchPoint(e);if(this.getClosestMenu(i.target)==t[0]){var s=t.dataSM("scroll");if(/(start|down)$/i.test(e.type))this.menuScrollStop(t)?(e.preventDefault(),this.$touchScrollingSub=t):this.$touchScrollingSub=null,this.menuScrollRefreshData(t),$.extend(s,{touchStartY:i.pageY,touchStartTime:e.timeStamp});else if(/move$/i.test(e.type)){var o=void 0!==s.touchY?s.touchY:s.touchStartY;if(void 0!==o&&o!=i.pageY){this.$touchScrollingSub=t;var a=i.pageY>o;void 0!==s.up&&s.up!=a&&$.extend(s,{touchStartY:i.pageY,touchStartTime:e.timeStamp}),$.extend(s,{up:a,touchY:i.pageY}),this.menuScroll(t,!0,Math.abs(i.pageY-o))}e.preventDefault()}else void 0!==s.touchY&&((s.momentum=15*Math.pow(Math.abs(i.pageY-s.touchStartY)/(e.timeStamp-s.touchStartTime),2))&&(this.menuScrollStop(t),this.menuScroll(t),e.preventDefault()),delete s.touchY)}}},menuShow:function(t){if((t.dataSM("beforefirstshowfired")||(t.dataSM("beforefirstshowfired",!0),this.$root.triggerHandler("beforefirstshow.smapi",t[0])!==!1))&&this.$root.triggerHandler("beforeshow.smapi",t[0])!==!1&&(t.dataSM("shown-before",!0),canAnimate&&t.stop(!0,!0),!t.is(":visible"))){var e=t.dataSM("parent-a"),i=this.isCollapsible();if((this.opts.keepHighlighted||i)&&e.addClass("highlighted"),i)t.removeClass("sm-nowrap").css({zIndex:"",width:"auto",minWidth:"",maxWidth:"",top:"",left:"",marginLeft:"",marginTop:""});else{if(t.css("z-index",this.zIndexInc=(this.zIndexInc||this.getStartZIndex())+1),(this.opts.subMenusMinWidth||this.opts.subMenusMaxWidth)&&(t.css({width:"auto",minWidth:"",maxWidth:""}).addClass("sm-nowrap"),this.opts.subMenusMinWidth&&t.css("min-width",this.opts.subMenusMinWidth),this.opts.subMenusMaxWidth)){var s=this.getWidth(t);t.css("max-width",this.opts.subMenusMaxWidth),s>this.getWidth(t)&&t.removeClass("sm-nowrap").css("width",this.opts.subMenusMaxWidth)}this.menuPosition(t)}var o=function(){t.css("overflow","")};i?canAnimate&&this.opts.collapsibleShowFunction?this.opts.collapsibleShowFunction.call(this,t,o):t.show(this.opts.collapsibleShowDuration,o):canAnimate&&this.opts.showFunction?this.opts.showFunction.call(this,t,o):t.show(this.opts.showDuration,o),e.attr("aria-expanded","true"),t.attr({"aria-expanded":"true","aria-hidden":"false"}),this.visibleSubMenus.push(t),this.$root.triggerHandler("show.smapi",t[0])}},popupHide:function(t){this.hideTimeout&&(clearTimeout(this.hideTimeout),this.hideTimeout=0);var e=this;this.hideTimeout=setTimeout(function(){e.menuHideAll()},t?1:this.opts.hideTimeout)},popupShow:function(t,e){if(!this.opts.isPopup)return alert('SmartMenus jQuery Error:\n\nIf you want to show this menu via the "popupShow" method, set the isPopup:true option.'),void 0;if(this.hideTimeout&&(clearTimeout(this.hideTimeout),this.hideTimeout=0),this.$root.dataSM("shown-before",!0),canAnimate&&this.$root.stop(!0,!0),!this.$root.is(":visible")){this.$root.css({left:t,top:e});var i=this,s=function(){i.$root.css("overflow","")};canAnimate&&this.opts.showFunction?this.opts.showFunction.call(this,this.$root,s):this.$root.show(this.opts.showDuration,s),this.visibleSubMenus[0]=this.$root}},refresh:function(){this.destroy(!0),this.init(!0)},rootKeyDown:function(t){if(this.handleEvents())switch(t.keyCode){case 27:var e=this.activatedItems[0];if(e){this.menuHideAll(),e[0].focus();var i=e.dataSM("sub");i&&this.menuHide(i)}break;case 32:var s=$(t.target);if(s.is("a")&&this.handleItemEvents(s)){var i=s.dataSM("sub");i&&!i.is(":visible")&&(this.itemClick({currentTarget:t.target}),t.preventDefault())}}},rootOut:function(t){if(this.handleEvents()&&!this.isTouchMode()&&t.target!=this.$root[0]&&(this.hideTimeout&&(clearTimeout(this.hideTimeout),this.hideTimeout=0),!this.opts.showOnClick||!this.opts.hideOnClick)){var e=this;this.hideTimeout=setTimeout(function(){e.menuHideAll()},this.opts.hideTimeout)}},rootOver:function(t){this.handleEvents()&&!this.isTouchMode()&&t.target!=this.$root[0]&&this.hideTimeout&&(clearTimeout(this.hideTimeout),this.hideTimeout=0)},winResize:function(t){if(this.handleEvents()){if(!("onorientationchange"in window)||"orientationchange"==t.type){var e=this.isCollapsible();this.wasCollapsible&&e||(this.activatedItems.length&&this.activatedItems[this.activatedItems.length-1][0].blur(),this.menuHideAll()),this.wasCollapsible=e}}else if(this.$disableOverlay){var i=this.$root.offset();this.$disableOverlay.css({top:i.top,left:i.left,width:this.$root.outerWidth(),height:this.$root.outerHeight()})}}}}),$.fn.dataSM=function(t,e){return e?this.data(t+"_smartmenus",e):this.data(t+"_smartmenus")},$.fn.removeDataSM=function(t){return this.removeData(t+"_smartmenus")},$.fn.smartmenus=function(options){if("string"==typeof options){var args=arguments,method=options;return Array.prototype.shift.call(args),this.each(function(){var t=$(this).data("smartmenus");t&&t[method]&&t[method].apply(t,args)})}return this.each(function(){var dataOpts=$(this).data("sm-options")||null;if(dataOpts)try{dataOpts=eval("("+dataOpts+")")}catch(e){dataOpts=null,alert('ERROR\n\nSmartMenus jQuery init:\nInvalid "data-sm-options" attribute value syntax.')}new $.SmartMenus(this,$.extend({},$.fn.smartmenus.defaults,options,dataOpts))})},$.fn.smartmenus.defaults={isPopup:!1,mainMenuSubOffsetX:0,mainMenuSubOffsetY:0,subMenusSubOffsetX:0,subMenusSubOffsetY:0,subMenusMinWidth:"10em",subMenusMaxWidth:"20em",subIndicators:!0,subIndicatorsPos:"append",subIndicatorsText:"",scrollStep:30,scrollAccelerate:!0,showTimeout:250,hideTimeout:500,showDuration:0,showFunction:null,hideDuration:0,hideFunction:function(t,e){t.fadeOut(200,e)},collapsibleShowDuration:0,collapsibleShowFunction:function(t,e){t.slideDown(200,e)},collapsibleHideDuration:0,collapsibleHideFunction:function(t,e){t.slideUp(200,e)},showOnClick:!1,hideOnClick:!0,noMouseOver:!1,keepInViewport:!0,keepHighlighted:!0,markCurrentItem:!1,markCurrentTree:!0,rightToLeftSubMenus:!1,bottomToTopSubMenus:!1,collapsibleBehavior:"default"},$}); \ No newline at end of file diff --git a/civicrm/bower_components/smartmenus/package.json b/civicrm/bower_components/smartmenus/package.json new file mode 100644 index 0000000000..aa751def0b --- /dev/null +++ b/civicrm/bower_components/smartmenus/package.json @@ -0,0 +1,53 @@ +{ + "name": "smartmenus", + "title": "SmartMenus", + "description": "Advanced jQuery website menu plugin. Mobile first, responsive and accessible list-based website menus that work on all devices.", + "keywords": [ + "menu", + "navigation", + "accessible", + "responsive", + "mobile", + "ui", + "jquery-plugin", + "bootstrap", + "ecosystem:jquery" + ], + "version": "1.1.0", + "version_keyboard_addon": "0.4.0", + "version_bootstrap_addon": "0.4.0", + "version_bootstrap_4_addon": "0.1.0", + "main": "dist/jquery.smartmenus.js", + "author": { + "name": "Vasil Dinkov", + "email": "vasko.dinkov@gmail.com", + "url": "http://vadikom.com" + }, + "licenses": [ + { + "type": "MIT", + "url": "http://www.opensource.org/licenses/MIT" + } + ], + "repository": { + "type": "git", + "url": "git://github.com/vadikom/smartmenus.git" + }, + "bugs": "https://github.com/vadikom/smartmenus/issues", + "homepage": "http://www.smartmenus.org/", + "docs": "http://www.smartmenus.org/docs/", + "download": "http://www.smartmenus.org/download/", + "dependencies": { + "jquery": ">=1.7.0" + }, + "devDependencies": { + "grunt": "~0.4.1", + "grunt-contrib-clean": "~0.4.0", + "grunt-contrib-concat": "~0.1.2", + "grunt-contrib-copy": "~0.4.1", + "grunt-contrib-sass": "^1.0.0", + "grunt-contrib-uglify": "~0.1.1", + "grunt-contrib-watch": "^1.0.0", + "grunt-zip": "~0.7.0" + } +} diff --git a/civicrm/bower_components/smartmenus/smartmenus.jquery.json b/civicrm/bower_components/smartmenus/smartmenus.jquery.json new file mode 100644 index 0000000000..87000ceb1e --- /dev/null +++ b/civicrm/bower_components/smartmenus/smartmenus.jquery.json @@ -0,0 +1,42 @@ +{ + "name": "smartmenus", + "title": "SmartMenus", + "description": "Advanced jQuery website menu plugin. Mobile first, responsive and accessible list-based website menus that work on all devices.", + "keywords": [ + "menu", + "navigation", + "accessible", + "responsive", + "mobile", + "ui", + "jquery-plugin", + "bootstrap", + "ecosystem:jquery" + ], + "version": "1.1.0", + "version_keyboard_addon": "0.4.0", + "version_bootstrap_addon": "0.4.0", + "version_bootstrap_4_addon": "0.1.0", + "author": { + "name": "Vasil Dinkov", + "email": "vasko.dinkov@gmail.com", + "url": "http://vadikom.com" + }, + "licenses": [ + { + "type": "MIT", + "url": "http://www.opensource.org/licenses/MIT" + } + ], + "repository": { + "type": "git", + "url": "git://github.com/vadikom/smartmenus.git" + }, + "bugs": "https://github.com/vadikom/smartmenus/issues", + "homepage": "http://www.smartmenus.org/", + "docs": "http://www.smartmenus.org/docs/", + "download": "http://www.smartmenus.org/download/", + "dependencies": { + "jquery": ">=1.7.0" + } +} diff --git a/civicrm/bower_components/smartmenus/src/addons/bootstrap-4/jquery.smartmenus.bootstrap-4.css b/civicrm/bower_components/smartmenus/src/addons/bootstrap-4/jquery.smartmenus.bootstrap-4.css new file mode 100644 index 0000000000..f4ae564a1f --- /dev/null +++ b/civicrm/bower_components/smartmenus/src/addons/bootstrap-4/jquery.smartmenus.bootstrap-4.css @@ -0,0 +1,128 @@ +/* + You probably do not need to edit this at all. + + Add some SmartMenus required styles not covered in Bootstrap 4's default CSS. + These are theme independent and should work with any Bootstrap 4 theme mod. +*/ + + +/* Carets in collapsible mode (make them look like +/- buttons) */ +.navbar-nav.sm-collapsible .sub-arrow { + position: absolute; + top: 50%; + right: 0; + margin: -0.7em 0.5em 0 0; + border: 1px solid rgba(0, 0, 0, .1); + border-radius: .25rem; + padding: 0; + width: 2em; + height: 1.4em; + font-size: 1.25rem; + line-height: 1.2em; + text-align: center; +} +.navbar-nav.sm-collapsible .sub-arrow::before { + content: '+'; +} +.navbar-nav.sm-collapsible .show > a > .sub-arrow::before { + content: '-'; +} +.navbar-dark .navbar-nav.sm-collapsible .nav-link .sub-arrow { + border-color: rgba(255, 255, 255, .1); +} +/* make sure there's room for the carets */ +.navbar-nav.sm-collapsible .has-submenu { + padding-right: 3em; +} +/* keep the carets properly positioned */ +.navbar-nav.sm-collapsible .nav-link, +.navbar-nav.sm-collapsible .dropdown-item { + position: relative; +} + + +/* Nav carets in expanded mode */ +.navbar-nav:not(.sm-collapsible) .nav-link .sub-arrow { + display: inline-block; + width: 0; + height: 0; + margin-left: .255em; + vertical-align: .255em; + border-top: .3em solid; + border-right: .3em solid transparent; + border-left: .3em solid transparent; +} +/* point the arrows up for .fixed-bottom navbars */ +.fixed-bottom .navbar-nav:not(.sm-collapsible) .nav-link .sub-arrow, +.fixed-bottom .navbar-nav:not(.sm-collapsible):not([data-sm-skip]) .dropdown-toggle::after { + border-top: 0; + border-bottom: .3em solid; +} + + +/* Dropdown carets in expanded mode */ +.navbar-nav:not(.sm-collapsible) .dropdown-item .sub-arrow, +.navbar-nav:not(.sm-collapsible):not([data-sm-skip]) .dropdown-menu .dropdown-toggle::after { + position: absolute; + top: 50%; + right: 0; + width: 0; + height: 0; + margin-top: -.3em; + margin-right: 1em; + border-top: .3em solid transparent; + border-bottom: .3em solid transparent; + border-left: .3em solid; +} +/* make sure there's room for the carets */ +.navbar-nav:not(.sm-collapsible) .dropdown-item.has-submenu { + padding-right: 2em; +} + + +/* Scrolling arrows for tall menus */ +.navbar-nav .scroll-up, +.navbar-nav .scroll-down { + position: absolute; + display: none; + visibility: hidden; + height: 20px; + overflow: hidden; + text-align: center; +} +.navbar-nav .scroll-up-arrow, +.navbar-nav .scroll-down-arrow { + position: absolute; + top: -2px; + left: 50%; + margin-left: -8px; + width: 0; + height: 0; + overflow: hidden; + border-top: 7px solid transparent; + border-right: 7px solid transparent; + border-bottom: 7px solid; + border-left: 7px solid transparent; +} +.navbar-nav .scroll-down-arrow { + top: 6px; + border-top: 7px solid; + border-right: 7px solid transparent; + border-bottom: 7px solid transparent; + border-left: 7px solid transparent; +} + + +/* Add some spacing for 2+ level sub menus in collapsible mode */ +.navbar-nav.sm-collapsible .dropdown-menu .dropdown-menu { + margin: .5em; +} + + +/* Fix SmartMenus sub menus auto width (subMenusMinWidth/subMenusMaxWidth options) */ +.navbar-nav:not([data-sm-skip]) .dropdown-item { + white-space: normal; +} +.navbar-nav:not(.sm-collapsible) .sm-nowrap > li > .dropdown-item { + white-space: nowrap; +} \ No newline at end of file diff --git a/civicrm/bower_components/smartmenus/src/addons/bootstrap-4/jquery.smartmenus.bootstrap-4.js b/civicrm/bower_components/smartmenus/src/addons/bootstrap-4/jquery.smartmenus.bootstrap-4.js new file mode 100644 index 0000000000..dd53469cee --- /dev/null +++ b/civicrm/bower_components/smartmenus/src/addons/bootstrap-4/jquery.smartmenus.bootstrap-4.js @@ -0,0 +1,167 @@ +/* + * SmartMenus jQuery Bootstrap 4 Addon - v0.1.0 + * http://www.smartmenus.org/ + * + * Copyright Vasil Dinkov, Vadikom Web Ltd. + * http://vadikom.com/ + * + * Released under the MIT license: + * http://www.opensource.org/licenses/MIT + */ + +(function(factory) { + if (typeof define === 'function' && define.amd) { + // AMD + define(['jquery', 'smartmenus'], factory); + } else if (typeof module === 'object' && typeof module.exports === 'object') { + // CommonJS + module.exports = factory(require('jquery')); + } else { + // Global jQuery + factory(jQuery); + } +} (function($) { + + $.extend($.SmartMenus.Bootstrap = {}, { + keydownFix: false, + init: function() { + // init all navbars that don't have the "data-sm-skip" attribute set + var $navbars = $('ul.navbar-nav:not([data-sm-skip])'); + $navbars.each(function() { + var $this = $(this), + obj = $this.data('smartmenus'); + // if this navbar is not initialized + if (!obj) { + var skipBehavior = $this.is('[data-sm-skip-collapsible-behavior]'), + rightAligned = $this.hasClass('ml-auto') || $this.prevAll('.mr-auto').length > 0; + + $this.smartmenus({ + // these are some good default options that should work for all + subMenusSubOffsetX: 2, + subMenusSubOffsetY: -9, + subIndicators: !skipBehavior, + collapsibleShowFunction: null, + collapsibleHideFunction: null, + rightToLeftSubMenus: rightAligned, + bottomToTopSubMenus: $this.closest('.fixed-bottom').length > 0, + // custom option(s) for the Bootstrap 4 addon + bootstrapHighlightClasses: 'text-dark bg-light' + }) + .on({ + // set/unset proper Bootstrap classes for some menu elements + 'show.smapi': function(e, menu) { + var $menu = $(menu), + $scrollArrows = $menu.dataSM('scroll-arrows'); + if ($scrollArrows) { + $scrollArrows.css('background-color', $menu.css('background-color')); + } + $menu.parent().addClass('show'); + if (obj.opts.keepHighlighted && $menu.dataSM('level') > 2) { + $menu.prevAll('a').addClass(obj.opts.bootstrapHighlightClasses); + } + }, + 'hide.smapi': function(e, menu) { + var $menu = $(menu); + $menu.parent().removeClass('show'); + if (obj.opts.keepHighlighted && $menu.dataSM('level') > 2) { + $menu.prevAll('a').removeClass(obj.opts.bootstrapHighlightClasses); + } + } + }); + + obj = $this.data('smartmenus'); + + function onInit() { + // set Bootstrap's "active" class to SmartMenus "current" items (should someone decide to enable markCurrentItem: true) + $this.find('a.current').each(function() { + var $this = $(this); + // dropdown items require the class to be set to the A's while for nav items it should be set to the parent LI's + ($this.hasClass('dropdown-item') ? $this : $this.parent()).addClass('active'); + }); + // parent items fixes + $this.find('a.has-submenu').each(function() { + var $this = $(this); + // remove Bootstrap required attributes that might cause conflicting issues with the SmartMenus script + if ($this.is('[data-toggle="dropdown"]')) { + $this.dataSM('bs-data-toggle-dropdown', true).removeAttr('data-toggle'); + } + // remove Bootstrap's carets generating class + if (!skipBehavior && $this.hasClass('dropdown-toggle')) { + $this.dataSM('bs-dropdown-toggle', true).removeClass('dropdown-toggle'); + } + }); + } + + onInit(); + + function onBeforeDestroy() { + $this.find('a.current').each(function() { + var $this = $(this); + ($this.hasClass('active') ? $this : $this.parent()).removeClass('active'); + }); + $this.find('a.has-submenu').each(function() { + var $this = $(this); + if ($this.dataSM('bs-dropdown-toggle')) { + $this.addClass('dropdown-toggle').removeDataSM('bs-dropdown-toggle'); + } + if ($this.dataSM('bs-data-toggle-dropdown')) { + $this.attr('data-toggle', 'dropdown').removeDataSM('bs-data-toggle-dropdown'); + } + }); + } + + // custom "refresh" method for Bootstrap + obj.refresh = function() { + $.SmartMenus.prototype.refresh.call(this); + onInit(); + // update collapsible detection + detectCollapsible(true); + }; + + // custom "destroy" method for Bootstrap + obj.destroy = function(refresh) { + onBeforeDestroy(); + $.SmartMenus.prototype.destroy.call(this, refresh); + }; + + // keep Bootstrap's default behavior (i.e. use the whole item area just as a sub menu toggle) + if (skipBehavior) { + obj.opts.collapsibleBehavior = 'toggle'; + } + + // onresize detect when the navbar becomes collapsible and add it the "sm-collapsible" class + var winW; + function detectCollapsible(force) { + var newW = obj.getViewportWidth(); + if (newW != winW || force) { + if (obj.isCollapsible()) { + $this.addClass('sm-collapsible'); + } else { + $this.removeClass('sm-collapsible'); + } + winW = newW; + } + } + detectCollapsible(); + $(window).on('resize.smartmenus' + obj.rootId, detectCollapsible); + } + }); + // keydown fix for Bootstrap 4 conflict + if ($navbars.length && !$.SmartMenus.Bootstrap.keydownFix) { + // unhook BS keydown handler for all dropdowns + $(document).off('keydown.bs.dropdown.data-api', '.dropdown-menu'); + // restore BS keydown handler for dropdowns that are not inside SmartMenus navbars + // SmartMenus won't add the "show" class so it's handy here + if ($.fn.dropdown && $.fn.dropdown.Constructor) { + $(document).on('keydown.bs.dropdown.data-api', '.dropdown-menu.show', $.fn.dropdown.Constructor._dataApiKeydownHandler); + } + $.SmartMenus.Bootstrap.keydownFix = true; + } + } + }); + + // init ondomready + $($.SmartMenus.Bootstrap.init); + + return $; +})); diff --git a/civicrm/bower_components/smartmenus/src/addons/bootstrap/jquery.smartmenus.bootstrap.css b/civicrm/bower_components/smartmenus/src/addons/bootstrap/jquery.smartmenus.bootstrap.css new file mode 100644 index 0000000000..8407ce1be0 --- /dev/null +++ b/civicrm/bower_components/smartmenus/src/addons/bootstrap/jquery.smartmenus.bootstrap.css @@ -0,0 +1,122 @@ +/* + You probably do not need to edit this at all. + + Add some SmartMenus required styles not covered in Bootstrap 3's default CSS. + These are theme independent and should work with any Bootstrap 3 theme mod. +*/ +/* sub menus arrows on desktop */ +.navbar-nav:not(.sm-collapsible) ul .caret { + position: absolute; + right: 0; + margin-top: 6px; + margin-right: 15px; + border-top: 4px solid transparent; + border-bottom: 4px solid transparent; + border-left: 4px dashed; +} +.navbar-nav:not(.sm-collapsible) ul a.has-submenu { + padding-right: 30px; +} +/* make sub menu arrows look like +/- buttons in collapsible mode */ +.navbar-nav.sm-collapsible .caret, .navbar-nav.sm-collapsible ul .caret { + position: absolute; + right: 0; + margin: -3px 15px 0 0; + padding: 0; + width: 32px; + height: 26px; + line-height: 24px; + text-align: center; + border-width: 1px; + border-style: solid; +} +.navbar-nav.sm-collapsible .caret:before { + content: '+'; + font-family: monospace; + font-weight: bold; +} +.navbar-nav.sm-collapsible .open > a > .caret:before { + content: '-'; +} +.navbar-nav.sm-collapsible a.has-submenu { + padding-right: 50px; +} +/* revert to Bootstrap's default carets in collapsible mode when the "data-sm-skip-collapsible-behavior" attribute is set to the ul.navbar-nav */ +.navbar-nav.sm-collapsible[data-sm-skip-collapsible-behavior] .caret, .navbar-nav.sm-collapsible[data-sm-skip-collapsible-behavior] ul .caret { + position: static; + margin: 0 0 0 2px; + padding: 0; + width: 0; + height: 0; + border-top: 4px dashed; + border-right: 4px solid transparent; + border-bottom: 0; + border-left: 4px solid transparent; +} +.navbar-nav.sm-collapsible[data-sm-skip-collapsible-behavior] .caret:before { + content: '' !important; +} +.navbar-nav.sm-collapsible[data-sm-skip-collapsible-behavior] a.has-submenu { + padding-right: 15px; +} +/* scrolling arrows for tall menus */ +.navbar-nav span.scroll-up, .navbar-nav span.scroll-down { + position: absolute; + display: none; + visibility: hidden; + height: 20px; + overflow: hidden; + text-align: center; +} +.navbar-nav span.scroll-up-arrow, .navbar-nav span.scroll-down-arrow { + position: absolute; + top: -2px; + left: 50%; + margin-left: -8px; + width: 0; + height: 0; + overflow: hidden; + border-top: 7px dashed transparent; + border-right: 7px dashed transparent; + border-bottom: 7px solid; + border-left: 7px dashed transparent; +} +.navbar-nav span.scroll-down-arrow { + top: 6px; + border-top: 7px solid; + border-right: 7px dashed transparent; + border-bottom: 7px dashed transparent; + border-left: 7px dashed transparent; +} +/* add more indentation for 2+ level sub in collapsible mode - Bootstrap normally supports just 1 level sub menus */ +.navbar-nav.sm-collapsible ul .dropdown-menu > li > a, +.navbar-nav.sm-collapsible ul .dropdown-menu .dropdown-header { + padding-left: 35px; +} +.navbar-nav.sm-collapsible ul ul .dropdown-menu > li > a, +.navbar-nav.sm-collapsible ul ul .dropdown-menu .dropdown-header { + padding-left: 45px; +} +.navbar-nav.sm-collapsible ul ul ul .dropdown-menu > li > a, +.navbar-nav.sm-collapsible ul ul ul .dropdown-menu .dropdown-header { + padding-left: 55px; +} +.navbar-nav.sm-collapsible ul ul ul ul .dropdown-menu > li > a, +.navbar-nav.sm-collapsible ul ul ul ul .dropdown-menu .dropdown-header { + padding-left: 65px; +} +/* fix SmartMenus sub menus auto width (subMenusMinWidth and subMenusMaxWidth options) */ +.navbar-nav .dropdown-menu > li > a { + white-space: normal; +} +.navbar-nav ul.sm-nowrap > li > a { + white-space: nowrap; +} +.navbar-nav.sm-collapsible ul.sm-nowrap > li > a { + white-space: normal; +} +/* fix .navbar-right subs alignment */ +.navbar-right ul.dropdown-menu { + left: 0; + right: auto; +} \ No newline at end of file diff --git a/civicrm/bower_components/smartmenus/src/addons/bootstrap/jquery.smartmenus.bootstrap.js b/civicrm/bower_components/smartmenus/src/addons/bootstrap/jquery.smartmenus.bootstrap.js new file mode 100644 index 0000000000..a9a7191b4f --- /dev/null +++ b/civicrm/bower_components/smartmenus/src/addons/bootstrap/jquery.smartmenus.bootstrap.js @@ -0,0 +1,160 @@ +/* + * SmartMenus jQuery Bootstrap Addon - v0.4.0 + * http://www.smartmenus.org/ + * + * Copyright Vasil Dinkov, Vadikom Web Ltd. + * http://vadikom.com/ + * + * Released under the MIT license: + * http://www.opensource.org/licenses/MIT + */ + +(function(factory) { + if (typeof define === 'function' && define.amd) { + // AMD + define(['jquery', 'smartmenus'], factory); + } else if (typeof module === 'object' && typeof module.exports === 'object') { + // CommonJS + module.exports = factory(require('jquery')); + } else { + // Global jQuery + factory(jQuery); + } +} (function($) { + + $.extend($.SmartMenus.Bootstrap = {}, { + keydownFix: false, + init: function() { + // init all navbars that don't have the "data-sm-skip" attribute set + var $navbars = $('ul.navbar-nav:not([data-sm-skip])'); + $navbars.each(function() { + var $this = $(this), + obj = $this.data('smartmenus'); + // if this navbar is not initialized + if (!obj) { + $this.smartmenus({ + // these are some good default options that should work for all + subMenusSubOffsetX: 2, + subMenusSubOffsetY: -6, + subIndicators: false, + collapsibleShowFunction: null, + collapsibleHideFunction: null, + rightToLeftSubMenus: $this.hasClass('navbar-right'), + bottomToTopSubMenus: $this.closest('.navbar').hasClass('navbar-fixed-bottom') + }) + .on({ + // set/unset proper Bootstrap classes for some menu elements + 'show.smapi': function(e, menu) { + var $menu = $(menu), + $scrollArrows = $menu.dataSM('scroll-arrows'); + if ($scrollArrows) { + // they inherit border-color from body, so we can use its background-color too + $scrollArrows.css('background-color', $(document.body).css('background-color')); + } + $menu.parent().addClass('open'); + }, + 'hide.smapi': function(e, menu) { + $(menu).parent().removeClass('open'); + } + }); + + function onInit() { + // set Bootstrap's "active" class to SmartMenus "current" items (should someone decide to enable markCurrentItem: true) + $this.find('a.current').parent().addClass('active'); + // remove any Bootstrap required attributes that might cause conflicting issues with the SmartMenus script + $this.find('a.has-submenu').each(function() { + var $this = $(this); + if ($this.is('[data-toggle="dropdown"]')) { + $this.dataSM('bs-data-toggle-dropdown', true).removeAttr('data-toggle'); + } + if ($this.is('[role="button"]')) { + $this.dataSM('bs-role-button', true).removeAttr('role'); + } + }); + } + + onInit(); + + function onBeforeDestroy() { + $this.find('a.current').parent().removeClass('active'); + $this.find('a.has-submenu').each(function() { + var $this = $(this); + if ($this.dataSM('bs-data-toggle-dropdown')) { + $this.attr('data-toggle', 'dropdown').removeDataSM('bs-data-toggle-dropdown'); + } + if ($this.dataSM('bs-role-button')) { + $this.attr('role', 'button').removeDataSM('bs-role-button'); + } + }); + } + + obj = $this.data('smartmenus'); + + // custom "isCollapsible" method for Bootstrap + obj.isCollapsible = function() { + return !/^(left|right)$/.test(this.$firstLink.parent().css('float')) && this.$root.css('display') == 'block'; + }; + + // custom "refresh" method for Bootstrap + obj.refresh = function() { + $.SmartMenus.prototype.refresh.call(this); + onInit(); + // update collapsible detection + detectCollapsible(true); + }; + + // custom "destroy" method for Bootstrap + obj.destroy = function(refresh) { + onBeforeDestroy(); + $.SmartMenus.prototype.destroy.call(this, refresh); + }; + + // keep Bootstrap's default behavior for parent items when the "data-sm-skip-collapsible-behavior" attribute is set to the ul.navbar-nav + // i.e. use the whole item area just as a sub menu toggle and don't customize the carets + if ($this.is('[data-sm-skip-collapsible-behavior]')) { + obj.opts.collapsibleBehavior = 'toggle'; + } + + // onresize detect when the navbar becomes collapsible and add it the "sm-collapsible" class + var winW; + function detectCollapsible(force) { + var newW = obj.getViewportWidth(); + if (newW != winW || force) { + var $carets = $this.find('.caret'); + if (obj.isCollapsible()) { + $this.addClass('sm-collapsible'); + // set "navbar-toggle" class to carets (so they look like a button) if the "data-sm-skip-collapsible-behavior" attribute is not set to the ul.navbar-nav + if (!$this.is('[data-sm-skip-collapsible-behavior]')) { + $carets.addClass('navbar-toggle sub-arrow'); + } + } else { + $this.removeClass('sm-collapsible'); + if (!$this.is('[data-sm-skip-collapsible-behavior]')) { + $carets.removeClass('navbar-toggle sub-arrow'); + } + } + winW = newW; + } + } + detectCollapsible(); + $(window).on('resize.smartmenus' + obj.rootId, detectCollapsible); + } + }); + // keydown fix for Bootstrap 3.3.5+ conflict + if ($navbars.length && !$.SmartMenus.Bootstrap.keydownFix) { + // unhook BS keydown handler for all dropdowns + $(document).off('keydown.bs.dropdown.data-api', '.dropdown-menu'); + // restore BS keydown handler for dropdowns that are not inside SmartMenus navbars + if ($.fn.dropdown && $.fn.dropdown.Constructor) { + $(document).on('keydown.bs.dropdown.data-api', '.dropdown-menu:not([id^="sm-"])', $.fn.dropdown.Constructor.prototype.keydown); + } + $.SmartMenus.Bootstrap.keydownFix = true; + } + } + }); + + // init ondomready + $($.SmartMenus.Bootstrap.init); + + return $; +})); diff --git a/civicrm/bower_components/smartmenus/src/addons/keyboard/jquery.smartmenus.keyboard.js b/civicrm/bower_components/smartmenus/src/addons/keyboard/jquery.smartmenus.keyboard.js new file mode 100644 index 0000000000..ad156c90b1 --- /dev/null +++ b/civicrm/bower_components/smartmenus/src/addons/keyboard/jquery.smartmenus.keyboard.js @@ -0,0 +1,216 @@ +/* + * SmartMenus jQuery Keyboard Addon - v0.4.0 + * http://www.smartmenus.org/ + * + * Copyright Vasil Dinkov, Vadikom Web Ltd. + * http://vadikom.com/ + * + * Released under the MIT license: + * http://www.opensource.org/licenses/MIT + */ + +(function(factory) { + if (typeof define === 'function' && define.amd) { + // AMD + define(['jquery', 'smartmenus'], factory); + } else if (typeof module === 'object' && typeof module.exports === 'object') { + // CommonJS + module.exports = factory(require('jquery')); + } else { + // Global jQuery + factory(jQuery); + } +} (function($) { + + function getFirstItemLink($ul) { + // make sure we also allow the link to be nested deeper inside the LI's (e.g. in a heading) + return $ul.find('> li > a:not(.disabled), > li > :not(ul) a:not(.disabled)').eq(0); + } + function getLastItemLink($ul) { + return $ul.find('> li > a:not(.disabled), > li > :not(ul) a:not(.disabled)').eq(-1); + } + function getNextItemLink($li, noLoop) { + var $a = $li.nextAll('li').find('> a:not(.disabled), > :not(ul) a:not(.disabled)').eq(0); + return noLoop || $a.length ? $a : getFirstItemLink($li.parent()); + } + function getPreviousItemLink($li, noLoop) { + // bug workaround: elements are returned in reverse order just in jQuery 1.8.x + var $a = $li.prevAll('li').find('> a:not(.disabled), > :not(ul) a:not(.disabled)').eq(/^1\.8\./.test($.fn.jquery) ? 0 : -1); + return noLoop || $a.length ? $a : getLastItemLink($li.parent()); + } + + // jQuery's .focus() is unreliable in some versions, so we're going to call the links' native JS focus method + $.fn.focusSM = function() { + if (this.length && this[0].focus) { + this[0].focus(); + } + return this; + }; + + $.extend($.SmartMenus.Keyboard = {}, { + docKeydown: function(e) { + var keyCode = e.keyCode; + if (!/^(37|38|39|40)$/.test(keyCode)) { + return; + } + var $root = $(this), + obj = $root.data('smartmenus'), + $target = $(e.target); + // exit if this is an A inside a mega drop-down + if (!obj || !$target.is('a') || !obj.handleItemEvents($target)) { + return; + } + var $li = $target.closest('li'), + $ul = $li.parent(), + level = $ul.dataSM('level'); + // swap left & right keys + if ($root.hasClass('sm-rtl')) { + if (keyCode == 37) { + keyCode = 39; + } else if (keyCode == 39) { + keyCode = 37; + } + } + switch (keyCode) { + case 37: // Left + if (obj.isCollapsible()) { + break; + } + if (level > 2 || level == 2 && $root.hasClass('sm-vertical')) { + obj.activatedItems[level - 2].focusSM(); + // move to previous non-disabled parent item (make sure we cycle so it might be the last item) + } else if (!$root.hasClass('sm-vertical')) { + getPreviousItemLink((obj.activatedItems[0] || $target).closest('li')).focusSM(); + } + break; + case 38: // Up + if (obj.isCollapsible()) { + var $firstItem; + // if this is the first item of a sub menu, move to the parent item + if (level > 1 && ($firstItem = getFirstItemLink($ul)).length && $target[0] == $firstItem[0]) { + obj.activatedItems[level - 2].focusSM(); + } else { + getPreviousItemLink($li).focusSM(); + } + } else { + if (level == 1 && !$root.hasClass('sm-vertical') && obj.opts.bottomToTopSubMenus) { + if (!obj.activatedItems[0] && $target.dataSM('sub')) { + if (obj.opts.showOnClick) { + obj.clickActivated = true; + } + obj.itemActivate($target); + if ($target.dataSM('sub').is(':visible')) { + obj.focusActivated = true; + } + } + if (obj.activatedItems[0] && obj.activatedItems[0].dataSM('sub') && obj.activatedItems[0].dataSM('sub').is(':visible') && !obj.activatedItems[0].dataSM('sub').hasClass('mega-menu')) { + getLastItemLink(obj.activatedItems[0].dataSM('sub')).focusSM(); + } + } else if (level > 1 || $root.hasClass('sm-vertical')) { + getPreviousItemLink($li).focusSM(); + } + } + break; + case 39: // Right + if (obj.isCollapsible()) { + break; + } + if (level == 1 && $root.hasClass('sm-vertical')) { + if (!obj.activatedItems[0] && $target.dataSM('sub')) { + if (obj.opts.showOnClick) { + obj.clickActivated = true; + } + obj.itemActivate($target); + if ($target.dataSM('sub').is(':visible')) { + obj.focusActivated = true; + } + } + if (obj.activatedItems[0] && obj.activatedItems[0].dataSM('sub') && obj.activatedItems[0].dataSM('sub').is(':visible') && !obj.activatedItems[0].dataSM('sub').hasClass('mega-menu')) { + getFirstItemLink(obj.activatedItems[0].dataSM('sub')).focusSM(); + } + // move to next non-disabled parent item (make sure we cycle so it might be the last item) + } else if ((level == 1 || obj.activatedItems[level - 1] && (!obj.activatedItems[level - 1].dataSM('sub') || !obj.activatedItems[level - 1].dataSM('sub').is(':visible') || obj.activatedItems[level - 1].dataSM('sub').hasClass('mega-menu'))) && !$root.hasClass('sm-vertical')) { + getNextItemLink((obj.activatedItems[0] || $target).closest('li')).focusSM(); + } else if (obj.activatedItems[level - 1] && obj.activatedItems[level - 1].dataSM('sub') && obj.activatedItems[level - 1].dataSM('sub').is(':visible') && !obj.activatedItems[level - 1].dataSM('sub').hasClass('mega-menu')) { + getFirstItemLink(obj.activatedItems[level - 1].dataSM('sub')).focusSM(); + } + break; + case 40: // Down + if (obj.isCollapsible()) { + var $firstSubItem, + $lastItem; + // move to sub menu if appropriate + if (obj.activatedItems[level - 1] && obj.activatedItems[level - 1].dataSM('sub') && obj.activatedItems[level - 1].dataSM('sub').is(':visible') && !obj.activatedItems[level - 1].dataSM('sub').hasClass('mega-menu') && ($firstSubItem = getFirstItemLink(obj.activatedItems[level - 1].dataSM('sub'))).length) { + $firstSubItem.focusSM(); + // if this is the last item of a sub menu, move to the next parent item + } else if (level > 1 && ($lastItem = getLastItemLink($ul)).length && $target[0] == $lastItem[0]) { + var $parentItem = obj.activatedItems[level - 2].closest('li'), + $nextParentItem = null; + while ($parentItem.is('li') && !($nextParentItem = getNextItemLink($parentItem, true)).length) { + $parentItem = $parentItem.parent().parent(); + } + if ($nextParentItem.length) { + $nextParentItem.focusSM(); + } else { + getFirstItemLink($root).focusSM(); + } + } else { + getNextItemLink($li).focusSM(); + } + } else { + if (level == 1 && !$root.hasClass('sm-vertical') && !obj.opts.bottomToTopSubMenus) { + if (!obj.activatedItems[0] && $target.dataSM('sub')) { + if (obj.opts.showOnClick) { + obj.clickActivated = true; + } + obj.itemActivate($target); + if ($target.dataSM('sub').is(':visible')) { + obj.focusActivated = true; + } + } + if (obj.activatedItems[0] && obj.activatedItems[0].dataSM('sub') && obj.activatedItems[0].dataSM('sub').is(':visible') && !obj.activatedItems[0].dataSM('sub').hasClass('mega-menu')) { + getFirstItemLink(obj.activatedItems[0].dataSM('sub')).focusSM(); + } + } else if (level > 1 || $root.hasClass('sm-vertical')) { + getNextItemLink($li).focusSM(); + } + } + break; + } + e.stopPropagation(); + e.preventDefault(); + } + }); + + // hook it + $(document).on('keydown.smartmenus', 'ul.sm, ul.navbar-nav:not([data-sm-skip])', $.SmartMenus.Keyboard.docKeydown); + + $.extend($.SmartMenus.prototype, { + keyboardSetHotkey: function(keyCode, modifiers) { + var self = this; + $(document).on('keydown.smartmenus' + this.rootId, function(e) { + if (keyCode == e.keyCode) { + var procede = true; + if (modifiers) { + if (typeof modifiers == 'string') { + modifiers = [modifiers]; + } + $.each(['ctrlKey', 'shiftKey', 'altKey', 'metaKey'], function(index, value) { + if ($.inArray(value, modifiers) >= 0 && !e[value] || $.inArray(value, modifiers) < 0 && e[value]) { + procede = false; + return false; + } + }); + } + if (procede) { + getFirstItemLink(self.$root).focusSM(); + e.stopPropagation(); + e.preventDefault(); + } + } + }); + } + }); + + return $; +})); \ No newline at end of file diff --git a/civicrm/bower_components/smartmenus/src/css/sm-blue/_mixins.scss b/civicrm/bower_components/smartmenus/src/css/sm-blue/_mixins.scss new file mode 100644 index 0000000000..0ed06503c8 --- /dev/null +++ b/civicrm/bower_components/smartmenus/src/css/sm-blue/_mixins.scss @@ -0,0 +1,2 @@ +@import 'mixins/_sub-items-indentation.scss'; +@import 'mixins/_round-corners-last-item.scss'; \ No newline at end of file diff --git a/civicrm/bower_components/smartmenus/src/css/sm-blue/_sm-blue-theme.scss b/civicrm/bower_components/smartmenus/src/css/sm-blue/_sm-blue-theme.scss new file mode 100644 index 0000000000..d7c2828432 --- /dev/null +++ b/civicrm/bower_components/smartmenus/src/css/sm-blue/_sm-blue-theme.scss @@ -0,0 +1,586 @@ +// This file is best viewed with Tab size 4 code indentation + + +// ----------------------------------------------------------------------------------------------------------------- +// 1. Theme Quick Settings (Variables) +// (for further control, you will need to dig into the actual CSS in 2.) +// ----------------------------------------------------------------------------------------------------------------- + + +// ---------------------------------------------------------- +// :: 1.1. Colors +// ---------------------------------------------------------- + +$sm-blue__blue: #3092c0 !default; +$sm-blue__blue-dark: darken($sm-blue__blue, 5%) !default; +$sm-blue__blue-darker: #006892 !default; +$sm-blue__blue-light: lighten($sm-blue__blue, 30%) !default; +$sm-blue__white: #fff !default; +$sm-blue__gray: darken($sm-blue__white, 34%) !default; + +$sm-blue__text-shadow: rgba(0, 0, 0, 0.2) !default; +$sm-blue__box-shadow: rgba(0, 0, 0, 0.2) !default; + +$sm-blue__gradients_amount: 2% !default; + + +// ---------------------------------------------------------- +// :: 1.2. Breakpoints +// ---------------------------------------------------------- + +$sm-blue__desktop-vp: 768px !default; // switch from collapsible to desktop + + +// ---------------------------------------------------------- +// :: 1.3. Typography +// ---------------------------------------------------------- + +// Import "PT Sans Narrow" font from Google fonts +@import url(https://fonts.googleapis.com/css?family=PT+Sans+Narrow:400,700); + +$sm-blue__font-family: "PT Sans Narrow", "Arial Narrow", Arial, Helvetica, sans-serif !default; +$sm-blue__font-size-base: 18px !default; +$sm-blue__font-size-small: 16px !default; +$sm-blue__line-height: 23px !default; + + +// ---------------------------------------------------------- +// :: 1.4. Borders +// ---------------------------------------------------------- + +$sm-blue__border-width: 1px !default; +$sm-blue__border-radius-base: 8px !default; +$sm-blue__border-radius-small: 4px !default; + + +// ---------------------------------------------------------- +// :: 1.5. Collapsible main menu +// ---------------------------------------------------------- + +// Menu box +$sm-blue__collapsible-bg: transparent !default; +$sm-blue__collapsible-border-radius: $sm-blue__border-radius-base !default; +$sm-blue__collapsible-box-shadow: 0 1px 4px $sm-blue__box-shadow !default; + +// Items +$sm-blue__collapsible-item-color: $sm-blue__white !default; +$sm-blue__collapsible-item-bg: $sm-blue__blue !default; +$sm-blue__collapsible-item-current-color: $sm-blue__white !default; +$sm-blue__collapsible-item-current-bg: $sm-blue__blue-darker !default; +$sm-blue__collapsible-item-disabled-color: lighten($sm-blue__blue, 30%) !default; +$sm-blue__collapsible-item-padding-vertical: 10px !default; +$sm-blue__collapsible-item-padding-horizontal: 20px !default; + +// Toggle button (sub menu indicators) +$sm-blue__collapsible-toggle-bg: rgba(0, 0, 0, 0.1) !default; + + +// ---------------------------------------------------------- +// :: 1.6. Collapsible sub menus +// ---------------------------------------------------------- + +// Menu box +$sm-blue__collapsible-sub-bg: $sm-blue__white !default; + +// Items +$sm-blue__collapsible-sub-item-color: $sm-blue__blue-dark !default; +$sm-blue__collapsible-sub-item-bg: transparent !default; +$sm-blue__collapsible-sub-item-current-color: $sm-blue__white !default; +$sm-blue__collapsible-sub-item-current-bg: $sm-blue__blue-darker !default; +$sm-blue__collapsible-sub-item-disabled-color: darken($sm-blue__white, 30%) !default; + +// Items separators +$sm-blue__collapsible-sub-separators-color: rgba(0, 0, 0, 0.05) !default; + +// Items text indentation for deeper levels +$sm-blue__collapsible-sub-item-indentation: 8px !default; + + +// ---------------------------------------------------------- +// :: 1.7. Desktop main menu +// ---------------------------------------------------------- + +// Menu box +$sm-blue__desktop-bg: $sm-blue__blue !default; +$sm-blue__desktop-border-radius: $sm-blue__border-radius-base !default; +$sm-blue__desktop-box-shadow: 0 1px 1px $sm-blue__box-shadow !default; + +// Items +$sm-blue__desktop-item-color: $sm-blue__white !default; +$sm-blue__desktop-item-bg: $sm-blue__blue !default; +$sm-blue__desktop-item-hover-bg: darken($sm-blue__blue, 5%) !default; +$sm-blue__desktop-item-current-color: $sm-blue__white !default; +$sm-blue__desktop-item-current-bg: $sm-blue__blue-darker !default; +$sm-blue__desktop-item-disabled-color: lighten($sm-blue__blue, 30%) !default; +$sm-blue__desktop-item-padding-vertical: 13px !default; +$sm-blue__desktop-item-padding-horizontal: 24px !default; + +// Items separators +$sm-blue__desktop-separators-size: 1px !default; +$sm-blue__desktop-separators-color: darken($sm-blue__blue, 5%) !default; + +// Sub menu indicators +$sm-blue__desktop-arrow-size: 5px !default; // border-width +$sm-blue__desktop-arrow-color: $sm-blue__blue-light !default; + +// Vertical menu box +$sm-blue__desktop-vertical-box-shadow: 0 1px 4px $sm-blue__box-shadow !default; + +// Vertical items +$sm-blue__desktop-vertical-item-padding-vertical: 9px !default; +$sm-blue__desktop-vertical-item-padding-horizontal: 23px !default; + + +// ---------------------------------------------------------- +// :: 1.8. Desktop sub menus +// ---------------------------------------------------------- + +// Menu box +$sm-blue__desktop-sub-bg: $sm-blue__white !default; +$sm-blue__desktop-sub-border-color: $sm-blue__gray !default; +$sm-blue__desktop-sub-border-radius: $sm-blue__border-radius-small !default; +$sm-blue__desktop-sub-box-shadow: 0 5px 12px $sm-blue__box-shadow !default; +$sm-blue__desktop-sub-padding-vertical: 7px !default; +$sm-blue__desktop-sub-padding-horizontal: 0 !default; + +// Items +$sm-blue__desktop-sub-item-color: $sm-blue__blue-dark !default; +$sm-blue__desktop-sub-item-bg: transparent !default; +$sm-blue__desktop-sub-item-hover-color: $sm-blue__white !default; +$sm-blue__desktop-sub-item-hover-bg: $sm-blue__blue !default; +$sm-blue__desktop-sub-item-current-color: $sm-blue__white !default; +$sm-blue__desktop-sub-item-current-bg: $sm-blue__blue-darker !default; +$sm-blue__desktop-sub-item-disabled-color: darken($sm-blue__white, 30%) !default; +$sm-blue__desktop-sub-item-padding-vertical: 9px !default; +$sm-blue__desktop-sub-item-padding-horizontal: 23px !default; + + +// ----------------------------------------------------------------------------------------------------------------- +// 2. Theme CSS +// ----------------------------------------------------------------------------------------------------------------- + + +// ---------------------------------------------------------- +// :: 2.1. Collapsible mode (mobile first) +// ---------------------------------------------------------- + +// calc item height and sub menus toggle button size +$sm-blue__item-height: $sm-blue__line-height + $sm-blue__collapsible-item-padding-vertical * 2; +// set toggle button size to 80% of item height +$sm-blue__toggle-size: floor($sm-blue__item-height * 0.8); +$sm-blue__toggle-spacing: floor($sm-blue__item-height * 0.1); + +// Main menu box +.sm-blue { + background: $sm-blue__collapsible-bg; + border-radius: $sm-blue__collapsible-border-radius; + box-shadow: $sm-blue__collapsible-box-shadow; + + // Main menu items + a { + &, + &:hover, + &:focus, + &:active { + padding: $sm-blue__collapsible-item-padding-vertical $sm-blue__collapsible-item-padding-horizontal; + /* make room for the toggle button (sub indicator) */ + padding-right: $sm-blue__collapsible-item-padding-horizontal + $sm-blue__toggle-size + $sm-blue__toggle-spacing; + background: $sm-blue__collapsible-item-bg; + background-image: linear-gradient(to bottom, lighten($sm-blue__collapsible-item-bg, $sm-blue__gradients_amount), darken($sm-blue__collapsible-item-bg, $sm-blue__gradients_amount)); + color: $sm-blue__collapsible-item-color; + font-family: $sm-blue__font-family; + font-size: $sm-blue__font-size-base; + font-weight: bold; + line-height: $sm-blue__line-height; + text-decoration: none; + text-shadow: 0 1px 0 $sm-blue__text-shadow; + } + + &.current { + background: $sm-blue__collapsible-item-current-bg; + background-image: linear-gradient(to bottom, darken($sm-blue__collapsible-item-current-bg, $sm-blue__gradients_amount), lighten($sm-blue__collapsible-item-current-bg, $sm-blue__gradients_amount)); + color: $sm-blue__collapsible-item-current-color; + } + + &.disabled { + color: $sm-blue__collapsible-item-disabled-color; + } + + // Toggle buttons (sub menu indicators) + .sub-arrow { + position: absolute; + top: 50%; + margin-top: -(ceil($sm-blue__toggle-size / 2)); + left: auto; + right: $sm-blue__toggle-spacing; + width: $sm-blue__toggle-size; + height: $sm-blue__toggle-size; + overflow: hidden; + font: bold #{$sm-blue__font-size-small}/#{$sm-blue__toggle-size} monospace !important; + text-align: center; + text-shadow: none; + background: $sm-blue__collapsible-toggle-bg; + border-radius: $sm-blue__border-radius-small; + } + .sub-arrow::before { + content: '+'; + } + &.highlighted .sub-arrow::before { + content: '-'; + } + } + + // round the corners of the first item + > li:first-child > a, > li:first-child > :not(ul) a { + border-radius: $sm-blue__collapsible-border-radius $sm-blue__collapsible-border-radius 0 0; + } + // round the corners of the last item + @include sm-blue__round-corners-last-item($sm-blue__collapsible-border-radius); + + // Sub menus box + ul { + background: $sm-blue__collapsible-sub-bg; + + // darken the background of the 2+ level sub menus + ul { + background: rgba(darken($sm-blue__collapsible-sub-bg, 60%), 0.1); + } + + // Sub menus items + a { + &, + &:hover, + &:focus, + &:active { + background: $sm-blue__collapsible-sub-item-bg; + color: $sm-blue__collapsible-sub-item-color; + font-size: $sm-blue__font-size-small; + text-shadow: none; + // add indentation for sub menus text + border-left: $sm-blue__collapsible-sub-item-indentation solid transparent; + } + + &.current { + background: $sm-blue__collapsible-sub-item-current-bg; + background-image: linear-gradient(to bottom, darken($sm-blue__collapsible-sub-item-current-bg, $sm-blue__gradients_amount), lighten($sm-blue__collapsible-sub-item-current-bg, $sm-blue__gradients_amount)); + color: $sm-blue__collapsible-sub-item-current-color; + } + + &.disabled { + color: $sm-blue__collapsible-sub-item-disabled-color; + } + } + + // Add indentation for sub menus text for deeper levels + @include sm-blue__sub-items-indentation($sm-blue__collapsible-sub-item-indentation); + + // Sub menus items separators + li { + border-top: 1px solid $sm-blue__collapsible-sub-separators-color; + + &:first-child { + border-top: 0; + } + } + } +} + + +// ---------------------------------------------------------- +// :: 2.2. Desktop mode +// ---------------------------------------------------------- + +@media (min-width: $sm-blue__desktop-vp) { + + /* Switch to desktop layout + ----------------------------------------------- + These transform the menu tree from + collapsible to desktop (navbar + dropdowns) + -----------------------------------------------*/ + /* start... (it's not recommended editing these rules) */ + .sm-blue ul{position:absolute;width:12em;} + .sm-blue li{float:left;} + .sm-blue.sm-rtl li{float:right;} + .sm-blue ul li,.sm-blue.sm-rtl ul li,.sm-blue.sm-vertical li{float:none;} + .sm-blue a{white-space:nowrap;} + .sm-blue ul a,.sm-blue.sm-vertical a{white-space:normal;} + .sm-blue .sm-nowrap > li > a,.sm-blue .sm-nowrap > li > :not(ul) a{white-space:nowrap;} + /* ...end */ + + // Main menu box + .sm-blue { + background: $sm-blue__desktop-bg; + background-image: linear-gradient(to bottom, lighten($sm-blue__desktop-bg, $sm-blue__gradients_amount), darken($sm-blue__desktop-bg, $sm-blue__gradients_amount)); + border-radius: $sm-blue__desktop-border-radius; + box-shadow: $sm-blue__desktop-box-shadow; + + // Main menu items + a { + &, + &:hover, + &:focus, + &:active, + &.highlighted { + padding: $sm-blue__desktop-item-padding-vertical $sm-blue__desktop-item-padding-horizontal; + background: $sm-blue__desktop-item-bg; + background-image: linear-gradient(to bottom, lighten($sm-blue__desktop-item-bg, $sm-blue__gradients_amount), darken($sm-blue__desktop-item-bg, $sm-blue__gradients_amount)); + color: $sm-blue__desktop-item-color; + } + + &:hover, + &:focus, + &:active, + &.highlighted { + background: $sm-blue__desktop-item-hover-bg; + background-image: linear-gradient(to bottom, lighten($sm-blue__desktop-item-hover-bg, $sm-blue__gradients_amount), darken($sm-blue__desktop-item-hover-bg, $sm-blue__gradients_amount)); + } + + &.current { + background: $sm-blue__desktop-item-current-bg; + background-image: linear-gradient(to bottom, darken($sm-blue__desktop-item-current-bg, $sm-blue__gradients_amount), lighten($sm-blue__desktop-item-current-bg, $sm-blue__gradients_amount)); + color: $sm-blue__desktop-item-current-color; + } + + &.disabled { + background: $sm-blue__desktop-item-bg; + background-image: linear-gradient(to bottom, lighten($sm-blue__desktop-item-bg, $sm-blue__gradients_amount), darken($sm-blue__desktop-item-bg, $sm-blue__gradients_amount)); + color: $sm-blue__desktop-item-disabled-color; + } + + // Sub menu indicators + .sub-arrow { + top: auto; + margin-top: 0; + bottom: 2px; + left: 50%; + margin-left: -$sm-blue__desktop-arrow-size; + right: auto; + width: 0; + height: 0; + border-width: $sm-blue__desktop-arrow-size; + border-style: solid dashed dashed dashed; + border-color: $sm-blue__desktop-arrow-color transparent transparent transparent; + background: transparent; + border-radius: 0; + } + // reset mobile first style + .sub-arrow::before { + display: none; + } + } + + // round the corners of the first and last items + > li:first-child > a, > li:first-child > :not(ul) a { + border-radius: $sm-blue__desktop-border-radius 0 0 $sm-blue__desktop-border-radius; + } + > li:last-child > a, > li:last-child > :not(ul) a { + border-radius: 0 $sm-blue__desktop-border-radius $sm-blue__desktop-border-radius 0 !important; + } + + // Main menu items separators + > li { + border-left: $sm-blue__desktop-separators-size solid $sm-blue__desktop-separators-color; + + &:first-child { + border-left: 0; + } + } + + // Sub menus box + ul { + border: $sm-blue__border-width solid $sm-blue__desktop-sub-border-color; + padding: $sm-blue__desktop-sub-padding-vertical $sm-blue__desktop-sub-padding-horizontal; + background: $sm-blue__desktop-sub-bg; + border-radius: 0 0 $sm-blue__desktop-sub-border-radius $sm-blue__desktop-sub-border-radius !important; + box-shadow: $sm-blue__desktop-sub-box-shadow; + + // 2+ sub levels need rounding of all corners + ul { + border-radius: $sm-blue__desktop-sub-border-radius !important; + background: $sm-blue__desktop-sub-bg; + } + + // Sub menus items + a { + &, + &:hover, + &:focus, + &:active, + &.highlighted { + border: 0 !important; + padding: $sm-blue__desktop-sub-item-padding-vertical $sm-blue__desktop-sub-item-padding-horizontal; + background: $sm-blue__desktop-sub-item-bg; + color: $sm-blue__desktop-sub-item-color; + border-radius: 0 !important; + } + + &:hover, + &:focus, + &:active, + &.highlighted { + background: $sm-blue__desktop-sub-item-hover-bg; + background-image: linear-gradient(to bottom, lighten($sm-blue__desktop-sub-item-hover-bg, $sm-blue__gradients_amount), darken($sm-blue__desktop-sub-item-hover-bg, $sm-blue__gradients_amount)); + color: $sm-blue__desktop-sub-item-hover-color; + } + + &.current { + background: $sm-blue__desktop-sub-item-current-bg; + background-image: linear-gradient(to bottom, darken($sm-blue__desktop-sub-item-current-bg, $sm-blue__gradients_amount), lighten($sm-blue__desktop-sub-item-current-bg, $sm-blue__gradients_amount)); + color: $sm-blue__desktop-sub-item-current-color; + } + + &.disabled { + background: $sm-blue__desktop-sub-bg; + color: $sm-blue__desktop-sub-item-disabled-color; + } + + // Sub menu indicators + .sub-arrow { + top: 50%; + margin-top: -$sm-blue__desktop-arrow-size; + bottom: auto; + left: auto; + margin-left: 0; + right: 10px; + border-style: dashed dashed dashed solid; + border-color: transparent transparent transparent $sm-blue__desktop-arrow-color; + } + } + + // No sub menus items separators + li { + border: 0; + } + } + + // Scrolling arrows containers for tall sub menus - test sub menu: "Sub test" -> "more..." in the default download package + .scroll-up, + .scroll-down { + position: absolute; + display: none; + visibility: hidden; + overflow: hidden; + background: $sm-blue__desktop-sub-bg; + height: 20px; + // width and position will be set automatically by the script + } + .scroll-up-arrow, + .scroll-down-arrow { + position: absolute; + top: -2px; + left: 50%; + margin-left: -8px; + // we will use one-side border to create a triangle so that we don't use a real background image, of course, you can use a real image if you like too + width: 0; + height: 0; + overflow: hidden; + border-width: 8px; // tweak size of the arrow + border-style: dashed dashed solid dashed; + border-color: transparent transparent $sm-blue__desktop-sub-item-color transparent; + } + .scroll-down-arrow { + top: 6px; + border-style: solid dashed dashed dashed; + border-color: $sm-blue__desktop-sub-item-color transparent transparent transparent; + } + + + // Rigth-to-left + + // Main menu box + &.sm-rtl { + + // Vertical main menu items + &.sm-vertical { + a { + // Sub menu indicators + .sub-arrow { + right: auto; + left: 10px; + border-style: dashed solid dashed dashed; + border-color: transparent $sm-blue__desktop-arrow-color transparent transparent; + } + } + } + + // round the corners of the first and last items + > li:first-child > a, > li:first-child > :not(ul) a { + border-radius: 0 $sm-blue__desktop-border-radius $sm-blue__desktop-border-radius 0; + } + > li:last-child > a, > li:last-child > :not(ul) a { + border-radius: $sm-blue__desktop-border-radius 0 0 $sm-blue__desktop-border-radius !important; + } + + // Main menu items separators + > li { + &:first-child { + border-left: $sm-blue__desktop-separators-size solid $sm-blue__desktop-separators-color; + } + &:last-child { + border-left: 0; + } + } + + // Sub menus box + ul { + a { + // Sub menu indicators + .sub-arrow { + right: auto; + left: 10px; + border-style: dashed solid dashed dashed; + border-color: transparent $sm-blue__desktop-arrow-color transparent transparent; + } + } + } + } + + + // Vertical main menu + + // Main menu box + &.sm-vertical { + box-shadow: $sm-blue__desktop-vertical-box-shadow; + + // Main menu items + a { + padding: $sm-blue__desktop-vertical-item-padding-vertical $sm-blue__desktop-vertical-item-padding-horizontal; + + // Sub menu indicators + .sub-arrow { + top: 50%; + margin-top: -$sm-blue__desktop-arrow-size; + bottom: auto; + left: auto; + margin-left: 0; + right: 10px; + border-style: dashed dashed dashed solid; + border-color: transparent transparent transparent $sm-blue__desktop-arrow-color; + } + } + + // round the corners of the first and last items + > li:first-child > a, > li:first-child > :not(ul) a { + border-radius: $sm-blue__desktop-border-radius $sm-blue__desktop-border-radius 0 0; + } + > li:last-child > a, > li:last-child > :not(ul) a { + border-radius: 0 0 $sm-blue__desktop-border-radius $sm-blue__desktop-border-radius !important; + } + + // No main menu item separators + > li { + border-left: 0 !important; + } + + // Sub menus box + ul { + border-radius: $sm-blue__desktop-sub-border-radius !important; + + // Sub menus items + a { + padding: $sm-blue__desktop-sub-item-padding-vertical $sm-blue__desktop-sub-item-padding-horizontal; + } + } + } + } +} \ No newline at end of file diff --git a/civicrm/bower_components/smartmenus/src/css/sm-blue/mixins/_round-corners-last-item.scss b/civicrm/bower_components/smartmenus/src/css/sm-blue/mixins/_round-corners-last-item.scss new file mode 100644 index 0000000000..9622771c0b --- /dev/null +++ b/civicrm/bower_components/smartmenus/src/css/sm-blue/mixins/_round-corners-last-item.scss @@ -0,0 +1,25 @@ +// Generate rules to round the corners of the last collapsible item + +@mixin sm-blue__round-corners-last-item($amount, $chainable: 'ul > li:last-child > ', $level: 4, $chain_prefix: '> li:last-child > ', $chain: '', $selector: '') { + $chain: $chain_prefix; + $selector: $chain + 'a, ' + $chain + '*:not(ul) a, ' + $chain + 'ul'; + @for $i from 1 through $level { + $chain: $chain + $chainable; + $selector: $selector + ', +' + $chain + ' a, ' + $chain + '*:not(ul) a, ' + $chain + ' ul'; + } + #{$selector} { + border-radius: 0 0 $amount $amount; + } + // highlighted items, don't need rounding since their sub is open + $chain: $chain_prefix; + $selector: $chain + 'a.highlighted, ' + $chain + '*:not(ul) a.highlighted'; + @for $i from 1 through $level { + $chain: $chain + $chainable; + $selector: $selector + ', +' + $chain + ' a.highlighted, ' + $chain + '*:not(ul) a.highlighted'; + } + #{$selector} { + border-radius: 0; + } +} \ No newline at end of file diff --git a/civicrm/bower_components/smartmenus/src/css/sm-blue/mixins/_sub-items-indentation.scss b/civicrm/bower_components/smartmenus/src/css/sm-blue/mixins/_sub-items-indentation.scss new file mode 100644 index 0000000000..30cd01b68a --- /dev/null +++ b/civicrm/bower_components/smartmenus/src/css/sm-blue/mixins/_sub-items-indentation.scss @@ -0,0 +1,15 @@ +// Generate rules to indent sub menus text +// +// We'll use left border to avoid messing with the padding. + +@mixin sm-blue__sub-items-indentation($amount, $chainable: 'ul ', $level: 4, $chain: '') { + @for $i from 1 through $level { + $chain: $chain + $chainable; + #{$chain} a, + #{$chain} a:hover, + #{$chain} a:focus, + #{$chain} a:active { + border-left: ($amount * ($i + 1)) solid transparent; + } + } +} \ No newline at end of file diff --git a/civicrm/bower_components/smartmenus/src/css/sm-blue/sm-blue.css b/civicrm/bower_components/smartmenus/src/css/sm-blue/sm-blue.css new file mode 100644 index 0000000000..4cff3bb543 --- /dev/null +++ b/civicrm/bower_components/smartmenus/src/css/sm-blue/sm-blue.css @@ -0,0 +1,333 @@ +@import url(https://fonts.googleapis.com/css?family=PT+Sans+Narrow:400,700); +.sm-blue { + background: transparent; + border-radius: 8px; + box-shadow: 0 1px 4px rgba(0, 0, 0, 0.2); +} +.sm-blue a, .sm-blue a:hover, .sm-blue a:focus, .sm-blue a:active { + padding: 10px 20px; + /* make room for the toggle button (sub indicator) */ + padding-right: 58px; + background: #3092c0; + background-image: linear-gradient(to bottom, #3298c8, #2e8cb8); + color: #fff; + font-family: "PT Sans Narrow", "Arial Narrow", Arial, Helvetica, sans-serif; + font-size: 18px; + font-weight: bold; + line-height: 23px; + text-decoration: none; + text-shadow: 0 1px 0 rgba(0, 0, 0, 0.2); +} +.sm-blue a.current { + background: #006892; + background-image: linear-gradient(to bottom, #006188, #006f9c); + color: #fff; +} +.sm-blue a.disabled { + color: #a1d1e8; +} +.sm-blue a .sub-arrow { + position: absolute; + top: 50%; + margin-top: -17px; + left: auto; + right: 4px; + width: 34px; + height: 34px; + overflow: hidden; + font: bold 16px/34px monospace !important; + text-align: center; + text-shadow: none; + background: rgba(0, 0, 0, 0.1); + border-radius: 4px; +} +.sm-blue a .sub-arrow::before { + content: '+'; +} +.sm-blue a.highlighted .sub-arrow::before { + content: '-'; +} +.sm-blue > li:first-child > a, .sm-blue > li:first-child > :not(ul) a { + border-radius: 8px 8px 0 0; +} +.sm-blue > li:last-child > a, .sm-blue > li:last-child > *:not(ul) a, .sm-blue > li:last-child > ul, .sm-blue > li:last-child > ul > li:last-child > a, .sm-blue > li:last-child > ul > li:last-child > *:not(ul) a, .sm-blue > li:last-child > ul > li:last-child > ul, .sm-blue > li:last-child > ul > li:last-child > ul > li:last-child > a, .sm-blue > li:last-child > ul > li:last-child > ul > li:last-child > *:not(ul) a, .sm-blue > li:last-child > ul > li:last-child > ul > li:last-child > ul, .sm-blue > li:last-child > ul > li:last-child > ul > li:last-child > ul > li:last-child > a, .sm-blue > li:last-child > ul > li:last-child > ul > li:last-child > ul > li:last-child > *:not(ul) a, .sm-blue > li:last-child > ul > li:last-child > ul > li:last-child > ul > li:last-child > ul, .sm-blue > li:last-child > ul > li:last-child > ul > li:last-child > ul > li:last-child > ul > li:last-child > a, .sm-blue > li:last-child > ul > li:last-child > ul > li:last-child > ul > li:last-child > ul > li:last-child > *:not(ul) a, .sm-blue > li:last-child > ul > li:last-child > ul > li:last-child > ul > li:last-child > ul > li:last-child > ul { + border-radius: 0 0 8px 8px; +} +.sm-blue > li:last-child > a.highlighted, .sm-blue > li:last-child > *:not(ul) a.highlighted, .sm-blue > li:last-child > ul > li:last-child > a.highlighted, .sm-blue > li:last-child > ul > li:last-child > *:not(ul) a.highlighted, .sm-blue > li:last-child > ul > li:last-child > ul > li:last-child > a.highlighted, .sm-blue > li:last-child > ul > li:last-child > ul > li:last-child > *:not(ul) a.highlighted, .sm-blue > li:last-child > ul > li:last-child > ul > li:last-child > ul > li:last-child > a.highlighted, .sm-blue > li:last-child > ul > li:last-child > ul > li:last-child > ul > li:last-child > *:not(ul) a.highlighted, .sm-blue > li:last-child > ul > li:last-child > ul > li:last-child > ul > li:last-child > ul > li:last-child > a.highlighted, .sm-blue > li:last-child > ul > li:last-child > ul > li:last-child > ul > li:last-child > ul > li:last-child > *:not(ul) a.highlighted { + border-radius: 0; +} +.sm-blue ul { + background: #fff; +} +.sm-blue ul ul { + background: rgba(102, 102, 102, 0.1); +} +.sm-blue ul a, .sm-blue ul a:hover, .sm-blue ul a:focus, .sm-blue ul a:active { + background: transparent; + color: #2b82ac; + font-size: 16px; + text-shadow: none; + border-left: 8px solid transparent; +} +.sm-blue ul a.current { + background: #006892; + background-image: linear-gradient(to bottom, #006188, #006f9c); + color: #fff; +} +.sm-blue ul a.disabled { + color: #b3b3b3; +} +.sm-blue ul ul a, +.sm-blue ul ul a:hover, +.sm-blue ul ul a:focus, +.sm-blue ul ul a:active { + border-left: 16px solid transparent; +} +.sm-blue ul ul ul a, +.sm-blue ul ul ul a:hover, +.sm-blue ul ul ul a:focus, +.sm-blue ul ul ul a:active { + border-left: 24px solid transparent; +} +.sm-blue ul ul ul ul a, +.sm-blue ul ul ul ul a:hover, +.sm-blue ul ul ul ul a:focus, +.sm-blue ul ul ul ul a:active { + border-left: 32px solid transparent; +} +.sm-blue ul ul ul ul ul a, +.sm-blue ul ul ul ul ul a:hover, +.sm-blue ul ul ul ul ul a:focus, +.sm-blue ul ul ul ul ul a:active { + border-left: 40px solid transparent; +} +.sm-blue ul li { + border-top: 1px solid rgba(0, 0, 0, 0.05); +} +.sm-blue ul li:first-child { + border-top: 0; +} + +@media (min-width: 768px) { + /* Switch to desktop layout + ----------------------------------------------- + These transform the menu tree from + collapsible to desktop (navbar + dropdowns) + -----------------------------------------------*/ + /* start... (it's not recommended editing these rules) */ + .sm-blue ul { + position: absolute; + width: 12em; + } + + .sm-blue li { + float: left; + } + + .sm-blue.sm-rtl li { + float: right; + } + + .sm-blue ul li, .sm-blue.sm-rtl ul li, .sm-blue.sm-vertical li { + float: none; + } + + .sm-blue a { + white-space: nowrap; + } + + .sm-blue ul a, .sm-blue.sm-vertical a { + white-space: normal; + } + + .sm-blue .sm-nowrap > li > a, .sm-blue .sm-nowrap > li > :not(ul) a { + white-space: nowrap; + } + + /* ...end */ + .sm-blue { + background: #3092c0; + background-image: linear-gradient(to bottom, #3298c8, #2e8cb8); + border-radius: 8px; + box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2); + } + .sm-blue a, .sm-blue a:hover, .sm-blue a:focus, .sm-blue a:active, .sm-blue a.highlighted { + padding: 13px 24px; + background: #3092c0; + background-image: linear-gradient(to bottom, #3298c8, #2e8cb8); + color: #fff; + } + .sm-blue a:hover, .sm-blue a:focus, .sm-blue a:active, .sm-blue a.highlighted { + background: #2b82ac; + background-image: linear-gradient(to bottom, #2d89b4, #297ca3); + } + .sm-blue a.current { + background: #006892; + background-image: linear-gradient(to bottom, #006188, #006f9c); + color: #fff; + } + .sm-blue a.disabled { + background: #3092c0; + background-image: linear-gradient(to bottom, #3298c8, #2e8cb8); + color: #a1d1e8; + } + .sm-blue a .sub-arrow { + top: auto; + margin-top: 0; + bottom: 2px; + left: 50%; + margin-left: -5px; + right: auto; + width: 0; + height: 0; + border-width: 5px; + border-style: solid dashed dashed dashed; + border-color: #a1d1e8 transparent transparent transparent; + background: transparent; + border-radius: 0; + } + .sm-blue a .sub-arrow::before { + display: none; + } + .sm-blue > li:first-child > a, .sm-blue > li:first-child > :not(ul) a { + border-radius: 8px 0 0 8px; + } + .sm-blue > li:last-child > a, .sm-blue > li:last-child > :not(ul) a { + border-radius: 0 8px 8px 0 !important; + } + .sm-blue > li { + border-left: 1px solid #2b82ac; + } + .sm-blue > li:first-child { + border-left: 0; + } + .sm-blue ul { + border: 1px solid #a8a8a8; + padding: 7px 0; + background: #fff; + border-radius: 0 0 4px 4px !important; + box-shadow: 0 5px 12px rgba(0, 0, 0, 0.2); + } + .sm-blue ul ul { + border-radius: 4px !important; + background: #fff; + } + .sm-blue ul a, .sm-blue ul a:hover, .sm-blue ul a:focus, .sm-blue ul a:active, .sm-blue ul a.highlighted { + border: 0 !important; + padding: 9px 23px; + background: transparent; + color: #2b82ac; + border-radius: 0 !important; + } + .sm-blue ul a:hover, .sm-blue ul a:focus, .sm-blue ul a:active, .sm-blue ul a.highlighted { + background: #3092c0; + background-image: linear-gradient(to bottom, #3298c8, #2e8cb8); + color: #fff; + } + .sm-blue ul a.current { + background: #006892; + background-image: linear-gradient(to bottom, #006188, #006f9c); + color: #fff; + } + .sm-blue ul a.disabled { + background: #fff; + color: #b3b3b3; + } + .sm-blue ul a .sub-arrow { + top: 50%; + margin-top: -5px; + bottom: auto; + left: auto; + margin-left: 0; + right: 10px; + border-style: dashed dashed dashed solid; + border-color: transparent transparent transparent #a1d1e8; + } + .sm-blue ul li { + border: 0; + } + .sm-blue .scroll-up, + .sm-blue .scroll-down { + position: absolute; + display: none; + visibility: hidden; + overflow: hidden; + background: #fff; + height: 20px; + } + .sm-blue .scroll-up-arrow, + .sm-blue .scroll-down-arrow { + position: absolute; + top: -2px; + left: 50%; + margin-left: -8px; + width: 0; + height: 0; + overflow: hidden; + border-width: 8px; + border-style: dashed dashed solid dashed; + border-color: transparent transparent #2b82ac transparent; + } + .sm-blue .scroll-down-arrow { + top: 6px; + border-style: solid dashed dashed dashed; + border-color: #2b82ac transparent transparent transparent; + } + .sm-blue.sm-rtl.sm-vertical a .sub-arrow { + right: auto; + left: 10px; + border-style: dashed solid dashed dashed; + border-color: transparent #a1d1e8 transparent transparent; + } + .sm-blue.sm-rtl > li:first-child > a, .sm-blue.sm-rtl > li:first-child > :not(ul) a { + border-radius: 0 8px 8px 0; + } + .sm-blue.sm-rtl > li:last-child > a, .sm-blue.sm-rtl > li:last-child > :not(ul) a { + border-radius: 8px 0 0 8px !important; + } + .sm-blue.sm-rtl > li:first-child { + border-left: 1px solid #2b82ac; + } + .sm-blue.sm-rtl > li:last-child { + border-left: 0; + } + .sm-blue.sm-rtl ul a .sub-arrow { + right: auto; + left: 10px; + border-style: dashed solid dashed dashed; + border-color: transparent #a1d1e8 transparent transparent; + } + .sm-blue.sm-vertical { + box-shadow: 0 1px 4px rgba(0, 0, 0, 0.2); + } + .sm-blue.sm-vertical a { + padding: 9px 23px; + } + .sm-blue.sm-vertical a .sub-arrow { + top: 50%; + margin-top: -5px; + bottom: auto; + left: auto; + margin-left: 0; + right: 10px; + border-style: dashed dashed dashed solid; + border-color: transparent transparent transparent #a1d1e8; + } + .sm-blue.sm-vertical > li:first-child > a, .sm-blue.sm-vertical > li:first-child > :not(ul) a { + border-radius: 8px 8px 0 0; + } + .sm-blue.sm-vertical > li:last-child > a, .sm-blue.sm-vertical > li:last-child > :not(ul) a { + border-radius: 0 0 8px 8px !important; + } + .sm-blue.sm-vertical > li { + border-left: 0 !important; + } + .sm-blue.sm-vertical ul { + border-radius: 4px !important; + } + .sm-blue.sm-vertical ul a { + padding: 9px 23px; + } +} + +/*# sourceMappingURL=sm-blue.css.map */ diff --git a/civicrm/bower_components/smartmenus/src/css/sm-blue/sm-blue.css.map b/civicrm/bower_components/smartmenus/src/css/sm-blue/sm-blue.css.map new file mode 100644 index 0000000000..b9c9d7e5d8 --- /dev/null +++ b/civicrm/bower_components/smartmenus/src/css/sm-blue/sm-blue.css.map @@ -0,0 +1,7 @@ +{ +"version": 3, +"mappings": "AAsCQ,2EAAmE;AAuI3E,QAAS;EACR,UAAU,EAlHsB,WAAW;EAmH3C,aAAa,EAlH2B,GAA4B;EAmHpE,UAAU,EAlH4B,4BAA+B;;AAsHpE,iEAGS;EACR,OAAO,EAAE,SAAyF;EAClG,qDAAqD;EACrD,aAAa,EAAE,IAAgG;EAC/G,UAAU,EAtC4B,OAAc;EAuCpD,gBAAgB,EAAE,4CAAiK;EACnL,KAAK,EAvCqC,IAAe;EAwCzD,WAAW,EAtJiB,8DAA8D;EAuJ1F,SAAS,EAtJqB,IAAI;EAuJlC,WAAW,EAAE,IAAI;EACjB,WAAW,EAtJiB,IAAI;EAuJhC,eAAe,EAAE,IAAI;EACrB,WAAW,EAAE,0BAA6B;;AAG3C,kBAAU;EACT,UAAU,EAhD8B,OAAqB;EAiD7D,gBAAgB,EAAE,4CAAiL;EACnM,KAAK,EAnDqC,IAAe;;AAsD1D,mBAAW;EACV,KAAK,EAxIsC,OAA4B;;AA4IxE,qBAAW;EACV,QAAQ,EAAE,QAAQ;EAClB,GAAG,EAAE,GAAG;EACR,UAAU,EAAE,KAAkC;EAC9C,IAAI,EAAE,IAAI;EACV,KAAK,EA5CkB,GAAkC;EA6CzD,KAAK,EA9Ce,IAAkC;EA+CtD,MAAM,EA/Cc,IAAkC;EAgDtD,QAAQ,EAAE,MAAM;EAChB,IAAI,EAAE,mCAA+E;EACrF,UAAU,EAAE,MAAM;EAClB,WAAW,EAAE,IAAI;EACjB,UAAU,EAnJyB,kBAAkB;EAoJrD,aAAa,EA1KqB,GAAG;;AA4KtC,6BAAmB;EAClB,OAAO,EAAE,GAAG;;AAEb,yCAAiC;EAChC,OAAO,EAAE,GAAG;;AAKd,qEAAoD;EACnD,aAAa,EAAE,WAA2E;;AChO3F,6mCAAa;EACZ,aAAa,EAAE,WAAmB;;AAUnC,w3BAAa;EACZ,aAAa,EAAE,CAAC;;AD0NjB,WAAG;EACF,UAAU,EA3FiC,IAAe;;AA8F1D,cAAG;EACF,UAAU,EAAE,wBAAoD;;AAKhE,6EAGS;EACR,UAAU,EAxK0B,WAAW;EAyK/C,KAAK,EA7G8B,OAAmB;EA8GtD,SAAS,EAtNqB,IAAI;EAuNlC,WAAW,EAAE,IAAI;EAEjB,WAAW,EAAE,qBAA4D;;AAG1E,qBAAU;EACT,UAAU,EAhH6B,OAAqB;EAiH5D,gBAAgB,EAAE,4CAAyL;EAC3M,KAAK,EAnHoC,IAAe;;AAsHzD,sBAAW;EACV,KAAK,EApLwC,OAA4B;;AElF3E;;;uBAGmB;EAClB,WAAW,EAAE,sBAAsC;;AAJpD;;;0BAGmB;EAClB,WAAW,EAAE,sBAAsC;;AAJpD;;;6BAGmB;EAClB,WAAW,EAAE,sBAAsC;;AAJpD;;;gCAGmB;EAClB,WAAW,EAAE,sBAAsC;;AF0QpD,cAAG;EACF,UAAU,EAAE,6BAAoD;;AAEhE,0BAAc;EACb,UAAU,EAAE,CAAC;;;AAWjB,yBAAyC;EAExC;;;;mDAIiD;EACjD,yDAAyD;EACzD,WAAW;IAAC,QAAQ,EAAC,QAAQ;IAAC,KAAK,EAAC,IAAI;;;EACxC,WAAW;IAAC,KAAK,EAAC,IAAI;;;EACtB,kBAAkB;IAAC,KAAK,EAAC,KAAK;;;EAC9B,8DAA4D;IAAC,KAAK,EAAC,IAAI;;;EACvE,UAAU;IAAC,WAAW,EAAC,MAAM;;;EAC7B,qCAAoC;IAAC,WAAW,EAAC,MAAM;;;EACvD,mEAAkE;IAAC,WAAW,EAAC,MAAM;;;EACrF,YAAY;EAGZ,QAAS;IACR,UAAU,EAlK6B,OAAc;IAmKrD,gBAAgB,EAAE,4CAA+I;IACjK,aAAa,EAjNuB,GAA4B;IAkNhE,UAAU,EAjNwB,4BAA+B;;EAqNhE,yFAIc;IACb,OAAO,EAAE,SAAiF;IAC1F,UAAU,EA/K2B,OAAc;IAgLnD,gBAAgB,EAAE,4CAAyJ;IAC3K,KAAK,EAhLoC,IAAe;;EAmLzD,6EAGc;IACb,UAAU,EA/NwB,OAA0B;IAgO5D,gBAAgB,EAAE,4CAAqK;;EAGxL,kBAAU;IACT,UAAU,EA3L6B,OAAqB;IA4L5D,gBAAgB,EAAE,4CAAyK;IAC3L,KAAK,EA9LoC,IAAe;;EAiMzD,mBAAW;IACV,UAAU,EAnM2B,OAAc;IAoMnD,gBAAgB,EAAE,4CAAyJ;IAC3K,KAAK,EAzOkC,OAA4B;;EA6OpE,qBAAW;IACV,GAAG,EAAE,IAAI;IACT,UAAU,EAAE,CAAC;IACb,MAAM,EAAE,GAAG;IACX,IAAI,EAAE,GAAG;IACT,WAAW,EAAE,IAA6B;IAC1C,KAAK,EAAE,IAAI;IACX,KAAK,EAAE,CAAC;IACR,MAAM,EAAE,CAAC;IACT,YAAY,EA7OoB,GAAG;IA8OnC,YAAY,EAAE,0BAA0B;IACxC,YAAY,EAAE,2CAAiE;IAC/E,UAAU,EAAE,WAAW;IACvB,aAAa,EAAE,CAAC;;EAGjB,6BAAmB;IAClB,OAAO,EAAE,IAAI;;EAKf,qEAAoD;IACnD,aAAa,EAAE,WAAmE;;EAEnF,mEAAkD;IACjD,aAAa,EAAE,sBAA8E;;EAI9F,aAAK;IACJ,WAAW,EAAE,iBAA0E;;EAEvF,yBAAc;IACb,WAAW,EAAE,CAAC;;EAKhB,WAAG;IACF,MAAM,EAAE,iBAA+D;IACvE,OAAO,EAAE,KAA+E;IACxF,UAAU,EAlPgC,IAAe;IAmPzD,aAAa,EAAE,sBAAsF;IACrG,UAAU,EA7P0B,6BAAgC;;EAgQpE,cAAG;IACF,aAAa,EAAE,cAA8C;IAC7D,UAAU,EAzP+B,IAAe;;EA8PxD,wGAIc;IACb,MAAM,EAAE,YAAY;IACpB,OAAO,EAAE,QAAyF;IAClG,UAAU,EAxQsB,WAAW;IAyQ3C,KAAK,EA1Q6B,OAAmB;IA2QrD,aAAa,EAAE,YAAY;;EAG5B,yFAGc;IACb,UAAU,EA/Q0B,OAAc;IAgRlD,gBAAgB,EAAE,4CAA6K;IAC/L,KAAK,EAhRmC,IAAe;;EAmRxD,qBAAU;IACT,UAAU,EAnR4B,OAAqB;IAoR3D,gBAAgB,EAAE,4CAAiL;IACnM,KAAK,EAtRmC,IAAe;;EAyRxD,sBAAW;IACV,UAAU,EA1R8B,IAAe;IA2RvD,KAAK,EAzRoC,OAA4B;;EA6RtE,wBAAW;IACV,GAAG,EAAE,GAAG;IACR,UAAU,EAAE,IAA6B;IACzC,MAAM,EAAE,IAAI;IACZ,IAAI,EAAE,IAAI;IACV,WAAW,EAAE,CAAC;IACd,KAAK,EAAE,IAAI;IACX,YAAY,EAAE,0BAA0B;IACxC,YAAY,EAAE,2CAAiE;;EAKjF,cAAG;IACF,MAAM,EAAE,CAAC;;EAKX;uBACa;IACZ,QAAQ,EAAE,QAAQ;IAClB,OAAO,EAAE,IAAI;IACb,UAAU,EAAE,MAAM;IAClB,QAAQ,EAAE,MAAM;IAChB,UAAU,EAxTgC,IAAe;IAyTzD,MAAM,EAAE,IAAI;;EAGb;6BACmB;IAClB,QAAQ,EAAE,QAAQ;IAClB,GAAG,EAAE,IAAI;IACT,IAAI,EAAE,GAAG;IACT,WAAW,EAAE,IAAI;IAEjB,KAAK,EAAE,CAAC;IACR,MAAM,EAAE,CAAC;IACT,QAAQ,EAAE,MAAM;IAChB,YAAY,EAAE,GAAG;IACjB,YAAY,EAAE,0BAA0B;IACxC,YAAY,EAAE,2CAAoE;;EAEnF,2BAAmB;IAClB,GAAG,EAAE,GAAG;IACR,YAAY,EAAE,0BAA0B;IACxC,YAAY,EAAE,2CAAoE;;EAahF,wCAAW;IACV,KAAK,EAAE,IAAI;IACX,IAAI,EAAE,IAAI;IACV,YAAY,EAAE,0BAA0B;IACxC,YAAY,EAAE,2CAAiE;;EAMlF,mFAAoD;IACnD,aAAa,EAAE,WAAmE;;EAEnF,iFAAkD;IACjD,aAAa,EAAE,sBAA8E;;EAK7F,gCAAc;IACb,WAAW,EAAE,iBAA0E;;EAExF,+BAAa;IACZ,WAAW,EAAE,CAAC;;EAQd,+BAAW;IACV,KAAK,EAAE,IAAI;IACX,IAAI,EAAE,IAAI;IACV,YAAY,EAAE,0BAA0B;IACxC,YAAY,EAAE,2CAAiE;;EAUnF,oBAAc;IACb,UAAU,EAha8B,4BAA+B;;EAmavE,sBAAE;IACD,OAAO,EAAE,QAAmG;;EAG5G,iCAAW;IACV,GAAG,EAAE,GAAG;IACR,UAAU,EAAE,IAA6B;IACzC,MAAM,EAAE,IAAI;IACZ,IAAI,EAAE,IAAI;IACV,WAAW,EAAE,CAAC;IACd,KAAK,EAAE,IAAI;IACX,YAAY,EAAE,0BAA0B;IACxC,YAAY,EAAE,2CAAiE;;EAKjF,6FAAoD;IACnD,aAAa,EAAE,WAAmE;;EAEnF,2FAAkD;IACjD,aAAa,EAAE,sBAA8E;;EAI9F,yBAAK;IACJ,WAAW,EAAE,YAAY;;EAI1B,uBAAG;IACF,aAAa,EAAE,cAA8C;;EAG7D,yBAAE;IACD,OAAO,EAAE,QAAyF", +"sources": ["_sm-blue-theme.scss","mixins/_round-corners-last-item.scss","mixins/_sub-items-indentation.scss"], +"names": [], +"file": "sm-blue.css" +} diff --git a/civicrm/bower_components/smartmenus/src/css/sm-blue/sm-blue.scss b/civicrm/bower_components/smartmenus/src/css/sm-blue/sm-blue.scss new file mode 100644 index 0000000000..ddb9f1cc2a --- /dev/null +++ b/civicrm/bower_components/smartmenus/src/css/sm-blue/sm-blue.scss @@ -0,0 +1,4 @@ +@import '_mixins.scss'; + +// the variables + the CSS +@import '_sm-blue-theme.scss'; \ No newline at end of file diff --git a/civicrm/bower_components/smartmenus/src/css/sm-clean/_mixins.scss b/civicrm/bower_components/smartmenus/src/css/sm-clean/_mixins.scss new file mode 100644 index 0000000000..0ed06503c8 --- /dev/null +++ b/civicrm/bower_components/smartmenus/src/css/sm-clean/_mixins.scss @@ -0,0 +1,2 @@ +@import 'mixins/_sub-items-indentation.scss'; +@import 'mixins/_round-corners-last-item.scss'; \ No newline at end of file diff --git a/civicrm/bower_components/smartmenus/src/css/sm-clean/_sm-clean-theme.scss b/civicrm/bower_components/smartmenus/src/css/sm-clean/_sm-clean-theme.scss new file mode 100644 index 0000000000..14bd800b0b --- /dev/null +++ b/civicrm/bower_components/smartmenus/src/css/sm-clean/_sm-clean-theme.scss @@ -0,0 +1,579 @@ +// This file is best viewed with Tab size 4 code indentation + + +// ----------------------------------------------------------------------------------------------------------------- +// 1. Theme Quick Settings (Variables) +// (for further control, you will need to dig into the actual CSS in 2.) +// ----------------------------------------------------------------------------------------------------------------- + + +// ---------------------------------------------------------- +// :: 1.1. Colors +// ---------------------------------------------------------- + +$sm-clean__white: #fff !default; +$sm-clean__gray: darken($sm-clean__white, 6.5%) !default; +$sm-clean__gray-dark: darken($sm-clean__white, 26.5%) !default; +$sm-clean__gray-darker: darken($sm-clean__white, 66.5%) !default; +$sm-clean__red: #D23600 !default; + +$sm-clean__box-shadow: rgba(0, 0, 0, 0.2) !default; + + +// ---------------------------------------------------------- +// :: 1.2. Breakpoints +// ---------------------------------------------------------- + +$sm-clean__desktop-vp: 768px !default; // switch from collapsible to desktop + + +// ---------------------------------------------------------- +// :: 1.3. Typography +// ---------------------------------------------------------- + +$sm-clean__font-family: "Lucida Sans Unicode", "Lucida Sans", "Lucida Grande", Arial, sans-serif !default; +$sm-clean__font-size-base: 18px !default; +$sm-clean__font-size-small: 16px !default; +$sm-clean__line-height: 17px !default; + + +// ---------------------------------------------------------- +// :: 1.4. Borders +// ---------------------------------------------------------- + +$sm-clean__border-width: 1px !default; +$sm-clean__border-radius: 5px !default; + + +// ---------------------------------------------------------- +// :: 1.5. Collapsible main menu +// ---------------------------------------------------------- + +// Menu box +$sm-clean__collapsible-bg: $sm-clean__gray !default; +$sm-clean__collapsible-border-radius: $sm-clean__border-radius !default; + +// Items +$sm-clean__collapsible-item-color: $sm-clean__gray-darker !default; +$sm-clean__collapsible-item-current-color: $sm-clean__red !default; +$sm-clean__collapsible-item-disabled-color: darken($sm-clean__gray, 20%) !default; +$sm-clean__collapsible-item-padding-vertical: 13px !default; +$sm-clean__collapsible-item-padding-horizontal: 20px !default; + +// Items separators +$sm-clean__collapsible-separators-color: rgba(0, 0, 0, 0.05) !default; + +// Toggle button (sub menu indicators) +$sm-clean__collapsible-toggle-bg: rgba(255, 255, 255, 0.5) !default; + + +// ---------------------------------------------------------- +// :: 1.6. Collapsible sub menus +// ---------------------------------------------------------- + +// Menu box +$sm-clean__collapsible-sub-bg: rgba(darken($sm-clean__collapsible-bg, 30%), 0.1) !default; + +// Items text indentation for deeper levels +$sm-clean__collapsible-sub-item-indentation: 8px !default; + + +// ---------------------------------------------------------- +// :: 1.7. Desktop main menu +// ---------------------------------------------------------- + +// Menu box +$sm-clean__desktop-bg: $sm-clean__gray !default; +$sm-clean__desktop-border-radius: 100px !default; +$sm-clean__desktop-padding-horizontal: 10px !default; + +// Items +$sm-clean__desktop-item-color: $sm-clean__gray-darker !default; +$sm-clean__desktop-item-hover-color: $sm-clean__red !default; +$sm-clean__desktop-item-current-color: $sm-clean__red !default; +$sm-clean__desktop-item-disabled-color: darken($sm-clean__gray, 20%) !default; +$sm-clean__desktop-item-padding-vertical: 12px !default; +$sm-clean__desktop-item-padding-horizontal: 12px !default; + +// Sub menu indicators +$sm-clean__desktop-arrow-size: 4px !default; // border-width +$sm-clean__desktop-arrow-color: $sm-clean__gray-darker !default; +$sm-clean__desktop-arrow-spacing: 4px !default; + +// Vertical menu box +$sm-clean__desktop-vertical-border-radius: $sm-clean__border-radius !default; +$sm-clean__desktop-vertical-padding-vertical: 10px !default; + +// Vertical items +$sm-clean__desktop-vertical-item-hover-bg: $sm-clean__white !default; +$sm-clean__desktop-vertical-item-padding-vertical: 10px !default; +$sm-clean__desktop-vertical-item-padding-horizontal: 20px !default; + + +// ---------------------------------------------------------- +// :: 1.8. Desktop sub menus +// ---------------------------------------------------------- + +// Menu box +$sm-clean__desktop-sub-bg: $sm-clean__white !default; +$sm-clean__desktop-sub-border-color: $sm-clean__gray-dark !default; +$sm-clean__desktop-sub-border-radius: $sm-clean__border-radius !default; +$sm-clean__desktop-sub-box-shadow: 0 5px 9px $sm-clean__box-shadow !default; +$sm-clean__desktop-sub-padding-vertical: 5px !default; +$sm-clean__desktop-sub-padding-horizontal: 0 !default; + +// Items +$sm-clean__desktop-sub-item-color: $sm-clean__gray-darker !default; +$sm-clean__desktop-sub-item-hover-color: $sm-clean__red !default; +$sm-clean__desktop-sub-item-hover-bg: $sm-clean__gray !default; +$sm-clean__desktop-sub-item-current-color: $sm-clean__red !default; +$sm-clean__desktop-sub-item-disabled-color: darken($sm-clean__white, 20%) !default; +$sm-clean__desktop-sub-item-padding-vertical: 10px !default; +$sm-clean__desktop-sub-item-padding-horizontal: 20px !default; + +// Sub menu indicators +$sm-clean__desktop-sub-arrow-size: 5px !default; // border-width + +// Sub menu carets +$sm-clean__desktop-sub-caret-size: 8px !default; // border-width +$sm-clean__desktop-sub-caret-left: 30px !default; + + +// ----------------------------------------------------------------------------------------------------------------- +// 2. Theme CSS +// ----------------------------------------------------------------------------------------------------------------- + + +// ---------------------------------------------------------- +// :: 2.1. Collapsible mode (mobile first) +// ---------------------------------------------------------- + +// calc item height and sub menus toggle button size +$sm-clean__item-height: $sm-clean__line-height + $sm-clean__collapsible-item-padding-vertical * 2; +// set toggle button size to 80% of item height +$sm-clean__toggle-size: floor($sm-clean__item-height * 0.8); +$sm-clean__toggle-spacing: floor($sm-clean__item-height * 0.1); + +// Main menu box +.sm-clean { + background: $sm-clean__collapsible-bg; + border-radius: $sm-clean__collapsible-border-radius; + + // Main menu items + a { + &, + &:hover, + &:focus, + &:active { + padding: $sm-clean__collapsible-item-padding-vertical $sm-clean__collapsible-item-padding-horizontal; + /* make room for the toggle button (sub indicator) */ + padding-right: $sm-clean__collapsible-item-padding-horizontal + $sm-clean__toggle-size + $sm-clean__toggle-spacing; + color: $sm-clean__collapsible-item-color; + font-family: $sm-clean__font-family; + font-size: $sm-clean__font-size-base; + font-weight: normal; + line-height: $sm-clean__line-height; + text-decoration: none; + } + + &.current { + color: $sm-clean__collapsible-item-current-color; + } + + &.disabled { + color: $sm-clean__collapsible-item-disabled-color; + } + + // Toggle buttons (sub menu indicators) + .sub-arrow { + position: absolute; + top: 50%; + margin-top: -(ceil($sm-clean__toggle-size / 2)); + left: auto; + right: $sm-clean__toggle-spacing; + width: $sm-clean__toggle-size; + height: $sm-clean__toggle-size; + overflow: hidden; + font: bold #{$sm-clean__font-size-small}/#{$sm-clean__toggle-size} monospace !important; + text-align: center; + text-shadow: none; + background: $sm-clean__collapsible-toggle-bg; + border-radius: $sm-clean__border-radius; + } + .sub-arrow::before { + content: '+'; + } + &.highlighted .sub-arrow::before { + content: '-'; + } + } + + // round the corners of the first item + > li:first-child > a, > li:first-child > :not(ul) a { + border-radius: $sm-clean__collapsible-border-radius $sm-clean__collapsible-border-radius 0 0; + } + // round the corners of the last item + @include sm-clean__round-corners-last-item($sm-clean__collapsible-border-radius); + + // Main menu items separators + li { + border-top: 1px solid $sm-clean__collapsible-separators-color; + } + > li:first-child { + border-top: 0; + } + + // Sub menus box + ul { + background: $sm-clean__collapsible-sub-bg; + + // Sub menus items + a { + &, + &:hover, + &:focus, + &:active { + font-size: $sm-clean__font-size-small; + // add indentation for sub menus text + border-left: $sm-clean__collapsible-sub-item-indentation solid transparent; + } + } + + // Add indentation for sub menus text for deeper levels + @include sm-clean__sub-items-indentation($sm-clean__collapsible-sub-item-indentation); + } +} + + +// ---------------------------------------------------------- +// :: 2.2. Desktop mode +// ---------------------------------------------------------- + +@media (min-width: $sm-clean__desktop-vp) { + + /* Switch to desktop layout + ----------------------------------------------- + These transform the menu tree from + collapsible to desktop (navbar + dropdowns) + -----------------------------------------------*/ + /* start... (it's not recommended editing these rules) */ + .sm-clean ul{position:absolute;width:12em;} + .sm-clean li{float:left;} + .sm-clean.sm-rtl li{float:right;} + .sm-clean ul li,.sm-clean.sm-rtl ul li,.sm-clean.sm-vertical li{float:none;} + .sm-clean a{white-space:nowrap;} + .sm-clean ul a,.sm-clean.sm-vertical a{white-space:normal;} + .sm-clean .sm-nowrap > li > a,.sm-clean .sm-nowrap > li > :not(ul) a{white-space:nowrap;} + /* ...end */ + + // Main menu box + .sm-clean { + padding: 0 $sm-clean__desktop-padding-horizontal; + background: $sm-clean__desktop-bg; + border-radius: $sm-clean__desktop-border-radius; + + // Main menu items + a { + &, + &:hover, + &:focus, + &:active, + &.highlighted { + padding: $sm-clean__desktop-item-padding-vertical $sm-clean__desktop-item-padding-horizontal; + color: $sm-clean__desktop-item-color; + border-radius: 0 !important; + } + + &:hover, + &:focus, + &:active, + &.highlighted { + color: $sm-clean__desktop-item-hover-color; + } + + &.current { + color: $sm-clean__desktop-item-current-color; + } + + &.disabled { + color: $sm-clean__desktop-item-disabled-color; + } + + // Make room for the sub arrows + &.has-submenu { + padding-right: $sm-clean__desktop-item-padding-horizontal + $sm-clean__desktop-arrow-size * 2 + $sm-clean__desktop-arrow-spacing; + } + + // Sub menu indicators + .sub-arrow { + top: 50%; + margin-top: -(ceil($sm-clean__desktop-arrow-size / 2)); + right: $sm-clean__desktop-item-padding-horizontal; + width: 0; + height: 0; + border-width: $sm-clean__desktop-arrow-size; + border-style: solid dashed dashed dashed; + border-color: $sm-clean__desktop-arrow-color transparent transparent transparent; + background: transparent; + border-radius: 0; + } + // reset mobile first style + .sub-arrow::before { + display: none; + } + } + + // No main menu items separators + li { + border-top: 0; + } + + // First sub level carets + > li > ul::before, + > li > ul::after { + content: ''; + position: absolute; + top: -($sm-clean__desktop-sub-caret-size * 2 + $sm-clean__border-width * 2); + left: $sm-clean__desktop-sub-caret-left; + width: 0; + height: 0; + overflow: hidden; + border-width: ($sm-clean__desktop-sub-caret-size + $sm-clean__border-width); + border-style: dashed dashed solid dashed; + border-color: transparent transparent $sm-clean__desktop-sub-border-color transparent; + } + > li > ul::after { + top: -($sm-clean__desktop-sub-caret-size * 2); + left: ($sm-clean__desktop-sub-caret-left + $sm-clean__border-width); + border-width: $sm-clean__desktop-sub-caret-size; + border-color: transparent transparent $sm-clean__desktop-sub-bg transparent; + } + + // Sub menus box + ul { + border: $sm-clean__border-width solid $sm-clean__desktop-sub-border-color; + padding: $sm-clean__desktop-sub-padding-vertical $sm-clean__desktop-sub-padding-horizontal; + background: $sm-clean__desktop-sub-bg; + border-radius: $sm-clean__desktop-sub-border-radius !important; + box-shadow: $sm-clean__desktop-sub-box-shadow; + + // Sub menus items + a { + &, + &:hover, + &:focus, + &:active, + &.highlighted { + border: 0 !important; + padding: $sm-clean__desktop-sub-item-padding-vertical $sm-clean__desktop-sub-item-padding-horizontal; + color: $sm-clean__desktop-sub-item-color; + } + + &:hover, + &:focus, + &:active, + &.highlighted { + background: $sm-clean__desktop-sub-item-hover-bg; + color: $sm-clean__desktop-sub-item-hover-color; + } + + &.current { + color: $sm-clean__desktop-sub-item-current-color; + } + + &.disabled { + background: $sm-clean__desktop-sub-bg; + color: $sm-clean__desktop-sub-item-disabled-color; + } + + // No need for additional room for the sub arrows + &.has-submenu { + padding-right: $sm-clean__desktop-sub-item-padding-horizontal; + } + + // Sub menu indicators + .sub-arrow { + right: 8px; + top: 50%; + margin-top: -$sm-clean__desktop-sub-arrow-size; + border-width: $sm-clean__desktop-sub-arrow-size; + border-style: dashed dashed dashed solid; + border-color: transparent transparent transparent $sm-clean__desktop-arrow-color; + } + } + } + + // Scrolling arrows containers for tall sub menus - test sub menu: "Sub test" -> "more..." in the default download package + .scroll-up, + .scroll-down { + position: absolute; + display: none; + visibility: hidden; + overflow: hidden; + background: $sm-clean__desktop-sub-bg; + height: 20px; + // width and position will be set automatically by the script + + &:hover { + background: $sm-clean__desktop-sub-item-hover-bg; + } + } + .scroll-up:hover .scroll-up-arrow { + border-color: transparent transparent $sm-clean__desktop-sub-item-hover-color transparent; + } + .scroll-down:hover .scroll-down-arrow { + border-color: $sm-clean__desktop-sub-item-hover-color transparent transparent transparent; + } + .scroll-up-arrow, + .scroll-down-arrow { + position: absolute; + top: 0; + left: 50%; + margin-left: -6px; + // we will use one-side border to create a triangle so that we don't use a real background image, of course, you can use a real image if you like too + width: 0; + height: 0; + overflow: hidden; + border-width: 6px; // tweak size of the arrow + border-style: dashed dashed solid dashed; + border-color: transparent transparent $sm-clean__desktop-sub-item-color transparent; + } + .scroll-down-arrow { + top: 8px; + border-style: solid dashed dashed dashed; + border-color: $sm-clean__desktop-sub-item-color transparent transparent transparent; + } + + + // Rigth-to-left + + // Main menu box + &.sm-rtl { + + // Main menu items + a { + + // Make room for the sub arrows + &.has-submenu { + padding-right: $sm-clean__desktop-item-padding-horizontal; + padding-left: $sm-clean__desktop-item-padding-horizontal + $sm-clean__desktop-arrow-size * 2 + $sm-clean__desktop-arrow-spacing; + } + + // Sub menu indicators + .sub-arrow { + right: auto; + left: $sm-clean__desktop-item-padding-horizontal; + } + } + + // Vertical main menu items + &.sm-vertical { + a { + + // No need for additional room for the sub arrows + &.has-submenu { + padding: $sm-clean__desktop-vertical-item-padding-vertical $sm-clean__desktop-vertical-item-padding-horizontal; + } + + // Sub menu indicators + .sub-arrow { + right: auto; + left: 8px; + border-style: dashed solid dashed dashed; + border-color: transparent $sm-clean__desktop-arrow-color transparent transparent; + } + } + } + + // First sub level carets + > li > ul::before { + left: auto; + right: $sm-clean__desktop-sub-caret-left; + } + > li > ul::after { + left: auto; + right: ($sm-clean__desktop-sub-caret-left + $sm-clean__border-width); + } + + // Sub menus box + ul { + a { + + // No need for additional room for the sub arrows + &.has-submenu { + padding: $sm-clean__desktop-sub-item-padding-vertical $sm-clean__desktop-sub-item-padding-horizontal !important; + } + + // Sub menu indicators + .sub-arrow { + right: auto; + left: 8px; + border-style: dashed solid dashed dashed; + border-color: transparent $sm-clean__desktop-arrow-color transparent transparent; + } + } + } + } + + + // Vertical main menu + + // Main menu box + &.sm-vertical { + padding: $sm-clean__desktop-vertical-padding-vertical 0; + border-radius: $sm-clean__desktop-vertical-border-radius; + + // Main menu items + a { + padding: $sm-clean__desktop-vertical-item-padding-vertical $sm-clean__desktop-vertical-item-padding-horizontal; + + &:hover, + &:focus, + &:active, + &.highlighted { + background: $sm-clean__desktop-vertical-item-hover-bg; + } + + &.disabled { + background: $sm-clean__desktop-bg; + } + + // Sub menu indicators + .sub-arrow { + right: 8px; + top: 50%; + margin-top: -$sm-clean__desktop-sub-arrow-size; + border-width: $sm-clean__desktop-sub-arrow-size; + border-style: dashed dashed dashed solid; + border-color: transparent transparent transparent $sm-clean__desktop-arrow-color; + } + } + + // No sub level carets + > li > ul::before, + > li > ul::after { + display: none; + } + + // Sub menus box + ul { + + // Sub menus items + a { + padding: $sm-clean__desktop-sub-item-padding-vertical $sm-clean__desktop-sub-item-padding-horizontal; + + &:hover, + &:focus, + &:active, + &.highlighted { + background: $sm-clean__desktop-sub-item-hover-bg; + } + + &.disabled { + background: $sm-clean__desktop-sub-bg; + } + } + } + } + } +} \ No newline at end of file diff --git a/civicrm/bower_components/smartmenus/src/css/sm-clean/mixins/_round-corners-last-item.scss b/civicrm/bower_components/smartmenus/src/css/sm-clean/mixins/_round-corners-last-item.scss new file mode 100644 index 0000000000..3687ba4c97 --- /dev/null +++ b/civicrm/bower_components/smartmenus/src/css/sm-clean/mixins/_round-corners-last-item.scss @@ -0,0 +1,25 @@ +// Generate rules to round the corners of the last collapsible item + +@mixin sm-clean__round-corners-last-item($amount, $chainable: 'ul > li:last-child > ', $level: 4, $chain_prefix: '> li:last-child > ', $chain: '', $selector: '') { + $chain: $chain_prefix; + $selector: $chain + 'a, ' + $chain + '*:not(ul) a, ' + $chain + 'ul'; + @for $i from 1 through $level { + $chain: $chain + $chainable; + $selector: $selector + ', +' + $chain + ' a, ' + $chain + '*:not(ul) a, ' + $chain + ' ul'; + } + #{$selector} { + border-radius: 0 0 $amount $amount; + } + // highlighted items, don't need rounding since their sub is open + $chain: $chain_prefix; + $selector: $chain + 'a.highlighted, ' + $chain + '*:not(ul) a.highlighted'; + @for $i from 1 through $level { + $chain: $chain + $chainable; + $selector: $selector + ', +' + $chain + ' a.highlighted, ' + $chain + '*:not(ul) a.highlighted'; + } + #{$selector} { + border-radius: 0; + } +} \ No newline at end of file diff --git a/civicrm/bower_components/smartmenus/src/css/sm-clean/mixins/_sub-items-indentation.scss b/civicrm/bower_components/smartmenus/src/css/sm-clean/mixins/_sub-items-indentation.scss new file mode 100644 index 0000000000..0225b65c23 --- /dev/null +++ b/civicrm/bower_components/smartmenus/src/css/sm-clean/mixins/_sub-items-indentation.scss @@ -0,0 +1,15 @@ +// Generate rules to indent sub menus text +// +// We'll use left border to avoid messing with the padding. + +@mixin sm-clean__sub-items-indentation($amount, $chainable: 'ul ', $level: 4, $chain: '') { + @for $i from 1 through $level { + $chain: $chain + $chainable; + #{$chain} a, + #{$chain} a:hover, + #{$chain} a:focus, + #{$chain} a:active { + border-left: ($amount * ($i + 1)) solid transparent; + } + } +} \ No newline at end of file diff --git a/civicrm/bower_components/smartmenus/src/css/sm-clean/sm-clean.css b/civicrm/bower_components/smartmenus/src/css/sm-clean/sm-clean.css new file mode 100644 index 0000000000..4fb39b72f6 --- /dev/null +++ b/civicrm/bower_components/smartmenus/src/css/sm-clean/sm-clean.css @@ -0,0 +1,327 @@ +.sm-clean { + background: #eeeeee; + border-radius: 5px; +} +.sm-clean a, .sm-clean a:hover, .sm-clean a:focus, .sm-clean a:active { + padding: 13px 20px; + /* make room for the toggle button (sub indicator) */ + padding-right: 58px; + color: #555555; + font-family: "Lucida Sans Unicode", "Lucida Sans", "Lucida Grande", Arial, sans-serif; + font-size: 18px; + font-weight: normal; + line-height: 17px; + text-decoration: none; +} +.sm-clean a.current { + color: #D23600; +} +.sm-clean a.disabled { + color: #bbbbbb; +} +.sm-clean a .sub-arrow { + position: absolute; + top: 50%; + margin-top: -17px; + left: auto; + right: 4px; + width: 34px; + height: 34px; + overflow: hidden; + font: bold 16px/34px monospace !important; + text-align: center; + text-shadow: none; + background: rgba(255, 255, 255, 0.5); + border-radius: 5px; +} +.sm-clean a .sub-arrow::before { + content: '+'; +} +.sm-clean a.highlighted .sub-arrow::before { + content: '-'; +} +.sm-clean > li:first-child > a, .sm-clean > li:first-child > :not(ul) a { + border-radius: 5px 5px 0 0; +} +.sm-clean > li:last-child > a, .sm-clean > li:last-child > *:not(ul) a, .sm-clean > li:last-child > ul, .sm-clean > li:last-child > ul > li:last-child > a, .sm-clean > li:last-child > ul > li:last-child > *:not(ul) a, .sm-clean > li:last-child > ul > li:last-child > ul, .sm-clean > li:last-child > ul > li:last-child > ul > li:last-child > a, .sm-clean > li:last-child > ul > li:last-child > ul > li:last-child > *:not(ul) a, .sm-clean > li:last-child > ul > li:last-child > ul > li:last-child > ul, .sm-clean > li:last-child > ul > li:last-child > ul > li:last-child > ul > li:last-child > a, .sm-clean > li:last-child > ul > li:last-child > ul > li:last-child > ul > li:last-child > *:not(ul) a, .sm-clean > li:last-child > ul > li:last-child > ul > li:last-child > ul > li:last-child > ul, .sm-clean > li:last-child > ul > li:last-child > ul > li:last-child > ul > li:last-child > ul > li:last-child > a, .sm-clean > li:last-child > ul > li:last-child > ul > li:last-child > ul > li:last-child > ul > li:last-child > *:not(ul) a, .sm-clean > li:last-child > ul > li:last-child > ul > li:last-child > ul > li:last-child > ul > li:last-child > ul { + border-radius: 0 0 5px 5px; +} +.sm-clean > li:last-child > a.highlighted, .sm-clean > li:last-child > *:not(ul) a.highlighted, .sm-clean > li:last-child > ul > li:last-child > a.highlighted, .sm-clean > li:last-child > ul > li:last-child > *:not(ul) a.highlighted, .sm-clean > li:last-child > ul > li:last-child > ul > li:last-child > a.highlighted, .sm-clean > li:last-child > ul > li:last-child > ul > li:last-child > *:not(ul) a.highlighted, .sm-clean > li:last-child > ul > li:last-child > ul > li:last-child > ul > li:last-child > a.highlighted, .sm-clean > li:last-child > ul > li:last-child > ul > li:last-child > ul > li:last-child > *:not(ul) a.highlighted, .sm-clean > li:last-child > ul > li:last-child > ul > li:last-child > ul > li:last-child > ul > li:last-child > a.highlighted, .sm-clean > li:last-child > ul > li:last-child > ul > li:last-child > ul > li:last-child > ul > li:last-child > *:not(ul) a.highlighted { + border-radius: 0; +} +.sm-clean li { + border-top: 1px solid rgba(0, 0, 0, 0.05); +} +.sm-clean > li:first-child { + border-top: 0; +} +.sm-clean ul { + background: rgba(162, 162, 162, 0.1); +} +.sm-clean ul a, .sm-clean ul a:hover, .sm-clean ul a:focus, .sm-clean ul a:active { + font-size: 16px; + border-left: 8px solid transparent; +} +.sm-clean ul ul a, +.sm-clean ul ul a:hover, +.sm-clean ul ul a:focus, +.sm-clean ul ul a:active { + border-left: 16px solid transparent; +} +.sm-clean ul ul ul a, +.sm-clean ul ul ul a:hover, +.sm-clean ul ul ul a:focus, +.sm-clean ul ul ul a:active { + border-left: 24px solid transparent; +} +.sm-clean ul ul ul ul a, +.sm-clean ul ul ul ul a:hover, +.sm-clean ul ul ul ul a:focus, +.sm-clean ul ul ul ul a:active { + border-left: 32px solid transparent; +} +.sm-clean ul ul ul ul ul a, +.sm-clean ul ul ul ul ul a:hover, +.sm-clean ul ul ul ul ul a:focus, +.sm-clean ul ul ul ul ul a:active { + border-left: 40px solid transparent; +} + +@media (min-width: 768px) { + /* Switch to desktop layout + ----------------------------------------------- + These transform the menu tree from + collapsible to desktop (navbar + dropdowns) + -----------------------------------------------*/ + /* start... (it's not recommended editing these rules) */ + .sm-clean ul { + position: absolute; + width: 12em; + } + + .sm-clean li { + float: left; + } + + .sm-clean.sm-rtl li { + float: right; + } + + .sm-clean ul li, .sm-clean.sm-rtl ul li, .sm-clean.sm-vertical li { + float: none; + } + + .sm-clean a { + white-space: nowrap; + } + + .sm-clean ul a, .sm-clean.sm-vertical a { + white-space: normal; + } + + .sm-clean .sm-nowrap > li > a, .sm-clean .sm-nowrap > li > :not(ul) a { + white-space: nowrap; + } + + /* ...end */ + .sm-clean { + padding: 0 10px; + background: #eeeeee; + border-radius: 100px; + } + .sm-clean a, .sm-clean a:hover, .sm-clean a:focus, .sm-clean a:active, .sm-clean a.highlighted { + padding: 12px 12px; + color: #555555; + border-radius: 0 !important; + } + .sm-clean a:hover, .sm-clean a:focus, .sm-clean a:active, .sm-clean a.highlighted { + color: #D23600; + } + .sm-clean a.current { + color: #D23600; + } + .sm-clean a.disabled { + color: #bbbbbb; + } + .sm-clean a.has-submenu { + padding-right: 24px; + } + .sm-clean a .sub-arrow { + top: 50%; + margin-top: -2px; + right: 12px; + width: 0; + height: 0; + border-width: 4px; + border-style: solid dashed dashed dashed; + border-color: #555555 transparent transparent transparent; + background: transparent; + border-radius: 0; + } + .sm-clean a .sub-arrow::before { + display: none; + } + .sm-clean li { + border-top: 0; + } + .sm-clean > li > ul::before, + .sm-clean > li > ul::after { + content: ''; + position: absolute; + top: -18px; + left: 30px; + width: 0; + height: 0; + overflow: hidden; + border-width: 9px; + border-style: dashed dashed solid dashed; + border-color: transparent transparent #bbbbbb transparent; + } + .sm-clean > li > ul::after { + top: -16px; + left: 31px; + border-width: 8px; + border-color: transparent transparent #fff transparent; + } + .sm-clean ul { + border: 1px solid #bbbbbb; + padding: 5px 0; + background: #fff; + border-radius: 5px !important; + box-shadow: 0 5px 9px rgba(0, 0, 0, 0.2); + } + .sm-clean ul a, .sm-clean ul a:hover, .sm-clean ul a:focus, .sm-clean ul a:active, .sm-clean ul a.highlighted { + border: 0 !important; + padding: 10px 20px; + color: #555555; + } + .sm-clean ul a:hover, .sm-clean ul a:focus, .sm-clean ul a:active, .sm-clean ul a.highlighted { + background: #eeeeee; + color: #D23600; + } + .sm-clean ul a.current { + color: #D23600; + } + .sm-clean ul a.disabled { + background: #fff; + color: #cccccc; + } + .sm-clean ul a.has-submenu { + padding-right: 20px; + } + .sm-clean ul a .sub-arrow { + right: 8px; + top: 50%; + margin-top: -5px; + border-width: 5px; + border-style: dashed dashed dashed solid; + border-color: transparent transparent transparent #555555; + } + .sm-clean .scroll-up, + .sm-clean .scroll-down { + position: absolute; + display: none; + visibility: hidden; + overflow: hidden; + background: #fff; + height: 20px; + } + .sm-clean .scroll-up:hover, + .sm-clean .scroll-down:hover { + background: #eeeeee; + } + .sm-clean .scroll-up:hover .scroll-up-arrow { + border-color: transparent transparent #D23600 transparent; + } + .sm-clean .scroll-down:hover .scroll-down-arrow { + border-color: #D23600 transparent transparent transparent; + } + .sm-clean .scroll-up-arrow, + .sm-clean .scroll-down-arrow { + position: absolute; + top: 0; + left: 50%; + margin-left: -6px; + width: 0; + height: 0; + overflow: hidden; + border-width: 6px; + border-style: dashed dashed solid dashed; + border-color: transparent transparent #555555 transparent; + } + .sm-clean .scroll-down-arrow { + top: 8px; + border-style: solid dashed dashed dashed; + border-color: #555555 transparent transparent transparent; + } + .sm-clean.sm-rtl a.has-submenu { + padding-right: 12px; + padding-left: 24px; + } + .sm-clean.sm-rtl a .sub-arrow { + right: auto; + left: 12px; + } + .sm-clean.sm-rtl.sm-vertical a.has-submenu { + padding: 10px 20px; + } + .sm-clean.sm-rtl.sm-vertical a .sub-arrow { + right: auto; + left: 8px; + border-style: dashed solid dashed dashed; + border-color: transparent #555555 transparent transparent; + } + .sm-clean.sm-rtl > li > ul::before { + left: auto; + right: 30px; + } + .sm-clean.sm-rtl > li > ul::after { + left: auto; + right: 31px; + } + .sm-clean.sm-rtl ul a.has-submenu { + padding: 10px 20px !important; + } + .sm-clean.sm-rtl ul a .sub-arrow { + right: auto; + left: 8px; + border-style: dashed solid dashed dashed; + border-color: transparent #555555 transparent transparent; + } + .sm-clean.sm-vertical { + padding: 10px 0; + border-radius: 5px; + } + .sm-clean.sm-vertical a { + padding: 10px 20px; + } + .sm-clean.sm-vertical a:hover, .sm-clean.sm-vertical a:focus, .sm-clean.sm-vertical a:active, .sm-clean.sm-vertical a.highlighted { + background: #fff; + } + .sm-clean.sm-vertical a.disabled { + background: #eeeeee; + } + .sm-clean.sm-vertical a .sub-arrow { + right: 8px; + top: 50%; + margin-top: -5px; + border-width: 5px; + border-style: dashed dashed dashed solid; + border-color: transparent transparent transparent #555555; + } + .sm-clean.sm-vertical > li > ul::before, + .sm-clean.sm-vertical > li > ul::after { + display: none; + } + .sm-clean.sm-vertical ul a { + padding: 10px 20px; + } + .sm-clean.sm-vertical ul a:hover, .sm-clean.sm-vertical ul a:focus, .sm-clean.sm-vertical ul a:active, .sm-clean.sm-vertical ul a.highlighted { + background: #eeeeee; + } + .sm-clean.sm-vertical ul a.disabled { + background: #fff; + } +} + +/*# sourceMappingURL=sm-clean.css.map */ diff --git a/civicrm/bower_components/smartmenus/src/css/sm-clean/sm-clean.css.map b/civicrm/bower_components/smartmenus/src/css/sm-clean/sm-clean.css.map new file mode 100644 index 0000000000..552d708b90 --- /dev/null +++ b/civicrm/bower_components/smartmenus/src/css/sm-clean/sm-clean.css.map @@ -0,0 +1,7 @@ +{ +"version": 3, +"mappings": "AA6JA,SAAU;EACT,UAAU,EA/B+B,OAAe;EAgCxD,aAAa,EA1G4B,GAAwB;;AA8GhE,qEAGS;EACR,OAAO,EAAE,SAA2F;EACpG,qDAAqD;EACrD,aAAa,EAAE,IAAmG;EAClH,KAAK,EA7CgC,OAAsB;EA8C3D,WAAW,EA1IkB,wEAAwE;EA2IrG,SAAS,EA1IsB,IAAI;EA2InC,WAAW,EAAE,MAAM;EACnB,WAAW,EA1IkB,IAAI;EA2IjC,eAAe,EAAE,IAAI;;AAGtB,mBAAU;EACT,KAAK,EAnDsC,OAAc;;AAsD1D,oBAAW;EACV,KAAK,EA7HuC,OAA4B;;AAiIzE,sBAAW;EACV,QAAQ,EAAE,QAAQ;EAClB,GAAG,EAAE,GAAG;EACR,UAAU,EAAE,KAAmC;EAC/C,IAAI,EAAE,IAAI;EACV,KAAK,EAtCmB,GAAmC;EAuC3D,KAAK,EAxCgB,IAAmC;EAyCxD,MAAM,EAzCe,IAAmC;EA0CxD,QAAQ,EAAE,MAAM;EAChB,IAAI,EAAE,mCAAiF;EACvF,UAAU,EAAE,MAAM;EAClB,WAAW,EAAE,IAAI;EACjB,UAAU,EArI0B,wBAAwB;EAsI5D,aAAa,EA5JiB,GAAG;;AA8JlC,8BAAmB;EAClB,OAAO,EAAE,GAAG;;AAEb,0CAAiC;EAChC,OAAO,EAAE,GAAG;;AAKd,uEAAoD;EACnD,aAAa,EAAE,WAA6E;;AC1M7F,4nCAAa;EACZ,aAAa,EAAE,WAAmB;;AAUnC,k4BAAa;EACZ,aAAa,EAAE,CAAC;;ADoMjB,YAAG;EACF,UAAU,EAAE,6BAAiD;;AAE9D,0BAAiB;EAChB,UAAU,EAAE,CAAC;;AAId,YAAG;EACF,UAAU,EAzJyB,wBAAiD;;AA6JnF,iFAGS;EACR,SAAS,EAxMsB,IAAI;EA0MnC,WAAW,EAAE,qBAA6D;;AEtO5E;;;wBAGmB;EAClB,WAAW,EAAE,sBAAsC;;AAJpD;;;2BAGmB;EAClB,WAAW,EAAE,sBAAsC;;AAJpD;;;8BAGmB;EAClB,WAAW,EAAE,sBAAsC;;AAJpD;;;iCAGmB;EAClB,WAAW,EAAE,sBAAsC;;;AFgPtD,yBAA0C;EAEzC;;;;mDAIiD;EACjD,yDAAyD;EACzD,YAAY;IAAC,QAAQ,EAAC,QAAQ;IAAC,KAAK,EAAC,IAAI;;;EACzC,YAAY;IAAC,KAAK,EAAC,IAAI;;;EACvB,mBAAmB;IAAC,KAAK,EAAC,KAAK;;;EAC/B,iEAA+D;IAAC,KAAK,EAAC,IAAI;;;EAC1E,WAAW;IAAC,WAAW,EAAC,MAAM;;;EAC9B,uCAAsC;IAAC,WAAW,EAAC,MAAM;;;EACzD,qEAAoE;IAAC,WAAW,EAAC,MAAM;;;EACvF,YAAY;EAGZ,SAAU;IACT,OAAO,EAAE,MAAuC;IAChD,UAAU,EAhJ8B,OAAe;IAiJvD,aAAa,EA1LwB,KAAK;;EA8LzC,8FAIc;IACb,OAAO,EAAE,SAAmF;IAC5F,KAAK,EA7J+B,OAAsB;IA8J1D,aAAa,EAAE,YAAY;;EAG5B,iFAGc;IACb,KAAK,EAlKqC,OAAc;;EAqKzD,mBAAU;IACT,KAAK,EAtKqC,OAAc;;EAyKzD,oBAAW;IACV,KAAK,EA7MmC,OAA4B;;EAiNrE,uBAAc;IACb,aAAa,EAAE,IAAiH;;EAIjI,sBAAW;IACV,GAAG,EAAE,GAAG;IACR,UAAU,EAAE,IAA0C;IACtD,KAAK,EAvNsC,IAAI;IAwN/C,KAAK,EAAE,CAAC;IACR,MAAM,EAAE,CAAC;IACT,YAAY,EAvNqB,GAAG;IAwNpC,YAAY,EAAE,0BAA0B;IACxC,YAAY,EAAE,2CAAkE;IAChF,UAAU,EAAE,WAAW;IACvB,aAAa,EAAE,CAAC;;EAGjB,8BAAmB;IAClB,OAAO,EAAE,IAAI;;EAKf,YAAG;IACF,UAAU,EAAE,CAAC;;EAId;4BACkB;IACjB,OAAO,EAAE,EAAE;IACX,QAAQ,EAAE,QAAQ;IAClB,GAAG,EAAE,KAAsE;IAC3E,IAAI,EAtMiC,IAAI;IAuMzC,KAAK,EAAE,CAAC;IACR,MAAM,EAAE,CAAC;IACT,QAAQ,EAAE,MAAM;IAChB,YAAY,EAAE,GAA6D;IAC3E,YAAY,EAAE,0BAA0B;IACxC,YAAY,EAAE,2CAAuE;;EAEtF,0BAAiB;IAChB,GAAG,EAAE,KAAwC;IAC7C,IAAI,EAAE,IAA6D;IACnE,YAAY,EAlNyB,GAAG;IAmNxC,YAAY,EAAE,wCAA6D;;EAI5E,YAAG;IACF,MAAM,EAAE,iBAAiE;IACzE,OAAO,EAAE,KAAiF;IAC1F,UAAU,EA9OqB,IAAgB;IA+O/C,aAAa,EAAE,cAA+C;IAC9D,UAAU,EA7O2B,4BAAgC;;EAiPpE,6GAIc;IACb,MAAM,EAAE,YAAY;IACpB,OAAO,EAAE,SAA2F;IACpG,KAAK,EAnP8B,OAAsB;;EAsP1D,6FAGc;IACb,UAAU,EAxP2B,OAAe;IAyPpD,KAAK,EAxPoC,OAAc;;EA2PxD,sBAAU;IACT,KAAK,EA5PoC,OAAc;;EA+PxD,uBAAW;IACV,UAAU,EA3QmB,IAAgB;IA4Q7C,KAAK,EAhQqC,OAA6B;;EAoQxE,0BAAc;IACb,aAAa,EAnQgC,IAAI;;EAuQlD,yBAAW;IACV,KAAK,EAAE,GAAG;IACV,GAAG,EAAE,GAAG;IACR,UAAU,EAAE,IAAkC;IAC9C,YAAY,EAxQuB,GAAG;IAyQtC,YAAY,EAAE,0BAA0B;IACxC,YAAY,EAAE,2CAAkE;;EAMnF;wBACc;IACb,QAAQ,EAAE,QAAQ;IAClB,OAAO,EAAE,IAAI;IACb,UAAU,EAAE,MAAM;IAClB,QAAQ,EAAE,MAAM;IAChB,UAAU,EAvSqB,IAAgB;IAwS/C,MAAM,EAAE,IAAI;;EAGZ;8BAAQ;IACP,UAAU,EAlS4B,OAAe;;EAqSvD,2CAAkC;IACjC,YAAY,EAAE,2CAA2E;;EAE1F,+CAAsC;IACrC,YAAY,EAAE,2CAA2E;;EAE1F;8BACmB;IAClB,QAAQ,EAAE,QAAQ;IAClB,GAAG,EAAE,CAAC;IACN,IAAI,EAAE,GAAG;IACT,WAAW,EAAE,IAAI;IAEjB,KAAK,EAAE,CAAC;IACR,MAAM,EAAE,CAAC;IACT,QAAQ,EAAE,MAAM;IAChB,YAAY,EAAE,GAAG;IACjB,YAAY,EAAE,0BAA0B;IACxC,YAAY,EAAE,2CAAqE;;EAEpF,4BAAmB;IAClB,GAAG,EAAE,GAAG;IACR,YAAY,EAAE,0BAA0B;IACxC,YAAY,EAAE,2CAAqE;;EAalF,8BAAc;IACb,aAAa,EA1W6B,IAAI;IA2W9C,YAAY,EAAE,IAAiH;;EAIhI,6BAAW;IACV,KAAK,EAAE,IAAI;IACX,IAAI,EAjXsC,IAAI;;EA0X9C,0CAAc;IACb,OAAO,EAAE,SAAqG;;EAI/G,yCAAW;IACV,KAAK,EAAE,IAAI;IACX,IAAI,EAAE,GAAG;IACT,YAAY,EAAE,0BAA0B;IACxC,YAAY,EAAE,2CAAkE;;EAMnF,kCAAkB;IACjB,IAAI,EAAE,IAAI;IACV,KAAK,EAhW+B,IAAI;;EAkWzC,iCAAiB;IAChB,IAAI,EAAE,IAAI;IACV,KAAK,EAAE,IAA6D;;EAQnE,iCAAc;IACb,OAAO,EAAE,oBAAsG;;EAIhH,gCAAW;IACV,KAAK,EAAE,IAAI;IACX,IAAI,EAAE,GAAG;IACT,YAAY,EAAE,0BAA0B;IACxC,YAAY,EAAE,2CAAkE;;EAUpF,qBAAc;IACb,OAAO,EAAE,MAA8C;IACvD,aAAa,EApa8B,GAAwB;;EAuanE,uBAAE;IACD,OAAO,EAAE,SAAqG;;EAE9G,iIAGc;IACb,UAAU,EAhamB,IAAgB;;EAma9C,gCAAW;IACV,UAAU,EA1Z2B,OAAe;;EA8ZrD,kCAAW;IACV,KAAK,EAAE,GAAG;IACV,GAAG,EAAE,GAAG;IACR,UAAU,EAAE,IAAkC;IAC9C,YAAY,EA3ZuB,GAAG;IA4ZtC,YAAY,EAAE,0BAA0B;IACxC,YAAY,EAAE,2CAAkE;;EAKlF;wCACkB;IACjB,OAAO,EAAE,IAAI;;EAOb,0BAAE;IACD,OAAO,EAAE,SAA2F;;EAEpG,6IAGc;IACb,UAAU,EAzb0B,OAAe;;EA4bpD,mCAAW;IACV,UAAU,EAvckB,IAAgB", +"sources": ["_sm-clean-theme.scss","mixins/_round-corners-last-item.scss","mixins/_sub-items-indentation.scss"], +"names": [], +"file": "sm-clean.css" +} diff --git a/civicrm/bower_components/smartmenus/src/css/sm-clean/sm-clean.scss b/civicrm/bower_components/smartmenus/src/css/sm-clean/sm-clean.scss new file mode 100644 index 0000000000..109712cda0 --- /dev/null +++ b/civicrm/bower_components/smartmenus/src/css/sm-clean/sm-clean.scss @@ -0,0 +1,4 @@ +@import '_mixins.scss'; + +// the variables + the CSS +@import '_sm-clean-theme.scss'; \ No newline at end of file diff --git a/civicrm/bower_components/smartmenus/src/css/sm-core-css.css b/civicrm/bower_components/smartmenus/src/css/sm-core-css.css new file mode 100644 index 0000000000..6130ae29f1 --- /dev/null +++ b/civicrm/bower_components/smartmenus/src/css/sm-core-css.css @@ -0,0 +1,14 @@ +/* Mobile first layout SmartMenus Core CSS (it's not recommended editing these rules) + You need this once per page no matter how many menu trees or different themes you use. +-------------------------------------------------------------------------------------------*/ + +.sm{box-sizing:border-box;position:relative;z-index:9999;-webkit-tap-highlight-color:rgba(0,0,0,0);} +.sm,.sm ul,.sm li{display:block;list-style:none;margin:0;padding:0;line-height:normal;direction:ltr;text-align:left;} +.sm-rtl,.sm-rtl ul,.sm-rtl li{direction:rtl;text-align:right;} +.sm>li>h1,.sm>li>h2,.sm>li>h3,.sm>li>h4,.sm>li>h5,.sm>li>h6{margin:0;padding:0;} +.sm ul{display:none;} +.sm li,.sm a{position:relative;} +.sm a{display:block;} +.sm a.disabled{cursor:default;} +.sm::after{content:"";display:block;height:0;font:0px/0 serif;clear:both;overflow:hidden;} +.sm *,.sm *::before,.sm *::after{box-sizing:inherit;} \ No newline at end of file diff --git a/civicrm/bower_components/smartmenus/src/css/sm-mint/_mixins.scss b/civicrm/bower_components/smartmenus/src/css/sm-mint/_mixins.scss new file mode 100644 index 0000000000..dd6ff7cabb --- /dev/null +++ b/civicrm/bower_components/smartmenus/src/css/sm-mint/_mixins.scss @@ -0,0 +1 @@ +@import 'mixins/_sub-items-indentation.scss'; \ No newline at end of file diff --git a/civicrm/bower_components/smartmenus/src/css/sm-mint/_sm-mint-theme.scss b/civicrm/bower_components/smartmenus/src/css/sm-mint/_sm-mint-theme.scss new file mode 100644 index 0000000000..ab8b12078f --- /dev/null +++ b/civicrm/bower_components/smartmenus/src/css/sm-mint/_sm-mint-theme.scss @@ -0,0 +1,569 @@ +// This file is best viewed with Tab size 4 code indentation + + +// ----------------------------------------------------------------------------------------------------------------- +// 1. Theme Quick Settings (Variables) +// (for further control, you will need to dig into the actual CSS in 2.) +// ----------------------------------------------------------------------------------------------------------------- + + +// ---------------------------------------------------------- +// :: 1.1. Colors +// ---------------------------------------------------------- + +$sm-mint__white: #fff !default; +$sm-mint__black: #333 !default; +$sm-mint__green: #F6FFED !default; +$sm-mint__green-dark: #8db863 !default; + +$sm-mint__box-shadow: rgba(0, 0, 0, 0.25) !default; + + +// ---------------------------------------------------------- +// :: 1.2. Breakpoints +// ---------------------------------------------------------- + +$sm-mint__desktop-vp: 768px !default; // switch from collapsible to desktop + + +// ---------------------------------------------------------- +// :: 1.3. Typography +// ---------------------------------------------------------- + +$sm-mint__font-family: Arial, sans-serif !default; +$sm-mint__font-size-base: 16px !default; +$sm-mint__font-size-small: 14px !default; +$sm-mint__line-height: 17px !default; + + +// ---------------------------------------------------------- +// :: 1.4. Borders +// ---------------------------------------------------------- + +$sm-mint__border-width: 2px !default; +$sm-mint__border-radius-base: 4px !default; + + +// ---------------------------------------------------------- +// :: 1.5. Collapsible main menu +// ---------------------------------------------------------- + +// Menu box +$sm-mint__collapsible-bg: $sm-mint__white !default; +$sm-mint__collapsible-border-color: $sm-mint__green-dark !default; + +// Items +$sm-mint__collapsible-item-color: $sm-mint__black !default; +$sm-mint__collapsible-item-disabled-color: darken($sm-mint__white, 20%) !default; +$sm-mint__collapsible-item-padding-vertical: 13px !default; +$sm-mint__collapsible-item-padding-horizontal: 20px !default; + +// Items separators +$sm-mint__collapsible-separators-color: rgba($sm-mint__green-dark, 0.2) !default; + +// Toggle button (sub menu indicators) +$sm-mint__collapsible-toggle-bg: rgba($sm-mint__green-dark, 0.2) !default; + + +// ---------------------------------------------------------- +// :: 1.6. Collapsible sub menus +// ---------------------------------------------------------- + +// Menu box +$sm-mint__collapsible-sub-bg: rgba($sm-mint__green-dark, 0.2) !default; + +// Items text indentation for deeper levels +$sm-mint__collapsible-sub-item-indentation: 8px !default; + + +// ---------------------------------------------------------- +// :: 1.7. Desktop main menu +// ---------------------------------------------------------- + +// Menu box +$sm-mint__desktop-bg: transparent !default; + +// Items +$sm-mint__desktop-item-color: $sm-mint__black !default; +$sm-mint__desktop-item-hover-color: $sm-mint__white !default; +$sm-mint__desktop-item-hover-bg: $sm-mint__green-dark !default; +$sm-mint__desktop-item-highlighted-color: $sm-mint__black !default; +$sm-mint__desktop-item-highlighted-bg: $sm-mint__green !default; +$sm-mint__desktop-item-highlighted-box-shadow: 0 4px 3px $sm-mint__box-shadow !default; +$sm-mint__desktop-item-disabled-color: darken($sm-mint__white, 20%) !default; +$sm-mint__desktop-item-padding-vertical: 11px !default; +$sm-mint__desktop-item-padding-horizontal: 20px !default; + +// Sub menu indicators +$sm-mint__desktop-arrow-size: 6px !default; // border-width +$sm-mint__desktop-arrow-color: $sm-mint__green-dark !default; +$sm-mint__desktop-arrow-hover-color: $sm-mint__white !default; +$sm-mint__desktop-arrow-highlighted-color: $sm-mint__green-dark !default; +$sm-mint__desktop-arrow-spacing: 6px !default; + +// Vertical items +$sm-mint__desktop-vertical-item-highlighted-color: $sm-mint__desktop-item-hover-color !default; +$sm-mint__desktop-vertical-item-highlighted-bg: $sm-mint__desktop-item-hover-bg !default; +$sm-mint__desktop-vertical-item-padding-vertical: 10px !default; +$sm-mint__desktop-vertical-item-padding-horizontal: 20px !default; + + +// ---------------------------------------------------------- +// :: 1.8. Desktop sub menus +// ---------------------------------------------------------- + +// Menu box +$sm-mint__desktop-sub-bg: $sm-mint__green !default; +$sm-mint__desktop-sub-box-shadow: 0 4px 3px $sm-mint__box-shadow !default; +$sm-mint__desktop-sub-padding-vertical: 8px !default; +$sm-mint__desktop-sub-padding-horizontal: 0 !default; + +// Items +$sm-mint__desktop-sub-item-color: $sm-mint__black !default; +$sm-mint__desktop-sub-item-hover-color: $sm-mint__white !default; +$sm-mint__desktop-sub-item-hover-bg: $sm-mint__green-dark !default; +$sm-mint__desktop-sub-item-disabled-color: lighten($sm-mint__black, 50%) !default; +$sm-mint__desktop-sub-item-padding-vertical: 10px !default; +$sm-mint__desktop-sub-item-padding-horizontal: 20px !default; + + +// ----------------------------------------------------------------------------------------------------------------- +// 2. Theme CSS +// ----------------------------------------------------------------------------------------------------------------- + + +// ---------------------------------------------------------- +// :: 2.1. Collapsible mode (mobile first) +// ---------------------------------------------------------- + +// calc item height and sub menus toggle button size +$sm-mint__item-height: $sm-mint__line-height + $sm-mint__collapsible-item-padding-vertical * 2; +// set toggle button size to 80% of item height +$sm-mint__toggle-size: floor($sm-mint__item-height * 0.8); +$sm-mint__toggle-spacing: floor($sm-mint__item-height * 0.1); + +// Main menu box +.sm-mint { + border-top: $sm-mint__border-width solid $sm-mint__collapsible-border-color; + border-bottom: $sm-mint__border-width solid $sm-mint__collapsible-border-color; + background: $sm-mint__collapsible-bg; + + // Main menu items + a { + &, + &:hover, + &:focus, + &:active { + padding: $sm-mint__collapsible-item-padding-vertical $sm-mint__collapsible-item-padding-horizontal; + /* make room for the toggle button (sub indicator) */ + padding-right: $sm-mint__collapsible-item-padding-horizontal + $sm-mint__toggle-size + $sm-mint__toggle-spacing; + color: $sm-mint__collapsible-item-color; + font-family: $sm-mint__font-family; + font-size: $sm-mint__font-size-base; + font-weight: normal; + line-height: $sm-mint__line-height; + text-decoration: none; + } + + &.current { + font-weight: bold; + } + + &.disabled { + color: $sm-mint__collapsible-item-disabled-color; + } + + // Toggle buttons (sub menu indicators) + .sub-arrow { + position: absolute; + top: 50%; + margin-top: -(ceil($sm-mint__toggle-size / 2)); + left: auto; + right: $sm-mint__toggle-spacing; + width: $sm-mint__toggle-size; + height: $sm-mint__toggle-size; + overflow: hidden; + font: bold #{$sm-mint__font-size-small}/#{$sm-mint__toggle-size} monospace !important; + text-align: center; + text-shadow: none; + background: $sm-mint__collapsible-toggle-bg; + border-radius: $sm-mint__border-radius-base; + } + .sub-arrow::before { + content: '+'; + } + &.highlighted .sub-arrow::before { + content: '-'; + } + } + + // Main menu items separators + li { + border-top: 1px solid $sm-mint__collapsible-separators-color; + } + > li:first-child { + border-top: 0; + } + + // Sub menus box + ul { + background: $sm-mint__collapsible-sub-bg; + + // Sub menus items + a { + &, + &:hover, + &:focus, + &:active { + font-size: $sm-mint__font-size-small; + // add indentation for sub menus text + border-left: $sm-mint__collapsible-sub-item-indentation solid transparent; + } + } + + // Add indentation for sub menus text for deeper levels + @include sm-mint__sub-items-indentation($sm-mint__collapsible-sub-item-indentation); + } +} + + +// ---------------------------------------------------------- +// :: 2.2. Desktop mode +// ---------------------------------------------------------- + +@media (min-width: $sm-mint__desktop-vp) { + + /* Switch to desktop layout + ----------------------------------------------- + These transform the menu tree from + collapsible to desktop (navbar + dropdowns) + -----------------------------------------------*/ + /* start... (it's not recommended editing these rules) */ + .sm-mint ul{position:absolute;width:12em;} + .sm-mint li{float:left;} + .sm-mint.sm-rtl li{float:right;} + .sm-mint ul li,.sm-mint.sm-rtl ul li,.sm-mint.sm-vertical li{float:none;} + .sm-mint a{white-space:nowrap;} + .sm-mint ul a,.sm-mint.sm-vertical a{white-space:normal;} + .sm-mint .sm-nowrap > li > a,.sm-mint .sm-nowrap > li > :not(ul) a{white-space:nowrap;} + /* ...end */ + + // Main menu box + .sm-mint { + border-top: 0; + background: $sm-mint__desktop-bg; + + // Main menu items + a { + &, + &:hover, + &:focus, + &:active, + &.highlighted { + padding: $sm-mint__desktop-item-padding-vertical $sm-mint__desktop-item-padding-horizontal; + color: $sm-mint__desktop-item-color; + border-radius: $sm-mint__border-radius-base $sm-mint__border-radius-base 0 0; + } + + &:hover, + &:focus, + &:active { + background: $sm-mint__desktop-item-hover-bg; + color: $sm-mint__desktop-item-hover-color; + } + + &.highlighted { + background: $sm-mint__desktop-item-highlighted-bg; + color: $sm-mint__desktop-item-highlighted-color; + box-shadow: $sm-mint__desktop-item-highlighted-box-shadow; + } + + &.disabled { + background: transparent; + color: $sm-mint__desktop-item-disabled-color; + box-shadow: none; + } + + // Make room for the sub arrows + &.has-submenu { + padding-right: $sm-mint__desktop-item-padding-horizontal + 8px + $sm-mint__desktop-arrow-spacing; + } + + // Sub menu indicators + .sub-arrow { + top: 50%; + margin-top: -(ceil($sm-mint__desktop-arrow-size / 2)); + right: $sm-mint__desktop-item-padding-horizontal; + width: 0; + height: 0; + border-width: $sm-mint__desktop-arrow-size ($sm-mint__desktop-arrow-size * 0.67) 0 ($sm-mint__desktop-arrow-size * 0.67); + border-style: solid dashed dashed dashed; + border-color: $sm-mint__desktop-arrow-color transparent transparent transparent; + background: transparent; + border-radius: 0; + } + &:hover .sub-arrow, + &:focus .sub-arrow, + &:active .sub-arrow { + border-color: $sm-mint__desktop-arrow-hover-color transparent transparent transparent; + } + &.highlighted .sub-arrow { + border-color: $sm-mint__desktop-arrow-highlighted-color transparent transparent transparent; + } + &.disabled .sub-arrow { + border-color: $sm-mint__desktop-arrow-color transparent transparent transparent; + } + // reset mobile first style + .sub-arrow::before { + display: none; + } + } + + // No main menu items separators + li { + border-top: 0; + } + + // Sub menus box + ul { + border: 0; + padding: $sm-mint__desktop-sub-padding-vertical $sm-mint__desktop-sub-padding-horizontal; + background: $sm-mint__desktop-sub-bg; + border-radius: 0 $sm-mint__border-radius-base $sm-mint__border-radius-base $sm-mint__border-radius-base; + box-shadow: $sm-mint__desktop-sub-box-shadow; + + // 2+ sub levels need rounding of all corners + ul { + border-radius: $sm-mint__border-radius-base; + } + + // Sub menus items + a { + &, + &:hover, + &:focus, + &:active, + &.highlighted { + border: 0 !important; + padding: $sm-mint__desktop-sub-item-padding-vertical $sm-mint__desktop-sub-item-padding-horizontal; + color: $sm-mint__desktop-sub-item-color; + border-radius: 0; + } + + &:hover, + &:focus, + &:active, + &.highlighted { + background: $sm-mint__desktop-sub-item-hover-bg; + color: $sm-mint__desktop-sub-item-hover-color; + box-shadow: none; + } + + &.disabled { + background: transparent; + color: $sm-mint__desktop-sub-item-disabled-color; + } + + // No need for additional room for the sub arrows + &.has-submenu { + padding-right: $sm-mint__desktop-item-padding-horizontal; + } + + // Sub menu indicators + .sub-arrow { + right: 10px; + margin-top: -($sm-mint__desktop-arrow-size * 0.67); + border-width: ($sm-mint__desktop-arrow-size * 0.67) 0 ($sm-mint__desktop-arrow-size * 0.67) $sm-mint__desktop-arrow-size; + border-style: dashed dashed dashed solid; + border-color: transparent transparent transparent $sm-mint__desktop-arrow-color; + } + &:hover .sub-arrow, + &:focus .sub-arrow, + &:active .sub-arrow, + &.highlighted .sub-arrow { + border-color: transparent transparent transparent $sm-mint__desktop-arrow-hover-color; + } + &.disabled .sub-arrow { + border-color: transparent transparent transparent $sm-mint__desktop-arrow-color; + } + } + } + + // Scrolling arrows containers for tall sub menus - test sub menu: "Sub test" -> "more..." in the default download package + .scroll-up, + .scroll-down { + position: absolute; + display: none; + visibility: hidden; + overflow: hidden; + background: $sm-mint__desktop-sub-bg; + height: 20px; + // width and position will be set automatically by the script + } + .scroll-up-arrow, + .scroll-down-arrow { + position: absolute; + top: 6px; + left: 50%; + margin-left: -8px; + // we will use one-side border to create a triangle so that we don't use a real background image, of course, you can use a real image if you like too + width: 0; + height: 0; + overflow: hidden; + border-width: 0 6px 8px 6px; // tweak size of the arrow + border-style: dashed dashed solid dashed; + border-color: transparent transparent $sm-mint__desktop-arrow-color transparent; + } + .scroll-down-arrow { + border-width: 8px 6px 0 6px; + border-style: solid dashed dashed dashed; + border-color: $sm-mint__desktop-arrow-color transparent transparent transparent; + } + + + // Rigth-to-left + + // Main menu box + &.sm-rtl { + + // Main menu items + a { + + // Make room for the sub arrows + &.has-submenu { + padding-right: $sm-mint__desktop-item-padding-horizontal; + padding-left: $sm-mint__desktop-item-padding-horizontal + 8px + $sm-mint__desktop-arrow-spacing; + } + + // Sub menu indicators + .sub-arrow { + right: auto; + left: $sm-mint__desktop-item-padding-horizontal; + } + } + + // Vertical main menu + &.sm-vertical { + border-right: 0; + border-left: $sm-mint__border-width solid $sm-mint__collapsible-border-color; + + // Vertical main menu items + a { + border-radius: 0 $sm-mint__border-radius-base $sm-mint__border-radius-base 0; + + // No need for additional room for the sub arrows + &.has-submenu { + padding: $sm-mint__desktop-vertical-item-padding-vertical $sm-mint__desktop-vertical-item-padding-horizontal; + } + + // Sub menu indicators + .sub-arrow { + right: auto; + left: 10px; + border-width: ($sm-mint__desktop-arrow-size * 0.67) $sm-mint__desktop-arrow-size ($sm-mint__desktop-arrow-size * 0.67) 0; + border-style: dashed solid dashed dashed; + border-color: transparent $sm-mint__desktop-arrow-color transparent transparent; + } + &:hover .sub-arrow, + &:focus .sub-arrow, + &:active .sub-arrow, + &.highlighted .sub-arrow { + border-color: transparent $sm-mint__desktop-arrow-hover-color transparent transparent; + } + &.disabled .sub-arrow { + border-color: transparent $sm-mint__desktop-arrow-color transparent transparent; + } + } + } + + // Sub menus box + ul { + border-radius: $sm-mint__border-radius-base 0 $sm-mint__border-radius-base $sm-mint__border-radius-base; + + a { + border-radius: 0 !important; + + // No need for additional room for the sub arrows + &.has-submenu { + padding: $sm-mint__desktop-sub-item-padding-vertical $sm-mint__desktop-sub-item-padding-horizontal !important; + } + + // Sub menu indicators + .sub-arrow { + right: auto; + left: 10px; + border-width: ($sm-mint__desktop-arrow-size * 0.67) $sm-mint__desktop-arrow-size ($sm-mint__desktop-arrow-size * 0.67) 0; + border-style: dashed solid dashed dashed; + border-color: transparent $sm-mint__desktop-arrow-color transparent transparent; + } + &:hover .sub-arrow, + &:focus .sub-arrow, + &:active .sub-arrow, + &.highlighted .sub-arrow { + border-color: transparent $sm-mint__desktop-arrow-hover-color transparent transparent; + } + &.disabled .sub-arrow { + border-color: transparent $sm-mint__desktop-arrow-color transparent transparent; + } + } + } + } + + + // Vertical main menu + + // Main menu box + &.sm-vertical { + border-bottom: 0; + border-right: $sm-mint__border-width solid $sm-mint__collapsible-border-color; + + // Main menu items + a { + padding: $sm-mint__desktop-vertical-item-padding-vertical $sm-mint__desktop-vertical-item-padding-horizontal; + border-radius: $sm-mint__border-radius-base 0 0 $sm-mint__border-radius-base; + + &:hover, + &:focus, + &:active, + &.highlighted { + background: $sm-mint__desktop-item-hover-bg; + color: $sm-mint__desktop-item-hover-color; + box-shadow: none; + } + + &.disabled { + background: transparent; + color: $sm-mint__desktop-item-disabled-color; + } + + // Sub menu indicators + .sub-arrow { + right: 10px; + margin-top: -($sm-mint__desktop-arrow-size * 0.67); + border-width: ($sm-mint__desktop-arrow-size * 0.67) 0 ($sm-mint__desktop-arrow-size * 0.67) $sm-mint__desktop-arrow-size; + border-style: dashed dashed dashed solid; + border-color: transparent transparent transparent $sm-mint__desktop-arrow-color; + } + &:hover .sub-arrow, + &:focus .sub-arrow, + &:active .sub-arrow, + &.highlighted .sub-arrow { + border-color: transparent transparent transparent $sm-mint__desktop-arrow-hover-color; + } + &.disabled .sub-arrow { + border-color: transparent transparent transparent $sm-mint__desktop-arrow-color; + } + } + + // Sub menus box + ul { + border-radius: $sm-mint__border-radius-base !important; + + // Sub menus items + a { + padding: $sm-mint__desktop-sub-item-padding-vertical $sm-mint__desktop-sub-item-padding-horizontal; + } + } + } + } +} \ No newline at end of file diff --git a/civicrm/bower_components/smartmenus/src/css/sm-mint/mixins/_sub-items-indentation.scss b/civicrm/bower_components/smartmenus/src/css/sm-mint/mixins/_sub-items-indentation.scss new file mode 100644 index 0000000000..28731337af --- /dev/null +++ b/civicrm/bower_components/smartmenus/src/css/sm-mint/mixins/_sub-items-indentation.scss @@ -0,0 +1,15 @@ +// Generate rules to indent sub menus text +// +// We'll use left border to avoid messing with the padding. + +@mixin sm-mint__sub-items-indentation($amount, $chainable: 'ul ', $level: 4, $chain: '') { + @for $i from 1 through $level { + $chain: $chain + $chainable; + #{$chain} a, + #{$chain} a:hover, + #{$chain} a:focus, + #{$chain} a:active { + border-left: ($amount * ($i + 1)) solid transparent; + } + } +} \ No newline at end of file diff --git a/civicrm/bower_components/smartmenus/src/css/sm-mint/sm-mint.css b/civicrm/bower_components/smartmenus/src/css/sm-mint/sm-mint.css new file mode 100644 index 0000000000..1ab65555da --- /dev/null +++ b/civicrm/bower_components/smartmenus/src/css/sm-mint/sm-mint.css @@ -0,0 +1,331 @@ +.sm-mint { + border-top: 2px solid #8db863; + border-bottom: 2px solid #8db863; + background: #fff; +} +.sm-mint a, .sm-mint a:hover, .sm-mint a:focus, .sm-mint a:active { + padding: 13px 20px; + /* make room for the toggle button (sub indicator) */ + padding-right: 58px; + color: #333; + font-family: Arial, sans-serif; + font-size: 16px; + font-weight: normal; + line-height: 17px; + text-decoration: none; +} +.sm-mint a.current { + font-weight: bold; +} +.sm-mint a.disabled { + color: #cccccc; +} +.sm-mint a .sub-arrow { + position: absolute; + top: 50%; + margin-top: -17px; + left: auto; + right: 4px; + width: 34px; + height: 34px; + overflow: hidden; + font: bold 14px/34px monospace !important; + text-align: center; + text-shadow: none; + background: rgba(141, 184, 99, 0.2); + border-radius: 4px; +} +.sm-mint a .sub-arrow::before { + content: '+'; +} +.sm-mint a.highlighted .sub-arrow::before { + content: '-'; +} +.sm-mint li { + border-top: 1px solid rgba(141, 184, 99, 0.2); +} +.sm-mint > li:first-child { + border-top: 0; +} +.sm-mint ul { + background: rgba(141, 184, 99, 0.2); +} +.sm-mint ul a, .sm-mint ul a:hover, .sm-mint ul a:focus, .sm-mint ul a:active { + font-size: 14px; + border-left: 8px solid transparent; +} +.sm-mint ul ul a, +.sm-mint ul ul a:hover, +.sm-mint ul ul a:focus, +.sm-mint ul ul a:active { + border-left: 16px solid transparent; +} +.sm-mint ul ul ul a, +.sm-mint ul ul ul a:hover, +.sm-mint ul ul ul a:focus, +.sm-mint ul ul ul a:active { + border-left: 24px solid transparent; +} +.sm-mint ul ul ul ul a, +.sm-mint ul ul ul ul a:hover, +.sm-mint ul ul ul ul a:focus, +.sm-mint ul ul ul ul a:active { + border-left: 32px solid transparent; +} +.sm-mint ul ul ul ul ul a, +.sm-mint ul ul ul ul ul a:hover, +.sm-mint ul ul ul ul ul a:focus, +.sm-mint ul ul ul ul ul a:active { + border-left: 40px solid transparent; +} + +@media (min-width: 768px) { + /* Switch to desktop layout + ----------------------------------------------- + These transform the menu tree from + collapsible to desktop (navbar + dropdowns) + -----------------------------------------------*/ + /* start... (it's not recommended editing these rules) */ + .sm-mint ul { + position: absolute; + width: 12em; + } + + .sm-mint li { + float: left; + } + + .sm-mint.sm-rtl li { + float: right; + } + + .sm-mint ul li, .sm-mint.sm-rtl ul li, .sm-mint.sm-vertical li { + float: none; + } + + .sm-mint a { + white-space: nowrap; + } + + .sm-mint ul a, .sm-mint.sm-vertical a { + white-space: normal; + } + + .sm-mint .sm-nowrap > li > a, .sm-mint .sm-nowrap > li > :not(ul) a { + white-space: nowrap; + } + + /* ...end */ + .sm-mint { + border-top: 0; + background: transparent; + } + .sm-mint a, .sm-mint a:hover, .sm-mint a:focus, .sm-mint a:active, .sm-mint a.highlighted { + padding: 11px 20px; + color: #333; + border-radius: 4px 4px 0 0; + } + .sm-mint a:hover, .sm-mint a:focus, .sm-mint a:active { + background: #8db863; + color: #fff; + } + .sm-mint a.highlighted { + background: #F6FFED; + color: #333; + box-shadow: 0 4px 3px rgba(0, 0, 0, 0.25); + } + .sm-mint a.disabled { + background: transparent; + color: #cccccc; + box-shadow: none; + } + .sm-mint a.has-submenu { + padding-right: 34px; + } + .sm-mint a .sub-arrow { + top: 50%; + margin-top: -3px; + right: 20px; + width: 0; + height: 0; + border-width: 6px 4.02px 0 4.02px; + border-style: solid dashed dashed dashed; + border-color: #8db863 transparent transparent transparent; + background: transparent; + border-radius: 0; + } + .sm-mint a:hover .sub-arrow, .sm-mint a:focus .sub-arrow, .sm-mint a:active .sub-arrow { + border-color: #fff transparent transparent transparent; + } + .sm-mint a.highlighted .sub-arrow { + border-color: #8db863 transparent transparent transparent; + } + .sm-mint a.disabled .sub-arrow { + border-color: #8db863 transparent transparent transparent; + } + .sm-mint a .sub-arrow::before { + display: none; + } + .sm-mint li { + border-top: 0; + } + .sm-mint ul { + border: 0; + padding: 8px 0; + background: #F6FFED; + border-radius: 0 4px 4px 4px; + box-shadow: 0 4px 3px rgba(0, 0, 0, 0.25); + } + .sm-mint ul ul { + border-radius: 4px; + } + .sm-mint ul a, .sm-mint ul a:hover, .sm-mint ul a:focus, .sm-mint ul a:active, .sm-mint ul a.highlighted { + border: 0 !important; + padding: 10px 20px; + color: #333; + border-radius: 0; + } + .sm-mint ul a:hover, .sm-mint ul a:focus, .sm-mint ul a:active, .sm-mint ul a.highlighted { + background: #8db863; + color: #fff; + box-shadow: none; + } + .sm-mint ul a.disabled { + background: transparent; + color: #b3b3b3; + } + .sm-mint ul a.has-submenu { + padding-right: 20px; + } + .sm-mint ul a .sub-arrow { + right: 10px; + margin-top: -4.02px; + border-width: 4.02px 0 4.02px 6px; + border-style: dashed dashed dashed solid; + border-color: transparent transparent transparent #8db863; + } + .sm-mint ul a:hover .sub-arrow, .sm-mint ul a:focus .sub-arrow, .sm-mint ul a:active .sub-arrow, .sm-mint ul a.highlighted .sub-arrow { + border-color: transparent transparent transparent #fff; + } + .sm-mint ul a.disabled .sub-arrow { + border-color: transparent transparent transparent #8db863; + } + .sm-mint .scroll-up, + .sm-mint .scroll-down { + position: absolute; + display: none; + visibility: hidden; + overflow: hidden; + background: #F6FFED; + height: 20px; + } + .sm-mint .scroll-up-arrow, + .sm-mint .scroll-down-arrow { + position: absolute; + top: 6px; + left: 50%; + margin-left: -8px; + width: 0; + height: 0; + overflow: hidden; + border-width: 0 6px 8px 6px; + border-style: dashed dashed solid dashed; + border-color: transparent transparent #8db863 transparent; + } + .sm-mint .scroll-down-arrow { + border-width: 8px 6px 0 6px; + border-style: solid dashed dashed dashed; + border-color: #8db863 transparent transparent transparent; + } + .sm-mint.sm-rtl a.has-submenu { + padding-right: 20px; + padding-left: 34px; + } + .sm-mint.sm-rtl a .sub-arrow { + right: auto; + left: 20px; + } + .sm-mint.sm-rtl.sm-vertical { + border-right: 0; + border-left: 2px solid #8db863; + } + .sm-mint.sm-rtl.sm-vertical a { + border-radius: 0 4px 4px 0; + } + .sm-mint.sm-rtl.sm-vertical a.has-submenu { + padding: 10px 20px; + } + .sm-mint.sm-rtl.sm-vertical a .sub-arrow { + right: auto; + left: 10px; + border-width: 4.02px 6px 4.02px 0; + border-style: dashed solid dashed dashed; + border-color: transparent #8db863 transparent transparent; + } + .sm-mint.sm-rtl.sm-vertical a:hover .sub-arrow, .sm-mint.sm-rtl.sm-vertical a:focus .sub-arrow, .sm-mint.sm-rtl.sm-vertical a:active .sub-arrow, .sm-mint.sm-rtl.sm-vertical a.highlighted .sub-arrow { + border-color: transparent #fff transparent transparent; + } + .sm-mint.sm-rtl.sm-vertical a.disabled .sub-arrow { + border-color: transparent #8db863 transparent transparent; + } + .sm-mint.sm-rtl ul { + border-radius: 4px 0 4px 4px; + } + .sm-mint.sm-rtl ul a { + border-radius: 0 !important; + } + .sm-mint.sm-rtl ul a.has-submenu { + padding: 10px 20px !important; + } + .sm-mint.sm-rtl ul a .sub-arrow { + right: auto; + left: 10px; + border-width: 4.02px 6px 4.02px 0; + border-style: dashed solid dashed dashed; + border-color: transparent #8db863 transparent transparent; + } + .sm-mint.sm-rtl ul a:hover .sub-arrow, .sm-mint.sm-rtl ul a:focus .sub-arrow, .sm-mint.sm-rtl ul a:active .sub-arrow, .sm-mint.sm-rtl ul a.highlighted .sub-arrow { + border-color: transparent #fff transparent transparent; + } + .sm-mint.sm-rtl ul a.disabled .sub-arrow { + border-color: transparent #8db863 transparent transparent; + } + .sm-mint.sm-vertical { + border-bottom: 0; + border-right: 2px solid #8db863; + } + .sm-mint.sm-vertical a { + padding: 10px 20px; + border-radius: 4px 0 0 4px; + } + .sm-mint.sm-vertical a:hover, .sm-mint.sm-vertical a:focus, .sm-mint.sm-vertical a:active, .sm-mint.sm-vertical a.highlighted { + background: #8db863; + color: #fff; + box-shadow: none; + } + .sm-mint.sm-vertical a.disabled { + background: transparent; + color: #cccccc; + } + .sm-mint.sm-vertical a .sub-arrow { + right: 10px; + margin-top: -4.02px; + border-width: 4.02px 0 4.02px 6px; + border-style: dashed dashed dashed solid; + border-color: transparent transparent transparent #8db863; + } + .sm-mint.sm-vertical a:hover .sub-arrow, .sm-mint.sm-vertical a:focus .sub-arrow, .sm-mint.sm-vertical a:active .sub-arrow, .sm-mint.sm-vertical a.highlighted .sub-arrow { + border-color: transparent transparent transparent #fff; + } + .sm-mint.sm-vertical a.disabled .sub-arrow { + border-color: transparent transparent transparent #8db863; + } + .sm-mint.sm-vertical ul { + border-radius: 4px !important; + } + .sm-mint.sm-vertical ul a { + padding: 10px 20px; + } +} + +/*# sourceMappingURL=sm-mint.css.map */ diff --git a/civicrm/bower_components/smartmenus/src/css/sm-mint/sm-mint.css.map b/civicrm/bower_components/smartmenus/src/css/sm-mint/sm-mint.css.map new file mode 100644 index 0000000000..2220dbd2b8 --- /dev/null +++ b/civicrm/bower_components/smartmenus/src/css/sm-mint/sm-mint.css.map @@ -0,0 +1,7 @@ +{ +"version": 3, +"mappings": "AAiJA,QAAS;EACR,UAAU,EAAE,iBAA+D;EAC3E,aAAa,EAAE,iBAA+D;EAC9E,UAAU,EA1BiC,IAAe;;AA8BzD,iEAGS;EACR,OAAO,EAAE,SAAyF;EAClG,qDAAqD;EACrD,aAAa,EAAE,IAAgG;EAC/G,KAAK,EAtC+B,IAAe;EAuCnD,WAAW,EAhIiB,iBAAiB;EAiI7C,SAAS,EAhIqB,IAAI;EAiIlC,WAAW,EAAE,MAAM;EACnB,WAAW,EAhIiB,IAAI;EAiIhC,eAAe,EAAE,IAAI;;AAGtB,kBAAU;EACT,WAAW,EAAE,IAAI;;AAGlB,mBAAW;EACV,KAAK,EApHsC,OAA4B;;AAwHxE,qBAAW;EACV,QAAQ,EAAE,QAAQ;EAClB,GAAG,EAAE,GAAG;EACR,UAAU,EAAE,KAAkC;EAC9C,IAAI,EAAE,IAAI;EACV,KAAK,EAvCkB,GAAkC;EAwCzD,KAAK,EAzCe,IAAkC;EA0CtD,MAAM,EA1Cc,IAAkC;EA2CtD,QAAQ,EAAE,MAAM;EAChB,IAAI,EAAE,mCAA+E;EACrF,UAAU,EAAE,MAAM;EAClB,WAAW,EAAE,IAAI;EACjB,UAAU,EA5HyB,uBAA+B;EA6HlE,aAAa,EAlJoB,GAAG;;AAoJrC,6BAAmB;EAClB,OAAO,EAAE,GAAG;;AAEb,yCAAiC;EAChC,OAAO,EAAE,GAAG;;AAKd,WAAG;EACF,UAAU,EAAE,iCAAgD;;AAEtD,yBAAiB;EACvB,UAAU,EAAE,CAAC;;AAId,WAAG;EACF,UAAU,EAzIwB,uBAA+B;;AA6IhE,6EAGS;EACR,SAAS,EAvLqB,IAAI;EAyLlC,WAAW,EAAE,qBAA4D;;ACpN3E;;;uBAGmB;EAClB,WAAW,EAAE,sBAAsC;;AAJpD;;;0BAGmB;EAClB,WAAW,EAAE,sBAAsC;;AAJpD;;;6BAGmB;EAClB,WAAW,EAAE,sBAAsC;;AAJpD;;;gCAGmB;EAClB,WAAW,EAAE,sBAAsC;;;AD8NtD,yBAAyC;EAExC;;;;mDAIiD;EACjD,yDAAyD;EACzD,WAAW;IAAC,QAAQ,EAAC,QAAQ;IAAC,KAAK,EAAC,IAAI;;;EACxC,WAAW;IAAC,KAAK,EAAC,IAAI;;;EACtB,kBAAkB;IAAC,KAAK,EAAC,KAAK;;;EAC9B,8DAA4D;IAAC,KAAK,EAAC,IAAI;;;EACvE,UAAU;IAAC,WAAW,EAAC,MAAM;;;EAC7B,qCAAoC;IAAC,WAAW,EAAC,MAAM;;;EACvD,mEAAkE;IAAC,WAAW,EAAC,MAAM;;;EACrF,YAAY;EAGZ,QAAS;IACR,UAAU,EAAE,CAAC;IACb,UAAU,EA1KkB,WAAW;;EA8KtC,yFAIc;IACb,OAAO,EAAE,SAAiF;IAC1F,KAAK,EA9I8B,IAAe;IA+IlD,aAAa,EAAE,WAA6D;;EAG7E,qDAES;IACR,UAAU,EAnJ2B,OAAoB;IAoJzD,KAAK,EArJmC,IAAe;;EAwJxD,sBAAc;IACb,UAAU,EAhKmB,OAAe;IAiK5C,KAAK,EA3J8B,IAAe;IA4JlD,UAAU,EA1LmC,6BAA+B;;EA6L7E,mBAAW;IACV,UAAU,EAAE,WAAW;IACvB,KAAK,EA9LkC,OAA4B;IA+LnE,UAAU,EAAE,IAAI;;EAIjB,sBAAc;IACb,aAAa,EAAE,IAAiF;;EAIjG,qBAAW;IACV,GAAG,EAAE,GAAG;IACR,UAAU,EAAE,IAAyC;IACrD,KAAK,EAzMqC,IAAI;IA0M9C,KAAK,EAAE,CAAC;IACR,MAAM,EAAE,CAAC;IACT,YAAY,EAAE,mBAA0G;IACxH,YAAY,EAAE,0BAA0B;IACxC,YAAY,EAAE,2CAAiE;IAC/E,UAAU,EAAE,WAAW;IACvB,aAAa,EAAE,CAAC;;EAEjB,sFAEoB;IACnB,YAAY,EAAE,wCAAuE;;EAEtF,iCAAyB;IACxB,YAAY,EAAE,2CAA6E;;EAE5F,8BAAsB;IACrB,YAAY,EAAE,2CAAiE;;EAGhF,6BAAmB;IAClB,OAAO,EAAE,IAAI;;EAKf,WAAG;IACF,UAAU,EAAE,CAAC;;EAId,WAAG;IACF,MAAM,EAAE,CAAC;IACT,OAAO,EAAE,KAA+E;IACxF,UAAU,EAvNoB,OAAe;IAwN7C,aAAa,EAAE,aAAwF;IACvG,UAAU,EAxN0B,6BAA+B;;EA2NnE,cAAG;IACF,aAAa,EArSmB,GAAG;;EA0SnC,wGAIc;IACb,MAAM,EAAE,YAAY;IACpB,OAAO,EAAE,SAAyF;IAClG,KAAK,EAnO6B,IAAe;IAoOjD,aAAa,EAAE,CAAC;;EAGjB,yFAGc;IACb,UAAU,EAzO0B,OAAoB;IA0OxD,KAAK,EA3OkC,IAAe;IA4OtD,UAAU,EAAE,IAAI;;EAGjB,sBAAW;IACV,UAAU,EAAE,WAAW;IACvB,KAAK,EA/OoC,OAA6B;;EAmPvE,yBAAc;IACb,aAAa,EAlR4B,IAAI;;EAsR9C,wBAAW;IACV,KAAK,EAAE,IAAI;IACX,UAAU,EAAE,OAAsC;IAClD,YAAY,EAAE,mBAA0G;IACxH,YAAY,EAAE,0BAA0B;IACxC,YAAY,EAAE,2CAAiE;;EAEhF,qIAG0B;IACzB,YAAY,EAAE,wCAAuE;;EAEtF,iCAAsB;IACrB,YAAY,EAAE,2CAAiE;;EAMlF;uBACa;IACZ,QAAQ,EAAE,QAAQ;IAClB,OAAO,EAAE,IAAI;IACb,UAAU,EAAE,MAAM;IAClB,QAAQ,EAAE,MAAM;IAChB,UAAU,EA3RoB,OAAe;IA4R7C,MAAM,EAAE,IAAI;;EAGb;6BACmB;IAClB,QAAQ,EAAE,QAAQ;IAClB,GAAG,EAAE,GAAG;IACR,IAAI,EAAE,GAAG;IACT,WAAW,EAAE,IAAI;IAEjB,KAAK,EAAE,CAAC;IACR,MAAM,EAAE,CAAC;IACT,QAAQ,EAAE,MAAM;IAChB,YAAY,EAAE,aAAa;IAC3B,YAAY,EAAE,0BAA0B;IACxC,YAAY,EAAE,2CAAiE;;EAEhF,2BAAmB;IAClB,YAAY,EAAE,aAAa;IAC3B,YAAY,EAAE,0BAA0B;IACxC,YAAY,EAAE,2CAAiE;;EAa9E,6BAAc;IACb,aAAa,EAnV4B,IAAI;IAoV7C,YAAY,EAAE,IAAiF;;EAIhG,4BAAW;IACV,KAAK,EAAE,IAAI;IACX,IAAI,EA1VqC,IAAI;;EA+V/C,2BAAc;IACb,YAAY,EAAE,CAAC;IACf,WAAW,EAAE,iBAA+D;;EAG5E,6BAAE;IACD,aAAa,EAAE,WAA6D;;EAG5E,yCAAc;IACb,OAAO,EAAE,SAAmG;;EAI7G,wCAAW;IACV,KAAK,EAAE,IAAI;IACX,IAAI,EAAE,IAAI;IACV,YAAY,EAAE,mBAA0G;IACxH,YAAY,EAAE,0BAA0B;IACxC,YAAY,EAAE,2CAAiE;;EAEhF,qMAG0B;IACzB,YAAY,EAAE,wCAAuE;;EAEtF,iDAAsB;IACrB,YAAY,EAAE,2CAAiE;;EAMlF,kBAAG;IACF,aAAa,EAAE,aAAwF;;EAEvG,oBAAE;IACD,aAAa,EAAE,YAAY;;EAG3B,gCAAc;IACb,OAAO,EAAE,oBAAoG;;EAI9G,+BAAW;IACV,KAAK,EAAE,IAAI;IACX,IAAI,EAAE,IAAI;IACV,YAAY,EAAE,mBAA0G;IACxH,YAAY,EAAE,0BAA0B;IACxC,YAAY,EAAE,2CAAiE;;EAEhF,iKAG0B;IACzB,YAAY,EAAE,wCAAuE;;EAEtF,wCAAsB;IACrB,YAAY,EAAE,2CAAiE;;EAUnF,oBAAc;IACb,aAAa,EAAE,CAAC;IAChB,YAAY,EAAE,iBAA+D;;EAG7E,sBAAE;IACD,OAAO,EAAE,SAAmG;IAC5G,aAAa,EAAE,WAA6D;;EAE5E,6HAGc;IACb,UAAU,EArZ0B,OAAoB;IAsZxD,KAAK,EAvZkC,IAAe;IAwZtD,UAAU,EAAE,IAAI;;EAGjB,+BAAW;IACV,UAAU,EAAE,WAAW;IACvB,KAAK,EA3biC,OAA4B;;EA+bnE,iCAAW;IACV,KAAK,EAAE,IAAI;IACX,UAAU,EAAE,OAAsC;IAClD,YAAY,EAAE,mBAA0G;IACxH,YAAY,EAAE,0BAA0B;IACxC,YAAY,EAAE,2CAAiE;;EAEhF,yKAG0B;IACzB,YAAY,EAAE,wCAAuE;;EAEtF,0CAAsB;IACrB,YAAY,EAAE,2CAAiE;;EAKjF,uBAAG;IACF,aAAa,EAAE,cAAuC;;EAGtD,yBAAE;IACD,OAAO,EAAE,SAAyF", +"sources": ["_sm-mint-theme.scss","mixins/_sub-items-indentation.scss"], +"names": [], +"file": "sm-mint.css" +} diff --git a/civicrm/bower_components/smartmenus/src/css/sm-mint/sm-mint.scss b/civicrm/bower_components/smartmenus/src/css/sm-mint/sm-mint.scss new file mode 100644 index 0000000000..00dc26762d --- /dev/null +++ b/civicrm/bower_components/smartmenus/src/css/sm-mint/sm-mint.scss @@ -0,0 +1,4 @@ +@import '_mixins.scss'; + +// the variables + the CSS +@import '_sm-mint-theme.scss'; \ No newline at end of file diff --git a/civicrm/bower_components/smartmenus/src/css/sm-simple/_mixins.scss b/civicrm/bower_components/smartmenus/src/css/sm-simple/_mixins.scss new file mode 100644 index 0000000000..dd6ff7cabb --- /dev/null +++ b/civicrm/bower_components/smartmenus/src/css/sm-simple/_mixins.scss @@ -0,0 +1 @@ +@import 'mixins/_sub-items-indentation.scss'; \ No newline at end of file diff --git a/civicrm/bower_components/smartmenus/src/css/sm-simple/_sm-simple-theme.scss b/civicrm/bower_components/smartmenus/src/css/sm-simple/_sm-simple-theme.scss new file mode 100644 index 0000000000..e72e20b1ea --- /dev/null +++ b/civicrm/bower_components/smartmenus/src/css/sm-simple/_sm-simple-theme.scss @@ -0,0 +1,446 @@ +// This file is best viewed with Tab size 4 code indentation + + +// ----------------------------------------------------------------------------------------------------------------- +// 1. Theme Quick Settings (Variables) +// (for further control, you will need to dig into the actual CSS in 2.) +// ----------------------------------------------------------------------------------------------------------------- + + +// ---------------------------------------------------------- +// :: 1.1. Colors +// ---------------------------------------------------------- + +$sm-simple__white: #fff !default; +$sm-simple__gray: darken($sm-simple__white, 6.5%) !default; +$sm-simple__gray-dark: darken($sm-simple__white, 26.5%) !default; +$sm-simple__gray-darker: darken($sm-simple__white, 66.5%) !default; + +$sm-simple__box-shadow: rgba(0, 0, 0, 0.2) !default; + + +// ---------------------------------------------------------- +// :: 1.2. Breakpoints +// ---------------------------------------------------------- + +$sm-simple__desktop-vp: 768px !default; // switch from collapsible to desktop + + +// ---------------------------------------------------------- +// :: 1.3. Typography +// ---------------------------------------------------------- + +$sm-simple__font-family: "Lucida Sans Unicode", "Lucida Sans", "Lucida Grande", Arial, sans-serif !default; +$sm-simple__font-size-base: 16px !default; +$sm-simple__font-size-small: 14px !default; +$sm-simple__line-height: 17px !default; + + +// ---------------------------------------------------------- +// :: 1.4. Borders +// ---------------------------------------------------------- + +$sm-simple__border-width: 1px !default; + + +// ---------------------------------------------------------- +// :: 1.5. Collapsible main menu +// ---------------------------------------------------------- + +// Menu box +$sm-simple__collapsible-bg: $sm-simple__white !default; +$sm-simple__collapsible-border-color: $sm-simple__gray-dark !default; +$sm-simple__collapsible-box-shadow: 0 1px 1px $sm-simple__box-shadow !default; + +// Items +$sm-simple__collapsible-item-color: $sm-simple__gray-darker !default; +$sm-simple__collapsible-item-current-color: $sm-simple__white !default; +$sm-simple__collapsible-item-current-bg: $sm-simple__gray-darker !default; +$sm-simple__collapsible-item-disabled-color: darken($sm-simple__white, 20%) !default; +$sm-simple__collapsible-item-padding-vertical: 13px !default; +$sm-simple__collapsible-item-padding-horizontal: 20px !default; + +// Items separators +$sm-simple__collapsible-separators-color: rgba(0, 0, 0, 0.05) !default; + +// Toggle button (sub menu indicators) +$sm-simple__collapsible-toggle-bg: rgba(0, 0, 0, 0.08) !default; + + +// ---------------------------------------------------------- +// :: 1.6. Collapsible sub menus +// ---------------------------------------------------------- + +// Menu box +$sm-simple__collapsible-sub-bg: rgba(darken($sm-simple__collapsible-bg, 30%), 0.1) !default; + +// Items text indentation for deeper levels +$sm-simple__collapsible-sub-item-indentation: 8px !default; + + +// ---------------------------------------------------------- +// :: 1.7. Desktop main menu and sub menus +// ---------------------------------------------------------- + +// Menu box +$sm-simple__desktop-bg: $sm-simple__white !default; + +// Items +$sm-simple__desktop-item-color: $sm-simple__gray-darker !default; +$sm-simple__desktop-item-hover-bg: $sm-simple__gray !default; +$sm-simple__desktop-item-current-color: $sm-simple__white !default; +$sm-simple__desktop-item-current-bg: $sm-simple__gray-darker !default; +$sm-simple__desktop-item-disabled-color: darken($sm-simple__white, 20%) !default; +$sm-simple__desktop-item-padding-vertical: 11px !default; +$sm-simple__desktop-item-padding-horizontal: 20px !default; + +// Items separators +$sm-simple__desktop-separators-size: 1px !default; +$sm-simple__desktop-separators-color: $sm-simple__gray !default; + +// Sub menu indicators +$sm-simple__desktop-arrow-spacing: 4px !default; + + +// ----------------------------------------------------------------------------------------------------------------- +// 2. Theme CSS +// ----------------------------------------------------------------------------------------------------------------- + + +// ---------------------------------------------------------- +// :: 2.1. Collapsible mode (mobile first) +// ---------------------------------------------------------- + +// calc item height and sub menus toggle button size +$sm-simple__item-height: $sm-simple__line-height + $sm-simple__collapsible-item-padding-vertical * 2; +// set toggle button size to 80% of item height +$sm-simple__toggle-size: floor($sm-simple__item-height * 0.8); +$sm-simple__toggle-spacing: floor($sm-simple__item-height * 0.1); + +// Main menu box +.sm-simple { + border: $sm-simple__border-width solid $sm-simple__collapsible-border-color; + background: $sm-simple__collapsible-bg; + box-shadow: $sm-simple__collapsible-box-shadow; + + // Main menu items + a { + &, + &:hover, + &:focus, + &:active { + padding: $sm-simple__collapsible-item-padding-vertical $sm-simple__collapsible-item-padding-horizontal; + /* make room for the toggle button (sub indicator) */ + padding-right: $sm-simple__collapsible-item-padding-horizontal + $sm-simple__toggle-size + $sm-simple__toggle-spacing; + color: $sm-simple__collapsible-item-color; + font-family: $sm-simple__font-family; + font-size: $sm-simple__font-size-base; + font-weight: normal; + line-height: $sm-simple__line-height; + text-decoration: none; + } + + &.current { + background: $sm-simple__collapsible-item-current-bg; + color: $sm-simple__collapsible-item-current-color; + } + + &.disabled { + color: $sm-simple__collapsible-item-disabled-color; + } + + // Toggle buttons (sub menu indicators) + .sub-arrow { + position: absolute; + top: 50%; + margin-top: -(ceil($sm-simple__toggle-size / 2)); + left: auto; + right: $sm-simple__toggle-spacing; + width: $sm-simple__toggle-size; + height: $sm-simple__toggle-size; + overflow: hidden; + font: bold #{$sm-simple__font-size-small}/#{$sm-simple__toggle-size} monospace !important; + text-align: center; + text-shadow: none; + background: $sm-simple__collapsible-toggle-bg; + } + .sub-arrow::before { + content: '+'; + } + &.highlighted .sub-arrow::before { + content: '-'; + } + } + + // Main menu items separators + li { + border-top: 1px solid $sm-simple__collapsible-separators-color; + } + > li:first-child { + border-top: 0; + } + + // Sub menus box + ul { + background: $sm-simple__collapsible-sub-bg; + + // Sub menus items + a { + &, + &:hover, + &:focus, + &:active { + font-size: $sm-simple__font-size-small; + // add indentation for sub menus text + border-left: $sm-simple__collapsible-sub-item-indentation solid transparent; + } + } + + // Add indentation for sub menus text for deeper levels + @include sm-simple__sub-items-indentation($sm-simple__collapsible-sub-item-indentation); + } +} + + +// ---------------------------------------------------------- +// :: 2.2. Desktop mode +// ---------------------------------------------------------- + +@media (min-width: $sm-simple__desktop-vp) { + + /* Switch to desktop layout + ----------------------------------------------- + These transform the menu tree from + collapsible to desktop (navbar + dropdowns) + -----------------------------------------------*/ + /* start... (it's not recommended editing these rules) */ + .sm-simple ul{position:absolute;width:12em;} + .sm-simple li{float:left;} + .sm-simple.sm-rtl li{float:right;} + .sm-simple ul li,.sm-simple.sm-rtl ul li,.sm-simple.sm-vertical li{float:none;} + .sm-simple a{white-space:nowrap;} + .sm-simple ul a,.sm-simple.sm-vertical a{white-space:normal;} + .sm-simple .sm-nowrap > li > a,.sm-simple .sm-nowrap > li > :not(ul) a{white-space:nowrap;} + /* ...end */ + + // Main menu box + .sm-simple { + background: $sm-simple__desktop-bg; + + // Main menu items + a { + &, + &:hover, + &:focus, + &:active, + &.highlighted { + padding: $sm-simple__desktop-item-padding-vertical $sm-simple__desktop-item-padding-horizontal; + color: $sm-simple__desktop-item-color; + } + + &:hover, + &:focus, + &:active, + &.highlighted { + background: $sm-simple__desktop-item-hover-bg; + } + + &.current { + background: $sm-simple__desktop-item-current-bg; + color: $sm-simple__desktop-item-current-color; + } + + &.disabled { + background: $sm-simple__desktop-bg; + color: $sm-simple__desktop-item-disabled-color; + } + + // Make room for the sub arrows + &.has-submenu { + padding-right: $sm-simple__desktop-item-padding-horizontal + 8px + $sm-simple__desktop-arrow-spacing; + } + + // Sub menu indicators + .sub-arrow { + top: 50%; + margin-top: -8px; + right: $sm-simple__desktop-item-padding-horizontal; + width: 8px; + height: 16px; + font: #{$sm-simple__font-size-small}/16px monospace !important; + background: transparent; + } + // reset mobile first style + &.highlighted .sub-arrow::before { + content: '+'; + } + } + + // Main menu items separators + > li { + border-top: 0; + border-left: $sm-simple__desktop-separators-size solid $sm-simple__desktop-separators-color; + + &:first-child { + border-left: 0; + } + } + + // Sub menus box + ul { + border: $sm-simple__border-width solid $sm-simple__collapsible-border-color; + background: $sm-simple__desktop-bg; + box-shadow: $sm-simple__collapsible-box-shadow; + + // Sub menus items + a { + border: 0 !important; + + // No need for additional room for the sub arrows + &.has-submenu { + padding-right: $sm-simple__desktop-item-padding-horizontal; + } + + // Sub menu indicators + .sub-arrow { + left: $sm-simple__desktop-item-padding-horizontal - 8px - $sm-simple__desktop-arrow-spacing; + right: auto; + } + } + + // Sub menus items separators + > li { + border-left: 0; + border-top: $sm-simple__desktop-separators-size solid $sm-simple__desktop-separators-color; + + &:first-child { + border-top: 0; + } + } + } + + // Scrolling arrows containers for tall sub menus - test sub menu: "Sub test" -> "more..." in the default download package + .scroll-up, + .scroll-down { + position: absolute; + display: none; + visibility: hidden; + overflow: hidden; + background: $sm-simple__desktop-bg; + height: 20px; + // width and position will be set automatically by the script + } + .scroll-up-arrow, + .scroll-down-arrow { + position: absolute; + top: -2px; + left: 50%; + margin-left: -8px; + // we will use one-side border to create a triangle so that we don't use a real background image, of course, you can use a real image if you like too + width: 0; + height: 0; + overflow: hidden; + border-width: 8px; // tweak size of the arrow + border-style: dashed dashed solid dashed; + border-color: transparent transparent $sm-simple__desktop-item-color transparent; + } + .scroll-down-arrow { + top: 6px; + border-style: solid dashed dashed dashed; + border-color: $sm-simple__desktop-item-color transparent transparent transparent; + } + + + // Rigth-to-left + + // Main menu box + &.sm-rtl { + + // Main menu items + a { + + // Make room for the sub arrows + &.has-submenu { + padding-right: $sm-simple__desktop-item-padding-horizontal; + padding-left: $sm-simple__desktop-item-padding-horizontal + 8px + $sm-simple__desktop-arrow-spacing; + } + + // Sub menu indicators + .sub-arrow { + left: $sm-simple__desktop-item-padding-horizontal; + right: auto; + } + } + + // Vertical main menu items + &.sm-vertical { + a { + + // No need for additional room for the sub arrows + &.has-submenu { + padding: $sm-simple__desktop-item-padding-vertical $sm-simple__desktop-item-padding-horizontal; + } + + // Sub menu indicators + .sub-arrow { + left: auto; + right: $sm-simple__desktop-item-padding-horizontal - 8px - $sm-simple__desktop-arrow-spacing; + } + } + } + + // Main menu items separators + > li { + &:first-child { + border-left: $sm-simple__desktop-separators-size solid $sm-simple__desktop-separators-color; + } + &:last-child { + border-left: 0; + } + } + + // Sub menus box + ul { + a { + + // No need for additional room for the sub arrows + &.has-submenu { + padding: $sm-simple__desktop-item-padding-vertical $sm-simple__desktop-item-padding-horizontal; + } + + // Sub menu indicators + .sub-arrow { + left: auto; + right: $sm-simple__desktop-item-padding-horizontal - 8px - $sm-simple__desktop-arrow-spacing; + } + } + } + } + + + // Vertical main menu + + // Main menu box + &.sm-vertical { + + // Main menu items + a { + + // Sub menu indicators + .sub-arrow { + left: $sm-simple__desktop-item-padding-horizontal - 8px - $sm-simple__desktop-arrow-spacing; + right: auto; + } + } + + // Main menu items separators + li { + border-left: 0; + border-top: $sm-simple__desktop-separators-size solid $sm-simple__desktop-separators-color; + } + > li:first-child { + border-top: 0; + } + } + } +} \ No newline at end of file diff --git a/civicrm/bower_components/smartmenus/src/css/sm-simple/mixins/_sub-items-indentation.scss b/civicrm/bower_components/smartmenus/src/css/sm-simple/mixins/_sub-items-indentation.scss new file mode 100644 index 0000000000..966e7c6a27 --- /dev/null +++ b/civicrm/bower_components/smartmenus/src/css/sm-simple/mixins/_sub-items-indentation.scss @@ -0,0 +1,15 @@ +// Generate rules to indent sub menus text +// +// We'll use left border to avoid messing with the padding. + +@mixin sm-simple__sub-items-indentation($amount, $chainable: 'ul ', $level: 4, $chain: '') { + @for $i from 1 through $level { + $chain: $chain + $chainable; + #{$chain} a, + #{$chain} a:hover, + #{$chain} a:focus, + #{$chain} a:active { + border-left: ($amount * ($i + 1)) solid transparent; + } + } +} \ No newline at end of file diff --git a/civicrm/bower_components/smartmenus/src/css/sm-simple/sm-simple.css b/civicrm/bower_components/smartmenus/src/css/sm-simple/sm-simple.css new file mode 100644 index 0000000000..8fcf0c159a --- /dev/null +++ b/civicrm/bower_components/smartmenus/src/css/sm-simple/sm-simple.css @@ -0,0 +1,249 @@ +.sm-simple { + border: 1px solid #bbbbbb; + background: #fff; + box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2); +} +.sm-simple a, .sm-simple a:hover, .sm-simple a:focus, .sm-simple a:active { + padding: 13px 20px; + /* make room for the toggle button (sub indicator) */ + padding-right: 58px; + color: #555555; + font-family: "Lucida Sans Unicode", "Lucida Sans", "Lucida Grande", Arial, sans-serif; + font-size: 16px; + font-weight: normal; + line-height: 17px; + text-decoration: none; +} +.sm-simple a.current { + background: #555555; + color: #fff; +} +.sm-simple a.disabled { + color: #cccccc; +} +.sm-simple a .sub-arrow { + position: absolute; + top: 50%; + margin-top: -17px; + left: auto; + right: 4px; + width: 34px; + height: 34px; + overflow: hidden; + font: bold 14px/34px monospace !important; + text-align: center; + text-shadow: none; + background: rgba(0, 0, 0, 0.08); +} +.sm-simple a .sub-arrow::before { + content: '+'; +} +.sm-simple a.highlighted .sub-arrow::before { + content: '-'; +} +.sm-simple li { + border-top: 1px solid rgba(0, 0, 0, 0.05); +} +.sm-simple > li:first-child { + border-top: 0; +} +.sm-simple ul { + background: rgba(179, 179, 179, 0.1); +} +.sm-simple ul a, .sm-simple ul a:hover, .sm-simple ul a:focus, .sm-simple ul a:active { + font-size: 14px; + border-left: 8px solid transparent; +} +.sm-simple ul ul a, +.sm-simple ul ul a:hover, +.sm-simple ul ul a:focus, +.sm-simple ul ul a:active { + border-left: 16px solid transparent; +} +.sm-simple ul ul ul a, +.sm-simple ul ul ul a:hover, +.sm-simple ul ul ul a:focus, +.sm-simple ul ul ul a:active { + border-left: 24px solid transparent; +} +.sm-simple ul ul ul ul a, +.sm-simple ul ul ul ul a:hover, +.sm-simple ul ul ul ul a:focus, +.sm-simple ul ul ul ul a:active { + border-left: 32px solid transparent; +} +.sm-simple ul ul ul ul ul a, +.sm-simple ul ul ul ul ul a:hover, +.sm-simple ul ul ul ul ul a:focus, +.sm-simple ul ul ul ul ul a:active { + border-left: 40px solid transparent; +} + +@media (min-width: 768px) { + /* Switch to desktop layout + ----------------------------------------------- + These transform the menu tree from + collapsible to desktop (navbar + dropdowns) + -----------------------------------------------*/ + /* start... (it's not recommended editing these rules) */ + .sm-simple ul { + position: absolute; + width: 12em; + } + + .sm-simple li { + float: left; + } + + .sm-simple.sm-rtl li { + float: right; + } + + .sm-simple ul li, .sm-simple.sm-rtl ul li, .sm-simple.sm-vertical li { + float: none; + } + + .sm-simple a { + white-space: nowrap; + } + + .sm-simple ul a, .sm-simple.sm-vertical a { + white-space: normal; + } + + .sm-simple .sm-nowrap > li > a, .sm-simple .sm-nowrap > li > :not(ul) a { + white-space: nowrap; + } + + /* ...end */ + .sm-simple { + background: #fff; + } + .sm-simple a, .sm-simple a:hover, .sm-simple a:focus, .sm-simple a:active, .sm-simple a.highlighted { + padding: 11px 20px; + color: #555555; + } + .sm-simple a:hover, .sm-simple a:focus, .sm-simple a:active, .sm-simple a.highlighted { + background: #eeeeee; + } + .sm-simple a.current { + background: #555555; + color: #fff; + } + .sm-simple a.disabled { + background: #fff; + color: #cccccc; + } + .sm-simple a.has-submenu { + padding-right: 32px; + } + .sm-simple a .sub-arrow { + top: 50%; + margin-top: -8px; + right: 20px; + width: 8px; + height: 16px; + font: 14px/16px monospace !important; + background: transparent; + } + .sm-simple a.highlighted .sub-arrow::before { + content: '+'; + } + .sm-simple > li { + border-top: 0; + border-left: 1px solid #eeeeee; + } + .sm-simple > li:first-child { + border-left: 0; + } + .sm-simple ul { + border: 1px solid #bbbbbb; + background: #fff; + box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2); + } + .sm-simple ul a { + border: 0 !important; + } + .sm-simple ul a.has-submenu { + padding-right: 20px; + } + .sm-simple ul a .sub-arrow { + left: 8px; + right: auto; + } + .sm-simple ul > li { + border-left: 0; + border-top: 1px solid #eeeeee; + } + .sm-simple ul > li:first-child { + border-top: 0; + } + .sm-simple .scroll-up, + .sm-simple .scroll-down { + position: absolute; + display: none; + visibility: hidden; + overflow: hidden; + background: #fff; + height: 20px; + } + .sm-simple .scroll-up-arrow, + .sm-simple .scroll-down-arrow { + position: absolute; + top: -2px; + left: 50%; + margin-left: -8px; + width: 0; + height: 0; + overflow: hidden; + border-width: 8px; + border-style: dashed dashed solid dashed; + border-color: transparent transparent #555555 transparent; + } + .sm-simple .scroll-down-arrow { + top: 6px; + border-style: solid dashed dashed dashed; + border-color: #555555 transparent transparent transparent; + } + .sm-simple.sm-rtl a.has-submenu { + padding-right: 20px; + padding-left: 32px; + } + .sm-simple.sm-rtl a .sub-arrow { + left: 20px; + right: auto; + } + .sm-simple.sm-rtl.sm-vertical a.has-submenu { + padding: 11px 20px; + } + .sm-simple.sm-rtl.sm-vertical a .sub-arrow { + left: auto; + right: 8px; + } + .sm-simple.sm-rtl > li:first-child { + border-left: 1px solid #eeeeee; + } + .sm-simple.sm-rtl > li:last-child { + border-left: 0; + } + .sm-simple.sm-rtl ul a.has-submenu { + padding: 11px 20px; + } + .sm-simple.sm-rtl ul a .sub-arrow { + left: auto; + right: 8px; + } + .sm-simple.sm-vertical a .sub-arrow { + left: 8px; + right: auto; + } + .sm-simple.sm-vertical li { + border-left: 0; + border-top: 1px solid #eeeeee; + } + .sm-simple.sm-vertical > li:first-child { + border-top: 0; + } +} + +/*# sourceMappingURL=sm-simple.css.map */ diff --git a/civicrm/bower_components/smartmenus/src/css/sm-simple/sm-simple.css.map b/civicrm/bower_components/smartmenus/src/css/sm-simple/sm-simple.css.map new file mode 100644 index 0000000000..88f04761bf --- /dev/null +++ b/civicrm/bower_components/smartmenus/src/css/sm-simple/sm-simple.css.map @@ -0,0 +1,7 @@ +{ +"version": 3, +"mappings": "AAwHA,UAAW;EACV,MAAM,EAAE,iBAAmE;EAC3E,UAAU,EAhCiC,IAAiB;EAiC5D,UAAU,EAvE8B,4BAAiC;;AA2ExE,yEAGS;EACR,OAAO,EAAE,SAA6F;EACtG,qDAAqD;EACrD,aAAa,EAAE,IAAsG;EACrH,KAAK,EA3CiC,OAAuB;EA4C7D,WAAW,EAvGkB,wEAAwE;EAwGrG,SAAS,EAvGuB,IAAI;EAwGpC,WAAW,EAAE,MAAM;EACnB,WAAW,EAvGkB,IAAI;EAwGjC,eAAe,EAAE,IAAI;;AAGtB,oBAAU;EACT,UAAU,EApD4B,OAAuB;EAqD7D,KAAK,EAtDoC,IAAiB;;AAyD3D,qBAAW;EACV,KAAK,EA1FuC,OAA8B;;AA8F3E,uBAAW;EACV,QAAQ,EAAE,QAAQ;EAClB,GAAG,EAAE,GAAG;EACR,UAAU,EAAE,KAAoC;EAChD,IAAI,EAAE,IAAI;EACV,KAAK,EAxCoB,GAAoC;EAyC7D,KAAK,EA1CiB,IAAoC;EA2C1D,MAAM,EA3CgB,IAAoC;EA4C1D,QAAQ,EAAE,MAAM;EAChB,IAAI,EAAE,mCAAmF;EACzF,UAAU,EAAE,MAAM;EAClB,WAAW,EAAE,IAAI;EACjB,UAAU,EAlG2B,mBAAmB;;AAoGzD,+BAAmB;EAClB,OAAO,EAAE,GAAG;;AAEb,2CAAiC;EAChC,OAAO,EAAE,GAAG;;AAKd,aAAG;EACF,UAAU,EAAE,6BAAkD;;AAExD,2BAAiB;EACvB,UAAU,EAAE,CAAC;;AAId,aAAG;EACF,UAAU,EA9G0B,wBAAkD;;AAkHrF,qFAGS;EACR,SAAS,EA9JsB,IAAI;EAgKnC,WAAW,EAAE,qBAA8D;;AC3L7E;;;yBAGmB;EAClB,WAAW,EAAE,sBAAsC;;AAJpD;;;4BAGmB;EAClB,WAAW,EAAE,sBAAsC;;AAJpD;;;+BAGmB;EAClB,WAAW,EAAE,sBAAsC;;AAJpD;;;kCAGmB;EAClB,WAAW,EAAE,sBAAsC;;;ADqMtD,yBAA2C;EAE1C;;;;mDAIiD;EACjD,yDAAyD;EACzD,aAAa;IAAC,QAAQ,EAAC,QAAQ;IAAC,KAAK,EAAC,IAAI;;;EAC1C,aAAa;IAAC,KAAK,EAAC,IAAI;;;EACxB,oBAAoB;IAAC,KAAK,EAAC,KAAK;;;EAChC,oEAAkE;IAAC,KAAK,EAAC,IAAI;;;EAC7E,YAAY;IAAC,WAAW,EAAC,MAAM;;;EAC/B,yCAAwC;IAAC,WAAW,EAAC,MAAM;;;EAC3D,uEAAsE;IAAC,WAAW,EAAC,MAAM;;;EACzF,YAAY;EAGZ,UAAW;IACV,UAAU,EAzIgC,IAAiB;;EA6I1D,mGAIc;IACb,OAAO,EAAE,SAAqF;IAC9F,KAAK,EAlJgC,OAAuB;;EAqJ7D,qFAGc;IACb,UAAU,EAlJ4B,OAAgB;;EAqJvD,oBAAU;IACT,UAAU,EA7J2B,OAAuB;IA8J5D,KAAK,EA/JmC,IAAiB;;EAkK1D,qBAAW;IACV,UAAU,EAnK8B,IAAiB;IAoKzD,KAAK,EAlKmC,OAA8B;;EAsKvE,wBAAc;IACb,aAAa,EAAE,IAAqF;;EAIrG,uBAAW;IACV,GAAG,EAAE,GAAG;IACR,UAAU,EAAE,IAAI;IAChB,KAAK,EA5KsC,IAAI;IA6K/C,KAAK,EAAE,GAAG;IACV,MAAM,EAAE,IAAI;IACZ,IAAI,EAAE,8BAAwD;IAC9D,UAAU,EAAE,WAAW;;EAGxB,2CAAiC;IAChC,OAAO,EAAE,GAAG;;EAKd,eAAK;IACJ,UAAU,EAAE,CAAC;IACb,WAAW,EAAE,iBAA8E;;EAE3F,2BAAc;IACb,WAAW,EAAE,CAAC;;EAKhB,aAAG;IACF,MAAM,EAAE,iBAAmE;IAC3E,UAAU,EAzM+B,IAAiB;IA0M1D,UAAU,EAhP4B,4BAAiC;;EAmPvE,eAAE;IACD,MAAM,EAAE,YAAY;;EAGpB,2BAAc;IACb,aAAa,EA9M6B,IAAI;;EAkN/C,0BAAW;IACV,IAAI,EAAE,GAAqF;IAC3F,KAAK,EAAE,IAAI;;EAKb,kBAAK;IACJ,WAAW,EAAE,CAAC;IACd,UAAU,EAAE,iBAA8E;;EAE1F,8BAAc;IACb,UAAU,EAAE,CAAC;;EAMhB;yBACa;IACZ,QAAQ,EAAE,QAAQ;IAClB,OAAO,EAAE,IAAI;IACb,UAAU,EAAE,MAAM;IAClB,QAAQ,EAAE,MAAM;IAChB,UAAU,EA9O+B,IAAiB;IA+O1D,MAAM,EAAE,IAAI;;EAGb;+BACmB;IAClB,QAAQ,EAAE,QAAQ;IAClB,GAAG,EAAE,IAAI;IACT,IAAI,EAAE,GAAG;IACT,WAAW,EAAE,IAAI;IAEjB,KAAK,EAAE,CAAC;IACR,MAAM,EAAE,CAAC;IACT,QAAQ,EAAE,MAAM;IAChB,YAAY,EAAE,GAAG;IACjB,YAAY,EAAE,0BAA0B;IACxC,YAAY,EAAE,2CAAkE;;EAEjF,6BAAmB;IAClB,GAAG,EAAE,GAAG;IACR,YAAY,EAAE,0BAA0B;IACxC,YAAY,EAAE,2CAAkE;;EAa/E,+BAAc;IACb,aAAa,EA7Q6B,IAAI;IA8Q9C,YAAY,EAAE,IAAqF;;EAIpG,8BAAW;IACV,IAAI,EAnRsC,IAAI;IAoR9C,KAAK,EAAE,IAAI;;EASX,2CAAc;IACb,OAAO,EAAE,SAAqF;;EAI/F,0CAAW;IACV,IAAI,EAAE,IAAI;IACV,KAAK,EAAE,GAAqF;;EAO9F,kCAAc;IACb,WAAW,EAAE,iBAA8E;;EAE5F,iCAAa;IACZ,WAAW,EAAE,CAAC;;EASd,kCAAc;IACb,OAAO,EAAE,SAAqF;;EAI/F,iCAAW;IACV,IAAI,EAAE,IAAI;IACV,KAAK,EAAE,GAAqF;;EAgB9F,mCAAW;IACV,IAAI,EAAE,GAAqF;IAC3F,KAAK,EAAE,IAAI;;EAKb,yBAAG;IACF,WAAW,EAAE,CAAC;IACd,UAAU,EAAE,iBAA8E;;EAE3F,uCAAiB;IAChB,UAAU,EAAE,CAAC", +"sources": ["_sm-simple-theme.scss","mixins/_sub-items-indentation.scss"], +"names": [], +"file": "sm-simple.css" +} diff --git a/civicrm/bower_components/smartmenus/src/css/sm-simple/sm-simple.scss b/civicrm/bower_components/smartmenus/src/css/sm-simple/sm-simple.scss new file mode 100644 index 0000000000..5415dbf372 --- /dev/null +++ b/civicrm/bower_components/smartmenus/src/css/sm-simple/sm-simple.scss @@ -0,0 +1,4 @@ +@import '_mixins.scss'; + +// the variables + the CSS +@import '_sm-simple-theme.scss'; \ No newline at end of file diff --git a/civicrm/bower_components/smartmenus/src/demo/bootstrap-4-navbar-fixed-bottom.html b/civicrm/bower_components/smartmenus/src/demo/bootstrap-4-navbar-fixed-bottom.html new file mode 100644 index 0000000000..1e830901e8 --- /dev/null +++ b/civicrm/bower_components/smartmenus/src/demo/bootstrap-4-navbar-fixed-bottom.html @@ -0,0 +1,377 @@ +<!DOCTYPE html> +<html lang="en"> + <head> + <meta charset="utf-8"> + <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> + + <title>SmartMenus jQuery Website Menu - Bootstrap 4 Addon - Navbar fixed bottom</title> + + + + + <!-- Bootstrap core CSS --> + <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css"> + + <!-- SmartMenus jQuery Bootstrap 4 Addon CSS --> + <link href="../addons/bootstrap-4/jquery.smartmenus.bootstrap-4.css" rel="stylesheet"> + + + + + </head> + + <body style="padding-bottom:80px;"> + + + + <!-- Navbar --> + <nav class="navbar navbar-expand-lg fixed-bottom navbar-dark bg-dark"> + <div class="container"> + <a class="navbar-brand" href="#">Navbar</a> + <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNavDropdown" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation"> + <span class="navbar-toggler-icon"></span> + </button> + + <div class="collapse navbar-collapse" id="navbarNavDropdown"> + + <!-- Left nav --> + <ul class="nav navbar-nav mr-auto"> + <li class="nav-item"><a class="nav-link" href="#">Link</a></li> + <li class="nav-item"><a class="nav-link" href="#">Link</a></li> + <li class="nav-item"><a class="nav-link" href="#">Link</a></li> + <li class="nav-item dropdown"><a class="nav-link dropdown-toggle" href="#">Dropdown</a> + <ul class="dropdown-menu"> + <li><a class="dropdown-item" href="#">Action</a></li> + <li><a class="dropdown-item disabled" href="#">Disabled link</a></li> + <li><a class="dropdown-item" href="#">Something else here</a></li> + <li class="dropdown-divider"></li> + <li class="dropdown-header">Nav header</li> + <li><a class="dropdown-item" href="#">Separated link</a></li> + <li class="dropdown"><a class="dropdown-item dropdown-toggle" href="#">One more separated link</a> + <ul class="dropdown-menu"> + <li><a class="dropdown-item" href="#">Action</a></li> + <li><a class="dropdown-item" href="#">Another action</a></li> + <li class="dropdown"><a class="dropdown-item dropdown-toggle" href="#">A long sub menu</a> + <ul class="dropdown-menu"> + <li><a class="dropdown-item" href="#">Action</a></li> + <li><a class="dropdown-item" href="#">Something else here</a></li> + <li><a class="dropdown-item" href="#">One more link</a></li> + <li><a class="dropdown-item" href="#">Menu item 1</a></li> + <li><a class="dropdown-item" href="#">Menu item 2</a></li> + <li><a class="dropdown-item" href="#">Menu item 3</a></li> + <li><a class="dropdown-item" href="#">Menu item 4</a></li> + <li><a class="dropdown-item" href="#">Menu item 5</a></li> + <li><a class="dropdown-item" href="#">Menu item 6</a></li> + <li><a class="dropdown-item" href="#">Menu item 7</a></li> + <li><a class="dropdown-item" href="#">Menu item 8</a></li> + <li><a class="dropdown-item" href="#">Menu item 9</a></li> + <li><a class="dropdown-item" href="#">Menu item 10</a></li> + <li><a class="dropdown-item" href="#">Menu item 11</a></li> + <li><a class="dropdown-item" href="#">Menu item 12</a></li> + <li><a class="dropdown-item" href="#">Menu item 13</a></li> + <li><a class="dropdown-item" href="#">Menu item 14</a></li> + <li><a class="dropdown-item" href="#">Menu item 15</a></li> + <li><a class="dropdown-item" href="#">Menu item 16</a></li> + <li><a class="dropdown-item" href="#">Menu item 17</a></li> + <li><a class="dropdown-item" href="#">Menu item 18</a></li> + <li><a class="dropdown-item" href="#">Menu item 19</a></li> + <li><a class="dropdown-item" href="#">Menu item 20</a></li> + <li><a class="dropdown-item" href="#">Menu item 21</a></li> + <li><a class="dropdown-item" href="#">Menu item 22</a></li> + <li><a class="dropdown-item" href="#">Menu item 23</a></li> + <li><a class="dropdown-item" href="#">Menu item 24</a></li> + <li><a class="dropdown-item" href="#">Menu item 25</a></li> + <li><a class="dropdown-item" href="#">Menu item 26</a></li> + <li><a class="dropdown-item" href="#">Menu item 27</a></li> + <li><a class="dropdown-item" href="#">Menu item 28</a></li> + <li><a class="dropdown-item" href="#">Menu item 29</a></li> + <li><a class="dropdown-item" href="#">Menu item 30</a></li> + <li><a class="dropdown-item" href="#">Menu item 31</a></li> + <li><a class="dropdown-item" href="#">Menu item 32</a></li> + <li><a class="dropdown-item" href="#">Menu item 33</a></li> + <li><a class="dropdown-item" href="#">Menu item 34</a></li> + <li><a class="dropdown-item" href="#">Menu item 35</a></li> + <li><a class="dropdown-item" href="#">Menu item 36</a></li> + <li><a class="dropdown-item" href="#">Menu item 37</a></li> + <li><a class="dropdown-item" href="#">Menu item 38</a></li> + <li><a class="dropdown-item" href="#">Menu item 39</a></li> + <li><a class="dropdown-item" href="#">Menu item 40</a></li> + <li><a class="dropdown-item" href="#">Menu item 41</a></li> + <li><a class="dropdown-item" href="#">Menu item 42</a></li> + <li><a class="dropdown-item" href="#">Menu item 43</a></li> + <li><a class="dropdown-item" href="#">Menu item 44</a></li> + <li><a class="dropdown-item" href="#">Menu item 45</a></li> + <li><a class="dropdown-item" href="#">Menu item 46</a></li> + <li><a class="dropdown-item" href="#">Menu item 47</a></li> + <li><a class="dropdown-item" href="#">Menu item 48</a></li> + <li><a class="dropdown-item" href="#">Menu item 49</a></li> + <li><a class="dropdown-item" href="#">Menu item 50</a></li> + <li><a class="dropdown-item" href="#">Menu item 51</a></li> + <li><a class="dropdown-item" href="#">Menu item 52</a></li> + <li><a class="dropdown-item" href="#">Menu item 53</a></li> + <li><a class="dropdown-item" href="#">Menu item 54</a></li> + <li><a class="dropdown-item" href="#">Menu item 55</a></li> + <li><a class="dropdown-item" href="#">Menu item 56</a></li> + <li><a class="dropdown-item" href="#">Menu item 57</a></li> + <li><a class="dropdown-item" href="#">Menu item 58</a></li> + <li><a class="dropdown-item" href="#">Menu item 59</a></li> + <li><a class="dropdown-item" href="#">Menu item 60</a></li> + </ul> + </li> + <li><a class="dropdown-item" href="#">Another link</a></li> + <li><a class="dropdown-item" href="#">One more link</a></li> + </ul> + </li> + </ul> + </li> + </ul> + + <!-- Right nav --> + <ul class="nav navbar-nav"> + <li class="nav-item"><a class="nav-link" href="bootstrap-4-navbar.html">Default</a></li> + <li class="nav-item"><a class="nav-link" href="bootstrap-4-navbar-static-top.html">Static top</a></li> + <li class="nav-item"><a class="nav-link" href="bootstrap-4-navbar-fixed-top.html">Fixed top</a></li> + <li class="nav-item active"><a class="nav-link" href="bootstrap-4-navbar-fixed-bottom.html">Fixed bottom</a></li> + <li class="nav-item dropdown"><a class="nav-link dropdown-toggle" href="#">Dropdown</a> + <ul class="dropdown-menu"> + <li><a class="dropdown-item" href="#">Action</a></li> + <li><a class="dropdown-item" href="#">Another action</a></li> + <li><a class="dropdown-item" href="#">Something else here</a></li> + <li class="dropdown-divider"></li> + <li class="dropdown-header">Nav header</li> + <li class="dropdown"><a class="dropdown-item dropdown-toggle" href="#">A sub menu</a> + <ul class="dropdown-menu"> + <li><a class="dropdown-item" href="#">Action</a></li> + <li><a class="dropdown-item" href="#">Another action</a></li> + <li><a class="dropdown-item" href="#">Something else here</a></li> + <li><a class="dropdown-item disabled" href="#">Disabled item</a></li> + <li><a class="dropdown-item" href="#">One more link</a></li> + </ul> + </li> + <li><a class="dropdown-item" href="#">A separated link</a></li> + </ul> + </li> + </ul> + + </div> + </div> + </nav> + + + + <div class="container pt-4"> + + <div class="jumbotron bg-light"> + <h1>SmartMenus Bootstrap 4 Addon (Navbar fixed bottom)</h1> + <p class="lead">Zero config advanced Bootstrap navbars with SmartMenus jQuery and the SmartMenus jQuery Bootstrap 4 Addon.</p> + </div> + + <p>You just need to include the JS/CSS files on your Bootstrap 4 powered pages and everything should work automatically including full support for your Bootstrap 4 theme. And you also have the power and flexibility of SmartMenus jQuery at hand should you need to tweak or customize anything.</p> + + <h2>Source Code</h2> + + <h3>CSS</h3> + <p>In addition to Bootstrap's CSS just include the SmartMenus jQuery Bootstrap 4 Addon CSS. It's just static CSS code you don't need to edit at all (and probably shouldn't try to).</p> + <pre class="border rounded p-3 bg-light"><!-- Bootstrap core CSS --> +<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet"> + +<span class="text-success"><!-- SmartMenus jQuery Bootstrap 4 Addon CSS --> +<link href="../addons/bootstrap-4/jquery.smartmenus.bootstrap-4.css" rel="stylesheet"></span></pre> + + <h3>HTML</h3> + <p><strong class="text-info">Note:</strong> Bootstrap 4 normally uses <code><div></code> elements as <code>.dropdown-menu</code> containers. But since we are building a multi-level menu tree, we need to replace them with nested <code><ul></code>/<code><li></code> elements.</p> + <pre class="border rounded p-3 bg-light"><!-- Navbar --> +<nav class="navbar navbar-expand-lg navbar-dark bg-dark mb-4"> + <div class="container"> + <a class="navbar-brand" href="#">Navbar</a> + <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNavDropdown" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation"> + <span class="navbar-toggler-icon"></span> + </button> + + <div class="collapse navbar-collapse" id="navbarNavDropdown"> + <span class="text-success"> + <!-- Left nav --> + <ul class="nav navbar-nav mr-auto"> + <li class="nav-item"><a class="nav-link" href="#">Link</a></li> + <li class="nav-item"><a class="nav-link" href="#">Link</a></li> + <li class="nav-item"><a class="nav-link" href="#">Link</a></li> + <li class="nav-item dropdown"><a class="nav-link dropdown-toggle" href="#">Dropdown</a> + <ul class="dropdown-menu"> + <li><a class="dropdown-item" href="#">Action</a></li> + <li><a class="dropdown-item disabled" href="#">Disabled link</a></li> + <li><a class="dropdown-item" href="#">Something else here</a></li> + <li class="dropdown-divider"></li> + <li class="dropdown-header">Nav header</li> + <li><a class="dropdown-item" href="#">Separated link</a></li> + <li class="dropdown"><a class="dropdown-item dropdown-toggle" href="#">One more separated link</a> + <ul class="dropdown-menu"> + <li><a class="dropdown-item" href="#">Action</a></li> + <li><a class="dropdown-item" href="#">Another action</a></li> + <li class="dropdown"><a class="dropdown-item dropdown-toggle" href="#">A long sub menu</a> + <ul class="dropdown-menu"> + <li><a class="dropdown-item" href="#">Action</a></li> + <li><a class="dropdown-item" href="#">Something else here</a></li> + <li><a class="dropdown-item" href="#">One more link</a></li> + <li><a class="dropdown-item" href="#">Menu item 1</a></li> + <li><a class="dropdown-item" href="#">Menu item 2</a></li> + <li><a class="dropdown-item" href="#">Menu item 3</a></li> + <li><a class="dropdown-item" href="#">Menu item 4</a></li> + <li><a class="dropdown-item" href="#">Menu item 5</a></li> + <li><a class="dropdown-item" href="#">Menu item 6</a></li> + <li><a class="dropdown-item" href="#">Menu item 7</a></li> + <li><a class="dropdown-item" href="#">Menu item 8</a></li> + <li><a class="dropdown-item" href="#">Menu item 9</a></li> + <li><a class="dropdown-item" href="#">Menu item 10</a></li> + <li><a class="dropdown-item" href="#">Menu item 11</a></li> + <li><a class="dropdown-item" href="#">Menu item 12</a></li> + <li><a class="dropdown-item" href="#">Menu item 13</a></li> + <li><a class="dropdown-item" href="#">Menu item 14</a></li> + <li><a class="dropdown-item" href="#">Menu item 15</a></li> + <li><a class="dropdown-item" href="#">Menu item 16</a></li> + <li><a class="dropdown-item" href="#">Menu item 17</a></li> + <li><a class="dropdown-item" href="#">Menu item 18</a></li> + <li><a class="dropdown-item" href="#">Menu item 19</a></li> + <li><a class="dropdown-item" href="#">Menu item 20</a></li> + <li><a class="dropdown-item" href="#">Menu item 21</a></li> + <li><a class="dropdown-item" href="#">Menu item 22</a></li> + <li><a class="dropdown-item" href="#">Menu item 23</a></li> + <li><a class="dropdown-item" href="#">Menu item 24</a></li> + <li><a class="dropdown-item" href="#">Menu item 25</a></li> + <li><a class="dropdown-item" href="#">Menu item 26</a></li> + <li><a class="dropdown-item" href="#">Menu item 27</a></li> + <li><a class="dropdown-item" href="#">Menu item 28</a></li> + <li><a class="dropdown-item" href="#">Menu item 29</a></li> + <li><a class="dropdown-item" href="#">Menu item 30</a></li> + <li><a class="dropdown-item" href="#">Menu item 31</a></li> + <li><a class="dropdown-item" href="#">Menu item 32</a></li> + <li><a class="dropdown-item" href="#">Menu item 33</a></li> + <li><a class="dropdown-item" href="#">Menu item 34</a></li> + <li><a class="dropdown-item" href="#">Menu item 35</a></li> + <li><a class="dropdown-item" href="#">Menu item 36</a></li> + <li><a class="dropdown-item" href="#">Menu item 37</a></li> + <li><a class="dropdown-item" href="#">Menu item 38</a></li> + <li><a class="dropdown-item" href="#">Menu item 39</a></li> + <li><a class="dropdown-item" href="#">Menu item 40</a></li> + <li><a class="dropdown-item" href="#">Menu item 41</a></li> + <li><a class="dropdown-item" href="#">Menu item 42</a></li> + <li><a class="dropdown-item" href="#">Menu item 43</a></li> + <li><a class="dropdown-item" href="#">Menu item 44</a></li> + <li><a class="dropdown-item" href="#">Menu item 45</a></li> + <li><a class="dropdown-item" href="#">Menu item 46</a></li> + <li><a class="dropdown-item" href="#">Menu item 47</a></li> + <li><a class="dropdown-item" href="#">Menu item 48</a></li> + <li><a class="dropdown-item" href="#">Menu item 49</a></li> + <li><a class="dropdown-item" href="#">Menu item 50</a></li> + <li><a class="dropdown-item" href="#">Menu item 51</a></li> + <li><a class="dropdown-item" href="#">Menu item 52</a></li> + <li><a class="dropdown-item" href="#">Menu item 53</a></li> + <li><a class="dropdown-item" href="#">Menu item 54</a></li> + <li><a class="dropdown-item" href="#">Menu item 55</a></li> + <li><a class="dropdown-item" href="#">Menu item 56</a></li> + <li><a class="dropdown-item" href="#">Menu item 57</a></li> + <li><a class="dropdown-item" href="#">Menu item 58</a></li> + <li><a class="dropdown-item" href="#">Menu item 59</a></li> + <li><a class="dropdown-item" href="#">Menu item 60</a></li> + </ul> + </li> + <li><a class="dropdown-item" href="#">Another link</a></li> + <li><a class="dropdown-item" href="#">One more link</a></li> + </ul> + </li> + </ul> + </li> + </ul> + + <!-- Right nav --> + <ul class="nav navbar-nav"> + <li class="nav-item"><a class="nav-link" href="bootstrap-4-navbar.html">Default</a></li> + <li class="nav-item"><a class="nav-link" href="bootstrap-4-navbar-static-top.html">Static top</a></li> + <li class="nav-item"><a class="nav-link" href="bootstrap-4-navbar-fixed-top.html">Fixed top</a></li> + <li class="nav-item active"><a class="nav-link" href="bootstrap-4-navbar-fixed-bottom.html">Fixed bottom</a></li> + <li class="nav-item dropdown"><a class="nav-link dropdown-toggle" href="#">Dropdown</a> + <ul class="dropdown-menu"> + <li><a class="dropdown-item" href="#">Action</a></li> + <li><a class="dropdown-item" href="#">Another action</a></li> + <li><a class="dropdown-item" href="#">Something else here</a></li> + <li class="dropdown-divider"></li> + <li class="dropdown-header">Nav header</li> + <li class="dropdown"><a class="dropdown-item dropdown-toggle" href="#">A sub menu</a> + <ul class="dropdown-menu"> + <li><a class="dropdown-item" href="#">Action</a></li> + <li><a class="dropdown-item" href="#">Another action</a></li> + <li><a class="dropdown-item" href="#">Something else here</a></li> + <li><a class="dropdown-item disabled" href="#">Disabled item</a></li> + <li><a class="dropdown-item" href="#">One more link</a></li> + </ul> + </li> + <li><a class="dropdown-item" href="#">A separated link</a></li> + </ul> + </li> + </ul> + </span> + </div> + </div> +</nav></pre> + + <h3>JavaScript</h3> + <p>In addition to Bootstrap's JavaScript just include SmartMenus jQuery and the SmartMenus jQuery Bootstrap 4 Addon. The default options used in <code>jquery.smartmenus.bootstrap.js</code> should work well for all. However, you can, of course, tweak them if you like.</p> + <pre class="border rounded p-3 bg-light"><!-- jQuery first, then Popper.js, then Bootstrap JS --> +<script src="http://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script> +<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.11.0/umd/popper.min.js" integrity="sha384-b/U6ypiBEHpOf/4+1nzFpr53nxSS+GLCkfwBdFNTxtclqqenISfwAzpKaMNFNmj4" crossorigin="anonymous"></script> +<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/js/bootstrap.min.js" integrity="sha384-h0AbiXch4ZDo7tp9hKZ4TsHbi047NrKGLO3SEJAg45jXxnGIfYzk4Si90RDIqNm1" crossorigin="anonymous"></script> + +<span class="text-success"><!-- SmartMenus jQuery plugin --> +<script type="text/javascript" src="../jquery.smartmenus.js"></script> + +<!-- SmartMenus jQuery Bootstrap 4 Addon --> +<script type="text/javascript" src="../addons/bootstrap-4/jquery.smartmenus.bootstrap-4.js"></script></span></pre> + + <h2>Quick customization</h2> + + <h3><code>data-*</code> attributes</h3> + <p>The Bootstrap 4 addon introduces the following additional <code>data-*</code> attributes which can be set to any <code>.navbar-nav</code>:</p> + <ul> + <li><code>data-sm-skip</code> - this will tell the script to skip this navbar and not apply any SmartMenus features to it so it will behave like a regular Bootstrap navbar.</li> + <li><code>data-sm-skip-collapsible-behavior</code> - this will tell the script to not apply SmartMenus' specific behavior to this navbar in collapsible mode (mobile view). Bootstrap's behavior for navbars in collapsible mode is to use the whole area of the parent items just as a toggle button for their sub menus and thus it's impossible to set a link to the parent items that can be followed on click/tap. SmartMenus' behavior is to add a separate +/- sub menus toggle button to parent items and thus allows the link of the parent items to be activated on the second click/tap (the first click/tap displays the sub menu if it's not visible). If you need even further control, you can check the <a href="https://www.smartmenus.org/docs/#collapsibleBehavior"><code>collapsibleBehavior</code></a> SmartMenus option which can be set in a <a href="https://www.smartmenus.org/docs/#data-sm-options"><code>data-sm-options</code></a> attribute.</li> + </ul> + + <h3>Options</h3> + <p>The following additional option can be set in a <a href="https://www.smartmenus.org/docs/#data-sm-options"><code>data-sm-options</code></a> attribute:</p> + <ul> + <li><code>bootstrapHighlightClasses: 'text-dark bg-light'</code> - CSS class(es) for highlighting expanded parent dropdown items.</li> + </ul> + <p><a href="https://www.smartmenus.org/docs/#options">Check the docs</a> for a complete list of all the available SmartMenus options.</p> + + <h3>API</h3> + <p>The following methods are available:</p> + <ul> + <li><code>jQuery.SmartMenus.Bootstrap.init()</code> - reinit the addon. Useful if you add any navbars dynamically on your page and need to init them at any time (all navbars are normally initialized ondomready).</li> + </ul> + + <hr /> + + <ul class="pagination"> + <li class="page-item"><a class="page-link" href="index.html">« Back to main demo</a></li> + </ul> + + </div> <!-- /container --> + + + + + <!-- jQuery first, then Popper.js, then Bootstrap JS --> + <script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script> + <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.11.0/umd/popper.min.js" integrity="sha384-b/U6ypiBEHpOf/4+1nzFpr53nxSS+GLCkfwBdFNTxtclqqenISfwAzpKaMNFNmj4" crossorigin="anonymous"></script> + <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/js/bootstrap.min.js" integrity="sha384-h0AbiXch4ZDo7tp9hKZ4TsHbi047NrKGLO3SEJAg45jXxnGIfYzk4Si90RDIqNm1" crossorigin="anonymous"></script> + + <!-- SmartMenus jQuery plugin --> + <script type="text/javascript" src="../jquery.smartmenus.js"></script> + + <!-- SmartMenus jQuery Bootstrap 4 Addon --> + <script type="text/javascript" src="../addons/bootstrap-4/jquery.smartmenus.bootstrap-4.js"></script> + + + + + </body> +</html> \ No newline at end of file diff --git a/civicrm/bower_components/smartmenus/src/demo/bootstrap-4-navbar-fixed-top.html b/civicrm/bower_components/smartmenus/src/demo/bootstrap-4-navbar-fixed-top.html new file mode 100644 index 0000000000..da63b1131b --- /dev/null +++ b/civicrm/bower_components/smartmenus/src/demo/bootstrap-4-navbar-fixed-top.html @@ -0,0 +1,377 @@ +<!DOCTYPE html> +<html lang="en"> + <head> + <meta charset="utf-8"> + <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> + + <title>SmartMenus jQuery Website Menu - Bootstrap 4 Addon - Navbar fixed top</title> + + + + + <!-- Bootstrap core CSS --> + <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css"> + + <!-- SmartMenus jQuery Bootstrap 4 Addon CSS --> + <link href="../addons/bootstrap-4/jquery.smartmenus.bootstrap-4.css" rel="stylesheet"> + + + + + </head> + + <body style="padding-top:80px;"> + + + + <!-- Navbar --> + <nav class="navbar navbar-expand-lg fixed-top navbar-dark bg-dark"> + <div class="container"> + <a class="navbar-brand" href="#">Navbar</a> + <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNavDropdown" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation"> + <span class="navbar-toggler-icon"></span> + </button> + + <div class="collapse navbar-collapse" id="navbarNavDropdown"> + + <!-- Left nav --> + <ul class="nav navbar-nav mr-auto"> + <li class="nav-item"><a class="nav-link" href="#">Link</a></li> + <li class="nav-item"><a class="nav-link" href="#">Link</a></li> + <li class="nav-item"><a class="nav-link" href="#">Link</a></li> + <li class="nav-item dropdown"><a class="nav-link dropdown-toggle" href="#">Dropdown</a> + <ul class="dropdown-menu"> + <li><a class="dropdown-item" href="#">Action</a></li> + <li><a class="dropdown-item disabled" href="#">Disabled link</a></li> + <li><a class="dropdown-item" href="#">Something else here</a></li> + <li class="dropdown-divider"></li> + <li class="dropdown-header">Nav header</li> + <li><a class="dropdown-item" href="#">Separated link</a></li> + <li class="dropdown"><a class="dropdown-item dropdown-toggle" href="#">One more separated link</a> + <ul class="dropdown-menu"> + <li><a class="dropdown-item" href="#">Action</a></li> + <li><a class="dropdown-item" href="#">Another action</a></li> + <li class="dropdown"><a class="dropdown-item dropdown-toggle" href="#">A long sub menu</a> + <ul class="dropdown-menu"> + <li><a class="dropdown-item" href="#">Action</a></li> + <li><a class="dropdown-item" href="#">Something else here</a></li> + <li><a class="dropdown-item" href="#">One more link</a></li> + <li><a class="dropdown-item" href="#">Menu item 1</a></li> + <li><a class="dropdown-item" href="#">Menu item 2</a></li> + <li><a class="dropdown-item" href="#">Menu item 3</a></li> + <li><a class="dropdown-item" href="#">Menu item 4</a></li> + <li><a class="dropdown-item" href="#">Menu item 5</a></li> + <li><a class="dropdown-item" href="#">Menu item 6</a></li> + <li><a class="dropdown-item" href="#">Menu item 7</a></li> + <li><a class="dropdown-item" href="#">Menu item 8</a></li> + <li><a class="dropdown-item" href="#">Menu item 9</a></li> + <li><a class="dropdown-item" href="#">Menu item 10</a></li> + <li><a class="dropdown-item" href="#">Menu item 11</a></li> + <li><a class="dropdown-item" href="#">Menu item 12</a></li> + <li><a class="dropdown-item" href="#">Menu item 13</a></li> + <li><a class="dropdown-item" href="#">Menu item 14</a></li> + <li><a class="dropdown-item" href="#">Menu item 15</a></li> + <li><a class="dropdown-item" href="#">Menu item 16</a></li> + <li><a class="dropdown-item" href="#">Menu item 17</a></li> + <li><a class="dropdown-item" href="#">Menu item 18</a></li> + <li><a class="dropdown-item" href="#">Menu item 19</a></li> + <li><a class="dropdown-item" href="#">Menu item 20</a></li> + <li><a class="dropdown-item" href="#">Menu item 21</a></li> + <li><a class="dropdown-item" href="#">Menu item 22</a></li> + <li><a class="dropdown-item" href="#">Menu item 23</a></li> + <li><a class="dropdown-item" href="#">Menu item 24</a></li> + <li><a class="dropdown-item" href="#">Menu item 25</a></li> + <li><a class="dropdown-item" href="#">Menu item 26</a></li> + <li><a class="dropdown-item" href="#">Menu item 27</a></li> + <li><a class="dropdown-item" href="#">Menu item 28</a></li> + <li><a class="dropdown-item" href="#">Menu item 29</a></li> + <li><a class="dropdown-item" href="#">Menu item 30</a></li> + <li><a class="dropdown-item" href="#">Menu item 31</a></li> + <li><a class="dropdown-item" href="#">Menu item 32</a></li> + <li><a class="dropdown-item" href="#">Menu item 33</a></li> + <li><a class="dropdown-item" href="#">Menu item 34</a></li> + <li><a class="dropdown-item" href="#">Menu item 35</a></li> + <li><a class="dropdown-item" href="#">Menu item 36</a></li> + <li><a class="dropdown-item" href="#">Menu item 37</a></li> + <li><a class="dropdown-item" href="#">Menu item 38</a></li> + <li><a class="dropdown-item" href="#">Menu item 39</a></li> + <li><a class="dropdown-item" href="#">Menu item 40</a></li> + <li><a class="dropdown-item" href="#">Menu item 41</a></li> + <li><a class="dropdown-item" href="#">Menu item 42</a></li> + <li><a class="dropdown-item" href="#">Menu item 43</a></li> + <li><a class="dropdown-item" href="#">Menu item 44</a></li> + <li><a class="dropdown-item" href="#">Menu item 45</a></li> + <li><a class="dropdown-item" href="#">Menu item 46</a></li> + <li><a class="dropdown-item" href="#">Menu item 47</a></li> + <li><a class="dropdown-item" href="#">Menu item 48</a></li> + <li><a class="dropdown-item" href="#">Menu item 49</a></li> + <li><a class="dropdown-item" href="#">Menu item 50</a></li> + <li><a class="dropdown-item" href="#">Menu item 51</a></li> + <li><a class="dropdown-item" href="#">Menu item 52</a></li> + <li><a class="dropdown-item" href="#">Menu item 53</a></li> + <li><a class="dropdown-item" href="#">Menu item 54</a></li> + <li><a class="dropdown-item" href="#">Menu item 55</a></li> + <li><a class="dropdown-item" href="#">Menu item 56</a></li> + <li><a class="dropdown-item" href="#">Menu item 57</a></li> + <li><a class="dropdown-item" href="#">Menu item 58</a></li> + <li><a class="dropdown-item" href="#">Menu item 59</a></li> + <li><a class="dropdown-item" href="#">Menu item 60</a></li> + </ul> + </li> + <li><a class="dropdown-item" href="#">Another link</a></li> + <li><a class="dropdown-item" href="#">One more link</a></li> + </ul> + </li> + </ul> + </li> + </ul> + + <!-- Right nav --> + <ul class="nav navbar-nav"> + <li class="nav-item"><a class="nav-link" href="bootstrap-4-navbar.html">Default</a></li> + <li class="nav-item"><a class="nav-link" href="bootstrap-4-navbar-static-top.html">Static top</a></li> + <li class="nav-item active"><a class="nav-link" href="bootstrap-4-navbar-fixed-top.html">Fixed top</a></li> + <li class="nav-item"><a class="nav-link" href="bootstrap-4-navbar-fixed-bottom.html">Fixed bottom</a></li> + <li class="nav-item dropdown"><a class="nav-link dropdown-toggle" href="#">Dropdown</a> + <ul class="dropdown-menu"> + <li><a class="dropdown-item" href="#">Action</a></li> + <li><a class="dropdown-item" href="#">Another action</a></li> + <li><a class="dropdown-item" href="#">Something else here</a></li> + <li class="dropdown-divider"></li> + <li class="dropdown-header">Nav header</li> + <li class="dropdown"><a class="dropdown-item dropdown-toggle" href="#">A sub menu</a> + <ul class="dropdown-menu"> + <li><a class="dropdown-item" href="#">Action</a></li> + <li><a class="dropdown-item" href="#">Another action</a></li> + <li><a class="dropdown-item" href="#">Something else here</a></li> + <li><a class="dropdown-item disabled" href="#">Disabled item</a></li> + <li><a class="dropdown-item" href="#">One more link</a></li> + </ul> + </li> + <li><a class="dropdown-item" href="#">A separated link</a></li> + </ul> + </li> + </ul> + + </div> + </div> + </nav> + + + + <div class="container"> + + <div class="jumbotron bg-light"> + <h1>SmartMenus Bootstrap 4 Addon (Navbar fixed top)</h1> + <p class="lead">Zero config advanced Bootstrap navbars with SmartMenus jQuery and the SmartMenus jQuery Bootstrap 4 Addon.</p> + </div> + + <p>You just need to include the JS/CSS files on your Bootstrap 4 powered pages and everything should work automatically including full support for your Bootstrap 4 theme. And you also have the power and flexibility of SmartMenus jQuery at hand should you need to tweak or customize anything.</p> + + <h2>Source Code</h2> + + <h3>CSS</h3> + <p>In addition to Bootstrap's CSS just include the SmartMenus jQuery Bootstrap 4 Addon CSS. It's just static CSS code you don't need to edit at all (and probably shouldn't try to).</p> + <pre class="border rounded p-3 bg-light"><!-- Bootstrap core CSS --> +<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet"> + +<span class="text-success"><!-- SmartMenus jQuery Bootstrap 4 Addon CSS --> +<link href="../addons/bootstrap-4/jquery.smartmenus.bootstrap-4.css" rel="stylesheet"></span></pre> + + <h3>HTML</h3> + <p><strong class="text-info">Note:</strong> Bootstrap 4 normally uses <code><div></code> elements as <code>.dropdown-menu</code> containers. But since we are building a multi-level menu tree, we need to replace them with nested <code><ul></code>/<code><li></code> elements.</p> + <pre class="border rounded p-3 bg-light"><!-- Navbar --> +<nav class="navbar navbar-expand-lg navbar-dark bg-dark mb-4"> + <div class="container"> + <a class="navbar-brand" href="#">Navbar</a> + <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNavDropdown" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation"> + <span class="navbar-toggler-icon"></span> + </button> + + <div class="collapse navbar-collapse" id="navbarNavDropdown"> + <span class="text-success"> + <!-- Left nav --> + <ul class="nav navbar-nav mr-auto"> + <li class="nav-item"><a class="nav-link" href="#">Link</a></li> + <li class="nav-item"><a class="nav-link" href="#">Link</a></li> + <li class="nav-item"><a class="nav-link" href="#">Link</a></li> + <li class="nav-item dropdown"><a class="nav-link dropdown-toggle" href="#">Dropdown</a> + <ul class="dropdown-menu"> + <li><a class="dropdown-item" href="#">Action</a></li> + <li><a class="dropdown-item disabled" href="#">Disabled link</a></li> + <li><a class="dropdown-item" href="#">Something else here</a></li> + <li class="dropdown-divider"></li> + <li class="dropdown-header">Nav header</li> + <li><a class="dropdown-item" href="#">Separated link</a></li> + <li class="dropdown"><a class="dropdown-item dropdown-toggle" href="#">One more separated link</a> + <ul class="dropdown-menu"> + <li><a class="dropdown-item" href="#">Action</a></li> + <li><a class="dropdown-item" href="#">Another action</a></li> + <li class="dropdown"><a class="dropdown-item dropdown-toggle" href="#">A long sub menu</a> + <ul class="dropdown-menu"> + <li><a class="dropdown-item" href="#">Action</a></li> + <li><a class="dropdown-item" href="#">Something else here</a></li> + <li><a class="dropdown-item" href="#">One more link</a></li> + <li><a class="dropdown-item" href="#">Menu item 1</a></li> + <li><a class="dropdown-item" href="#">Menu item 2</a></li> + <li><a class="dropdown-item" href="#">Menu item 3</a></li> + <li><a class="dropdown-item" href="#">Menu item 4</a></li> + <li><a class="dropdown-item" href="#">Menu item 5</a></li> + <li><a class="dropdown-item" href="#">Menu item 6</a></li> + <li><a class="dropdown-item" href="#">Menu item 7</a></li> + <li><a class="dropdown-item" href="#">Menu item 8</a></li> + <li><a class="dropdown-item" href="#">Menu item 9</a></li> + <li><a class="dropdown-item" href="#">Menu item 10</a></li> + <li><a class="dropdown-item" href="#">Menu item 11</a></li> + <li><a class="dropdown-item" href="#">Menu item 12</a></li> + <li><a class="dropdown-item" href="#">Menu item 13</a></li> + <li><a class="dropdown-item" href="#">Menu item 14</a></li> + <li><a class="dropdown-item" href="#">Menu item 15</a></li> + <li><a class="dropdown-item" href="#">Menu item 16</a></li> + <li><a class="dropdown-item" href="#">Menu item 17</a></li> + <li><a class="dropdown-item" href="#">Menu item 18</a></li> + <li><a class="dropdown-item" href="#">Menu item 19</a></li> + <li><a class="dropdown-item" href="#">Menu item 20</a></li> + <li><a class="dropdown-item" href="#">Menu item 21</a></li> + <li><a class="dropdown-item" href="#">Menu item 22</a></li> + <li><a class="dropdown-item" href="#">Menu item 23</a></li> + <li><a class="dropdown-item" href="#">Menu item 24</a></li> + <li><a class="dropdown-item" href="#">Menu item 25</a></li> + <li><a class="dropdown-item" href="#">Menu item 26</a></li> + <li><a class="dropdown-item" href="#">Menu item 27</a></li> + <li><a class="dropdown-item" href="#">Menu item 28</a></li> + <li><a class="dropdown-item" href="#">Menu item 29</a></li> + <li><a class="dropdown-item" href="#">Menu item 30</a></li> + <li><a class="dropdown-item" href="#">Menu item 31</a></li> + <li><a class="dropdown-item" href="#">Menu item 32</a></li> + <li><a class="dropdown-item" href="#">Menu item 33</a></li> + <li><a class="dropdown-item" href="#">Menu item 34</a></li> + <li><a class="dropdown-item" href="#">Menu item 35</a></li> + <li><a class="dropdown-item" href="#">Menu item 36</a></li> + <li><a class="dropdown-item" href="#">Menu item 37</a></li> + <li><a class="dropdown-item" href="#">Menu item 38</a></li> + <li><a class="dropdown-item" href="#">Menu item 39</a></li> + <li><a class="dropdown-item" href="#">Menu item 40</a></li> + <li><a class="dropdown-item" href="#">Menu item 41</a></li> + <li><a class="dropdown-item" href="#">Menu item 42</a></li> + <li><a class="dropdown-item" href="#">Menu item 43</a></li> + <li><a class="dropdown-item" href="#">Menu item 44</a></li> + <li><a class="dropdown-item" href="#">Menu item 45</a></li> + <li><a class="dropdown-item" href="#">Menu item 46</a></li> + <li><a class="dropdown-item" href="#">Menu item 47</a></li> + <li><a class="dropdown-item" href="#">Menu item 48</a></li> + <li><a class="dropdown-item" href="#">Menu item 49</a></li> + <li><a class="dropdown-item" href="#">Menu item 50</a></li> + <li><a class="dropdown-item" href="#">Menu item 51</a></li> + <li><a class="dropdown-item" href="#">Menu item 52</a></li> + <li><a class="dropdown-item" href="#">Menu item 53</a></li> + <li><a class="dropdown-item" href="#">Menu item 54</a></li> + <li><a class="dropdown-item" href="#">Menu item 55</a></li> + <li><a class="dropdown-item" href="#">Menu item 56</a></li> + <li><a class="dropdown-item" href="#">Menu item 57</a></li> + <li><a class="dropdown-item" href="#">Menu item 58</a></li> + <li><a class="dropdown-item" href="#">Menu item 59</a></li> + <li><a class="dropdown-item" href="#">Menu item 60</a></li> + </ul> + </li> + <li><a class="dropdown-item" href="#">Another link</a></li> + <li><a class="dropdown-item" href="#">One more link</a></li> + </ul> + </li> + </ul> + </li> + </ul> + + <!-- Right nav --> + <ul class="nav navbar-nav"> + <li class="nav-item"><a class="nav-link" href="bootstrap-4-navbar.html">Default</a></li> + <li class="nav-item"><a class="nav-link" href="bootstrap-4-navbar-static-top.html">Static top</a></li> + <li class="nav-item active"><a class="nav-link" href="bootstrap-4-navbar-fixed-top.html">Fixed top</a></li> + <li class="nav-item"><a class="nav-link" href="bootstrap-4-navbar-fixed-bottom.html">Fixed bottom</a></li> + <li class="nav-item dropdown"><a class="nav-link dropdown-toggle" href="#">Dropdown</a> + <ul class="dropdown-menu"> + <li><a class="dropdown-item" href="#">Action</a></li> + <li><a class="dropdown-item" href="#">Another action</a></li> + <li><a class="dropdown-item" href="#">Something else here</a></li> + <li class="dropdown-divider"></li> + <li class="dropdown-header">Nav header</li> + <li class="dropdown"><a class="dropdown-item dropdown-toggle" href="#">A sub menu</a> + <ul class="dropdown-menu"> + <li><a class="dropdown-item" href="#">Action</a></li> + <li><a class="dropdown-item" href="#">Another action</a></li> + <li><a class="dropdown-item" href="#">Something else here</a></li> + <li><a class="dropdown-item disabled" href="#">Disabled item</a></li> + <li><a class="dropdown-item" href="#">One more link</a></li> + </ul> + </li> + <li><a class="dropdown-item" href="#">A separated link</a></li> + </ul> + </li> + </ul> + </span> + </div> + </div> +</nav></pre> + + <h3>JavaScript</h3> + <p>In addition to Bootstrap's JavaScript just include SmartMenus jQuery and the SmartMenus jQuery Bootstrap 4 Addon. The default options used in <code>jquery.smartmenus.bootstrap.js</code> should work well for all. However, you can, of course, tweak them if you like.</p> + <pre class="border rounded p-3 bg-light"><!-- jQuery first, then Popper.js, then Bootstrap JS --> +<script src="http://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script> +<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.11.0/umd/popper.min.js" integrity="sha384-b/U6ypiBEHpOf/4+1nzFpr53nxSS+GLCkfwBdFNTxtclqqenISfwAzpKaMNFNmj4" crossorigin="anonymous"></script> +<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/js/bootstrap.min.js" integrity="sha384-h0AbiXch4ZDo7tp9hKZ4TsHbi047NrKGLO3SEJAg45jXxnGIfYzk4Si90RDIqNm1" crossorigin="anonymous"></script> + +<span class="text-success"><!-- SmartMenus jQuery plugin --> +<script type="text/javascript" src="../jquery.smartmenus.js"></script> + +<!-- SmartMenus jQuery Bootstrap 4 Addon --> +<script type="text/javascript" src="../addons/bootstrap-4/jquery.smartmenus.bootstrap-4.js"></script></span></pre> + + <h2>Quick customization</h2> + + <h3><code>data-*</code> attributes</h3> + <p>The Bootstrap 4 addon introduces the following additional <code>data-*</code> attributes which can be set to any <code>.navbar-nav</code>:</p> + <ul> + <li><code>data-sm-skip</code> - this will tell the script to skip this navbar and not apply any SmartMenus features to it so it will behave like a regular Bootstrap navbar.</li> + <li><code>data-sm-skip-collapsible-behavior</code> - this will tell the script to not apply SmartMenus' specific behavior to this navbar in collapsible mode (mobile view). Bootstrap's behavior for navbars in collapsible mode is to use the whole area of the parent items just as a toggle button for their sub menus and thus it's impossible to set a link to the parent items that can be followed on click/tap. SmartMenus' behavior is to add a separate +/- sub menus toggle button to parent items and thus allows the link of the parent items to be activated on the second click/tap (the first click/tap displays the sub menu if it's not visible). If you need even further control, you can check the <a href="https://www.smartmenus.org/docs/#collapsibleBehavior"><code>collapsibleBehavior</code></a> SmartMenus option which can be set in a <a href="https://www.smartmenus.org/docs/#data-sm-options"><code>data-sm-options</code></a> attribute.</li> + </ul> + + <h3>Options</h3> + <p>The following additional option can be set in a <a href="https://www.smartmenus.org/docs/#data-sm-options"><code>data-sm-options</code></a> attribute:</p> + <ul> + <li><code>bootstrapHighlightClasses: 'text-dark bg-light'</code> - CSS class(es) for highlighting expanded parent dropdown items.</li> + </ul> + <p><a href="https://www.smartmenus.org/docs/#options">Check the docs</a> for a complete list of all the available SmartMenus options.</p> + + <h3>API</h3> + <p>The following methods are available:</p> + <ul> + <li><code>jQuery.SmartMenus.Bootstrap.init()</code> - reinit the addon. Useful if you add any navbars dynamically on your page and need to init them at any time (all navbars are normally initialized ondomready).</li> + </ul> + + <hr /> + + <ul class="pagination"> + <li class="page-item"><a class="page-link" href="index.html">« Back to main demo</a></li> + </ul> + + </div> <!-- /container --> + + + + + <!-- jQuery first, then Popper.js, then Bootstrap JS --> + <script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script> + <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.11.0/umd/popper.min.js" integrity="sha384-b/U6ypiBEHpOf/4+1nzFpr53nxSS+GLCkfwBdFNTxtclqqenISfwAzpKaMNFNmj4" crossorigin="anonymous"></script> + <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/js/bootstrap.min.js" integrity="sha384-h0AbiXch4ZDo7tp9hKZ4TsHbi047NrKGLO3SEJAg45jXxnGIfYzk4Si90RDIqNm1" crossorigin="anonymous"></script> + + <!-- SmartMenus jQuery plugin --> + <script type="text/javascript" src="../jquery.smartmenus.js"></script> + + <!-- SmartMenus jQuery Bootstrap 4 Addon --> + <script type="text/javascript" src="../addons/bootstrap-4/jquery.smartmenus.bootstrap-4.js"></script> + + + + + </body> +</html> \ No newline at end of file diff --git a/civicrm/bower_components/smartmenus/src/demo/bootstrap-4-navbar-static-top.html b/civicrm/bower_components/smartmenus/src/demo/bootstrap-4-navbar-static-top.html new file mode 100644 index 0000000000..5ee83c8b5f --- /dev/null +++ b/civicrm/bower_components/smartmenus/src/demo/bootstrap-4-navbar-static-top.html @@ -0,0 +1,377 @@ +<!DOCTYPE html> +<html lang="en"> + <head> + <meta charset="utf-8"> + <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> + + <title>SmartMenus jQuery Website Menu - Bootstrap 4 Addon - Navbar static top</title> + + + + + <!-- Bootstrap core CSS --> + <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css"> + + <!-- SmartMenus jQuery Bootstrap 4 Addon CSS --> + <link href="../addons/bootstrap-4/jquery.smartmenus.bootstrap-4.css" rel="stylesheet"> + + + + + </head> + + <body> + + + + <!-- Navbar --> + <nav class="navbar navbar-expand-lg navbar-dark bg-dark mb-4"> + <div class="container"> + <a class="navbar-brand" href="#">Navbar</a> + <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNavDropdown" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation"> + <span class="navbar-toggler-icon"></span> + </button> + + <div class="collapse navbar-collapse" id="navbarNavDropdown"> + + <!-- Left nav --> + <ul class="nav navbar-nav mr-auto"> + <li class="nav-item"><a class="nav-link" href="#">Link</a></li> + <li class="nav-item"><a class="nav-link" href="#">Link</a></li> + <li class="nav-item"><a class="nav-link" href="#">Link</a></li> + <li class="nav-item dropdown"><a class="nav-link dropdown-toggle" href="#">Dropdown</a> + <ul class="dropdown-menu"> + <li><a class="dropdown-item" href="#">Action</a></li> + <li><a class="dropdown-item disabled" href="#">Disabled link</a></li> + <li><a class="dropdown-item" href="#">Something else here</a></li> + <li class="dropdown-divider"></li> + <li class="dropdown-header">Nav header</li> + <li><a class="dropdown-item" href="#">Separated link</a></li> + <li class="dropdown"><a class="dropdown-item dropdown-toggle" href="#">One more separated link</a> + <ul class="dropdown-menu"> + <li><a class="dropdown-item" href="#">Action</a></li> + <li><a class="dropdown-item" href="#">Another action</a></li> + <li class="dropdown"><a class="dropdown-item dropdown-toggle" href="#">A long sub menu</a> + <ul class="dropdown-menu"> + <li><a class="dropdown-item" href="#">Action</a></li> + <li><a class="dropdown-item" href="#">Something else here</a></li> + <li><a class="dropdown-item" href="#">One more link</a></li> + <li><a class="dropdown-item" href="#">Menu item 1</a></li> + <li><a class="dropdown-item" href="#">Menu item 2</a></li> + <li><a class="dropdown-item" href="#">Menu item 3</a></li> + <li><a class="dropdown-item" href="#">Menu item 4</a></li> + <li><a class="dropdown-item" href="#">Menu item 5</a></li> + <li><a class="dropdown-item" href="#">Menu item 6</a></li> + <li><a class="dropdown-item" href="#">Menu item 7</a></li> + <li><a class="dropdown-item" href="#">Menu item 8</a></li> + <li><a class="dropdown-item" href="#">Menu item 9</a></li> + <li><a class="dropdown-item" href="#">Menu item 10</a></li> + <li><a class="dropdown-item" href="#">Menu item 11</a></li> + <li><a class="dropdown-item" href="#">Menu item 12</a></li> + <li><a class="dropdown-item" href="#">Menu item 13</a></li> + <li><a class="dropdown-item" href="#">Menu item 14</a></li> + <li><a class="dropdown-item" href="#">Menu item 15</a></li> + <li><a class="dropdown-item" href="#">Menu item 16</a></li> + <li><a class="dropdown-item" href="#">Menu item 17</a></li> + <li><a class="dropdown-item" href="#">Menu item 18</a></li> + <li><a class="dropdown-item" href="#">Menu item 19</a></li> + <li><a class="dropdown-item" href="#">Menu item 20</a></li> + <li><a class="dropdown-item" href="#">Menu item 21</a></li> + <li><a class="dropdown-item" href="#">Menu item 22</a></li> + <li><a class="dropdown-item" href="#">Menu item 23</a></li> + <li><a class="dropdown-item" href="#">Menu item 24</a></li> + <li><a class="dropdown-item" href="#">Menu item 25</a></li> + <li><a class="dropdown-item" href="#">Menu item 26</a></li> + <li><a class="dropdown-item" href="#">Menu item 27</a></li> + <li><a class="dropdown-item" href="#">Menu item 28</a></li> + <li><a class="dropdown-item" href="#">Menu item 29</a></li> + <li><a class="dropdown-item" href="#">Menu item 30</a></li> + <li><a class="dropdown-item" href="#">Menu item 31</a></li> + <li><a class="dropdown-item" href="#">Menu item 32</a></li> + <li><a class="dropdown-item" href="#">Menu item 33</a></li> + <li><a class="dropdown-item" href="#">Menu item 34</a></li> + <li><a class="dropdown-item" href="#">Menu item 35</a></li> + <li><a class="dropdown-item" href="#">Menu item 36</a></li> + <li><a class="dropdown-item" href="#">Menu item 37</a></li> + <li><a class="dropdown-item" href="#">Menu item 38</a></li> + <li><a class="dropdown-item" href="#">Menu item 39</a></li> + <li><a class="dropdown-item" href="#">Menu item 40</a></li> + <li><a class="dropdown-item" href="#">Menu item 41</a></li> + <li><a class="dropdown-item" href="#">Menu item 42</a></li> + <li><a class="dropdown-item" href="#">Menu item 43</a></li> + <li><a class="dropdown-item" href="#">Menu item 44</a></li> + <li><a class="dropdown-item" href="#">Menu item 45</a></li> + <li><a class="dropdown-item" href="#">Menu item 46</a></li> + <li><a class="dropdown-item" href="#">Menu item 47</a></li> + <li><a class="dropdown-item" href="#">Menu item 48</a></li> + <li><a class="dropdown-item" href="#">Menu item 49</a></li> + <li><a class="dropdown-item" href="#">Menu item 50</a></li> + <li><a class="dropdown-item" href="#">Menu item 51</a></li> + <li><a class="dropdown-item" href="#">Menu item 52</a></li> + <li><a class="dropdown-item" href="#">Menu item 53</a></li> + <li><a class="dropdown-item" href="#">Menu item 54</a></li> + <li><a class="dropdown-item" href="#">Menu item 55</a></li> + <li><a class="dropdown-item" href="#">Menu item 56</a></li> + <li><a class="dropdown-item" href="#">Menu item 57</a></li> + <li><a class="dropdown-item" href="#">Menu item 58</a></li> + <li><a class="dropdown-item" href="#">Menu item 59</a></li> + <li><a class="dropdown-item" href="#">Menu item 60</a></li> + </ul> + </li> + <li><a class="dropdown-item" href="#">Another link</a></li> + <li><a class="dropdown-item" href="#">One more link</a></li> + </ul> + </li> + </ul> + </li> + </ul> + + <!-- Right nav --> + <ul class="nav navbar-nav"> + <li class="nav-item"><a class="nav-link" href="bootstrap-4-navbar.html">Default</a></li> + <li class="nav-item active"><a class="nav-link" href="bootstrap-4-navbar-static-top.html">Static top</a></li> + <li class="nav-item"><a class="nav-link" href="bootstrap-4-navbar-fixed-top.html">Fixed top</a></li> + <li class="nav-item"><a class="nav-link" href="bootstrap-4-navbar-fixed-bottom.html">Fixed bottom</a></li> + <li class="nav-item dropdown"><a class="nav-link dropdown-toggle" href="#">Dropdown</a> + <ul class="dropdown-menu"> + <li><a class="dropdown-item" href="#">Action</a></li> + <li><a class="dropdown-item" href="#">Another action</a></li> + <li><a class="dropdown-item" href="#">Something else here</a></li> + <li class="dropdown-divider"></li> + <li class="dropdown-header">Nav header</li> + <li class="dropdown"><a class="dropdown-item dropdown-toggle" href="#">A sub menu</a> + <ul class="dropdown-menu"> + <li><a class="dropdown-item" href="#">Action</a></li> + <li><a class="dropdown-item" href="#">Another action</a></li> + <li><a class="dropdown-item" href="#">Something else here</a></li> + <li><a class="dropdown-item disabled" href="#">Disabled item</a></li> + <li><a class="dropdown-item" href="#">One more link</a></li> + </ul> + </li> + <li><a class="dropdown-item" href="#">A separated link</a></li> + </ul> + </li> + </ul> + + </div> + </div> + </nav> + + + + <div class="container"> + + <div class="jumbotron bg-light"> + <h1>SmartMenus Bootstrap 4 Addon (Navbar static top)</h1> + <p class="lead">Zero config advanced Bootstrap navbars with SmartMenus jQuery and the SmartMenus jQuery Bootstrap 4 Addon.</p> + </div> + + <p>You just need to include the JS/CSS files on your Bootstrap 4 powered pages and everything should work automatically including full support for your Bootstrap 4 theme. And you also have the power and flexibility of SmartMenus jQuery at hand should you need to tweak or customize anything.</p> + + <h2>Source Code</h2> + + <h3>CSS</h3> + <p>In addition to Bootstrap's CSS just include the SmartMenus jQuery Bootstrap 4 Addon CSS. It's just static CSS code you don't need to edit at all (and probably shouldn't try to).</p> + <pre class="border rounded p-3 bg-light"><!-- Bootstrap core CSS --> +<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet"> + +<span class="text-success"><!-- SmartMenus jQuery Bootstrap 4 Addon CSS --> +<link href="../addons/bootstrap-4/jquery.smartmenus.bootstrap-4.css" rel="stylesheet"></span></pre> + + <h3>HTML</h3> + <p><strong class="text-info">Note:</strong> Bootstrap 4 normally uses <code><div></code> elements as <code>.dropdown-menu</code> containers. But since we are building a multi-level menu tree, we need to replace them with nested <code><ul></code>/<code><li></code> elements.</p> + <pre class="border rounded p-3 bg-light"><!-- Navbar --> +<nav class="navbar navbar-expand-lg navbar-dark bg-dark mb-4"> + <div class="container"> + <a class="navbar-brand" href="#">Navbar</a> + <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNavDropdown" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation"> + <span class="navbar-toggler-icon"></span> + </button> + + <div class="collapse navbar-collapse" id="navbarNavDropdown"> + <span class="text-success"> + <!-- Left nav --> + <ul class="nav navbar-nav mr-auto"> + <li class="nav-item"><a class="nav-link" href="#">Link</a></li> + <li class="nav-item"><a class="nav-link" href="#">Link</a></li> + <li class="nav-item"><a class="nav-link" href="#">Link</a></li> + <li class="nav-item dropdown"><a class="nav-link dropdown-toggle" href="#">Dropdown</a> + <ul class="dropdown-menu"> + <li><a class="dropdown-item" href="#">Action</a></li> + <li><a class="dropdown-item disabled" href="#">Disabled link</a></li> + <li><a class="dropdown-item" href="#">Something else here</a></li> + <li class="dropdown-divider"></li> + <li class="dropdown-header">Nav header</li> + <li><a class="dropdown-item" href="#">Separated link</a></li> + <li class="dropdown"><a class="dropdown-item dropdown-toggle" href="#">One more separated link</a> + <ul class="dropdown-menu"> + <li><a class="dropdown-item" href="#">Action</a></li> + <li><a class="dropdown-item" href="#">Another action</a></li> + <li class="dropdown"><a class="dropdown-item dropdown-toggle" href="#">A long sub menu</a> + <ul class="dropdown-menu"> + <li><a class="dropdown-item" href="#">Action</a></li> + <li><a class="dropdown-item" href="#">Something else here</a></li> + <li><a class="dropdown-item" href="#">One more link</a></li> + <li><a class="dropdown-item" href="#">Menu item 1</a></li> + <li><a class="dropdown-item" href="#">Menu item 2</a></li> + <li><a class="dropdown-item" href="#">Menu item 3</a></li> + <li><a class="dropdown-item" href="#">Menu item 4</a></li> + <li><a class="dropdown-item" href="#">Menu item 5</a></li> + <li><a class="dropdown-item" href="#">Menu item 6</a></li> + <li><a class="dropdown-item" href="#">Menu item 7</a></li> + <li><a class="dropdown-item" href="#">Menu item 8</a></li> + <li><a class="dropdown-item" href="#">Menu item 9</a></li> + <li><a class="dropdown-item" href="#">Menu item 10</a></li> + <li><a class="dropdown-item" href="#">Menu item 11</a></li> + <li><a class="dropdown-item" href="#">Menu item 12</a></li> + <li><a class="dropdown-item" href="#">Menu item 13</a></li> + <li><a class="dropdown-item" href="#">Menu item 14</a></li> + <li><a class="dropdown-item" href="#">Menu item 15</a></li> + <li><a class="dropdown-item" href="#">Menu item 16</a></li> + <li><a class="dropdown-item" href="#">Menu item 17</a></li> + <li><a class="dropdown-item" href="#">Menu item 18</a></li> + <li><a class="dropdown-item" href="#">Menu item 19</a></li> + <li><a class="dropdown-item" href="#">Menu item 20</a></li> + <li><a class="dropdown-item" href="#">Menu item 21</a></li> + <li><a class="dropdown-item" href="#">Menu item 22</a></li> + <li><a class="dropdown-item" href="#">Menu item 23</a></li> + <li><a class="dropdown-item" href="#">Menu item 24</a></li> + <li><a class="dropdown-item" href="#">Menu item 25</a></li> + <li><a class="dropdown-item" href="#">Menu item 26</a></li> + <li><a class="dropdown-item" href="#">Menu item 27</a></li> + <li><a class="dropdown-item" href="#">Menu item 28</a></li> + <li><a class="dropdown-item" href="#">Menu item 29</a></li> + <li><a class="dropdown-item" href="#">Menu item 30</a></li> + <li><a class="dropdown-item" href="#">Menu item 31</a></li> + <li><a class="dropdown-item" href="#">Menu item 32</a></li> + <li><a class="dropdown-item" href="#">Menu item 33</a></li> + <li><a class="dropdown-item" href="#">Menu item 34</a></li> + <li><a class="dropdown-item" href="#">Menu item 35</a></li> + <li><a class="dropdown-item" href="#">Menu item 36</a></li> + <li><a class="dropdown-item" href="#">Menu item 37</a></li> + <li><a class="dropdown-item" href="#">Menu item 38</a></li> + <li><a class="dropdown-item" href="#">Menu item 39</a></li> + <li><a class="dropdown-item" href="#">Menu item 40</a></li> + <li><a class="dropdown-item" href="#">Menu item 41</a></li> + <li><a class="dropdown-item" href="#">Menu item 42</a></li> + <li><a class="dropdown-item" href="#">Menu item 43</a></li> + <li><a class="dropdown-item" href="#">Menu item 44</a></li> + <li><a class="dropdown-item" href="#">Menu item 45</a></li> + <li><a class="dropdown-item" href="#">Menu item 46</a></li> + <li><a class="dropdown-item" href="#">Menu item 47</a></li> + <li><a class="dropdown-item" href="#">Menu item 48</a></li> + <li><a class="dropdown-item" href="#">Menu item 49</a></li> + <li><a class="dropdown-item" href="#">Menu item 50</a></li> + <li><a class="dropdown-item" href="#">Menu item 51</a></li> + <li><a class="dropdown-item" href="#">Menu item 52</a></li> + <li><a class="dropdown-item" href="#">Menu item 53</a></li> + <li><a class="dropdown-item" href="#">Menu item 54</a></li> + <li><a class="dropdown-item" href="#">Menu item 55</a></li> + <li><a class="dropdown-item" href="#">Menu item 56</a></li> + <li><a class="dropdown-item" href="#">Menu item 57</a></li> + <li><a class="dropdown-item" href="#">Menu item 58</a></li> + <li><a class="dropdown-item" href="#">Menu item 59</a></li> + <li><a class="dropdown-item" href="#">Menu item 60</a></li> + </ul> + </li> + <li><a class="dropdown-item" href="#">Another link</a></li> + <li><a class="dropdown-item" href="#">One more link</a></li> + </ul> + </li> + </ul> + </li> + </ul> + + <!-- Right nav --> + <ul class="nav navbar-nav"> + <li class="nav-item"><a class="nav-link" href="bootstrap-4-navbar.html">Default</a></li> + <li class="nav-item active"><a class="nav-link" href="bootstrap-4-navbar-static-top.html">Static top</a></li> + <li class="nav-item"><a class="nav-link" href="bootstrap-4-navbar-fixed-top.html">Fixed top</a></li> + <li class="nav-item"><a class="nav-link" href="bootstrap-4-navbar-fixed-bottom.html">Fixed bottom</a></li> + <li class="nav-item dropdown"><a class="nav-link dropdown-toggle" href="#">Dropdown</a> + <ul class="dropdown-menu"> + <li><a class="dropdown-item" href="#">Action</a></li> + <li><a class="dropdown-item" href="#">Another action</a></li> + <li><a class="dropdown-item" href="#">Something else here</a></li> + <li class="dropdown-divider"></li> + <li class="dropdown-header">Nav header</li> + <li class="dropdown"><a class="dropdown-item dropdown-toggle" href="#">A sub menu</a> + <ul class="dropdown-menu"> + <li><a class="dropdown-item" href="#">Action</a></li> + <li><a class="dropdown-item" href="#">Another action</a></li> + <li><a class="dropdown-item" href="#">Something else here</a></li> + <li><a class="dropdown-item disabled" href="#">Disabled item</a></li> + <li><a class="dropdown-item" href="#">One more link</a></li> + </ul> + </li> + <li><a class="dropdown-item" href="#">A separated link</a></li> + </ul> + </li> + </ul> + </span> + </div> + </div> +</nav></pre> + + <h3>JavaScript</h3> + <p>In addition to Bootstrap's JavaScript just include SmartMenus jQuery and the SmartMenus jQuery Bootstrap 4 Addon. The default options used in <code>jquery.smartmenus.bootstrap.js</code> should work well for all. However, you can, of course, tweak them if you like.</p> + <pre class="border rounded p-3 bg-light"><!-- jQuery first, then Popper.js, then Bootstrap JS --> +<script src="http://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script> +<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.11.0/umd/popper.min.js" integrity="sha384-b/U6ypiBEHpOf/4+1nzFpr53nxSS+GLCkfwBdFNTxtclqqenISfwAzpKaMNFNmj4" crossorigin="anonymous"></script> +<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/js/bootstrap.min.js" integrity="sha384-h0AbiXch4ZDo7tp9hKZ4TsHbi047NrKGLO3SEJAg45jXxnGIfYzk4Si90RDIqNm1" crossorigin="anonymous"></script> + +<span class="text-success"><!-- SmartMenus jQuery plugin --> +<script type="text/javascript" src="../jquery.smartmenus.js"></script> + +<!-- SmartMenus jQuery Bootstrap 4 Addon --> +<script type="text/javascript" src="../addons/bootstrap-4/jquery.smartmenus.bootstrap-4.js"></script></span></pre> + + <h2>Quick customization</h2> + + <h3><code>data-*</code> attributes</h3> + <p>The Bootstrap 4 addon introduces the following additional <code>data-*</code> attributes which can be set to any <code>.navbar-nav</code>:</p> + <ul> + <li><code>data-sm-skip</code> - this will tell the script to skip this navbar and not apply any SmartMenus features to it so it will behave like a regular Bootstrap navbar.</li> + <li><code>data-sm-skip-collapsible-behavior</code> - this will tell the script to not apply SmartMenus' specific behavior to this navbar in collapsible mode (mobile view). Bootstrap's behavior for navbars in collapsible mode is to use the whole area of the parent items just as a toggle button for their sub menus and thus it's impossible to set a link to the parent items that can be followed on click/tap. SmartMenus' behavior is to add a separate +/- sub menus toggle button to parent items and thus allows the link of the parent items to be activated on the second click/tap (the first click/tap displays the sub menu if it's not visible). If you need even further control, you can check the <a href="https://www.smartmenus.org/docs/#collapsibleBehavior"><code>collapsibleBehavior</code></a> SmartMenus option which can be set in a <a href="https://www.smartmenus.org/docs/#data-sm-options"><code>data-sm-options</code></a> attribute.</li> + </ul> + + <h3>Options</h3> + <p>The following additional option can be set in a <a href="https://www.smartmenus.org/docs/#data-sm-options"><code>data-sm-options</code></a> attribute:</p> + <ul> + <li><code>bootstrapHighlightClasses: 'text-dark bg-light'</code> - CSS class(es) for highlighting expanded parent dropdown items.</li> + </ul> + <p><a href="https://www.smartmenus.org/docs/#options">Check the docs</a> for a complete list of all the available SmartMenus options.</p> + + <h3>API</h3> + <p>The following methods are available:</p> + <ul> + <li><code>jQuery.SmartMenus.Bootstrap.init()</code> - reinit the addon. Useful if you add any navbars dynamically on your page and need to init them at any time (all navbars are normally initialized ondomready).</li> + </ul> + + <hr /> + + <ul class="pagination"> + <li class="page-item"><a class="page-link" href="index.html">« Back to main demo</a></li> + </ul> + + </div> <!-- /container --> + + + + + <!-- jQuery first, then Popper.js, then Bootstrap JS --> + <script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script> + <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.11.0/umd/popper.min.js" integrity="sha384-b/U6ypiBEHpOf/4+1nzFpr53nxSS+GLCkfwBdFNTxtclqqenISfwAzpKaMNFNmj4" crossorigin="anonymous"></script> + <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/js/bootstrap.min.js" integrity="sha384-h0AbiXch4ZDo7tp9hKZ4TsHbi047NrKGLO3SEJAg45jXxnGIfYzk4Si90RDIqNm1" crossorigin="anonymous"></script> + + <!-- SmartMenus jQuery plugin --> + <script type="text/javascript" src="../jquery.smartmenus.js"></script> + + <!-- SmartMenus jQuery Bootstrap 4 Addon --> + <script type="text/javascript" src="../addons/bootstrap-4/jquery.smartmenus.bootstrap-4.js"></script> + + + + + </body> +</html> \ No newline at end of file diff --git a/civicrm/bower_components/smartmenus/src/demo/bootstrap-4-navbar.html b/civicrm/bower_components/smartmenus/src/demo/bootstrap-4-navbar.html new file mode 100644 index 0000000000..a92cf20685 --- /dev/null +++ b/civicrm/bower_components/smartmenus/src/demo/bootstrap-4-navbar.html @@ -0,0 +1,373 @@ +<!DOCTYPE html> +<html lang="en"> + <head> + <meta charset="utf-8"> + <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> + + <title>SmartMenus jQuery Website Menu - Bootstrap 4 Addon - Navbar</title> + + + + + <!-- Bootstrap core CSS --> + <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css"> + + <!-- SmartMenus jQuery Bootstrap 4 Addon CSS --> + <link href="../addons/bootstrap-4/jquery.smartmenus.bootstrap-4.css" rel="stylesheet"> + + + + + </head> + + <body style="padding-top:20px;"> + + <div class="container"> + + + + <!-- Navbar --> + <nav class="navbar navbar-expand-lg navbar-light bg-light rounded mb-4"> + <a class="navbar-brand" href="#">Navbar</a> + <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNavDropdown" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation"> + <span class="navbar-toggler-icon"></span> + </button> + + <div class="collapse navbar-collapse" id="navbarNavDropdown"> + + <!-- Left nav --> + <ul class="nav navbar-nav mr-auto"> + <li class="nav-item"><a class="nav-link" href="#">Link</a></li> + <li class="nav-item"><a class="nav-link" href="#">Link</a></li> + <li class="nav-item"><a class="nav-link" href="#">Link</a></li> + <li class="nav-item dropdown"><a class="nav-link dropdown-toggle" href="#">Dropdown</a> + <ul class="dropdown-menu"> + <li><a class="dropdown-item" href="#">Action</a></li> + <li><a class="dropdown-item disabled" href="#">Disabled link</a></li> + <li><a class="dropdown-item" href="#">Something else here</a></li> + <li class="dropdown-divider"></li> + <li class="dropdown-header">Nav header</li> + <li><a class="dropdown-item" href="#">Separated link</a></li> + <li class="dropdown"><a class="dropdown-item dropdown-toggle" href="#">One more separated link</a> + <ul class="dropdown-menu"> + <li><a class="dropdown-item" href="#">Action</a></li> + <li><a class="dropdown-item" href="#">Another action</a></li> + <li class="dropdown"><a class="dropdown-item dropdown-toggle" href="#">A long sub menu</a> + <ul class="dropdown-menu"> + <li><a class="dropdown-item" href="#">Action</a></li> + <li><a class="dropdown-item" href="#">Something else here</a></li> + <li><a class="dropdown-item" href="#">One more link</a></li> + <li><a class="dropdown-item" href="#">Menu item 1</a></li> + <li><a class="dropdown-item" href="#">Menu item 2</a></li> + <li><a class="dropdown-item" href="#">Menu item 3</a></li> + <li><a class="dropdown-item" href="#">Menu item 4</a></li> + <li><a class="dropdown-item" href="#">Menu item 5</a></li> + <li><a class="dropdown-item" href="#">Menu item 6</a></li> + <li><a class="dropdown-item" href="#">Menu item 7</a></li> + <li><a class="dropdown-item" href="#">Menu item 8</a></li> + <li><a class="dropdown-item" href="#">Menu item 9</a></li> + <li><a class="dropdown-item" href="#">Menu item 10</a></li> + <li><a class="dropdown-item" href="#">Menu item 11</a></li> + <li><a class="dropdown-item" href="#">Menu item 12</a></li> + <li><a class="dropdown-item" href="#">Menu item 13</a></li> + <li><a class="dropdown-item" href="#">Menu item 14</a></li> + <li><a class="dropdown-item" href="#">Menu item 15</a></li> + <li><a class="dropdown-item" href="#">Menu item 16</a></li> + <li><a class="dropdown-item" href="#">Menu item 17</a></li> + <li><a class="dropdown-item" href="#">Menu item 18</a></li> + <li><a class="dropdown-item" href="#">Menu item 19</a></li> + <li><a class="dropdown-item" href="#">Menu item 20</a></li> + <li><a class="dropdown-item" href="#">Menu item 21</a></li> + <li><a class="dropdown-item" href="#">Menu item 22</a></li> + <li><a class="dropdown-item" href="#">Menu item 23</a></li> + <li><a class="dropdown-item" href="#">Menu item 24</a></li> + <li><a class="dropdown-item" href="#">Menu item 25</a></li> + <li><a class="dropdown-item" href="#">Menu item 26</a></li> + <li><a class="dropdown-item" href="#">Menu item 27</a></li> + <li><a class="dropdown-item" href="#">Menu item 28</a></li> + <li><a class="dropdown-item" href="#">Menu item 29</a></li> + <li><a class="dropdown-item" href="#">Menu item 30</a></li> + <li><a class="dropdown-item" href="#">Menu item 31</a></li> + <li><a class="dropdown-item" href="#">Menu item 32</a></li> + <li><a class="dropdown-item" href="#">Menu item 33</a></li> + <li><a class="dropdown-item" href="#">Menu item 34</a></li> + <li><a class="dropdown-item" href="#">Menu item 35</a></li> + <li><a class="dropdown-item" href="#">Menu item 36</a></li> + <li><a class="dropdown-item" href="#">Menu item 37</a></li> + <li><a class="dropdown-item" href="#">Menu item 38</a></li> + <li><a class="dropdown-item" href="#">Menu item 39</a></li> + <li><a class="dropdown-item" href="#">Menu item 40</a></li> + <li><a class="dropdown-item" href="#">Menu item 41</a></li> + <li><a class="dropdown-item" href="#">Menu item 42</a></li> + <li><a class="dropdown-item" href="#">Menu item 43</a></li> + <li><a class="dropdown-item" href="#">Menu item 44</a></li> + <li><a class="dropdown-item" href="#">Menu item 45</a></li> + <li><a class="dropdown-item" href="#">Menu item 46</a></li> + <li><a class="dropdown-item" href="#">Menu item 47</a></li> + <li><a class="dropdown-item" href="#">Menu item 48</a></li> + <li><a class="dropdown-item" href="#">Menu item 49</a></li> + <li><a class="dropdown-item" href="#">Menu item 50</a></li> + <li><a class="dropdown-item" href="#">Menu item 51</a></li> + <li><a class="dropdown-item" href="#">Menu item 52</a></li> + <li><a class="dropdown-item" href="#">Menu item 53</a></li> + <li><a class="dropdown-item" href="#">Menu item 54</a></li> + <li><a class="dropdown-item" href="#">Menu item 55</a></li> + <li><a class="dropdown-item" href="#">Menu item 56</a></li> + <li><a class="dropdown-item" href="#">Menu item 57</a></li> + <li><a class="dropdown-item" href="#">Menu item 58</a></li> + <li><a class="dropdown-item" href="#">Menu item 59</a></li> + <li><a class="dropdown-item" href="#">Menu item 60</a></li> + </ul> + </li> + <li><a class="dropdown-item" href="#">Another link</a></li> + <li><a class="dropdown-item" href="#">One more link</a></li> + </ul> + </li> + </ul> + </li> + </ul> + + <!-- Right nav --> + <ul class="nav navbar-nav"> + <li class="nav-item active"><a class="nav-link" href="bootstrap-4-navbar.html">Default</a></li> + <li class="nav-item"><a class="nav-link" href="bootstrap-4-navbar-static-top.html">Static top</a></li> + <li class="nav-item"><a class="nav-link" href="bootstrap-4-navbar-fixed-top.html">Fixed top</a></li> + <li class="nav-item"><a class="nav-link" href="bootstrap-4-navbar-fixed-bottom.html">Fixed bottom</a></li> + <li class="nav-item dropdown"><a class="nav-link dropdown-toggle" href="#">Dropdown</a> + <ul class="dropdown-menu"> + <li><a class="dropdown-item" href="#">Action</a></li> + <li><a class="dropdown-item" href="#">Another action</a></li> + <li><a class="dropdown-item" href="#">Something else here</a></li> + <li class="dropdown-divider"></li> + <li class="dropdown-header">Nav header</li> + <li class="dropdown"><a class="dropdown-item dropdown-toggle" href="#">A sub menu</a> + <ul class="dropdown-menu"> + <li><a class="dropdown-item" href="#">Action</a></li> + <li><a class="dropdown-item" href="#">Another action</a></li> + <li><a class="dropdown-item" href="#">Something else here</a></li> + <li><a class="dropdown-item disabled" href="#">Disabled item</a></li> + <li><a class="dropdown-item" href="#">One more link</a></li> + </ul> + </li> + <li><a class="dropdown-item" href="#">A separated link</a></li> + </ul> + </li> + </ul> + + </div> + </nav> + + + + <div class="jumbotron bg-light"> + <h1>SmartMenus Bootstrap 4 Addon (Navbar)</h1> + <p class="lead">Zero config advanced Bootstrap navbars with SmartMenus jQuery and the SmartMenus jQuery Bootstrap 4 Addon.</p> + </div> + + <p>You just need to include the JS/CSS files on your Bootstrap 4 powered pages and everything should work automatically including full support for your Bootstrap 4 theme. And you also have the power and flexibility of SmartMenus jQuery at hand should you need to tweak or customize anything.</p> + + <h2>Source Code</h2> + + <h3>CSS</h3> + <p>In addition to Bootstrap's CSS just include the SmartMenus jQuery Bootstrap 4 Addon CSS. It's just static CSS code you don't need to edit at all (and probably shouldn't try to).</p> + <pre class="border rounded p-3 bg-light"><!-- Bootstrap core CSS --> +<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet"> + +<span class="text-success"><!-- SmartMenus jQuery Bootstrap 4 Addon CSS --> +<link href="../addons/bootstrap-4/jquery.smartmenus.bootstrap-4.css" rel="stylesheet"></span></pre> + + <h3>HTML</h3> + <p><strong class="text-info">Note:</strong> Bootstrap 4 normally uses <code><div></code> elements as <code>.dropdown-menu</code> containers. But since we are building a multi-level menu tree, we need to replace them with nested <code><ul></code>/<code><li></code> elements.</p> + <pre class="border rounded p-3 bg-light"><!-- Navbar --> +<nav class="navbar navbar-expand-lg navbar-light bg-light rounded mb-4"> + <a class="navbar-brand" href="#">Navbar</a> + <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNavDropdown" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation"> + <span class="navbar-toggler-icon"></span> + </button> + + <div class="collapse navbar-collapse" id="navbarNavDropdown"> +<span class="text-success"> + <!-- Left nav --> + <ul class="nav navbar-nav mr-auto"> + <li class="nav-item"><a class="nav-link" href="#">Link</a></li> + <li class="nav-item"><a class="nav-link" href="#">Link</a></li> + <li class="nav-item"><a class="nav-link" href="#">Link</a></li> + <li class="nav-item dropdown"><a class="nav-link dropdown-toggle" href="#">Dropdown</a> + <ul class="dropdown-menu"> + <li><a class="dropdown-item" href="#">Action</a></li> + <li><a class="dropdown-item disabled" href="#">Disabled link</a></li> + <li><a class="dropdown-item" href="#">Something else here</a></li> + <li class="dropdown-divider"></li> + <li class="dropdown-header">Nav header</li> + <li><a class="dropdown-item" href="#">Separated link</a></li> + <li class="dropdown"><a class="dropdown-item dropdown-toggle" href="#">One more separated link</a> + <ul class="dropdown-menu"> + <li><a class="dropdown-item" href="#">Action</a></li> + <li><a class="dropdown-item" href="#">Another action</a></li> + <li class="dropdown"><a class="dropdown-item dropdown-toggle" href="#">A long sub menu</a> + <ul class="dropdown-menu"> + <li><a class="dropdown-item" href="#">Action</a></li> + <li><a class="dropdown-item" href="#">Something else here</a></li> + <li><a class="dropdown-item" href="#">One more link</a></li> + <li><a class="dropdown-item" href="#">Menu item 1</a></li> + <li><a class="dropdown-item" href="#">Menu item 2</a></li> + <li><a class="dropdown-item" href="#">Menu item 3</a></li> + <li><a class="dropdown-item" href="#">Menu item 4</a></li> + <li><a class="dropdown-item" href="#">Menu item 5</a></li> + <li><a class="dropdown-item" href="#">Menu item 6</a></li> + <li><a class="dropdown-item" href="#">Menu item 7</a></li> + <li><a class="dropdown-item" href="#">Menu item 8</a></li> + <li><a class="dropdown-item" href="#">Menu item 9</a></li> + <li><a class="dropdown-item" href="#">Menu item 10</a></li> + <li><a class="dropdown-item" href="#">Menu item 11</a></li> + <li><a class="dropdown-item" href="#">Menu item 12</a></li> + <li><a class="dropdown-item" href="#">Menu item 13</a></li> + <li><a class="dropdown-item" href="#">Menu item 14</a></li> + <li><a class="dropdown-item" href="#">Menu item 15</a></li> + <li><a class="dropdown-item" href="#">Menu item 16</a></li> + <li><a class="dropdown-item" href="#">Menu item 17</a></li> + <li><a class="dropdown-item" href="#">Menu item 18</a></li> + <li><a class="dropdown-item" href="#">Menu item 19</a></li> + <li><a class="dropdown-item" href="#">Menu item 20</a></li> + <li><a class="dropdown-item" href="#">Menu item 21</a></li> + <li><a class="dropdown-item" href="#">Menu item 22</a></li> + <li><a class="dropdown-item" href="#">Menu item 23</a></li> + <li><a class="dropdown-item" href="#">Menu item 24</a></li> + <li><a class="dropdown-item" href="#">Menu item 25</a></li> + <li><a class="dropdown-item" href="#">Menu item 26</a></li> + <li><a class="dropdown-item" href="#">Menu item 27</a></li> + <li><a class="dropdown-item" href="#">Menu item 28</a></li> + <li><a class="dropdown-item" href="#">Menu item 29</a></li> + <li><a class="dropdown-item" href="#">Menu item 30</a></li> + <li><a class="dropdown-item" href="#">Menu item 31</a></li> + <li><a class="dropdown-item" href="#">Menu item 32</a></li> + <li><a class="dropdown-item" href="#">Menu item 33</a></li> + <li><a class="dropdown-item" href="#">Menu item 34</a></li> + <li><a class="dropdown-item" href="#">Menu item 35</a></li> + <li><a class="dropdown-item" href="#">Menu item 36</a></li> + <li><a class="dropdown-item" href="#">Menu item 37</a></li> + <li><a class="dropdown-item" href="#">Menu item 38</a></li> + <li><a class="dropdown-item" href="#">Menu item 39</a></li> + <li><a class="dropdown-item" href="#">Menu item 40</a></li> + <li><a class="dropdown-item" href="#">Menu item 41</a></li> + <li><a class="dropdown-item" href="#">Menu item 42</a></li> + <li><a class="dropdown-item" href="#">Menu item 43</a></li> + <li><a class="dropdown-item" href="#">Menu item 44</a></li> + <li><a class="dropdown-item" href="#">Menu item 45</a></li> + <li><a class="dropdown-item" href="#">Menu item 46</a></li> + <li><a class="dropdown-item" href="#">Menu item 47</a></li> + <li><a class="dropdown-item" href="#">Menu item 48</a></li> + <li><a class="dropdown-item" href="#">Menu item 49</a></li> + <li><a class="dropdown-item" href="#">Menu item 50</a></li> + <li><a class="dropdown-item" href="#">Menu item 51</a></li> + <li><a class="dropdown-item" href="#">Menu item 52</a></li> + <li><a class="dropdown-item" href="#">Menu item 53</a></li> + <li><a class="dropdown-item" href="#">Menu item 54</a></li> + <li><a class="dropdown-item" href="#">Menu item 55</a></li> + <li><a class="dropdown-item" href="#">Menu item 56</a></li> + <li><a class="dropdown-item" href="#">Menu item 57</a></li> + <li><a class="dropdown-item" href="#">Menu item 58</a></li> + <li><a class="dropdown-item" href="#">Menu item 59</a></li> + <li><a class="dropdown-item" href="#">Menu item 60</a></li> + </ul> + </li> + <li><a class="dropdown-item" href="#">Another link</a></li> + <li><a class="dropdown-item" href="#">One more link</a></li> + </ul> + </li> + </ul> + </li> + </ul> + + <!-- Right nav --> + <ul class="nav navbar-nav"> + <li class="nav-item active"><a class="nav-link" href="bootstrap-4-navbar.html">Default</a></li> + <li class="nav-item"><a class="nav-link" href="bootstrap-4-navbar-static-top.html">Static top</a></li> + <li class="nav-item"><a class="nav-link" href="bootstrap-4-navbar-fixed-top.html">Fixed top</a></li> + <li class="nav-item"><a class="nav-link" href="bootstrap-4-navbar-fixed-bottom.html">Fixed bottom</a></li> + <li class="nav-item dropdown"><a class="nav-link dropdown-toggle" href="#">Dropdown</a> + <ul class="dropdown-menu"> + <li><a class="dropdown-item" href="#">Action</a></li> + <li><a class="dropdown-item" href="#">Another action</a></li> + <li><a class="dropdown-item" href="#">Something else here</a></li> + <li class="dropdown-divider"></li> + <li class="dropdown-header">Nav header</li> + <li class="dropdown"><a class="dropdown-item dropdown-toggle" href="#">A sub menu</a> + <ul class="dropdown-menu"> + <li><a class="dropdown-item" href="#">Action</a></li> + <li><a class="dropdown-item" href="#">Another action</a></li> + <li><a class="dropdown-item" href="#">Something else here</a></li> + <li><a class="dropdown-item disabled" href="#">Disabled item</a></li> + <li><a class="dropdown-item" href="#">One more link</a></li> + </ul> + </li> + <li><a class="dropdown-item" href="#">A separated link</a></li> + </ul> + </li> + </ul> +</span> + </div> +</nav></pre> + + <h3>JavaScript</h3> + <p>In addition to Bootstrap's JavaScript just include SmartMenus jQuery and the SmartMenus jQuery Bootstrap 4 Addon. The default options used in <code>jquery.smartmenus.bootstrap.js</code> should work well for all. However, you can, of course, tweak them if you like.</p> + <pre class="border rounded p-3 bg-light"><!-- jQuery first, then Popper.js, then Bootstrap JS --> +<script src="http://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script> +<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.11.0/umd/popper.min.js" integrity="sha384-b/U6ypiBEHpOf/4+1nzFpr53nxSS+GLCkfwBdFNTxtclqqenISfwAzpKaMNFNmj4" crossorigin="anonymous"></script> +<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/js/bootstrap.min.js" integrity="sha384-h0AbiXch4ZDo7tp9hKZ4TsHbi047NrKGLO3SEJAg45jXxnGIfYzk4Si90RDIqNm1" crossorigin="anonymous"></script> + +<span class="text-success"><!-- SmartMenus jQuery plugin --> +<script type="text/javascript" src="../jquery.smartmenus.js"></script> + +<!-- SmartMenus jQuery Bootstrap 4 Addon --> +<script type="text/javascript" src="../addons/bootstrap-4/jquery.smartmenus.bootstrap-4.js"></script></span></pre> + + <h2>Quick customization</h2> + + <h3><code>data-*</code> attributes</h3> + <p>The Bootstrap 4 addon introduces the following additional <code>data-*</code> attributes which can be set to any <code>.navbar-nav</code>:</p> + <ul> + <li><code>data-sm-skip</code> - this will tell the script to skip this navbar and not apply any SmartMenus features to it so it will behave like a regular Bootstrap navbar.</li> + <li><code>data-sm-skip-collapsible-behavior</code> - this will tell the script to not apply SmartMenus' specific behavior to this navbar in collapsible mode (mobile view). Bootstrap's behavior for navbars in collapsible mode is to use the whole area of the parent items just as a toggle button for their sub menus and thus it's impossible to set a link to the parent items that can be followed on click/tap. SmartMenus' behavior is to add a separate +/- sub menus toggle button to parent items and thus allows the link of the parent items to be activated on the second click/tap (the first click/tap displays the sub menu if it's not visible). If you need even further control, you can check the <a href="https://www.smartmenus.org/docs/#collapsibleBehavior"><code>collapsibleBehavior</code></a> SmartMenus option which can be set in a <a href="https://www.smartmenus.org/docs/#data-sm-options"><code>data-sm-options</code></a> attribute.</li> + </ul> + + <h3>Options</h3> + <p>The following additional option can be set in a <a href="https://www.smartmenus.org/docs/#data-sm-options"><code>data-sm-options</code></a> attribute:</p> + <ul> + <li><code>bootstrapHighlightClasses: 'text-dark bg-light'</code> - CSS class(es) for highlighting expanded parent dropdown items.</li> + </ul> + <p><a href="https://www.smartmenus.org/docs/#options">Check the docs</a> for a complete list of all the available SmartMenus options.</p> + + <h3>API</h3> + <p>The following methods are available:</p> + <ul> + <li><code>jQuery.SmartMenus.Bootstrap.init()</code> - reinit the addon. Useful if you add any navbars dynamically on your page and need to init them at any time (all navbars are normally initialized ondomready).</li> + </ul> + + <hr /> + + <ul class="pagination"> + <li class="page-item"><a class="page-link" href="index.html">« Back to main demo</a></li> + </ul> + + </div> <!-- /container --> + + + + + <!-- jQuery first, then Popper.js, then Bootstrap JS --> + <script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script> + <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.11.0/umd/popper.min.js" integrity="sha384-b/U6ypiBEHpOf/4+1nzFpr53nxSS+GLCkfwBdFNTxtclqqenISfwAzpKaMNFNmj4" crossorigin="anonymous"></script> + <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/js/bootstrap.min.js" integrity="sha384-h0AbiXch4ZDo7tp9hKZ4TsHbi047NrKGLO3SEJAg45jXxnGIfYzk4Si90RDIqNm1" crossorigin="anonymous"></script> + + <!-- SmartMenus jQuery plugin --> + <script type="text/javascript" src="../jquery.smartmenus.js"></script> + + <!-- SmartMenus jQuery Bootstrap 4 Addon --> + <script type="text/javascript" src="../addons/bootstrap-4/jquery.smartmenus.bootstrap-4.js"></script> + + + + + </body> +</html> \ No newline at end of file diff --git a/civicrm/bower_components/smartmenus/src/demo/bootstrap-navbar-fixed-bottom.html b/civicrm/bower_components/smartmenus/src/demo/bootstrap-navbar-fixed-bottom.html new file mode 100644 index 0000000000..4b9f4b0a31 --- /dev/null +++ b/civicrm/bower_components/smartmenus/src/demo/bootstrap-navbar-fixed-bottom.html @@ -0,0 +1,391 @@ +<!DOCTYPE html> +<html lang="en"> + <head> + <meta charset="utf-8"> + <meta http-equiv="X-UA-Compatible" content="IE=edge"> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + + <title>SmartMenus jQuery Website Menu - Bootstrap Addon - Navbar fixed bottom</title> + + + + + <!-- Bootstrap core CSS --> + <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet"> + + <!-- SmartMenus jQuery Bootstrap Addon CSS --> + <link href="../addons/bootstrap/jquery.smartmenus.bootstrap.css" rel="stylesheet"> + + <!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries --> + <!--[if lt IE 9]> + <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script> + <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script> + <![endif]--> + + + + + </head> + + <body style="padding-bottom:60px;"> + + + + + <!-- Navbar fixed bottom --> + <div class="navbar navbar-default navbar-fixed-bottom" role="navigation"> + <div class="container"> + <div class="navbar-header"> + <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse"> + <span class="sr-only">Toggle navigation</span> + <span class="icon-bar"></span> + <span class="icon-bar"></span> + <span class="icon-bar"></span> + </button> + <a class="navbar-brand" href="#">Project name</a> + </div> + <div class="navbar-collapse collapse"> + + <!-- Left nav --> + <ul class="nav navbar-nav"> + <li><a href="#">Link</a></li> + <li><a href="#">Link</a></li> + <li><a href="#">Link</a></li> + <li><a href="#" class="dropup">Dropdown <span class="caret"></span></a> + <ul class="dropdown-menu"> + <li><a href="#">Action</a></li> + <li><a href="#">Another action</a></li> + <li><a href="#">Something else here</a></li> + <li class="divider"></li> + <li class="dropdown-header">Nav header</li> + <li><a href="#">Separated link</a></li> + <li><a href="#">One more separated link <span class="caret"></span></a> + <ul class="dropdown-menu"> + <li><a href="#">Action</a></li> + <li><a href="#">Another action</a></li> + <li><a href="#">A long sub menu <span class="caret"></span></a> + <ul class="dropdown-menu"> + <li><a href="#">Action</a></li> + <li><a href="#">Something else here</a></li> + <li class="disabled"><a class="disabled" href="#">Disabled item</a></li> + <li><a href="#">One more link</a></li> + <li><a href="#">Menu item 1</a></li> + <li><a href="#">Menu item 2</a></li> + <li><a href="#">Menu item 3</a></li> + <li><a href="#">Menu item 4</a></li> + <li><a href="#">Menu item 5</a></li> + <li><a href="#">Menu item 6</a></li> + <li><a href="#">Menu item 7</a></li> + <li><a href="#">Menu item 8</a></li> + <li><a href="#">Menu item 9</a></li> + <li><a href="#">Menu item 10</a></li> + <li><a href="#">Menu item 11</a></li> + <li><a href="#">Menu item 12</a></li> + <li><a href="#">Menu item 13</a></li> + <li><a href="#">Menu item 14</a></li> + <li><a href="#">Menu item 15</a></li> + <li><a href="#">Menu item 16</a></li> + <li><a href="#">Menu item 17</a></li> + <li><a href="#">Menu item 18</a></li> + <li><a href="#">Menu item 19</a></li> + <li><a href="#">Menu item 20</a></li> + <li><a href="#">Menu item 21</a></li> + <li><a href="#">Menu item 22</a></li> + <li><a href="#">Menu item 23</a></li> + <li><a href="#">Menu item 24</a></li> + <li><a href="#">Menu item 25</a></li> + <li><a href="#">Menu item 26</a></li> + <li><a href="#">Menu item 27</a></li> + <li><a href="#">Menu item 28</a></li> + <li><a href="#">Menu item 29</a></li> + <li><a href="#">Menu item 30</a></li> + <li><a href="#">Menu item 31</a></li> + <li><a href="#">Menu item 32</a></li> + <li><a href="#">Menu item 33</a></li> + <li><a href="#">Menu item 34</a></li> + <li><a href="#">Menu item 35</a></li> + <li><a href="#">Menu item 36</a></li> + <li><a href="#">Menu item 37</a></li> + <li><a href="#">Menu item 38</a></li> + <li><a href="#">Menu item 39</a></li> + <li><a href="#">Menu item 40</a></li> + <li><a href="#">Menu item 41</a></li> + <li><a href="#">Menu item 42</a></li> + <li><a href="#">Menu item 43</a></li> + <li><a href="#">Menu item 44</a></li> + <li><a href="#">Menu item 45</a></li> + <li><a href="#">Menu item 46</a></li> + <li><a href="#">Menu item 47</a></li> + <li><a href="#">Menu item 48</a></li> + <li><a href="#">Menu item 49</a></li> + <li><a href="#">Menu item 50</a></li> + <li><a href="#">Menu item 51</a></li> + <li><a href="#">Menu item 52</a></li> + <li><a href="#">Menu item 53</a></li> + <li><a href="#">Menu item 54</a></li> + <li><a href="#">Menu item 55</a></li> + <li><a href="#">Menu item 56</a></li> + <li><a href="#">Menu item 57</a></li> + <li><a href="#">Menu item 58</a></li> + <li><a href="#">Menu item 59</a></li> + <li><a href="#">Menu item 60</a></li> + </ul> + </li> + <li><a href="#">Another link</a></li> + <li><a href="#">One more link</a></li> + </ul> + </li> + </ul> + </li> + </ul> + + <!-- Right nav --> + <ul class="nav navbar-nav navbar-right"> + <li><a href="bootstrap-navbar.html">Default</a></li> + <li><a href="bootstrap-navbar-static-top.html">Static top</a></li> + <li><a href="bootstrap-navbar-fixed-top.html">Fixed top</a></li> + <li class="active"><a href="bootstrap-navbar-fixed-bottom.html">Fixed bottom</a></li> + <li><a href="#" class="dropup">Dropdown <span class="caret"></span></a> + <ul class="dropdown-menu"> + <li><a href="#">Action</a></li> + <li><a href="#">Another action</a></li> + <li><a href="#">Something else here</a></li> + <li class="divider"></li> + <li class="dropdown-header">Nav header</li> + <li><a href="#">A sub menu <span class="caret"></span></a> + <ul class="dropdown-menu"> + <li><a href="#">Action</a></li> + <li><a href="#">Another action</a></li> + <li><a href="#">Something else here</a></li> + <li class="disabled"><a class="disabled" href="#">Disabled item</a></li> + <li><a href="#">One more link</a></li> + </ul> + </li> + <li><a href="#">A separated link</a></li> + </ul> + </li> + </ul> + + </div><!--/.nav-collapse --> + </div><!--/.container --> + </div> + + + + + + <div class="container"> + + <div class="page-header"> + <h1>SmartMenus Bootstrap Addon (Navbar fixed bottom)</h1> + <p class="lead">Creating zero config advanced Bootstrap 3 navbars with SmartMenus jQuery and the SmartMenus jQuery Bootstrap Addon.</p> + </div> + <p>You basically just need to include the JS/CSS files on your Bootstrap 3 powered pages and everything should work automatically including full support for whatever Bootstrap theme you already use. And, of course, you still have the full power and flexibility of SmartMenus jQuery at hand should you need to tweak or customize anything.</p> + + <h2>Source Code</h2> + + <h3>CSS</h3> + <p>In addition to Bootstrap's CSS just include the SmartMenus jQuery Bootstrap Addon CSS. It's just static CSS code you don't need to edit at all (and probably shouldn't try to).</p> + <pre><!-- Bootstrap core CSS --> +<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet"> + +<span style="color:#419641;"><!-- SmartMenus jQuery Bootstrap Addon CSS --> +<link href="../addons/bootstrap/jquery.smartmenus.bootstrap.css" rel="stylesheet"></span></pre> + + <h3>HTML</h3> + <pre><!-- Navbar fixed bottom --> +<div class="navbar navbar-default navbar-fixed-bottom" role="navigation"> + <div class="container"> + <div class="navbar-header"> + <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse"> + <span class="sr-only">Toggle navigation</span> + <span class="icon-bar"></span> + <span class="icon-bar"></span> + <span class="icon-bar"></span> + </button> + <a class="navbar-brand" href="#">Project name</a> + </div> + <div class="navbar-collapse collapse"> + + <span style="color:#419641;"><!-- Left nav --> + <ul class="nav navbar-nav"> + <li><a href="#">Link</a></li> + <li><a href="#">Link</a></li> + <li><a href="#">Link</a></li> + <li><a href="#" class="dropup">Dropdown <span class="caret"></span></a> + <ul class="dropdown-menu"> + <li><a href="#">Action</a></li> + <li><a href="#">Another action</a></li> + <li><a href="#">Something else here</a></li> + <li class="divider"></li> + <li class="dropdown-header">Nav header</li> + <li><a href="#">Separated link</a></li> + <li><a href="#">One more separated link <span class="caret"></span></a> + <ul class="dropdown-menu"> + <li><a href="#">Action</a></li> + <li><a href="#">Another action</a></li> + <li><a href="#">A long sub menu <span class="caret"></span></a> + <ul class="dropdown-menu"> + <li><a href="#">Action</a></li> + <li><a href="#">Something else here</a></li> + <li class="disabled"><a class="disabled" href="#">Disabled item</a></li> + <li><a href="#">One more link</a></li> + <li><a href="#">Menu item 1</a></li> + <li><a href="#">Menu item 2</a></li> + <li><a href="#">Menu item 3</a></li> + <li><a href="#">Menu item 4</a></li> + <li><a href="#">Menu item 5</a></li> + <li><a href="#">Menu item 6</a></li> + <li><a href="#">Menu item 7</a></li> + <li><a href="#">Menu item 8</a></li> + <li><a href="#">Menu item 9</a></li> + <li><a href="#">Menu item 10</a></li> + <li><a href="#">Menu item 11</a></li> + <li><a href="#">Menu item 12</a></li> + <li><a href="#">Menu item 13</a></li> + <li><a href="#">Menu item 14</a></li> + <li><a href="#">Menu item 15</a></li> + <li><a href="#">Menu item 16</a></li> + <li><a href="#">Menu item 17</a></li> + <li><a href="#">Menu item 18</a></li> + <li><a href="#">Menu item 19</a></li> + <li><a href="#">Menu item 20</a></li> + <li><a href="#">Menu item 21</a></li> + <li><a href="#">Menu item 22</a></li> + <li><a href="#">Menu item 23</a></li> + <li><a href="#">Menu item 24</a></li> + <li><a href="#">Menu item 25</a></li> + <li><a href="#">Menu item 26</a></li> + <li><a href="#">Menu item 27</a></li> + <li><a href="#">Menu item 28</a></li> + <li><a href="#">Menu item 29</a></li> + <li><a href="#">Menu item 30</a></li> + <li><a href="#">Menu item 31</a></li> + <li><a href="#">Menu item 32</a></li> + <li><a href="#">Menu item 33</a></li> + <li><a href="#">Menu item 34</a></li> + <li><a href="#">Menu item 35</a></li> + <li><a href="#">Menu item 36</a></li> + <li><a href="#">Menu item 37</a></li> + <li><a href="#">Menu item 38</a></li> + <li><a href="#">Menu item 39</a></li> + <li><a href="#">Menu item 40</a></li> + <li><a href="#">Menu item 41</a></li> + <li><a href="#">Menu item 42</a></li> + <li><a href="#">Menu item 43</a></li> + <li><a href="#">Menu item 44</a></li> + <li><a href="#">Menu item 45</a></li> + <li><a href="#">Menu item 46</a></li> + <li><a href="#">Menu item 47</a></li> + <li><a href="#">Menu item 48</a></li> + <li><a href="#">Menu item 49</a></li> + <li><a href="#">Menu item 50</a></li> + <li><a href="#">Menu item 51</a></li> + <li><a href="#">Menu item 52</a></li> + <li><a href="#">Menu item 53</a></li> + <li><a href="#">Menu item 54</a></li> + <li><a href="#">Menu item 55</a></li> + <li><a href="#">Menu item 56</a></li> + <li><a href="#">Menu item 57</a></li> + <li><a href="#">Menu item 58</a></li> + <li><a href="#">Menu item 59</a></li> + <li><a href="#">Menu item 60</a></li> + </ul> + </li> + <li><a href="#">Another link</a></li> + <li><a href="#">One more link</a></li> + </ul> + </li> + </ul> + </li> + </ul></span> + + <span style="color:#419641;"><!-- Right nav --> + <ul class="nav navbar-nav navbar-right"> + <li><a href="bootstrap-navbar.html">Default</a></li> + <li><a href="bootstrap-navbar-static-top.html">Static top</a></li> + <li><a href="bootstrap-navbar-fixed-top.html">Fixed top</a></li> + <li class="active"><a href="bootstrap-navbar-fixed-bottom.html">Fixed bottom</a></li> + <li><a href="#" class="dropup">Dropdown <span class="caret"></span></a> + <ul class="dropdown-menu"> + <li><a href="#">Action</a></li> + <li><a href="#">Another action</a></li> + <li><a href="#">Something else here</a></li> + <li class="divider"></li> + <li class="dropdown-header">Nav header</li> + <li><a href="#">A sub menu <span class="caret"></span></a> + <ul class="dropdown-menu"> + <li><a href="#">Action</a></li> + <li><a href="#">Another action</a></li> + <li><a href="#">Something else here</a></li> + <li class="disabled"><a class="disabled" href="#">Disabled item</a></li> + <li><a href="#">One more link</a></li> + </ul> + </li> + <li><a href="#">A separated link</a></li> + </ul> + </li> + </ul></span> + + </div><!--/.nav-collapse --> + </div><!--/.container --> +</div></pre> + + <h3>JavaScript</h3> + <p>In addition to Bootstrap's JavaScript just include SmartMenus jQuery and the SmartMenus jQuery Bootstrap Addon. The default options used in <code>jquery.smartmenus.bootstrap.js</code> should work well for all. However, you can, of course, tweak them if you like.</p> + <pre><!-- Bootstrap core JavaScript +================================================== --> +<!-- Placed at the end of the document so the pages load faster --> +<script src="https://code.jquery.com/jquery-1.11.3.min.js"></script> +<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script> + +<span style="color:#419641;"><!-- SmartMenus jQuery plugin --> +<script type="text/javascript" src="../jquery.smartmenus.js"></script> + +<!-- SmartMenus jQuery Bootstrap Addon --> +<script type="text/javascript" src="../addons/bootstrap/jquery.smartmenus.bootstrap.js"></script></span></pre> + + <h2>Quick customization</h2> + + <h3><code>data-*</code> attributes</h3> + <p>The following <code>data-*</code> attributes can be set to any <code>ul.navbar-nav</code>:</p> + <ul> + <li><code>data-sm-options</code> - set any custom options for the SmartMenus jQuery plugin (<a href="http://www.smartmenus.org/docs/#data-sm-options">check the docs</a> for details).</li> + <li><code>data-sm-skip</code> - this will tell the script to skip this navbar and not apply any SmartMenus features to it so it will behave like a regular Bootstrap navbar.</li> + <li><code>data-sm-skip-collapsible-behavior</code> - this will tell the script to not apply SmartMenus' specific behavior to this navbar in collapsible mode (mobile view). Bootstrap's behavior for navbars in collapsible mode is to use the whole area of the parent items just as a toggle button for their sub menus and thus it's impossible to set a link to the parent items that can be followed on click/tap. SmartMenus' behavior is to add a separate dedicated +/- sub menus toggle button to parent items and thus allows the link of the parent items to be activated on the second click/tap (the first click/tap displays the sub menu if it's not visible).</li> + </ul> + + <h3>API</h3> + <p>The following methods are available:</p> + <ul> + <li><code>jQuery.SmartMenus.Bootstrap.init()</code> - reinit the addon. Useful if you add any navbars dynamically on your page and need to init them (all navbars are normally initialized ondomready).</li> + </ul> + + <hr /> + + <ul class="pagination"> + <li><a href="index.html">« Back to main demo</a></li> + </ul> + + </div> <!-- /container --> + + + + + <!-- Bootstrap core JavaScript + ================================================== --> + <!-- Placed at the end of the document so the pages load faster --> + <script src="https://code.jquery.com/jquery-1.11.3.min.js"></script> + <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script> + + <!-- SmartMenus jQuery plugin --> + <script type="text/javascript" src="../jquery.smartmenus.js"></script> + + <!-- SmartMenus jQuery Bootstrap Addon --> + <script type="text/javascript" src="../addons/bootstrap/jquery.smartmenus.bootstrap.js"></script> + + + + + </body> +</html> \ No newline at end of file diff --git a/civicrm/bower_components/smartmenus/src/demo/bootstrap-navbar-fixed-top.html b/civicrm/bower_components/smartmenus/src/demo/bootstrap-navbar-fixed-top.html new file mode 100644 index 0000000000..709c92c482 --- /dev/null +++ b/civicrm/bower_components/smartmenus/src/demo/bootstrap-navbar-fixed-top.html @@ -0,0 +1,391 @@ +<!DOCTYPE html> +<html lang="en"> + <head> + <meta charset="utf-8"> + <meta http-equiv="X-UA-Compatible" content="IE=edge"> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + + <title>SmartMenus jQuery Website Menu - Bootstrap Addon - Navbar fixed top</title> + + + + + <!-- Bootstrap core CSS --> + <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet"> + + <!-- SmartMenus jQuery Bootstrap Addon CSS --> + <link href="../addons/bootstrap/jquery.smartmenus.bootstrap.css" rel="stylesheet"> + + <!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries --> + <!--[if lt IE 9]> + <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script> + <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script> + <![endif]--> + + + + + </head> + + <body> + + + + + <!-- Navbar fixed top --> + <div class="navbar navbar-default navbar-fixed-top" role="navigation"> + <div class="container"> + <div class="navbar-header"> + <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse"> + <span class="sr-only">Toggle navigation</span> + <span class="icon-bar"></span> + <span class="icon-bar"></span> + <span class="icon-bar"></span> + </button> + <a class="navbar-brand" href="#">Project name</a> + </div> + <div class="navbar-collapse collapse"> + + <!-- Left nav --> + <ul class="nav navbar-nav"> + <li><a href="#">Link</a></li> + <li><a href="#">Link</a></li> + <li><a href="#">Link</a></li> + <li><a href="#">Dropdown <span class="caret"></span></a> + <ul class="dropdown-menu"> + <li><a href="#">Action</a></li> + <li><a href="#">Another action</a></li> + <li><a href="#">Something else here</a></li> + <li class="divider"></li> + <li class="dropdown-header">Nav header</li> + <li><a href="#">Separated link</a></li> + <li><a href="#">One more separated link <span class="caret"></span></a> + <ul class="dropdown-menu"> + <li><a href="#">Action</a></li> + <li><a href="#">Another action</a></li> + <li><a href="#">A long sub menu <span class="caret"></span></a> + <ul class="dropdown-menu"> + <li><a href="#">Action</a></li> + <li><a href="#">Something else here</a></li> + <li class="disabled"><a class="disabled" href="#">Disabled item</a></li> + <li><a href="#">One more link</a></li> + <li><a href="#">Menu item 1</a></li> + <li><a href="#">Menu item 2</a></li> + <li><a href="#">Menu item 3</a></li> + <li><a href="#">Menu item 4</a></li> + <li><a href="#">Menu item 5</a></li> + <li><a href="#">Menu item 6</a></li> + <li><a href="#">Menu item 7</a></li> + <li><a href="#">Menu item 8</a></li> + <li><a href="#">Menu item 9</a></li> + <li><a href="#">Menu item 10</a></li> + <li><a href="#">Menu item 11</a></li> + <li><a href="#">Menu item 12</a></li> + <li><a href="#">Menu item 13</a></li> + <li><a href="#">Menu item 14</a></li> + <li><a href="#">Menu item 15</a></li> + <li><a href="#">Menu item 16</a></li> + <li><a href="#">Menu item 17</a></li> + <li><a href="#">Menu item 18</a></li> + <li><a href="#">Menu item 19</a></li> + <li><a href="#">Menu item 20</a></li> + <li><a href="#">Menu item 21</a></li> + <li><a href="#">Menu item 22</a></li> + <li><a href="#">Menu item 23</a></li> + <li><a href="#">Menu item 24</a></li> + <li><a href="#">Menu item 25</a></li> + <li><a href="#">Menu item 26</a></li> + <li><a href="#">Menu item 27</a></li> + <li><a href="#">Menu item 28</a></li> + <li><a href="#">Menu item 29</a></li> + <li><a href="#">Menu item 30</a></li> + <li><a href="#">Menu item 31</a></li> + <li><a href="#">Menu item 32</a></li> + <li><a href="#">Menu item 33</a></li> + <li><a href="#">Menu item 34</a></li> + <li><a href="#">Menu item 35</a></li> + <li><a href="#">Menu item 36</a></li> + <li><a href="#">Menu item 37</a></li> + <li><a href="#">Menu item 38</a></li> + <li><a href="#">Menu item 39</a></li> + <li><a href="#">Menu item 40</a></li> + <li><a href="#">Menu item 41</a></li> + <li><a href="#">Menu item 42</a></li> + <li><a href="#">Menu item 43</a></li> + <li><a href="#">Menu item 44</a></li> + <li><a href="#">Menu item 45</a></li> + <li><a href="#">Menu item 46</a></li> + <li><a href="#">Menu item 47</a></li> + <li><a href="#">Menu item 48</a></li> + <li><a href="#">Menu item 49</a></li> + <li><a href="#">Menu item 50</a></li> + <li><a href="#">Menu item 51</a></li> + <li><a href="#">Menu item 52</a></li> + <li><a href="#">Menu item 53</a></li> + <li><a href="#">Menu item 54</a></li> + <li><a href="#">Menu item 55</a></li> + <li><a href="#">Menu item 56</a></li> + <li><a href="#">Menu item 57</a></li> + <li><a href="#">Menu item 58</a></li> + <li><a href="#">Menu item 59</a></li> + <li><a href="#">Menu item 60</a></li> + </ul> + </li> + <li><a href="#">Another link</a></li> + <li><a href="#">One more link</a></li> + </ul> + </li> + </ul> + </li> + </ul> + + <!-- Right nav --> + <ul class="nav navbar-nav navbar-right"> + <li><a href="bootstrap-navbar.html">Default</a></li> + <li><a href="bootstrap-navbar-static-top.html">Static top</a></li> + <li class="active"><a href="bootstrap-navbar-fixed-top.html">Fixed top</a></li> + <li><a href="bootstrap-navbar-fixed-bottom.html">Fixed bottom</a></li> + <li><a href="#">Dropdown <span class="caret"></span></a> + <ul class="dropdown-menu"> + <li><a href="#">Action</a></li> + <li><a href="#">Another action</a></li> + <li><a href="#">Something else here</a></li> + <li class="divider"></li> + <li class="dropdown-header">Nav header</li> + <li><a href="#">A sub menu <span class="caret"></span></a> + <ul class="dropdown-menu"> + <li><a href="#">Action</a></li> + <li><a href="#">Another action</a></li> + <li><a href="#">Something else here</a></li> + <li class="disabled"><a class="disabled" href="#">Disabled item</a></li> + <li><a href="#">One more link</a></li> + </ul> + </li> + <li><a href="#">A separated link</a></li> + </ul> + </li> + </ul> + + </div><!--/.nav-collapse --> + </div><!--/.container --> + </div> + + + + + + <div class="container" style="margin-top:70px;"> + + <div class="page-header"> + <h1>SmartMenus Bootstrap Addon (Navbar fixed top)</h1> + <p class="lead">Creating zero config advanced Bootstrap 3 navbars with SmartMenus jQuery and the SmartMenus jQuery Bootstrap Addon.</p> + </div> + <p>You basically just need to include the JS/CSS files on your Bootstrap 3 powered pages and everything should work automatically including full support for whatever Bootstrap theme you already use. And, of course, you still have the full power and flexibility of SmartMenus jQuery at hand should you need to tweak or customize anything.</p> + + <h2>Source Code</h2> + + <h3>CSS</h3> + <p>In addition to Bootstrap's CSS just include the SmartMenus jQuery Bootstrap Addon CSS. It's just static CSS code you don't need to edit at all (and probably shouldn't try to).</p> + <pre><!-- Bootstrap core CSS --> +<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet"> + +<span style="color:#419641;"><!-- SmartMenus jQuery Bootstrap Addon CSS --> +<link href="../addons/bootstrap/jquery.smartmenus.bootstrap.css" rel="stylesheet"></span></pre> + + <h3>HTML</h3> + <pre><!-- Navbar fixed top --> +<div class="navbar navbar-default navbar-fixed-top" role="navigation"> + <div class="container"> + <div class="navbar-header"> + <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse"> + <span class="sr-only">Toggle navigation</span> + <span class="icon-bar"></span> + <span class="icon-bar"></span> + <span class="icon-bar"></span> + </button> + <a class="navbar-brand" href="#">Project name</a> + </div> + <div class="navbar-collapse collapse"> + + <span style="color:#419641;"><!-- Left nav --> + <ul class="nav navbar-nav"> + <li><a href="#">Link</a></li> + <li><a href="#">Link</a></li> + <li><a href="#">Link</a></li> + <li><a href="#">Dropdown <span class="caret"></span></a> + <ul class="dropdown-menu"> + <li><a href="#">Action</a></li> + <li><a href="#">Another action</a></li> + <li><a href="#">Something else here</a></li> + <li class="divider"></li> + <li class="dropdown-header">Nav header</li> + <li><a href="#">Separated link</a></li> + <li><a href="#">One more separated link <span class="caret"></span></a> + <ul class="dropdown-menu"> + <li><a href="#">Action</a></li> + <li><a href="#">Another action</a></li> + <li><a href="#">A long sub menu <span class="caret"></span></a> + <ul class="dropdown-menu"> + <li><a href="#">Action</a></li> + <li><a href="#">Something else here</a></li> + <li class="disabled"><a class="disabled" href="#">Disabled item</a></li> + <li><a href="#">One more link</a></li> + <li><a href="#">Menu item 1</a></li> + <li><a href="#">Menu item 2</a></li> + <li><a href="#">Menu item 3</a></li> + <li><a href="#">Menu item 4</a></li> + <li><a href="#">Menu item 5</a></li> + <li><a href="#">Menu item 6</a></li> + <li><a href="#">Menu item 7</a></li> + <li><a href="#">Menu item 8</a></li> + <li><a href="#">Menu item 9</a></li> + <li><a href="#">Menu item 10</a></li> + <li><a href="#">Menu item 11</a></li> + <li><a href="#">Menu item 12</a></li> + <li><a href="#">Menu item 13</a></li> + <li><a href="#">Menu item 14</a></li> + <li><a href="#">Menu item 15</a></li> + <li><a href="#">Menu item 16</a></li> + <li><a href="#">Menu item 17</a></li> + <li><a href="#">Menu item 18</a></li> + <li><a href="#">Menu item 19</a></li> + <li><a href="#">Menu item 20</a></li> + <li><a href="#">Menu item 21</a></li> + <li><a href="#">Menu item 22</a></li> + <li><a href="#">Menu item 23</a></li> + <li><a href="#">Menu item 24</a></li> + <li><a href="#">Menu item 25</a></li> + <li><a href="#">Menu item 26</a></li> + <li><a href="#">Menu item 27</a></li> + <li><a href="#">Menu item 28</a></li> + <li><a href="#">Menu item 29</a></li> + <li><a href="#">Menu item 30</a></li> + <li><a href="#">Menu item 31</a></li> + <li><a href="#">Menu item 32</a></li> + <li><a href="#">Menu item 33</a></li> + <li><a href="#">Menu item 34</a></li> + <li><a href="#">Menu item 35</a></li> + <li><a href="#">Menu item 36</a></li> + <li><a href="#">Menu item 37</a></li> + <li><a href="#">Menu item 38</a></li> + <li><a href="#">Menu item 39</a></li> + <li><a href="#">Menu item 40</a></li> + <li><a href="#">Menu item 41</a></li> + <li><a href="#">Menu item 42</a></li> + <li><a href="#">Menu item 43</a></li> + <li><a href="#">Menu item 44</a></li> + <li><a href="#">Menu item 45</a></li> + <li><a href="#">Menu item 46</a></li> + <li><a href="#">Menu item 47</a></li> + <li><a href="#">Menu item 48</a></li> + <li><a href="#">Menu item 49</a></li> + <li><a href="#">Menu item 50</a></li> + <li><a href="#">Menu item 51</a></li> + <li><a href="#">Menu item 52</a></li> + <li><a href="#">Menu item 53</a></li> + <li><a href="#">Menu item 54</a></li> + <li><a href="#">Menu item 55</a></li> + <li><a href="#">Menu item 56</a></li> + <li><a href="#">Menu item 57</a></li> + <li><a href="#">Menu item 58</a></li> + <li><a href="#">Menu item 59</a></li> + <li><a href="#">Menu item 60</a></li> + </ul> + </li> + <li><a href="#">Another link</a></li> + <li><a href="#">One more link</a></li> + </ul> + </li> + </ul> + </li> + </ul></span> + + <span style="color:#419641;"><!-- Right nav --> + <ul class="nav navbar-nav navbar-right"> + <li><a href="bootstrap-navbar.html">Default</a></li> + <li><a href="bootstrap-navbar-static-top.html">Static top</a></li> + <li class="active"><a href="bootstrap-navbar-fixed-top.html">Fixed top</a></li> + <li><a href="bootstrap-navbar-fixed-bottom.html">Fixed bottom</a></li> + <li><a href="#">Dropdown <span class="caret"></span></a> + <ul class="dropdown-menu"> + <li><a href="#">Action</a></li> + <li><a href="#">Another action</a></li> + <li><a href="#">Something else here</a></li> + <li class="divider"></li> + <li class="dropdown-header">Nav header</li> + <li><a href="#">A sub menu <span class="caret"></span></a> + <ul class="dropdown-menu"> + <li><a href="#">Action</a></li> + <li><a href="#">Another action</a></li> + <li><a href="#">Something else here</a></li> + <li class="disabled"><a class="disabled" href="#">Disabled item</a></li> + <li><a href="#">One more link</a></li> + </ul> + </li> + <li><a href="#">A separated link</a></li> + </ul> + </li> + </ul></span> + + </div><!--/.nav-collapse --> + </div><!--/.container --> +</div></pre> + + <h3>JavaScript</h3> + <p>In addition to Bootstrap's JavaScript just include SmartMenus jQuery and the SmartMenus jQuery Bootstrap Addon. The default options used in <code>jquery.smartmenus.bootstrap.js</code> should work well for all. However, you can, of course, tweak them if you like.</p> + <pre><!-- Bootstrap core JavaScript +================================================== --> +<!-- Placed at the end of the document so the pages load faster --> +<script src="https://code.jquery.com/jquery-1.11.3.min.js"></script> +<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script> + +<span style="color:#419641;"><!-- SmartMenus jQuery plugin --> +<script type="text/javascript" src="../jquery.smartmenus.js"></script> + +<!-- SmartMenus jQuery Bootstrap Addon --> +<script type="text/javascript" src="../addons/bootstrap/jquery.smartmenus.bootstrap.js"></script></span></pre> + + <h2>Quick customization</h2> + + <h3><code>data-*</code> attributes</h3> + <p>The following <code>data-*</code> attributes can be set to any <code>ul.navbar-nav</code>:</p> + <ul> + <li><code>data-sm-options</code> - set any custom options for the SmartMenus jQuery plugin (<a href="http://www.smartmenus.org/docs/#data-sm-options">check the docs</a> for details).</li> + <li><code>data-sm-skip</code> - this will tell the script to skip this navbar and not apply any SmartMenus features to it so it will behave like a regular Bootstrap navbar.</li> + <li><code>data-sm-skip-collapsible-behavior</code> - this will tell the script to not apply SmartMenus' specific behavior to this navbar in collapsible mode (mobile view). Bootstrap's behavior for navbars in collapsible mode is to use the whole area of the parent items just as a toggle button for their sub menus and thus it's impossible to set a link to the parent items that can be followed on click/tap. SmartMenus' behavior is to add a separate dedicated +/- sub menus toggle button to parent items and thus allows the link of the parent items to be activated on the second click/tap (the first click/tap displays the sub menu if it's not visible).</li> + </ul> + + <h3>API</h3> + <p>The following methods are available:</p> + <ul> + <li><code>jQuery.SmartMenus.Bootstrap.init()</code> - reinit the addon. Useful if you add any navbars dynamically on your page and need to init them (all navbars are normally initialized ondomready).</li> + </ul> + + <hr /> + + <ul class="pagination"> + <li><a href="index.html">« Back to main demo</a></li> + </ul> + + </div> <!-- /container --> + + + + + <!-- Bootstrap core JavaScript + ================================================== --> + <!-- Placed at the end of the document so the pages load faster --> + <script src="https://code.jquery.com/jquery-1.11.3.min.js"></script> + <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script> + + <!-- SmartMenus jQuery plugin --> + <script type="text/javascript" src="../jquery.smartmenus.js"></script> + + <!-- SmartMenus jQuery Bootstrap Addon --> + <script type="text/javascript" src="../addons/bootstrap/jquery.smartmenus.bootstrap.js"></script> + + + + + </body> +</html> \ No newline at end of file diff --git a/civicrm/bower_components/smartmenus/src/demo/bootstrap-navbar-static-top.html b/civicrm/bower_components/smartmenus/src/demo/bootstrap-navbar-static-top.html new file mode 100644 index 0000000000..4bf8b379bb --- /dev/null +++ b/civicrm/bower_components/smartmenus/src/demo/bootstrap-navbar-static-top.html @@ -0,0 +1,390 @@ +<!DOCTYPE html> +<html lang="en"> + <head> + <meta charset="utf-8"> + <meta http-equiv="X-UA-Compatible" content="IE=edge"> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + + <title>SmartMenus jQuery Website Menu - Bootstrap Addon - Navbar static top</title> + + + + + <!-- Bootstrap core CSS --> + <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet"> + + <!-- SmartMenus jQuery Bootstrap Addon CSS --> + <link href="../addons/bootstrap/jquery.smartmenus.bootstrap.css" rel="stylesheet"> + + <!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries --> + <!--[if lt IE 9]> + <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script> + <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script> + <![endif]--> + + + + + </head> + + <body> + + + + + <!-- Navbar static top --> + <div class="navbar navbar-default navbar-static-top" role="navigation"> + <div class="container"> + <div class="navbar-header"> + <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse"> + <span class="sr-only">Toggle navigation</span> + <span class="icon-bar"></span> + <span class="icon-bar"></span> + <span class="icon-bar"></span> + </button> + <a class="navbar-brand" href="#">Project name</a> + </div> + <div class="navbar-collapse collapse"> + + <!-- Left nav --> + <ul class="nav navbar-nav"> + <li><a href="#">Link</a></li> + <li><a href="#">Link</a></li> + <li><a href="#">Link</a></li> + <li><a href="#">Dropdown <span class="caret"></span></a> + <ul class="dropdown-menu"> + <li><a href="#">Action</a></li> + <li><a href="#">Another action</a></li> + <li><a href="#">Something else here</a></li> + <li class="divider"></li> + <li class="dropdown-header">Nav header</li> + <li><a href="#">Separated link</a></li> + <li><a href="#">One more separated link <span class="caret"></span></a> + <ul class="dropdown-menu"> + <li><a href="#">Action</a></li> + <li><a href="#">Another action</a></li> + <li><a href="#">A long sub menu <span class="caret"></span></a> + <ul class="dropdown-menu"> + <li><a href="#">Action</a></li> + <li><a href="#">Something else here</a></li> + <li class="disabled"><a class="disabled" href="#">Disabled item</a></li> + <li><a href="#">One more link</a></li> + <li><a href="#">Menu item 1</a></li> + <li><a href="#">Menu item 2</a></li> + <li><a href="#">Menu item 3</a></li> + <li><a href="#">Menu item 4</a></li> + <li><a href="#">Menu item 5</a></li> + <li><a href="#">Menu item 6</a></li> + <li><a href="#">Menu item 7</a></li> + <li><a href="#">Menu item 8</a></li> + <li><a href="#">Menu item 9</a></li> + <li><a href="#">Menu item 10</a></li> + <li><a href="#">Menu item 11</a></li> + <li><a href="#">Menu item 12</a></li> + <li><a href="#">Menu item 13</a></li> + <li><a href="#">Menu item 14</a></li> + <li><a href="#">Menu item 15</a></li> + <li><a href="#">Menu item 16</a></li> + <li><a href="#">Menu item 17</a></li> + <li><a href="#">Menu item 18</a></li> + <li><a href="#">Menu item 19</a></li> + <li><a href="#">Menu item 20</a></li> + <li><a href="#">Menu item 21</a></li> + <li><a href="#">Menu item 22</a></li> + <li><a href="#">Menu item 23</a></li> + <li><a href="#">Menu item 24</a></li> + <li><a href="#">Menu item 25</a></li> + <li><a href="#">Menu item 26</a></li> + <li><a href="#">Menu item 27</a></li> + <li><a href="#">Menu item 28</a></li> + <li><a href="#">Menu item 29</a></li> + <li><a href="#">Menu item 30</a></li> + <li><a href="#">Menu item 31</a></li> + <li><a href="#">Menu item 32</a></li> + <li><a href="#">Menu item 33</a></li> + <li><a href="#">Menu item 34</a></li> + <li><a href="#">Menu item 35</a></li> + <li><a href="#">Menu item 36</a></li> + <li><a href="#">Menu item 37</a></li> + <li><a href="#">Menu item 38</a></li> + <li><a href="#">Menu item 39</a></li> + <li><a href="#">Menu item 40</a></li> + <li><a href="#">Menu item 41</a></li> + <li><a href="#">Menu item 42</a></li> + <li><a href="#">Menu item 43</a></li> + <li><a href="#">Menu item 44</a></li> + <li><a href="#">Menu item 45</a></li> + <li><a href="#">Menu item 46</a></li> + <li><a href="#">Menu item 47</a></li> + <li><a href="#">Menu item 48</a></li> + <li><a href="#">Menu item 49</a></li> + <li><a href="#">Menu item 50</a></li> + <li><a href="#">Menu item 51</a></li> + <li><a href="#">Menu item 52</a></li> + <li><a href="#">Menu item 53</a></li> + <li><a href="#">Menu item 54</a></li> + <li><a href="#">Menu item 55</a></li> + <li><a href="#">Menu item 56</a></li> + <li><a href="#">Menu item 57</a></li> + <li><a href="#">Menu item 58</a></li> + <li><a href="#">Menu item 59</a></li> + <li><a href="#">Menu item 60</a></li> + </ul> + </li> + <li><a href="#">Another link</a></li> + <li><a href="#">One more link</a></li> + </ul> + </li> + </ul> + </li> + </ul> + + <!-- Right nav --> + <ul class="nav navbar-nav navbar-right"> + <li><a href="bootstrap-navbar.html">Default</a></li> + <li class="active"><a href="bootstrap-navbar-static-top.html">Static top</a></li> + <li><a href="bootstrap-navbar-fixed-top.html">Fixed top</a></li> + <li><a href="bootstrap-navbar-fixed-bottom.html">Fixed bottom</a></li> + <li><a href="#">Dropdown <span class="caret"></span></a> + <ul class="dropdown-menu"> + <li><a href="#">Action</a></li> + <li><a href="#">Another action</a></li> + <li><a href="#">Something else here</a></li> + <li class="divider"></li> + <li class="dropdown-header">Nav header</li> + <li><a href="#">A sub menu <span class="caret"></span></a> + <ul class="dropdown-menu"> + <li><a href="#">Action</a></li> + <li><a href="#">Another action</a></li> + <li><a href="#">Something else here</a></li> + <li class="disabled"><a class="disabled" href="#">Disabled item</a></li> + <li><a href="#">One more link</a></li> + </ul> + </li> + <li><a href="#">A separated link</a></li> + </ul> + </li> + </ul> + + </div><!--/.nav-collapse --> + </div><!--/.container --> + </div> + + + + + <div class="container"> + + <div class="page-header"> + <h1>SmartMenus Bootstrap Addon (Navbar static top)</h1> + <p class="lead">Creating zero config advanced Bootstrap 3 navbars with SmartMenus jQuery and the SmartMenus jQuery Bootstrap Addon.</p> + </div> + <p>You basically just need to include the JS/CSS files on your Bootstrap 3 powered pages and everything should work automatically including full support for whatever Bootstrap theme you already use. And, of course, you still have the full power and flexibility of SmartMenus jQuery at hand should you need to tweak or customize anything.</p> + + <h2>Source Code</h2> + + <h3>CSS</h3> + <p>In addition to Bootstrap's CSS just include the SmartMenus jQuery Bootstrap Addon CSS. It's just static CSS code you don't need to edit at all (and probably shouldn't try to).</p> + <pre><!-- Bootstrap core CSS --> +<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet"> + +<span style="color:#419641;"><!-- SmartMenus jQuery Bootstrap Addon CSS --> +<link href="../addons/bootstrap/jquery.smartmenus.bootstrap.css" rel="stylesheet"></span></pre> + + <h3>HTML</h3> + <pre><!-- Navbar static top --> +<div class="navbar navbar-default navbar-static-top" role="navigation"> + <div class="container"> + <div class="navbar-header"> + <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse"> + <span class="sr-only">Toggle navigation</span> + <span class="icon-bar"></span> + <span class="icon-bar"></span> + <span class="icon-bar"></span> + </button> + <a class="navbar-brand" href="#">Project name</a> + </div> + <div class="navbar-collapse collapse"> + + <span style="color:#419641;"><!-- Left nav --> + <ul class="nav navbar-nav"> + <li><a href="#">Link</a></li> + <li><a href="#">Link</a></li> + <li><a href="#">Link</a></li> + <li><a href="#">Dropdown <span class="caret"></span></a> + <ul class="dropdown-menu"> + <li><a href="#">Action</a></li> + <li><a href="#">Another action</a></li> + <li><a href="#">Something else here</a></li> + <li class="divider"></li> + <li class="dropdown-header">Nav header</li> + <li><a href="#">Separated link</a></li> + <li><a href="#">One more separated link <span class="caret"></span></a> + <ul class="dropdown-menu"> + <li><a href="#">Action</a></li> + <li><a href="#">Another action</a></li> + <li><a href="#">A long sub menu <span class="caret"></span></a> + <ul class="dropdown-menu"> + <li><a href="#">Action</a></li> + <li><a href="#">Something else here</a></li> + <li class="disabled"><a class="disabled" href="#">Disabled item</a></li> + <li><a href="#">One more link</a></li> + <li><a href="#">Menu item 1</a></li> + <li><a href="#">Menu item 2</a></li> + <li><a href="#">Menu item 3</a></li> + <li><a href="#">Menu item 4</a></li> + <li><a href="#">Menu item 5</a></li> + <li><a href="#">Menu item 6</a></li> + <li><a href="#">Menu item 7</a></li> + <li><a href="#">Menu item 8</a></li> + <li><a href="#">Menu item 9</a></li> + <li><a href="#">Menu item 10</a></li> + <li><a href="#">Menu item 11</a></li> + <li><a href="#">Menu item 12</a></li> + <li><a href="#">Menu item 13</a></li> + <li><a href="#">Menu item 14</a></li> + <li><a href="#">Menu item 15</a></li> + <li><a href="#">Menu item 16</a></li> + <li><a href="#">Menu item 17</a></li> + <li><a href="#">Menu item 18</a></li> + <li><a href="#">Menu item 19</a></li> + <li><a href="#">Menu item 20</a></li> + <li><a href="#">Menu item 21</a></li> + <li><a href="#">Menu item 22</a></li> + <li><a href="#">Menu item 23</a></li> + <li><a href="#">Menu item 24</a></li> + <li><a href="#">Menu item 25</a></li> + <li><a href="#">Menu item 26</a></li> + <li><a href="#">Menu item 27</a></li> + <li><a href="#">Menu item 28</a></li> + <li><a href="#">Menu item 29</a></li> + <li><a href="#">Menu item 30</a></li> + <li><a href="#">Menu item 31</a></li> + <li><a href="#">Menu item 32</a></li> + <li><a href="#">Menu item 33</a></li> + <li><a href="#">Menu item 34</a></li> + <li><a href="#">Menu item 35</a></li> + <li><a href="#">Menu item 36</a></li> + <li><a href="#">Menu item 37</a></li> + <li><a href="#">Menu item 38</a></li> + <li><a href="#">Menu item 39</a></li> + <li><a href="#">Menu item 40</a></li> + <li><a href="#">Menu item 41</a></li> + <li><a href="#">Menu item 42</a></li> + <li><a href="#">Menu item 43</a></li> + <li><a href="#">Menu item 44</a></li> + <li><a href="#">Menu item 45</a></li> + <li><a href="#">Menu item 46</a></li> + <li><a href="#">Menu item 47</a></li> + <li><a href="#">Menu item 48</a></li> + <li><a href="#">Menu item 49</a></li> + <li><a href="#">Menu item 50</a></li> + <li><a href="#">Menu item 51</a></li> + <li><a href="#">Menu item 52</a></li> + <li><a href="#">Menu item 53</a></li> + <li><a href="#">Menu item 54</a></li> + <li><a href="#">Menu item 55</a></li> + <li><a href="#">Menu item 56</a></li> + <li><a href="#">Menu item 57</a></li> + <li><a href="#">Menu item 58</a></li> + <li><a href="#">Menu item 59</a></li> + <li><a href="#">Menu item 60</a></li> + </ul> + </li> + <li><a href="#">Another link</a></li> + <li><a href="#">One more link</a></li> + </ul> + </li> + </ul> + </li> + </ul></span> + + <span style="color:#419641;"><!-- Right nav --> + <ul class="nav navbar-nav navbar-right"> + <li><a href="bootstrap-navbar.html">Default</a></li> + <li class="active"><a href="bootstrap-navbar-static-top.html">Static top</a></li> + <li><a href="bootstrap-navbar-fixed-top.html">Fixed top</a></li> + <li><a href="bootstrap-navbar-fixed-bottom.html">Fixed bottom</a></li> + <li><a href="#">Dropdown <span class="caret"></span></a> + <ul class="dropdown-menu"> + <li><a href="#">Action</a></li> + <li><a href="#">Another action</a></li> + <li><a href="#">Something else here</a></li> + <li class="divider"></li> + <li class="dropdown-header">Nav header</li> + <li><a href="#">A sub menu <span class="caret"></span></a> + <ul class="dropdown-menu"> + <li><a href="#">Action</a></li> + <li><a href="#">Another action</a></li> + <li><a href="#">Something else here</a></li> + <li class="disabled"><a class="disabled" href="#">Disabled item</a></li> + <li><a href="#">One more link</a></li> + </ul> + </li> + <li><a href="#">A separated link</a></li> + </ul> + </li> + </ul></span> + + </div><!--/.nav-collapse --> + </div><!--/.container --> +</div></pre> + + <h3>JavaScript</h3> + <p>In addition to Bootstrap's JavaScript just include SmartMenus jQuery and the SmartMenus jQuery Bootstrap Addon. The default options used in <code>jquery.smartmenus.bootstrap.js</code> should work well for all. However, you can, of course, tweak them if you like.</p> + <pre><!-- Bootstrap core JavaScript +================================================== --> +<!-- Placed at the end of the document so the pages load faster --> +<script src="https://code.jquery.com/jquery-1.11.3.min.js"></script> +<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script> + +<span style="color:#419641;"><!-- SmartMenus jQuery plugin --> +<script type="text/javascript" src="../jquery.smartmenus.js"></script> + +<!-- SmartMenus jQuery Bootstrap Addon --> +<script type="text/javascript" src="../addons/bootstrap/jquery.smartmenus.bootstrap.js"></script></span></pre> + + <h2>Quick customization</h2> + + <h3><code>data-*</code> attributes</h3> + <p>The following <code>data-*</code> attributes can be set to any <code>ul.navbar-nav</code>:</p> + <ul> + <li><code>data-sm-options</code> - set any custom options for the SmartMenus jQuery plugin (<a href="http://www.smartmenus.org/docs/#data-sm-options">check the docs</a> for details).</li> + <li><code>data-sm-skip</code> - this will tell the script to skip this navbar and not apply any SmartMenus features to it so it will behave like a regular Bootstrap navbar.</li> + <li><code>data-sm-skip-collapsible-behavior</code> - this will tell the script to not apply SmartMenus' specific behavior to this navbar in collapsible mode (mobile view). Bootstrap's behavior for navbars in collapsible mode is to use the whole area of the parent items just as a toggle button for their sub menus and thus it's impossible to set a link to the parent items that can be followed on click/tap. SmartMenus' behavior is to add a separate dedicated +/- sub menus toggle button to parent items and thus allows the link of the parent items to be activated on the second click/tap (the first click/tap displays the sub menu if it's not visible).</li> + </ul> + + <h3>API</h3> + <p>The following methods are available:</p> + <ul> + <li><code>jQuery.SmartMenus.Bootstrap.init()</code> - reinit the addon. Useful if you add any navbars dynamically on your page and need to init them (all navbars are normally initialized ondomready).</li> + </ul> + + <hr /> + + <ul class="pagination"> + <li><a href="index.html">« Back to main demo</a></li> + </ul> + + </div> <!-- /container --> + + + + + <!-- Bootstrap core JavaScript + ================================================== --> + <!-- Placed at the end of the document so the pages load faster --> + <script src="https://code.jquery.com/jquery-1.11.3.min.js"></script> + <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script> + + <!-- SmartMenus jQuery plugin --> + <script type="text/javascript" src="../jquery.smartmenus.js"></script> + + <!-- SmartMenus jQuery Bootstrap Addon --> + <script type="text/javascript" src="../addons/bootstrap/jquery.smartmenus.bootstrap.js"></script> + + + + + </body> +</html> \ No newline at end of file diff --git a/civicrm/bower_components/smartmenus/src/demo/bootstrap-navbar.html b/civicrm/bower_components/smartmenus/src/demo/bootstrap-navbar.html new file mode 100644 index 0000000000..fad489d2d4 --- /dev/null +++ b/civicrm/bower_components/smartmenus/src/demo/bootstrap-navbar.html @@ -0,0 +1,386 @@ +<!DOCTYPE html> +<html lang="en"> + <head> + <meta charset="utf-8"> + <meta http-equiv="X-UA-Compatible" content="IE=edge"> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + + <title>SmartMenus jQuery Website Menu - Bootstrap Addon - Navbar</title> + + + + + <!-- Bootstrap core CSS --> + <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet"> + + <!-- SmartMenus jQuery Bootstrap Addon CSS --> + <link href="../addons/bootstrap/jquery.smartmenus.bootstrap.css" rel="stylesheet"> + + <!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries --> + <!--[if lt IE 9]> + <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script> + <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script> + <![endif]--> + + + + + </head> + + <body style="padding-top:20px;"> + + <div class="container"> + + + + + <!-- Navbar --> + <div class="navbar navbar-default" role="navigation"> + <div class="navbar-header"> + <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse"> + <span class="sr-only">Toggle navigation</span> + <span class="icon-bar"></span> + <span class="icon-bar"></span> + <span class="icon-bar"></span> + </button> + <a class="navbar-brand" href="#">Project name</a> + </div> + <div class="navbar-collapse collapse"> + + <!-- Left nav --> + <ul class="nav navbar-nav"> + <li><a href="#">Link</a></li> + <li><a href="#">Link</a></li> + <li><a href="#">Link</a></li> + <li><a href="#">Dropdown <span class="caret"></span></a> + <ul class="dropdown-menu"> + <li><a href="#">Action</a></li> + <li><a href="#">Another action</a></li> + <li><a href="#">Something else here</a></li> + <li class="divider"></li> + <li class="dropdown-header">Nav header</li> + <li><a href="#">Separated link</a></li> + <li><a href="#">One more separated link <span class="caret"></span></a> + <ul class="dropdown-menu"> + <li><a href="#">Action</a></li> + <li><a href="#">Another action</a></li> + <li><a href="#">A long sub menu <span class="caret"></span></a> + <ul class="dropdown-menu"> + <li><a href="#">Action</a></li> + <li><a href="#">Something else here</a></li> + <li class="disabled"><a class="disabled" href="#">Disabled item</a></li> + <li><a href="#">One more link</a></li> + <li><a href="#">Menu item 1</a></li> + <li><a href="#">Menu item 2</a></li> + <li><a href="#">Menu item 3</a></li> + <li><a href="#">Menu item 4</a></li> + <li><a href="#">Menu item 5</a></li> + <li><a href="#">Menu item 6</a></li> + <li><a href="#">Menu item 7</a></li> + <li><a href="#">Menu item 8</a></li> + <li><a href="#">Menu item 9</a></li> + <li><a href="#">Menu item 10</a></li> + <li><a href="#">Menu item 11</a></li> + <li><a href="#">Menu item 12</a></li> + <li><a href="#">Menu item 13</a></li> + <li><a href="#">Menu item 14</a></li> + <li><a href="#">Menu item 15</a></li> + <li><a href="#">Menu item 16</a></li> + <li><a href="#">Menu item 17</a></li> + <li><a href="#">Menu item 18</a></li> + <li><a href="#">Menu item 19</a></li> + <li><a href="#">Menu item 20</a></li> + <li><a href="#">Menu item 21</a></li> + <li><a href="#">Menu item 22</a></li> + <li><a href="#">Menu item 23</a></li> + <li><a href="#">Menu item 24</a></li> + <li><a href="#">Menu item 25</a></li> + <li><a href="#">Menu item 26</a></li> + <li><a href="#">Menu item 27</a></li> + <li><a href="#">Menu item 28</a></li> + <li><a href="#">Menu item 29</a></li> + <li><a href="#">Menu item 30</a></li> + <li><a href="#">Menu item 31</a></li> + <li><a href="#">Menu item 32</a></li> + <li><a href="#">Menu item 33</a></li> + <li><a href="#">Menu item 34</a></li> + <li><a href="#">Menu item 35</a></li> + <li><a href="#">Menu item 36</a></li> + <li><a href="#">Menu item 37</a></li> + <li><a href="#">Menu item 38</a></li> + <li><a href="#">Menu item 39</a></li> + <li><a href="#">Menu item 40</a></li> + <li><a href="#">Menu item 41</a></li> + <li><a href="#">Menu item 42</a></li> + <li><a href="#">Menu item 43</a></li> + <li><a href="#">Menu item 44</a></li> + <li><a href="#">Menu item 45</a></li> + <li><a href="#">Menu item 46</a></li> + <li><a href="#">Menu item 47</a></li> + <li><a href="#">Menu item 48</a></li> + <li><a href="#">Menu item 49</a></li> + <li><a href="#">Menu item 50</a></li> + <li><a href="#">Menu item 51</a></li> + <li><a href="#">Menu item 52</a></li> + <li><a href="#">Menu item 53</a></li> + <li><a href="#">Menu item 54</a></li> + <li><a href="#">Menu item 55</a></li> + <li><a href="#">Menu item 56</a></li> + <li><a href="#">Menu item 57</a></li> + <li><a href="#">Menu item 58</a></li> + <li><a href="#">Menu item 59</a></li> + <li><a href="#">Menu item 60</a></li> + </ul> + </li> + <li><a href="#">Another link</a></li> + <li><a href="#">One more link</a></li> + </ul> + </li> + </ul> + </li> + </ul> + + <!-- Right nav --> + <ul class="nav navbar-nav navbar-right"> + <li class="active"><a href="bootstrap-navbar.html">Default</a></li> + <li><a href="bootstrap-navbar-static-top.html">Static top</a></li> + <li><a href="bootstrap-navbar-fixed-top.html">Fixed top</a></li> + <li><a href="bootstrap-navbar-fixed-bottom.html">Fixed bottom</a></li> + <li><a href="#">Dropdown <span class="caret"></span></a> + <ul class="dropdown-menu"> + <li><a href="#">Action</a></li> + <li><a href="#">Another action</a></li> + <li><a href="#">Something else here</a></li> + <li class="divider"></li> + <li class="dropdown-header">Nav header</li> + <li><a href="#">A sub menu <span class="caret"></span></a> + <ul class="dropdown-menu"> + <li><a href="#">Action</a></li> + <li><a href="#">Another action</a></li> + <li><a href="#">Something else here</a></li> + <li class="disabled"><a class="disabled" href="#">Disabled item</a></li> + <li><a href="#">One more link</a></li> + </ul> + </li> + <li><a href="#">A separated link</a></li> + </ul> + </li> + </ul> + + </div><!--/.nav-collapse --> + </div> + + + + + <div class="page-header"> + <h1>SmartMenus Bootstrap Addon (Navbar)</h1> + <p class="lead">Creating zero config advanced Bootstrap 3 navbars with SmartMenus jQuery and the SmartMenus jQuery Bootstrap Addon.</p> + </div> + <p>You basically just need to include the JS/CSS files on your Bootstrap 3 powered pages and everything should work automatically including full support for whatever Bootstrap theme you already use. And, of course, you still have the full power and flexibility of SmartMenus jQuery at hand should you need to tweak or customize anything.</p> + + <h2>Source Code</h2> + + <h3>CSS</h3> + <p>In addition to Bootstrap's CSS just include the SmartMenus jQuery Bootstrap Addon CSS. It's just static CSS code you don't need to edit at all (and probably shouldn't try to).</p> + <pre><!-- Bootstrap core CSS --> +<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet"> + +<span style="color:#419641;"><!-- SmartMenus jQuery Bootstrap Addon CSS --> +<link href="../addons/bootstrap/jquery.smartmenus.bootstrap.css" rel="stylesheet"></span></pre> + + <h3>HTML</h3> + <pre><!-- Navbar --> +<div class="navbar navbar-default" role="navigation"> + <div class="navbar-header"> + <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse"> + <span class="sr-only">Toggle navigation</span> + <span class="icon-bar"></span> + <span class="icon-bar"></span> + <span class="icon-bar"></span> + </button> + <a class="navbar-brand" href="#">Project name</a> + </div> + <div class="navbar-collapse collapse"> + + <span style="color:#419641;"><!-- Left nav --> + <ul class="nav navbar-nav"> + <li><a href="#">Link</a></li> + <li><a href="#">Link</a></li> + <li><a href="#">Link</a></li> + <li><a href="#">Dropdown <span class="caret"></span></a> + <ul class="dropdown-menu"> + <li><a href="#">Action</a></li> + <li><a href="#">Another action</a></li> + <li><a href="#">Something else here</a></li> + <li class="divider"></li> + <li class="dropdown-header">Nav header</li> + <li><a href="#">Separated link</a></li> + <li><a href="#">One more separated link <span class="caret"></span></a> + <ul class="dropdown-menu"> + <li><a href="#">Action</a></li> + <li><a href="#">Another action</a></li> + <li><a href="#">A long sub menu <span class="caret"></span></a> + <ul class="dropdown-menu"> + <li><a href="#">Action</a></li> + <li><a href="#">Something else here</a></li> + <li class="disabled"><a class="disabled" href="#">Disabled item</a></li> + <li><a href="#">One more link</a></li> + <li><a href="#">Menu item 1</a></li> + <li><a href="#">Menu item 2</a></li> + <li><a href="#">Menu item 3</a></li> + <li><a href="#">Menu item 4</a></li> + <li><a href="#">Menu item 5</a></li> + <li><a href="#">Menu item 6</a></li> + <li><a href="#">Menu item 7</a></li> + <li><a href="#">Menu item 8</a></li> + <li><a href="#">Menu item 9</a></li> + <li><a href="#">Menu item 10</a></li> + <li><a href="#">Menu item 11</a></li> + <li><a href="#">Menu item 12</a></li> + <li><a href="#">Menu item 13</a></li> + <li><a href="#">Menu item 14</a></li> + <li><a href="#">Menu item 15</a></li> + <li><a href="#">Menu item 16</a></li> + <li><a href="#">Menu item 17</a></li> + <li><a href="#">Menu item 18</a></li> + <li><a href="#">Menu item 19</a></li> + <li><a href="#">Menu item 20</a></li> + <li><a href="#">Menu item 21</a></li> + <li><a href="#">Menu item 22</a></li> + <li><a href="#">Menu item 23</a></li> + <li><a href="#">Menu item 24</a></li> + <li><a href="#">Menu item 25</a></li> + <li><a href="#">Menu item 26</a></li> + <li><a href="#">Menu item 27</a></li> + <li><a href="#">Menu item 28</a></li> + <li><a href="#">Menu item 29</a></li> + <li><a href="#">Menu item 30</a></li> + <li><a href="#">Menu item 31</a></li> + <li><a href="#">Menu item 32</a></li> + <li><a href="#">Menu item 33</a></li> + <li><a href="#">Menu item 34</a></li> + <li><a href="#">Menu item 35</a></li> + <li><a href="#">Menu item 36</a></li> + <li><a href="#">Menu item 37</a></li> + <li><a href="#">Menu item 38</a></li> + <li><a href="#">Menu item 39</a></li> + <li><a href="#">Menu item 40</a></li> + <li><a href="#">Menu item 41</a></li> + <li><a href="#">Menu item 42</a></li> + <li><a href="#">Menu item 43</a></li> + <li><a href="#">Menu item 44</a></li> + <li><a href="#">Menu item 45</a></li> + <li><a href="#">Menu item 46</a></li> + <li><a href="#">Menu item 47</a></li> + <li><a href="#">Menu item 48</a></li> + <li><a href="#">Menu item 49</a></li> + <li><a href="#">Menu item 50</a></li> + <li><a href="#">Menu item 51</a></li> + <li><a href="#">Menu item 52</a></li> + <li><a href="#">Menu item 53</a></li> + <li><a href="#">Menu item 54</a></li> + <li><a href="#">Menu item 55</a></li> + <li><a href="#">Menu item 56</a></li> + <li><a href="#">Menu item 57</a></li> + <li><a href="#">Menu item 58</a></li> + <li><a href="#">Menu item 59</a></li> + <li><a href="#">Menu item 60</a></li> + </ul> + </li> + <li><a href="#">Another link</a></li> + <li><a href="#">One more link</a></li> + </ul> + </li> + </ul> + </li> + </ul></span> + + <span style="color:#419641;"><!-- Right nav --> + <ul class="nav navbar-nav navbar-right"> + <li class="active"><a href="bootstrap-navbar.html">Default</a></li> + <li><a href="bootstrap-navbar-static-top.html">Static top</a></li> + <li><a href="bootstrap-navbar-fixed-top.html">Fixed top</a></li> + <li><a href="bootstrap-navbar-fixed-bottom.html">Fixed bottom</a></li> + <li><a href="#">Dropdown <span class="caret"></span></a> + <ul class="dropdown-menu"> + <li><a href="#">Action</a></li> + <li><a href="#">Another action</a></li> + <li><a href="#">Something else here</a></li> + <li class="divider"></li> + <li class="dropdown-header">Nav header</li> + <li><a href="#">A sub menu <span class="caret"></span></a> + <ul class="dropdown-menu"> + <li><a href="#">Action</a></li> + <li><a href="#">Another action</a></li> + <li><a href="#">Something else here</a></li> + <li class="disabled"><a class="disabled" href="#">Disabled item</a></li> + <li><a href="#">One more link</a></li> + </ul> + </li> + <li><a href="#">A separated link</a></li> + </ul> + </li> + </ul></span> + + </div><!--/.nav-collapse --> +</div></pre> + + <h3>JavaScript</h3> + <p>In addition to Bootstrap's JavaScript just include SmartMenus jQuery and the SmartMenus jQuery Bootstrap Addon. The default options used in <code>jquery.smartmenus.bootstrap.js</code> should work well for all. However, you can, of course, tweak them if you like.</p> + <pre><!-- Bootstrap core JavaScript +================================================== --> +<!-- Placed at the end of the document so the pages load faster --> +<script src="https://code.jquery.com/jquery-1.11.3.min.js"></script> +<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script> + +<span style="color:#419641;"><!-- SmartMenus jQuery plugin --> +<script type="text/javascript" src="../jquery.smartmenus.js"></script> + +<!-- SmartMenus jQuery Bootstrap Addon --> +<script type="text/javascript" src="../addons/bootstrap/jquery.smartmenus.bootstrap.js"></script></span></pre> + + <h2>Quick customization</h2> + + <h3><code>data-*</code> attributes</h3> + <p>The following <code>data-*</code> attributes can be set to any <code>ul.navbar-nav</code>:</p> + <ul> + <li><code>data-sm-options</code> - set any custom options for the SmartMenus jQuery plugin (<a href="http://www.smartmenus.org/docs/#data-sm-options">check the docs</a> for details).</li> + <li><code>data-sm-skip</code> - this will tell the script to skip this navbar and not apply any SmartMenus features to it so it will behave like a regular Bootstrap navbar.</li> + <li><code>data-sm-skip-collapsible-behavior</code> - this will tell the script to not apply SmartMenus' specific behavior to this navbar in collapsible mode (mobile view). Bootstrap's behavior for navbars in collapsible mode is to use the whole area of the parent items just as a toggle button for their sub menus and thus it's impossible to set a link to the parent items that can be followed on click/tap. SmartMenus' behavior is to add a separate dedicated +/- sub menus toggle button to parent items and thus allows the link of the parent items to be activated on the second click/tap (the first click/tap displays the sub menu if it's not visible).</li> + </ul> + + <h3>API</h3> + <p>The following methods are available:</p> + <ul> + <li><code>jQuery.SmartMenus.Bootstrap.init()</code> - reinit the addon. Useful if you add any navbars dynamically on your page and need to init them (all navbars are normally initialized ondomready).</li> + </ul> + + <hr /> + + <ul class="pagination"> + <li><a href="index.html">« Back to main demo</a></li> + </ul> + + </div> <!-- /container --> + + + + + <!-- Bootstrap core JavaScript + ================================================== --> + <!-- Placed at the end of the document so the pages load faster --> + <script src="https://code.jquery.com/jquery-1.11.3.min.js"></script> + <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script> + + <!-- SmartMenus jQuery plugin --> + <script type="text/javascript" src="../jquery.smartmenus.js"></script> + + <!-- SmartMenus jQuery Bootstrap Addon --> + <script type="text/javascript" src="../addons/bootstrap/jquery.smartmenus.bootstrap.js"></script> + + + + + </body> +</html> \ No newline at end of file diff --git a/civicrm/bower_components/smartmenus/src/demo/index.html b/civicrm/bower_components/smartmenus/src/demo/index.html new file mode 100644 index 0000000000..6d0e97acd3 --- /dev/null +++ b/civicrm/bower_components/smartmenus/src/demo/index.html @@ -0,0 +1,226 @@ +<!DOCTYPE html> +<html lang="en"> + <head> + <title>SmartMenus jQuery Website Menu - jQuery Plugin</title> + <meta charset="utf-8"> + <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> + + + + + <!-- SmartMenus core CSS (required) --> + <link href="../css/sm-core-css.css" rel="stylesheet" type="text/css" /> + + <!-- "sm-blue" menu theme (optional, you can use your own CSS, too) --> + <link href="../css/sm-blue/sm-blue.css" rel="stylesheet" type="text/css" /> + + + + + <!-- YOU DO NOT NEED THIS - demo page content styles --> + <link href="../libs/demo-assets/demo.css" rel="stylesheet" type="text/css" /> + + </head> + + <body> + + + + + <nav id="main-nav"> + <!-- Sample menu definition --> + <ul id="main-menu" class="sm sm-blue"> + <li><a href="http://www.smartmenus.org/">Home</a></li> + <li><a href="http://www.smartmenus.org/about/">About</a> + <ul> + <li><a href="http://www.smartmenus.org/about/introduction-to-smartmenus-jquery/">Introduction to SmartMenus jQuery</a></li> + <li><a href="http://www.smartmenus.org/about/themes/">Demos + themes</a></li> + <li><a href="http://vadikom.com/about/#vasil-dinkov">The author</a></li> + <li><a href="http://www.smartmenus.org/about/vadikom/">The company</a> + <ul> + <li><a href="http://vadikom.com/about/">About Vadikom</a></li> + <li><a href="http://vadikom.com/projects/">Projects</a></li> + <li><a href="http://vadikom.com/services/">Services</a></li> + <li><a href="http://www.smartmenus.org/about/vadikom/privacy-policy/">Privacy policy</a></li> + </ul> + </li> + </ul> + </li> + <li><a href="http://www.smartmenus.org/download/">Download</a></li> + <li><a href="http://www.smartmenus.org/support/">Support</a> + <ul> + <li><a href="http://www.smartmenus.org/support/premium-support/">Premium support</a></li> + <li><a href="http://www.smartmenus.org/support/forums/">Forums</a></li> + </ul> + </li> + <li><a href="http://www.smartmenus.org/docs/">Docs</a></li> + <li><a href="#">Sub test</a> + <ul> + <li><a href="#">Dummy item</a></li> + <li><a href="#">Dummy item</a></li> + <li><a href="#" class="disabled">Disabled menu item</a></li> + <li><a href="#">Dummy item</a></li> + <li><a href="#">more...</a> + <ul> + <li><a href="#">A pretty long text to test the default subMenusMaxWidth:20em setting for the sub menus</a></li> + <li><a href="#">Dummy item</a></li> + <li><a href="#">Dummy item</a></li> + <li><a href="#">Dummy item</a></li> + <li><a href="#">Dummy item</a></li> + <li><a href="#">Dummy item</a></li> + <li><a href="#">more...</a> + <ul> + <li><a href="#">Dummy item</a></li> + <li><a href="#" class="current">A 'current' class item</a></li> + <li><a href="#">Dummy item</a></li> + <li><a href="#">more...</a> + <ul> + <li><a href="#">subMenusMinWidth</a></li> + <li><a href="#">10em</a></li> + <li><a href="#">forced.</a></li> + </ul> + </li> + <li><a href="#">Dummy item</a></li> + <li><a href="#">Dummy item</a></li> + </ul> + </li> + <li><a href="#">Dummy item</a></li> + <li><a href="#">Dummy item</a></li> + <li><a href="#">Dummy item</a></li> + <li><a href="#">Dummy item</a></li> + <li><a href="#">A pretty long text to test the default subMenusMaxWidth:20em setting for the sub menus</a></li> + <li><a href="#">Dummy item</a></li> + <li><a href="#">Dummy item</a></li> + <li><a href="#">Dummy item</a></li> + <li><a href="#">Dummy item</a></li> + <li><a href="#">Dummy item</a></li> + <li><a href="#">Dummy item</a></li> + <li><a href="#">Dummy item</a></li> + <li><a href="#">Dummy item</a></li> + <li><a href="#">Dummy item</a></li> + <li><a href="#">Dummy item</a></li> + <li><a href="#">A pretty long text to test the default subMenusMaxWidth:20em setting for the sub menus</a></li> + <li><a href="#">Dummy item</a></li> + <li><a href="#">Dummy item</a></li> + <li><a href="#">Dummy item</a></li> + <li><a href="#">Dummy item</a></li> + <li><a href="#">Dummy item</a></li> + <li><a href="#">Dummy item</a></li> + <li><a href="#">Dummy item</a></li> + <li><a href="#">Dummy item</a></li> + <li><a href="#">Dummy item</a></li> + <li><a href="#">Dummy item</a></li> + <li><a href="#">A pretty long text to test the default subMenusMaxWidth:20em setting for the sub menus</a></li> + <li><a href="#">Dummy item</a></li> + <li><a href="#">Dummy item</a></li> + <li><a href="#">Dummy item</a></li> + <li><a href="#">Dummy item</a></li> + <li><a href="#">Dummy item</a></li> + <li><a href="#">Dummy item</a></li> + <li><a href="#">Dummy item</a></li> + <li><a href="#">Dummy item</a></li> + <li><a href="#">Dummy item</a></li> + <li><a href="#">Dummy item</a></li> + <li><a href="#">A pretty long text to test the default subMenusMaxWidth:20em setting for the sub menus</a></li> + <li><a href="#">Dummy item</a></li> + <li><a href="#">Dummy item</a></li> + <li><a href="#">Dummy item</a></li> + <li><a href="#">Dummy item</a></li> + <li><a href="#">Dummy item</a></li> + <li><a href="#">Dummy item</a></li> + <li><a href="#">Dummy item</a></li> + <li><a href="#">Dummy item</a></li> + <li><a href="#">Dummy item</a></li> + <li><a href="#">Dummy item</a></li> + <li><a href="#">A pretty long text to test the default subMenusMaxWidth:20em setting for the sub menus</a></li> + <li><a href="#">Dummy item</a></li> + <li><a href="#">Dummy item</a></li> + <li><a href="#">Dummy item</a></li> + <li><a href="#">Dummy item</a></li> + <li><a href="#">Dummy item</a></li> + <li><a href="#">Dummy item</a></li> + <li><a href="#">Dummy item</a></li> + <li><a href="#">Dummy item</a></li> + <li><a href="#">Dummy item</a></li> + <li><a href="#">Dummy item</a></li> + </ul> + </li> + </ul> + </li> + <li><a href="#">Mega menu</a> + <ul class="mega-menu"> + <li> + <!-- The mega drop down contents --> + <div style="width:400px;max-width:100%;"> + <div style="padding:5px 24px;"> + <p>This is a mega drop down test. Just set the "mega-menu" class to the parent UL element to inform the SmartMenus script. It can contain <strong>any HTML</strong>.</p> + <p>Just style the contents as you like (you may need to reset some SmartMenus inherited styles - e.g. for lists, links, etc.)</p> + </div> + </div> + </li> + </ul> + </li> + </ul> + </nav> + + + + + <!-- YOU DO NOT NEED THIS - demo page content --> + <div class="columns"> + <div class="left-column"> + <div id="content"> + <h1>SmartMenus</h1> + <p>jQuery website menu plugin. Responsive and accessible list-based website menus that work on all devices.</p> + <ul> + <li><a href="http://www.smartmenus.org/docs/">Getting started and API documentation</a></li> + <li><a href="https://github.com/vadikom/smartmenus/issues">Bugs and issues</a></li> + <li><a href="http://www.smartmenus.org/forums/">Support forums</a></li> + <li><a href="http://www.smartmenus.org/support/premium-support/">Premium support</a></li> + </ul> + <h2>Examples</h2> + <p>Basic bundled demos:</p> + <ul> + <li><a href="keyboard-navigation.html">Keyboard Addon</a></li> + <li><a href="bootstrap-4-navbar.html">Bootstrap 4 Addon (Navbar)</a></li> + <li><a href="bootstrap-4-navbar-static-top.html">Bootstrap 4 Addon (Navbar static top)</a></li> + <li><a href="bootstrap-4-navbar-fixed-top.html">Bootstrap 4 Addon (Navbar fixed top)</a></li> + <li><a href="bootstrap-4-navbar-fixed-bottom.html">Bootstrap 4 Addon (Navbar fixed bottom)</a></li> + <li><a href="bootstrap-navbar.html">Bootstrap Addon (Navbar)</a></li> + <li><a href="bootstrap-navbar-static-top.html">Bootstrap Addon (Navbar static top)</a></li> + <li><a href="bootstrap-navbar-fixed-top.html">Bootstrap Addon (Navbar fixed top)</a></li> + <li><a href="bootstrap-navbar-fixed-bottom.html">Bootstrap Addon (Navbar fixed bottom)</a></li> + </ul> + <p><a href="http://www.smartmenus.org/about/themes/#demos-gallery" class="gray-button">Online demos + themes gallery »</a></p> + </div> + </div> + <div class="right-column"></div> + </div> + + + + + <!-- jQuery --> + <script type="text/javascript" src="../libs/jquery/jquery.js"></script> + + <!-- SmartMenus jQuery plugin --> + <script type="text/javascript" src="../jquery.smartmenus.js"></script> + + <!-- SmartMenus jQuery init --> + <script type="text/javascript"> + $(function() { + $('#main-menu').smartmenus({ + subMenusSubOffsetX: 1, + subMenusSubOffsetY: -8 + }); + }); + </script> + + + + + <!-- YOU DO NOT NEED THIS - demo page themes switcher --> + <script type="text/javascript" src="../libs/demo-assets/themes-switcher.js"></script> + + </body> +</html> \ No newline at end of file diff --git a/civicrm/bower_components/smartmenus/src/demo/keyboard-navigation.html b/civicrm/bower_components/smartmenus/src/demo/keyboard-navigation.html new file mode 100644 index 0000000000..069e6fcfbb --- /dev/null +++ b/civicrm/bower_components/smartmenus/src/demo/keyboard-navigation.html @@ -0,0 +1,243 @@ +<!DOCTYPE html> +<html lang="en"> + <head> + <title>SmartMenus jQuery Website Menu - Keyboard Addon</title> + <meta charset="utf-8"> + <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> + + + + + <!-- SmartMenus core CSS (required) --> + <link href="../css/sm-core-css.css" rel="stylesheet" type="text/css" /> + + <!-- "sm-blue" menu theme (optional, you can use your own CSS, too) --> + <link href="../css/sm-blue/sm-blue.css" rel="stylesheet" type="text/css" /> + + + + + <!-- YOU DO NOT NEED THIS - demo page content styles --> + <link href="../libs/demo-assets/demo.css" rel="stylesheet" type="text/css" /> + + </head> + + <body> + + + + + <nav id="main-nav"> + <!-- Sample menu definition --> + <ul id="main-menu" class="sm sm-blue"> + <li><h2><a href="http://www.smartmenus.org/">Home</a></h2></li> + <li><h2><a href="http://www.smartmenus.org/about/">About</a></h2> + <ul> + <li><a href="http://www.smartmenus.org/about/introduction-to-smartmenus-jquery/">Introduction to SmartMenus jQuery</a></li> + <li><a href="http://www.smartmenus.org/about/themes/">Demos + themes</a></li> + <li><a href="http://vadikom.com/about/#vasil-dinkov">The author</a></li> + <li><a href="http://www.smartmenus.org/about/vadikom/">The company</a> + <ul> + <li><a href="http://vadikom.com/about/">About Vadikom</a></li> + <li><a href="http://vadikom.com/projects/">Projects</a></li> + <li><a href="http://vadikom.com/services/">Services</a></li> + <li><a href="http://www.smartmenus.org/about/vadikom/privacy-policy/">Privacy policy</a></li> + </ul> + </li> + </ul> + </li> + <li><h2><a href="http://www.smartmenus.org/download/">Download</a></h2></li> + <li><h2><a href="http://www.smartmenus.org/support/">Support</a></h2> + <ul> + <li><a href="http://www.smartmenus.org/support/premium-support/">Premium support</a></li> + <li><a href="http://www.smartmenus.org/support/forums/">Forums</a></li> + </ul> + </li> + <li><h2><a href="http://www.smartmenus.org/docs/">Docs</a></h2></li> + <li><h2><a href="#">Sub test</a></h2> + <ul> + <li><a href="#">Dummy item</a></li> + <li><a href="#">Dummy item</a></li> + <li><a href="#" class="disabled">Disabled menu item</a></li> + <li><a href="#">Dummy item</a></li> + <li><a href="#">more...</a> + <ul> + <li><a href="#">A pretty long text to test the default subMenusMaxWidth:20em setting for the sub menus</a></li> + <li><a href="#">Dummy item</a></li> + <li><a href="#">Dummy item</a></li> + <li><a href="#">Dummy item</a></li> + <li><a href="#">Dummy item</a></li> + <li><a href="#">Dummy item</a></li> + <li><a href="#">more...</a> + <ul> + <li><a href="#">Dummy item</a></li> + <li><a href="#" class="current">A 'current' class item</a></li> + <li><a href="#">Dummy item</a></li> + <li><a href="#">more...</a> + <ul> + <li><a href="#">subMenusMinWidth</a></li> + <li><a href="#">10em</a></li> + <li><a href="#">forced.</a></li> + </ul> + </li> + <li><a href="#">Dummy item</a></li> + <li><a href="#">Dummy item</a></li> + </ul> + </li> + <li><a href="#">Dummy item</a></li> + <li><a href="#">Dummy item</a></li> + <li><a href="#">Dummy item</a></li> + <li><a href="#">Dummy item</a></li> + <li><a href="#">A pretty long text to test the default subMenusMaxWidth:20em setting for the sub menus</a></li> + <li><a href="#">Dummy item</a></li> + <li><a href="#">Dummy item</a></li> + <li><a href="#">Dummy item</a></li> + <li><a href="#">Dummy item</a></li> + <li><a href="#">Dummy item</a></li> + <li><a href="#">Dummy item</a></li> + <li><a href="#">Dummy item</a></li> + <li><a href="#">Dummy item</a></li> + <li><a href="#">Dummy item</a></li> + <li><a href="#">Dummy item</a></li> + <li><a href="#">A pretty long text to test the default subMenusMaxWidth:20em setting for the sub menus</a></li> + <li><a href="#">Dummy item</a></li> + <li><a href="#">Dummy item</a></li> + <li><a href="#">Dummy item</a></li> + <li><a href="#">Dummy item</a></li> + <li><a href="#">Dummy item</a></li> + <li><a href="#">Dummy item</a></li> + <li><a href="#">Dummy item</a></li> + <li><a href="#">Dummy item</a></li> + <li><a href="#">Dummy item</a></li> + <li><a href="#">Dummy item</a></li> + <li><a href="#">A pretty long text to test the default subMenusMaxWidth:20em setting for the sub menus</a></li> + <li><a href="#">Dummy item</a></li> + <li><a href="#">Dummy item</a></li> + <li><a href="#">Dummy item</a></li> + <li><a href="#">Dummy item</a></li> + <li><a href="#">Dummy item</a></li> + <li><a href="#">Dummy item</a></li> + <li><a href="#">Dummy item</a></li> + <li><a href="#">Dummy item</a></li> + <li><a href="#">Dummy item</a></li> + <li><a href="#">Dummy item</a></li> + <li><a href="#">A pretty long text to test the default subMenusMaxWidth:20em setting for the sub menus</a></li> + <li><a href="#">Dummy item</a></li> + <li><a href="#">Dummy item</a></li> + <li><a href="#">Dummy item</a></li> + <li><a href="#">Dummy item</a></li> + <li><a href="#">Dummy item</a></li> + <li><a href="#">Dummy item</a></li> + <li><a href="#">Dummy item</a></li> + <li><a href="#">Dummy item</a></li> + <li><a href="#">Dummy item</a></li> + <li><a href="#">Dummy item</a></li> + <li><a href="#">A pretty long text to test the default subMenusMaxWidth:20em setting for the sub menus</a></li> + <li><a href="#">Dummy item</a></li> + <li><a href="#">Dummy item</a></li> + <li><a href="#">Dummy item</a></li> + <li><a href="#">Dummy item</a></li> + <li><a href="#">Dummy item</a></li> + <li><a href="#">Dummy item</a></li> + <li><a href="#">Dummy item</a></li> + <li><a href="#">Dummy item</a></li> + <li><a href="#">Dummy item</a></li> + <li><a href="#">Dummy item</a></li> + </ul> + </li> + </ul> + </li> + <li><h2><a href="#">Mega menu</a></h2> + <ul class="mega-menu"> + <li> + <!-- The mega drop down contents --> + <div style="width:400px;max-width:100%;"> + <div style="padding:5px 24px;"> + <p>This is a mega drop down test. Just set the "mega-menu" class to the parent UL element to inform the SmartMenus script. It can contain <strong>any HTML</strong>.</p> + <p>Just style the contents as you like (you may need to reset some SmartMenus inherited styles - e.g. for lists, links, etc.)</p> + </div> + </div> + </li> + </ul> + </li> + </ul> + </nav> + + + + + <!-- YOU DO NOT NEED THIS - demo page content --> + <div class="columns"> + <div class="left-column"> + <div id="content"> + <h1>SmartMenus Keyboard Addon</h1> + <p>This is a demo of the SmartMenus jQuery Keyboard Addon which you can optionally include on your pages in addition to the SmartMenus jQuery plugin. It brings advanced keyboard navigation for all menu trees you may have on your pages.</p> + <p>By default without this addon the SmartMenus plugin includes basic keyboard navigation support - a user can use the <kbd>Tab</kbd> key to cycle through all main menu links, the <kbd>Enter</kbd> or <kbd>Space</kbd> key to activate the sub menus and also include their links in the tab order and the <kbd>Esc</kbd> key to deactivate the sub menus.</p> + <p>This addon takes keyboard navigation to a more advanced level by allowing the use of the keyboard <kbd>←</kbd> <kbd>→</kbd> <kbd>↑</kbd> <kbd>↓</kbd> arrow keys to browse the menu tree conveniently. Additionally a hotkey can be set too if needed - i.e. a keyboard shortcut that will send focus to any menu tree.</p> + <h2>Improving further accessibility</h2> + <p>You can consider improving even further accessibility for users of screen readers or text mode browsers by wrapping the main menu item links in headings - e.g. on this demo page <code><h2></code> tags are used. This would allow such users to skip from branch to branch more easily in certain scenarios.</p> + <h2>Demo</h2> + <p>Press <kbd>Shift</kbd> + <kbd>F12</kbd> to send focus to the first link in the main menu above (or press <kbd>Tab</kbd> as many times as need to focus some of the menu items). Then press <kbd>Enter</kbd>, <kbd>Space</kbd> or <kbd>↓</kbd> to activate some sub menu and then you can use the <kbd>←</kbd> <kbd>→</kbd> <kbd>↑</kbd> <kbd>↓</kbd> arrow keys to move the focus to other menu items. The script will automatically show/hide the sub menus as needed. You can press <kbd>Esc</kbd> at any time to deactivate the sub menus.</p> + <h2>Methods</h2> + <p>This addon introduces the following API method:</p> + <dl class="docs-terms"> + <dt>keyboardSetHotkey</dt> + <dd> + <div>Sets a hotkey combination that will send focus to the menu tree.</div> + <div>Arguments:</div> + <dl class="docs-arguments"> + <dt>keyCode</dt> + <dd>Type: Integer<br />The key code for the hotkey (<a href="http://www.cambiaresearch.com/articles/15/javascript-char-codes-key-codes">a good char code reference</a>).</dd> + <dt>modifiers</dt> + <dd>Type: String, Array<br />The hotkey modifier key. None, one or multiple of <code>'ctrlKey'</code>, <code>'shiftKey'</code>, <code>'altKey'</code>, <code>'metaKey'</code>.</dd> + </dl> + <div>Code sample:</div> + <pre class="sh_javascript sh_sourceCode">// set Shift + F12 hotkey + $('#main-menu').smartmenus('keyboardSetHotkey', 123, 'shiftKey'); + + // set Ctrl + Alt + Shift + F12 hotkey + $('#main-menu').smartmenus('keyboardSetHotkey', 123, ['ctrlKey', 'altKey', 'shiftKey']);</pre> + <div>Note: It is recommended to always use a combination (i.e. modifier + key) rather than use just a single key to avoid preventing important default browser features from working. <code>'shiftKey'</code> is best supported and probably the safest modifier you could use. <code>'ctrlKey'</code> and <code>'altKey'</code> generally work well too, there were just some issues with older Opera versions. <code>'metaKey'</code> is the Mac <kbd title="Apple / Command">⌘</kbd> key and it only works on Macs so, unless you know what you are doing, you probably shouldn't use it.</div> + </dd> + </dl> + <p class="pagination"><a href="index.html">« Back to main demo</a></p> + </div> + </div> + <div class="right-column"></div> + </div> + + + + + <!-- jQuery --> + <script type="text/javascript" src="../libs/jquery/jquery.js"></script> + + <!-- SmartMenus jQuery plugin --> + <script type="text/javascript" src="../jquery.smartmenus.js"></script> + + <!-- SmartMenus jQuery Keyboard Addon --> + <script type="text/javascript" src="../addons/keyboard/jquery.smartmenus.keyboard.js"></script> + + <!-- SmartMenus jQuery init --> + <script type="text/javascript"> + $(function() { + $('#main-menu').smartmenus({ + subMenusSubOffsetX: 1, + subMenusSubOffsetY: -8 + }); + $('#main-menu').smartmenus('keyboardSetHotkey', '123', 'shiftKey'); + }); + </script> + + + + + <!-- YOU DO NOT NEED THIS - demo page themes switcher --> + <script type="text/javascript"> + addonScriptSrc = [ ['SmartMenus jQuery Keyboard Addon', '../addons/keyboard/jquery.smartmenus.keyboard.js'] ]; + addonScriptInit = "\t\t$('#main-menu').smartmenus('keyboardSetHotkey', 123, 'shiftKey');\n"; + </script> + <script type="text/javascript" src="../libs/demo-assets/themes-switcher.js"></script> + +</body> +</html> \ No newline at end of file diff --git a/civicrm/bower_components/smartmenus/src/jquery.smartmenus.js b/civicrm/bower_components/smartmenus/src/jquery.smartmenus.js new file mode 100644 index 0000000000..678cbd4468 --- /dev/null +++ b/civicrm/bower_components/smartmenus/src/jquery.smartmenus.js @@ -0,0 +1,1217 @@ +/* + * SmartMenus jQuery v1.1.0 + * http://www.smartmenus.org/ + * + * Copyright Vasil Dinkov, Vadikom Web Ltd. + * http://vadikom.com/ + * + * Released under the MIT license: + * http://www.opensource.org/licenses/MIT + */ + +(function(factory) { + if (typeof define === 'function' && define.amd) { + // AMD + define(['jquery'], factory); + } else if (typeof module === 'object' && typeof module.exports === 'object') { + // CommonJS + module.exports = factory(require('jquery')); + } else { + // Global jQuery + factory(jQuery); + } +} (function($) { + + var menuTrees = [], + mouse = false, // optimize for touch by default - we will detect for mouse input + touchEvents = 'ontouchstart' in window, // we use this just to choose between toucn and pointer events, not for touch screen detection + mouseDetectionEnabled = false, + requestAnimationFrame = window.requestAnimationFrame || function(callback) { return setTimeout(callback, 1000 / 60); }, + cancelAnimationFrame = window.cancelAnimationFrame || function(id) { clearTimeout(id); }, + canAnimate = !!$.fn.animate; + + // Handle detection for mouse input (i.e. desktop browsers, tablets with a mouse, etc.) + function initMouseDetection(disable) { + var eNS = '.smartmenus_mouse'; + if (!mouseDetectionEnabled && !disable) { + // if we get two consecutive mousemoves within 2 pixels from each other and within 300ms, we assume a real mouse/cursor is present + // in practice, this seems like impossible to trick unintentianally with a real mouse and a pretty safe detection on touch devices (even with older browsers that do not support touch events) + var firstTime = true, + lastMove = null, + events = { + 'mousemove': function(e) { + var thisMove = { x: e.pageX, y: e.pageY, timeStamp: new Date().getTime() }; + if (lastMove) { + var deltaX = Math.abs(lastMove.x - thisMove.x), + deltaY = Math.abs(lastMove.y - thisMove.y); + if ((deltaX > 0 || deltaY > 0) && deltaX <= 2 && deltaY <= 2 && thisMove.timeStamp - lastMove.timeStamp <= 300) { + mouse = true; + // if this is the first check after page load, check if we are not over some item by chance and call the mouseenter handler if yes + if (firstTime) { + var $a = $(e.target).closest('a'); + if ($a.is('a')) { + $.each(menuTrees, function() { + if ($.contains(this.$root[0], $a[0])) { + this.itemEnter({ currentTarget: $a[0] }); + return false; + } + }); + } + firstTime = false; + } + } + } + lastMove = thisMove; + } + }; + events[touchEvents ? 'touchstart' : 'pointerover pointermove pointerout MSPointerOver MSPointerMove MSPointerOut'] = function(e) { + if (isTouchEvent(e.originalEvent)) { + mouse = false; + } + }; + $(document).on(getEventsNS(events, eNS)); + mouseDetectionEnabled = true; + } else if (mouseDetectionEnabled && disable) { + $(document).off(eNS); + mouseDetectionEnabled = false; + } + } + + function isTouchEvent(e) { + return !/^(4|mouse)$/.test(e.pointerType); + } + + // returns a jQuery on() ready object + function getEventsNS(events, eNS) { + if (!eNS) { + eNS = ''; + } + var eventsNS = {}; + for (var i in events) { + eventsNS[i.split(' ').join(eNS + ' ') + eNS] = events[i]; + } + return eventsNS; + } + + $.SmartMenus = function(elm, options) { + this.$root = $(elm); + this.opts = options; + this.rootId = ''; // internal + this.accessIdPrefix = ''; + this.$subArrow = null; + this.activatedItems = []; // stores last activated A's for each level + this.visibleSubMenus = []; // stores visible sub menus UL's (might be in no particular order) + this.showTimeout = 0; + this.hideTimeout = 0; + this.scrollTimeout = 0; + this.clickActivated = false; + this.focusActivated = false; + this.zIndexInc = 0; + this.idInc = 0; + this.$firstLink = null; // we'll use these for some tests + this.$firstSub = null; // at runtime so we'll cache them + this.disabled = false; + this.$disableOverlay = null; + this.$touchScrollingSub = null; + this.cssTransforms3d = 'perspective' in elm.style || 'webkitPerspective' in elm.style; + this.wasCollapsible = false; + this.init(); + }; + + $.extend($.SmartMenus, { + hideAll: function() { + $.each(menuTrees, function() { + this.menuHideAll(); + }); + }, + destroy: function() { + while (menuTrees.length) { + menuTrees[0].destroy(); + } + initMouseDetection(true); + }, + prototype: { + init: function(refresh) { + var self = this; + + if (!refresh) { + menuTrees.push(this); + + this.rootId = (new Date().getTime() + Math.random() + '').replace(/\D/g, ''); + this.accessIdPrefix = 'sm-' + this.rootId + '-'; + + if (this.$root.hasClass('sm-rtl')) { + this.opts.rightToLeftSubMenus = true; + } + + // init root (main menu) + var eNS = '.smartmenus'; + this.$root + .data('smartmenus', this) + .attr('data-smartmenus-id', this.rootId) + .dataSM('level', 1) + .on(getEventsNS({ + 'mouseover focusin': $.proxy(this.rootOver, this), + 'mouseout focusout': $.proxy(this.rootOut, this), + 'keydown': $.proxy(this.rootKeyDown, this) + }, eNS)) + .on(getEventsNS({ + 'mouseenter': $.proxy(this.itemEnter, this), + 'mouseleave': $.proxy(this.itemLeave, this), + 'mousedown': $.proxy(this.itemDown, this), + 'focus': $.proxy(this.itemFocus, this), + 'blur': $.proxy(this.itemBlur, this), + 'click': $.proxy(this.itemClick, this) + }, eNS), 'a'); + + // hide menus on tap or click outside the root UL + eNS += this.rootId; + if (this.opts.hideOnClick) { + $(document).on(getEventsNS({ + 'touchstart': $.proxy(this.docTouchStart, this), + 'touchmove': $.proxy(this.docTouchMove, this), + 'touchend': $.proxy(this.docTouchEnd, this), + // for Opera Mobile < 11.5, webOS browser, etc. we'll check click too + 'click': $.proxy(this.docClick, this) + }, eNS)); + } + // hide sub menus on resize + $(window).on(getEventsNS({ 'resize orientationchange': $.proxy(this.winResize, this) }, eNS)); + + if (this.opts.subIndicators) { + this.$subArrow = $('<span/>').addClass('sub-arrow'); + if (this.opts.subIndicatorsText) { + this.$subArrow.html(this.opts.subIndicatorsText); + } + } + + // make sure mouse detection is enabled + initMouseDetection(); + } + + // init sub menus + this.$firstSub = this.$root.find('ul').each(function() { self.menuInit($(this)); }).eq(0); + + this.$firstLink = this.$root.find('a').eq(0); + + // find current item + if (this.opts.markCurrentItem) { + var reDefaultDoc = /(index|default)\.[^#\?\/]*/i, + reHash = /#.*/, + locHref = window.location.href.replace(reDefaultDoc, ''), + locHrefNoHash = locHref.replace(reHash, ''); + this.$root.find('a').each(function() { + var href = this.href.replace(reDefaultDoc, ''), + $this = $(this); + if (href == locHref || href == locHrefNoHash) { + $this.addClass('current'); + if (self.opts.markCurrentTree) { + $this.parentsUntil('[data-smartmenus-id]', 'ul').each(function() { + $(this).dataSM('parent-a').addClass('current'); + }); + } + } + }); + } + + // save initial state + this.wasCollapsible = this.isCollapsible(); + }, + destroy: function(refresh) { + if (!refresh) { + var eNS = '.smartmenus'; + this.$root + .removeData('smartmenus') + .removeAttr('data-smartmenus-id') + .removeDataSM('level') + .off(eNS); + eNS += this.rootId; + $(document).off(eNS); + $(window).off(eNS); + if (this.opts.subIndicators) { + this.$subArrow = null; + } + } + this.menuHideAll(); + var self = this; + this.$root.find('ul').each(function() { + var $this = $(this); + if ($this.dataSM('scroll-arrows')) { + $this.dataSM('scroll-arrows').remove(); + } + if ($this.dataSM('shown-before')) { + if (self.opts.subMenusMinWidth || self.opts.subMenusMaxWidth) { + $this.css({ width: '', minWidth: '', maxWidth: '' }).removeClass('sm-nowrap'); + } + if ($this.dataSM('scroll-arrows')) { + $this.dataSM('scroll-arrows').remove(); + } + $this.css({ zIndex: '', top: '', left: '', marginLeft: '', marginTop: '', display: '' }); + } + if (($this.attr('id') || '').indexOf(self.accessIdPrefix) == 0) { + $this.removeAttr('id'); + } + }) + .removeDataSM('in-mega') + .removeDataSM('shown-before') + .removeDataSM('scroll-arrows') + .removeDataSM('parent-a') + .removeDataSM('level') + .removeDataSM('beforefirstshowfired') + .removeAttr('role') + .removeAttr('aria-hidden') + .removeAttr('aria-labelledby') + .removeAttr('aria-expanded'); + this.$root.find('a.has-submenu').each(function() { + var $this = $(this); + if ($this.attr('id').indexOf(self.accessIdPrefix) == 0) { + $this.removeAttr('id'); + } + }) + .removeClass('has-submenu') + .removeDataSM('sub') + .removeAttr('aria-haspopup') + .removeAttr('aria-controls') + .removeAttr('aria-expanded') + .closest('li').removeDataSM('sub'); + if (this.opts.subIndicators) { + this.$root.find('span.sub-arrow').remove(); + } + if (this.opts.markCurrentItem) { + this.$root.find('a.current').removeClass('current'); + } + if (!refresh) { + this.$root = null; + this.$firstLink = null; + this.$firstSub = null; + if (this.$disableOverlay) { + this.$disableOverlay.remove(); + this.$disableOverlay = null; + } + menuTrees.splice($.inArray(this, menuTrees), 1); + } + }, + disable: function(noOverlay) { + if (!this.disabled) { + this.menuHideAll(); + // display overlay over the menu to prevent interaction + if (!noOverlay && !this.opts.isPopup && this.$root.is(':visible')) { + var pos = this.$root.offset(); + this.$disableOverlay = $('<div class="sm-jquery-disable-overlay"/>').css({ + position: 'absolute', + top: pos.top, + left: pos.left, + width: this.$root.outerWidth(), + height: this.$root.outerHeight(), + zIndex: this.getStartZIndex(true), + opacity: 0 + }).appendTo(document.body); + } + this.disabled = true; + } + }, + docClick: function(e) { + if (this.$touchScrollingSub) { + this.$touchScrollingSub = null; + return; + } + // hide on any click outside the menu or on a menu link + if (this.visibleSubMenus.length && !$.contains(this.$root[0], e.target) || $(e.target).closest('a').length) { + this.menuHideAll(); + } + }, + docTouchEnd: function(e) { + if (!this.lastTouch) { + return; + } + if (this.visibleSubMenus.length && (this.lastTouch.x2 === undefined || this.lastTouch.x1 == this.lastTouch.x2) && (this.lastTouch.y2 === undefined || this.lastTouch.y1 == this.lastTouch.y2) && (!this.lastTouch.target || !$.contains(this.$root[0], this.lastTouch.target))) { + if (this.hideTimeout) { + clearTimeout(this.hideTimeout); + this.hideTimeout = 0; + } + // hide with a delay to prevent triggering accidental unwanted click on some page element + var self = this; + this.hideTimeout = setTimeout(function() { self.menuHideAll(); }, 350); + } + this.lastTouch = null; + }, + docTouchMove: function(e) { + if (!this.lastTouch) { + return; + } + var touchPoint = e.originalEvent.touches[0]; + this.lastTouch.x2 = touchPoint.pageX; + this.lastTouch.y2 = touchPoint.pageY; + }, + docTouchStart: function(e) { + var touchPoint = e.originalEvent.touches[0]; + this.lastTouch = { x1: touchPoint.pageX, y1: touchPoint.pageY, target: touchPoint.target }; + }, + enable: function() { + if (this.disabled) { + if (this.$disableOverlay) { + this.$disableOverlay.remove(); + this.$disableOverlay = null; + } + this.disabled = false; + } + }, + getClosestMenu: function(elm) { + var $closestMenu = $(elm).closest('ul'); + while ($closestMenu.dataSM('in-mega')) { + $closestMenu = $closestMenu.parent().closest('ul'); + } + return $closestMenu[0] || null; + }, + getHeight: function($elm) { + return this.getOffset($elm, true); + }, + // returns precise width/height float values + getOffset: function($elm, height) { + var old; + if ($elm.css('display') == 'none') { + old = { position: $elm[0].style.position, visibility: $elm[0].style.visibility }; + $elm.css({ position: 'absolute', visibility: 'hidden' }).show(); + } + var box = $elm[0].getBoundingClientRect && $elm[0].getBoundingClientRect(), + val = box && (height ? box.height || box.bottom - box.top : box.width || box.right - box.left); + if (!val && val !== 0) { + val = height ? $elm[0].offsetHeight : $elm[0].offsetWidth; + } + if (old) { + $elm.hide().css(old); + } + return val; + }, + getStartZIndex: function(root) { + var zIndex = parseInt(this[root ? '$root' : '$firstSub'].css('z-index')); + if (!root && isNaN(zIndex)) { + zIndex = parseInt(this.$root.css('z-index')); + } + return !isNaN(zIndex) ? zIndex : 1; + }, + getTouchPoint: function(e) { + return e.touches && e.touches[0] || e.changedTouches && e.changedTouches[0] || e; + }, + getViewport: function(height) { + var name = height ? 'Height' : 'Width', + val = document.documentElement['client' + name], + val2 = window['inner' + name]; + if (val2) { + val = Math.min(val, val2); + } + return val; + }, + getViewportHeight: function() { + return this.getViewport(true); + }, + getViewportWidth: function() { + return this.getViewport(); + }, + getWidth: function($elm) { + return this.getOffset($elm); + }, + handleEvents: function() { + return !this.disabled && this.isCSSOn(); + }, + handleItemEvents: function($a) { + return this.handleEvents() && !this.isLinkInMegaMenu($a); + }, + isCollapsible: function() { + return this.$firstSub.css('position') == 'static'; + }, + isCSSOn: function() { + return this.$firstLink.css('display') != 'inline'; + }, + isFixed: function() { + var isFixed = this.$root.css('position') == 'fixed'; + if (!isFixed) { + this.$root.parentsUntil('body').each(function() { + if ($(this).css('position') == 'fixed') { + isFixed = true; + return false; + } + }); + } + return isFixed; + }, + isLinkInMegaMenu: function($a) { + return $(this.getClosestMenu($a[0])).hasClass('mega-menu'); + }, + isTouchMode: function() { + return !mouse || this.opts.noMouseOver || this.isCollapsible(); + }, + itemActivate: function($a, hideDeeperSubs) { + var $ul = $a.closest('ul'), + level = $ul.dataSM('level'); + // if for some reason the parent item is not activated (e.g. this is an API call to activate the item), activate all parent items first + if (level > 1 && (!this.activatedItems[level - 2] || this.activatedItems[level - 2][0] != $ul.dataSM('parent-a')[0])) { + var self = this; + $($ul.parentsUntil('[data-smartmenus-id]', 'ul').get().reverse()).add($ul).each(function() { + self.itemActivate($(this).dataSM('parent-a')); + }); + } + // hide any visible deeper level sub menus + if (!this.isCollapsible() || hideDeeperSubs) { + this.menuHideSubMenus(!this.activatedItems[level - 1] || this.activatedItems[level - 1][0] != $a[0] ? level - 1 : level); + } + // save new active item for this level + this.activatedItems[level - 1] = $a; + if (this.$root.triggerHandler('activate.smapi', $a[0]) === false) { + return; + } + // show the sub menu if this item has one + var $sub = $a.dataSM('sub'); + if ($sub && (this.isTouchMode() || (!this.opts.showOnClick || this.clickActivated))) { + this.menuShow($sub); + } + }, + itemBlur: function(e) { + var $a = $(e.currentTarget); + if (!this.handleItemEvents($a)) { + return; + } + this.$root.triggerHandler('blur.smapi', $a[0]); + }, + itemClick: function(e) { + var $a = $(e.currentTarget); + if (!this.handleItemEvents($a)) { + return; + } + if (this.$touchScrollingSub && this.$touchScrollingSub[0] == $a.closest('ul')[0]) { + this.$touchScrollingSub = null; + e.stopPropagation(); + return false; + } + if (this.$root.triggerHandler('click.smapi', $a[0]) === false) { + return false; + } + var subArrowClicked = $(e.target).is('.sub-arrow'), + $sub = $a.dataSM('sub'), + firstLevelSub = $sub ? $sub.dataSM('level') == 2 : false, + collapsible = this.isCollapsible(), + behaviorToggle = /toggle$/.test(this.opts.collapsibleBehavior), + behaviorLink = /link$/.test(this.opts.collapsibleBehavior), + behaviorAccordion = /^accordion/.test(this.opts.collapsibleBehavior); + // if the sub is hidden, try to show it + if ($sub && !$sub.is(':visible')) { + if (!behaviorLink || !collapsible || subArrowClicked) { + if (this.opts.showOnClick && firstLevelSub) { + this.clickActivated = true; + } + // try to activate the item and show the sub + this.itemActivate($a, behaviorAccordion); + // if "itemActivate" showed the sub, prevent the click so that the link is not loaded + // if it couldn't show it, then the sub menus are disabled with an !important declaration (e.g. via mobile styles) so let the link get loaded + if ($sub.is(':visible')) { + this.focusActivated = true; + return false; + } + } + // if the sub is visible and we are in collapsible mode + } else if (collapsible && (behaviorToggle || subArrowClicked)) { + this.itemActivate($a, behaviorAccordion); + this.menuHide($sub); + if (behaviorToggle) { + this.focusActivated = false; + } + return false; + } + if (this.opts.showOnClick && firstLevelSub || $a.hasClass('disabled') || this.$root.triggerHandler('select.smapi', $a[0]) === false) { + return false; + } + }, + itemDown: function(e) { + var $a = $(e.currentTarget); + if (!this.handleItemEvents($a)) { + return; + } + $a.dataSM('mousedown', true); + }, + itemEnter: function(e) { + var $a = $(e.currentTarget); + if (!this.handleItemEvents($a)) { + return; + } + if (!this.isTouchMode()) { + if (this.showTimeout) { + clearTimeout(this.showTimeout); + this.showTimeout = 0; + } + var self = this; + this.showTimeout = setTimeout(function() { self.itemActivate($a); }, this.opts.showOnClick && $a.closest('ul').dataSM('level') == 1 ? 1 : this.opts.showTimeout); + } + this.$root.triggerHandler('mouseenter.smapi', $a[0]); + }, + itemFocus: function(e) { + var $a = $(e.currentTarget); + if (!this.handleItemEvents($a)) { + return; + } + // fix (the mousedown check): in some browsers a tap/click produces consecutive focus + click events so we don't need to activate the item on focus + if (this.focusActivated && (!this.isTouchMode() || !$a.dataSM('mousedown')) && (!this.activatedItems.length || this.activatedItems[this.activatedItems.length - 1][0] != $a[0])) { + this.itemActivate($a, true); + } + this.$root.triggerHandler('focus.smapi', $a[0]); + }, + itemLeave: function(e) { + var $a = $(e.currentTarget); + if (!this.handleItemEvents($a)) { + return; + } + if (!this.isTouchMode()) { + $a[0].blur(); + if (this.showTimeout) { + clearTimeout(this.showTimeout); + this.showTimeout = 0; + } + } + $a.removeDataSM('mousedown'); + this.$root.triggerHandler('mouseleave.smapi', $a[0]); + }, + menuHide: function($sub) { + if (this.$root.triggerHandler('beforehide.smapi', $sub[0]) === false) { + return; + } + if (canAnimate) { + $sub.stop(true, true); + } + if ($sub.css('display') != 'none') { + var complete = function() { + // unset z-index + $sub.css('z-index', ''); + }; + // if sub is collapsible (mobile view) + if (this.isCollapsible()) { + if (canAnimate && this.opts.collapsibleHideFunction) { + this.opts.collapsibleHideFunction.call(this, $sub, complete); + } else { + $sub.hide(this.opts.collapsibleHideDuration, complete); + } + } else { + if (canAnimate && this.opts.hideFunction) { + this.opts.hideFunction.call(this, $sub, complete); + } else { + $sub.hide(this.opts.hideDuration, complete); + } + } + // deactivate scrolling if it is activated for this sub + if ($sub.dataSM('scroll')) { + this.menuScrollStop($sub); + $sub.css({ 'touch-action': '', '-ms-touch-action': '', '-webkit-transform': '', transform: '' }) + .off('.smartmenus_scroll').removeDataSM('scroll').dataSM('scroll-arrows').hide(); + } + // unhighlight parent item + accessibility + $sub.dataSM('parent-a').removeClass('highlighted').attr('aria-expanded', 'false'); + $sub.attr({ + 'aria-expanded': 'false', + 'aria-hidden': 'true' + }); + var level = $sub.dataSM('level'); + this.activatedItems.splice(level - 1, 1); + this.visibleSubMenus.splice($.inArray($sub, this.visibleSubMenus), 1); + this.$root.triggerHandler('hide.smapi', $sub[0]); + } + }, + menuHideAll: function() { + if (this.showTimeout) { + clearTimeout(this.showTimeout); + this.showTimeout = 0; + } + // hide all subs + // if it's a popup, this.visibleSubMenus[0] is the root UL + var level = this.opts.isPopup ? 1 : 0; + for (var i = this.visibleSubMenus.length - 1; i >= level; i--) { + this.menuHide(this.visibleSubMenus[i]); + } + // hide root if it's popup + if (this.opts.isPopup) { + if (canAnimate) { + this.$root.stop(true, true); + } + if (this.$root.is(':visible')) { + if (canAnimate && this.opts.hideFunction) { + this.opts.hideFunction.call(this, this.$root); + } else { + this.$root.hide(this.opts.hideDuration); + } + } + } + this.activatedItems = []; + this.visibleSubMenus = []; + this.clickActivated = false; + this.focusActivated = false; + // reset z-index increment + this.zIndexInc = 0; + this.$root.triggerHandler('hideAll.smapi'); + }, + menuHideSubMenus: function(level) { + for (var i = this.activatedItems.length - 1; i >= level; i--) { + var $sub = this.activatedItems[i].dataSM('sub'); + if ($sub) { + this.menuHide($sub); + } + } + }, + menuInit: function($ul) { + if (!$ul.dataSM('in-mega')) { + // mark UL's in mega drop downs (if any) so we can neglect them + if ($ul.hasClass('mega-menu')) { + $ul.find('ul').dataSM('in-mega', true); + } + // get level (much faster than, for example, using parentsUntil) + var level = 2, + par = $ul[0]; + while ((par = par.parentNode.parentNode) != this.$root[0]) { + level++; + } + // cache stuff for quick access + var $a = $ul.prevAll('a').eq(-1); + // if the link is nested (e.g. in a heading) + if (!$a.length) { + $a = $ul.prevAll().find('a').eq(-1); + } + $a.addClass('has-submenu').dataSM('sub', $ul); + $ul.dataSM('parent-a', $a) + .dataSM('level', level) + .parent().dataSM('sub', $ul); + // accessibility + var aId = $a.attr('id') || this.accessIdPrefix + (++this.idInc), + ulId = $ul.attr('id') || this.accessIdPrefix + (++this.idInc); + $a.attr({ + id: aId, + 'aria-haspopup': 'true', + 'aria-controls': ulId, + 'aria-expanded': 'false' + }); + $ul.attr({ + id: ulId, + 'role': 'group', + 'aria-hidden': 'true', + 'aria-labelledby': aId, + 'aria-expanded': 'false' + }); + // add sub indicator to parent item + if (this.opts.subIndicators) { + $a[this.opts.subIndicatorsPos](this.$subArrow.clone()); + } + } + }, + menuPosition: function($sub) { + var $a = $sub.dataSM('parent-a'), + $li = $a.closest('li'), + $ul = $li.parent(), + level = $sub.dataSM('level'), + subW = this.getWidth($sub), + subH = this.getHeight($sub), + itemOffset = $a.offset(), + itemX = itemOffset.left, + itemY = itemOffset.top, + itemW = this.getWidth($a), + itemH = this.getHeight($a), + $win = $(window), + winX = $win.scrollLeft(), + winY = $win.scrollTop(), + winW = this.getViewportWidth(), + winH = this.getViewportHeight(), + horizontalParent = $ul.parent().is('[data-sm-horizontal-sub]') || level == 2 && !$ul.hasClass('sm-vertical'), + rightToLeft = this.opts.rightToLeftSubMenus && !$li.is('[data-sm-reverse]') || !this.opts.rightToLeftSubMenus && $li.is('[data-sm-reverse]'), + subOffsetX = level == 2 ? this.opts.mainMenuSubOffsetX : this.opts.subMenusSubOffsetX, + subOffsetY = level == 2 ? this.opts.mainMenuSubOffsetY : this.opts.subMenusSubOffsetY, + x, y; + if (horizontalParent) { + x = rightToLeft ? itemW - subW - subOffsetX : subOffsetX; + y = this.opts.bottomToTopSubMenus ? -subH - subOffsetY : itemH + subOffsetY; + } else { + x = rightToLeft ? subOffsetX - subW : itemW - subOffsetX; + y = this.opts.bottomToTopSubMenus ? itemH - subOffsetY - subH : subOffsetY; + } + if (this.opts.keepInViewport) { + var absX = itemX + x, + absY = itemY + y; + if (rightToLeft && absX < winX) { + x = horizontalParent ? winX - absX + x : itemW - subOffsetX; + } else if (!rightToLeft && absX + subW > winX + winW) { + x = horizontalParent ? winX + winW - subW - absX + x : subOffsetX - subW; + } + if (!horizontalParent) { + if (subH < winH && absY + subH > winY + winH) { + y += winY + winH - subH - absY; + } else if (subH >= winH || absY < winY) { + y += winY - absY; + } + } + // do we need scrolling? + // 0.49 used for better precision when dealing with float values + if (horizontalParent && (absY + subH > winY + winH + 0.49 || absY < winY) || !horizontalParent && subH > winH + 0.49) { + var self = this; + if (!$sub.dataSM('scroll-arrows')) { + $sub.dataSM('scroll-arrows', $([$('<span class="scroll-up"><span class="scroll-up-arrow"></span></span>')[0], $('<span class="scroll-down"><span class="scroll-down-arrow"></span></span>')[0]]) + .on({ + mouseenter: function() { + $sub.dataSM('scroll').up = $(this).hasClass('scroll-up'); + self.menuScroll($sub); + }, + mouseleave: function(e) { + self.menuScrollStop($sub); + self.menuScrollOut($sub, e); + }, + 'mousewheel DOMMouseScroll': function(e) { e.preventDefault(); } + }) + .insertAfter($sub) + ); + } + // bind scroll events and save scroll data for this sub + var eNS = '.smartmenus_scroll'; + $sub.dataSM('scroll', { + y: this.cssTransforms3d ? 0 : y - itemH, + step: 1, + // cache stuff for faster recalcs later + itemH: itemH, + subH: subH, + arrowDownH: this.getHeight($sub.dataSM('scroll-arrows').eq(1)) + }) + .on(getEventsNS({ + 'mouseover': function(e) { self.menuScrollOver($sub, e); }, + 'mouseout': function(e) { self.menuScrollOut($sub, e); }, + 'mousewheel DOMMouseScroll': function(e) { self.menuScrollMousewheel($sub, e); } + }, eNS)) + .dataSM('scroll-arrows').css({ top: 'auto', left: '0', marginLeft: x + (parseInt($sub.css('border-left-width')) || 0), width: subW - (parseInt($sub.css('border-left-width')) || 0) - (parseInt($sub.css('border-right-width')) || 0), zIndex: $sub.css('z-index') }) + .eq(horizontalParent && this.opts.bottomToTopSubMenus ? 0 : 1).show(); + // when a menu tree is fixed positioned we allow scrolling via touch too + // since there is no other way to access such long sub menus if no mouse is present + if (this.isFixed()) { + var events = {}; + events[touchEvents ? 'touchstart touchmove touchend' : 'pointerdown pointermove pointerup MSPointerDown MSPointerMove MSPointerUp'] = function(e) { + self.menuScrollTouch($sub, e); + }; + $sub.css({ 'touch-action': 'none', '-ms-touch-action': 'none' }).on(getEventsNS(events, eNS)); + } + } + } + $sub.css({ top: 'auto', left: '0', marginLeft: x, marginTop: y - itemH }); + }, + menuScroll: function($sub, once, step) { + var data = $sub.dataSM('scroll'), + $arrows = $sub.dataSM('scroll-arrows'), + end = data.up ? data.upEnd : data.downEnd, + diff; + if (!once && data.momentum) { + data.momentum *= 0.92; + diff = data.momentum; + if (diff < 0.5) { + this.menuScrollStop($sub); + return; + } + } else { + diff = step || (once || !this.opts.scrollAccelerate ? this.opts.scrollStep : Math.floor(data.step)); + } + // hide any visible deeper level sub menus + var level = $sub.dataSM('level'); + if (this.activatedItems[level - 1] && this.activatedItems[level - 1].dataSM('sub') && this.activatedItems[level - 1].dataSM('sub').is(':visible')) { + this.menuHideSubMenus(level - 1); + } + data.y = data.up && end <= data.y || !data.up && end >= data.y ? data.y : (Math.abs(end - data.y) > diff ? data.y + (data.up ? diff : -diff) : end); + $sub.css(this.cssTransforms3d ? { '-webkit-transform': 'translate3d(0, ' + data.y + 'px, 0)', transform: 'translate3d(0, ' + data.y + 'px, 0)' } : { marginTop: data.y }); + // show opposite arrow if appropriate + if (mouse && (data.up && data.y > data.downEnd || !data.up && data.y < data.upEnd)) { + $arrows.eq(data.up ? 1 : 0).show(); + } + // if we've reached the end + if (data.y == end) { + if (mouse) { + $arrows.eq(data.up ? 0 : 1).hide(); + } + this.menuScrollStop($sub); + } else if (!once) { + if (this.opts.scrollAccelerate && data.step < this.opts.scrollStep) { + data.step += 0.2; + } + var self = this; + this.scrollTimeout = requestAnimationFrame(function() { self.menuScroll($sub); }); + } + }, + menuScrollMousewheel: function($sub, e) { + if (this.getClosestMenu(e.target) == $sub[0]) { + e = e.originalEvent; + var up = (e.wheelDelta || -e.detail) > 0; + if ($sub.dataSM('scroll-arrows').eq(up ? 0 : 1).is(':visible')) { + $sub.dataSM('scroll').up = up; + this.menuScroll($sub, true); + } + } + e.preventDefault(); + }, + menuScrollOut: function($sub, e) { + if (mouse) { + if (!/^scroll-(up|down)/.test((e.relatedTarget || '').className) && ($sub[0] != e.relatedTarget && !$.contains($sub[0], e.relatedTarget) || this.getClosestMenu(e.relatedTarget) != $sub[0])) { + $sub.dataSM('scroll-arrows').css('visibility', 'hidden'); + } + } + }, + menuScrollOver: function($sub, e) { + if (mouse) { + if (!/^scroll-(up|down)/.test(e.target.className) && this.getClosestMenu(e.target) == $sub[0]) { + this.menuScrollRefreshData($sub); + var data = $sub.dataSM('scroll'), + upEnd = $(window).scrollTop() - $sub.dataSM('parent-a').offset().top - data.itemH; + $sub.dataSM('scroll-arrows').eq(0).css('margin-top', upEnd).end() + .eq(1).css('margin-top', upEnd + this.getViewportHeight() - data.arrowDownH).end() + .css('visibility', 'visible'); + } + } + }, + menuScrollRefreshData: function($sub) { + var data = $sub.dataSM('scroll'), + upEnd = $(window).scrollTop() - $sub.dataSM('parent-a').offset().top - data.itemH; + if (this.cssTransforms3d) { + upEnd = -(parseFloat($sub.css('margin-top')) - upEnd); + } + $.extend(data, { + upEnd: upEnd, + downEnd: upEnd + this.getViewportHeight() - data.subH + }); + }, + menuScrollStop: function($sub) { + if (this.scrollTimeout) { + cancelAnimationFrame(this.scrollTimeout); + this.scrollTimeout = 0; + $sub.dataSM('scroll').step = 1; + return true; + } + }, + menuScrollTouch: function($sub, e) { + e = e.originalEvent; + if (isTouchEvent(e)) { + var touchPoint = this.getTouchPoint(e); + // neglect event if we touched a visible deeper level sub menu + if (this.getClosestMenu(touchPoint.target) == $sub[0]) { + var data = $sub.dataSM('scroll'); + if (/(start|down)$/i.test(e.type)) { + if (this.menuScrollStop($sub)) { + // if we were scrolling, just stop and don't activate any link on the first touch + e.preventDefault(); + this.$touchScrollingSub = $sub; + } else { + this.$touchScrollingSub = null; + } + // update scroll data since the user might have zoomed, etc. + this.menuScrollRefreshData($sub); + // extend it with the touch properties + $.extend(data, { + touchStartY: touchPoint.pageY, + touchStartTime: e.timeStamp + }); + } else if (/move$/i.test(e.type)) { + var prevY = data.touchY !== undefined ? data.touchY : data.touchStartY; + if (prevY !== undefined && prevY != touchPoint.pageY) { + this.$touchScrollingSub = $sub; + var up = prevY < touchPoint.pageY; + // changed direction? reset... + if (data.up !== undefined && data.up != up) { + $.extend(data, { + touchStartY: touchPoint.pageY, + touchStartTime: e.timeStamp + }); + } + $.extend(data, { + up: up, + touchY: touchPoint.pageY + }); + this.menuScroll($sub, true, Math.abs(touchPoint.pageY - prevY)); + } + e.preventDefault(); + } else { // touchend/pointerup + if (data.touchY !== undefined) { + if (data.momentum = Math.pow(Math.abs(touchPoint.pageY - data.touchStartY) / (e.timeStamp - data.touchStartTime), 2) * 15) { + this.menuScrollStop($sub); + this.menuScroll($sub); + e.preventDefault(); + } + delete data.touchY; + } + } + } + } + }, + menuShow: function($sub) { + if (!$sub.dataSM('beforefirstshowfired')) { + $sub.dataSM('beforefirstshowfired', true); + if (this.$root.triggerHandler('beforefirstshow.smapi', $sub[0]) === false) { + return; + } + } + if (this.$root.triggerHandler('beforeshow.smapi', $sub[0]) === false) { + return; + } + $sub.dataSM('shown-before', true); + if (canAnimate) { + $sub.stop(true, true); + } + if (!$sub.is(':visible')) { + // highlight parent item + var $a = $sub.dataSM('parent-a'), + collapsible = this.isCollapsible(); + if (this.opts.keepHighlighted || collapsible) { + $a.addClass('highlighted'); + } + if (collapsible) { + $sub.removeClass('sm-nowrap').css({ zIndex: '', width: 'auto', minWidth: '', maxWidth: '', top: '', left: '', marginLeft: '', marginTop: '' }); + } else { + // set z-index + $sub.css('z-index', this.zIndexInc = (this.zIndexInc || this.getStartZIndex()) + 1); + // min/max-width fix - no way to rely purely on CSS as all UL's are nested + if (this.opts.subMenusMinWidth || this.opts.subMenusMaxWidth) { + $sub.css({ width: 'auto', minWidth: '', maxWidth: '' }).addClass('sm-nowrap'); + if (this.opts.subMenusMinWidth) { + $sub.css('min-width', this.opts.subMenusMinWidth); + } + if (this.opts.subMenusMaxWidth) { + var noMaxWidth = this.getWidth($sub); + $sub.css('max-width', this.opts.subMenusMaxWidth); + if (noMaxWidth > this.getWidth($sub)) { + $sub.removeClass('sm-nowrap').css('width', this.opts.subMenusMaxWidth); + } + } + } + this.menuPosition($sub); + } + var complete = function() { + // fix: "overflow: hidden;" is not reset on animation complete in jQuery < 1.9.0 in Chrome when global "box-sizing: border-box;" is used + $sub.css('overflow', ''); + }; + // if sub is collapsible (mobile view) + if (collapsible) { + if (canAnimate && this.opts.collapsibleShowFunction) { + this.opts.collapsibleShowFunction.call(this, $sub, complete); + } else { + $sub.show(this.opts.collapsibleShowDuration, complete); + } + } else { + if (canAnimate && this.opts.showFunction) { + this.opts.showFunction.call(this, $sub, complete); + } else { + $sub.show(this.opts.showDuration, complete); + } + } + // accessibility + $a.attr('aria-expanded', 'true'); + $sub.attr({ + 'aria-expanded': 'true', + 'aria-hidden': 'false' + }); + // store sub menu in visible array + this.visibleSubMenus.push($sub); + this.$root.triggerHandler('show.smapi', $sub[0]); + } + }, + popupHide: function(noHideTimeout) { + if (this.hideTimeout) { + clearTimeout(this.hideTimeout); + this.hideTimeout = 0; + } + var self = this; + this.hideTimeout = setTimeout(function() { + self.menuHideAll(); + }, noHideTimeout ? 1 : this.opts.hideTimeout); + }, + popupShow: function(left, top) { + if (!this.opts.isPopup) { + alert('SmartMenus jQuery Error:\n\nIf you want to show this menu via the "popupShow" method, set the isPopup:true option.'); + return; + } + if (this.hideTimeout) { + clearTimeout(this.hideTimeout); + this.hideTimeout = 0; + } + this.$root.dataSM('shown-before', true); + if (canAnimate) { + this.$root.stop(true, true); + } + if (!this.$root.is(':visible')) { + this.$root.css({ left: left, top: top }); + // show menu + var self = this, + complete = function() { + self.$root.css('overflow', ''); + }; + if (canAnimate && this.opts.showFunction) { + this.opts.showFunction.call(this, this.$root, complete); + } else { + this.$root.show(this.opts.showDuration, complete); + } + this.visibleSubMenus[0] = this.$root; + } + }, + refresh: function() { + this.destroy(true); + this.init(true); + }, + rootKeyDown: function(e) { + if (!this.handleEvents()) { + return; + } + switch (e.keyCode) { + case 27: // reset on Esc + var $activeTopItem = this.activatedItems[0]; + if ($activeTopItem) { + this.menuHideAll(); + $activeTopItem[0].focus(); + var $sub = $activeTopItem.dataSM('sub'); + if ($sub) { + this.menuHide($sub); + } + } + break; + case 32: // activate item's sub on Space + var $target = $(e.target); + if ($target.is('a') && this.handleItemEvents($target)) { + var $sub = $target.dataSM('sub'); + if ($sub && !$sub.is(':visible')) { + this.itemClick({ currentTarget: e.target }); + e.preventDefault(); + } + } + break; + } + }, + rootOut: function(e) { + if (!this.handleEvents() || this.isTouchMode() || e.target == this.$root[0]) { + return; + } + if (this.hideTimeout) { + clearTimeout(this.hideTimeout); + this.hideTimeout = 0; + } + if (!this.opts.showOnClick || !this.opts.hideOnClick) { + var self = this; + this.hideTimeout = setTimeout(function() { self.menuHideAll(); }, this.opts.hideTimeout); + } + }, + rootOver: function(e) { + if (!this.handleEvents() || this.isTouchMode() || e.target == this.$root[0]) { + return; + } + if (this.hideTimeout) { + clearTimeout(this.hideTimeout); + this.hideTimeout = 0; + } + }, + winResize: function(e) { + if (!this.handleEvents()) { + // we still need to resize the disable overlay if it's visible + if (this.$disableOverlay) { + var pos = this.$root.offset(); + this.$disableOverlay.css({ + top: pos.top, + left: pos.left, + width: this.$root.outerWidth(), + height: this.$root.outerHeight() + }); + } + return; + } + // hide sub menus on resize - on mobile do it only on orientation change + if (!('onorientationchange' in window) || e.type == 'orientationchange') { + var collapsible = this.isCollapsible(); + // if it was collapsible before resize and still is, don't do it + if (!(this.wasCollapsible && collapsible)) { + if (this.activatedItems.length) { + this.activatedItems[this.activatedItems.length - 1][0].blur(); + } + this.menuHideAll(); + } + this.wasCollapsible = collapsible; + } + } + } + }); + + $.fn.dataSM = function(key, val) { + if (val) { + return this.data(key + '_smartmenus', val); + } + return this.data(key + '_smartmenus'); + }; + + $.fn.removeDataSM = function(key) { + return this.removeData(key + '_smartmenus'); + }; + + $.fn.smartmenus = function(options) { + if (typeof options == 'string') { + var args = arguments, + method = options; + Array.prototype.shift.call(args); + return this.each(function() { + var smartmenus = $(this).data('smartmenus'); + if (smartmenus && smartmenus[method]) { + smartmenus[method].apply(smartmenus, args); + } + }); + } + return this.each(function() { + // [data-sm-options] attribute on the root UL + var dataOpts = $(this).data('sm-options') || null; + if (dataOpts) { + try { + dataOpts = eval('(' + dataOpts + ')'); + } catch(e) { + dataOpts = null; + alert('ERROR\n\nSmartMenus jQuery init:\nInvalid "data-sm-options" attribute value syntax.'); + }; + } + new $.SmartMenus(this, $.extend({}, $.fn.smartmenus.defaults, options, dataOpts)); + }); + }; + + // default settings + $.fn.smartmenus.defaults = { + isPopup: false, // is this a popup menu (can be shown via the popupShow/popupHide methods) or a permanent menu bar + mainMenuSubOffsetX: 0, // pixels offset from default position + mainMenuSubOffsetY: 0, // pixels offset from default position + subMenusSubOffsetX: 0, // pixels offset from default position + subMenusSubOffsetY: 0, // pixels offset from default position + subMenusMinWidth: '10em', // min-width for the sub menus (any CSS unit) - if set, the fixed width set in CSS will be ignored + subMenusMaxWidth: '20em', // max-width for the sub menus (any CSS unit) - if set, the fixed width set in CSS will be ignored + subIndicators: true, // create sub menu indicators - creates a SPAN and inserts it in the A + subIndicatorsPos: 'append', // position of the SPAN relative to the menu item content ('append', 'prepend') + subIndicatorsText: '', // [optionally] add text in the SPAN (e.g. '+') (you may want to check the CSS for the sub indicators too) + scrollStep: 30, // pixels step when scrolling long sub menus that do not fit in the viewport height + scrollAccelerate: true, // accelerate scrolling or use a fixed step + showTimeout: 250, // timeout before showing the sub menus + hideTimeout: 500, // timeout before hiding the sub menus + showDuration: 0, // duration for show animation - set to 0 for no animation - matters only if showFunction:null + showFunction: null, // custom function to use when showing a sub menu (the default is the jQuery 'show') + // don't forget to call complete() at the end of whatever you do + // e.g.: function($ul, complete) { $ul.fadeIn(250, complete); } + hideDuration: 0, // duration for hide animation - set to 0 for no animation - matters only if hideFunction:null + hideFunction: function($ul, complete) { $ul.fadeOut(200, complete); }, // custom function to use when hiding a sub menu (the default is the jQuery 'hide') + // don't forget to call complete() at the end of whatever you do + // e.g.: function($ul, complete) { $ul.fadeOut(250, complete); } + collapsibleShowDuration:0, // duration for show animation for collapsible sub menus - matters only if collapsibleShowFunction:null + collapsibleShowFunction:function($ul, complete) { $ul.slideDown(200, complete); }, // custom function to use when showing a collapsible sub menu + // (i.e. when mobile styles are used to make the sub menus collapsible) + collapsibleHideDuration:0, // duration for hide animation for collapsible sub menus - matters only if collapsibleHideFunction:null + collapsibleHideFunction:function($ul, complete) { $ul.slideUp(200, complete); }, // custom function to use when hiding a collapsible sub menu + // (i.e. when mobile styles are used to make the sub menus collapsible) + showOnClick: false, // show the first-level sub menus onclick instead of onmouseover (i.e. mimic desktop app menus) (matters only for mouse input) + hideOnClick: true, // hide the sub menus on click/tap anywhere on the page + noMouseOver: false, // disable sub menus activation onmouseover (i.e. behave like in touch mode - use just mouse clicks) (matters only for mouse input) + keepInViewport: true, // reposition the sub menus if needed to make sure they always appear inside the viewport + keepHighlighted: true, // keep all ancestor items of the current sub menu highlighted (adds the 'highlighted' class to the A's) + markCurrentItem: false, // automatically add the 'current' class to the A element of the item linking to the current URL + markCurrentTree: true, // add the 'current' class also to the A elements of all ancestor items of the current item + rightToLeftSubMenus: false, // right to left display of the sub menus (check the CSS for the sub indicators' position) + bottomToTopSubMenus: false, // bottom to top display of the sub menus + collapsibleBehavior: 'default' // parent items behavior in collapsible (mobile) view ('default', 'toggle', 'link', 'accordion', 'accordion-toggle', 'accordion-link') + // 'default' - first tap on parent item expands sub, second tap loads its link + // 'toggle' - the whole parent item acts just as a toggle button for its sub menu (expands/collapses on each tap) + // 'link' - the parent item acts as a regular item (first tap loads its link), the sub menu can be expanded only via the +/- button + // 'accordion' - like 'default' but on expand also resets any visible sub menus from deeper levels or other branches + // 'accordion-toggle' - like 'toggle' but on expand also resets any visible sub menus from deeper levels or other branches + // 'accordion-link' - like 'link' but on expand also resets any visible sub menus from deeper levels or other branches + }; + + return $; +})); \ No newline at end of file diff --git a/civicrm/bower_components/smartmenus/src/libs/demo-assets/demo.css b/civicrm/bower_components/smartmenus/src/libs/demo-assets/demo.css new file mode 100644 index 0000000000..b5425a5218 --- /dev/null +++ b/civicrm/bower_components/smartmenus/src/libs/demo-assets/demo.css @@ -0,0 +1,209 @@ +/* Import "Lora" font from Google fonts */ +@import url(http://fonts.googleapis.com/css?family=Lora:400,700); + +html, body { + background:#fbf3e8; +} +body { + margin:0; + padding:2em 5px; + font:100% Lora,Georgia,'Times New Roman',Times,serif; + color:#222; +} +#content { + padding:0 5px; +} +#content p a { + word-wrap:break-word; +} +h1, h2, h3 { + font-family:"PT Sans Narrow","Arial Narrow",Arial,Helvetica,sans-serif; + font-weight:bold; + color:#1675A1; +} +h1 { + margin-top:1em; + margin-bottom:0.36em; + font-size:2.26em; +} +h2 { + font-size:1.667em; +} +h2, h3, h4 { + margin-top:0; + margin-bottom:0.416em; +} +p, ul, dl { + margin-bottom:1.5em; + line-height:1.625em; +} +ul { + list-style:circle; + padding-left:1.3em; +} +a { + color:#D23600; + text-decoration:none; +} +a:hover, a:focus, a:active { + color:#980000; +} +small { + font-size:0.8em; +} +#themes { + margin:2.5625em 0 2em 0; + border:1px solid; + border-color:#ebe3d9; + border-color:rgba(0,0,0,0.04); + padding:2.5%; + background:#f4ece1; + background:rgba(0,0,0,0.03); + -moz-border-radius:8px; + -webkit-border-radius:8px; + border-radius:8px; +} +#themes p:last-child { + margin-bottom:0; +} +#themes select { + display:block; + width:100%; + height:24px; + line-height:24px; + background:#fff; +} +#themes label { + margin-left:0.3em; +} +.right-column h2 { + margin-top:0; +} +.right-column h4 { + font-size:1em; + font-weight:normal; +} +dl.docs-terms dt { + margin:0 0 0.5em 0; + font-weight:bold; +} +dl.docs-terms dd { + margin:0 0 1.5em 1.3em; +} +dl.docs-arguments { + margin:0 0 0 1.3em; +} +dl.docs-arguments dt, dl.docs-arguments dd { + margin:0; +} +pre.sh_sourceCode { + border:1px solid; + border-color:#e1ddd8; + border-color:rgba(0,0,0,0.10); + padding:0.5em; + background:#f9f5f0; + background:rgba(255,255,255,0.5); + overflow:auto; + min-width:0; + font:0.89em Consolas,'Lucida Console',Monaco,'Courier New',Courier,monospace; + -moz-border-radius:3px; + -webkit-border-radius:3px; + border-radius:3px; +} +code { + background:#f9f5f0; + background:rgba(255,255,255,0.5); + -moz-border-radius:3px; + -webkit-border-radius:3px; + border-radius:3px; +} +kbd { + /* Thanks to: https://github.com/michaelhue/keyscss */ + display: inline; + display: inline-block; + min-width: 1em; + padding: .2em .3em; + font: normal .85em/1 "Arial Unicode MS", "Lucida Grande", "Lucida Sans Unicode", Arial, Helvetica, sans-serif; + text-align: center; + -moz-border-radius: .3em; + -webkit-border-radius: .3em; + border-radius: .3em; + cursor: default; + -moz-user-select: none; + -webkit-user-select: none; + user-select: none; + background: #555; + background-image:-moz-linear-gradient(top,rgb(70,70,70) 0%,rgb(90,90,90) 100%); + background-image:-webkit-gradient(linear,left top,left bottom,color-stop(0%,rgb(70,70,70)),color-stop(100%,rgb(90,90,90))); + background-image:-webkit-linear-gradient(top,rgb(70,70,70) 0%,rgb(90,90,90) 100%); + background-image:-o-linear-gradient(top,rgb(70,70,70) 0%,rgb(90,90,90) 100%); + background-image:-ms-linear-gradient(top,rgb(70,70,70) 0%,rgb(90,90,90) 100%); + background-image:linear-gradient(top,rgb(70,70,70) 0%,rgb(90,90,90) 100%); + color: #fff; + text-shadow: -1px -1px 0 rgb(70, 70, 70); + -moz-box-shadow: inset 0 0 1px rgb(150, 150, 150), inset 0 -.05em .4em rgb(80, 80, 80), 0 .1em 0 rgb(30, 30, 30), 0 .1em .1em rgba(0, 0, 0, .3); + -webkit-box-shadow: inset 0 0 1px rgb(150, 150, 150), inset 0 -.05em .4em rgb(80, 80, 80), 0 .1em 0 rgb(30, 30, 30), 0 .1em .1em rgba(0, 0, 0, .3); + box-shadow: inset 0 0 1px rgb(150, 150, 150), inset 0 -.05em .4em rgb(80, 80, 80), 0 .1em 0 rgb(30, 30, 30), 0 .1em .1em rgba(0, 0, 0, .3); +} +.pagination { + text-align:center; +} +.pagination a { + margin:1em 0.5em 0 0.5em; + display:inline-block; + border:1px solid #dad3c9; + border-color:rgba(0,0,0,0.10); + padding:0.111em 0.666em; + text-decoration:none; + color:#1675A1; + -moz-border-radius:50px; + -webkit-border-radius:50px; + border-radius:50px; +} +.pagination a:hover, .pagination a:focus, .pagination a:active { + color:#d23600; +} +.gray-button { + display:inline-block; + border:1px solid #dad3c9; + padding:0.111em 0.666em; + text-decoration:none; + background:transparent; + color:#1675A1; + white-space:nowrap; + font-family:inherit; + font-size:1em; + font-weight:bold; + line-height:1.61em; + -moz-border-radius:50px; + -webkit-border-radius:50px; + border-radius:50px; + cursor:pointer; + outline:none; +} +.gray-button:hover, .gray-button:focus, .gray-button:active { + color:#d23600; +} +@media (min-width: 640px) { + body { + padding:2em; + font-size:112.5%; + } + .columns { + overflow:hidden; + } + .left-column, .right-column { + float:left; + width:50%; + } + .right-column { + float:right; + } + #content { + margin:0 24px; + padding:0; + } + #themes { + margin:2.5625em 24px 2em 24px; + } +} \ No newline at end of file diff --git a/civicrm/bower_components/smartmenus/src/libs/demo-assets/readme.txt b/civicrm/bower_components/smartmenus/src/libs/demo-assets/readme.txt new file mode 100644 index 0000000000..c2f006e8a2 --- /dev/null +++ b/civicrm/bower_components/smartmenus/src/libs/demo-assets/readme.txt @@ -0,0 +1,3 @@ +SmartMenus jQuery DOES NOT depend on any file in this folder. + +This folder and its sub folders contain JavaScript and CSS files that are used just for the demo pages' layout and styling. \ No newline at end of file diff --git a/civicrm/bower_components/smartmenus/src/libs/demo-assets/shjs/shjs.css b/civicrm/bower_components/smartmenus/src/libs/demo-assets/shjs/shjs.css new file mode 100644 index 0000000000..9e08d43484 --- /dev/null +++ b/civicrm/bower_components/smartmenus/src/libs/demo-assets/shjs/shjs.css @@ -0,0 +1,110 @@ +pre.sh_sourceCode .sh_keyword { + color: #aa0d91; + font-weight: normal; + font-style: normal; +} +pre.sh_sourceCode .sh_type { + color: #008000; + font-weight: normal; + font-style: normal; +} +pre.sh_sourceCode .sh_string { + color: #c80000; + font-weight: normal; + font-style: normal; +} +pre.sh_sourceCode .sh_regexp { + color: #008000; + font-weight: normal; + font-style: normal; +} +pre.sh_sourceCode .sh_specialchar { + color: #ff00ff; + font-weight: normal; + font-style: normal; +} +pre.sh_sourceCode .sh_comment { + color: #007400; + font-weight: normal; + font-style: normal; +} +pre.sh_sourceCode .sh_number { + color: #3200ff; + font-weight: normal; + font-style: normal; +} +pre.sh_sourceCode .sh_preproc { + color: #008200; + font-weight: normal; + font-style: normal; +} +pre.sh_sourceCode .sh_function { + color: #000000; + font-weight: normal; + font-style: normal; +} +pre.sh_sourceCode .sh_url { + color: #008000; + font-weight: normal; + font-style: normal; +} +pre.sh_sourceCode .sh_date { + color: #000000; + font-weight: bold; + font-style: normal; +} +pre.sh_sourceCode .sh_time { + color: #000000; + font-weight: bold; + font-style: normal; +} +pre.sh_sourceCode .sh_file { + color: #000000; + font-weight: bold; + font-style: normal; +} +pre.sh_sourceCode .sh_ip { + color: #008000; + font-weight: normal; + font-style: normal; +} +pre.sh_sourceCode .sh_name { + color: #008000; + font-weight: normal; + font-style: normal; +} +pre.sh_sourceCode .sh_variable { + color: #000000; + font-weight: bold; + font-style: normal; +} +pre.sh_sourceCode .sh_oldfile { + color: #ff00ff; + font-weight: normal; + font-style: normal; +} +pre.sh_sourceCode .sh_newfile { + color: #008000; + font-weight: normal; + font-style: normal; +} +pre.sh_sourceCode .sh_difflines { + color: #000000; + font-weight: bold; + font-style: normal; +} +pre.sh_sourceCode .sh_selector { + color: #000000; + font-weight: normal; + font-style: normal; +} +pre.sh_sourceCode .sh_property { + color: #c80000; + font-weight: normal; + font-style: normal; +} +pre.sh_sourceCode .sh_value { + color: #3200ff; + font-weight: normal; + font-style: normal; +} \ No newline at end of file diff --git a/civicrm/bower_components/smartmenus/src/libs/demo-assets/shjs/shjs.js b/civicrm/bower_components/smartmenus/src/libs/demo-assets/shjs/shjs.js new file mode 100644 index 0000000000..ecd5bfe872 --- /dev/null +++ b/civicrm/bower_components/smartmenus/src/libs/demo-assets/shjs/shjs.js @@ -0,0 +1,20 @@ +/* Copyright (C) 2007, 2008 gnombat@users.sourceforge.net */ +/* License: http://shjs.sourceforge.net/doc/gplv3.html */ + +if(!this.sh_languages){this.sh_languages={}}var sh_requests={};function sh_isEmailAddress(a){if(/^mailto:/.test(a)){return false}return a.indexOf("@")!==-1}function sh_setHref(b,c,d){var a=d.substring(b[c-2].pos,b[c-1].pos);if(a.length>=2&&a.charAt(0)==="<"&&a.charAt(a.length-1)===">"){a=a.substr(1,a.length-2)}if(sh_isEmailAddress(a)){a="mailto:"+a}b[c-2].node.href=a}function sh_konquerorExec(b){var a=[""];a.index=b.length;a.input=b;return a}function sh_highlightString(B,o){if(/Konqueror/.test(navigator.userAgent)){if(!o.konquered){for(var F=0;F<o.length;F++){for(var H=0;H<o[F].length;H++){var G=o[F][H][0];if(G.source==="$"){G.exec=sh_konquerorExec}}}o.konquered=true}}var N=document.createElement("a");var q=document.createElement("span");var A=[];var j=0;var n=[];var C=0;var k=null;var x=function(i,a){var p=i.length;if(p===0){return}if(!a){var Q=n.length;if(Q!==0){var r=n[Q-1];if(!r[3]){a=r[1]}}}if(k!==a){if(k){A[j++]={pos:C};if(k==="sh_url"){sh_setHref(A,j,B)}}if(a){var P;if(a==="sh_url"){P=N.cloneNode(false)}else{P=q.cloneNode(false)}P.className=a;A[j++]={node:P,pos:C}}}C+=p;k=a};var t=/\r\n|\r|\n/g;t.lastIndex=0;var d=B.length;while(C<d){var v=C;var l;var w;var h=t.exec(B);if(h===null){l=d;w=d}else{l=h.index;w=t.lastIndex}var g=B.substring(v,l);var M=[];for(;;){var I=C-v;var D;var y=n.length;if(y===0){D=0}else{D=n[y-1][2]}var O=o[D];var z=O.length;var m=M[D];if(!m){m=M[D]=[]}var E=null;var u=-1;for(var K=0;K<z;K++){var f;if(K<m.length&&(m[K]===null||I<=m[K].index)){f=m[K]}else{var c=O[K][0];c.lastIndex=I;f=c.exec(g);m[K]=f}if(f!==null&&(E===null||f.index<E.index)){E=f;u=K;if(f.index===I){break}}}if(E===null){x(g.substring(I),null);break}else{if(E.index>I){x(g.substring(I,E.index),null)}var e=O[u];var J=e[1];var b;if(J instanceof Array){for(var L=0;L<J.length;L++){b=E[L+1];x(b,J[L])}}else{b=E[0];x(b,J)}switch(e[2]){case -1:break;case -2:n.pop();break;case -3:n.length=0;break;default:n.push(e);break}}}if(k){A[j++]={pos:C};if(k==="sh_url"){sh_setHref(A,j,B)}k=null}C=w}return A}function sh_getClasses(d){var a=[];var b=d.className;if(b&&b.length>0){var e=b.split(" ");for(var c=0;c<e.length;c++){if(e[c].length>0){a.push(e[c])}}}return a}function sh_addClass(c,a){var d=sh_getClasses(c);for(var b=0;b<d.length;b++){if(a.toLowerCase()===d[b].toLowerCase()){return}}d.push(a);c.className=d.join(" ")}function sh_extractTagsFromNodeList(c,a){var f=c.length;for(var d=0;d<f;d++){var e=c.item(d);switch(e.nodeType){case 1:if(e.nodeName.toLowerCase()==="br"){var b;if(/MSIE/.test(navigator.userAgent)){b="\r"}else{b="\n"}a.text.push(b);a.pos++}else{a.tags.push({node:e.cloneNode(false),pos:a.pos});sh_extractTagsFromNodeList(e.childNodes,a);a.tags.push({pos:a.pos})}break;case 3:case 4:a.text.push(e.data);a.pos+=e.length;break}}}function sh_extractTags(c,b){var a={};a.text=[];a.tags=b;a.pos=0;sh_extractTagsFromNodeList(c.childNodes,a);return a.text.join("")}function sh_mergeTags(d,f){var a=d.length;if(a===0){return f}var c=f.length;if(c===0){return d}var i=[];var e=0;var b=0;while(e<a&&b<c){var h=d[e];var g=f[b];if(h.pos<=g.pos){i.push(h);e++}else{i.push(g);if(f[b+1].pos<=h.pos){b++;i.push(f[b]);b++}else{i.push({pos:h.pos});f[b]={node:g.node.cloneNode(false),pos:h.pos}}}}while(e<a){i.push(d[e]);e++}while(b<c){i.push(f[b]);b++}return i}function sh_insertTags(k,h){var g=document;var l=document.createDocumentFragment();var e=0;var d=k.length;var b=0;var j=h.length;var c=l;while(b<j||e<d){var i;var a;if(e<d){i=k[e];a=i.pos}else{a=j}if(a<=b){if(i.node){var f=i.node;c.appendChild(f);c=f}else{c=c.parentNode}e++}else{c.appendChild(g.createTextNode(h.substring(b,a)));b=a}}return l}function sh_highlightElement(d,g){sh_addClass(d,"sh_sourceCode");var c=[];var e=sh_extractTags(d,c);var f=sh_highlightString(e,g);var b=sh_mergeTags(c,f);var a=sh_insertTags(b,e);while(d.hasChildNodes()){d.removeChild(d.firstChild)}d.appendChild(a)}function sh_getXMLHttpRequest(){if(window.ActiveXObject){return new ActiveXObject("Msxml2.XMLHTTP")}else{if(window.XMLHttpRequest){return new XMLHttpRequest()}}throw"No XMLHttpRequest implementation available"}function sh_load(language,element,prefix,suffix){if(language in sh_requests){sh_requests[language].push(element);return}sh_requests[language]=[element];var request=sh_getXMLHttpRequest();var url=prefix+"sh_"+language+suffix;request.open("GET",url,true);request.onreadystatechange=function(){if(request.readyState===4){try{if(!request.status||request.status===200){eval(request.responseText);var elements=sh_requests[language];for(var i=0;i<elements.length;i++){sh_highlightElement(elements[i],sh_languages[language])}}else{throw"HTTP error: status "+request.status}}finally{request=null}}};request.send(null)}function sh_highlightDocument(g,k){var b=document.getElementsByTagName("pre");for(var e=0;e<b.length;e++){var f=b.item(e);var a=sh_getClasses(f);for(var c=0;c<a.length;c++){var h=a[c].toLowerCase();if(h==="sh_sourcecode"){continue}if(h.substr(0,3)==="sh_"){var d=h.substring(3);if(d in sh_languages){sh_highlightElement(f,sh_languages[d])}else{if(typeof(g)==="string"&&typeof(k)==="string"){sh_load(d,f,g,k)}else{throw'Found <pre> element with class="'+h+'", but no such language exists'}}break}}}}; + + +// JavaScript syntax module +if(!this.sh_languages){this.sh_languages={}}sh_languages.javascript=[[[/\/\/\//g,"sh_comment",1],[/\/\//g,"sh_comment",7],[/\/\*\*/g,"sh_comment",8],[/\/\*/g,"sh_comment",9],[/\b(?:abstract|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|false|final|finally|for|function|goto|if|implements|in|instanceof|interface|native|new|null|private|protected|public|return|static|super|switch|synchronized|throw|throws|this|transient|true|try|typeof|var|volatile|while|with)\b/g,"sh_keyword",-1],[/(\+\+|--|\)|\])(\s*)(\/=?(?![*\/]))/g,["sh_symbol","sh_normal","sh_symbol"],-1],[/(0x[A-Fa-f0-9]+|(?:[\d]*\.)?[\d]+(?:[eE][+-]?[\d]+)?)(\s*)(\/(?![*\/]))/g,["sh_number","sh_normal","sh_symbol"],-1],[/([A-Za-z$_][A-Za-z0-9$_]*\s*)(\/=?(?![*\/]))/g,["sh_normal","sh_symbol"],-1],[/\/(?:\\.|[^*\\\/])(?:\\.|[^\\\/])*\/[gim]*/g,"sh_regexp",-1],[/\b[+-]?(?:(?:0x[A-Fa-f0-9]+)|(?:(?:[\d]*\.)?[\d]+(?:[eE][+-]?[\d]+)?))u?(?:(?:int(?:8|16|32|64))|L)?\b/g,"sh_number",-1],[/"/g,"sh_string",10],[/'/g,"sh_string",11],[/~|!|%|\^|\*|\(|\)|-|\+|=|\[|\]|\\|:|;|,|\.|\/|\?|&|<|>|\|/g,"sh_symbol",-1],[/\{|\}/g,"sh_cbracket",-1],[/\b(?:Math|Infinity|NaN|undefined|arguments)\b/g,"sh_predef_var",-1],[/\b(?:Array|Boolean|Date|Error|EvalError|Function|Number|Object|RangeError|ReferenceError|RegExp|String|SyntaxError|TypeError|URIError|decodeURI|decodeURIComponent|encodeURI|encodeURIComponent|eval|isFinite|isNaN|parseFloat|parseInt)\b/g,"sh_predef_func",-1],[/\b(?:applicationCache|closed|Components|content|controllers|crypto|defaultStatus|dialogArguments|directories|document|frameElement|frames|fullScreen|globalStorage|history|innerHeight|innerWidth|length|location|locationbar|menubar|name|navigator|opener|outerHeight|outerWidth|pageXOffset|pageYOffset|parent|personalbar|pkcs11|returnValue|screen|availTop|availLeft|availHeight|availWidth|colorDepth|height|left|pixelDepth|top|width|screenX|screenY|scrollbars|scrollMaxX|scrollMaxY|scrollX|scrollY|self|sessionStorage|sidebar|status|statusbar|toolbar|top|window)\b/g,"sh_predef_var",-1],[/\b(?:alert|addEventListener|atob|back|blur|btoa|captureEvents|clearInterval|clearTimeout|close|confirm|dump|escape|find|focus|forward|getAttention|getComputedStyle|getSelection|home|moveBy|moveTo|open|openDialog|postMessage|print|prompt|releaseEvents|removeEventListener|resizeBy|resizeTo|scroll|scrollBy|scrollByLines|scrollByPages|scrollTo|setInterval|setTimeout|showModalDialog|sizeToContent|stop|unescape|updateCommands|onabort|onbeforeunload|onblur|onchange|onclick|onclose|oncontextmenu|ondragdrop|onerror|onfocus|onkeydown|onkeypress|onkeyup|onload|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|onpaint|onreset|onresize|onscroll|onselect|onsubmit|onunload)\b/g,"sh_predef_func",-1],[/(?:[A-Za-z]|_)[A-Za-z0-9_]*(?=[ \t]*\()/g,"sh_function",-1]],[[/$/g,null,-2],[/(?:<?)[A-Za-z0-9_\.\/\-_~]+@[A-Za-z0-9_\.\/\-_~]+(?:>?)|(?:<?)[A-Za-z0-9_]+:\/\/[A-Za-z0-9_\.\/\-_~]+(?:>?)/g,"sh_url",-1],[/<\?xml/g,"sh_preproc",2,1],[/<!DOCTYPE/g,"sh_preproc",4,1],[/<!--/g,"sh_comment",5],[/<(?:\/)?[A-Za-z](?:[A-Za-z0-9_:.-]*)(?:\/)?>/g,"sh_keyword",-1],[/<(?:\/)?[A-Za-z](?:[A-Za-z0-9_:.-]*)/g,"sh_keyword",6,1],[/&(?:[A-Za-z0-9]+);/g,"sh_preproc",-1],[/<(?:\/)?[A-Za-z][A-Za-z0-9]*(?:\/)?>/g,"sh_keyword",-1],[/<(?:\/)?[A-Za-z][A-Za-z0-9]*/g,"sh_keyword",6,1],[/@[A-Za-z]+/g,"sh_type",-1],[/(?:TODO|FIXME|BUG)(?:[:]?)/g,"sh_todo",-1]],[[/\?>/g,"sh_preproc",-2],[/([^=" \t>]+)([ \t]*)(=?)/g,["sh_type","sh_normal","sh_symbol"],-1],[/"/g,"sh_string",3]],[[/\\(?:\\|")/g,null,-1],[/"/g,"sh_string",-2]],[[/>/g,"sh_preproc",-2],[/([^=" \t>]+)([ \t]*)(=?)/g,["sh_type","sh_normal","sh_symbol"],-1],[/"/g,"sh_string",3]],[[/-->/g,"sh_comment",-2],[/<!--/g,"sh_comment",5]],[[/(?:\/)?>/g,"sh_keyword",-2],[/([^=" \t>]+)([ \t]*)(=?)/g,["sh_type","sh_normal","sh_symbol"],-1],[/"/g,"sh_string",3]],[[/$/g,null,-2]],[[/\*\//g,"sh_comment",-2],[/(?:<?)[A-Za-z0-9_\.\/\-_~]+@[A-Za-z0-9_\.\/\-_~]+(?:>?)|(?:<?)[A-Za-z0-9_]+:\/\/[A-Za-z0-9_\.\/\-_~]+(?:>?)/g,"sh_url",-1],[/<\?xml/g,"sh_preproc",2,1],[/<!DOCTYPE/g,"sh_preproc",4,1],[/<!--/g,"sh_comment",5],[/<(?:\/)?[A-Za-z](?:[A-Za-z0-9_:.-]*)(?:\/)?>/g,"sh_keyword",-1],[/<(?:\/)?[A-Za-z](?:[A-Za-z0-9_:.-]*)/g,"sh_keyword",6,1],[/&(?:[A-Za-z0-9]+);/g,"sh_preproc",-1],[/<(?:\/)?[A-Za-z][A-Za-z0-9]*(?:\/)?>/g,"sh_keyword",-1],[/<(?:\/)?[A-Za-z][A-Za-z0-9]*/g,"sh_keyword",6,1],[/@[A-Za-z]+/g,"sh_type",-1],[/(?:TODO|FIXME|BUG)(?:[:]?)/g,"sh_todo",-1]],[[/\*\//g,"sh_comment",-2],[/(?:<?)[A-Za-z0-9_\.\/\-_~]+@[A-Za-z0-9_\.\/\-_~]+(?:>?)|(?:<?)[A-Za-z0-9_]+:\/\/[A-Za-z0-9_\.\/\-_~]+(?:>?)/g,"sh_url",-1],[/(?:TODO|FIXME|BUG)(?:[:]?)/g,"sh_todo",-1]],[[/"/g,"sh_string",-2],[/\\./g,"sh_specialchar",-1]],[[/'/g,"sh_string",-2],[/\\./g,"sh_specialchar",-1]]]; + + +// CSS syntax module +if(!this.sh_languages){this.sh_languages={}}sh_languages.css=[[[/\/\/\//g,"sh_comment",1],[/\/\//g,"sh_comment",7],[/\/\*\*/g,"sh_comment",8],[/\/\*/g,"sh_comment",9],[/(?:\.|#)[A-Za-z0-9_]+/g,"sh_selector",-1],[/\{/g,"sh_cbracket",10,1],[/~|!|%|\^|\*|\(|\)|-|\+|=|\[|\]|\\|:|;|,|\.|\/|\?|&|<|>|\|/g,"sh_symbol",-1]],[[/$/g,null,-2],[/(?:<?)[A-Za-z0-9_\.\/\-_~]+@[A-Za-z0-9_\.\/\-_~]+(?:>?)|(?:<?)[A-Za-z0-9_]+:\/\/[A-Za-z0-9_\.\/\-_~]+(?:>?)/g,"sh_url",-1],[/<\?xml/g,"sh_preproc",2,1],[/<!DOCTYPE/g,"sh_preproc",4,1],[/<!--/g,"sh_comment",5],[/<(?:\/)?[A-Za-z](?:[A-Za-z0-9_:.-]*)(?:\/)?>/g,"sh_keyword",-1],[/<(?:\/)?[A-Za-z](?:[A-Za-z0-9_:.-]*)/g,"sh_keyword",6,1],[/&(?:[A-Za-z0-9]+);/g,"sh_preproc",-1],[/<(?:\/)?[A-Za-z][A-Za-z0-9]*(?:\/)?>/g,"sh_keyword",-1],[/<(?:\/)?[A-Za-z][A-Za-z0-9]*/g,"sh_keyword",6,1],[/@[A-Za-z]+/g,"sh_type",-1],[/(?:TODO|FIXME|BUG)(?:[:]?)/g,"sh_todo",-1]],[[/\?>/g,"sh_preproc",-2],[/([^=" \t>]+)([ \t]*)(=?)/g,["sh_type","sh_normal","sh_symbol"],-1],[/"/g,"sh_string",3]],[[/\\(?:\\|")/g,null,-1],[/"/g,"sh_string",-2]],[[/>/g,"sh_preproc",-2],[/([^=" \t>]+)([ \t]*)(=?)/g,["sh_type","sh_normal","sh_symbol"],-1],[/"/g,"sh_string",3]],[[/-->/g,"sh_comment",-2],[/<!--/g,"sh_comment",5]],[[/(?:\/)?>/g,"sh_keyword",-2],[/([^=" \t>]+)([ \t]*)(=?)/g,["sh_type","sh_normal","sh_symbol"],-1],[/"/g,"sh_string",3]],[[/$/g,null,-2]],[[/\*\//g,"sh_comment",-2],[/(?:<?)[A-Za-z0-9_\.\/\-_~]+@[A-Za-z0-9_\.\/\-_~]+(?:>?)|(?:<?)[A-Za-z0-9_]+:\/\/[A-Za-z0-9_\.\/\-_~]+(?:>?)/g,"sh_url",-1],[/<\?xml/g,"sh_preproc",2,1],[/<!DOCTYPE/g,"sh_preproc",4,1],[/<!--/g,"sh_comment",5],[/<(?:\/)?[A-Za-z](?:[A-Za-z0-9_:.-]*)(?:\/)?>/g,"sh_keyword",-1],[/<(?:\/)?[A-Za-z](?:[A-Za-z0-9_:.-]*)/g,"sh_keyword",6,1],[/&(?:[A-Za-z0-9]+);/g,"sh_preproc",-1],[/<(?:\/)?[A-Za-z][A-Za-z0-9]*(?:\/)?>/g,"sh_keyword",-1],[/<(?:\/)?[A-Za-z][A-Za-z0-9]*/g,"sh_keyword",6,1],[/@[A-Za-z]+/g,"sh_type",-1],[/(?:TODO|FIXME|BUG)(?:[:]?)/g,"sh_todo",-1]],[[/\*\//g,"sh_comment",-2],[/(?:<?)[A-Za-z0-9_\.\/\-_~]+@[A-Za-z0-9_\.\/\-_~]+(?:>?)|(?:<?)[A-Za-z0-9_]+:\/\/[A-Za-z0-9_\.\/\-_~]+(?:>?)/g,"sh_url",-1],[/(?:TODO|FIXME|BUG)(?:[:]?)/g,"sh_todo",-1]],[[/\}/g,"sh_cbracket",-2],[/\/\/\//g,"sh_comment",1],[/\/\//g,"sh_comment",7],[/\/\*\*/g,"sh_comment",8],[/\/\*/g,"sh_comment",9],[/[A-Za-z0-9_-]+[ \t]*:/g,"sh_property",-1],[/[.%A-Za-z0-9_-]+/g,"sh_value",-1],[/#(?:[A-Za-z0-9_]+)/g,"sh_string",-1]]]; + + +// PHP syntax module +if(!this.sh_languages){this.sh_languages={}}sh_languages.php=[[[/\b(?:include|include_once|require|require_once)\b/g,"sh_preproc",-1],[/\/\//g,"sh_comment",1],[/#/g,"sh_comment",1],[/\b[+-]?(?:(?:0x[A-Fa-f0-9]+)|(?:(?:[\d]*\.)?[\d]+(?:[eE][+-]?[\d]+)?))u?(?:(?:int(?:8|16|32|64))|L)?\b/g,"sh_number",-1],[/"/g,"sh_string",2],[/'/g,"sh_string",3],[/\b(?:and|or|xor|__FILE__|exception|php_user_filter|__LINE__|array|as|break|case|cfunction|class|const|continue|declare|default|die|do|each|echo|else|elseif|empty|enddeclare|endfor|endforeach|endif|endswitch|endwhile|eval|exit|extends|for|foreach|function|global|if|isset|list|new|old_function|print|return|static|switch|unset|use|var|while|__FUNCTION__|__CLASS__|__METHOD__)\b/g,"sh_keyword",-1],[/\/\/\//g,"sh_comment",4],[/\/\//g,"sh_comment",1],[/\/\*\*/g,"sh_comment",9],[/\/\*/g,"sh_comment",10],[/(?:\$[#]?|@|%)[A-Za-z0-9_]+/g,"sh_variable",-1],[/<\?php|~|!|%|\^|\*|\(|\)|-|\+|=|\[|\]|\\|:|;|,|\.|\/|\?|&|<|>|\|/g,"sh_symbol",-1],[/\{|\}/g,"sh_cbracket",-1],[/(?:[A-Za-z]|_)[A-Za-z0-9_]*(?=[ \t]*\()/g,"sh_function",-1]],[[/$/g,null,-2]],[[/\\(?:\\|")/g,null,-1],[/"/g,"sh_string",-2]],[[/\\(?:\\|')/g,null,-1],[/'/g,"sh_string",-2]],[[/$/g,null,-2],[/(?:<?)[A-Za-z0-9_\.\/\-_~]+@[A-Za-z0-9_\.\/\-_~]+(?:>?)|(?:<?)[A-Za-z0-9_]+:\/\/[A-Za-z0-9_\.\/\-_~]+(?:>?)/g,"sh_url",-1],[/<\?xml/g,"sh_preproc",5,1],[/<!DOCTYPE/g,"sh_preproc",6,1],[/<!--/g,"sh_comment",7],[/<(?:\/)?[A-Za-z](?:[A-Za-z0-9_:.-]*)(?:\/)?>/g,"sh_keyword",-1],[/<(?:\/)?[A-Za-z](?:[A-Za-z0-9_:.-]*)/g,"sh_keyword",8,1],[/&(?:[A-Za-z0-9]+);/g,"sh_preproc",-1],[/<(?:\/)?[A-Za-z][A-Za-z0-9]*(?:\/)?>/g,"sh_keyword",-1],[/<(?:\/)?[A-Za-z][A-Za-z0-9]*/g,"sh_keyword",8,1],[/@[A-Za-z]+/g,"sh_type",-1],[/(?:TODO|FIXME|BUG)(?:[:]?)/g,"sh_todo",-1]],[[/\?>/g,"sh_preproc",-2],[/([^=" \t>]+)([ \t]*)(=?)/g,["sh_type","sh_normal","sh_symbol"],-1],[/"/g,"sh_string",2]],[[/>/g,"sh_preproc",-2],[/([^=" \t>]+)([ \t]*)(=?)/g,["sh_type","sh_normal","sh_symbol"],-1],[/"/g,"sh_string",2]],[[/-->/g,"sh_comment",-2],[/<!--/g,"sh_comment",7]],[[/(?:\/)?>/g,"sh_keyword",-2],[/([^=" \t>]+)([ \t]*)(=?)/g,["sh_type","sh_normal","sh_symbol"],-1],[/"/g,"sh_string",2]],[[/\*\//g,"sh_comment",-2],[/(?:<?)[A-Za-z0-9_\.\/\-_~]+@[A-Za-z0-9_\.\/\-_~]+(?:>?)|(?:<?)[A-Za-z0-9_]+:\/\/[A-Za-z0-9_\.\/\-_~]+(?:>?)/g,"sh_url",-1],[/<\?xml/g,"sh_preproc",5,1],[/<!DOCTYPE/g,"sh_preproc",6,1],[/<!--/g,"sh_comment",7],[/<(?:\/)?[A-Za-z](?:[A-Za-z0-9_:.-]*)(?:\/)?>/g,"sh_keyword",-1],[/<(?:\/)?[A-Za-z](?:[A-Za-z0-9_:.-]*)/g,"sh_keyword",8,1],[/&(?:[A-Za-z0-9]+);/g,"sh_preproc",-1],[/<(?:\/)?[A-Za-z][A-Za-z0-9]*(?:\/)?>/g,"sh_keyword",-1],[/<(?:\/)?[A-Za-z][A-Za-z0-9]*/g,"sh_keyword",8,1],[/@[A-Za-z]+/g,"sh_type",-1],[/(?:TODO|FIXME|BUG)(?:[:]?)/g,"sh_todo",-1]],[[/\*\//g,"sh_comment",-2],[/(?:<?)[A-Za-z0-9_\.\/\-_~]+@[A-Za-z0-9_\.\/\-_~]+(?:>?)|(?:<?)[A-Za-z0-9_]+:\/\/[A-Za-z0-9_\.\/\-_~]+(?:>?)/g,"sh_url",-1],[/(?:TODO|FIXME|BUG)(?:[:]?)/g,"sh_todo",-1]]]; + + +// HTML syntax module +if(!this.sh_languages){this.sh_languages={}}sh_languages.html=[[[/<\?xml/g,"sh_preproc",1,1],[/<!DOCTYPE/g,"sh_preproc",3,1],[/<!--/g,"sh_comment",4],[/<(?:\/)?[A-Za-z](?:[A-Za-z0-9_:.-]*)(?:\/)?>/g,"sh_keyword",-1],[/<(?:\/)?[A-Za-z](?:[A-Za-z0-9_:.-]*)/g,"sh_keyword",5,1],[/&(?:[A-Za-z0-9]+);/g,"sh_preproc",-1],[/<(?:\/)?[A-Za-z][A-Za-z0-9]*(?:\/)?>/g,"sh_keyword",-1],[/<(?:\/)?[A-Za-z][A-Za-z0-9]*/g,"sh_keyword",5,1]],[[/\?>/g,"sh_preproc",-2],[/([^=" \t>]+)([ \t]*)(=?)/g,["sh_type","sh_normal","sh_symbol"],-1],[/"/g,"sh_string",2]],[[/\\(?:\\|")/g,null,-1],[/"/g,"sh_string",-2]],[[/>/g,"sh_preproc",-2],[/([^=" \t>]+)([ \t]*)(=?)/g,["sh_type","sh_normal","sh_symbol"],-1],[/"/g,"sh_string",2]],[[/-->/g,"sh_comment",-2],[/<!--/g,"sh_comment",4]],[[/(?:\/)?>/g,"sh_keyword",-2],[/([^=" \t>]+)([ \t]*)(=?)/g,["sh_type","sh_normal","sh_symbol"],-1],[/"/g,"sh_string",2]]]; \ No newline at end of file diff --git a/civicrm/bower_components/smartmenus/src/libs/demo-assets/themes-switcher.js b/civicrm/bower_components/smartmenus/src/libs/demo-assets/themes-switcher.js new file mode 100644 index 0000000000..38038bd38d --- /dev/null +++ b/civicrm/bower_components/smartmenus/src/libs/demo-assets/themes-switcher.js @@ -0,0 +1,246 @@ +$(function() { + + var $menu = $('#main-menu'); + + // add the HTML structure + $('div.right-column').prepend('\ + <div id="themes">\ + <h2>Switch theme (class)</h2>\ + <p>\ + <select id="themes-classes">\ +\ +\ + <!-- include new themes by adding a new option below -->\ +\ +\ + <option value="sm-blue" data-page-bg="#fbf3e8" data-codepen-url="http://codepen.io/vadikom/pen/rVMmMm?editors=010" data-init-options="{\n\ + subMenusSubOffsetX: 1,\n\ + subMenusSubOffsetY: -8\n\ + }" data-init-options-vertical="{\n\ + mainMenuSubOffsetX: 1,\n\ + mainMenuSubOffsetY: -8,\n\ + subMenusSubOffsetX: 1,\n\ + subMenusSubOffsetY: -8\n\ + }">sm-blue</option>\ + <option value="sm-clean" data-page-bg="#fcfcfc" data-codepen-url="http://codepen.io/vadikom/pen/Mwjmbb?editors=010" data-init-options="{\n\ + mainMenuSubOffsetX: -1,\n\ + mainMenuSubOffsetY: 4,\n\ + subMenusSubOffsetX: 6,\n\ + subMenusSubOffsetY: -6\n\ + }" data-init-options-vertical="{\n\ + mainMenuSubOffsetX: 6,\n\ + mainMenuSubOffsetY: -6,\n\ + subMenusSubOffsetX: 6,\n\ + subMenusSubOffsetY: -6\n\ + }">sm-clean</option>\ + <option value="sm-mint" data-page-bg="#fff" data-codepen-url="http://codepen.io/vadikom/pen/LVRybm?editors=010" data-init-options="{\n\ + subMenusSubOffsetX: 6,\n\ + subMenusSubOffsetY: -8\n\ + }" data-init-options-vertical="{\n\ + mainMenuSubOffsetX: 6,\n\ + mainMenuSubOffsetY: -8,\n\ + subMenusSubOffsetX: 6,\n\ + subMenusSubOffsetY: -8\n\ + }">sm-mint</option>\ + <option value="sm-simple" data-page-bg="#f6f6f6" data-codepen-url="http://codepen.io/vadikom/pen/OVRmbe?editors=010" data-init-options="{\n\ + mainMenuSubOffsetX: -1,\n\ + subMenusSubOffsetX: 10,\n\ + subMenusSubOffsetY: 0\n\ + }" data-init-options-vertical="{\n\ + mainMenuSubOffsetX: 10,\n\ + mainMenuSubOffsetY: 0,\n\ + subMenusSubOffsetX: 10,\n\ + subMenusSubOffsetY: 0\n\ + }">sm-simple</option>\ + </select>\ + <span style="float:right;"><a id="themes-codepen-url" href="http://codepen.io/vadikom/pen/rVMmMm?editors=010">Customize "<span id="themes-codepen-theme-name">sm-blue</span>" on Codepen</a></span><br />\ + <!--[if lt IE 9]><strong>IE8 note: Changing the following options will not produce proper preview for you due to Respond.js related issues. However, these main menu configurations will work just fine on your live website.</strong><br /><![endif]-->\ + <input id="themes-horizontal-fullwidth" name="themes-orientation" value="horizontal-fullwidth" type="radio" checked="checked" /><label for="themes-horizontal-fullwidth">Horizontal full width main menu</label><br />\ + <span id="themes-horizontal-fullwidth-align-holder" style="display:block;padding-left:1.5em;">\ + <input id="themes-horizontal-fullwidth-align-justified" type="checkbox" /><label for="themes-horizontal-fullwidth-align-justified">justified<small style="display:none;"><br />Note: Some themes may need minor changes like tweaking the main menu sub indicators\' position, etc.</small></label><br />\ + </span>\ + <input id="themes-horizontal" name="themes-orientation" value="horizontal" type="radio" /><label for="themes-horizontal">Horizontal main menu</label><br />\ + <span id="themes-horizontal-align-holder" style="display:block;padding-left:1.5em;">\ + <input id="themes-horizontal-align-left" name="themes-horizontal-align" value="left" type="radio" checked="checked" /><label for="themes-horizontal-align-left">left</label> \ + <input id="themes-horizontal-align-center" name="themes-horizontal-align" value="center" type="radio" /><label for="themes-horizontal-align-center">center</label> \ + <input id="themes-horizontal-align-right" name="themes-horizontal-align" value="right" type="radio" /><label for="themes-horizontal-align-right">right</label><br />\ + </span>\ + <input id="themes-vertical" name="themes-orientation" value="vertical" type="radio" /><label for="themes-vertical">Vertical main menu</label><br />\ + <input id="themes-rtl" type="checkbox" /><label for="themes-rtl" title="Won\'t use real RTL text, just preview the theme">Right-to-left</label><br />\ + </p>\ + <h3>Source code</h3>\ + <h4>CSS:</h4>\ + <pre class="sh_html sh_sourceCode"><!-- SmartMenus core CSS (required) -->\n\ +<link href="../css/sm-core-css.css" rel="stylesheet" type="text/css" />\n\ +\n\ +<!-- "<span class="themes-code-class">sm-blue</span>" menu theme (optional, you can use your own CSS, too) -->\n\ +<link href="../css/<span class="themes-code-class">sm-blue</span>/<span class="themes-code-class">sm-blue</span>.css" rel="stylesheet" type="text/css" />\ +<span class="themes-code-main-menu-css-holder" style="display:none;">\n\n\ +<!-- #main-menu config - instance specific stuff not covered in the theme -->\n\ +<!-- You could put this in an external stylesheet (e.g. where the rest of your page styles are) -->\n\ +<style type="text/css">\n<span class="themes-code-main-menu-css"></span></style>\ +</span></pre>\ + <h4>HTML:</h4>\ + <pre class="sh_html sh_sourceCode">' + (window.addonHTMLBefore ? window.addonHTMLBefore : '') + '\<nav id="main-nav">\n\ + <ul id="main-menu" class="<span class="themes-code-main-class">' + $menu[0].className + '</span>">\n\ + ...\n\ + </ul>\n\ +</nav>' + (window.addonHTMLAfter ? window.addonHTMLAfter : '') + '</pre>\ + <h4>JavaScript:</h4>\ + <pre class="sh_html sh_sourceCode"><!-- jQuery -->\n\ +<script type="text/javascript" src="../libs/jquery/jquery.js"></script>\n\ +\n\ +<!-- SmartMenus jQuery plugin -->\n\ +<script type="text/javascript" src="../jquery.smartmenus.js"></script>\n' + (window.addonScriptSrc ? $.map(window.addonScriptSrc, function(arr) { + return '\n<!-- ' + arr[0] + ' -->\n<script type="text/javascript" src="' + arr[1] + '"></script>\n'; +}).join('') : '') + '\ +\n\ +<!-- SmartMenus jQuery init -->\n\ +<script type="text/javascript">\n\ + $(function() {\n\ + $(\'#main-menu\').smartmenus(<span class="themes-code-init-options">{\n\ + subMenusSubOffsetX: 1,\n\ + subMenusSubOffsetY: -8\n\ + }</span>);\n' + (window.addonScriptInit ? window.addonScriptInit : '') + '\ + });\n\ +</script></pre>\ + </div>\ +'); + + // hide sub options + $('#themes-horizontal-align-holder').hide(); + + // load additional themes + $('#themes-classes option').not(':first').each(function() { + var className = $(this).attr('value'); + $('<link href="../css/' + className + '/' + className + '.css" rel="stylesheet" type="text/css" />').appendTo('head'); + }); + + // update Respond.js to parse all themes loaded dynamically + if (window.respond) { + respond.update(); + } + + // define the styles for the different main menu configurations + var mainMenuConfigs = { + horizontalLeft: ' @media (min-width: 768px) {\n\ + #main-nav {\n\ + line-height: 0;\n\ + text-align: left;\n\ + }\n\ + #main-menu {\n\ + display: inline-block;\n\ + }\n\ + }\n', + horizontalCenter: ' @media (min-width: 768px) {\n\ + #main-nav {\n\ + line-height: 0;\n\ + text-align: center;\n\ + }\n\ + #main-menu {\n\ + display: inline-block;\n\ + }\n\ + }\n', + horizontalRight: ' @media (min-width: 768px) {\n\ + #main-nav {\n\ + line-height: 0;\n\ + text-align: right;\n\ + }\n\ + #main-menu {\n\ + display: inline-block;\n\ + }\n\ + }\n', + horizontalFullwidthLeft: '', + horizontalFullwidthJustified: ' @media (min-width: 768px) {\n\ + #main-menu > li {\n\ + float: none;\n\ + display: table-cell;\n\ + width: 1%;\n\ + text-align: center;\n\ + }\n\ + }\n', + vertical: ' @media (min-width: 768px) {\n\ + #main-menu {\n\ + float: left;\n\ + width: 12em;\n\ + }\n\ + }\n', + verticalRTL: ' @media (min-width: 768px) {\n\ + #main-menu {\n\ + float: right;\n\ + width: 12em;\n\ + }\n\ + }\n' + }; + + // hook theme switcher + $('#themes-classes, #themes-horizontal, #themes-horizontal-align-left, #themes-horizontal-align-center, #themes-horizontal-align-right, #themes-horizontal-fullwidth, #themes-horizontal-fullwidth-align-justified, #themes-vertical, #themes-rtl').change(function() { + var $select = $('#themes-classes'), + $mainMenuCSS = $('#main-menu-css'), + mainMenuCSS, + className = $select.val(), + horizontal = $('#themes-horizontal')[0].checked, + horizontalLeft = horizontal && $('#themes-horizontal-align-left')[0].checked, + horizontalCenter = horizontal && $('#themes-horizontal-align-center')[0].checked, + horizontalRight = horizontal && $('#themes-horizontal-align-right')[0].checked, + horizontalFullwidth = $('#themes-horizontal-fullwidth')[0].checked, + horizontalFullwidthLeft = horizontalFullwidth && !$('#themes-horizontal-fullwidth-align-justified')[0].checked, + horizontalFullwidthJustified = horizontalFullwidth && $('#themes-horizontal-fullwidth-align-justified')[0].checked, + vertical = $('#themes-vertical')[0].checked, + rtl = $('#themes-rtl')[0].checked, + $optionElm = $select.children().eq($select[0].selectedIndex), + initOptions = $optionElm.data('init-options' + (vertical ? '-vertical' : '')), + mainMenuClass = 'sm ' + (rtl ? 'sm-rtl ' : '') + (vertical ? 'sm-vertical ' : '') + className; + + if ($mainMenuCSS.length) { + $mainMenuCSS.remove(); + $mainMenuCSS = null; + } else { + // remove the inline style on init + $('style').eq(0).remove(); + } + mainMenuCSS = (horizontalLeft ? mainMenuConfigs['horizontalLeft'] : + horizontalCenter ? mainMenuConfigs['horizontalCenter'] : + horizontalRight ? mainMenuConfigs['horizontalRight'] : + horizontalFullwidthLeft ? mainMenuConfigs['horizontalFullwidthLeft'] : + horizontalFullwidthJustified ? mainMenuConfigs['horizontalFullwidthJustified'] : + // vertical + !rtl ? mainMenuConfigs['vertical'] : mainMenuConfigs['verticalRTL']); + $('<style id="main-menu-css">' + mainMenuCSS + '</style>').appendTo('head'); + + // show/hide sub options + $('#themes-horizontal-align-holder')[horizontal ? 'slideDown' : 'slideUp'](250); + $('#themes-horizontal-fullwidth-align-holder')[horizontalFullwidth ? 'slideDown' : 'slideUp'](250); + + // switch #main-menu theme + $menu.smartmenus('destroy')[0].className = mainMenuClass; + $menu.smartmenus(eval('(' + initOptions + ')')); + $('html, body').css('background', $optionElm.data('page-bg')); + + // update code samples + $('span.themes-code-class span, #themes-codepen-theme-name').text(className); + $('#themes-codepen-url').attr('href', $optionElm.data('codepen-url')); + $('span.themes-code-main-class span').text(mainMenuClass); + $('span.themes-code-main-menu-css').text(mainMenuCSS); + $('span.themes-code-main-menu-css-holder')[mainMenuCSS ? 'show' : 'hide'](); + $('span.themes-code-init-options').text(initOptions); + + // display horizontal justified note if needed + if ($(this).is('#themes-horizontal-fullwidth-align-justified')) { + $('label[for="themes-horizontal-fullwidth-align-justified"] small')[this.checked ? 'show' : 'hide'](); + } + + // call any addon init code + if (window.addonScriptInit) { + try { eval(window.addonScriptInit); } catch(e) {}; + } + }); + + // init SHJS syntax highlighter + $('<link href="../libs/demo-assets/shjs/shjs.css" rel="stylesheet" type="text/css" />').appendTo('head'); + sh_highlightDocument(); + +}); + +// load SHJS syntax highlighter synchronously +document.write('<scr' + 'ipt type="text/javascript" src="../libs/demo-assets/shjs/shjs.js"></scr' + 'ipt>'); \ No newline at end of file diff --git a/civicrm/bower_components/smartmenus/src/libs/jquery/jquery.js b/civicrm/bower_components/smartmenus/src/libs/jquery/jquery.js new file mode 100644 index 0000000000..b0ecaddee2 --- /dev/null +++ b/civicrm/bower_components/smartmenus/src/libs/jquery/jquery.js @@ -0,0 +1,5 @@ +/*! jQuery v1.12.4 | (c) jQuery Foundation | jquery.org/license */ +!function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=a.document,e=c.slice,f=c.concat,g=c.push,h=c.indexOf,i={},j=i.toString,k=i.hasOwnProperty,l={},m="1.12.4",n=function(a,b){return new n.fn.init(a,b)},o=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,p=/^-ms-/,q=/-([\da-z])/gi,r=function(a,b){return b.toUpperCase()};n.fn=n.prototype={jquery:m,constructor:n,selector:"",length:0,toArray:function(){return e.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:e.call(this)},pushStack:function(a){var b=n.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a){return n.each(this,a)},map:function(a){return this.pushStack(n.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(e.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor()},push:g,sort:c.sort,splice:c.splice},n.extend=n.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||n.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(e=arguments[h]))for(d in e)a=g[d],c=e[d],g!==c&&(j&&c&&(n.isPlainObject(c)||(b=n.isArray(c)))?(b?(b=!1,f=a&&n.isArray(a)?a:[]):f=a&&n.isPlainObject(a)?a:{},g[d]=n.extend(j,f,c)):void 0!==c&&(g[d]=c));return g},n.extend({expando:"jQuery"+(m+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===n.type(a)},isArray:Array.isArray||function(a){return"array"===n.type(a)},isWindow:function(a){return null!=a&&a==a.window},isNumeric:function(a){var b=a&&a.toString();return!n.isArray(a)&&b-parseFloat(b)+1>=0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},isPlainObject:function(a){var b;if(!a||"object"!==n.type(a)||a.nodeType||n.isWindow(a))return!1;try{if(a.constructor&&!k.call(a,"constructor")&&!k.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}if(!l.ownFirst)for(b in a)return k.call(a,b);for(b in a);return void 0===b||k.call(a,b)},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?i[j.call(a)]||"object":typeof a},globalEval:function(b){b&&n.trim(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(p,"ms-").replace(q,r)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b){var c,d=0;if(s(a)){for(c=a.length;c>d;d++)if(b.call(a[d],d,a[d])===!1)break}else for(d in a)if(b.call(a[d],d,a[d])===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(o,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(s(Object(a))?n.merge(c,"string"==typeof a?[a]:a):g.call(c,a)),c},inArray:function(a,b,c){var d;if(b){if(h)return h.call(b,a,c);for(d=b.length,c=c?0>c?Math.max(0,d+c):c:0;d>c;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,b){var c=+b.length,d=0,e=a.length;while(c>d)a[e++]=b[d++];if(c!==c)while(void 0!==b[d])a[e++]=b[d++];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,e,g=0,h=[];if(s(a))for(d=a.length;d>g;g++)e=b(a[g],g,c),null!=e&&h.push(e);else for(g in a)e=b(a[g],g,c),null!=e&&h.push(e);return f.apply([],h)},guid:1,proxy:function(a,b){var c,d,f;return"string"==typeof b&&(f=a[b],b=a,a=f),n.isFunction(a)?(c=e.call(arguments,2),d=function(){return a.apply(b||this,c.concat(e.call(arguments)))},d.guid=a.guid=a.guid||n.guid++,d):void 0},now:function(){return+new Date},support:l}),"function"==typeof Symbol&&(n.fn[Symbol.iterator]=c[Symbol.iterator]),n.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),function(a,b){i["[object "+b+"]"]=b.toLowerCase()});function s(a){var b=!!a&&"length"in a&&a.length,c=n.type(a);return"function"===c||n.isWindow(a)?!1:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var t=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+1*new Date,v=a.document,w=0,x=0,y=ga(),z=ga(),A=ga(),B=function(a,b){return a===b&&(l=!0),0},C=1<<31,D={}.hasOwnProperty,E=[],F=E.pop,G=E.push,H=E.push,I=E.slice,J=function(a,b){for(var c=0,d=a.length;d>c;c++)if(a[c]===b)return c;return-1},K="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",L="[\\x20\\t\\r\\n\\f]",M="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",N="\\["+L+"*("+M+")(?:"+L+"*([*^$|!~]?=)"+L+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+M+"))|)"+L+"*\\]",O=":("+M+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+N+")*)|.*)\\)|)",P=new RegExp(L+"+","g"),Q=new RegExp("^"+L+"+|((?:^|[^\\\\])(?:\\\\.)*)"+L+"+$","g"),R=new RegExp("^"+L+"*,"+L+"*"),S=new RegExp("^"+L+"*([>+~]|"+L+")"+L+"*"),T=new RegExp("="+L+"*([^\\]'\"]*?)"+L+"*\\]","g"),U=new RegExp(O),V=new RegExp("^"+M+"$"),W={ID:new RegExp("^#("+M+")"),CLASS:new RegExp("^\\.("+M+")"),TAG:new RegExp("^("+M+"|[*])"),ATTR:new RegExp("^"+N),PSEUDO:new RegExp("^"+O),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+L+"*(even|odd|(([+-]|)(\\d*)n|)"+L+"*(?:([+-]|)"+L+"*(\\d+)|))"+L+"*\\)|)","i"),bool:new RegExp("^(?:"+K+")$","i"),needsContext:new RegExp("^"+L+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+L+"*((?:-\\d)?\\d*)"+L+"*\\)|)(?=[^-]|$)","i")},X=/^(?:input|select|textarea|button)$/i,Y=/^h\d$/i,Z=/^[^{]+\{\s*\[native \w/,$=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,_=/[+~]/,aa=/'|\\/g,ba=new RegExp("\\\\([\\da-f]{1,6}"+L+"?|("+L+")|.)","ig"),ca=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)},da=function(){m()};try{H.apply(E=I.call(v.childNodes),v.childNodes),E[v.childNodes.length].nodeType}catch(ea){H={apply:E.length?function(a,b){G.apply(a,I.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function fa(a,b,d,e){var f,h,j,k,l,o,r,s,w=b&&b.ownerDocument,x=b?b.nodeType:9;if(d=d||[],"string"!=typeof a||!a||1!==x&&9!==x&&11!==x)return d;if(!e&&((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,p)){if(11!==x&&(o=$.exec(a)))if(f=o[1]){if(9===x){if(!(j=b.getElementById(f)))return d;if(j.id===f)return d.push(j),d}else if(w&&(j=w.getElementById(f))&&t(b,j)&&j.id===f)return d.push(j),d}else{if(o[2])return H.apply(d,b.getElementsByTagName(a)),d;if((f=o[3])&&c.getElementsByClassName&&b.getElementsByClassName)return H.apply(d,b.getElementsByClassName(f)),d}if(c.qsa&&!A[a+" "]&&(!q||!q.test(a))){if(1!==x)w=b,s=a;else if("object"!==b.nodeName.toLowerCase()){(k=b.getAttribute("id"))?k=k.replace(aa,"\\$&"):b.setAttribute("id",k=u),r=g(a),h=r.length,l=V.test(k)?"#"+k:"[id='"+k+"']";while(h--)r[h]=l+" "+qa(r[h]);s=r.join(","),w=_.test(a)&&oa(b.parentNode)||b}if(s)try{return H.apply(d,w.querySelectorAll(s)),d}catch(y){}finally{k===u&&b.removeAttribute("id")}}}return i(a.replace(Q,"$1"),b,d,e)}function ga(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function ha(a){return a[u]=!0,a}function ia(a){var b=n.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function ja(a,b){var c=a.split("|"),e=c.length;while(e--)d.attrHandle[c[e]]=b}function ka(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||C)-(~a.sourceIndex||C);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function la(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function ma(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function na(a){return ha(function(b){return b=+b,ha(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function oa(a){return a&&"undefined"!=typeof a.getElementsByTagName&&a}c=fa.support={},f=fa.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},m=fa.setDocument=function(a){var b,e,g=a?a.ownerDocument||a:v;return g!==n&&9===g.nodeType&&g.documentElement?(n=g,o=n.documentElement,p=!f(n),(e=n.defaultView)&&e.top!==e&&(e.addEventListener?e.addEventListener("unload",da,!1):e.attachEvent&&e.attachEvent("onunload",da)),c.attributes=ia(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ia(function(a){return a.appendChild(n.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=Z.test(n.getElementsByClassName),c.getById=ia(function(a){return o.appendChild(a).id=u,!n.getElementsByName||!n.getElementsByName(u).length}),c.getById?(d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c=b.getElementById(a);return c?[c]:[]}},d.filter.ID=function(a){var b=a.replace(ba,ca);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(ba,ca);return function(a){var c="undefined"!=typeof a.getAttributeNode&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return"undefined"!=typeof b.getElementsByTagName?b.getElementsByTagName(a):c.qsa?b.querySelectorAll(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return"undefined"!=typeof b.getElementsByClassName&&p?b.getElementsByClassName(a):void 0},r=[],q=[],(c.qsa=Z.test(n.querySelectorAll))&&(ia(function(a){o.appendChild(a).innerHTML="<a id='"+u+"'></a><select id='"+u+"-\r\\' msallowcapture=''><option selected=''></option></select>",a.querySelectorAll("[msallowcapture^='']").length&&q.push("[*^$]="+L+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+L+"*(?:value|"+K+")"),a.querySelectorAll("[id~="+u+"-]").length||q.push("~="),a.querySelectorAll(":checked").length||q.push(":checked"),a.querySelectorAll("a#"+u+"+*").length||q.push(".#.+[+~]")}),ia(function(a){var b=n.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+L+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=Z.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ia(function(a){c.disconnectedMatch=s.call(a,"div"),s.call(a,"[s!='']:x"),r.push("!=",O)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=Z.test(o.compareDocumentPosition),t=b||Z.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===n||a.ownerDocument===v&&t(v,a)?-1:b===n||b.ownerDocument===v&&t(v,b)?1:k?J(k,a)-J(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,e=a.parentNode,f=b.parentNode,g=[a],h=[b];if(!e||!f)return a===n?-1:b===n?1:e?-1:f?1:k?J(k,a)-J(k,b):0;if(e===f)return ka(a,b);c=a;while(c=c.parentNode)g.unshift(c);c=b;while(c=c.parentNode)h.unshift(c);while(g[d]===h[d])d++;return d?ka(g[d],h[d]):g[d]===v?-1:h[d]===v?1:0},n):n},fa.matches=function(a,b){return fa(a,null,null,b)},fa.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(T,"='$1']"),c.matchesSelector&&p&&!A[b+" "]&&(!r||!r.test(b))&&(!q||!q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return fa(b,n,null,[a]).length>0},fa.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},fa.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&D.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},fa.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},fa.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=fa.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=fa.selectors={cacheLength:50,createPseudo:ha,match:W,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(ba,ca),a[3]=(a[3]||a[4]||a[5]||"").replace(ba,ca),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||fa.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&fa.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return W.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&U.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(ba,ca).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+L+")"+a+"("+L+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||"undefined"!=typeof a.getAttribute&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=fa.attr(d,a);return null==e?"!="===b:b?(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e.replace(P," ")+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h,t=!1;if(q){if(f){while(p){m=b;while(m=m[p])if(h?m.nodeName.toLowerCase()===r:1===m.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){m=q,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n&&j[2],m=n&&q.childNodes[n];while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if(1===m.nodeType&&++t&&m===b){k[a]=[w,n,t];break}}else if(s&&(m=b,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n),t===!1)while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if((h?m.nodeName.toLowerCase()===r:1===m.nodeType)&&++t&&(s&&(l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),k[a]=[w,t]),m===b))break;return t-=e,t===d||t%d===0&&t/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||fa.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?ha(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=J(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:ha(function(a){var b=[],c=[],d=h(a.replace(Q,"$1"));return d[u]?ha(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),b[0]=null,!c.pop()}}),has:ha(function(a){return function(b){return fa(a,b).length>0}}),contains:ha(function(a){return a=a.replace(ba,ca),function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:ha(function(a){return V.test(a||"")||fa.error("unsupported lang: "+a),a=a.replace(ba,ca).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return Y.test(a.nodeName)},input:function(a){return X.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:na(function(){return[0]}),last:na(function(a,b){return[b-1]}),eq:na(function(a,b,c){return[0>c?c+b:c]}),even:na(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:na(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:na(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:na(function(a,b,c){for(var d=0>c?c+b:c;++d<b;)a.push(d);return a})}},d.pseudos.nth=d.pseudos.eq;for(b in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})d.pseudos[b]=la(b);for(b in{submit:!0,reset:!0})d.pseudos[b]=ma(b);function pa(){}pa.prototype=d.filters=d.pseudos,d.setFilters=new pa,g=fa.tokenize=function(a,b){var c,e,f,g,h,i,j,k=z[a+" "];if(k)return b?0:k.slice(0);h=a,i=[],j=d.preFilter;while(h){c&&!(e=R.exec(h))||(e&&(h=h.slice(e[0].length)||h),i.push(f=[])),c=!1,(e=S.exec(h))&&(c=e.shift(),f.push({value:c,type:e[0].replace(Q," ")}),h=h.slice(c.length));for(g in d.filter)!(e=W[g].exec(h))||j[g]&&!(e=j[g](e))||(c=e.shift(),f.push({value:c,type:g,matches:e}),h=h.slice(c.length));if(!c)break}return b?h.length:h?fa.error(a):z(a,i).slice(0)};function qa(a){for(var b=0,c=a.length,d="";c>b;b++)d+=a[b].value;return d}function ra(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=x++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j,k=[w,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(j=b[u]||(b[u]={}),i=j[b.uniqueID]||(j[b.uniqueID]={}),(h=i[d])&&h[0]===w&&h[1]===f)return k[2]=h[2];if(i[d]=k,k[2]=a(b,c,g))return!0}}}function sa(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function ta(a,b,c){for(var d=0,e=b.length;e>d;d++)fa(a,b[d],c);return c}function ua(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(c&&!c(f,d,e)||(g.push(f),j&&b.push(h)));return g}function va(a,b,c,d,e,f){return d&&!d[u]&&(d=va(d)),e&&!e[u]&&(e=va(e,f)),ha(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||ta(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:ua(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=ua(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?J(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=ua(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):H.apply(g,r)})}function wa(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=ra(function(a){return a===b},h,!0),l=ra(function(a){return J(b,a)>-1},h,!0),m=[function(a,c,d){var e=!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d));return b=null,e}];f>i;i++)if(c=d.relative[a[i].type])m=[ra(sa(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;f>e;e++)if(d.relative[a[e].type])break;return va(i>1&&sa(m),i>1&&qa(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(Q,"$1"),c,e>i&&wa(a.slice(i,e)),f>e&&wa(a=a.slice(e)),f>e&&qa(a))}m.push(c)}return sa(m)}function xa(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,o,q,r=0,s="0",t=f&&[],u=[],v=j,x=f||e&&d.find.TAG("*",k),y=w+=null==v?1:Math.random()||.1,z=x.length;for(k&&(j=g===n||g||k);s!==z&&null!=(l=x[s]);s++){if(e&&l){o=0,g||l.ownerDocument===n||(m(l),h=!p);while(q=a[o++])if(q(l,g||n,h)){i.push(l);break}k&&(w=y)}c&&((l=!q&&l)&&r--,f&&t.push(l))}if(r+=s,c&&s!==r){o=0;while(q=b[o++])q(t,u,g,h);if(f){if(r>0)while(s--)t[s]||u[s]||(u[s]=F.call(i));u=ua(u)}H.apply(i,u),k&&!f&&u.length>0&&r+b.length>1&&fa.uniqueSort(i)}return k&&(w=y,j=v),t};return c?ha(f):f}return h=fa.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=wa(b[c]),f[u]?d.push(f):e.push(f);f=A(a,xa(e,d)),f.selector=a}return f},i=fa.select=function(a,b,e,f){var i,j,k,l,m,n="function"==typeof a&&a,o=!f&&g(a=n.selector||a);if(e=e||[],1===o.length){if(j=o[0]=o[0].slice(0),j.length>2&&"ID"===(k=j[0]).type&&c.getById&&9===b.nodeType&&p&&d.relative[j[1].type]){if(b=(d.find.ID(k.matches[0].replace(ba,ca),b)||[])[0],!b)return e;n&&(b=b.parentNode),a=a.slice(j.shift().value.length)}i=W.needsContext.test(a)?0:j.length;while(i--){if(k=j[i],d.relative[l=k.type])break;if((m=d.find[l])&&(f=m(k.matches[0].replace(ba,ca),_.test(j[0].type)&&oa(b.parentNode)||b))){if(j.splice(i,1),a=f.length&&qa(j),!a)return H.apply(e,f),e;break}}}return(n||h(a,o))(f,b,!p,e,!b||_.test(a)&&oa(b.parentNode)||b),e},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ia(function(a){return 1&a.compareDocumentPosition(n.createElement("div"))}),ia(function(a){return a.innerHTML="<a href='#'></a>","#"===a.firstChild.getAttribute("href")})||ja("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ia(function(a){return a.innerHTML="<input/>",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||ja("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),ia(function(a){return null==a.getAttribute("disabled")})||ja(K,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),fa}(a);n.find=t,n.expr=t.selectors,n.expr[":"]=n.expr.pseudos,n.uniqueSort=n.unique=t.uniqueSort,n.text=t.getText,n.isXMLDoc=t.isXML,n.contains=t.contains;var u=function(a,b,c){var d=[],e=void 0!==c;while((a=a[b])&&9!==a.nodeType)if(1===a.nodeType){if(e&&n(a).is(c))break;d.push(a)}return d},v=function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c},w=n.expr.match.needsContext,x=/^<([\w-]+)\s*\/?>(?:<\/\1>|)$/,y=/^.[^:#\[\.,]*$/;function z(a,b,c){if(n.isFunction(b))return n.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return n.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(y.test(b))return n.filter(b,a,c);b=n.filter(b,a)}return n.grep(a,function(a){return n.inArray(a,b)>-1!==c})}n.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?n.find.matchesSelector(d,a)?[d]:[]:n.find.matches(a,n.grep(b,function(a){return 1===a.nodeType}))},n.fn.extend({find:function(a){var b,c=[],d=this,e=d.length;if("string"!=typeof a)return this.pushStack(n(a).filter(function(){for(b=0;e>b;b++)if(n.contains(d[b],this))return!0}));for(b=0;e>b;b++)n.find(a,d[b],c);return c=this.pushStack(e>1?n.unique(c):c),c.selector=this.selector?this.selector+" "+a:a,c},filter:function(a){return this.pushStack(z(this,a||[],!1))},not:function(a){return this.pushStack(z(this,a||[],!0))},is:function(a){return!!z(this,"string"==typeof a&&w.test(a)?n(a):a||[],!1).length}});var A,B=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,C=n.fn.init=function(a,b,c){var e,f;if(!a)return this;if(c=c||A,"string"==typeof a){if(e="<"===a.charAt(0)&&">"===a.charAt(a.length-1)&&a.length>=3?[null,a,null]:B.exec(a),!e||!e[1]&&b)return!b||b.jquery?(b||c).find(a):this.constructor(b).find(a);if(e[1]){if(b=b instanceof n?b[0]:b,n.merge(this,n.parseHTML(e[1],b&&b.nodeType?b.ownerDocument||b:d,!0)),x.test(e[1])&&n.isPlainObject(b))for(e in b)n.isFunction(this[e])?this[e](b[e]):this.attr(e,b[e]);return this}if(f=d.getElementById(e[2]),f&&f.parentNode){if(f.id!==e[2])return A.find(a);this.length=1,this[0]=f}return this.context=d,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):n.isFunction(a)?"undefined"!=typeof c.ready?c.ready(a):a(n):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),n.makeArray(a,this))};C.prototype=n.fn,A=n(d);var D=/^(?:parents|prev(?:Until|All))/,E={children:!0,contents:!0,next:!0,prev:!0};n.fn.extend({has:function(a){var b,c=n(a,this),d=c.length;return this.filter(function(){for(b=0;d>b;b++)if(n.contains(this,c[b]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=w.test(a)||"string"!=typeof a?n(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&n.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?n.uniqueSort(f):f)},index:function(a){return a?"string"==typeof a?n.inArray(this[0],n(a)):n.inArray(a.jquery?a[0]:a,this):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(n.uniqueSort(n.merge(this.get(),n(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function F(a,b){do a=a[b];while(a&&1!==a.nodeType);return a}n.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return u(a,"parentNode")},parentsUntil:function(a,b,c){return u(a,"parentNode",c)},next:function(a){return F(a,"nextSibling")},prev:function(a){return F(a,"previousSibling")},nextAll:function(a){return u(a,"nextSibling")},prevAll:function(a){return u(a,"previousSibling")},nextUntil:function(a,b,c){return u(a,"nextSibling",c)},prevUntil:function(a,b,c){return u(a,"previousSibling",c)},siblings:function(a){return v((a.parentNode||{}).firstChild,a)},children:function(a){return v(a.firstChild)},contents:function(a){return n.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:n.merge([],a.childNodes)}},function(a,b){n.fn[a]=function(c,d){var e=n.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=n.filter(d,e)),this.length>1&&(E[a]||(e=n.uniqueSort(e)),D.test(a)&&(e=e.reverse())),this.pushStack(e)}});var G=/\S+/g;function H(a){var b={};return n.each(a.match(G)||[],function(a,c){b[c]=!0}),b}n.Callbacks=function(a){a="string"==typeof a?H(a):n.extend({},a);var b,c,d,e,f=[],g=[],h=-1,i=function(){for(e=a.once,d=b=!0;g.length;h=-1){c=g.shift();while(++h<f.length)f[h].apply(c[0],c[1])===!1&&a.stopOnFalse&&(h=f.length,c=!1)}a.memory||(c=!1),b=!1,e&&(f=c?[]:"")},j={add:function(){return f&&(c&&!b&&(h=f.length-1,g.push(c)),function d(b){n.each(b,function(b,c){n.isFunction(c)?a.unique&&j.has(c)||f.push(c):c&&c.length&&"string"!==n.type(c)&&d(c)})}(arguments),c&&!b&&i()),this},remove:function(){return n.each(arguments,function(a,b){var c;while((c=n.inArray(b,f,c))>-1)f.splice(c,1),h>=c&&h--}),this},has:function(a){return a?n.inArray(a,f)>-1:f.length>0},empty:function(){return f&&(f=[]),this},disable:function(){return e=g=[],f=c="",this},disabled:function(){return!f},lock:function(){return e=!0,c||j.disable(),this},locked:function(){return!!e},fireWith:function(a,c){return e||(c=c||[],c=[a,c.slice?c.slice():c],g.push(c),b||i()),this},fire:function(){return j.fireWith(this,arguments),this},fired:function(){return!!d}};return j},n.extend({Deferred:function(a){var b=[["resolve","done",n.Callbacks("once memory"),"resolved"],["reject","fail",n.Callbacks("once memory"),"rejected"],["notify","progress",n.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return n.Deferred(function(c){n.each(b,function(b,f){var g=n.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&n.isFunction(a.promise)?a.promise().progress(c.notify).done(c.resolve).fail(c.reject):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?n.extend(a,d):d}},e={};return d.pipe=d.then,n.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+"With"](this===e?d:this,arguments),this},e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=e.call(arguments),d=c.length,f=1!==d||a&&n.isFunction(a.promise)?d:0,g=1===f?a:n.Deferred(),h=function(a,b,c){return function(d){b[a]=this,c[a]=arguments.length>1?e.call(arguments):d,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(d>1)for(i=new Array(d),j=new Array(d),k=new Array(d);d>b;b++)c[b]&&n.isFunction(c[b].promise)?c[b].promise().progress(h(b,j,i)).done(h(b,k,c)).fail(g.reject):--f;return f||g.resolveWith(k,c),g.promise()}});var I;n.fn.ready=function(a){return n.ready.promise().done(a),this},n.extend({isReady:!1,readyWait:1,holdReady:function(a){a?n.readyWait++:n.ready(!0)},ready:function(a){(a===!0?--n.readyWait:n.isReady)||(n.isReady=!0,a!==!0&&--n.readyWait>0||(I.resolveWith(d,[n]),n.fn.triggerHandler&&(n(d).triggerHandler("ready"),n(d).off("ready"))))}});function J(){d.addEventListener?(d.removeEventListener("DOMContentLoaded",K),a.removeEventListener("load",K)):(d.detachEvent("onreadystatechange",K),a.detachEvent("onload",K))}function K(){(d.addEventListener||"load"===a.event.type||"complete"===d.readyState)&&(J(),n.ready())}n.ready.promise=function(b){if(!I)if(I=n.Deferred(),"complete"===d.readyState||"loading"!==d.readyState&&!d.documentElement.doScroll)a.setTimeout(n.ready);else if(d.addEventListener)d.addEventListener("DOMContentLoaded",K),a.addEventListener("load",K);else{d.attachEvent("onreadystatechange",K),a.attachEvent("onload",K);var c=!1;try{c=null==a.frameElement&&d.documentElement}catch(e){}c&&c.doScroll&&!function f(){if(!n.isReady){try{c.doScroll("left")}catch(b){return a.setTimeout(f,50)}J(),n.ready()}}()}return I.promise(b)},n.ready.promise();var L;for(L in n(l))break;l.ownFirst="0"===L,l.inlineBlockNeedsLayout=!1,n(function(){var a,b,c,e;c=d.getElementsByTagName("body")[0],c&&c.style&&(b=d.createElement("div"),e=d.createElement("div"),e.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",c.appendChild(e).appendChild(b),"undefined"!=typeof b.style.zoom&&(b.style.cssText="display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1",l.inlineBlockNeedsLayout=a=3===b.offsetWidth,a&&(c.style.zoom=1)),c.removeChild(e))}),function(){var a=d.createElement("div");l.deleteExpando=!0;try{delete a.test}catch(b){l.deleteExpando=!1}a=null}();var M=function(a){var b=n.noData[(a.nodeName+" ").toLowerCase()],c=+a.nodeType||1;return 1!==c&&9!==c?!1:!b||b!==!0&&a.getAttribute("classid")===b},N=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,O=/([A-Z])/g;function P(a,b,c){if(void 0===c&&1===a.nodeType){var d="data-"+b.replace(O,"-$1").toLowerCase();if(c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:N.test(c)?n.parseJSON(c):c}catch(e){}n.data(a,b,c)}else c=void 0; +}return c}function Q(a){var b;for(b in a)if(("data"!==b||!n.isEmptyObject(a[b]))&&"toJSON"!==b)return!1;return!0}function R(a,b,d,e){if(M(a)){var f,g,h=n.expando,i=a.nodeType,j=i?n.cache:a,k=i?a[h]:a[h]&&h;if(k&&j[k]&&(e||j[k].data)||void 0!==d||"string"!=typeof b)return k||(k=i?a[h]=c.pop()||n.guid++:h),j[k]||(j[k]=i?{}:{toJSON:n.noop}),"object"!=typeof b&&"function"!=typeof b||(e?j[k]=n.extend(j[k],b):j[k].data=n.extend(j[k].data,b)),g=j[k],e||(g.data||(g.data={}),g=g.data),void 0!==d&&(g[n.camelCase(b)]=d),"string"==typeof b?(f=g[b],null==f&&(f=g[n.camelCase(b)])):f=g,f}}function S(a,b,c){if(M(a)){var d,e,f=a.nodeType,g=f?n.cache:a,h=f?a[n.expando]:n.expando;if(g[h]){if(b&&(d=c?g[h]:g[h].data)){n.isArray(b)?b=b.concat(n.map(b,n.camelCase)):b in d?b=[b]:(b=n.camelCase(b),b=b in d?[b]:b.split(" ")),e=b.length;while(e--)delete d[b[e]];if(c?!Q(d):!n.isEmptyObject(d))return}(c||(delete g[h].data,Q(g[h])))&&(f?n.cleanData([a],!0):l.deleteExpando||g!=g.window?delete g[h]:g[h]=void 0)}}}n.extend({cache:{},noData:{"applet ":!0,"embed ":!0,"object ":"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"},hasData:function(a){return a=a.nodeType?n.cache[a[n.expando]]:a[n.expando],!!a&&!Q(a)},data:function(a,b,c){return R(a,b,c)},removeData:function(a,b){return S(a,b)},_data:function(a,b,c){return R(a,b,c,!0)},_removeData:function(a,b){return S(a,b,!0)}}),n.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=n.data(f),1===f.nodeType&&!n._data(f,"parsedAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=n.camelCase(d.slice(5)),P(f,d,e[d])));n._data(f,"parsedAttrs",!0)}return e}return"object"==typeof a?this.each(function(){n.data(this,a)}):arguments.length>1?this.each(function(){n.data(this,a,b)}):f?P(f,a,n.data(f,a)):void 0},removeData:function(a){return this.each(function(){n.removeData(this,a)})}}),n.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=n._data(a,b),c&&(!d||n.isArray(c)?d=n._data(a,b,n.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=n.queue(a,b),d=c.length,e=c.shift(),f=n._queueHooks(a,b),g=function(){n.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return n._data(a,c)||n._data(a,c,{empty:n.Callbacks("once memory").add(function(){n._removeData(a,b+"queue"),n._removeData(a,c)})})}}),n.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.length<c?n.queue(this[0],a):void 0===b?this:this.each(function(){var c=n.queue(this,a,b);n._queueHooks(this,a),"fx"===a&&"inprogress"!==c[0]&&n.dequeue(this,a)})},dequeue:function(a){return this.each(function(){n.dequeue(this,a)})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,b){var c,d=1,e=n.Deferred(),f=this,g=this.length,h=function(){--d||e.resolveWith(f,[f])};"string"!=typeof a&&(b=a,a=void 0),a=a||"fx";while(g--)c=n._data(f[g],a+"queueHooks"),c&&c.empty&&(d++,c.empty.add(h));return h(),e.promise(b)}}),function(){var a;l.shrinkWrapBlocks=function(){if(null!=a)return a;a=!1;var b,c,e;return c=d.getElementsByTagName("body")[0],c&&c.style?(b=d.createElement("div"),e=d.createElement("div"),e.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",c.appendChild(e).appendChild(b),"undefined"!=typeof b.style.zoom&&(b.style.cssText="-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:1px;width:1px;zoom:1",b.appendChild(d.createElement("div")).style.width="5px",a=3!==b.offsetWidth),c.removeChild(e),a):void 0}}();var T=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,U=new RegExp("^(?:([+-])=|)("+T+")([a-z%]*)$","i"),V=["Top","Right","Bottom","Left"],W=function(a,b){return a=b||a,"none"===n.css(a,"display")||!n.contains(a.ownerDocument,a)};function X(a,b,c,d){var e,f=1,g=20,h=d?function(){return d.cur()}:function(){return n.css(a,b,"")},i=h(),j=c&&c[3]||(n.cssNumber[b]?"":"px"),k=(n.cssNumber[b]||"px"!==j&&+i)&&U.exec(n.css(a,b));if(k&&k[3]!==j){j=j||k[3],c=c||[],k=+i||1;do f=f||".5",k/=f,n.style(a,b,k+j);while(f!==(f=h()/i)&&1!==f&&--g)}return c&&(k=+k||+i||0,e=c[1]?k+(c[1]+1)*c[2]:+c[2],d&&(d.unit=j,d.start=k,d.end=e)),e}var Y=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===n.type(c)){e=!0;for(h in c)Y(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,n.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(n(a),c)})),b))for(;i>h;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f},Z=/^(?:checkbox|radio)$/i,$=/<([\w:-]+)/,_=/^$|\/(?:java|ecma)script/i,aa=/^\s+/,ba="abbr|article|aside|audio|bdi|canvas|data|datalist|details|dialog|figcaption|figure|footer|header|hgroup|main|mark|meter|nav|output|picture|progress|section|summary|template|time|video";function ca(a){var b=ba.split("|"),c=a.createDocumentFragment();if(c.createElement)while(b.length)c.createElement(b.pop());return c}!function(){var a=d.createElement("div"),b=d.createDocumentFragment(),c=d.createElement("input");a.innerHTML=" <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",l.leadingWhitespace=3===a.firstChild.nodeType,l.tbody=!a.getElementsByTagName("tbody").length,l.htmlSerialize=!!a.getElementsByTagName("link").length,l.html5Clone="<:nav></:nav>"!==d.createElement("nav").cloneNode(!0).outerHTML,c.type="checkbox",c.checked=!0,b.appendChild(c),l.appendChecked=c.checked,a.innerHTML="<textarea>x</textarea>",l.noCloneChecked=!!a.cloneNode(!0).lastChild.defaultValue,b.appendChild(a),c=d.createElement("input"),c.setAttribute("type","radio"),c.setAttribute("checked","checked"),c.setAttribute("name","t"),a.appendChild(c),l.checkClone=a.cloneNode(!0).cloneNode(!0).lastChild.checked,l.noCloneEvent=!!a.addEventListener,a[n.expando]=1,l.attributes=!a.getAttribute(n.expando)}();var da={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],area:[1,"<map>","</map>"],param:[1,"<object>","</object>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:l.htmlSerialize?[0,"",""]:[1,"X<div>","</div>"]};da.optgroup=da.option,da.tbody=da.tfoot=da.colgroup=da.caption=da.thead,da.th=da.td;function ea(a,b){var c,d,e=0,f="undefined"!=typeof a.getElementsByTagName?a.getElementsByTagName(b||"*"):"undefined"!=typeof a.querySelectorAll?a.querySelectorAll(b||"*"):void 0;if(!f)for(f=[],c=a.childNodes||a;null!=(d=c[e]);e++)!b||n.nodeName(d,b)?f.push(d):n.merge(f,ea(d,b));return void 0===b||b&&n.nodeName(a,b)?n.merge([a],f):f}function fa(a,b){for(var c,d=0;null!=(c=a[d]);d++)n._data(c,"globalEval",!b||n._data(b[d],"globalEval"))}var ga=/<|&#?\w+;/,ha=/<tbody/i;function ia(a){Z.test(a.type)&&(a.defaultChecked=a.checked)}function ja(a,b,c,d,e){for(var f,g,h,i,j,k,m,o=a.length,p=ca(b),q=[],r=0;o>r;r++)if(g=a[r],g||0===g)if("object"===n.type(g))n.merge(q,g.nodeType?[g]:g);else if(ga.test(g)){i=i||p.appendChild(b.createElement("div")),j=($.exec(g)||["",""])[1].toLowerCase(),m=da[j]||da._default,i.innerHTML=m[1]+n.htmlPrefilter(g)+m[2],f=m[0];while(f--)i=i.lastChild;if(!l.leadingWhitespace&&aa.test(g)&&q.push(b.createTextNode(aa.exec(g)[0])),!l.tbody){g="table"!==j||ha.test(g)?"<table>"!==m[1]||ha.test(g)?0:i:i.firstChild,f=g&&g.childNodes.length;while(f--)n.nodeName(k=g.childNodes[f],"tbody")&&!k.childNodes.length&&g.removeChild(k)}n.merge(q,i.childNodes),i.textContent="";while(i.firstChild)i.removeChild(i.firstChild);i=p.lastChild}else q.push(b.createTextNode(g));i&&p.removeChild(i),l.appendChecked||n.grep(ea(q,"input"),ia),r=0;while(g=q[r++])if(d&&n.inArray(g,d)>-1)e&&e.push(g);else if(h=n.contains(g.ownerDocument,g),i=ea(p.appendChild(g),"script"),h&&fa(i),c){f=0;while(g=i[f++])_.test(g.type||"")&&c.push(g)}return i=null,p}!function(){var b,c,e=d.createElement("div");for(b in{submit:!0,change:!0,focusin:!0})c="on"+b,(l[b]=c in a)||(e.setAttribute(c,"t"),l[b]=e.attributes[c].expando===!1);e=null}();var ka=/^(?:input|select|textarea)$/i,la=/^key/,ma=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,na=/^(?:focusinfocus|focusoutblur)$/,oa=/^([^.]*)(?:\.(.+)|)/;function pa(){return!0}function qa(){return!1}function ra(){try{return d.activeElement}catch(a){}}function sa(a,b,c,d,e,f){var g,h;if("object"==typeof b){"string"!=typeof c&&(d=d||c,c=void 0);for(h in b)sa(a,h,c,d,b[h],f);return a}if(null==d&&null==e?(e=c,d=c=void 0):null==e&&("string"==typeof c?(e=d,d=void 0):(e=d,d=c,c=void 0)),e===!1)e=qa;else if(!e)return a;return 1===f&&(g=e,e=function(a){return n().off(a),g.apply(this,arguments)},e.guid=g.guid||(g.guid=n.guid++)),a.each(function(){n.event.add(this,b,e,d,c)})}n.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=n._data(a);if(r){c.handler&&(i=c,c=i.handler,e=i.selector),c.guid||(c.guid=n.guid++),(g=r.events)||(g=r.events={}),(k=r.handle)||(k=r.handle=function(a){return"undefined"==typeof n||a&&n.event.triggered===a.type?void 0:n.event.dispatch.apply(k.elem,arguments)},k.elem=a),b=(b||"").match(G)||[""],h=b.length;while(h--)f=oa.exec(b[h])||[],o=q=f[1],p=(f[2]||"").split(".").sort(),o&&(j=n.event.special[o]||{},o=(e?j.delegateType:j.bindType)||o,j=n.event.special[o]||{},l=n.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&n.expr.match.needsContext.test(e),namespace:p.join(".")},i),(m=g[o])||(m=g[o]=[],m.delegateCount=0,j.setup&&j.setup.call(a,d,p,k)!==!1||(a.addEventListener?a.addEventListener(o,k,!1):a.attachEvent&&a.attachEvent("on"+o,k))),j.add&&(j.add.call(a,l),l.handler.guid||(l.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,l):m.push(l),n.event.global[o]=!0);a=null}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=n.hasData(a)&&n._data(a);if(r&&(k=r.events)){b=(b||"").match(G)||[""],j=b.length;while(j--)if(h=oa.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o){l=n.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,m=k[o]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),i=f=m.length;while(f--)g=m[f],!e&&q!==g.origType||c&&c.guid!==g.guid||h&&!h.test(g.namespace)||d&&d!==g.selector&&("**"!==d||!g.selector)||(m.splice(f,1),g.selector&&m.delegateCount--,l.remove&&l.remove.call(a,g));i&&!m.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||n.removeEvent(a,o,r.handle),delete k[o])}else for(o in k)n.event.remove(a,o+b[j],c,d,!0);n.isEmptyObject(k)&&(delete r.handle,n._removeData(a,"events"))}},trigger:function(b,c,e,f){var g,h,i,j,l,m,o,p=[e||d],q=k.call(b,"type")?b.type:b,r=k.call(b,"namespace")?b.namespace.split("."):[];if(i=m=e=e||d,3!==e.nodeType&&8!==e.nodeType&&!na.test(q+n.event.triggered)&&(q.indexOf(".")>-1&&(r=q.split("."),q=r.shift(),r.sort()),h=q.indexOf(":")<0&&"on"+q,b=b[n.expando]?b:new n.Event(q,"object"==typeof b&&b),b.isTrigger=f?2:3,b.namespace=r.join("."),b.rnamespace=b.namespace?new RegExp("(^|\\.)"+r.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=e),c=null==c?[b]:n.makeArray(c,[b]),l=n.event.special[q]||{},f||!l.trigger||l.trigger.apply(e,c)!==!1)){if(!f&&!l.noBubble&&!n.isWindow(e)){for(j=l.delegateType||q,na.test(j+q)||(i=i.parentNode);i;i=i.parentNode)p.push(i),m=i;m===(e.ownerDocument||d)&&p.push(m.defaultView||m.parentWindow||a)}o=0;while((i=p[o++])&&!b.isPropagationStopped())b.type=o>1?j:l.bindType||q,g=(n._data(i,"events")||{})[b.type]&&n._data(i,"handle"),g&&g.apply(i,c),g=h&&i[h],g&&g.apply&&M(i)&&(b.result=g.apply(i,c),b.result===!1&&b.preventDefault());if(b.type=q,!f&&!b.isDefaultPrevented()&&(!l._default||l._default.apply(p.pop(),c)===!1)&&M(e)&&h&&e[q]&&!n.isWindow(e)){m=e[h],m&&(e[h]=null),n.event.triggered=q;try{e[q]()}catch(s){}n.event.triggered=void 0,m&&(e[h]=m)}return b.result}},dispatch:function(a){a=n.event.fix(a);var b,c,d,f,g,h=[],i=e.call(arguments),j=(n._data(this,"events")||{})[a.type]||[],k=n.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=n.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,c=0;while((g=f.handlers[c++])&&!a.isImmediatePropagationStopped())a.rnamespace&&!a.rnamespace.test(g.namespace)||(a.handleObj=g,a.data=g.data,d=((n.event.special[g.origType]||{}).handle||g.handler).apply(f.elem,i),void 0!==d&&(a.result=d)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&("click"!==a.type||isNaN(a.button)||a.button<1))for(;i!=this;i=i.parentNode||this)if(1===i.nodeType&&(i.disabled!==!0||"click"!==a.type)){for(d=[],c=0;h>c;c++)f=b[c],e=f.selector+" ",void 0===d[e]&&(d[e]=f.needsContext?n(e,this).index(i)>-1:n.find(e,this,null,[i]).length),d[e]&&d.push(f);d.length&&g.push({elem:i,handlers:d})}return h<b.length&&g.push({elem:this,handlers:b.slice(h)}),g},fix:function(a){if(a[n.expando])return a;var b,c,e,f=a.type,g=a,h=this.fixHooks[f];h||(this.fixHooks[f]=h=ma.test(f)?this.mouseHooks:la.test(f)?this.keyHooks:{}),e=h.props?this.props.concat(h.props):this.props,a=new n.Event(g),b=e.length;while(b--)c=e[b],a[c]=g[c];return a.target||(a.target=g.srcElement||d),3===a.target.nodeType&&(a.target=a.target.parentNode),a.metaKey=!!a.metaKey,h.filter?h.filter(a,g):a},props:"altKey bubbles cancelable ctrlKey currentTarget detail eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(a,b){return null==a.which&&(a.which=null!=b.charCode?b.charCode:b.keyCode),a}},mouseHooks:{props:"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(a,b){var c,e,f,g=b.button,h=b.fromElement;return null==a.pageX&&null!=b.clientX&&(e=a.target.ownerDocument||d,f=e.documentElement,c=e.body,a.pageX=b.clientX+(f&&f.scrollLeft||c&&c.scrollLeft||0)-(f&&f.clientLeft||c&&c.clientLeft||0),a.pageY=b.clientY+(f&&f.scrollTop||c&&c.scrollTop||0)-(f&&f.clientTop||c&&c.clientTop||0)),!a.relatedTarget&&h&&(a.relatedTarget=h===a.target?b.toElement:h),a.which||void 0===g||(a.which=1&g?1:2&g?3:4&g?2:0),a}},special:{load:{noBubble:!0},focus:{trigger:function(){if(this!==ra()&&this.focus)try{return this.focus(),!1}catch(a){}},delegateType:"focusin"},blur:{trigger:function(){return this===ra()&&this.blur?(this.blur(),!1):void 0},delegateType:"focusout"},click:{trigger:function(){return n.nodeName(this,"input")&&"checkbox"===this.type&&this.click?(this.click(),!1):void 0},_default:function(a){return n.nodeName(a.target,"a")}},beforeunload:{postDispatch:function(a){void 0!==a.result&&a.originalEvent&&(a.originalEvent.returnValue=a.result)}}},simulate:function(a,b,c){var d=n.extend(new n.Event,c,{type:a,isSimulated:!0});n.event.trigger(d,null,b),d.isDefaultPrevented()&&c.preventDefault()}},n.removeEvent=d.removeEventListener?function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c)}:function(a,b,c){var d="on"+b;a.detachEvent&&("undefined"==typeof a[d]&&(a[d]=null),a.detachEvent(d,c))},n.Event=function(a,b){return this instanceof n.Event?(a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||void 0===a.defaultPrevented&&a.returnValue===!1?pa:qa):this.type=a,b&&n.extend(this,b),this.timeStamp=a&&a.timeStamp||n.now(),void(this[n.expando]=!0)):new n.Event(a,b)},n.Event.prototype={constructor:n.Event,isDefaultPrevented:qa,isPropagationStopped:qa,isImmediatePropagationStopped:qa,preventDefault:function(){var a=this.originalEvent;this.isDefaultPrevented=pa,a&&(a.preventDefault?a.preventDefault():a.returnValue=!1)},stopPropagation:function(){var a=this.originalEvent;this.isPropagationStopped=pa,a&&!this.isSimulated&&(a.stopPropagation&&a.stopPropagation(),a.cancelBubble=!0)},stopImmediatePropagation:function(){var a=this.originalEvent;this.isImmediatePropagationStopped=pa,a&&a.stopImmediatePropagation&&a.stopImmediatePropagation(),this.stopPropagation()}},n.each({mouseenter:"mouseover",mouseleave:"mouseout",pointerenter:"pointerover",pointerleave:"pointerout"},function(a,b){n.event.special[a]={delegateType:b,bindType:b,handle:function(a){var c,d=this,e=a.relatedTarget,f=a.handleObj;return e&&(e===d||n.contains(d,e))||(a.type=f.origType,c=f.handler.apply(this,arguments),a.type=b),c}}}),l.submit||(n.event.special.submit={setup:function(){return n.nodeName(this,"form")?!1:void n.event.add(this,"click._submit keypress._submit",function(a){var b=a.target,c=n.nodeName(b,"input")||n.nodeName(b,"button")?n.prop(b,"form"):void 0;c&&!n._data(c,"submit")&&(n.event.add(c,"submit._submit",function(a){a._submitBubble=!0}),n._data(c,"submit",!0))})},postDispatch:function(a){a._submitBubble&&(delete a._submitBubble,this.parentNode&&!a.isTrigger&&n.event.simulate("submit",this.parentNode,a))},teardown:function(){return n.nodeName(this,"form")?!1:void n.event.remove(this,"._submit")}}),l.change||(n.event.special.change={setup:function(){return ka.test(this.nodeName)?("checkbox"!==this.type&&"radio"!==this.type||(n.event.add(this,"propertychange._change",function(a){"checked"===a.originalEvent.propertyName&&(this._justChanged=!0)}),n.event.add(this,"click._change",function(a){this._justChanged&&!a.isTrigger&&(this._justChanged=!1),n.event.simulate("change",this,a)})),!1):void n.event.add(this,"beforeactivate._change",function(a){var b=a.target;ka.test(b.nodeName)&&!n._data(b,"change")&&(n.event.add(b,"change._change",function(a){!this.parentNode||a.isSimulated||a.isTrigger||n.event.simulate("change",this.parentNode,a)}),n._data(b,"change",!0))})},handle:function(a){var b=a.target;return this!==b||a.isSimulated||a.isTrigger||"radio"!==b.type&&"checkbox"!==b.type?a.handleObj.handler.apply(this,arguments):void 0},teardown:function(){return n.event.remove(this,"._change"),!ka.test(this.nodeName)}}),l.focusin||n.each({focus:"focusin",blur:"focusout"},function(a,b){var c=function(a){n.event.simulate(b,a.target,n.event.fix(a))};n.event.special[b]={setup:function(){var d=this.ownerDocument||this,e=n._data(d,b);e||d.addEventListener(a,c,!0),n._data(d,b,(e||0)+1)},teardown:function(){var d=this.ownerDocument||this,e=n._data(d,b)-1;e?n._data(d,b,e):(d.removeEventListener(a,c,!0),n._removeData(d,b))}}}),n.fn.extend({on:function(a,b,c,d){return sa(this,a,b,c,d)},one:function(a,b,c,d){return sa(this,a,b,c,d,1)},off:function(a,b,c){var d,e;if(a&&a.preventDefault&&a.handleObj)return d=a.handleObj,n(a.delegateTarget).off(d.namespace?d.origType+"."+d.namespace:d.origType,d.selector,d.handler),this;if("object"==typeof a){for(e in a)this.off(e,b,a[e]);return this}return b!==!1&&"function"!=typeof b||(c=b,b=void 0),c===!1&&(c=qa),this.each(function(){n.event.remove(this,a,c,b)})},trigger:function(a,b){return this.each(function(){n.event.trigger(a,b,this)})},triggerHandler:function(a,b){var c=this[0];return c?n.event.trigger(a,b,c,!0):void 0}});var ta=/ jQuery\d+="(?:null|\d+)"/g,ua=new RegExp("<(?:"+ba+")[\\s/>]","i"),va=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:-]+)[^>]*)\/>/gi,wa=/<script|<style|<link/i,xa=/checked\s*(?:[^=]|=\s*.checked.)/i,ya=/^true\/(.*)/,za=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,Aa=ca(d),Ba=Aa.appendChild(d.createElement("div"));function Ca(a,b){return n.nodeName(a,"table")&&n.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function Da(a){return a.type=(null!==n.find.attr(a,"type"))+"/"+a.type,a}function Ea(a){var b=ya.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function Fa(a,b){if(1===b.nodeType&&n.hasData(a)){var c,d,e,f=n._data(a),g=n._data(b,f),h=f.events;if(h){delete g.handle,g.events={};for(c in h)for(d=0,e=h[c].length;e>d;d++)n.event.add(b,c,h[c][d])}g.data&&(g.data=n.extend({},g.data))}}function Ga(a,b){var c,d,e;if(1===b.nodeType){if(c=b.nodeName.toLowerCase(),!l.noCloneEvent&&b[n.expando]){e=n._data(b);for(d in e.events)n.removeEvent(b,d,e.handle);b.removeAttribute(n.expando)}"script"===c&&b.text!==a.text?(Da(b).text=a.text,Ea(b)):"object"===c?(b.parentNode&&(b.outerHTML=a.outerHTML),l.html5Clone&&a.innerHTML&&!n.trim(b.innerHTML)&&(b.innerHTML=a.innerHTML)):"input"===c&&Z.test(a.type)?(b.defaultChecked=b.checked=a.checked,b.value!==a.value&&(b.value=a.value)):"option"===c?b.defaultSelected=b.selected=a.defaultSelected:"input"!==c&&"textarea"!==c||(b.defaultValue=a.defaultValue)}}function Ha(a,b,c,d){b=f.apply([],b);var e,g,h,i,j,k,m=0,o=a.length,p=o-1,q=b[0],r=n.isFunction(q);if(r||o>1&&"string"==typeof q&&!l.checkClone&&xa.test(q))return a.each(function(e){var f=a.eq(e);r&&(b[0]=q.call(this,e,f.html())),Ha(f,b,c,d)});if(o&&(k=ja(b,a[0].ownerDocument,!1,a,d),e=k.firstChild,1===k.childNodes.length&&(k=e),e||d)){for(i=n.map(ea(k,"script"),Da),h=i.length;o>m;m++)g=k,m!==p&&(g=n.clone(g,!0,!0),h&&n.merge(i,ea(g,"script"))),c.call(a[m],g,m);if(h)for(j=i[i.length-1].ownerDocument,n.map(i,Ea),m=0;h>m;m++)g=i[m],_.test(g.type||"")&&!n._data(g,"globalEval")&&n.contains(j,g)&&(g.src?n._evalUrl&&n._evalUrl(g.src):n.globalEval((g.text||g.textContent||g.innerHTML||"").replace(za,"")));k=e=null}return a}function Ia(a,b,c){for(var d,e=b?n.filter(b,a):a,f=0;null!=(d=e[f]);f++)c||1!==d.nodeType||n.cleanData(ea(d)),d.parentNode&&(c&&n.contains(d.ownerDocument,d)&&fa(ea(d,"script")),d.parentNode.removeChild(d));return a}n.extend({htmlPrefilter:function(a){return a.replace(va,"<$1></$2>")},clone:function(a,b,c){var d,e,f,g,h,i=n.contains(a.ownerDocument,a);if(l.html5Clone||n.isXMLDoc(a)||!ua.test("<"+a.nodeName+">")?f=a.cloneNode(!0):(Ba.innerHTML=a.outerHTML,Ba.removeChild(f=Ba.firstChild)),!(l.noCloneEvent&&l.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||n.isXMLDoc(a)))for(d=ea(f),h=ea(a),g=0;null!=(e=h[g]);++g)d[g]&&Ga(e,d[g]);if(b)if(c)for(h=h||ea(a),d=d||ea(f),g=0;null!=(e=h[g]);g++)Fa(e,d[g]);else Fa(a,f);return d=ea(f,"script"),d.length>0&&fa(d,!i&&ea(a,"script")),d=h=e=null,f},cleanData:function(a,b){for(var d,e,f,g,h=0,i=n.expando,j=n.cache,k=l.attributes,m=n.event.special;null!=(d=a[h]);h++)if((b||M(d))&&(f=d[i],g=f&&j[f])){if(g.events)for(e in g.events)m[e]?n.event.remove(d,e):n.removeEvent(d,e,g.handle);j[f]&&(delete j[f],k||"undefined"==typeof d.removeAttribute?d[i]=void 0:d.removeAttribute(i),c.push(f))}}}),n.fn.extend({domManip:Ha,detach:function(a){return Ia(this,a,!0)},remove:function(a){return Ia(this,a)},text:function(a){return Y(this,function(a){return void 0===a?n.text(this):this.empty().append((this[0]&&this[0].ownerDocument||d).createTextNode(a))},null,a,arguments.length)},append:function(){return Ha(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Ca(this,a);b.appendChild(a)}})},prepend:function(){return Ha(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Ca(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return Ha(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return Ha(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},empty:function(){for(var a,b=0;null!=(a=this[b]);b++){1===a.nodeType&&n.cleanData(ea(a,!1));while(a.firstChild)a.removeChild(a.firstChild);a.options&&n.nodeName(a,"select")&&(a.options.length=0)}return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return n.clone(this,a,b)})},html:function(a){return Y(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a)return 1===b.nodeType?b.innerHTML.replace(ta,""):void 0;if("string"==typeof a&&!wa.test(a)&&(l.htmlSerialize||!ua.test(a))&&(l.leadingWhitespace||!aa.test(a))&&!da[($.exec(a)||["",""])[1].toLowerCase()]){a=n.htmlPrefilter(a);try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(n.cleanData(ea(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=[];return Ha(this,arguments,function(b){var c=this.parentNode;n.inArray(this,a)<0&&(n.cleanData(ea(this)),c&&c.replaceChild(b,this))},a)}}),n.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){n.fn[a]=function(a){for(var c,d=0,e=[],f=n(a),h=f.length-1;h>=d;d++)c=d===h?this:this.clone(!0),n(f[d])[b](c),g.apply(e,c.get());return this.pushStack(e)}});var Ja,Ka={HTML:"block",BODY:"block"};function La(a,b){var c=n(b.createElement(a)).appendTo(b.body),d=n.css(c[0],"display");return c.detach(),d}function Ma(a){var b=d,c=Ka[a];return c||(c=La(a,b),"none"!==c&&c||(Ja=(Ja||n("<iframe frameborder='0' width='0' height='0'/>")).appendTo(b.documentElement),b=(Ja[0].contentWindow||Ja[0].contentDocument).document,b.write(),b.close(),c=La(a,b),Ja.detach()),Ka[a]=c),c}var Na=/^margin/,Oa=new RegExp("^("+T+")(?!px)[a-z%]+$","i"),Pa=function(a,b,c,d){var e,f,g={};for(f in b)g[f]=a.style[f],a.style[f]=b[f];e=c.apply(a,d||[]);for(f in b)a.style[f]=g[f];return e},Qa=d.documentElement;!function(){var b,c,e,f,g,h,i=d.createElement("div"),j=d.createElement("div");if(j.style){j.style.cssText="float:left;opacity:.5",l.opacity="0.5"===j.style.opacity,l.cssFloat=!!j.style.cssFloat,j.style.backgroundClip="content-box",j.cloneNode(!0).style.backgroundClip="",l.clearCloneStyle="content-box"===j.style.backgroundClip,i=d.createElement("div"),i.style.cssText="border:0;width:8px;height:0;top:0;left:-9999px;padding:0;margin-top:1px;position:absolute",j.innerHTML="",i.appendChild(j),l.boxSizing=""===j.style.boxSizing||""===j.style.MozBoxSizing||""===j.style.WebkitBoxSizing,n.extend(l,{reliableHiddenOffsets:function(){return null==b&&k(),f},boxSizingReliable:function(){return null==b&&k(),e},pixelMarginRight:function(){return null==b&&k(),c},pixelPosition:function(){return null==b&&k(),b},reliableMarginRight:function(){return null==b&&k(),g},reliableMarginLeft:function(){return null==b&&k(),h}});function k(){var k,l,m=d.documentElement;m.appendChild(i),j.style.cssText="-webkit-box-sizing:border-box;box-sizing:border-box;position:relative;display:block;margin:auto;border:1px;padding:1px;top:1%;width:50%",b=e=h=!1,c=g=!0,a.getComputedStyle&&(l=a.getComputedStyle(j),b="1%"!==(l||{}).top,h="2px"===(l||{}).marginLeft,e="4px"===(l||{width:"4px"}).width,j.style.marginRight="50%",c="4px"===(l||{marginRight:"4px"}).marginRight,k=j.appendChild(d.createElement("div")),k.style.cssText=j.style.cssText="-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:0",k.style.marginRight=k.style.width="0",j.style.width="1px",g=!parseFloat((a.getComputedStyle(k)||{}).marginRight),j.removeChild(k)),j.style.display="none",f=0===j.getClientRects().length,f&&(j.style.display="",j.innerHTML="<table><tr><td></td><td>t</td></tr></table>",j.childNodes[0].style.borderCollapse="separate",k=j.getElementsByTagName("td"),k[0].style.cssText="margin:0;border:0;padding:0;display:none",f=0===k[0].offsetHeight,f&&(k[0].style.display="",k[1].style.display="none",f=0===k[0].offsetHeight)),m.removeChild(i)}}}();var Ra,Sa,Ta=/^(top|right|bottom|left)$/;a.getComputedStyle?(Ra=function(b){var c=b.ownerDocument.defaultView;return c&&c.opener||(c=a),c.getComputedStyle(b)},Sa=function(a,b,c){var d,e,f,g,h=a.style;return c=c||Ra(a),g=c?c.getPropertyValue(b)||c[b]:void 0,""!==g&&void 0!==g||n.contains(a.ownerDocument,a)||(g=n.style(a,b)),c&&!l.pixelMarginRight()&&Oa.test(g)&&Na.test(b)&&(d=h.width,e=h.minWidth,f=h.maxWidth,h.minWidth=h.maxWidth=h.width=g,g=c.width,h.width=d,h.minWidth=e,h.maxWidth=f),void 0===g?g:g+""}):Qa.currentStyle&&(Ra=function(a){return a.currentStyle},Sa=function(a,b,c){var d,e,f,g,h=a.style;return c=c||Ra(a),g=c?c[b]:void 0,null==g&&h&&h[b]&&(g=h[b]),Oa.test(g)&&!Ta.test(b)&&(d=h.left,e=a.runtimeStyle,f=e&&e.left,f&&(e.left=a.currentStyle.left),h.left="fontSize"===b?"1em":g,g=h.pixelLeft+"px",h.left=d,f&&(e.left=f)),void 0===g?g:g+""||"auto"});function Ua(a,b){return{get:function(){return a()?void delete this.get:(this.get=b).apply(this,arguments)}}}var Va=/alpha\([^)]*\)/i,Wa=/opacity\s*=\s*([^)]*)/i,Xa=/^(none|table(?!-c[ea]).+)/,Ya=new RegExp("^("+T+")(.*)$","i"),Za={position:"absolute",visibility:"hidden",display:"block"},$a={letterSpacing:"0",fontWeight:"400"},_a=["Webkit","O","Moz","ms"],ab=d.createElement("div").style;function bb(a){if(a in ab)return a;var b=a.charAt(0).toUpperCase()+a.slice(1),c=_a.length;while(c--)if(a=_a[c]+b,a in ab)return a}function cb(a,b){for(var c,d,e,f=[],g=0,h=a.length;h>g;g++)d=a[g],d.style&&(f[g]=n._data(d,"olddisplay"),c=d.style.display,b?(f[g]||"none"!==c||(d.style.display=""),""===d.style.display&&W(d)&&(f[g]=n._data(d,"olddisplay",Ma(d.nodeName)))):(e=W(d),(c&&"none"!==c||!e)&&n._data(d,"olddisplay",e?c:n.css(d,"display"))));for(g=0;h>g;g++)d=a[g],d.style&&(b&&"none"!==d.style.display&&""!==d.style.display||(d.style.display=b?f[g]||"":"none"));return a}function db(a,b,c){var d=Ya.exec(b);return d?Math.max(0,d[1]-(c||0))+(d[2]||"px"):b}function eb(a,b,c,d,e){for(var f=c===(d?"border":"content")?4:"width"===b?1:0,g=0;4>f;f+=2)"margin"===c&&(g+=n.css(a,c+V[f],!0,e)),d?("content"===c&&(g-=n.css(a,"padding"+V[f],!0,e)),"margin"!==c&&(g-=n.css(a,"border"+V[f]+"Width",!0,e))):(g+=n.css(a,"padding"+V[f],!0,e),"padding"!==c&&(g+=n.css(a,"border"+V[f]+"Width",!0,e)));return g}function fb(a,b,c){var d=!0,e="width"===b?a.offsetWidth:a.offsetHeight,f=Ra(a),g=l.boxSizing&&"border-box"===n.css(a,"boxSizing",!1,f);if(0>=e||null==e){if(e=Sa(a,b,f),(0>e||null==e)&&(e=a.style[b]),Oa.test(e))return e;d=g&&(l.boxSizingReliable()||e===a.style[b]),e=parseFloat(e)||0}return e+eb(a,b,c||(g?"border":"content"),d,f)+"px"}n.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=Sa(a,"opacity");return""===c?"1":c}}}},cssNumber:{animationIterationCount:!0,columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":l.cssFloat?"cssFloat":"styleFloat"},style:function(a,b,c,d){if(a&&3!==a.nodeType&&8!==a.nodeType&&a.style){var e,f,g,h=n.camelCase(b),i=a.style;if(b=n.cssProps[h]||(n.cssProps[h]=bb(h)||h),g=n.cssHooks[b]||n.cssHooks[h],void 0===c)return g&&"get"in g&&void 0!==(e=g.get(a,!1,d))?e:i[b];if(f=typeof c,"string"===f&&(e=U.exec(c))&&e[1]&&(c=X(a,b,e),f="number"),null!=c&&c===c&&("number"===f&&(c+=e&&e[3]||(n.cssNumber[h]?"":"px")),l.clearCloneStyle||""!==c||0!==b.indexOf("background")||(i[b]="inherit"),!(g&&"set"in g&&void 0===(c=g.set(a,c,d)))))try{i[b]=c}catch(j){}}},css:function(a,b,c,d){var e,f,g,h=n.camelCase(b);return b=n.cssProps[h]||(n.cssProps[h]=bb(h)||h),g=n.cssHooks[b]||n.cssHooks[h],g&&"get"in g&&(f=g.get(a,!0,c)),void 0===f&&(f=Sa(a,b,d)),"normal"===f&&b in $a&&(f=$a[b]),""===c||c?(e=parseFloat(f),c===!0||isFinite(e)?e||0:f):f}}),n.each(["height","width"],function(a,b){n.cssHooks[b]={get:function(a,c,d){return c?Xa.test(n.css(a,"display"))&&0===a.offsetWidth?Pa(a,Za,function(){return fb(a,b,d)}):fb(a,b,d):void 0},set:function(a,c,d){var e=d&&Ra(a);return db(a,c,d?eb(a,b,d,l.boxSizing&&"border-box"===n.css(a,"boxSizing",!1,e),e):0)}}}),l.opacity||(n.cssHooks.opacity={get:function(a,b){return Wa.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?.01*parseFloat(RegExp.$1)+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=n.isNumeric(b)?"alpha(opacity="+100*b+")":"",f=d&&d.filter||c.filter||"";c.zoom=1,(b>=1||""===b)&&""===n.trim(f.replace(Va,""))&&c.removeAttribute&&(c.removeAttribute("filter"),""===b||d&&!d.filter)||(c.filter=Va.test(f)?f.replace(Va,e):f+" "+e)}}),n.cssHooks.marginRight=Ua(l.reliableMarginRight,function(a,b){return b?Pa(a,{display:"inline-block"},Sa,[a,"marginRight"]):void 0}),n.cssHooks.marginLeft=Ua(l.reliableMarginLeft,function(a,b){return b?(parseFloat(Sa(a,"marginLeft"))||(n.contains(a.ownerDocument,a)?a.getBoundingClientRect().left-Pa(a,{ +marginLeft:0},function(){return a.getBoundingClientRect().left}):0))+"px":void 0}),n.each({margin:"",padding:"",border:"Width"},function(a,b){n.cssHooks[a+b]={expand:function(c){for(var d=0,e={},f="string"==typeof c?c.split(" "):[c];4>d;d++)e[a+V[d]+b]=f[d]||f[d-2]||f[0];return e}},Na.test(a)||(n.cssHooks[a+b].set=db)}),n.fn.extend({css:function(a,b){return Y(this,function(a,b,c){var d,e,f={},g=0;if(n.isArray(b)){for(d=Ra(a),e=b.length;e>g;g++)f[b[g]]=n.css(a,b[g],!1,d);return f}return void 0!==c?n.style(a,b,c):n.css(a,b)},a,b,arguments.length>1)},show:function(){return cb(this,!0)},hide:function(){return cb(this)},toggle:function(a){return"boolean"==typeof a?a?this.show():this.hide():this.each(function(){W(this)?n(this).show():n(this).hide()})}});function gb(a,b,c,d,e){return new gb.prototype.init(a,b,c,d,e)}n.Tween=gb,gb.prototype={constructor:gb,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||n.easing._default,this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(n.cssNumber[c]?"":"px")},cur:function(){var a=gb.propHooks[this.prop];return a&&a.get?a.get(this):gb.propHooks._default.get(this)},run:function(a){var b,c=gb.propHooks[this.prop];return this.options.duration?this.pos=b=n.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):this.pos=b=a,this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):gb.propHooks._default.set(this),this}},gb.prototype.init.prototype=gb.prototype,gb.propHooks={_default:{get:function(a){var b;return 1!==a.elem.nodeType||null!=a.elem[a.prop]&&null==a.elem.style[a.prop]?a.elem[a.prop]:(b=n.css(a.elem,a.prop,""),b&&"auto"!==b?b:0)},set:function(a){n.fx.step[a.prop]?n.fx.step[a.prop](a):1!==a.elem.nodeType||null==a.elem.style[n.cssProps[a.prop]]&&!n.cssHooks[a.prop]?a.elem[a.prop]=a.now:n.style(a.elem,a.prop,a.now+a.unit)}}},gb.propHooks.scrollTop=gb.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},n.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2},_default:"swing"},n.fx=gb.prototype.init,n.fx.step={};var hb,ib,jb=/^(?:toggle|show|hide)$/,kb=/queueHooks$/;function lb(){return a.setTimeout(function(){hb=void 0}),hb=n.now()}function mb(a,b){var c,d={height:a},e=0;for(b=b?1:0;4>e;e+=2-b)c=V[e],d["margin"+c]=d["padding"+c]=a;return b&&(d.opacity=d.width=a),d}function nb(a,b,c){for(var d,e=(qb.tweeners[b]||[]).concat(qb.tweeners["*"]),f=0,g=e.length;g>f;f++)if(d=e[f].call(c,b,a))return d}function ob(a,b,c){var d,e,f,g,h,i,j,k,m=this,o={},p=a.style,q=a.nodeType&&W(a),r=n._data(a,"fxshow");c.queue||(h=n._queueHooks(a,"fx"),null==h.unqueued&&(h.unqueued=0,i=h.empty.fire,h.empty.fire=function(){h.unqueued||i()}),h.unqueued++,m.always(function(){m.always(function(){h.unqueued--,n.queue(a,"fx").length||h.empty.fire()})})),1===a.nodeType&&("height"in b||"width"in b)&&(c.overflow=[p.overflow,p.overflowX,p.overflowY],j=n.css(a,"display"),k="none"===j?n._data(a,"olddisplay")||Ma(a.nodeName):j,"inline"===k&&"none"===n.css(a,"float")&&(l.inlineBlockNeedsLayout&&"inline"!==Ma(a.nodeName)?p.zoom=1:p.display="inline-block")),c.overflow&&(p.overflow="hidden",l.shrinkWrapBlocks()||m.always(function(){p.overflow=c.overflow[0],p.overflowX=c.overflow[1],p.overflowY=c.overflow[2]}));for(d in b)if(e=b[d],jb.exec(e)){if(delete b[d],f=f||"toggle"===e,e===(q?"hide":"show")){if("show"!==e||!r||void 0===r[d])continue;q=!0}o[d]=r&&r[d]||n.style(a,d)}else j=void 0;if(n.isEmptyObject(o))"inline"===("none"===j?Ma(a.nodeName):j)&&(p.display=j);else{r?"hidden"in r&&(q=r.hidden):r=n._data(a,"fxshow",{}),f&&(r.hidden=!q),q?n(a).show():m.done(function(){n(a).hide()}),m.done(function(){var b;n._removeData(a,"fxshow");for(b in o)n.style(a,b,o[b])});for(d in o)g=nb(q?r[d]:0,d,m),d in r||(r[d]=g.start,q&&(g.end=g.start,g.start="width"===d||"height"===d?1:0))}}function pb(a,b){var c,d,e,f,g;for(c in a)if(d=n.camelCase(c),e=b[d],f=a[c],n.isArray(f)&&(e=f[1],f=a[c]=f[0]),c!==d&&(a[d]=f,delete a[c]),g=n.cssHooks[d],g&&"expand"in g){f=g.expand(f),delete a[d];for(c in f)c in a||(a[c]=f[c],b[c]=e)}else b[d]=e}function qb(a,b,c){var d,e,f=0,g=qb.prefilters.length,h=n.Deferred().always(function(){delete i.elem}),i=function(){if(e)return!1;for(var b=hb||lb(),c=Math.max(0,j.startTime+j.duration-b),d=c/j.duration||0,f=1-d,g=0,i=j.tweens.length;i>g;g++)j.tweens[g].run(f);return h.notifyWith(a,[j,f,c]),1>f&&i?c:(h.resolveWith(a,[j]),!1)},j=h.promise({elem:a,props:n.extend({},b),opts:n.extend(!0,{specialEasing:{},easing:n.easing._default},c),originalProperties:b,originalOptions:c,startTime:hb||lb(),duration:c.duration,tweens:[],createTween:function(b,c){var d=n.Tween(a,j.opts,b,c,j.opts.specialEasing[b]||j.opts.easing);return j.tweens.push(d),d},stop:function(b){var c=0,d=b?j.tweens.length:0;if(e)return this;for(e=!0;d>c;c++)j.tweens[c].run(1);return b?(h.notifyWith(a,[j,1,0]),h.resolveWith(a,[j,b])):h.rejectWith(a,[j,b]),this}}),k=j.props;for(pb(k,j.opts.specialEasing);g>f;f++)if(d=qb.prefilters[f].call(j,a,k,j.opts))return n.isFunction(d.stop)&&(n._queueHooks(j.elem,j.opts.queue).stop=n.proxy(d.stop,d)),d;return n.map(k,nb,j),n.isFunction(j.opts.start)&&j.opts.start.call(a,j),n.fx.timer(n.extend(i,{elem:a,anim:j,queue:j.opts.queue})),j.progress(j.opts.progress).done(j.opts.done,j.opts.complete).fail(j.opts.fail).always(j.opts.always)}n.Animation=n.extend(qb,{tweeners:{"*":[function(a,b){var c=this.createTween(a,b);return X(c.elem,a,U.exec(b),c),c}]},tweener:function(a,b){n.isFunction(a)?(b=a,a=["*"]):a=a.match(G);for(var c,d=0,e=a.length;e>d;d++)c=a[d],qb.tweeners[c]=qb.tweeners[c]||[],qb.tweeners[c].unshift(b)},prefilters:[ob],prefilter:function(a,b){b?qb.prefilters.unshift(a):qb.prefilters.push(a)}}),n.speed=function(a,b,c){var d=a&&"object"==typeof a?n.extend({},a):{complete:c||!c&&b||n.isFunction(a)&&a,duration:a,easing:c&&b||b&&!n.isFunction(b)&&b};return d.duration=n.fx.off?0:"number"==typeof d.duration?d.duration:d.duration in n.fx.speeds?n.fx.speeds[d.duration]:n.fx.speeds._default,null!=d.queue&&d.queue!==!0||(d.queue="fx"),d.old=d.complete,d.complete=function(){n.isFunction(d.old)&&d.old.call(this),d.queue&&n.dequeue(this,d.queue)},d},n.fn.extend({fadeTo:function(a,b,c,d){return this.filter(W).css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){var e=n.isEmptyObject(a),f=n.speed(b,c,d),g=function(){var b=qb(this,n.extend({},a),f);(e||n._data(this,"finish"))&&b.stop(!0)};return g.finish=g,e||f.queue===!1?this.each(g):this.queue(f.queue,g)},stop:function(a,b,c){var d=function(a){var b=a.stop;delete a.stop,b(c)};return"string"!=typeof a&&(c=b,b=a,a=void 0),b&&a!==!1&&this.queue(a||"fx",[]),this.each(function(){var b=!0,e=null!=a&&a+"queueHooks",f=n.timers,g=n._data(this);if(e)g[e]&&g[e].stop&&d(g[e]);else for(e in g)g[e]&&g[e].stop&&kb.test(e)&&d(g[e]);for(e=f.length;e--;)f[e].elem!==this||null!=a&&f[e].queue!==a||(f[e].anim.stop(c),b=!1,f.splice(e,1));!b&&c||n.dequeue(this,a)})},finish:function(a){return a!==!1&&(a=a||"fx"),this.each(function(){var b,c=n._data(this),d=c[a+"queue"],e=c[a+"queueHooks"],f=n.timers,g=d?d.length:0;for(c.finish=!0,n.queue(this,a,[]),e&&e.stop&&e.stop.call(this,!0),b=f.length;b--;)f[b].elem===this&&f[b].queue===a&&(f[b].anim.stop(!0),f.splice(b,1));for(b=0;g>b;b++)d[b]&&d[b].finish&&d[b].finish.call(this);delete c.finish})}}),n.each(["toggle","show","hide"],function(a,b){var c=n.fn[b];n.fn[b]=function(a,d,e){return null==a||"boolean"==typeof a?c.apply(this,arguments):this.animate(mb(b,!0),a,d,e)}}),n.each({slideDown:mb("show"),slideUp:mb("hide"),slideToggle:mb("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){n.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),n.timers=[],n.fx.tick=function(){var a,b=n.timers,c=0;for(hb=n.now();c<b.length;c++)a=b[c],a()||b[c]!==a||b.splice(c--,1);b.length||n.fx.stop(),hb=void 0},n.fx.timer=function(a){n.timers.push(a),a()?n.fx.start():n.timers.pop()},n.fx.interval=13,n.fx.start=function(){ib||(ib=a.setInterval(n.fx.tick,n.fx.interval))},n.fx.stop=function(){a.clearInterval(ib),ib=null},n.fx.speeds={slow:600,fast:200,_default:400},n.fn.delay=function(b,c){return b=n.fx?n.fx.speeds[b]||b:b,c=c||"fx",this.queue(c,function(c,d){var e=a.setTimeout(c,b);d.stop=function(){a.clearTimeout(e)}})},function(){var a,b=d.createElement("input"),c=d.createElement("div"),e=d.createElement("select"),f=e.appendChild(d.createElement("option"));c=d.createElement("div"),c.setAttribute("className","t"),c.innerHTML=" <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",a=c.getElementsByTagName("a")[0],b.setAttribute("type","checkbox"),c.appendChild(b),a=c.getElementsByTagName("a")[0],a.style.cssText="top:1px",l.getSetAttribute="t"!==c.className,l.style=/top/.test(a.getAttribute("style")),l.hrefNormalized="/a"===a.getAttribute("href"),l.checkOn=!!b.value,l.optSelected=f.selected,l.enctype=!!d.createElement("form").enctype,e.disabled=!0,l.optDisabled=!f.disabled,b=d.createElement("input"),b.setAttribute("value",""),l.input=""===b.getAttribute("value"),b.value="t",b.setAttribute("type","radio"),l.radioValue="t"===b.value}();var rb=/\r/g,sb=/[\x20\t\r\n\f]+/g;n.fn.extend({val:function(a){var b,c,d,e=this[0];{if(arguments.length)return d=n.isFunction(a),this.each(function(c){var e;1===this.nodeType&&(e=d?a.call(this,c,n(this).val()):a,null==e?e="":"number"==typeof e?e+="":n.isArray(e)&&(e=n.map(e,function(a){return null==a?"":a+""})),b=n.valHooks[this.type]||n.valHooks[this.nodeName.toLowerCase()],b&&"set"in b&&void 0!==b.set(this,e,"value")||(this.value=e))});if(e)return b=n.valHooks[e.type]||n.valHooks[e.nodeName.toLowerCase()],b&&"get"in b&&void 0!==(c=b.get(e,"value"))?c:(c=e.value,"string"==typeof c?c.replace(rb,""):null==c?"":c)}}}),n.extend({valHooks:{option:{get:function(a){var b=n.find.attr(a,"value");return null!=b?b:n.trim(n.text(a)).replace(sb," ")}},select:{get:function(a){for(var b,c,d=a.options,e=a.selectedIndex,f="select-one"===a.type||0>e,g=f?null:[],h=f?e+1:d.length,i=0>e?h:f?e:0;h>i;i++)if(c=d[i],(c.selected||i===e)&&(l.optDisabled?!c.disabled:null===c.getAttribute("disabled"))&&(!c.parentNode.disabled||!n.nodeName(c.parentNode,"optgroup"))){if(b=n(c).val(),f)return b;g.push(b)}return g},set:function(a,b){var c,d,e=a.options,f=n.makeArray(b),g=e.length;while(g--)if(d=e[g],n.inArray(n.valHooks.option.get(d),f)>-1)try{d.selected=c=!0}catch(h){d.scrollHeight}else d.selected=!1;return c||(a.selectedIndex=-1),e}}}}),n.each(["radio","checkbox"],function(){n.valHooks[this]={set:function(a,b){return n.isArray(b)?a.checked=n.inArray(n(a).val(),b)>-1:void 0}},l.checkOn||(n.valHooks[this].get=function(a){return null===a.getAttribute("value")?"on":a.value})});var tb,ub,vb=n.expr.attrHandle,wb=/^(?:checked|selected)$/i,xb=l.getSetAttribute,yb=l.input;n.fn.extend({attr:function(a,b){return Y(this,n.attr,a,b,arguments.length>1)},removeAttr:function(a){return this.each(function(){n.removeAttr(this,a)})}}),n.extend({attr:function(a,b,c){var d,e,f=a.nodeType;if(3!==f&&8!==f&&2!==f)return"undefined"==typeof a.getAttribute?n.prop(a,b,c):(1===f&&n.isXMLDoc(a)||(b=b.toLowerCase(),e=n.attrHooks[b]||(n.expr.match.bool.test(b)?ub:tb)),void 0!==c?null===c?void n.removeAttr(a,b):e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:(a.setAttribute(b,c+""),c):e&&"get"in e&&null!==(d=e.get(a,b))?d:(d=n.find.attr(a,b),null==d?void 0:d))},attrHooks:{type:{set:function(a,b){if(!l.radioValue&&"radio"===b&&n.nodeName(a,"input")){var c=a.value;return a.setAttribute("type",b),c&&(a.value=c),b}}}},removeAttr:function(a,b){var c,d,e=0,f=b&&b.match(G);if(f&&1===a.nodeType)while(c=f[e++])d=n.propFix[c]||c,n.expr.match.bool.test(c)?yb&&xb||!wb.test(c)?a[d]=!1:a[n.camelCase("default-"+c)]=a[d]=!1:n.attr(a,c,""),a.removeAttribute(xb?c:d)}}),ub={set:function(a,b,c){return b===!1?n.removeAttr(a,c):yb&&xb||!wb.test(c)?a.setAttribute(!xb&&n.propFix[c]||c,c):a[n.camelCase("default-"+c)]=a[c]=!0,c}},n.each(n.expr.match.bool.source.match(/\w+/g),function(a,b){var c=vb[b]||n.find.attr;yb&&xb||!wb.test(b)?vb[b]=function(a,b,d){var e,f;return d||(f=vb[b],vb[b]=e,e=null!=c(a,b,d)?b.toLowerCase():null,vb[b]=f),e}:vb[b]=function(a,b,c){return c?void 0:a[n.camelCase("default-"+b)]?b.toLowerCase():null}}),yb&&xb||(n.attrHooks.value={set:function(a,b,c){return n.nodeName(a,"input")?void(a.defaultValue=b):tb&&tb.set(a,b,c)}}),xb||(tb={set:function(a,b,c){var d=a.getAttributeNode(c);return d||a.setAttributeNode(d=a.ownerDocument.createAttribute(c)),d.value=b+="","value"===c||b===a.getAttribute(c)?b:void 0}},vb.id=vb.name=vb.coords=function(a,b,c){var d;return c?void 0:(d=a.getAttributeNode(b))&&""!==d.value?d.value:null},n.valHooks.button={get:function(a,b){var c=a.getAttributeNode(b);return c&&c.specified?c.value:void 0},set:tb.set},n.attrHooks.contenteditable={set:function(a,b,c){tb.set(a,""===b?!1:b,c)}},n.each(["width","height"],function(a,b){n.attrHooks[b]={set:function(a,c){return""===c?(a.setAttribute(b,"auto"),c):void 0}}})),l.style||(n.attrHooks.style={get:function(a){return a.style.cssText||void 0},set:function(a,b){return a.style.cssText=b+""}});var zb=/^(?:input|select|textarea|button|object)$/i,Ab=/^(?:a|area)$/i;n.fn.extend({prop:function(a,b){return Y(this,n.prop,a,b,arguments.length>1)},removeProp:function(a){return a=n.propFix[a]||a,this.each(function(){try{this[a]=void 0,delete this[a]}catch(b){}})}}),n.extend({prop:function(a,b,c){var d,e,f=a.nodeType;if(3!==f&&8!==f&&2!==f)return 1===f&&n.isXMLDoc(a)||(b=n.propFix[b]||b,e=n.propHooks[b]),void 0!==c?e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:a[b]=c:e&&"get"in e&&null!==(d=e.get(a,b))?d:a[b]},propHooks:{tabIndex:{get:function(a){var b=n.find.attr(a,"tabindex");return b?parseInt(b,10):zb.test(a.nodeName)||Ab.test(a.nodeName)&&a.href?0:-1}}},propFix:{"for":"htmlFor","class":"className"}}),l.hrefNormalized||n.each(["href","src"],function(a,b){n.propHooks[b]={get:function(a){return a.getAttribute(b,4)}}}),l.optSelected||(n.propHooks.selected={get:function(a){var b=a.parentNode;return b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex),null},set:function(a){var b=a.parentNode;b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex)}}),n.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){n.propFix[this.toLowerCase()]=this}),l.enctype||(n.propFix.enctype="encoding");var Bb=/[\t\r\n\f]/g;function Cb(a){return n.attr(a,"class")||""}n.fn.extend({addClass:function(a){var b,c,d,e,f,g,h,i=0;if(n.isFunction(a))return this.each(function(b){n(this).addClass(a.call(this,b,Cb(this)))});if("string"==typeof a&&a){b=a.match(G)||[];while(c=this[i++])if(e=Cb(c),d=1===c.nodeType&&(" "+e+" ").replace(Bb," ")){g=0;while(f=b[g++])d.indexOf(" "+f+" ")<0&&(d+=f+" ");h=n.trim(d),e!==h&&n.attr(c,"class",h)}}return this},removeClass:function(a){var b,c,d,e,f,g,h,i=0;if(n.isFunction(a))return this.each(function(b){n(this).removeClass(a.call(this,b,Cb(this)))});if(!arguments.length)return this.attr("class","");if("string"==typeof a&&a){b=a.match(G)||[];while(c=this[i++])if(e=Cb(c),d=1===c.nodeType&&(" "+e+" ").replace(Bb," ")){g=0;while(f=b[g++])while(d.indexOf(" "+f+" ")>-1)d=d.replace(" "+f+" "," ");h=n.trim(d),e!==h&&n.attr(c,"class",h)}}return this},toggleClass:function(a,b){var c=typeof a;return"boolean"==typeof b&&"string"===c?b?this.addClass(a):this.removeClass(a):n.isFunction(a)?this.each(function(c){n(this).toggleClass(a.call(this,c,Cb(this),b),b)}):this.each(function(){var b,d,e,f;if("string"===c){d=0,e=n(this),f=a.match(G)||[];while(b=f[d++])e.hasClass(b)?e.removeClass(b):e.addClass(b)}else void 0!==a&&"boolean"!==c||(b=Cb(this),b&&n._data(this,"__className__",b),n.attr(this,"class",b||a===!1?"":n._data(this,"__className__")||""))})},hasClass:function(a){var b,c,d=0;b=" "+a+" ";while(c=this[d++])if(1===c.nodeType&&(" "+Cb(c)+" ").replace(Bb," ").indexOf(b)>-1)return!0;return!1}}),n.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(a,b){n.fn[b]=function(a,c){return arguments.length>0?this.on(b,null,a,c):this.trigger(b)}}),n.fn.extend({hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}});var Db=a.location,Eb=n.now(),Fb=/\?/,Gb=/(,)|(\[|{)|(}|])|"(?:[^"\\\r\n]|\\["\\\/bfnrt]|\\u[\da-fA-F]{4})*"\s*:?|true|false|null|-?(?!0\d)\d+(?:\.\d+|)(?:[eE][+-]?\d+|)/g;n.parseJSON=function(b){if(a.JSON&&a.JSON.parse)return a.JSON.parse(b+"");var c,d=null,e=n.trim(b+"");return e&&!n.trim(e.replace(Gb,function(a,b,e,f){return c&&b&&(d=0),0===d?a:(c=e||b,d+=!f-!e,"")}))?Function("return "+e)():n.error("Invalid JSON: "+b)},n.parseXML=function(b){var c,d;if(!b||"string"!=typeof b)return null;try{a.DOMParser?(d=new a.DOMParser,c=d.parseFromString(b,"text/xml")):(c=new a.ActiveXObject("Microsoft.XMLDOM"),c.async="false",c.loadXML(b))}catch(e){c=void 0}return c&&c.documentElement&&!c.getElementsByTagName("parsererror").length||n.error("Invalid XML: "+b),c};var Hb=/#.*$/,Ib=/([?&])_=[^&]*/,Jb=/^(.*?):[ \t]*([^\r\n]*)\r?$/gm,Kb=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Lb=/^(?:GET|HEAD)$/,Mb=/^\/\//,Nb=/^([\w.+-]+:)(?:\/\/(?:[^\/?#]*@|)([^\/?#:]*)(?::(\d+)|)|)/,Ob={},Pb={},Qb="*/".concat("*"),Rb=Db.href,Sb=Nb.exec(Rb.toLowerCase())||[];function Tb(a){return function(b,c){"string"!=typeof b&&(c=b,b="*");var d,e=0,f=b.toLowerCase().match(G)||[];if(n.isFunction(c))while(d=f[e++])"+"===d.charAt(0)?(d=d.slice(1)||"*",(a[d]=a[d]||[]).unshift(c)):(a[d]=a[d]||[]).push(c)}}function Ub(a,b,c,d){var e={},f=a===Pb;function g(h){var i;return e[h]=!0,n.each(a[h]||[],function(a,h){var j=h(b,c,d);return"string"!=typeof j||f||e[j]?f?!(i=j):void 0:(b.dataTypes.unshift(j),g(j),!1)}),i}return g(b.dataTypes[0])||!e["*"]&&g("*")}function Vb(a,b){var c,d,e=n.ajaxSettings.flatOptions||{};for(d in b)void 0!==b[d]&&((e[d]?a:c||(c={}))[d]=b[d]);return c&&n.extend(!0,a,c),a}function Wb(a,b,c){var d,e,f,g,h=a.contents,i=a.dataTypes;while("*"===i[0])i.shift(),void 0===e&&(e=a.mimeType||b.getResponseHeader("Content-Type"));if(e)for(g in h)if(h[g]&&h[g].test(e)){i.unshift(g);break}if(i[0]in c)f=i[0];else{for(g in c){if(!i[0]||a.converters[g+" "+i[0]]){f=g;break}d||(d=g)}f=f||d}return f?(f!==i[0]&&i.unshift(f),c[f]):void 0}function Xb(a,b,c,d){var e,f,g,h,i,j={},k=a.dataTypes.slice();if(k[1])for(g in a.converters)j[g.toLowerCase()]=a.converters[g];f=k.shift();while(f)if(a.responseFields[f]&&(c[a.responseFields[f]]=b),!i&&d&&a.dataFilter&&(b=a.dataFilter(b,a.dataType)),i=f,f=k.shift())if("*"===f)f=i;else if("*"!==i&&i!==f){if(g=j[i+" "+f]||j["* "+f],!g)for(e in j)if(h=e.split(" "),h[1]===f&&(g=j[i+" "+h[0]]||j["* "+h[0]])){g===!0?g=j[e]:j[e]!==!0&&(f=h[0],k.unshift(h[1]));break}if(g!==!0)if(g&&a["throws"])b=g(b);else try{b=g(b)}catch(l){return{state:"parsererror",error:g?l:"No conversion from "+i+" to "+f}}}return{state:"success",data:b}}n.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:Rb,type:"GET",isLocal:Kb.test(Sb[1]),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Qb,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/\bxml\b/,html:/\bhtml/,json:/\bjson\b/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":n.parseJSON,"text xml":n.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(a,b){return b?Vb(Vb(a,n.ajaxSettings),b):Vb(n.ajaxSettings,a)},ajaxPrefilter:Tb(Ob),ajaxTransport:Tb(Pb),ajax:function(b,c){"object"==typeof b&&(c=b,b=void 0),c=c||{};var d,e,f,g,h,i,j,k,l=n.ajaxSetup({},c),m=l.context||l,o=l.context&&(m.nodeType||m.jquery)?n(m):n.event,p=n.Deferred(),q=n.Callbacks("once memory"),r=l.statusCode||{},s={},t={},u=0,v="canceled",w={readyState:0,getResponseHeader:function(a){var b;if(2===u){if(!k){k={};while(b=Jb.exec(g))k[b[1].toLowerCase()]=b[2]}b=k[a.toLowerCase()]}return null==b?null:b},getAllResponseHeaders:function(){return 2===u?g:null},setRequestHeader:function(a,b){var c=a.toLowerCase();return u||(a=t[c]=t[c]||a,s[a]=b),this},overrideMimeType:function(a){return u||(l.mimeType=a),this},statusCode:function(a){var b;if(a)if(2>u)for(b in a)r[b]=[r[b],a[b]];else w.always(a[w.status]);return this},abort:function(a){var b=a||v;return j&&j.abort(b),y(0,b),this}};if(p.promise(w).complete=q.add,w.success=w.done,w.error=w.fail,l.url=((b||l.url||Rb)+"").replace(Hb,"").replace(Mb,Sb[1]+"//"),l.type=c.method||c.type||l.method||l.type,l.dataTypes=n.trim(l.dataType||"*").toLowerCase().match(G)||[""],null==l.crossDomain&&(d=Nb.exec(l.url.toLowerCase()),l.crossDomain=!(!d||d[1]===Sb[1]&&d[2]===Sb[2]&&(d[3]||("http:"===d[1]?"80":"443"))===(Sb[3]||("http:"===Sb[1]?"80":"443")))),l.data&&l.processData&&"string"!=typeof l.data&&(l.data=n.param(l.data,l.traditional)),Ub(Ob,l,c,w),2===u)return w;i=n.event&&l.global,i&&0===n.active++&&n.event.trigger("ajaxStart"),l.type=l.type.toUpperCase(),l.hasContent=!Lb.test(l.type),f=l.url,l.hasContent||(l.data&&(f=l.url+=(Fb.test(f)?"&":"?")+l.data,delete l.data),l.cache===!1&&(l.url=Ib.test(f)?f.replace(Ib,"$1_="+Eb++):f+(Fb.test(f)?"&":"?")+"_="+Eb++)),l.ifModified&&(n.lastModified[f]&&w.setRequestHeader("If-Modified-Since",n.lastModified[f]),n.etag[f]&&w.setRequestHeader("If-None-Match",n.etag[f])),(l.data&&l.hasContent&&l.contentType!==!1||c.contentType)&&w.setRequestHeader("Content-Type",l.contentType),w.setRequestHeader("Accept",l.dataTypes[0]&&l.accepts[l.dataTypes[0]]?l.accepts[l.dataTypes[0]]+("*"!==l.dataTypes[0]?", "+Qb+"; q=0.01":""):l.accepts["*"]);for(e in l.headers)w.setRequestHeader(e,l.headers[e]);if(l.beforeSend&&(l.beforeSend.call(m,w,l)===!1||2===u))return w.abort();v="abort";for(e in{success:1,error:1,complete:1})w[e](l[e]);if(j=Ub(Pb,l,c,w)){if(w.readyState=1,i&&o.trigger("ajaxSend",[w,l]),2===u)return w;l.async&&l.timeout>0&&(h=a.setTimeout(function(){w.abort("timeout")},l.timeout));try{u=1,j.send(s,y)}catch(x){if(!(2>u))throw x;y(-1,x)}}else y(-1,"No Transport");function y(b,c,d,e){var k,s,t,v,x,y=c;2!==u&&(u=2,h&&a.clearTimeout(h),j=void 0,g=e||"",w.readyState=b>0?4:0,k=b>=200&&300>b||304===b,d&&(v=Wb(l,w,d)),v=Xb(l,v,w,k),k?(l.ifModified&&(x=w.getResponseHeader("Last-Modified"),x&&(n.lastModified[f]=x),x=w.getResponseHeader("etag"),x&&(n.etag[f]=x)),204===b||"HEAD"===l.type?y="nocontent":304===b?y="notmodified":(y=v.state,s=v.data,t=v.error,k=!t)):(t=y,!b&&y||(y="error",0>b&&(b=0))),w.status=b,w.statusText=(c||y)+"",k?p.resolveWith(m,[s,y,w]):p.rejectWith(m,[w,y,t]),w.statusCode(r),r=void 0,i&&o.trigger(k?"ajaxSuccess":"ajaxError",[w,l,k?s:t]),q.fireWith(m,[w,y]),i&&(o.trigger("ajaxComplete",[w,l]),--n.active||n.event.trigger("ajaxStop")))}return w},getJSON:function(a,b,c){return n.get(a,b,c,"json")},getScript:function(a,b){return n.get(a,void 0,b,"script")}}),n.each(["get","post"],function(a,b){n[b]=function(a,c,d,e){return n.isFunction(c)&&(e=e||d,d=c,c=void 0),n.ajax(n.extend({url:a,type:b,dataType:e,data:c,success:d},n.isPlainObject(a)&&a))}}),n._evalUrl=function(a){return n.ajax({url:a,type:"GET",dataType:"script",cache:!0,async:!1,global:!1,"throws":!0})},n.fn.extend({wrapAll:function(a){if(n.isFunction(a))return this.each(function(b){n(this).wrapAll(a.call(this,b))});if(this[0]){var b=n(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&1===a.firstChild.nodeType)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){return n.isFunction(a)?this.each(function(b){n(this).wrapInner(a.call(this,b))}):this.each(function(){var b=n(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=n.isFunction(a);return this.each(function(c){n(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){n.nodeName(this,"body")||n(this).replaceWith(this.childNodes)}).end()}});function Yb(a){return a.style&&a.style.display||n.css(a,"display")}function Zb(a){if(!n.contains(a.ownerDocument||d,a))return!0;while(a&&1===a.nodeType){if("none"===Yb(a)||"hidden"===a.type)return!0;a=a.parentNode}return!1}n.expr.filters.hidden=function(a){return l.reliableHiddenOffsets()?a.offsetWidth<=0&&a.offsetHeight<=0&&!a.getClientRects().length:Zb(a)},n.expr.filters.visible=function(a){return!n.expr.filters.hidden(a)};var $b=/%20/g,_b=/\[\]$/,ac=/\r?\n/g,bc=/^(?:submit|button|image|reset|file)$/i,cc=/^(?:input|select|textarea|keygen)/i;function dc(a,b,c,d){var e;if(n.isArray(b))n.each(b,function(b,e){c||_b.test(a)?d(a,e):dc(a+"["+("object"==typeof e&&null!=e?b:"")+"]",e,c,d)});else if(c||"object"!==n.type(b))d(a,b);else for(e in b)dc(a+"["+e+"]",b[e],c,d)}n.param=function(a,b){var c,d=[],e=function(a,b){b=n.isFunction(b)?b():null==b?"":b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};if(void 0===b&&(b=n.ajaxSettings&&n.ajaxSettings.traditional),n.isArray(a)||a.jquery&&!n.isPlainObject(a))n.each(a,function(){e(this.name,this.value)});else for(c in a)dc(c,a[c],b,e);return d.join("&").replace($b,"+")},n.fn.extend({serialize:function(){return n.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var a=n.prop(this,"elements");return a?n.makeArray(a):this}).filter(function(){var a=this.type;return this.name&&!n(this).is(":disabled")&&cc.test(this.nodeName)&&!bc.test(a)&&(this.checked||!Z.test(a))}).map(function(a,b){var c=n(this).val();return null==c?null:n.isArray(c)?n.map(c,function(a){return{name:b.name,value:a.replace(ac,"\r\n")}}):{name:b.name,value:c.replace(ac,"\r\n")}}).get()}}),n.ajaxSettings.xhr=void 0!==a.ActiveXObject?function(){return this.isLocal?ic():d.documentMode>8?hc():/^(get|post|head|put|delete|options)$/i.test(this.type)&&hc()||ic()}:hc;var ec=0,fc={},gc=n.ajaxSettings.xhr();a.attachEvent&&a.attachEvent("onunload",function(){for(var a in fc)fc[a](void 0,!0)}),l.cors=!!gc&&"withCredentials"in gc,gc=l.ajax=!!gc,gc&&n.ajaxTransport(function(b){if(!b.crossDomain||l.cors){var c;return{send:function(d,e){var f,g=b.xhr(),h=++ec;if(g.open(b.type,b.url,b.async,b.username,b.password),b.xhrFields)for(f in b.xhrFields)g[f]=b.xhrFields[f];b.mimeType&&g.overrideMimeType&&g.overrideMimeType(b.mimeType),b.crossDomain||d["X-Requested-With"]||(d["X-Requested-With"]="XMLHttpRequest");for(f in d)void 0!==d[f]&&g.setRequestHeader(f,d[f]+"");g.send(b.hasContent&&b.data||null),c=function(a,d){var f,i,j;if(c&&(d||4===g.readyState))if(delete fc[h],c=void 0,g.onreadystatechange=n.noop,d)4!==g.readyState&&g.abort();else{j={},f=g.status,"string"==typeof g.responseText&&(j.text=g.responseText);try{i=g.statusText}catch(k){i=""}f||!b.isLocal||b.crossDomain?1223===f&&(f=204):f=j.text?200:404}j&&e(f,i,j,g.getAllResponseHeaders())},b.async?4===g.readyState?a.setTimeout(c):g.onreadystatechange=fc[h]=c:c()},abort:function(){c&&c(void 0,!0)}}}});function hc(){try{return new a.XMLHttpRequest}catch(b){}}function ic(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}n.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/\b(?:java|ecma)script\b/},converters:{"text script":function(a){return n.globalEval(a),a}}}),n.ajaxPrefilter("script",function(a){void 0===a.cache&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),n.ajaxTransport("script",function(a){if(a.crossDomain){var b,c=d.head||n("head")[0]||d.documentElement;return{send:function(e,f){b=d.createElement("script"),b.async=!0,a.scriptCharset&&(b.charset=a.scriptCharset),b.src=a.url,b.onload=b.onreadystatechange=function(a,c){(c||!b.readyState||/loaded|complete/.test(b.readyState))&&(b.onload=b.onreadystatechange=null,b.parentNode&&b.parentNode.removeChild(b),b=null,c||f(200,"success"))},c.insertBefore(b,c.firstChild)},abort:function(){b&&b.onload(void 0,!0)}}}});var jc=[],kc=/(=)\?(?=&|$)|\?\?/;n.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var a=jc.pop()||n.expando+"_"+Eb++;return this[a]=!0,a}}),n.ajaxPrefilter("json jsonp",function(b,c,d){var e,f,g,h=b.jsonp!==!1&&(kc.test(b.url)?"url":"string"==typeof b.data&&0===(b.contentType||"").indexOf("application/x-www-form-urlencoded")&&kc.test(b.data)&&"data");return h||"jsonp"===b.dataTypes[0]?(e=b.jsonpCallback=n.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,h?b[h]=b[h].replace(kc,"$1"+e):b.jsonp!==!1&&(b.url+=(Fb.test(b.url)?"&":"?")+b.jsonp+"="+e),b.converters["script json"]=function(){return g||n.error(e+" was not called"),g[0]},b.dataTypes[0]="json",f=a[e],a[e]=function(){g=arguments},d.always(function(){void 0===f?n(a).removeProp(e):a[e]=f,b[e]&&(b.jsonpCallback=c.jsonpCallback,jc.push(e)),g&&n.isFunction(f)&&f(g[0]),g=f=void 0}),"script"):void 0}),n.parseHTML=function(a,b,c){if(!a||"string"!=typeof a)return null;"boolean"==typeof b&&(c=b,b=!1),b=b||d;var e=x.exec(a),f=!c&&[];return e?[b.createElement(e[1])]:(e=ja([a],b,f),f&&f.length&&n(f).remove(),n.merge([],e.childNodes))};var lc=n.fn.load;n.fn.load=function(a,b,c){if("string"!=typeof a&&lc)return lc.apply(this,arguments);var d,e,f,g=this,h=a.indexOf(" ");return h>-1&&(d=n.trim(a.slice(h,a.length)),a=a.slice(0,h)),n.isFunction(b)?(c=b,b=void 0):b&&"object"==typeof b&&(e="POST"),g.length>0&&n.ajax({url:a,type:e||"GET",dataType:"html",data:b}).done(function(a){f=arguments,g.html(d?n("<div>").append(n.parseHTML(a)).find(d):a)}).always(c&&function(a,b){g.each(function(){c.apply(this,f||[a.responseText,b,a])})}),this},n.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(a,b){n.fn[b]=function(a){return this.on(b,a)}}),n.expr.filters.animated=function(a){return n.grep(n.timers,function(b){return a===b.elem}).length};function mc(a){return n.isWindow(a)?a:9===a.nodeType?a.defaultView||a.parentWindow:!1}n.offset={setOffset:function(a,b,c){var d,e,f,g,h,i,j,k=n.css(a,"position"),l=n(a),m={};"static"===k&&(a.style.position="relative"),h=l.offset(),f=n.css(a,"top"),i=n.css(a,"left"),j=("absolute"===k||"fixed"===k)&&n.inArray("auto",[f,i])>-1,j?(d=l.position(),g=d.top,e=d.left):(g=parseFloat(f)||0,e=parseFloat(i)||0),n.isFunction(b)&&(b=b.call(a,c,n.extend({},h))),null!=b.top&&(m.top=b.top-h.top+g),null!=b.left&&(m.left=b.left-h.left+e),"using"in b?b.using.call(a,m):l.css(m)}},n.fn.extend({offset:function(a){if(arguments.length)return void 0===a?this:this.each(function(b){n.offset.setOffset(this,a,b)});var b,c,d={top:0,left:0},e=this[0],f=e&&e.ownerDocument;if(f)return b=f.documentElement,n.contains(b,e)?("undefined"!=typeof e.getBoundingClientRect&&(d=e.getBoundingClientRect()),c=mc(f),{top:d.top+(c.pageYOffset||b.scrollTop)-(b.clientTop||0),left:d.left+(c.pageXOffset||b.scrollLeft)-(b.clientLeft||0)}):d},position:function(){if(this[0]){var a,b,c={top:0,left:0},d=this[0];return"fixed"===n.css(d,"position")?b=d.getBoundingClientRect():(a=this.offsetParent(),b=this.offset(),n.nodeName(a[0],"html")||(c=a.offset()),c.top+=n.css(a[0],"borderTopWidth",!0),c.left+=n.css(a[0],"borderLeftWidth",!0)),{top:b.top-c.top-n.css(d,"marginTop",!0),left:b.left-c.left-n.css(d,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var a=this.offsetParent;while(a&&!n.nodeName(a,"html")&&"static"===n.css(a,"position"))a=a.offsetParent;return a||Qa})}}),n.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(a,b){var c=/Y/.test(b);n.fn[a]=function(d){return Y(this,function(a,d,e){var f=mc(a);return void 0===e?f?b in f?f[b]:f.document.documentElement[d]:a[d]:void(f?f.scrollTo(c?n(f).scrollLeft():e,c?e:n(f).scrollTop()):a[d]=e)},a,d,arguments.length,null)}}),n.each(["top","left"],function(a,b){n.cssHooks[b]=Ua(l.pixelPosition,function(a,c){return c?(c=Sa(a,b),Oa.test(c)?n(a).position()[b]+"px":c):void 0})}),n.each({Height:"height",Width:"width"},function(a,b){n.each({ +padding:"inner"+a,content:b,"":"outer"+a},function(c,d){n.fn[d]=function(d,e){var f=arguments.length&&(c||"boolean"!=typeof d),g=c||(d===!0||e===!0?"margin":"border");return Y(this,function(b,c,d){var e;return n.isWindow(b)?b.document.documentElement["client"+a]:9===b.nodeType?(e=b.documentElement,Math.max(b.body["scroll"+a],e["scroll"+a],b.body["offset"+a],e["offset"+a],e["client"+a])):void 0===d?n.css(b,c,g):n.style(b,c,d,g)},b,f?d:void 0,f,null)}})}),n.fn.extend({bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return 1===arguments.length?this.off(a,"**"):this.off(b,a||"**",c)}}),n.fn.size=function(){return this.length},n.fn.andSelf=n.fn.addBack,"function"==typeof define&&define.amd&&define("jquery",[],function(){return n});var nc=a.jQuery,oc=a.$;return n.noConflict=function(b){return a.$===n&&(a.$=oc),b&&a.jQuery===n&&(a.jQuery=nc),n},b||(a.jQuery=a.$=n),n}); \ No newline at end of file diff --git a/civicrm/civicrm-version.php b/civicrm/civicrm-version.php index 2a3f2cd0ee..8ae23b5a96 100644 --- a/civicrm/civicrm-version.php +++ b/civicrm/civicrm-version.php @@ -1,7 +1,7 @@ <?php /** @deprecated */ function civicrmVersion( ) { - return array( 'version' => '5.11.0', + return array( 'version' => '5.12.0', 'cms' => 'Wordpress', 'revision' => '' ); } diff --git a/civicrm/composer.json b/civicrm/composer.json index 829f8ae59f..0a2bb8786f 100644 --- a/civicrm/composer.json +++ b/civicrm/composer.json @@ -49,15 +49,17 @@ "zetacomponents/base": "1.7.*", "zetacomponents/mail": "dev-1.7-civi", "marcj/topsort": "~1.1", - "phpoffice/phpword": "^0.14.0", + "phpoffice/phpword": "^0.15.0", "pear/Validate_Finance_CreditCard": "dev-master", "civicrm/civicrm-cxn-rpc": "~0.19.01.08", "pear/Auth_SASL": "1.1.0", "pear/Net_SMTP": "1.6.*", "pear/Net_socket": "1.0.*", + "pear/mail": "^1.4", "civicrm/civicrm-setup": "~0.2.0", "guzzlehttp/guzzle": "^6.3", - "psr/simple-cache": "~1.0.1" + "psr/simple-cache": "~1.0.1", + "cweagans/composer-patches": "~1.0" }, "repositories": [ { @@ -71,6 +73,7 @@ "bash tools/scripts/composer/tcpdf-cleanup.sh", "bash tools/scripts/composer/pear-exception-fix.sh", "bash tools/scripts/composer/net-smtp-fix.sh", + "bash tools/scripts/composer/pear-mail-fix.sh", "bash tools/scripts/composer/phpword-jquery.sh" ], "post-update-cmd": [ @@ -78,7 +81,18 @@ "bash tools/scripts/composer/tcpdf-cleanup.sh", "bash tools/scripts/composer/pear-exception-fix.sh", "bash tools/scripts/composer/net-smtp-fix.sh", + "bash tools/scripts/composer/pear-mail-fix.sh", "bash tools/scripts/composer/phpword-jquery.sh" ] + }, + "extra": { + "patches": { + "phpoffice/common": { + "Fix handling of libxml_disable_entity_loader": "tools/scripts/composer/patches/phpoffice-common-xml-entity-fix.patch" + }, + "phpoffice/phpword": { + "Fix handling of libxml_disable_entity_loader": "tools/scripts/composer/patches/phpword-libxml-fix-global-handling.patch" + } + } } } diff --git a/civicrm/composer.lock b/civicrm/composer.lock index b3028039cf..5e4c864c04 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": "3a5a920dad6f16458645ee4b5944716a", + "content-hash": "55c8f835d55c424d93e0e9dad1efc729", "packages": [ { "name": "civicrm/civicrm-cxn-rpc", @@ -80,6 +80,50 @@ "description": "CiviCRM installation library", "time": "2018-01-23T06:26:55+00:00" }, + { + "name": "cweagans/composer-patches", + "version": "1.6.5", + "source": { + "type": "git", + "url": "https://github.com/cweagans/composer-patches.git", + "reference": "2ec4f00ff5fb64de584c8c4aea53bf9053ecb0b3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/cweagans/composer-patches/zipball/2ec4f00ff5fb64de584c8c4aea53bf9053ecb0b3", + "reference": "2ec4f00ff5fb64de584c8c4aea53bf9053ecb0b3", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^1.0", + "php": ">=5.3.0" + }, + "require-dev": { + "composer/composer": "~1.0", + "phpunit/phpunit": "~4.6" + }, + "type": "composer-plugin", + "extra": { + "class": "cweagans\\Composer\\Patches" + }, + "autoload": { + "psr-4": { + "cweagans\\Composer\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Cameron Eagans", + "email": "me@cweagans.net" + } + ], + "description": "Provides a way to patch Composer packages.", + "time": "2018-05-11T18:00:16+00:00" + }, { "name": "dompdf/dompdf", "version": "v0.8.0", @@ -110,9 +154,6 @@ "extra": { "branch-alias": { "dev-develop": "0.7-dev" - }, - "patches_applied": { - "Fix Fatal error: Uncaught Dompdf Exception: No block-level parent found.": "tools/scripts/composer/patches/dompdf_no_block_level_parent_fix.patch" } }, "autoload": { @@ -503,6 +544,111 @@ "description": "Abstraction of various SASL mechanism responses", "time": "2017-03-07T14:37:05+00:00" }, + { + "name": "pear/console_getopt", + "version": "v1.4.1", + "source": { + "type": "git", + "url": "https://github.com/pear/Console_Getopt.git", + "reference": "82f05cd1aa3edf34e19aa7c8ca312ce13a6a577f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/pear/Console_Getopt/zipball/82f05cd1aa3edf34e19aa7c8ca312ce13a6a577f", + "reference": "82f05cd1aa3edf34e19aa7c8ca312ce13a6a577f", + "shasum": "" + }, + "type": "library", + "autoload": { + "psr-0": { + "Console": "./" + } + }, + "notification-url": "https://packagist.org/downloads/", + "include-path": [ + "./" + ], + "license": [ + "BSD-2-Clause" + ], + "authors": [ + { + "name": "Greg Beaver", + "email": "cellog@php.net", + "role": "Helper" + }, + { + "name": "Andrei Zmievski", + "email": "andrei@php.net", + "role": "Lead" + }, + { + "name": "Stig Bakken", + "email": "stig@php.net", + "role": "Developer" + } + ], + "description": "More info available on: http://pear.php.net/package/Console_Getopt", + "time": "2015-07-20T20:28:12+00:00" + }, + { + "name": "pear/mail", + "version": "v1.4.1", + "source": { + "type": "git", + "url": "https://github.com/pear/Mail.git", + "reference": "9609ed5e42ac5b221dfd9af85de005c59d418ee7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/pear/Mail/zipball/9609ed5e42ac5b221dfd9af85de005c59d418ee7", + "reference": "9609ed5e42ac5b221dfd9af85de005c59d418ee7", + "shasum": "" + }, + "require": { + "pear/pear-core-minimal": "~1.9", + "php": ">=5.2.1" + }, + "require-dev": { + "pear/pear": "*" + }, + "suggest": { + "pear/net_smtp": "Install optionally via your project's composer.json" + }, + "type": "library", + "autoload": { + "psr-0": { + "Mail": "./" + } + }, + "notification-url": "https://packagist.org/downloads/", + "include-path": [ + "./" + ], + "license": [ + "BSD-2-Clause" + ], + "authors": [ + { + "name": "Chuck Hagenbuch", + "email": "chuck@horde.org", + "role": "Lead" + }, + { + "name": "Richard Heyes", + "email": "richard@phpguru.org", + "role": "Developer" + }, + { + "name": "Aleksander Machniak", + "email": "alec@alec.pl", + "role": "Developer" + } + ], + "description": "Class that provides multiple interfaces for sending emails.", + "homepage": "http://pear.php.net/package/Mail", + "time": "2017-04-11T17:27:29+00:00" + }, { "name": "pear/net_smtp", "version": "1.6.3", @@ -529,14 +675,6 @@ "pear/auth_sasl": "Install optionally via your project's composer.json" }, "type": "library", - "extra": { - "patches_applied": { - "CRM-8744 Display CiviCRM Specific error message": "tools/scripts/composer/patches/net-smtp-patch.patch", - "Fix PHP7 Compliance": "tools/scripts/composer/patches/net-smtp-php7-patch.patch", - "Fix Pass by reference issues": "tools/scripts/composer/patches/net-smtp-ref-patch.patch", - "Fix TLS support issue in PHP5.6": "tools/scripts/composer/patches/net-smtp-tls-patch.patch" - } - }, "autoload": { "psr-0": { "Net": "./" @@ -624,6 +762,50 @@ "description": "More info available on: http://pear.php.net/package/Net_Socket", "time": "2014-02-20T19:27:06+00:00" }, + { + "name": "pear/pear-core-minimal", + "version": "v1.10.7", + "source": { + "type": "git", + "url": "https://github.com/pear/pear-core-minimal.git", + "reference": "19a3e0fcd50492c4357372f623f55f1b144346da" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/pear/pear-core-minimal/zipball/19a3e0fcd50492c4357372f623f55f1b144346da", + "reference": "19a3e0fcd50492c4357372f623f55f1b144346da", + "shasum": "" + }, + "require": { + "pear/console_getopt": "~1.4", + "pear/pear_exception": "~1.0" + }, + "replace": { + "rsky/pear-core-min": "self.version" + }, + "type": "library", + "autoload": { + "psr-0": { + "": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "include-path": [ + "src/" + ], + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Christian Weiske", + "email": "cweiske@php.net", + "role": "Lead" + } + ], + "description": "Minimal set of PEAR core files to be used as composer dependency", + "time": "2018-12-05T20:03:52+00:00" + }, { "name": "pear/pear_exception", "version": "v1.0.0", @@ -799,16 +981,16 @@ }, { "name": "phpoffice/common", - "version": "v0.2.6", + "version": "0.2.9", "source": { "type": "git", "url": "https://github.com/PHPOffice/Common.git", - "reference": "c9be70c80637c28c728be78e66aad4878a34f8dd" + "reference": "edb5d32b1e3400a35a5c91e2539ed6f6ce925e4d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHPOffice/Common/zipball/c9be70c80637c28c728be78e66aad4878a34f8dd", - "reference": "c9be70c80637c28c728be78e66aad4878a34f8dd", + "url": "https://api.github.com/repos/PHPOffice/Common/zipball/edb5d32b1e3400a35a5c91e2539ed6f6ce925e4d", + "reference": "edb5d32b1e3400a35a5c91e2539ed6f6ce925e4d", "shasum": "" }, "require": { @@ -819,11 +1001,16 @@ "phpdocumentor/phpdocumentor": "2.*", "phploc/phploc": "2.*", "phpmd/phpmd": "2.*", - "phpunit/phpunit": "3.7.*", + "phpunit/phpunit": "^4.8.36 || ^7.0", "sebastian/phpcpd": "2.*", "squizlabs/php_codesniffer": "2.*" }, "type": "library", + "extra": { + "patches_applied": { + "Fix handling of libxml_disable_entity_loader": "tools/scripts/composer/patches/phpoffice-common-xml-entity-fix.patch" + } + }, "autoload": { "psr-4": { "PhpOffice\\Common\\": "src/Common/" @@ -850,38 +1037,39 @@ "office", "php" ], - "time": "2016-07-07T17:26:55+00:00" + "time": "2018-07-13T14:12:34+00:00" }, { "name": "phpoffice/phpword", - "version": "v0.14.0", + "version": "0.15.0", "source": { "type": "git", "url": "https://github.com/PHPOffice/PHPWord.git", - "reference": "b614497ae6dd44280be1c2dda56772198bcd25ae" + "reference": "dfa2f36cad2b632b7ab1c56473e4f5db9a7caf7f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHPOffice/PHPWord/zipball/b614497ae6dd44280be1c2dda56772198bcd25ae", - "reference": "b614497ae6dd44280be1c2dda56772198bcd25ae", + "url": "https://api.github.com/repos/PHPOffice/PHPWord/zipball/dfa2f36cad2b632b7ab1c56473e4f5db9a7caf7f", + "reference": "dfa2f36cad2b632b7ab1c56473e4f5db9a7caf7f", "shasum": "" }, "require": { "ext-xml": "*", "php": "^5.3.3 || ^7.0", - "phpoffice/common": "^0.2", - "zendframework/zend-escaper": "^2.2", - "zendframework/zend-stdlib": "^2.2 || ^3.0" + "phpoffice/common": "^0.2.9", + "zendframework/zend-escaper": "^2.2" }, "require-dev": { "dompdf/dompdf": "0.8.*", - "friendsofphp/php-cs-fixer": "^2.0", - "mpdf/mpdf": "5.* || 6.* || 7.*", - "phpdocumentor/phpdocumentor": "2.*", + "ext-gd": "*", + "ext-zip": "*", + "friendsofphp/php-cs-fixer": "^2.2", + "mpdf/mpdf": "5.7.4 || 6.* || 7.*", + "php-coveralls/php-coveralls": "1.1.0 || ^2.0", "phploc/phploc": "2.* || 3.* || 4.*", "phpmd/phpmd": "2.*", - "phpunit/phpunit": "^4.8.36 || ^5.0", - "squizlabs/php_codesniffer": "^2.7", + "phpunit/phpunit": "^4.8.36 || ^7.0", + "squizlabs/php_codesniffer": "^2.9", "tecnickcom/tcpdf": "6.*" }, "suggest": { @@ -892,6 +1080,14 @@ "ext-zip": "Allows writing OOXML and ODF" }, "type": "library", + "extra": { + "branch-alias": { + "dev-develop": "0.16-dev" + }, + "patches_applied": { + "Fix handling of libxml_disable_entity_loader": "tools/scripts/composer/patches/phpword-libxml-fix-global-handling.patch" + } + }, "autoload": { "psr-4": { "PhpOffice\\PhpWord\\": "src/PhpWord" @@ -953,7 +1149,7 @@ "word", "writer" ], - "time": "2017-12-29T01:30:53+00:00" + "time": "2018-07-14T16:59:43+00:00" }, { "name": "phpseclib/phpseclib", diff --git a/civicrm/css/civicrm.css b/civicrm/css/civicrm.css index 73e5e72fd8..087f64c56c 100644 --- a/civicrm/css/civicrm.css +++ b/civicrm/css/civicrm.css @@ -5,8 +5,7 @@ * Other civi blocks outside the main container also have the class crm-container (but not the id) * All styles should start with .crm-container unless they are specific to the main div only */ -.crm-container input, -#civicrm-menu input { +.crm-container input { box-sizing: content-box; } @@ -2922,7 +2921,6 @@ tbody.scrollContent tr.alternateRow { .crm-container div.status, -div.m ul#civicrm-menu, .crm-container #help, .crm-container .help, .crm-container .ui-tabs-panel, diff --git a/civicrm/css/civicrmNavigation.css b/civicrm/css/civicrmNavigation.css deleted file mode 100644 index 5cf48d3f3c..0000000000 --- a/civicrm/css/civicrmNavigation.css +++ /dev/null @@ -1,181 +0,0 @@ -html>body div.outerbox -{ - padding: 0 5px 5px 0; - z-index:999999; - font-size: 13px; - margin-top:2px; -} -html>body div.outerbox div.shadowbox1 -{ - position: absolute; - right: 0; - bottom: 5px; - width: 5px; - height: 100%; - background: url(../i/myshadow.png) no-repeat right top; -} -html>body div.outerbox div.shadowbox2 -{ - position: absolute; - bottom: 0; - right: 5px; - height: 5px; - width: 100%; - background: url(../i/myshadow.png) left bottom; -} -html>body div.outerbox div.shadowbox3 -{ - position: absolute; - bottom: 0; - right: 0; - height: 5px; - width: 5px; - background: url(../i/myshadow.png) no-repeat right bottom; -} -html>body .innerbox -{ - margin: 0; - z-index:999999; - margin-left:10px; -} - -#root-menu-div ul { - border: 1px solid #000; -} -#root-menu-div li{ - white-space:nowrap; - background-image: none; - text-align: left; -} -* html #root-menu-div li{ - height: 1.5em; /* fixing ie6 problem */ -} -#civicrm-menu, -#root-menu-div ul { - list-style: none; - margin: 0; - padding: 0; - background:#5D5D5D; - color: white; - cursor: default; - font-size: 12px; - font-family: Tahoma, Verdana, Arial, sans-serif; -} - -#civicrm-menu { - position:fixed; - top:0; - left:0; - background:#1B1B1B repeat-x; - width:100%; - height:27px; - z-index:99999; - overflow: hidden; -} - -li.menu-separator.active{ - background-color: transparent; -} - -.menu-ul li.active { - background-color: #aaa; -} - -#civicrm-menu .activetarget{ - background-color: #aaa; -} - -#civicrm-menu li a, #root-menu-div li a { - color:white; - cursor:pointer; - display:block; - font-weight:normal; - text-decoration:none; - border:0; -} - -* html div.menu-item { - display: inline; /* fixes problem in ie6 */ -} - -li.menumain { - float: left; - padding: 3px 10px; - background-image: none; - border-right: 1px solid #5D5D5D; - margin:0; -} - -#root-menu-div .menu-ul li { - margin: 0; - padding: 0 20px 0 2px; -} - -div.menu-item { - padding: 1px 10px 1px 4px; - height: auto; -} -#civicrm-menu .menu-item-arrow, -#root-menu-div .menu-item-arrow { - position: absolute; - right: 4px; - top: 6px; -} -#civicrm-menu i, -#root-menu-div i { - margin-right: 5px; -} -li.menu-separator{ - border-bottom: 1px solid #000; - font-size: 0; /* for ie */ - height: 0; - line-height: 0; /* for ie */ - margin: 2px 0; -} -#civicrm-menu .crm-logo-sm, -.crm-container .crm-logo-sm { - background: url('../i/logo_sm.png') no-repeat; - display: inline-block; - width: 16px; - height: 16px; - vertical-align: middle; -} - -#civicrm-menu .ui-autocomplete-input, -.crm-container .ui-autocomplete-input { - background: white url("../bower_components/select2/select2.png") no-repeat scroll right -23px; - padding-right: 16px; - /* so that text doesn't flow on top of icon */ -} - -#civicrm-menu #crm-qsearch { - padding: 1px 0 1px 2px; - background-color: transparent !important; - border-right: none; -} - -#civicrm-menu #crm-qsearch input { - background-color: #eaeaea; - border: 1px solid black; - margin: 0; - padding: 2px 16px 3px 2px; - height: 17px; -} -#civicrm-menu #crm-qsearch input:hover, -#civicrm-menu #crm-qsearch input:focus, -#civicrm-menu #crm-qsearch.activetarget input { - background-color: #ffffff; -} -/* This ensures the drop-down menus appear at the right height */ -#civicrm-menu > li.menumain { - height: 19px !important; -} - -/* No results */ -.crm-quickSearch-results.ui-menu-disabled { - opacity: .9; - background-color: #f8f8f8; -} -.crm-quickSearch-results.ui-menu-disabled li { - cursor: default; -} diff --git a/civicrm/css/crm-menubar.css b/civicrm/css/crm-menubar.css new file mode 100644 index 0000000000..06800779a6 --- /dev/null +++ b/civicrm/css/crm-menubar.css @@ -0,0 +1,347 @@ +/* CiviCRM navigation menu stylesheet */ + +#civicrm-menu-nav { + line-height: 0; + text-align: left; + font-size: 13px; +} +#civicrm-menu { + background-color: #f2f2f2; + width: 100%; + z-index: 500; + height: auto; + margin: 0; +} +#civicrm-menu i { + margin-right: 3px; +} +#civicrm-menu li { + border: none; + padding: 0; +} +#civicrm-menu li a { + padding: 12px 8px; + text-decoration: none; + color: #333; + box-shadow: none; + border: none; +} +#civicrm-menu li a[href="#"] { + cursor: default; +} +#civicrm-menu li li a { + padding: 6px 36px 6px 10px; +} +#civicrm-menu li.crm-menu-border-bottom:not(:last-child) { + border-bottom: 1px solid #bbb; +} +#civicrm-menu li:not(.crm-menu-border-bottom) + li.crm-menu-border-top { + border-top: 1px solid #bbb; +} +#civicrm-menu li a:focus, +#civicrm-menu li a:hover, +#civicrm-menu li a.highlighted { + text-decoration: none; + background-color: #fff; +} +#civicrm-menu li li .sub-arrow:before { + content: "\f0da"; + font-family: 'FontAwesome'; + color: #666; + float: right; + margin-right: -25px; +} +/* x icon */ +#crm-menubar-state:checked ~ .crm-menubar-toggle-btn .crm-menubar-toggle-btn-icon { + height: 0; + background: transparent; +} +#crm-menubar-state:checked ~ .crm-menubar-toggle-btn .crm-menubar-toggle-btn-icon:before { + top: 0; + -webkit-transform: rotate(-45deg); + transform: rotate(-45deg); +} +#crm-menubar-state:checked ~ .crm-menubar-toggle-btn .crm-menubar-toggle-btn-icon:after { + top: 0; + -webkit-transform: rotate(45deg); + transform: rotate(45deg); +} +/* hide menu state checkbox (keep it visible to screen readers) */ +#civicrm-menu-nav #crm-menubar-state { + position: absolute; + width: 1px; + height: 1px; + margin: -1px; + border: 0; + padding: 0; + overflow: hidden; + clip: rect(1px,1px,1px,1px); +} +#civicrm-menu-nav .crm-menubar-toggle-btn { + position: relative; + display: inline-block; + width: 57px; + height: 28px; + text-indent: 28px; + white-space: nowrap; + overflow: hidden; + cursor: pointer; + color: transparent; + -webkit-tap-highlight-color: rgba(0,0,0,0); + background-color: #333; +} + +/* responsive icon */ + +#civicrm-menu-nav .crm-menubar-toggle-btn-icon, +#civicrm-menu-nav .crm-menubar-toggle-btn-icon:before, +#civicrm-menu-nav .crm-menubar-toggle-btn-icon:after { + position: absolute; + top: 50%; + left: 27px; + height: 2px; + width: 24px; + background: #bbb; + -webkit-transition: all 0.25s; + transition: all 0.25s; +} +#civicrm-menu-nav .crm-menubar-toggle-btn-icon:before { + content: ''; + top: -7px; + left: 0; +} +#civicrm-menu-nav .crm-menubar-toggle-btn-icon:after { + content: ''; + top: 7px; + left: 0; +} + +/* Quicksearch */ +#crm-qsearch { + padding: 1px 0 1px 2px; + background-color: transparent !important; +} +#civicrm-menu #crm-qsearch > a { + padding: 2px 0 0 2px; +} + +input#crm-qsearch-input { + box-sizing: border-box; + background-color: #eaeaea; + font-size: 13px; + border: 1px solid #ccc; + margin: 4px 4px 0; + padding: 2px 8px; + height: 30px; + width: 30px; + transition: width .5s .05s, background-color .3s .05s; +} +a.highlighted #crm-qsearch-input, +#crm-qsearch-input:focus, +#crm-qsearch-input.has-user-input { + background-color: white; + width: 130px; +} +input#crm-qsearch-input:-ms-input-placeholder { + font-family: 'FontAwesome'; +} +input#crm-qsearch-input::-webkit-input-placeholder { + font-family: 'FontAwesome'; +} +input#crm-qsearch-input::-moz-placeholder { + font-family: 'FontAwesome'; +} +input#crm-qsearch-input::placeholder { + font-family: 'FontAwesome'; +} + +ul.crm-quickSearch-results { + z-index: 100001; +} +ul.crm-quickSearch-results.ui-state-disabled { + opacity: .8; +} + +#civicrm-menu-nav .crm-logo-sm { + background: url(../i/logo_sm.png) no-repeat; + display: inline-block; + width: 16px; + height: 16px; + margin: 0 2px; +} + +#civicrm-menu #crm-menubar-toggle-position { + float: right; +} +#civicrm-menu #crm-menubar-toggle-position a i { + color: #888; + margin: 0; + border-top: 2px solid #888; + font-size: 11px; +} +body.crm-menubar-over-cms-menu #crm-menubar-toggle-position a i { + transform: rotate(180deg); +} + +@media (min-width: 768px) { + + /* Switch to desktop layout + ----------------------------------------------- + These transform the menu tree from + collapsible to desktop (navbar + dropdowns) + -----------------------------------------------*/ + /* start... (it's not recommended editing these rules) */ + #civicrm-menu ul{position:absolute;width:12em;} + #civicrm-menu li{float:left;} + #civicrm-menu.sm-rtl li{float:right;} + #civicrm-menu ul li,#civicrm-menu.sm-rtl ul li,#civicrm-menu.sm-vertical li{float:none;} + #civicrm-menu a{white-space:nowrap;} + #civicrm-menu ul a,#civicrm-menu.sm-vertical a{white-space:normal;} + #civicrm-menu .sm-nowrap > li > a,#civicrm-menu .sm-nowrap > li > :not(ul) a{white-space:nowrap;} + /* ...end */ + + /* hide the button in desktop view */ + #civicrm-menu-nav .crm-menubar-toggle-btn { + position: absolute; + top: -99999px; + } + + #civicrm-menu { + border-bottom: 1px solid #ccc; + } + + body.crm-menubar-below-cms-menu > #civicrm-menu-nav #civicrm-menu { + top: 30px; + } + + #civicrm-menu ul { + background-color: #fff; + box-shadow: 0px 0px 2px 0 rgba(0,0,0,0.3); + } + + #civicrm-menu > li > a { + height: 40px; + } + + #civicrm-menu > li > a.highlighted { + z-index: 200000; + } + + #civicrm-menu ul li a:focus, + #civicrm-menu ul li a:hover, + #civicrm-menu ul li a.highlighted { + background-color: #f2f2f2; + color: #222; + } + + body.crm-menubar-over-cms-menu #civicrm-menu, + body.crm-menubar-below-cms-menu #civicrm-menu { + position: fixed; + top: 0; + } + + body.crm-menubar-over-cms-menu #civicrm-menu { + z-index: 99999; + } + + body.crm-menubar-hidden #civicrm-menu { + display: none; + } +} + +@media (max-width: 768px) { + /* hide the menu in mobile view */ + #crm-menubar-state:not(:checked) ~ #civicrm-menu { + display: none; + } + #civicrm-menu { + z-index: 100000; + background-color: #333; + } + #civicrm-menu ul { + background-color: #444; + } + #civicrm-menu ul ul { + background-color: #555; + } + #civicrm-menu ul ul ul { + background-color: #666; + } + #civicrm-menu li { + padding: 5px; + } + #civicrm-menu li a { + text-align: center; + font-size: 14px; + color: #ddd; + } + #civicrm-menu li a:focus, + #civicrm-menu li a:hover, + #civicrm-menu li a.highlighted { + background-color: #676767; + color: #fff; + } + #civicrm-menu li .sub-arrow:before, + #civicrm-menu li li .sub-arrow:before { + content: "\f0da"; + font-family: 'FontAwesome'; + color: #bbb; + float: none; + margin-left: 10px; + } + #civicrm-menu li a.highlighted .sub-arrow:before { + content: "\f0d7"; + } + #civicrm-menu-nav { + position: fixed; + background: transparent; + pointer-events: none; + top: 0; + left: 0; + height: 50px; + width: 100%; + z-index: 100000; + } + #civicrm-menu-nav > * { + pointer-events: auto; + } + #civicrm-menu-nav .crm-menubar-toggle-btn { + margin-left: 20px; + z-index: 110000; + margin-top: 10px; + } + #civicrm-menu-nav .crm-menubar-toggle-btn span.crm-menu-logo { + display: block; + position: absolute; + left: 5px; + width: 18px; + height: 18px; + background: url(../i/logo_lg.png) no-repeat; + background-size: 18px; + top: 6px; + } + #crm-qsearch { + text-align: center; + } + #crm-qsearch .sub-arrow { + display: none; + } + + #civicrm-menu li[data-name="Hide Menu"] { + display: none; + } + + #crm-qsearch-input { + width: 14em !important; + } + + #crm-menubar-toggle-position { + display: none; + } + + /* Make sure we can click overlapped submenus in responsive mode */ + #civicrm-menu li ul li { + z-index: 110000; + background-color: inherit; + } +} diff --git a/civicrm/css/joomla.css b/civicrm/css/joomla.css index 5c5d55e415..d49a764898 100644 --- a/civicrm/css/joomla.css +++ b/civicrm/css/joomla.css @@ -294,10 +294,6 @@ br.clear { /* Joomla Admin Menu alterations */ /* Moved from civicrm.css in v3.2 */ -ul#civicrm-menu { - position:relative; - z-index: 1; -} div#toolbar-box div.m { padding: 0px !important; @@ -310,9 +306,6 @@ div#toolbar-box, div#toolbar-box div.m{ height: auto; } -ul#civicrm-menu li#crm-qsearch { - height:0px; -} .crm-tab-button, .ui-tabs .ui-tabs-nav li { border: 1px; @@ -390,25 +383,12 @@ body.admin.com_civicrm .container-fluid.container-main { padding: 0; border-top: 1px solid #787878; } +body.admin.com_civicrm.task-civicrmupgrade .container-fluid.container-main { + padding: 10px 25px 25px; +} body.admin.com_civicrm #crm-nav-menu-container { padding-bottom: 0 !important; } body.admin.com_civicrm #content-right { padding: 12px; } -body.admin.com_civicrm #civicrm-menu #crm-qsearch { - padding-left: 20px; -} -body.admin.com_civicrm #root-menu-div div.outerbox:first-of-type { - margin-left: 20px; -} -body.admin.com_civicrm div.outerbox { - z-index: 1000; -} - -/* Shoreditch-specific */ - -body.admin.com_civicrm { - padding-top: 0px !important; - margin-top: 30px !important; -} diff --git a/civicrm/css/menubar-backdrop.css b/civicrm/css/menubar-backdrop.css new file mode 100644 index 0000000000..b238c51f40 --- /dev/null +++ b/civicrm/css/menubar-backdrop.css @@ -0,0 +1,44 @@ +@media (min-width: 768px) { + + body.crm-menubar-visible.crm-menubar-over-cms-menu { + border-top: 0 none !important; + margin-top: 40px; + } + body.crm-menubar-visible.crm-menubar-over-cms-menu.crm-menubar-wrapped { + margin-top: 80px; + } + body.crm-menubar-visible.crm-menubar-over-cms-menu #admin-bar { + visibility: hidden; + } + + body.crm-menubar-visible.crm-menubar-below-cms-menu { + padding-top: 37px; + } + body.crm-menubar-visible.crm-menubar-below-cms-menu.crm-menubar-wrapped { + padding-top: 77px; + } + .admin-bar body.crm-menubar-below-cms-menu #civicrm-menu { + z-index: 999; + } + .admin-bar body.backdrop-admin-bar-position-absolute #civicrm-menu { + position: absolute; + } + body.crm-menubar-below-cms-menu #admin-bar { + z-index: 1000; + } + +} +@media (max-width: 768px) { + + body.backdrop-admin-bar-position-absolute #civicrm-menu-nav { + position: absolute; + } + + body #civicrm-menu-nav .crm-menubar-toggle-btn { + position: absolute; + right: 120px; + top: 0; + margin-top: 3px; + } + +} diff --git a/civicrm/css/menubar-drupal7.css b/civicrm/css/menubar-drupal7.css new file mode 100644 index 0000000000..8317feb022 --- /dev/null +++ b/civicrm/css/menubar-drupal7.css @@ -0,0 +1,115 @@ +@media (min-width: 768px) { + + body.crm-menubar-visible.crm-menubar-over-cms-menu #toolbar { + display: none; + } + + body.crm-menubar-visible.crm-menubar-over-cms-menu { + padding-top: 40px !important; + } + body.crm-menubar-visible.crm-menubar-over-cms-menu.crm-menubar-wrapped { + padding-top: 80px !important; + } + + body.crm-menubar-visible.crm-menubar-over-cms-menu #toolbar .toolbar-drawer { + display: none !important; + } + + body.toolbar.crm-menubar-visible.crm-menubar-below-cms-menu { + padding-top: 70px !important; + } + body.toolbar.crm-menubar-visible.crm-menubar-below-cms-menu.crm-menubar-wrapped { + padding-top: 110px !important; + } + + body.toolbar.toolbar-drawer.crm-menubar-visible.crm-menubar-below-cms-menu { + padding-top: 104px !important; + } + body.toolbar.toolbar-drawer.crm-menubar-visible.crm-menubar-below-cms-menu.crm-menubar-wrapped { + padding-top: 144px !important; + } + + body.toolbar.crm-menubar-visible.crm-menubar-below-cms-menu #toolbar { + -moz-box-shadow: none; + -webkit-box-shadow: none; + box-shadow: none; + } + + body.toolbar.toolbar-drawer.crm-menubar-below-cms-menu #civicrm-menu { + top: 64px !important; + } + + /* For admin_menu */ + body.admin-menu.crm-menubar-visible.crm-menubar-over-cms-menu { + margin-top: 0 !important; + } + body.crm-menubar-visible.crm-menubar-below-cms-menu #admin-menu { + min-height: 30px; + } + body.crm-menubar-visible.crm-menubar-below-cms-menu.admin-menu { + padding-top: 40px !important; + } + body.crm-menubar-visible.crm-menubar-below-cms-menu.crm-menubar-wrapped.admin-menu { + padding-top: 80px !important; + } + body.crm-menubar-visible.crm-menubar-over-cms-menu #admin-menu { + display: none; + } + + /* For adminimal_admin_menu */ + body.crm-menubar-visible.crm-menubar-over-cms-menu.admin-menu.adminimal-menu:before { + height: 0; + } + body.crm-menubar-visible.crm-menubar-below-cms-menu.admin-menu.adminimal-menu.menu-render-newline #civicrm-menu-nav #civicrm-menu { + top: 55px; + } + +} + +/* For adminimal_admin_menu */ +@media (min-width: 768px) and (max-width: 1024px) { + + body.crm-menubar-visible.crm-menubar-over-cms-menu.admin-menu.adminimal-menu > .slicknav_menu { + display: none; + } + body.crm-menubar-visible.crm-menubar-below-cms-menu.admin-menu.adminimal-menu { + padding-top: 0px !important; + } + body.crm-menubar-below-cms-menu.admin-menu.adminimal-menu > #civicrm-menu-nav #civicrm-menu { + top: 0px !important; + } +} + +@media (max-width: 768px) { + + body.toolbar.crm-menubar-visible #toolbar-home { + visibility: hidden; + } + body.crm-menubar-visible #toolbar-menu { + display: none; + } + + body #civicrm-menu-nav .crm-menubar-toggle-btn { + margin-top: 0; + } + + /* For admin_menu */ + body.admin-menu #civicrm-menu-nav .crm-menubar-toggle-btn { + margin-left: 0; + } + body.admin-menu.crm-menubar-visible #admin-menu-icon > li.admin-menu-icon > a { + visibility: hidden; + width: 40px; + } + + /* For adminimal_admin_menu */ + body.admin-menu.adminimal-menu #civicrm-menu-nav { + position: absolute; + } + body.admin-menu.adminimal-menu #civicrm-menu-nav .crm-menubar-toggle-btn { + float: right; + margin-top: 9px; + margin-right: 50px; + } + +} diff --git a/civicrm/css/menubar-drupal8.css b/civicrm/css/menubar-drupal8.css new file mode 100644 index 0000000000..868a7864da --- /dev/null +++ b/civicrm/css/menubar-drupal8.css @@ -0,0 +1,55 @@ +#toolbar-tray-civicrm { + display: none; +} + +body.crm-menubar-visible.crm-menubar-over-cms-menu, +body.crm-menubar-visible.crm-menubar-below-cms-menu { + margin-left: 0 !important; +} + +nav#civicrm-menu-nav .crm-menubar-toggle-btn { + margin: 0; + position: absolute; + top: 0; + height: 38px; +} +#crm-menubar-state:checked ~ .crm-menubar-toggle-btn { + left: 0!important; +} +nav#civicrm-menu-nav .crm-menubar-toggle-btn span.crm-menu-logo { + top: 10px; + left: 20px; +} +nav#civicrm-menu-nav .crm-menubar-toggle-btn-icon { + left: 44px; +} + +@media (min-width: 768px) { + + body.crm-menubar-visible.crm-menubar-over-cms-menu #toolbar-administration { + display: none; + } + + body.crm-menubar-visible.crm-menubar-over-cms-menu { + padding-top: 40px !important; + } + body.crm-menubar-visible.crm-menubar-over-cms-menu.crm-menubar-wrapped, + body.crm-menubar-visible.crm-menubar-below-cms-menu { + padding-top: 80px !important; + } + body.crm-menubar-visible.crm-menubar-below-cms-menu.crm-menubar-wrapped { + padding-top: 120px !important; + } + + body.crm-menubar-below-cms-menu > #civicrm-menu-nav ul#civicrm-menu { + z-index: 1000; + top: 40px; + } + +} + +@media (max-width: 609px) { + nav#civicrm-menu-nav { + position: absolute; + } +} diff --git a/civicrm/css/menubar-joomla.css b/civicrm/css/menubar-joomla.css new file mode 100644 index 0000000000..482f8c2ac6 --- /dev/null +++ b/civicrm/css/menubar-joomla.css @@ -0,0 +1,29 @@ +@media (min-width: 768px) { + + body.crm-menubar-over-cms-menu.crm-menubar-visible { + padding-top: 40px; + } + body.crm-menubar-over-cms-menu.crm-menubar-visible.crm-menubar-wrapped { + padding-top: 80px; + } + + body.crm-menubar-below-cms-menu.crm-menubar-visible { + margin-top: 40px; + } + body.crm-menubar-below-cms-menu.crm-menubar-visible.crm-menubar-wrapped { + margin-top: 80px; + } + +} +@media (max-width: 768px) { + + body #civicrm-menu-nav { + position: absolute; + } + + body #civicrm-menu-nav .crm-menubar-toggle-btn { + margin-top: 3px; + margin-left: 6px; + } + +} diff --git a/civicrm/css/menubar-wordpress.css b/civicrm/css/menubar-wordpress.css new file mode 100644 index 0000000000..33d227418d --- /dev/null +++ b/civicrm/css/menubar-wordpress.css @@ -0,0 +1,59 @@ +@media (min-width: 768px) { + + body.crm-menubar-over-cms-menu.crm-menubar-visible #wpbody { + padding-top: 8px; + } + body.crm-menubar-over-cms-menu.crm-menubar-visible.crm-menubar-wrapped #wpbody { + padding-top: 48px; + } + + body.crm-menubar-over-cms-menu.crm-menubar-visible #wpadminbar { + visibility: hidden; + } + + .wp-toolbar body.crm-menubar-below-cms-menu > #civicrm-menu-nav #civicrm-menu { + top: 32px; + left: 160px; + width: calc(100% - 160px); + } + + .wp-toolbar body.crm-menubar-below-cms-menu.folded > #civicrm-menu-nav #civicrm-menu { + left: 36px; + width: calc(100% - 36px); + } + + body.crm-menubar-below-cms-menu.crm-menubar-visible #wpbody { + padding-top: 40px; + } + body.crm-menubar-below-cms-menu.crm-menubar-visible.crm-menubar-wrapped #wpbody { + padding-top: 80px; + } + body.crm-menubar-over-cms-menu.crm-menubar-visible.crm-menubar-wrapped #adminmenuwrap { + margin-top: 40px; + } + +} +@media (min-width: 768px) and (max-width: 960px) { + + /* For the auto-fold toolbar */ + .wp-toolbar body.crm-menubar-below-cms-menu.auto-fold > #civicrm-menu-nav #civicrm-menu { + left: 36px; + width: calc(100% - 36px); + } + +} +@media (max-width: 768px) { + + body #civicrm-menu-nav .crm-menubar-toggle-btn { + position: absolute; + right: 50px; + } + +} +@media (max-width: 600px) { + + body #civicrm-menu-nav { + position: absolute; + } + +} diff --git a/civicrm/extension-compatibility.json b/civicrm/extension-compatibility.json index 2f8bd4b813..4192e68e5a 100644 --- a/civicrm/extension-compatibility.json +++ b/civicrm/extension-compatibility.json @@ -1,4 +1,13 @@ { + "uk.squiffle.kam": { + "obsolete": "5.12" + }, + "com.aghstrategies.slicknav": { + "obsolete": "5.12" + }, + "de.systopia.recentitems": { + "obsolete": "5.12" + }, "com.ixiam.modules.quicksearch": { "obsolete": "5.8" } diff --git a/civicrm/install/index.php b/civicrm/install/index.php index 994786d193..1bded4d2bb 100644 --- a/civicrm/install/index.php +++ b/civicrm/install/index.php @@ -557,6 +557,16 @@ class InstallRequirements { ts('Unable to create triggers. This MySQL user is missing the CREATE TRIGGERS privilege.'), ) ); + $this->requireMySQLUtf8mb4($databaseConfig['server'], + $databaseConfig['username'], + $databaseConfig['password'], + $databaseConfig['database'], + array( + ts("MySQL %1 Configuration", array(1 => $dbName)), + ts('Is the <code>utf8mb4</code> character set supported?'), + ts('This MySQL server does not support the <code>utf8mb4</code> character set.'), + ) + ); } } } @@ -1333,6 +1343,57 @@ class InstallRequirements { } } + /** + * @param $server + * @param string $username + * @param $password + * @param $database + * @param $testDetails + */ + public function requireMysqlUtf8mb4($server, $username, $password, $database, $testDetails) { + $this->testing($testDetails); + $conn = $this->connect($server, $username, $password); + if (!$conn) { + $testDetails[2] = ts('Could not connect to the database server.'); + $this->error($testDetails); + return; + } + + if (!@mysqli_select_db($conn, $database)) { + $testDetails[2] = ts('Could not select the database.'); + $this->error($testDetails); + return; + } + + $result = mysqli_query($conn, 'CREATE TABLE civicrm_utf8mb4_test (id VARCHAR(255), PRIMARY KEY(id(255))) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci ROW_FORMAT=DYNAMIC ENGINE=INNODB'); + if (!$result) { + $testDetails[2] = ts('It is recommended, though not yet required, to configure your MySQL server for utf8mb4 support. You will need the following MySQL server configuration: innodb_large_prefix=true innodb_file_format=barracuda innodb_file_per_table=true'); + $this->warning($testDetails); + return; + } + $result = mysqli_query($conn, 'DROP TABLE civicrm_utf8mb4_test'); + + // Ensure that the MySQL driver supports utf8mb4 encoding. + $version = mysqli_get_client_info($conn); + if (strpos($version, 'mysqlnd') !== FALSE) { + // The mysqlnd driver supports utf8mb4 starting at version 5.0.9. + $version = preg_replace('/^\D+([\d.]+).*/', '$1', $version); + if (version_compare($version, '5.0.9', '<')) { + $testDetails[2] = 'It is recommended, though not yet required, to upgrade your PHP MySQL driver (mysqlnd) to >= 5.0.9 for utf8mb4 support.'; + $this->warning($testDetails); + return; + } + } + else { + // The libmysqlclient driver supports utf8mb4 starting at version 5.5.3. + if (version_compare($version, '5.5.3', '<')) { + $testDetails[2] = 'It is recommended, though not yet required, to upgrade your PHP MySQL driver (libmysqlclient) to >= 5.5.3 for utf8mb4 support.'; + $this->warning($testDetails); + return; + } + } + } + /** * @param $testDetails * diff --git a/civicrm/js/Common.js b/civicrm/js/Common.js index 93f7b1032f..d53f2c1a54 100644 --- a/civicrm/js/Common.js +++ b/civicrm/js/Common.js @@ -256,7 +256,7 @@ if (!CRM.vars) CRM.vars = {}; CRM.CMSjQuery = window.jQuery; window.jQuery = CRM.$; } - script.src = url; + script.src = url + (_.includes(url, '?') ? '&r=' : '?r=') + CRM.config.resourceCacheCode; document.getElementsByTagName("head")[0].appendChild(script); } return scriptsLoaded[url]; @@ -466,7 +466,7 @@ if (!CRM.vars) CRM.vars = {}; var entity = $(this).data('api-entity') || ''; $(this) .off('.crmEntity') - .removeClass('crm-form-entityref crm-' + entity.toLowerCase() + '-ref') + .removeClass('crm-form-entityref crm-' + _.kebabCase(entity) + '-ref') .crmSelect2('destroy'); }); } @@ -475,13 +475,17 @@ if (!CRM.vars) CRM.vars = {}; return $(this).each(function() { var $el = $(this).off('.crmEntity'), - entity = options.entity || $el.data('api-entity') || 'contact', + entity = options.entity || $el.data('api-entity') || 'Contact', selectParams = {}; + // Legacy: fix entity name if passed in as snake case + if (entity.charAt(0).toUpperCase() !== entity.charAt(0)) { + entity = _.capitalize(_.camelCase(entity)); + } $el.data('api-entity', entity); $el.data('select-params', $.extend({}, $el.data('select-params') || {}, options.select)); $el.data('api-params', $.extend(true, {}, $el.data('api-params') || {}, options.api)); $el.data('create-links', options.create || $el.data('create-links')); - $el.addClass('crm-form-entityref crm-' + entity.toLowerCase() + '-ref'); + $el.addClass('crm-form-entityref crm-' + _.kebabCase(entity) + '-ref'); var settings = { // Use select2 ajax helper instead of CRM.api3 because it provides more value ajax: { @@ -527,7 +531,7 @@ if (!CRM.vars) CRM.vars = {}; } }; // Create new items inline - works for tags - if ($el.data('create-links') && entity.toLowerCase() === 'tag') { + if ($el.data('create-links') && entity === 'Tag') { selectParams.createSearchChoice = function(term, data) { if (!_.findKey(data, {label: term})) { return {id: "0", term: term, label: term + ' (' + ts('new tag') + ')'}; @@ -570,7 +574,6 @@ if (!CRM.vars) CRM.vars = {}; }; $el.on('select2-open.crmEntity', function() { var $el = $(this); - renderEntityRefFilterValue($el); $('#select2-drop') .off('.crmEntity') .on('click.crmEntity', 'a.crm-add-entity', function(e) { @@ -601,7 +604,7 @@ if (!CRM.vars) CRM.vars = {}; filter.value = $(this).val(); $(this).toggleClass('active', !!filter.value); $el.data('user-filter', filter); - if (filter.value) { + if (filter.value && $(this).is('select')) { // Once a filter has been chosen, rerender create links and refocus the search box $el.select2('close'); $el.select2('open'); @@ -685,12 +688,13 @@ if (!CRM.vars) CRM.vars = {}; var createLinks = $el.data('create-links'), params = getEntityRefApiParams($el).params, + entity = $el.data('api-entity'), markup = '<div class="crm-entityref-links">'; - if (!createLinks || (createLinks === true && $el.data('api-entity').toLowerCase() !== 'contact')) { + if (!createLinks || (createLinks === true && !CRM.config.entityRef.links[entity])) { return ''; } if (createLinks === true) { - createLinks = params.contact_type ? _.where(CRM.config.entityRef.contactCreate, {type: params.contact_type}) : CRM.config.entityRef.contactCreate; + createLinks = params.contact_type ? _.where(CRM.config.entityRef.links[entity], {type: params.contact_type}) : CRM.config.entityRef.links[entity]; } _.each(createLinks, function(link) { markup += ' <a class="crm-add-entity crm-hover-button" href="' + link.url + '">' + @@ -703,13 +707,12 @@ if (!CRM.vars) CRM.vars = {}; function getEntityRefFilters($el) { var - entity = $el.data('api-entity').toLowerCase(), + entity = $el.data('api-entity'), filters = CRM.config.entityRef.filters[entity] || [], params = $.extend({params: {}}, $el.data('api-params') || {}).params, result = []; - $.each(filters, function() { - var filter = $.extend({type: 'select', 'attributes': {}, entity: entity}, this); - $.extend(this, filter); + _.each(filters, function(filter) { + _.defaults(filter, {type: 'select', 'attributes': {}, entity: entity}); if (!params[filter.key]) { // Filter out options if params don't match its condition if (filter.condition && !_.isMatch(params, _.pick(filter.condition, _.keys(params)))) { @@ -739,14 +742,14 @@ if (!CRM.vars) CRM.vars = {}; '<select class="crm-entityref-filter-key' + (filter.key ? ' active' : '') + '">' + '<option value="">' + _.escape(ts('Refine search...')) + '</option>' + CRM.utils.renderOptions(filters, filter.key) + - '</select>' + entityRefFilterValueMarkup(filter, filterSpec) + '</div>'; + '</select>' + entityRefFilterValueMarkup($el, filter, filterSpec) + '</div>'; return markup; } /** * Provide markup for entity ref filter value field */ - function entityRefFilterValueMarkup(filter, filterSpec) { + function entityRefFilterValueMarkup($el, filter, filterSpec) { var markup = ''; if (filterSpec) { var attrs = '', @@ -760,7 +763,12 @@ if (!CRM.vars) CRM.vars = {}; attrs += ' ' + attr + '="' + val + '"'; }); if (filterSpec.type === 'select') { - markup = '<select' + attrs + '><option value="">' + _.escape(ts('- select -')) + '</option></select>'; + var fieldName = _.last(filter.key.split('.')), + options = [{key: '', value: ts('- select -')}]; + if (filterSpec.options) { + options = options.concat(getEntityRefFilterOptions(fieldName, $el, filterSpec)); + } + markup = '<select' + attrs + '>' + CRM.utils.renderOptions(options, filter.value) + '</select>'; } else { markup = '<input' + attrs + '/>'; } @@ -773,14 +781,13 @@ if (!CRM.vars) CRM.vars = {}; */ function renderEntityRefFilterValue($el) { var - entity = $el.data('api-entity').toLowerCase(), filter = $el.data('user-filter') || {}, filterSpec = filter.key ? _.find(getEntityRefFilters($el), {key: filter.key}) : null, $keyField = $('.crm-entityref-filter-key', '#select2-drop'), $valField = null; if (filterSpec) { $('.crm-entityref-filter-value', '#select2-drop').remove(); - $valField = $(entityRefFilterValueMarkup(filter, filterSpec)); + $valField = $(entityRefFilterValueMarkup($el, filter, filterSpec)); $keyField.after($valField); if (filterSpec.type === 'select') { loadEntityRefFilterOptions(filter, filterSpec, $valField, $el); @@ -795,10 +802,9 @@ if (!CRM.vars) CRM.vars = {}; */ function loadEntityRefFilterOptions(filter, filterSpec, $valField, $el) { // Fieldname may be prefixed with joins - strip those out - var fieldName = _.last(filter.key.split('.')), - params = $.extend({params: {}}, $el.data('api-params') || {}).params; + var fieldName = _.last(filter.key.split('.')); if (filterSpec.options) { - setEntityRefFilterOptions($valField, fieldName, params, filterSpec); + CRM.utils.setOptions($valField, getEntityRefFilterOptions(fieldName, $el, filterSpec), false, filter.value); return; } $('.crm-entityref-filters select', '#select2-drop').prop('disabled', true); @@ -808,19 +814,19 @@ if (!CRM.vars) CRM.vars = {}; // Store options globally so we don't have to look them up again filterSpec.options = result.values; $('.crm-entityref-filters select', '#select2-drop').prop('disabled', false); - setEntityRefFilterOptions($valField, fieldName, params, filterSpec); - $valField.val(filter.value || ''); + CRM.utils.setOptions($valField, getEntityRefFilterOptions(fieldName, $el, filterSpec), false, filter.value); }); } - function setEntityRefFilterOptions($valField, fieldName, params, filterSpec) { - var values = _.cloneDeep(filterSpec.options); + function getEntityRefFilterOptions(fieldName, $el, filterSpec) { + var values = _.cloneDeep(filterSpec.options), + params = $.extend({params: {}}, $el.data('api-params') || {}).params; if (fieldName === 'contact_type' && params.contact_type) { values = _.remove(values, function(option) { return option.key.indexOf(params.contact_type + '__') === 0; }); } - CRM.utils.setOptions($valField, values); + return values; } //CRM-15598 - Override url validator method to allow relative url's (e.g. /index.htm) diff --git a/civicrm/js/crm.backdrop.js b/civicrm/js/crm.backdrop.js index 911982de03..9620b4e30c 100644 --- a/civicrm/js/crm.backdrop.js +++ b/civicrm/js/crm.backdrop.js @@ -1,10 +1,8 @@ // http://civicrm.org/licensing -CRM.$(function($) { - $('#admin-bar').css('display', 'none'); - $('.crm-hidemenu').click(function(e) { - $('#admin-bar').css('display', 'block'); +(function($) { + $(document).on('crmLoad', '#civicrm-menu', function() { + if (Backdrop.settings.admin_bar && !Backdrop.settings.admin_bar.position_fixed) { + $('body').addClass('backdrop-admin-bar-position-absolute'); + } }); - $('#crm-notification-container').on('click', '#crm-restore-menu', function() { - $('#admin-bar').css('display', 'none'); - }); -}); +})(CRM.$); diff --git a/civicrm/js/crm.drupal7.js b/civicrm/js/crm.drupal7.js index fe3c5b9ec6..8dc539d502 100644 --- a/civicrm/js/crm.drupal7.js +++ b/civicrm/js/crm.drupal7.js @@ -10,10 +10,5 @@ // D7 hack, restore toolbar position (CRM-15341) $('#toolbar').css('z-index', ''); } - }) - .on('crmLoad', '#civicrm-menu', function(e) { - if ($('#toolbar a.toggle').length) { - $('#civicrm-menu').css({width: 'calc(100% - 40px)'}); - } }); })(CRM.$); diff --git a/civicrm/js/crm.drupal8.js b/civicrm/js/crm.drupal8.js index d141841815..74e64cb779 100644 --- a/civicrm/js/crm.drupal8.js +++ b/civicrm/js/crm.drupal8.js @@ -1,17 +1,29 @@ // http://civicrm.org/licensing -CRM.$(function($) { - // d8 Hack to hide title when it should be (CRM-19960) - var pageTitle = $('.page-title'); - if ('<span id="crm-remove-title" style="display:none">CiviCRM</span>' == pageTitle.text()) { - pageTitle.hide(); - } - $('#toolbar-bar').hide(); +// When on a CiviCRM page the CiviCRM toolbar tab should be active +localStorage.setItem('Drupal.toolbar.activeTabID', JSON.stringify('toolbar-item-civicrm')); - $('body').on('click', '.crm-hidemenu', function() { - $('#toolbar-bar').slideDown(); - }); - $('#crm-notification-container').on('click', '#crm-restore-menu', function() { - $('#toolbar-bar').slideUp(); - }); -}); +(function($) { + function adjustToggle() { + if ($(window).width() < 768) { + $('#civicrm-menu-nav .crm-menubar-toggle-btn').css({ + left: '' + $('#toolbar-item-civicrm').offset().left + 'px', + width: '' + $('#toolbar-item-civicrm').innerWidth() + 'px' + }); + } + } + $(window).resize(adjustToggle); + $(document).on('crmLoad', adjustToggle); + + // Wait for document.ready so Drupal's jQuery is available to this script + $(function($) { + // Need Drupal's jQuery to listen to this event + jQuery(document).on('drupalToolbarTabChange', function(event, tab) { + if (CRM.menubar && CRM.menubar.position === 'below-cms-menu') { + var action = jQuery(tab).is('#toolbar-item-civicrm') ? 'show' : 'hide'; + CRM.menubar[action](); + } + }); + }); + +})(CRM.$); diff --git a/civicrm/js/crm.menubar.js b/civicrm/js/crm.menubar.js new file mode 100644 index 0000000000..ad91a49e1b --- /dev/null +++ b/civicrm/js/crm.menubar.js @@ -0,0 +1,483 @@ +// https://civicrm.org/licensing +(function($, _) { + "use strict"; + var templates, initialized, + ENTER_KEY = 13, + SPACE_KEY = 32; + CRM.menubar = _.extend({ + data: null, + settings: {collapsibleBehavior: 'accordion'}, + position: 'over-cms-menu', + attachTo: (CRM.menubar && CRM.menubar.position === 'above-crm-container') ? '#crm-container' : 'body', + initialize: function() { + var cache = CRM.cache.get('menubar'); + if (cache && cache.code === CRM.menubar.cacheCode && cache.locale === CRM.config.locale && cache.cid === CRM.config.cid && localStorage.civiMenubar) { + CRM.menubar.data = cache.data; + insert(localStorage.civiMenubar); + } else { + $.getJSON(CRM.url('civicrm/ajax/navmenu', {code: CRM.menubar.cacheCode, locale: CRM.config.locale, cid: CRM.config.cid})) + .done(function(data) { + var markup = getTpl('tree')(data); + CRM.cache.set('menubar', {code: CRM.menubar.cacheCode, locale: CRM.config.locale, cid: CRM.config.cid, data: data}); + CRM.menubar.data = data; + localStorage.setItem('civiMenubar', markup); + insert(markup); + }); + } + + // Wait for crm-container present on the page as it's faster than document.ready + function insert(markup) { + if ($('#crm-container').length) { + render(markup); + } else { + new MutationObserver(function(mutations, observer) { + _.each(mutations, function(mutant) { + _.each(mutant.addedNodes, function(node) { + if ($(node).is('#crm-container')) { + render(markup); + observer.disconnect(); + } + }); + }); + }).observe(document, {childList: true, subtree: true}); + } + } + + function render(markup) { + var position = CRM.menubar.attachTo === 'body' ? 'beforeend' : 'afterbegin'; + $(CRM.menubar.attachTo)[0].insertAdjacentHTML(position, markup); + CRM.menubar.initializePosition(); + $('#civicrm-menu').trigger('crmLoad'); + $(document).ready(function() { + handleResize(); + $('#civicrm-menu') + .on('click', 'a[href="#"]', function() { + // For empty links - keep the menu open and don't jump the page anchor + return false; + }) + .on('click', 'a:not([href^="#"])', function(e) { + if (e.ctrlKey || e.altKey || e.shiftKey || e.metaKey) { + // Prevent menu closing when link is clicked with a keyboard modifier. + e.stopPropagation(); + } + }) + .on('dragstart', function() { + // Stop user from accidentally dragging menu links + // This was added because a user noticed they could drag the civi icon into the quicksearch box. + return false; + }) + .on('click', 'a[href="#hidemenu"]', function(e) { + e.preventDefault(); + CRM.menubar.hide(250, true); + }) + .on('keyup', 'a', function(e) { + // Simulate a click when spacebar key is pressed + if (e.which == SPACE_KEY) { + $(e.currentTarget)[0].click(); + } + }) + .on('show.smapi', function(e, menu) { + // Focus menu when opened with an accesskey + $(menu).siblings('a[accesskey]:not(:hover)').focus(); + }) + .smartmenus(CRM.menubar.settings); + initialized = true; + CRM.menubar.initializeResponsive(); + CRM.menubar.initializeSearch(); + }); + } + }, + destroy: function() { + $.SmartMenus.destroy(); + $('#civicrm-menu-nav').remove(); + initialized = false; + $('body[class]').attr('class', function(i, c) { + return c.replace(/(^|\s)crm-menubar-\S+/g, ''); + }); + }, + show: function(speed) { + if (typeof speed === 'number') { + $('#civicrm-menu').slideDown(speed, function() { + $(this).css('display', ''); + }); + } + $('body') + .removeClass('crm-menubar-hidden') + .addClass('crm-menubar-visible'); + }, + hide: function(speed, showMessage) { + if (typeof speed === 'number') { + $('#civicrm-menu').slideUp(speed, function() { + $(this).css('display', ''); + }); + } + $('body') + .addClass('crm-menubar-hidden') + .removeClass('crm-menubar-visible'); + if (showMessage === true && $('#crm-notification-container').length && initialized) { + var alert = CRM.alert('<a href="#" id="crm-restore-menu" >' + _.escape(ts('Restore CiviCRM Menu')) + '</a>', ts('Menu hidden'), 'none', {expires: 10000}); + $('#crm-restore-menu') + .click(function(e) { + e.preventDefault(); + alert.close(); + CRM.menubar.show(speed); + }); + } + }, + open: function(itemName) { + var $item = $('li[data-name="' + itemName + '"] > a', '#civicrm-menu'); + if ($item.length) { + $('#civicrm-menu').smartmenus('itemActivate', $item); + $item[0].focus(); + } + }, + close: $.SmartMenus.hideAll, + isOpen: function(itemName) { + if (itemName) { + return !!$('li[data-name="' + itemName + '"] > ul[aria-expanded="true"]', '#civicrm-menu').length; + } + return !!$('ul[aria-expanded="true"]', '#civicrm-menu').length; + }, + spin: function(spin) { + $('.crm-logo-sm', '#civicrm-menu').toggleClass('fa-spin', spin); + }, + getItem: function(itemName) { + return traverse(CRM.menubar.data.menu, itemName, 'get'); + }, + addItems: function(position, targetName, items) { + var list, container, $ul; + if (position === 'before' || position === 'after') { + if (!targetName) { + throw 'Cannot add sibling of main menu'; + } + list = traverse(CRM.menubar.data.menu, targetName, 'parent'); + if (!list) { + throw targetName + ' not found'; + } + var offset = position === 'before' ? 0 : 1; + position = offset + _.findIndex(list, {name: targetName}); + $ul = $('li[data-name="' + targetName + '"]', '#civicrm-menu').closest('ul'); + } else if (targetName) { + container = traverse(CRM.menubar.data.menu, targetName, 'get'); + if (!container) { + throw targetName + ' not found'; + } + container.child = container.child || []; + list = container.child; + var $target = $('li[data-name="' + targetName + '"]', '#civicrm-menu'); + if (!$target.children('ul').length) { + $target.append('<ul>'); + } + $ul = $target.children('ul').first(); + } else { + list = CRM.menubar.data.menu; + } + if (position < 0) { + position = list.length + 1 + position; + } + if (position >= list.length) { + list.push.apply(list, items); + position = list.length - 1; + } else { + list.splice.apply(list, [position, 0].concat(items)); + } + if (targetName && !$ul.is('#civicrm-menu')) { + $ul.html(getTpl('branch')({items: list, branchTpl: getTpl('branch')})); + } else { + $('#civicrm-menu > li').eq(position).after(getTpl('branch')({items: items, branchTpl: getTpl('branch')})); + } + CRM.menubar.refresh(); + }, + removeItem: function(itemName) { + var item = traverse(CRM.menubar.data.menu, itemName, 'delete'); + if (item) { + $('li[data-name="' + itemName + '"]', '#civicrm-menu').remove(); + CRM.menubar.refresh(); + } + return item; + }, + updateItem: function(item) { + if (!item.name) { + throw 'No name passed to CRM.menubar.updateItem'; + } + var menuItem = CRM.menubar.getItem(item.name); + if (!menuItem) { + throw item.name + ' not found'; + } + _.extend(menuItem, item); + $('li[data-name="' + item.name + '"]', '#civicrm-menu').replaceWith(getTpl('branch')({items: [menuItem], branchTpl: getTpl('branch')})); + CRM.menubar.refresh(); + }, + refresh: function() { + if (initialized) { + $('#civicrm-menu').smartmenus('refresh'); + handleResize(); + } + }, + togglePosition: function(persist) { + $('body').toggleClass('crm-menubar-over-cms-menu crm-menubar-below-cms-menu'); + CRM.menubar.position = CRM.menubar.position === 'over-cms-menu' ? 'below-cms-menu' : 'over-cms-menu'; + handleResize(); + if (persist !== false) { + CRM.cache.set('menubarPosition', CRM.menubar.position); + } + }, + initializePosition: function() { + if (CRM.menubar.position === 'over-cms-menu' || CRM.menubar.position === 'below-cms-menu') { + $('#civicrm-menu') + .on('click', 'a[href="#toggle-position"]', function(e) { + e.preventDefault(); + CRM.menubar.togglePosition(); + }) + .append('<li id="crm-menubar-toggle-position"><a href="#toggle-position" title="' + ts('Adjust menu position') + '"><i class="crm-i fa-arrow-up"></i></a>'); + CRM.menubar.position = CRM.cache.get('menubarPosition', CRM.menubar.position); + } + $('body').addClass('crm-menubar-visible crm-menubar-' + CRM.menubar.position); + }, + initializeResponsive: function() { + var $mainMenuState = $('#crm-menubar-state'); + // hide mobile menu beforeunload + $(window).on('beforeunload unload', function() { + CRM.menubar.spin(true); + if ($mainMenuState[0].checked) { + $mainMenuState[0].click(); + } + }) + .on('resize', function() { + if ($(window).width() >= 768 && $mainMenuState[0].checked) { + $mainMenuState[0].click(); + } + handleResize(); + }); + $mainMenuState.click(function() { + // Use absolute position instead of fixed when open to allow scrolling menu + var open = $(this).is(':checked'); + if (open) { + window.scroll({top: 0}); + } + $('#civicrm-menu-nav') + .css('position', open ? 'absolute' : '') + .parentsUntil('body') + .css('position', open ? 'static' : ''); + }); + }, + initializeSearch: function() { + $('input[name=qfKey]', '#crm-qsearch').attr('value', CRM.menubar.qfKey); + $('#crm-qsearch-input') + .autocomplete({ + source: function(request, response) { + //start spinning the civi logo + CRM.menubar.spin(true); + var + option = $('input[name=quickSearchField]:checked'), + params = { + name: request.term, + field_name: option.val() + }; + CRM.api3('contact', 'getquick', params).done(function(result) { + var ret = []; + if (result.values.length > 0) { + $('#crm-qsearch-input').autocomplete('widget').menu('option', 'disabled', false); + $.each(result.values, function(k, v) { + ret.push({value: v.id, label: v.data}); + }); + } else { + $('#crm-qsearch-input').autocomplete('widget').menu('option', 'disabled', true); + var label = option.closest('label').text(); + var msg = ts('%1 not found.', {1: label}); + // Remind user they are not searching by contact name (unless they enter a number) + if (params.field_name !== 'sort_name' && !(/[\d].*/.test(params.name))) { + msg += ' ' + ts('Did you mean to search by Name/Email instead?'); + } + ret.push({value: '0', label: msg}); + } + response(ret); + //stop spinning the civi logo + CRM.menubar.spin(false); + CRM.menubar.close(); + }); + }, + focus: function (event, ui) { + return false; + }, + select: function (event, ui) { + if (ui.item.value > 0) { + document.location = CRM.url('civicrm/contact/view', {reset: 1, cid: ui.item.value}); + } + return false; + }, + create: function() { + $(this).autocomplete('widget').addClass('crm-quickSearch-results'); + } + }) + .on('keyup change', function() { + $(this).toggleClass('has-user-input', !!$(this).val()); + }) + .keyup(function(e) { + CRM.menubar.close(); + if (e.which === ENTER_KEY) { + if (!$(this).val()) { + CRM.menubar.open('QuickSearch'); + } + } + }); + $('#crm-qsearch > a').keyup(function(e) { + if ($(e.target).is(this)) { + $('#crm-qsearch-input').focus(); + CRM.menubar.close(); + } + }); + $('#crm-qsearch form[name=search_block]').on('submit', function() { + if (!$('#crm-qsearch-input').val()) { + return false; + } + var $menu = $('#crm-qsearch-input').autocomplete('widget'); + if ($('li.ui-menu-item', $menu).length === 1) { + var cid = $('li.ui-menu-item', $menu).data('ui-autocomplete-item').value; + if (cid > 0) { + document.location = CRM.url('civicrm/contact/view', {reset: 1, cid: cid}); + return false; + } + } + }); + $('#civicrm-menu').on('show.smapi', function(e, menu) { + if ($(menu).parent().attr('data-name') === 'QuickSearch') { + $('#crm-qsearch-input').focus(); + } + }); + function setQuickSearchValue() { + var $selection = $('.crm-quickSearchField input:checked'), + label = $selection.parent().text(), + value = $selection.val(); + // These fields are not supported by advanced search + if (!value || value === 'first_name' || value === 'last_name') { + value = 'sort_name'; + } + $('#crm-qsearch-input').attr({name: value, placeholder: '\uf002 ' + label}); + } + $('.crm-quickSearchField').click(function() { + var input = $('input', this); + // Wait for event - its default was prevented by our link handler which interferes with checking the radio input + window.setTimeout(function() { + input.prop('checked', true); + CRM.cache.set('quickSearchField', input.val()); + setQuickSearchValue(); + $('#crm-qsearch-input').focus().autocomplete("search"); + }, 1); + }); + $('.crm-quickSearchField input[value="' + CRM.cache.get('quickSearchField', 'sort_name') + '"]').prop('checked', true); + setQuickSearchValue(); + $('#civicrm-menu').on('activate.smapi', function(e, item) { + return !$('ul.crm-quickSearch-results').is(':visible:not(.ui-state-disabled)'); + }); + }, + treeTpl: + '<nav id="civicrm-menu-nav">' + + '<input id="crm-menubar-state" type="checkbox" />' + + '<label class="crm-menubar-toggle-btn" for="crm-menubar-state">' + + '<span class="crm-menu-logo"></span>' + + '<span class="crm-menubar-toggle-btn-icon"></span>' + + '<%- ts("Toggle main menu") %>' + + '</label>' + + '<ul id="civicrm-menu" class="sm sm-civicrm">' + + '<%= searchTpl({items: search}) %>' + + '<%= branchTpl({items: menu, branchTpl: branchTpl}) %>' + + '</ul>' + + '</nav>', + searchTpl: + '<li id="crm-qsearch" data-name="QuickSearch">' + + '<a href="#"> ' + + '<form action="<%= CRM.url(\'civicrm/contact/search/advanced\') %>" name="search_block" method="post">' + + '<div>' + + '<input type="text" id="crm-qsearch-input" name="sort_name" placeholder="\uf002" accesskey="q" />' + + '<input type="hidden" name="hidden_location" value="1" />' + + '<input type="hidden" name="hidden_custom" value="1" />' + + '<input type="hidden" name="qfKey" />' + + '<input type="hidden" name="_qf_Advanced_refresh" value="Search" />' + + '</div>' + + '</form>' + + '</a>' + + '<ul>' + + '<% _.forEach(items, function(item) { %>' + + '<li><a href="#" class="crm-quickSearchField"><label><input type="radio" value="<%= item.key %>" name="quickSearchField"> <%- item.value %></label></a></li>' + + '<% }) %>' + + '</ul>' + + '</li>', + branchTpl: + '<% _.forEach(items, function(item) { %>' + + '<li <%= attr("li", item) %>>' + + '<a <%= attr("a", item) %>>' + + '<% if (item.icon) { %>' + + '<i class="<%- item.icon %>"></i>' + + '<% } %>' + + '<% if (item.label) { %>' + + '<span><%- item.label %></span>' + + '<% } %>' + + '</a>' + + '<% if (item.child) { %>' + + '<ul><%= branchTpl({items: item.child, branchTpl: branchTpl}) %></ul>' + + '<% } %>' + + '</li>' + + '<% }) %>' + }, CRM.menubar || {}); + + function getTpl(name) { + if (!templates) { + templates = { + branch: _.template(CRM.menubar.branchTpl, {imports: {_: _, attr: attr}}), + search: _.template(CRM.menubar.searchTpl, {imports: {_: _, ts: ts, CRM: CRM}}) + }; + templates.tree = _.template(CRM.menubar.treeTpl, {imports: {branchTpl: templates.branch, searchTpl: templates.search, ts: ts}}); + } + return templates[name]; + } + + function handleResize() { + if ($(window).width() >= 768 && $('#civicrm-menu').height() > 50) { + $('body').addClass('crm-menubar-wrapped'); + } else { + $('body').removeClass('crm-menubar-wrapped'); + } + } + + function traverse(items, itemName, op) { + var found; + _.each(items, function(item, index) { + if (item.name === itemName) { + found = (op === 'parent' ? items : item); + if (op === 'delete') { + items.splice(index, 1); + } + return false; + } + if (item.child) { + found = traverse(item.child, itemName, op); + if (found) { + return false; + } + } + }); + return found; + } + + function attr(el, item) { + var ret = [], attr = _.cloneDeep(item.attr || {}), a = ['rel', 'accesskey']; + if (el === 'a') { + attr = _.pick(attr, a); + attr.href = item.url || "#"; + } else { + attr = _.omit(attr, a); + attr['data-name'] = item.name; + if (item.separator) { + attr.class = (attr.class ? attr.class + ' ' : '') + 'crm-menu-border-' + item.separator; + } + } + _.each(attr, function(val, name) { + ret.push(name + '="' + val + '"'); + }); + return ret.join(' '); + } + + CRM.menubar.initialize(); + +})(CRM.$, CRM._); diff --git a/civicrm/js/crm.wordpress.js b/civicrm/js/crm.wordpress.js index 774b24a35f..740b224650 100644 --- a/civicrm/js/crm.wordpress.js +++ b/civicrm/js/crm.wordpress.js @@ -18,4 +18,20 @@ CRM.$(function($) { }); } }); + // Prevent screen reader shortcuts from changing the document hash and breaking angular routes + $('a.screen-reader-shortcut').click(function() { + var href = $(this).attr('href'); + // Show toolbar if hidden + if (href === '#wp-toolbar' && CRM.menubar.position === 'over-cms-menu') { + CRM.menubar.togglePosition(false); + } + $(href).focus(); + return false; + }); + $('<a href="#crm-qsearch-input" class="screen-reader-shortcut">' + ts("Open CiviCRM Menu") + '</a>') + .prependTo('#adminmenumain') + .click(function() { + CRM.menubar.open('Home'); + return false; + }); }); diff --git a/civicrm/package.json b/civicrm/package.json index 8800a314e9..c6dfe242ef 100644 --- a/civicrm/package.json +++ b/civicrm/package.json @@ -11,7 +11,7 @@ "devDependencies": { "bower": "^1.3.1", "civicrm-cv": "^0.1.2", - "karma": "^3.1.1", + "karma": "^4.0.1", "karma-ng-html2js-preprocessor": "^1.0.0", "karma-phantomjs-launcher": "^1.0.4", "jasmine-core": "~3.3.0", diff --git a/civicrm/packages/PEAR/FixPHP5PEARWarnings.php b/civicrm/packages/PEAR/FixPHP5PEARWarnings.php deleted file mode 100644 index 32807c2905..0000000000 --- a/civicrm/packages/PEAR/FixPHP5PEARWarnings.php +++ /dev/null @@ -1,7 +0,0 @@ -<?php -if ($skipmsg) { - $a = new $ec($code, $mode, $options, $userinfo); -} else { - $a = new $ec($message, $code, $mode, $options, $userinfo); -} -?> diff --git a/civicrm/packages/PEAR5.php b/civicrm/packages/PEAR5.php deleted file mode 100644 index ce7b467ea8..0000000000 --- a/civicrm/packages/PEAR5.php +++ /dev/null @@ -1,33 +0,0 @@ -<?php -/** - * This is only meant for PHP 5 to get rid of certain strict warning - * that doesn't get hidden since it's in the shutdown function - */ -class PEAR5 -{ - /** - * If you have a class that's mostly/entirely static, and you need static - * properties, you can use this method to simulate them. Eg. in your method(s) - * do this: $myVar = PEAR5::getStaticProperty('myclass', 'myVar'); - * You MUST use a reference, or they will not persist! - * - * @access public - * @param string $class The calling classname, to prevent clashes - * @param string $var The variable to retrieve. - * @return mixed A reference to the variable. If not set it will be - * auto initialised to NULL. - */ - static function &getStaticProperty($class, $var) - { - static $properties; - if (!isset($properties[$class])) { - $properties[$class] = array(); - } - - if (!array_key_exists($var, $properties[$class])) { - $properties[$class][$var] = null; - } - - return $properties[$class][$var]; - } -} \ No newline at end of file diff --git a/civicrm/packages/jquery/plugins/jquery.menu.js b/civicrm/packages/jquery/plugins/jquery.menu.js deleted file mode 100755 index 59c2a70340..0000000000 --- a/civicrm/packages/jquery/plugins/jquery.menu.js +++ /dev/null @@ -1,936 +0,0 @@ -/* - * jQuery Menu plugin - * Version: 0.0.9 - * - * Copyright (c) 2007 Roman Weich - * http://p.sohei.org - * - * Dual licensed under the MIT and GPL licenses - * (This means that you can choose the license that best suits your project, and use it accordingly): - * http://www.opensource.org/licenses/mit-license.php - * http://www.gnu.org/licenses/gpl.html - * - * Changelog: - * v 0.0.9 - 2008-01-19 - */ - -(function($) -{ - var menus = [], //list of all menus - visibleMenus = [], //list of all visible menus - activeMenu = activeItem = null, - menuDIVElement = $('<div class="menu-div outerbox" style="position:absolute;top:0;left:0;display:none;"><div class="shadowbox1"></div><div class="shadowbox2"></div><div class="shadowbox3"></div></div>')[0], - menuULElement = $('<ul class="menu-ul innerbox"></ul>')[0], - menuItemElement = $('<li style="position:relative;"><div class="menu-item"></div></li>')[0], - $rootDiv = $('<div id="root-menu-div" style="position:absolute;top:0;left:0;"></div>'), //create main menu div - defaults = { - // $.Menu options - showDelay : 200, - hideDelay : 200, - hoverOpenDelay: 0, - offsetTop : 0, - offsetLeft : 0, - minWidth: 0, - onOpen: null, - onClose: null, - - // $.MenuItem options - onClick: null, - arrowClass: null, - addExpando: false, - - // $.fn.menuFromElement options - copyClassAttr: false - }; - - $(function(){ - $rootDiv.appendTo('body'); - }); - - $.extend({ - MenuCollection : function(items) { - - this.menus = []; - - this.init(items); - } - }); - $.extend($.MenuCollection, { - prototype : { - init : function(items) - { - if ( items && items.length ) - { - for ( var i = 0; i < items.length; i++ ) - { - this.addMenu(items[i]); - items[i].menuCollection = this; - } - } - }, - addMenu : function(menu) - { - if ( menu instanceof $.Menu ) - this.menus.push(menu); - - menu.menuCollection = this; - - var self = this; - $(menu.target).hover(function(){ - if ( menu.visible ) - return; - - //when there is an open menu in this collection, hide it and show the new one - for ( var i = 0; i < self.menus.length; i++ ) - { - if ( self.menus[i].visible ) - { - self.menus[i].hide(); - menu.show(); - return; - } - } - }, function(){}); - } - } - }); - - - $.extend({ - Menu : function(target, items, options) { - this.menuItems = []; //all direct child $.MenuItem objects - this.subMenus = []; //all subMenus from this.menuItems - this.visible = false; - this.active = false; //this menu has hover or one of its submenus is open - this.parentMenuItem = null; - this.settings = $.extend({}, defaults, options); - this.target = target; - this.$eDIV = null; - this.$eUL = null; - this.timer = null; - this.menuCollection = null; - this.openTimer = null; - - this.init(); - if ( items && items.constructor == Array ) - this.addItems(items); - } - }); - - $.extend($.Menu, { - checkMouse : function(e) - { - var t = e.target; - - //the user clicked on the target of the currenty open menu - if ( visibleMenus.length && t == visibleMenus[0].target ) - return; - - //get the last node before the #root-menu-div - while ( t.parentNode && t.parentNode != $rootDiv[0] ) - t = t.parentNode; - - //is the found node one of the visible menu elements? - if ( !$(visibleMenus).filter(function(){ return this.$eDIV[0] == t; }).length ) - { - $.Menu.closeAll(); - } - }, - checkKey : function(e) - { - switch ( e.keyCode ) - { - case 13: //return - if ( activeItem ) - activeItem.click(e, activeItem.$eLI[0]); - break; - case 27: //ESC - $.Menu.closeAll(); - break; - case 37: //left - if ( !activeMenu ) - activeMenu = visibleMenus[0]; - var a = activeMenu; - if ( a && a.parentMenuItem ) //select the parent menu and close the submenu - { - //unbind the events temporary, as we dont want the hoverout event to fire - var pmi = a.parentMenuItem; - pmi.$eLI.unbind('mouseout').unbind('mouseover'); - a.hide(); - pmi.hoverIn(true); - setTimeout(function(){ //bind again..but delay it - pmi.bindHover(); - }); - } - else if ( a && a.menuCollection ) //select the previous menu in the collection - { - var pos, - mcm = a.menuCollection.menus; - if ( (pos = $.inArray(a, mcm)) > -1 ) - { - if ( --pos < 0 ) - pos = mcm.length - 1; - $.Menu.closeAll(); - mcm[pos].show(); - mcm[pos].setActive(); - if ( mcm[pos].menuItems.length ) //select the first item - mcm[pos].menuItems[0].hoverIn(true); - } - } - break; - case 38: //up - if ( activeMenu ) - activeMenu.selectNextItem(-1); - break; - case 39: //right - if ( !activeMenu ) - activeMenu = visibleMenus[0]; - var m, - a = activeMenu, - asm = activeItem ? activeItem.subMenu : null; - if ( a ) - { - if ( asm && asm.menuItems.length ) //select the submenu - { - asm.show(); - asm.menuItems[0].hoverIn(); - } - else if ( (a = a.inMenuCollection()) ) //select the next menu in the collection - { - var pos, - mcm = a.menuCollection.menus; - if ( (pos = $.inArray(a, mcm)) > -1 ) - { - if ( ++pos >= mcm.length ) - pos = 0; - $.Menu.closeAll(); - mcm[pos].show(); - mcm[pos].setActive(); - if ( mcm[pos].menuItems.length ) //select the first item - mcm[pos].menuItems[0].hoverIn(true); - } - } - } - break; - case 40: //down - if ( !activeMenu ) - { - if ( visibleMenus.length && visibleMenus[0].menuItems.length ) - visibleMenus[0].menuItems[0].hoverIn(); - } - else - activeMenu.selectNextItem(); - break; - } - if ( e.keyCode > 36 && e.keyCode < 41 ) - return false; //this will prevent scrolling - }, - closeAll : function() - { - while ( visibleMenus.length ) - visibleMenus[0].hide(); - }, - setDefaults : function(d) - { - $.extend(defaults, d); - }, - prototype : { - /** - * create / initialize new menu - */ - init : function() - { - var self = this; - if ( !this.target ) - return; - else if ( this.target instanceof $.MenuItem ) - { - this.parentMenuItem = this.target; - this.target.addSubMenu(this); - this.target = this.target.$eLI; - } - - menus.push(this); - - //use the dom methods instead the ones from jquery (faster) - this.$eDIV = $(menuDIVElement.cloneNode(1)); - this.$eUL = $(menuULElement.cloneNode(1)); - this.$eDIV[0].appendChild(this.$eUL[0]); - $rootDiv[0].appendChild(this.$eDIV[0]); - - //bind events - if ( !this.parentMenuItem ) - { - $(this.target).click(function(e){ - self.onClick(e); - }).hover(function(e){ - self.setActive(); - - if ( self.settings.hoverOpenDelay ) - { - self.openTimer = setTimeout(function(){ - if ( !self.visible ) - self.onClick(e); - }, self.settings.hoverOpenDelay); - } - }, function(){ - if ( !self.visible ) - $(this).removeClass('activetarget'); - - if ( self.openTimer ) - clearTimeout(self.openTimer); - }); - } - else - { - this.$eDIV.hover(function(){ - self.setActive(); - }, function(){}); - } - }, - setActive : function() - { - if ( !this.parentMenuItem ) - $(this.target).addClass('activetarget'); - else - this.active = true; - }, - addItem : function(item) - { - if ( item instanceof $.MenuItem ) - { - if ( $.inArray(item, this.menuItems) == -1 ) - { - this.$eUL.append(item.$eLI); - this.menuItems.push(item); - item.parentMenu = this; - if ( item.subMenu ) - this.subMenus.push(item.subMenu); - } - } - else - { - this.addItem(new $.MenuItem(item, this.settings)); - } - }, - addItems : function(items) - { - for ( var i = 0; i < items.length; i++ ) - { - this.addItem(items[i]); - } - }, - removeItem : function(item) - { - var pos = $.inArray(item, this.menuItems); - if ( pos > -1 ) - this.menuItems.splice(pos, 1); - item.parentMenu = null; - }, - hide : function() - { - if ( !this.visible ) - return; - - var i, - pos = $.inArray(this, visibleMenus); - - this.$eDIV.hide(); - - if ( pos >= 0 ) - visibleMenus.splice(pos, 1); - this.visible = this.active = false; - - $(this.target).removeClass('activetarget'); - - //hide all submenus - for ( i = 0; i < this.subMenus.length; i++ ) - { - this.subMenus[i].hide(); - } - - //set all items inactive (e.g. remove hover class..) - for ( i = 0; i < this.menuItems.length; i++ ) - { - if ( this.menuItems[i].active ) - this.menuItems[i].setInactive(); - } - - if ( !visibleMenus.length ) //unbind events when the last menu was closed - $(document).unbind('mousedown', $.Menu.checkMouse).unbind('keydown', $.Menu.checkKey); - - if ( activeMenu == this ) - activeMenu = null; - - if ( this.settings.onClose ) - this.settings.onClose.call(this); - }, - show : function(e) - { - if ( this.visible ) - return; - - var zi, - pmi = this.parentMenuItem; - - if ( this.menuItems.length ) //show only when it has items - { - if ( pmi ) //set z-index - { - zi = parseInt(pmi.parentMenu.$eDIV.css('z-index')); - this.$eDIV.css('z-index', (isNaN(zi) ? 1 : zi + 1)); - } - this.$eDIV.css({visibility: 'hidden', display:'block'}); - - //set min-width - if ( this.settings.minWidth ) - { - if ( this.$eDIV.width() < this.settings.minWidth ) - this.$eDIV.css('width', this.settings.minWidth); - } - - this.setPosition(); - this.$eDIV.css({display:'none', visibility: ''}).show(); - - if ( this.settings.onOpen ) - this.settings.onOpen.call(this); - } - if ( visibleMenus.length == 0 ) - $(document).bind('mousedown', $.Menu.checkMouse).bind('keydown', $.Menu.checkKey); - - this.visible = true; - visibleMenus.push(this); - }, - setPosition : function() - { - var $t, o, posX, posY, - pmo, //parent menu offset - wst, //window scroll top - wsl, //window scroll left - ww = $(window).width(), - wh = $(window).height(), - pmi = this.parentMenuItem, - height = this.$eDIV[0].clientHeight, - width = this.$eDIV[0].clientWidth, - pheight; //parent height - - if ( pmi ) - { - //position on the right side of the parent menu item - o = pmi.$eLI.offset(); - posX = o.left + pmi.$eLI.width(); - posY = o.top; - } - else - { - //position right below the target - $t = $(this.target); - o = $t.offset(); - posX = o.left + this.settings.offsetLeft; - posY = o.top + $t.height() + this.settings.offsetTop; - } - - //y-pos - if ( $.fn.scrollTop ) - { - wst = $(window).scrollTop(); - if ( wh < height ) //menu is bigger than the window - { - //position the menu at the top of the visible area - posY = wst; - } - else if ( wh + wst < posY + height ) //outside on the bottom? - { - if ( pmi ) - { - pmo = pmi.parentMenu.$eDIV.offset(); - pheight = pmi.parentMenu.$eDIV[0].clientHeight; - if ( height <= pheight ) - { - //bottom position = parentmenu-bottom position - posY = pmo.top + pheight - height; - } - else - { - //top position = parentmenu-top position - posY = pmo.top; - } - //still outside on the bottom? - if ( wh + wst < posY + height ) - { - //shift the menu upwards till the bottom is visible - posY -= posY + height - (wh + wst); - } - } - else - { - //shift the menu upwards till the bottom is visible - posY -= posY + height - (wh + wst); - } - } - } - //x-pos - if ( $.fn.scrollLeft ) - { - wsl = $(window).scrollLeft(); - if ( ww + wsl < posX + width ) - { - if ( pmi ) - { - //display the menu not on the right side but on the left side - posX -= pmi.$eLI.width() + width; - //outside on the left now? - if ( posX < wsl ) - posX = wsl; - } - else - { - //shift the menu to the left until it fits - posX -= posX + width - (ww + wsl); - } - } - } - - //set position - this.$eDIV.css({left: posX, top: posY}); - }, - onClick : function(e) - { - if ( this.visible ) - { - this.hide(); - this.setActive(); //the class is removed in the hide() method..add it again - } - else - { - //close all open menus - $.Menu.closeAll(); - this.show(e); - } - }, - addTimer : function(callback, delay) - { - var self = this; - this.timer = setTimeout(function(){ - callback.call(self); - self.timer = null; - }, delay); - }, - removeTimer : function() - { - if ( this.timer ) - { - clearTimeout(this.timer); - this.timer = null; - } - }, - selectNextItem : function(offset) - { - var i, pos = 0, - mil = this.menuItems.length, - o = offset || 1; - - //get current pos - for ( i = 0; i < mil; i++ ) - { - if ( this.menuItems[i].active ) - { - pos = i; - break; - } - } - this.menuItems[pos].hoverOut(); - - do //jump over the separators - { - pos += o; - if ( pos >= mil ) - pos = 0; - else if ( pos < 0 ) - pos = mil - 1; - } while ( this.menuItems[pos].separator ); - this.menuItems[pos].hoverIn(true); - }, - inMenuCollection : function() - { - var m = this; - while ( m.parentMenuItem ) - m = m.parentMenuItem.parentMenu; - return m.menuCollection ? m : null; - }, - destroy : function() //delete menu - { - var pos, item; - - this.hide(); - - //unbind events - if ( !this.parentMenuItem ) - $(this.target).unbind('click').unbind('mouseover').unbind('mouseout'); - else - this.$eDIV.unbind('mouseover').unbind('mouseout'); - - //destroy all items - while ( this.menuItems.length ) - { - item = this.menuItems[0]; - item.destroy(); - delete item; - } - - if ( (pos = $.inArray(this, menus)) > -1 ) - menus.splice(pos, 1); - - if ( this.menuCollection ) - { - if ( (pos = $.inArray(this, this.menuCollection.menus)) > -1 ) - this.menuCollection.menus.splice(pos, 1); - } - - this.$eDIV.remove(); - } - } - }); - - $.extend({ - MenuItem : function(obj, options) - { - if ( typeof obj == 'string' ) - obj = {src: obj}; - - this.src = obj.src || ''; - this.url = obj.url || null; - this.urlTarget = obj.target || null; - this.addClass = obj.addClass || null; - this.data = obj.data || null; - - this.$eLI = null; - this.parentMenu = null; - this.subMenu = null; - this.settings = $.extend({}, defaults, options); - this.active = false; - this.enabled = true; - this.separator = false; - - this.init(); - - if ( obj.subMenu ) - new $.Menu(this, obj.subMenu, options); - } - }); - - $.extend($.MenuItem, { - prototype : { - init : function() - { - var i, isStr, - src = this.src, - self = this; - - this.$eLI = $(menuItemElement.cloneNode(1)); - - if ( this.addClass ) - this.$eLI[0].setAttribute('class', this.addClass); - - if ( this.settings.addExpando && this.data ) - this.$eLI[0].menuData = this.data; - - if ( src == '' ) - { - this.$eLI.addClass('menu-separator'); - this.separator = true; - } - else - { - isStr = typeof src == 'string'; - if ( isStr && this.url ) //create a link node, when we have an url - src = $('<a href="' + this.url + '"' + (this.urlTarget ? 'target="' + this.urlTarget + '"' : '') + '>' + src + '</a>'); - else if ( isStr || !src.length ) - src = [src]; - //go through the passed DOM-Elements (or jquery objects or text nodes.) and append them to the menus list item - //this.$eLI.append(this.src) is really slow when having a lot(!!!) of items - for ( i = 0; i < src.length; i++ ) - { - if ( typeof src[i] == 'string' ) - { - //we cant use createTextNode, as html entities won't be displayed correctly (eg. ©) - elem = document.createElement('span'); - elem.innerHTML = src[i]; - this.$eLI[0].firstChild.appendChild(elem); - } - else - this.$eLI[0].firstChild.appendChild(src[i].cloneNode(1)); - } - } - - this.$eLI.click(function(e){ - self.click(e, this); - }); - this.bindHover(); - }, - click : function(e, scope) - { - if ( this.enabled && this.settings.onClick ) - this.settings.onClick.call(scope, e, this); - }, - bindHover : function() - { - var self = this; - this.$eLI.hover(function(){ - self.hoverIn(); - }, function(){ - self.hoverOut(); - }); - }, - hoverIn : function(noSubMenu) - { - this.removeTimer(); - - var i, - pms = this.parentMenu.subMenus, - pmi = this.parentMenu.menuItems, - self = this; - - //remove the timer from the parent item, when there is one (e.g. to close the menu) - if ( this.parentMenu.timer ) - this.parentMenu.removeTimer(); - - if ( !this.enabled ) - return; - - //deactivate all menuItems on the same level - for ( i = 0; i < pmi.length; i++ ) - { - if ( pmi[i].active ) - pmi[i].setInactive(); - } - - this.setActive(); - activeMenu = this.parentMenu; - - //are there open submenus on the same level? close them! - for ( i = 0; i < pms.length; i++ ) - { - if ( pms[i].visible && pms[i] != this.subMenu && !pms[i].timer ) //close if there is no closetimer running already - pms[i].addTimer(function(){ - this.hide(); - }, pms[i].settings.hideDelay); - } - - if ( this.subMenu && !noSubMenu ) - { - //set timeout to show menu - this.subMenu.addTimer(function(){ - this.show(); - }, this.subMenu.settings.showDelay); - } - }, - hoverOut : function() - { - this.removeTimer(); - - if ( !this.enabled ) - return; - - if ( !this.subMenu || !this.subMenu.visible ) - this.setInactive(); - }, - removeTimer : function() - { - if ( this.subMenu ) - { - this.subMenu.removeTimer(); - } - }, - setActive : function() - { - this.active = true; - this.$eLI.addClass('active'); - - //set the parent menu item active too if necessary - var pmi = this.parentMenu.parentMenuItem; - if ( pmi && !pmi.active ) - pmi.setActive(); - - activeItem = this; - }, - setInactive : function() - { - this.active = false; - this.$eLI.removeClass('active'); - if ( this == activeItem ) - activeItem = null; - }, - enable : function() - { - this.$eLI.removeClass('disabled'); - this.enabled = true; - }, - disable : function() - { - this.$eLI.addClass('disabled'); - this.enabled = false; - }, - destroy : function() - { - this.removeTimer(); - - this.$eLI.remove(); - - //unbind events - this.$eLI.unbind('mouseover').unbind('mouseout').unbind('click'); - //delete submenu - if ( this.subMenu ) - { - this.subMenu.destroy(); - delete this.subMenu; - } - this.parentMenu.removeItem(this); - }, - addSubMenu : function(menu) - { - if ( this.subMenu ) - return; - this.subMenu = menu; - if ( this.parentMenu && $.inArray(menu, this.parentMenu.subMenus) == -1 ) - this.parentMenu.subMenus.push(menu); - if ( this.settings.arrowClass ) { - var a = $('<i class="menu-item-arrow"></i>').addClass(this.settings.arrowClass); - this.$eLI[0].firstChild.appendChild(a[0]); - } - } - } - }); - - - $.extend($.fn, { - menuFromElement : function(options, list, bar) - { - var createItems = function(ul) - { - var menuItems = [], - subItems, - menuItem, - lis, $li, i, subUL, submenu, target, - classNames = null; - - lis = getAllChilds(ul, 'LI'); - for ( i = 0; i < lis.length; i++ ) - { - subItems = []; - - if ( !lis[i].childNodes.length ) //empty item? add separator - { - menuItems.push(new $.MenuItem('', options)); - continue; - } - - if ( (subUL = getOneChild(lis[i], 'UL')) ) - { - subItems = createItems(subUL); - //remove subUL from DOM - $(subUL).remove(); - } - - //select the target...get the elements inside the li - $li = $(lis[i]); - if ( $li[0].childNodes.length == 1 && $li[0].childNodes[0].nodeType == 3 ) - target = $li[0].childNodes[0].nodeValue; - else - target = $li[0].childNodes; - - if ( options && options.copyClassAttr ) - classNames = $li.attr('class'); - - //create item - menuItem = new $.MenuItem({src: target, addClass: classNames}, options); - menuItems.push(menuItem); - //add submenu - if ( subItems.length ) - new $.Menu(menuItem, subItems, options); - - } - return menuItems; - }; - return this.each(function() - { - var ul, m; - //get the list element - if ( list || (ul = getOneChild(this, 'UL')) ) - { - //if a specific list element is used, clone it, as we probably need it more than once - ul = list ? $(list).clone(true)[0] : ul; - menuItems = createItems(ul); - if ( menuItems.length ) - { - m = new $.Menu(this, menuItems, options); - if ( bar ) - bar.addMenu(m); - } - $(ul).hide(); - } - }); - }, - menuBarFromUL : function(options) - { - return this.each(function() - { - var i, - lis = getAllChilds(this, 'LI'); - - if ( lis.length ) - { - bar = new $.MenuCollection(); - for ( i = 0; i < lis.length; i++ ) - $(lis[i]).menuFromElement(options, null, bar); - } - }); - }, - menuBar : function(options, items) - { - return this.each(function() - { - if ( items && items.constructor == Array ) - new $.Menu(this, items, options); - else - { - if ( this.nodeName.toUpperCase() == 'UL' ) - $(this).menuBarFromUL(options); - else - $(this).menuFromElement(options, items); - } - }); - } - }); - - //faster than using jquery - var getOneChild = function(elem, name) - { - if ( !elem ) - return null; - - var n = elem.firstChild; - for ( ; n; n = n.nextSibling ) - { - if ( n.nodeType == 1 && n.nodeName.toUpperCase() == name ) - return n; - } - return null; - }; - //faster than using jquery - var getAllChilds = function(elem, name) - { - if ( !elem ) - return []; - - var r = [], - n = elem.firstChild; - for ( ; n; n = n.nextSibling ) - { - if ( n.nodeType == 1 && n.nodeName.toUpperCase() == name ) - r[r.length] = n; - } - return r; - }; - -})(jQuery); diff --git a/civicrm/packages/jquery/plugins/jquery.menu.min.js b/civicrm/packages/jquery/plugins/jquery.menu.min.js deleted file mode 100644 index a231f541c3..0000000000 --- a/civicrm/packages/jquery/plugins/jquery.menu.min.js +++ /dev/null @@ -1 +0,0 @@ -!function(e){var t=[],i=[],n=activeItem=null,s=e('<div class="menu-div outerbox" style="position:absolute;top:0;left:0;display:none;"><div class="shadowbox1"></div><div class="shadowbox2"></div><div class="shadowbox3"></div></div>')[0],h=e('<ul class="menu-ul innerbox"></ul>')[0],u=e('<li style="position:relative;"><div class="menu-item"></div></li>')[0],o=e('<div id="root-menu-div" style="position:absolute;top:0;left:0;"></div>'),l={showDelay:200,hideDelay:200,hoverOpenDelay:0,offsetTop:0,offsetLeft:0,minWidth:0,onOpen:null,onClose:null,onClick:null,arrowClass:null,addExpando:!1,copyClassAttr:!1};e(function(){o.appendTo("body")}),e.extend({MenuCollection:function(e){this.menus=[],this.init(e)}}),e.extend(e.MenuCollection,{prototype:{init:function(e){if(e&&e.length)for(var t=0;t<e.length;t++)this.addMenu(e[t]),e[t].menuCollection=this},addMenu:function(t){t instanceof e.Menu&&this.menus.push(t),t.menuCollection=this;var i=this;e(t.target).hover(function(){if(!t.visible)for(var e=0;e<i.menus.length;e++)if(i.menus[e].visible)return i.menus[e].hide(),void t.show()},function(){})}}}),e.extend({Menu:function(t,i,n){this.menuItems=[],this.subMenus=[],this.visible=!1,this.active=!1,this.parentMenuItem=null,this.settings=e.extend({},l,n),this.target=t,this.$eDIV=null,this.$eUL=null,this.timer=null,this.menuCollection=null,this.openTimer=null,this.init(),i&&i.constructor==Array&&this.addItems(i)}}),e.extend(e.Menu,{checkMouse:function(t){var n=t.target;if(!i.length||n!=i[0].target){for(;n.parentNode&&n.parentNode!=o[0];)n=n.parentNode;e(i).filter(function(){return this.$eDIV[0]==n}).length||e.Menu.closeAll()}},checkKey:function(t){switch(t.keyCode){case 13:activeItem&&activeItem.click(t,activeItem.$eLI[0]);break;case 27:e.Menu.closeAll();break;case 37:if(n||(n=i[0]),(u=n)&&u.parentMenuItem){var s=u.parentMenuItem;s.$eLI.unbind("mouseout").unbind("mouseover"),u.hide(),s.hoverIn(!0),setTimeout(function(){s.bindHover()})}else if(u&&u.menuCollection){var h=u.menuCollection.menus;(l=e.inArray(u,h))>-1&&(--l<0&&(l=h.length-1),e.Menu.closeAll(),h[l].show(),h[l].setActive(),h[l].menuItems.length&&h[l].menuItems[0].hoverIn(!0))}break;case 38:n&&n.selectNextItem(-1);break;case 39:n||(n=i[0]);var u=n,o=activeItem?activeItem.subMenu:null;if(u)if(o&&o.menuItems.length)o.show(),o.menuItems[0].hoverIn();else if(u=u.inMenuCollection()){var l;h=u.menuCollection.menus;(l=e.inArray(u,h))>-1&&(++l>=h.length&&(l=0),e.Menu.closeAll(),h[l].show(),h[l].setActive(),h[l].menuItems.length&&h[l].menuItems[0].hoverIn(!0))}break;case 40:n?n.selectNextItem():i.length&&i[0].menuItems.length&&i[0].menuItems[0].hoverIn()}if(t.keyCode>36&&t.keyCode<41)return!1},closeAll:function(){for(;i.length;)i[0].hide()},setDefaults:function(t){e.extend(l,t)},prototype:{init:function(){var i=this;this.target&&(this.target instanceof e.MenuItem&&(this.parentMenuItem=this.target,this.target.addSubMenu(this),this.target=this.target.$eLI),t.push(this),this.$eDIV=e(s.cloneNode(1)),this.$eUL=e(h.cloneNode(1)),this.$eDIV[0].appendChild(this.$eUL[0]),o[0].appendChild(this.$eDIV[0]),this.parentMenuItem?this.$eDIV.hover(function(){i.setActive()},function(){}):e(this.target).click(function(e){i.onClick(e)}).hover(function(e){i.setActive(),i.settings.hoverOpenDelay&&(i.openTimer=setTimeout(function(){i.visible||i.onClick(e)},i.settings.hoverOpenDelay))},function(){i.visible||e(this).removeClass("activetarget"),i.openTimer&&clearTimeout(i.openTimer)}))},setActive:function(){this.parentMenuItem?this.active=!0:e(this.target).addClass("activetarget")},addItem:function(t){t instanceof e.MenuItem?-1==e.inArray(t,this.menuItems)&&(this.$eUL.append(t.$eLI),this.menuItems.push(t),t.parentMenu=this,t.subMenu&&this.subMenus.push(t.subMenu)):this.addItem(new e.MenuItem(t,this.settings))},addItems:function(e){for(var t=0;t<e.length;t++)this.addItem(e[t])},removeItem:function(t){var i=e.inArray(t,this.menuItems);i>-1&&this.menuItems.splice(i,1),t.parentMenu=null},hide:function(){if(this.visible){var t,s=e.inArray(this,i);for(this.$eDIV.hide(),s>=0&&i.splice(s,1),this.visible=this.active=!1,e(this.target).removeClass("activetarget"),t=0;t<this.subMenus.length;t++)this.subMenus[t].hide();for(t=0;t<this.menuItems.length;t++)this.menuItems[t].active&&this.menuItems[t].setInactive();i.length||e(document).unbind("mousedown",e.Menu.checkMouse).unbind("keydown",e.Menu.checkKey),n==this&&(n=null),this.settings.onClose&&this.settings.onClose.call(this)}},show:function(t){if(!this.visible){var n,s=this.parentMenuItem;this.menuItems.length&&(s&&(n=parseInt(s.parentMenu.$eDIV.css("z-index")),this.$eDIV.css("z-index",isNaN(n)?1:n+1)),this.$eDIV.css({visibility:"hidden",display:"block"}),this.settings.minWidth&&this.$eDIV.width()<this.settings.minWidth&&this.$eDIV.css("width",this.settings.minWidth),this.setPosition(),this.$eDIV.css({display:"none",visibility:""}).show(),this.settings.onOpen&&this.settings.onOpen.call(this)),0==i.length&&e(document).bind("mousedown",e.Menu.checkMouse).bind("keydown",e.Menu.checkKey),this.visible=!0,i.push(this)}},setPosition:function(){var t,i,n,s,h,u,o,l,r=e(window).width(),a=e(window).height(),c=this.parentMenuItem,d=this.$eDIV[0].clientHeight,m=this.$eDIV[0].clientWidth;c?(n=(i=c.$eLI.offset()).left+c.$eLI.width(),s=i.top):(n=(i=(t=e(this.target)).offset()).left+this.settings.offsetLeft,s=i.top+t.height()+this.settings.offsetTop),e.fn.scrollTop&&(u=e(window).scrollTop(),a<d?s=u:a+u<s+d&&(c?(h=c.parentMenu.$eDIV.offset(),a+u<(s=d<=(l=c.parentMenu.$eDIV[0].clientHeight)?h.top+l-d:h.top)+d&&(s-=s+d-(a+u))):s-=s+d-(a+u))),e.fn.scrollLeft&&r+(o=e(window).scrollLeft())<n+m&&(c?(n-=c.$eLI.width()+m)<o&&(n=o):n-=n+m-(r+o)),this.$eDIV.css({left:n,top:s})},onClick:function(t){this.visible?(this.hide(),this.setActive()):(e.Menu.closeAll(),this.show(t))},addTimer:function(e,t){var i=this;this.timer=setTimeout(function(){e.call(i),i.timer=null},t)},removeTimer:function(){this.timer&&(clearTimeout(this.timer),this.timer=null)},selectNextItem:function(e){var t,i=0,n=this.menuItems.length,s=e||1;for(t=0;t<n;t++)if(this.menuItems[t].active){i=t;break}this.menuItems[i].hoverOut();do{(i+=s)>=n?i=0:i<0&&(i=n-1)}while(this.menuItems[i].separator);this.menuItems[i].hoverIn(!0)},inMenuCollection:function(){for(var e=this;e.parentMenuItem;)e=e.parentMenuItem.parentMenu;return e.menuCollection?e:null},destroy:function(){var i;for(this.hide(),this.parentMenuItem?this.$eDIV.unbind("mouseover").unbind("mouseout"):e(this.target).unbind("click").unbind("mouseover").unbind("mouseout");this.menuItems.length;)this.menuItems[0].destroy(),0;(i=e.inArray(this,t))>-1&&t.splice(i,1),this.menuCollection&&(i=e.inArray(this,this.menuCollection.menus))>-1&&this.menuCollection.menus.splice(i,1),this.$eDIV.remove()}}}),e.extend({MenuItem:function(t,i){"string"==typeof t&&(t={src:t}),this.src=t.src||"",this.url=t.url||null,this.urlTarget=t.target||null,this.addClass=t.addClass||null,this.data=t.data||null,this.$eLI=null,this.parentMenu=null,this.subMenu=null,this.settings=e.extend({},l,i),this.active=!1,this.enabled=!0,this.separator=!1,this.init(),t.subMenu&&new e.Menu(this,t.subMenu,i)}}),e.extend(e.MenuItem,{prototype:{init:function(){var t,i,n=this.src,s=this;if(this.$eLI=e(u.cloneNode(1)),this.addClass&&this.$eLI[0].setAttribute("class",this.addClass),this.settings.addExpando&&this.data&&(this.$eLI[0].menuData=this.data),""==n)this.$eLI.addClass("menu-separator"),this.separator=!0;else for((i="string"==typeof n)&&this.url?n=e('<a href="'+this.url+'"'+(this.urlTarget?'target="'+this.urlTarget+'"':"")+">"+n+"</a>"):!i&&n.length||(n=[n]),t=0;t<n.length;t++)"string"==typeof n[t]?(elem=document.createElement("span"),elem.innerHTML=n[t],this.$eLI[0].firstChild.appendChild(elem)):this.$eLI[0].firstChild.appendChild(n[t].cloneNode(1));this.$eLI.click(function(e){s.click(e,this)}),this.bindHover()},click:function(e,t){this.enabled&&this.settings.onClick&&this.settings.onClick.call(t,e,this)},bindHover:function(){var e=this;this.$eLI.hover(function(){e.hoverIn()},function(){e.hoverOut()})},hoverIn:function(e){this.removeTimer();var t,i=this.parentMenu.subMenus,s=this.parentMenu.menuItems;if(this.parentMenu.timer&&this.parentMenu.removeTimer(),this.enabled){for(t=0;t<s.length;t++)s[t].active&&s[t].setInactive();for(this.setActive(),n=this.parentMenu,t=0;t<i.length;t++)i[t].visible&&i[t]!=this.subMenu&&!i[t].timer&&i[t].addTimer(function(){this.hide()},i[t].settings.hideDelay);this.subMenu&&!e&&this.subMenu.addTimer(function(){this.show()},this.subMenu.settings.showDelay)}},hoverOut:function(){this.removeTimer(),this.enabled&&(this.subMenu&&this.subMenu.visible||this.setInactive())},removeTimer:function(){this.subMenu&&this.subMenu.removeTimer()},setActive:function(){this.active=!0,this.$eLI.addClass("active");var e=this.parentMenu.parentMenuItem;e&&!e.active&&e.setActive(),activeItem=this},setInactive:function(){this.active=!1,this.$eLI.removeClass("active"),this==activeItem&&(activeItem=null)},enable:function(){this.$eLI.removeClass("disabled"),this.enabled=!0},disable:function(){this.$eLI.addClass("disabled"),this.enabled=!1},destroy:function(){this.removeTimer(),this.$eLI.remove(),this.$eLI.unbind("mouseover").unbind("mouseout").unbind("click"),this.subMenu&&(this.subMenu.destroy(),delete this.subMenu),this.parentMenu.removeItem(this)},addSubMenu:function(t){if(!this.subMenu&&(this.subMenu=t,this.parentMenu&&-1==e.inArray(t,this.parentMenu.subMenus)&&this.parentMenu.subMenus.push(t),this.settings.arrowClass)){var i=e('<i class="menu-item-arrow"></i>').addClass(this.settings.arrowClass);this.$eLI[0].firstChild.appendChild(i[0])}}}}),e.extend(e.fn,{menuFromElement:function(t,i,n){var s=function(i){var n,h,u,o,l,c,d,m=[],f=null;for(u=a(i,"LI"),l=0;l<u.length;l++)n=[],u[l].childNodes.length?((c=r(u[l],"UL"))&&(n=s(c),e(c).remove()),d=1==(o=e(u[l]))[0].childNodes.length&&3==o[0].childNodes[0].nodeType?o[0].childNodes[0].nodeValue:o[0].childNodes,t&&t.copyClassAttr&&(f=o.attr("class")),h=new e.MenuItem({src:d,addClass:f},t),m.push(h),n.length&&new e.Menu(h,n,t)):m.push(new e.MenuItem("",t));return m};return this.each(function(){var h,u;(i||(h=r(this,"UL")))&&(h=i?e(i).clone(!0)[0]:h,menuItems=s(h),menuItems.length&&(u=new e.Menu(this,menuItems,t),n&&n.addMenu(u)),e(h).hide())})},menuBarFromUL:function(t){return this.each(function(){var i,n=a(this,"LI");if(n.length)for(bar=new e.MenuCollection,i=0;i<n.length;i++)e(n[i]).menuFromElement(t,null,bar)})},menuBar:function(t,i){return this.each(function(){i&&i.constructor==Array?new e.Menu(this,i,t):"UL"==this.nodeName.toUpperCase()?e(this).menuBarFromUL(t):e(this).menuFromElement(t,i)})}});var r=function(e,t){if(!e)return null;for(var i=e.firstChild;i;i=i.nextSibling)if(1==i.nodeType&&i.nodeName.toUpperCase()==t)return i;return null},a=function(e,t){if(!e)return[];for(var i=[],n=e.firstChild;n;n=n.nextSibling)1==n.nodeType&&n.nodeName.toUpperCase()==t&&(i[i.length]=n);return i}}(jQuery); \ No newline at end of file diff --git a/civicrm/release-notes.md b/civicrm/release-notes.md index 16a4767f91..9d85e58ec8 100644 --- a/civicrm/release-notes.md +++ b/civicrm/release-notes.md @@ -14,7 +14,18 @@ Other resources for identifying changes are: * https://github.com/civicrm/civicrm-joomla * https://github.com/civicrm/civicrm-wordpress -# CiviCRM 5.11.0 +## CiviCRM 5.12.0 + +Released April 3, 2019 + +- **[Synopsis](release-notes/5.12.0.md#synopsis)** +- **[Features](release-notes/5.12.0.md#features)** +- **[Bugs resolved](release-notes/5.12.0.md#bugs)** +- **[Miscellany](release-notes/5.12.0.md#misc)** +- **[Credits](release-notes/5.12.0.md#credits)** +- **[Feedback](release-notes/5.12.0.md#feedback)** + +## CiviCRM 5.11.0 Released March 6, 2019 diff --git a/civicrm/release-notes/5.12.0.md b/civicrm/release-notes/5.12.0.md new file mode 100644 index 0000000000..8133f09ce1 --- /dev/null +++ b/civicrm/release-notes/5.12.0.md @@ -0,0 +1,861 @@ +# CiviCRM 5.12.0 + +Released April 3, 2019 + +- **[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?** | **yes** | +| **Fix problems installing or upgrading to a previous version?** | **yes** | +| **Introduce features?** | **yes** | +| **Fix bugs?** | **yes** | + +## <a name="features"></a>Features + +### Core CiviCRM + +- **Migrate KAM smartmenus to core + ([13582](https://github.com/civicrm/civicrm-core/pull/13582), + [240](https://github.com/civicrm/civicrm-packages/pull/240), + [13612](https://github.com/civicrm/civicrm-core/pull/13612), + [13729](https://github.com/civicrm/civicrm-core/pull/13729), + [13820](https://github.com/civicrm/civicrm-core/pull/13820), and + [13876](https://github.com/civicrm/civicrm-core/pull/13876))** + + The Keyboard Accessible Menus extension is now moved to core, replacing the + CiviCRM navigation menu with a grey one provided by the SmartMenus jQuery + plugin. The new menu is mobile-responsive and more accessible. + +- **[dev/core#657](https://lab.civicrm.org/dev/core/issues/657) Add filter for + country on Repeat Contributions Report + ([13432](https://github.com/civicrm/civicrm-core/pull/13432))** + + This change adds a filter for Country to the Repeat Contributions Report. + +- **[dev/core#690](https://lab.civicrm.org/dev/core/issues/690) Support more + entities in Attachment API by short-circuiting permission check + ([13529](https://github.com/civicrm/civicrm-core/pull/13529))** + + You can now use the Attachment API to update attachment custom fields on + Memberships and several other entities. + +- **[dev/core#561](https://lab.civicrm.org/dev/core/issues/561) Replace + jcalendar instances with datepicker + ([13704](https://github.com/civicrm/civicrm-core/pull/13704), + [13701](https://github.com/civicrm/civicrm-core/pull/13701) and + [13746](https://github.com/civicrm/civicrm-core/pull/13746)) Continued Work** + + These changes update the following places to use the datepicker instead of the + jcalendar widget: the age field on the Advanced Search form in the + Demographics section, the activity date time field on the find activites form, + and the date field on the Change Case Type Form. Additionally on the Find + Activities form these changes make it possible to pass the activity_date_time + criteria in the url. + +- **Add install and runtime status warnings if MySQL utf8mb4 is not supported + ([13425](https://github.com/civicrm/civicrm-core/pull/13425) and + [13682](https://github.com/civicrm/civicrm-core/pull/13682))** + + This change adds a warning to the system status page, as well as at install + time, if a site's MySQL server does not support the utf8mb4 character set. See + also [dev/core#749](https://lab.civicrm.org/dev/core/issues/749) for an + intra-release regression related to this. + +- **Record change log entry when contact is moved to or restored from trash + ([13276](https://github.com/civicrm/civicrm-core/pull/13276))** + + This change makes it so that a change log entry is created when a contact is + moved to the trash or restored from the trash. + +- **Towards supporting EntityForm for 'View Action' + ([13578](https://github.com/civicrm/civicrm-core/pull/13578))** + + This change enhances support for viewing entities in the abstracted + "EntityForm" code. This may be used in the future to standardize viewing and + editing CiviCRM entities. + +- **Standardize format for entityRef create links + ([13628](https://github.com/civicrm/civicrm-core/pull/13628))** + + This change standardizes the creation links in entity reference fields so that + they are pre-loaded for the client and so that they work equally well with all + entities. + +- **Add in Exception API to support the refactor of Dedupe Exception Page + ([13611](https://github.com/civicrm/civicrm-core/pull/13611))** + + This change adds an API to create, get, and delete dedupe exceptions. + +- **CRM.loadScript improvements + ([13555](https://github.com/civicrm/civicrm-core/pull/13555))** + + This change makes it so that dynamically loaded scripts are not served from + stale browser caches and allows angular apps to dynamically load scripts. + +- **Make submitOnce() button js into a button parameter + ([13333](https://github.com/civicrm/civicrm-core/pull/13333))** + + This change makes it so that developers can set a button as submit only once + using the parameter `submitOnce = TRUE`. + +- **[dev/core#562](https://lab.civicrm.org/dev/core/issues/562) Remove instances + of $dao->free ([13560](https://github.com/civicrm/civicrm-core/pull/13560) and + [13564](https://github.com/civicrm/civicrm-core/pull/13564)) Continued Work** + + These changes improve performance by removing instances of $dao->free. + +- **Upgrade PHPWord + ([13686](https://github.com/civicrm/civicrm-core/pull/13686))** + + CiviCRM now contains an updated version of the code library for generating + Word documents. + +### CiviContribute + +- **Add pseudoconstant for payment_processor_id to contributionrecur + ([13702](https://github.com/civicrm/civicrm-core/pull/13702)) Continued Work** + + This change alters the schema to add support for payment_processor_id as a + pseudoconstant for recurring contributions. + +- **[dev/core#767](https://lab.civicrm.org/dev/core/issues/767) Add 'Cancelled / + Refunded Date' and 'Cancellation / Refund Reason' in the Detail Contributions + Report ([13726](https://github.com/civicrm/civicrm-core/pull/13726))** + + This change adds the fields and filters 'Cancelled / Refunded Date' and + 'Cancellation / Refund Reason' to the Contribution Detail report. + +- **[dev/report#8](https://lab.civicrm.org/dev/report/issues/8) Contribution + reports don't include thank-you date + ([13653](https://github.com/civicrm/civicrm-core/pull/13653))** + + This change adds the "thank you date" field to the Contribution Summary and + Detail reports. + +- **[dev/core#735](https://lab.civicrm.org/dev/core/issues/735) Query + performance - suppress 'product' and related fields where products are not in + the database ([13638](https://github.com/civicrm/civicrm-core/pull/13638))** + + This change removes the "Premium" column from the Contribution tab for sites + that do not use products and improves performance on those sites by not + searching for product related fields. + +- **Speed up contribution results by removing join on civicrm_financial_type + table when rendering search results. + ([13720](https://github.com/civicrm/civicrm-core/pull/13720))** + + This change improves performance when searching contributions. + +- **Allow viewing of cancelled recurring contributions + ([13745](https://github.com/civicrm/civicrm-core/pull/13745))** + + It is now possible to view canceled recurring contributions through the user + interface. + +- **Add new Payment.sendconfirmation api + ([13610](https://github.com/civicrm/civicrm-core/pull/13610), + [13561](https://github.com/civicrm/civicrm-core/pull/13561) and + [13609](https://github.com/civicrm/civicrm-core/pull/13609))** + + A new Payment.sendconfirmation API method is available for generating payment + confirmation emails. + +- **Switch additional payment form to use Payment.sendconfirmation api + ([13649](https://github.com/civicrm/civicrm-core/pull/13649))** + + The additional payment form now generates confirmation emails using the new + Payment.sendconfirmation API. + +- **Payment notification formatting, move greeting into table + ([13669](https://github.com/civicrm/civicrm-core/pull/13669))** + + The greeting in the payment notification email is now aligned with the table + of payment information. + +- **Update Payment Notification to use greeting, remove text to 'Please print + this confirmation for your records. + ([13655](https://github.com/civicrm/civicrm-core/pull/13655))** + + The Payment Notification email no longer asks recipients to "Please print this + confirmation for your records." It also is updated to use the email_greeting + instead of the display_name for the greeting. + +- **Contribution/ContributionRecur metadata updates for EntityForm + ([13579](https://github.com/civicrm/civicrm-core/pull/13579))** + + These changes update the metadata for Contribution and ContributionRecur so + that they can be used to autogenerate forms with EntityForm. + +### CiviMember + +- **CiviCRM Membership Detail report, add column to display if membership is + Primary or Inherited + ([13736](https://github.com/civicrm/civicrm-core/pull/13736))** + + This change adds a column "Primary/Inherited?" to the Membership Detail + report. + +### Drupal Integration + +- **Make address Supplemental line 3 available to views + ([551](https://github.com/civicrm/civicrm-drupal/pull/551))** + + This change makes it so that one can use the address field "Supplemental + Address 3" in a view. + +### Joomla Integration + +- **Improves styling on Joomla! upgrade screen + ([13557](https://github.com/civicrm/civicrm-core/pull/13557))** + + This change improves the styling of the Joomla upgrade screen. + +## <a name="bugs"></a>Bugs resolved + +### Core CiviCRM + +- **[dev/core#842](https://lab.civicrm.org/dev/core/issues/842) Regression?? + Inline editing of website field deletes it + ([13939](https://github.com/civicrm/civicrm-core/pull/13939))** + + This resolves a bug where editing a website field inline on the contact + summary tab sometimes would delete the field entirely. + +- **[dev/core#190](https://lab.civicrm.org/dev/core/issues/190) custom data with + multiple records profile: after submission, profile view shows first record + instead of most recent + ([12337](https://github.com/civicrm/civicrm-core/pull/12337))** + + When submitting a profile with files that allow multiple records, the most + recently created record is now retrieved on the confirmation page. Before + this change, the first record was retrieved. + +- **Fix (sometimes serious) performance problem on submitting profiles for + specified contacts + ([13606](https://github.com/civicrm/civicrm-core/pull/13606))** + +- **[dev/core#748](https://lab.civicrm.org/dev/core/issues/748) Deadlocks and + performance issues when using smartgroups / ACLs extensively + ([13732](https://github.com/civicrm/civicrm-core/pull/13732))** + + This change improves performance of many queries by no longer using the + `UPPER()` and `LOWER()` MySQL functions. + +- **[dev/core#397](https://lab.civicrm.org/dev/core/issues/397) Dedupe for + Individual Birth Date Results in Error + ([13538](https://github.com/civicrm/civicrm-core/pull/13538))** + + This change fixes a fatal error when using a dedupe rule with the birth date + field. + +- **[dev/core#821](https://lab.civicrm.org/dev/core/issues/821) Activity: + Assigned to: It is not possible to search by the "refine search" drop-down + ([13893](https://github.com/civicrm/civicrm-core/pull/13893))** + + When setting an activity assignee, a bug prevented using the filters in the + contact reference field. + +- **[dev/core#580](https://lab.civicrm.org/dev/core/issues/580) No groups + displayed on Manage Groups when "All Groups" is selected + ([13373](https://github.com/civicrm/civicrm-core/pull/13373))** + + This resolves a bug where if a user had an ACL that gave them permission to + Edit "All Groups" but did not have the permission "View All Contacts", on the + "Manage Groups" screen no groups would appear. + +- **[dev/core#642](https://lab.civicrm.org/dev/core/issues/642) New Contact + Report: New report isn't created automatically when the user selects the + "Create Report" action + ([13404](https://github.com/civicrm/civicrm-core/pull/13404))** + + This resolves a Javascript error when attempting to create a new report from + the Constituent Report (Summary) template. + +- **[dev/core#683](https://lab.civicrm.org/dev/core/issues/683) Incorrectly + encoded state and country names + ([13591](https://github.com/civicrm/civicrm-core/pull/13591))** + + This change ensures that when countries and state/provinces are added they use + proper character encoding. + +- **[dev/core#691](https://lab.civicrm.org/dev/core/issues/691) It is no longer + possible to have the default country not set + ([13523](https://github.com/civicrm/civicrm-core/pull/13523))** + + This change makes the default country field on the settings form optional, + before this change it was required. + +- **[dev/core#700](https://lab.civicrm.org/dev/core/issues/700) Advanced Search: + The reason of failed search result is not displayed, when a contact with the + matching Contact ID was not found + ([13549](https://github.com/civicrm/civicrm-core/pull/13549))** + + When using the Advanced Search form to search by contact ID, this change + ensures that if there is no matching contact the message states the search + criteria. + +- **[dev/core#708](https://lab.civicrm.org/dev/core/issues/708) Advanced Search: + The "Modified By" option was set instead of "Added by" + ([13566](https://github.com/civicrm/civicrm-core/pull/13566))** + + In Advanced Search, the listing of search criteria for searches yielding no + results would display "modified by" when "added by" was a criterion. + +- **[dev/core#705](https://lab.civicrm.org/dev/core/issues/705) Disabling + Alphabetical Pager is not respected for events and contribution pages. + ([13592](https://github.com/civicrm/civicrm-core/pull/13592))** + +- **[dev/core#714](https://lab.civicrm.org/dev/core/issues/714) Manage groups: + Error: "API permission check failed for Group/create call; insufficient + permission" when the user tries to edit some group's details + ([13573](https://github.com/civicrm/civicrm-core/pull/13573))** + + On the Manage Groups form, if a user does not have permissions to edit a + group, the edit link is disabled. + +- **[dev/core#742](https://lab.civicrm.org/dev/core/issues/742) Repeated + warning: "simplexml_load_file(): I/O warning : failed to load external entity + ".../xml/Menu/Activity.xml" + ([13654](https://github.com/civicrm/civicrm-core/pull/13654))** + + This change fixes warnings regarding failing to parse the XML file when + clearing the CiviCRM caches. + +- **[dev/report#11](https://lab.civicrm.org/dev/report/issues/11) Soft Credit + report fails when Only Full Group By is enabled + ([13671](https://github.com/civicrm/civicrm-core/pull/13671))** + +- **Remove mcrypt system status check + ([13770](https://github.com/civicrm/civicrm-core/pull/13770))** + + PHP 7.2 does not support mcrypt, which is being deprecated. This removes the + status check that would notify administrators if mcrypt is not installed. + +- **Fix api bug whereby 0 & '0' are not accepted as range parameters for BETWEEN + ([13766](https://github.com/civicrm/civicrm-core/pull/13766))** + +- **Render Note field tokens correctly - they are already HTML. + ([13283](https://github.com/civicrm/civicrm-core/pull/13283))** + +- **Rationalise Activity api ACLs for consistency, to respect the hook & improve + performance ([13664](https://github.com/civicrm/civicrm-core/pull/13664))** + + This change alters the way permissions are handled on sites that use ACLs when + the activity.get api is called with the 'check_permissions' flag set to TRUE. + This would usually be the case for Javascript calls. + +- **Upgrader: Don't abort if state_province already exists + ([13744](https://github.com/civicrm/civicrm-core/pull/13744))** + + This change fixes a fatal error when upgrading from 4.7.30 and 4.7.32 if + state_province values already exists so that sites with state_province values + can safely upgrade from 4.7.30 t0 4.7.32. + +- **Do not attempt to store out-of-range street number + ([13340](https://github.com/civicrm/civicrm-core/pull/13340))** + + Before this change attempting to geocode an address with a long street number + would result in a fatal error "DB Error Out of range value for column + 'street_number'". This change aborts parsing for addresses with long street + numbers. + +- **geocode job: Do not return more messages than can fit in the log data column + ([13346](https://github.com/civicrm/civicrm-core/pull/13346))** + + This change fixes an error: "DB Error: Data too long for column 'data' at row + 1" when running the geocoder job on a site with over 500 unparseable + addresses. This error was being thrown because the message in the job log was + too big to be saved, and this change makes it so that the message is shortened to + fit in the database. + +- **only set custom field to null if it is really null, not string 'null' + ([13042](https://github.com/civicrm/civicrm-core/pull/13042))** + + Custom fields saved with `NULL`, `Null`, or any value other than `null` will + be saved as-is. A value of `null`, however, still saves a null value. + +- **CRM/Logging - Fix various bugs in schema parsing + ([13441](https://github.com/civicrm/civicrm-core/pull/13441))** + + This change improves logging so that logs return constraints as well as + indexes (before this change indexes were not returned), and returns column + lengths without surrounding parenthesis and returns arrays using ['index1', + 'index2'] syntax instead of [0 => ['constraint_name' => 'foo']] syntax. + +- **CRM/Logging - Fix log table exceptions + ([13675](https://github.com/civicrm/civicrm-core/pull/13675))** + + This change ensures that log table exceptions are applied for columns + regardless of whether or not they have backticks. + +- **Fix html2pdf default PDF format when multiple pdf_format are available. + ([13543](https://github.com/civicrm/civicrm-core/pull/13543))** + + This change ensures that the correct default PDF format is selected when + multiple pdf format options are available. + +- **Always load recaptcha JS over HTTPS + ([13601](https://github.com/civicrm/civicrm-core/pull/13601))** + + This change ensures that reCAPTCHA is loaded regardless of whether the site is + being served over HTTP or HTTPS. + +- **If a profile is used to create a contact with a subtype the contact will not + have any existing subtypes + ([13499](https://github.com/civicrm/civicrm-core/pull/13499))** + + This change fixes PHP notices being thrown when creating a contact with a + subtype via a profile. + +- **Remove activitystatus js. Add submitOnce handler for activity create + ([13342](https://github.com/civicrm/civicrm-core/pull/13342))** + + This change makes it so users can only click "save" once when creating an + activity to prevent users from accidentally creating multiple activities by + clicking save multiple times. + +- **Fix contact ID help on advanced search + ([13569](https://github.com/civicrm/civicrm-core/pull/13569))** + + This change ensures the help text appears when one clicks the help icon next + to Contact ID on the Advanced Search form. + +- **Used buildoptions function to get all groups + ([13327](https://github.com/civicrm/civicrm-core/pull/13327))** + + This change fixes a "DB Error: no such field" message when using the Contact + API to get contacts from a group where the group name and group title are + different so that no error is thrown. + +### CiviCase + +- **[dev/core#684](https://lab.civicrm.org/dev/core/issues/684) Case Manager not + updating correctly (CiviCRM 5.8.2) + ([13528](https://github.com/civicrm/civicrm-core/pull/13528))** + + This change ensures that if the Case Manager is changed on the Manage Case + screen the "(Case Manager)" tag appears correctly. + +- **[dev/core#739](https://lab.civicrm.org/dev/core/issues/739) Field not found + when sorting report by Case Type as a section header + ([13666](https://github.com/civicrm/civicrm-core/pull/13666))** + + This change fixes the "Unknown column 'case_civireport.case_type_name' in + 'field list'" error thrown on a Case Detail report sorted by the field Case + Type with the option "Section Header" checked. + +- **[dev/core#770](https://lab.civicrm.org/dev/core/issues/770) View Case + Activity page displays disabled custom fields + ([13741](https://github.com/civicrm/civicrm-core/pull/13741))** + +### CiviContribute + +- **[dev/core#644](https://lab.civicrm.org/dev/core/issues/644) "From" address + on membership renewal notices is wrong + ([13776](https://github.com/civicrm/civicrm-core/pull/13776))** + + In some configurations, contribution receipts would be sent with a contact ID + as the "From" address rather than an actual address. + +- **[dev/core#659](https://lab.civicrm.org/dev/core/issues/659) Civi returning + 500 errors to Paypal Pro request to civicrm/extern/ipn.php + ([13796](https://github.com/civicrm/civicrm-core/pull/13796))** + + When CiviCRM encounters an error in processing an instant payment + notification, it no longer returns HTTP status of 500. PayPal would disable + IPN after too many 500 errors, assuming the site is broken. + +- **[dev/core#716](https://lab.civicrm.org/dev/core/issues/716) Add decimals in + Contribution Amount on Repeat Contributions Report + ([13659](https://github.com/civicrm/civicrm-core/pull/13659))** + + This change ensures that the Repeat Contributions Report does not truncate the + decimals of contributions. + +- **[dev/core#801](https://lab.civicrm.org/dev/core/issues/801) Thank You + letters have an invalid 'from' when sending from the contact's email address + ([13825](https://github.com/civicrm/civicrm-core/pull/13825))** + +- **[dev/core#720](https://lab.civicrm.org/dev/core/issues/720) Performance + change approved - remove mode & median slow queries + ([13607](https://github.com/civicrm/civicrm-core/pull/13607), + [13630](https://github.com/civicrm/civicrm-core/pull/13630) and + [13605](https://github.com/civicrm/civicrm-core/pull/13605))** + + This change removes the mode and median stats on the contribution search + summary and contribution tab on contacts to improve performance. + +- **Remove another instance of 'lower' + ([13636](https://github.com/civicrm/civicrm-core/pull/13636))** + + This change improves performance when searching notes fields on a + contribution. + +- **[dev/core#769](https://lab.civicrm.org/dev/core/issues/769) ZIP Archive for + multiple batch exports fail + ([13728](https://github.com/civicrm/civicrm-core/pull/13728))** + + This change fixes ZIP Archives for multiple batch exports for instances with + any PHP version greater than 5.6. + +- **[dev/report#7](https://lab.civicrm.org/dev/report/issues/7) Transaction Date + filter in Bookkeeping Transactions report + ([13571](https://github.com/civicrm/civicrm-core/pull/13571))** + + This change ensures that the trxn_date field on the Bookkeeping Report filter + respects the times designated in the filter. Before this change it would only + return transactions that occurred at midnight. + +- **[dev/core#812](https://lab.civicrm.org/dev/core/issues/812) Contribution row + displayed even if contact has 0 contributions. + ([13881](https://github.com/civicrm/civicrm-core/pull/13881))** + +- **Status of test contribution is not fetched on ThankYou page. + ([13724](https://github.com/civicrm/civicrm-core/pull/13724))** + + This change ensures that on a Contribution page with a payment processor that + captures payment instantly and does not use the confirmation page, the + confirmation message on the Thank You page states the status of the + transaction instead of "Your contribution has been submitted...". + +- **Move assign of currency for entityForm outside of foreach so order of fields + don't matter ([13696](https://github.com/civicrm/civicrm-core/pull/13696))** + + This change ensures assign currency works regardless of whether currency is + before or after the money fields. + +- **Find Contributions columns/headers not aligned when "Contributions OR Soft + Credits?" filter set to "Soft Credits Only" + ([13517](https://github.com/civicrm/civicrm-core/pull/13517))** + + This change ensures that when running a Find Contributions search with the + "Contributions OR Soft Credits?" filter set to "Soft Credits Only" the headers + line up with the correct columns. + +### CiviEvent + +- **[dev/core#696](https://lab.civicrm.org/dev/core/issues/696) Changes to + copied event phone and email reflects in original event phone and email + ([13534](https://github.com/civicrm/civicrm-core/pull/13534))** + + This change fixes a bug where if a user copied an event and then edited the + email and or phone number on the copy, the changes would be applied to the + original event. + +- **Fix Custom post outer div class on event registration form + ([13753](https://github.com/civicrm/civicrm-core/pull/13753))** + + This change updates the class applied to the outer div around a custom profile + in the post section of the form to use 1 custom_pre-section and 1 + custom_post-section instead of two custom_pre-sections. + +- **Fix the invocation of post hook for ParticipantPayment ensuring that an id + is passed in post hook + ([13739](https://github.com/civicrm/civicrm-core/pull/13739))** + +### CiviMail + +- **[dev/core#469](https://lab.civicrm.org/dev/core/issues/469) Error on action + "Email - schedule/send via CiviMail" with multiple event names filter + ([13539](https://github.com/civicrm/civicrm-core/pull/13539))** + +- **CiviMail: Fix reply forwarding for mailers with From: and Return-path: + limitations ([12641](https://github.com/civicrm/civicrm-core/pull/12641))** + +- **"Only variable references should be returned by reference" notice in + Mail_smtp ([220](https://github.com/civicrm/civicrm-packages/pull/220))** + + This change fixes a "Only variable references should be returned by reference" + PHP notice under various SMTP error conditions. + +### CiviMember + +- **[dev/core#631](https://lab.civicrm.org/dev/core/issues/631) Problem when + merging contacts which have membership records + ([13588](https://github.com/civicrm/civicrm-core/pull/13588))** + + When merging contacts with memberships, the default is now that the "add new" + box is checked. This brings memberships over from the left-hand contact + without attempting to merge memberships. Merging memberships from the contact + merge interface can result in data loss. + +### Drupal Integration + +- **fix broken logic in CRM_Utils_System_DrupalBase::formatResourceUrl() + ([13400](https://github.com/civicrm/civicrm-core/pull/13400))** + + This change fixes a bug where Drupal sites were not processing absolute URLs + containing the $base_url passed in from extensions (like Shoreditch) + correctly. + +- **[dev/core#381](https://lab.civicrm.org/dev/core/issues/381) + civicrm/file/imagefile serving up wrong images + ([564](https://github.com/civicrm/civicrm-drupal/pull/564)) Extends work** + + This change fixes a problem with the Views file field handler displaying + incorrect uploaded images. + +### Wordpress Integration + +- **[dev/wordpress#18](https://lab.civicrm.org/dev/wordpress/issues/18) wp-cli + sometimes fails to find cms path + ([147](https://github.com/civicrm/civicrm-wordpress/pull/147))** + + This change ensures that the path specified to wp-cli as `--path` is passed to + CiviCRM which fixes some URL errors specifically but not limited to when + sending bulk mailings with trackable URLs. + +## <a name="misc"></a>Miscellany + +- **Upgrade Karma version to latest version + ([13751](https://github.com/civicrm/civicrm-core/pull/13751))** + +- **[infra/ops#878](https://lab.civicrm.org/infra/ops/issues/878) Add a test + matrix for E2E tests on each CMS + ([13808](https://github.com/civicrm/civicrm-core/pull/13808))** + + This change improves reliability by increasing test coverage. + +- **Try and add data set example where email_on_hold / on_hold is NULL in the + formValues ([13765](https://github.com/civicrm/civicrm-core/pull/13765))** + + This change adds test coverage for certain smart group criteria. + +- **[dev/core#746](https://lab.civicrm.org/dev/core/issues/746) Search Builder + searches using > 1 smart group where operator is equals is broken from 5.10.0 + ([13685](https://github.com/civicrm/civicrm-core/pull/13685)) Continued work** + + This change adds test coverage for Search Builder searches using > 1 smart + group. + +- **[dev/report#10](https://lab.civicrm.org/dev/report/issues/10) No pagination + on Contribution Detail report + ([13678](https://github.com/civicrm/civicrm-core/pull/13678)) Continued Work** + + This change adds a unit test for pagination on the Contribution Detail report. + +- **Optimize CRM_Core_BAO_FinancialTrxn::getTotalPayment + ([13187](https://github.com/civicrm/civicrm-core/pull/13187))** + +- **Bump minimum upgradable ver to 4.2.9 + ([13580](https://github.com/civicrm/civicrm-core/pull/13580))** + +- **Use CRM_Utils_SQL_TempTable to drop and create table. + ([13688](https://github.com/civicrm/civicrm-core/pull/13688))** + +- **Clean up Payment.create function + ([13690](https://github.com/civicrm/civicrm-core/pull/13690))** + +- **[dev/report#9](https://lab.civicrm.org/dev/report/issues/9) Deprecate + `getBasicContactFields` in favor of `getColumns('Contact')` + ([13657](https://github.com/civicrm/civicrm-core/pull/13657))** + +- **Extract getSearchSQLParts function + ([13735](https://github.com/civicrm/civicrm-core/pull/13735))** + +- **[Test changes] Mailing job test use + ([13629](https://github.com/civicrm/civicrm-core/pull/13629))** + +- **Code cleanup - remove extraneous permissions clause + ([13645](https://github.com/civicrm/civicrm-core/pull/13645))** + +- **Fix typo in comments + ([13771](https://github.com/civicrm/civicrm-core/pull/13771))** + +- **Removes redundant IF + ([13769](https://github.com/civicrm/civicrm-core/pull/13769))** + +- **(NFC) formatting changes + ([148](https://github.com/civicrm/civicrm-wordpress/pull/148))** + +- **report clean up - remove redundant code + ([13761](https://github.com/civicrm/civicrm-core/pull/13761))** + +- **Fix typo and space + ([13577](https://github.com/civicrm/civicrm-core/pull/13577))** + +- **[minor cleanup] reduce params passed to searchQuery + ([13715](https://github.com/civicrm/civicrm-core/pull/13715))** + +- **[TEST FIX] Increase uniqueness in testSingleNowDates + ([13705](https://github.com/civicrm/civicrm-core/pull/13705))** + +- **Revert "[REF] Extract record refund function" + ([13693](https://github.com/civicrm/civicrm-core/pull/13693))** + +- **Minor code cleanup + ([13687](https://github.com/civicrm/civicrm-core/pull/13687))** + +- **[NFC, test class] formatting, remove unused variables + ([13634](https://github.com/civicrm/civicrm-core/pull/13634))** + +- **Authorizenet test - reduce chance of intermittent fails + ([13642](https://github.com/civicrm/civicrm-core/pull/13642))** + +- **[unused code cleanup] Remove unused 'signupType' url support + ([13620](https://github.com/civicrm/civicrm-core/pull/13620))** + +- **[Test support] Add extra output info when getsingle fails as this seems to + be common in intermittant fails + ([13618](https://github.com/civicrm/civicrm-core/pull/13618))** + +- **Remove tests that no longer work due to dead service + ([13617](https://github.com/civicrm/civicrm-core/pull/13617))** + +- **Refactor CRM_Utils_SQL_TempTable::build()->createWithQuery($sql) interface + to support MEMORY tabls + ([13644](https://github.com/civicrm/civicrm-core/pull/13644))** + +- **REF Convert deprecated functions to buildOptions for case + ([13364](https://github.com/civicrm/civicrm-core/pull/13364))** + +- **[REF] Extract record refund function + ([13691](https://github.com/civicrm/civicrm-core/pull/13691))** + +- **[REF] Extract getSearchSQL from getSearchQuery. + ([13668](https://github.com/civicrm/civicrm-core/pull/13668))** + +- **[REF] minor code cleanup - do not build order var just to hurt brains + ([13650](https://github.com/civicrm/civicrm-core/pull/13650))** + +- **[REF] minor cleanup of groupBy definition. + ([13656](https://github.com/civicrm/civicrm-core/pull/13656))** + +- **[REF] extract add median to stats + ([13616](https://github.com/civicrm/civicrm-core/pull/13616))** + +- **[REF] extract cancelled stats to own function + ([13626](https://github.com/civicrm/civicrm-core/pull/13626))** + +- **[REF] Move entityRef filters into their respective BAOs + ([13625](https://github.com/civicrm/civicrm-core/pull/13625))** + +- **[REF] extract basic soft credit stats to separate function + ([13622](https://github.com/civicrm/civicrm-core/pull/13622))** + +- **[REF] Remove unused function parameter + ([13619](https://github.com/civicrm/civicrm-core/pull/13619))** + +- **[REF] Extract lines to add the pseudoconstant to the select + ([13717](https://github.com/civicrm/civicrm-core/pull/13717))** + +- **[REF] extract calculation of mode stat + ([13614](https://github.com/civicrm/civicrm-core/pull/13614))** + +- **[REF] extract calculation of basic stats + ([13608](https://github.com/civicrm/civicrm-core/pull/13608))** + +- **[REF] Move addSelectWhere-like function to be located on BAO_Contribution + ([13587](https://github.com/civicrm/civicrm-core/pull/13587))** + +- **[REF] Fix silly function to do less handling of non-existent scenarios + ([13563](https://github.com/civicrm/civicrm-core/pull/13563))** + +- **[REF] extract chunk of code to a separate function + ([13600](https://github.com/civicrm/civicrm-core/pull/13600))** + +- **[REF] Use api rather than selector for rendering contributions on user + dashboard ([13584](https://github.com/civicrm/civicrm-core/pull/13584) and + [13903](https://github.com/civicrm/civicrm-core/pull/13903))** + +- **[REF] switch from (undeclared) class property to local variable. + ([13583](https://github.com/civicrm/civicrm-core/pull/13583))** + +- **[REF] Minor readability cleanup + ([13562](https://github.com/civicrm/civicrm-core/pull/13562))** + +- **[REF] Remove useless class CRM_Report_Form_Event + ([13632](https://github.com/civicrm/civicrm-core/pull/13632))** + +- **[REF] extract getToFinancialAccount from + CRM_Contribute_PseudoConstantt::contributionStatus + ([13757](https://github.com/civicrm/civicrm-core/pull/13757))** + +- **[ref] Extract activity payment creation + ([13695](https://github.com/civicrm/civicrm-core/pull/13695))** + +- **[REF] separate financial handling & component transitioning in + Payment.create ([13756](https://github.com/civicrm/civicrm-core/pull/13756))** + +- **[REF] towards cleanup of update membership code + ([13759](https://github.com/civicrm/civicrm-core/pull/13759))** + +- **(REF) Rename variables and adjust variable definitions for Event Register + form ([13287](https://github.com/civicrm/civicrm-core/pull/13287))** + +- **[REF] Extract recordPayment portion + ([13692](https://github.com/civicrm/civicrm-core/pull/13692))** + +- **[REF] minor refactor around retrieving processor id for recur + ([13643](https://github.com/civicrm/civicrm-core/pull/13643))** + +- **[code cleanup] Default wrong declared + ([13621](https://github.com/civicrm/civicrm-core/pull/13621))** + +- **[Code cleanup] Remove unused $stationery_path parameter + ([13624](https://github.com/civicrm/civicrm-core/pull/13624))** + +- **Remove long block of commented out code from 4 years ago + ([13623](https://github.com/civicrm/civicrm-core/pull/13623))** + +- **Add unit test on getContributionBalance fn (#13187) + ([13558](https://github.com/civicrm/civicrm-core/pull/13558))** + +- **Phase out CIVICRM_TEMP_FORCE_UTF8 + ([13658](https://github.com/civicrm/civicrm-core/pull/13658))** + +- **Extract record refund function + ([13694](https://github.com/civicrm/civicrm-core/pull/13694))** + +- **Move pear/mail from packages to composer.json + ([13289](https://github.com/civicrm/civicrm-core/pull/13289))** + +- **Decommision getPartialPaymentTrxn function + ([13718](https://github.com/civicrm/civicrm-core/pull/13718))** + +- **Fix & test searchQuery order by to be less dependent on what is selected for + search ([13680](https://github.com/civicrm/civicrm-core/pull/13680))** + +- **EntityRef - Standardize on PascalCase for entity name and fix minor bug + ([13631](https://github.com/civicrm/civicrm-core/pull/13631))** + +## <a name="credits"></a>Credits + +This release was developed by the following code authors: + +AGH Strategies - Alice Frumin, Andrew Hunt; Agileware - Alok Patel; Alexy +Mikhailichenko; Australian Greens - Seamus Lee; avall-llovera; CiviCRM - Coleman +Watts, Tim Otten; CiviDesk - Yashodha Chaku; Coop SymbioTIC - Mathieu Lutfy; +Electronic Frontier Foundation - Mark Burdett; Francesc Bassas i Bullich; Fuzion - +Jitendra Purohit; GreenPeace Central and Eastern Europe - Patrick Figel; JMA +Consulting - Edsel Lopez, Monish Deb; Ken West; Lighthouse Design and Consulting - +Brian Shaughnessy; Megaphone Technology Consulting - Jon Goldberg; MJW +Consulting - Matthew Wire; Nicol Wistreich; Pradeep Nayak; Skvare - Mark Hanna; +Squiffle Consulting - Aidan Saunders; Wikimedia Foundation - Eileen McNaughton + +Most authors also reviewed code for this release; in addition, the following +reviewers contributed their comments: + +Agileware - Justin Freeman; Circle Interactive - Dave Jenkins, Reece Benson; +CiviDesk - Sunil Pawar; Dave D; Fuzion - Peter Davis; JMA Consulting - Joe +Murray; Luna Design - Andrew Wasson; Mark Westergaard; MJCO - Mikey O'Toole; +Progressive Technology Project - Jamie McClelland; Richard van Oosterhout; +Tadpole Collective - Kevin Cristiano; Third Sector Design - Michael McAndrew + +## <a name="feedback"></a>Feedback + +These release notes are edited by Alice Frumin and Andrew 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/Core.setting.php b/civicrm/settings/Core.setting.php index b332f3b8e1..8d4cdc0968 100644 --- a/civicrm/settings/Core.setting.php +++ b/civicrm/settings/Core.setting.php @@ -1017,4 +1017,24 @@ return array( ), 'quick_form_type' => 'Select', ), + 'menubar_position' => array( + 'group_name' => 'CiviCRM Preferences', + 'group' => 'core', + 'name' => 'menubar_position', + 'type' => 'String', + 'html_type' => 'select', + 'default' => 'over-cms-menu', + 'add' => '5.9', + 'title' => ts('Menubar position'), + 'is_domain' => 1, + 'is_contact' => 0, + 'description' => ts('Location of the CiviCRM main menu.'), + 'help_text' => NULL, + 'options' => array( + 'over-cms-menu' => ts('Replace website menu'), + 'below-cms-menu' => ts('Below website menu'), + 'above-crm-container' => ts('Above content area'), + 'none' => ts('None - disable menu'), + ), + ), ); diff --git a/civicrm/settings/Localization.setting.php b/civicrm/settings/Localization.setting.php index 54f05b2971..3d15ee0f22 100644 --- a/civicrm/settings/Localization.setting.php +++ b/civicrm/settings/Localization.setting.php @@ -156,11 +156,11 @@ return array( 'html_attributes' => array( //'class' => 'crm-select2', ), - 'default' => '1228', 'add' => '4.4', 'title' => 'Default Country', 'is_domain' => 1, 'is_contact' => 0, + 'is_required' => FALSE, 'description' => 'This value is selected by default when adding a new contact address.', 'help_text' => NULL, 'pseudoconstant' => array( diff --git a/civicrm/settings/Multisite.setting.php b/civicrm/settings/Multisite.setting.php index 7325a95b18..6f4770bba1 100644 --- a/civicrm/settings/Multisite.setting.php +++ b/civicrm/settings/Multisite.setting.php @@ -58,7 +58,7 @@ return array( 'title' => ts('Multisite Domain Group'), 'type' => 'Integer', 'html_type' => 'entity_reference', - 'entity_reference_options' => ['entity' => 'group', 'select' => array('minimumInputLength' => 0)], + 'entity_reference_options' => ['entity' => 'Group', 'select' => array('minimumInputLength' => 0)], 'default' => '0', 'add' => '4.1', 'is_domain' => 1, diff --git a/civicrm/sql/civicrm.mysql b/civicrm/sql/civicrm.mysql index c95ec4ca49..8c9a3159ed 100644 --- a/civicrm/sql/civicrm.mysql +++ b/civicrm/sql/civicrm.mysql @@ -1497,8 +1497,8 @@ CREATE TABLE `civicrm_dedupe_exception` ( `id` int unsigned NOT NULL AUTO_INCREMENT COMMENT 'Unique dedupe exception id', - `contact_id1` int unsigned COMMENT 'FK to Contact ID', - `contact_id2` int unsigned COMMENT 'FK to Contact ID' + `contact_id1` int unsigned NOT NULL COMMENT 'FK to Contact ID', + `contact_id2` int unsigned NOT NULL COMMENT 'FK to Contact ID' , PRIMARY KEY (`id`) @@ -4084,7 +4084,7 @@ CREATE TABLE `civicrm_contribution_recur` ( `id` int unsigned NOT NULL AUTO_INCREMENT COMMENT 'Contribution Recur ID', - `contact_id` int unsigned NOT NULL COMMENT 'Foreign key to civicrm_contact.id .', + `contact_id` int unsigned NOT NULL COMMENT 'Foreign key to civicrm_contact.id.', `amount` decimal(20,2) NOT NULL COMMENT 'Amount to be contributed or charged each recurrence.', `currency` varchar(3) DEFAULT NULL COMMENT '3 character string, value from config setting or input via user.', `frequency_unit` varchar(8) DEFAULT 'month' COMMENT 'Time units for recurrence of payment.', diff --git a/civicrm/sql/civicrm_data.mysql b/civicrm/sql/civicrm_data.mysql index 4c45025199..aaaee6ad9c 100644 --- a/civicrm/sql/civicrm_data.mysql +++ b/civicrm/sql/civicrm_data.mysql @@ -11897,15 +11897,13 @@ INSERT INTO civicrm_msg_template ', @tpl_ovid_pcp_owner_notify, 0, 1) , - ('Additional Payment Receipt or Refund Notification', '{if $isRefund}{ts}Refund Notification{/ts}{else}{ts}Payment Receipt{/ts}{/if} - {if $component eq \'event\'}{$event.title}{/if}', 'Dear {$contactDisplayName} -{if $isRefund} + ('Additional Payment Receipt or Refund Notification', '{if $isRefund}{ts}Refund Notification{/ts}{else}{ts}Payment Receipt{/ts}{/if} - {if $component eq \'event\'}{$event.title}{/if}', '{if $emailGreeting}{$emailGreeting}, +{/if}{if $isRefund} {ts}A refund has been issued based on changes in your registration selections.{/ts} {else} {ts}A payment has been received.{/ts} {/if} -{ts}Please print this confirmation for your records.{/ts} - {if $isRefund} =============================================================================== @@ -11945,7 +11943,7 @@ INSERT INTO civicrm_msg_template {if $checkNumber} {ts}Check Number{/ts}: {$checkNumber} {/if} -{if $contributeMode eq \'direct\' and !$isAmountzero} +{if $billingName || $address} =============================================================================== @@ -11957,7 +11955,7 @@ INSERT INTO civicrm_msg_template {$address} {/if} -{if $contributeMode eq \'direct\' and !$isAmountzero} +{if $credit_card_number} =========================================================== {ts}Credit Card Information{/ts} @@ -12013,7 +12011,6 @@ INSERT INTO civicrm_msg_template {capture assign=emptyBlockStyle }style="padding: 10px; border-bottom: 1px solid #999;background-color: #f7f7f7;"{/capture} {capture assign=emptyBlockValueStyle }style="padding: 10px; border-bottom: 1px solid #999;"{/capture} -<p>Dear {$contactDisplayName}</p> <center> <table width="620" border="0" cellpadding="0" cellspacing="0" id="crm-event_receipt" style="font-family: Arial, Verdana, sans-serif; text-align: left;"> @@ -12022,7 +12019,7 @@ INSERT INTO civicrm_msg_template <!-- END HEADER --> <!-- BEGIN CONTENT --> - + {if $emailGreeting}<tr><td>{$emailGreeting},</td></tr>{/if} <tr> <td> {if $isRefund} @@ -12030,7 +12027,6 @@ INSERT INTO civicrm_msg_template {else} <p>{ts}A payment has been received.{/ts}</p> {/if} - <p>{ts}Please print this confirmation for your records.{/ts}</p> </td> </tr> <tr> @@ -12148,7 +12144,7 @@ INSERT INTO civicrm_msg_template <tr> <td> <table style="border: 1px solid #999; margin: 1em 0em 1em; border-collapse: collapse; width:100%;"> - {if $contributeMode eq \'direct\' and !$isAmountzero} + {if $billingName || $address} <tr> <th {$headerStyle}> {ts}Billing Name and Address{/ts} @@ -12161,7 +12157,7 @@ INSERT INTO civicrm_msg_template </td> </tr> {/if} - {if $contributeMode eq\'direct\' and !$isAmountzero} + {if $credit_card_number} <tr> <th {$headerStyle}> {ts}Credit Card Information{/ts} @@ -12253,15 +12249,13 @@ INSERT INTO civicrm_msg_template </body> </html> ', @tpl_ovid_payment_or_refund_notification, 1, 0), - ('Additional Payment Receipt or Refund Notification', '{if $isRefund}{ts}Refund Notification{/ts}{else}{ts}Payment Receipt{/ts}{/if} - {if $component eq \'event\'}{$event.title}{/if}', 'Dear {$contactDisplayName} -{if $isRefund} + ('Additional Payment Receipt or Refund Notification', '{if $isRefund}{ts}Refund Notification{/ts}{else}{ts}Payment Receipt{/ts}{/if} - {if $component eq \'event\'}{$event.title}{/if}', '{if $emailGreeting}{$emailGreeting}, +{/if}{if $isRefund} {ts}A refund has been issued based on changes in your registration selections.{/ts} {else} {ts}A payment has been received.{/ts} {/if} -{ts}Please print this confirmation for your records.{/ts} - {if $isRefund} =============================================================================== @@ -12301,7 +12295,7 @@ INSERT INTO civicrm_msg_template {if $checkNumber} {ts}Check Number{/ts}: {$checkNumber} {/if} -{if $contributeMode eq \'direct\' and !$isAmountzero} +{if $billingName || $address} =============================================================================== @@ -12313,7 +12307,7 @@ INSERT INTO civicrm_msg_template {$address} {/if} -{if $contributeMode eq \'direct\' and !$isAmountzero} +{if $credit_card_number} =========================================================== {ts}Credit Card Information{/ts} @@ -12369,7 +12363,6 @@ INSERT INTO civicrm_msg_template {capture assign=emptyBlockStyle }style="padding: 10px; border-bottom: 1px solid #999;background-color: #f7f7f7;"{/capture} {capture assign=emptyBlockValueStyle }style="padding: 10px; border-bottom: 1px solid #999;"{/capture} -<p>Dear {$contactDisplayName}</p> <center> <table width="620" border="0" cellpadding="0" cellspacing="0" id="crm-event_receipt" style="font-family: Arial, Verdana, sans-serif; text-align: left;"> @@ -12378,7 +12371,7 @@ INSERT INTO civicrm_msg_template <!-- END HEADER --> <!-- BEGIN CONTENT --> - + {if $emailGreeting}<tr><td>{$emailGreeting},</td></tr>{/if} <tr> <td> {if $isRefund} @@ -12386,7 +12379,6 @@ INSERT INTO civicrm_msg_template {else} <p>{ts}A payment has been received.{/ts}</p> {/if} - <p>{ts}Please print this confirmation for your records.{/ts}</p> </td> </tr> <tr> @@ -12504,7 +12496,7 @@ INSERT INTO civicrm_msg_template <tr> <td> <table style="border: 1px solid #999; margin: 1em 0em 1em; border-collapse: collapse; width:100%;"> - {if $contributeMode eq \'direct\' and !$isAmountzero} + {if $billingName || $address} <tr> <th {$headerStyle}> {ts}Billing Name and Address{/ts} @@ -12517,7 +12509,7 @@ INSERT INTO civicrm_msg_template </td> </tr> {/if} - {if $contributeMode eq\'direct\' and !$isAmountzero} + {if $credit_card_number} <tr> <th {$headerStyle}> {ts}Credit Card Information{/ts} @@ -24043,4 +24035,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.11.0'; +UPDATE civicrm_domain SET version = '5.12.0'; diff --git a/civicrm/sql/civicrm_generated.mysql b/civicrm/sql/civicrm_generated.mysql index 152a14bb6f..e3f586d11e 100644 --- a/civicrm/sql/civicrm_generated.mysql +++ b/civicrm/sql/civicrm_generated.mysql @@ -399,7 +399,7 @@ UNLOCK TABLES; LOCK TABLES `civicrm_domain` WRITE; /*!40000 ALTER TABLE `civicrm_domain` DISABLE KEYS */; -INSERT INTO `civicrm_domain` (`id`, `name`, `description`, `config_backend`, `version`, `contact_id`, `locales`, `locale_custom_strings`) VALUES (1,'Default Domain Name',NULL,NULL,'5.11.0',1,NULL,'a:1:{s:5:\"en_US\";a:0:{}}'); +INSERT INTO `civicrm_domain` (`id`, `name`, `description`, `config_backend`, `version`, `contact_id`, `locales`, `locale_custom_strings`) VALUES (1,'Default Domain Name',NULL,NULL,'5.12.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/Activity/Form/Activity.tpl b/civicrm/templates/CRM/Activity/Form/Activity.tpl index 28f9145495..9069edfc88 100644 --- a/civicrm/templates/CRM/Activity/Form/Activity.tpl +++ b/civicrm/templates/CRM/Activity/Form/Activity.tpl @@ -32,8 +32,6 @@ {/if} <div class="crm-block crm-form-block crm-activity-form-block"> {/if} - {* added onload javascript for source contact*} - {include file="CRM/Activity/Form/ActivityJs.tpl" tokenContext="activity"} {if !$action or ( $action eq 1 ) or ( $action eq 2 ) } <div class="crm-submit-buttons">{include file="CRM/common/formButtons.tpl" location="top"}</div> {/if} diff --git a/civicrm/templates/CRM/Activity/Form/ActivityJs.tpl b/civicrm/templates/CRM/Activity/Form/ActivityJs.tpl deleted file mode 100644 index d3d517aaed..0000000000 --- a/civicrm/templates/CRM/Activity/Form/ActivityJs.tpl +++ /dev/null @@ -1,51 +0,0 @@ -{* - +--------------------------------------------------------------------+ - | CiviCRM version 5 | - +--------------------------------------------------------------------+ - | Copyright CiviCRM LLC (c) 2004-2019 | - +--------------------------------------------------------------------+ - | This file is a part of CiviCRM. | - | | - | CiviCRM is free software; you can copy, modify, and distribute it | - | under the terms of the GNU Affero General Public License | - | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. | - | | - | CiviCRM is distributed in the hope that it will be useful, but | - | WITHOUT ANY WARRANTY; without even the implied warranty of | - | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | - | See the GNU Affero General Public License for more details. | - | | - | You should have received a copy of the GNU Affero General Public | - | License and the CiviCRM Licensing Exception along | - | with this program; if not, contact CiviCRM LLC | - | at info[AT]civicrm[DOT]org. If you have questions about the | - | GNU Affero General Public License or the licensing of CiviCRM, | - | see the CiviCRM license FAQ at http://civicrm.org/licensing | - +--------------------------------------------------------------------+ -*} -{* added onload javascript for source contact*} -{literal} -<script type="text/javascript"> - /** - * Function to check activity status in relavent to activity date - * - * @param message JSON object. - */ - function activityStatus(message) { - var activityDate = cj("#activity_date_time_display").datepicker('getDate'); - if (activityDate) { - var - // Ignore time, only compare dates - today = new Date().setHours(0,0,0,0), - activityStatusId = cj('#status_id').val(); - if (activityStatusId == 2 && today < activityDate) { - return confirm(message.completed); - } - else if (activityStatusId == 1 && today > activityDate) { - return confirm(message.scheduled); - } - } - } - -</script> -{/literal} diff --git a/civicrm/templates/CRM/Activity/Form/Search/Common.tpl b/civicrm/templates/CRM/Activity/Form/Search/Common.tpl index b260c49bb2..9df96580da 100644 --- a/civicrm/templates/CRM/Activity/Form/Search/Common.tpl +++ b/civicrm/templates/CRM/Activity/Form/Search/Common.tpl @@ -89,10 +89,9 @@ </tr> <tr> - <td><label>{ts}Activity Dates{/ts}</label></td> -</tr> -<tr> - {include file="CRM/Core/DateRange.tpl" fieldName="activity_date" from='_low' to='_high'} + <td> + {include file="CRM/Core/DatePickerRange.tpl" fieldName="activity_date_time" from='_low' to='_high'} + </td> </tr> <tr> <td> diff --git a/civicrm/templates/CRM/Admin/Form/Preferences/Display.tpl b/civicrm/templates/CRM/Admin/Form/Preferences/Display.tpl index de8986889f..02f0f38f7e 100644 --- a/civicrm/templates/CRM/Admin/Form/Preferences/Display.tpl +++ b/civicrm/templates/CRM/Admin/Form/Preferences/Display.tpl @@ -209,6 +209,13 @@ <td> </td> <td class="description">{$settings_fields.sort_name_format.description}</td> </tr> + <tr class="crm-preferences-display-form-block_menubar_position"> + <td class="label">{$form.menubar_position.label}</td> + <td> + {$form.menubar_position.html} + <div class="description">{ts}Default position for the CiviCRM menubar.{/ts}</div> + </td> + </tr> </table> <div class="crm-submit-buttons">{include file="CRM/common/formButtons.tpl" location="bottom"}</div> </div> diff --git a/civicrm/templates/CRM/Case/Form/Activity.tpl b/civicrm/templates/CRM/Case/Form/Activity.tpl index fff7efa834..dc48f6202e 100644 --- a/civicrm/templates/CRM/Case/Form/Activity.tpl +++ b/civicrm/templates/CRM/Case/Form/Activity.tpl @@ -30,10 +30,6 @@ {if $action neq 8 and $action neq 32768 } {* Include form buttons on top for new and edit modes. *} <div class="crm-submit-buttons">{include file="CRM/common/formButtons.tpl" location="top"}</div> - - {* added onload javascript for source contact*} - {include file="CRM/Activity/Form/ActivityJs.tpl" tokenContext="case_activity"} - {/if} {if $action eq 8 or $action eq 32768 } diff --git a/civicrm/templates/CRM/Case/Form/Activity/ChangeCaseType.tpl b/civicrm/templates/CRM/Case/Form/Activity/ChangeCaseType.tpl index 000cccb578..34630c50f5 100644 --- a/civicrm/templates/CRM/Case/Form/Activity/ChangeCaseType.tpl +++ b/civicrm/templates/CRM/Case/Form/Activity/ChangeCaseType.tpl @@ -33,17 +33,18 @@ <td class="label">{$form.is_reset_timeline.label}</td> <td>{$form.is_reset_timeline.html}</td> </tr> - <tr class="crm-case-changecasetype-form-block-reset_date_time" id="resetTimeline"> - <td class="label">{$form.reset_date_time.label}</td> - <td>{include file="CRM/common/jcalendar.tpl" elementName=reset_date_time}</td> + <tr class="crm-case-changecasetype-form-block-reset_date_time"> + <td class="label">{$form.reset_date_time.label} <span class="crm-marker">*</span></td> + <td>{$form.reset_date_time.html}</td> </tr> - -{include file="CRM/common/showHideByFieldValue.tpl" -trigger_field_id ="is_reset_timeline" -trigger_value = true -target_element_id ="resetTimeline" -target_element_type ="table-row" -field_type ="radio" -invert = 0 -} </div> +{literal} + <script type="text/javascript"> + CRM.$(function($) { + var $form = $('form.{/literal}{$form.formClass}{literal}'); + $('input[name=is_reset_timeline]', $form).click(function() { + $('.crm-case-changecasetype-form-block-reset_date_time').toggle($(this).val() === '1'); + }) + }) + </script> +{/literal} diff --git a/civicrm/templates/CRM/Contact/Form/Contact.hlp b/civicrm/templates/CRM/Contact/Form/Contact.hlp index cfa949c977..3aae0d2132 100644 --- a/civicrm/templates/CRM/Contact/Form/Contact.hlp +++ b/civicrm/templates/CRM/Contact/Form/Contact.hlp @@ -128,10 +128,10 @@ <p>{ts}Upload a photo or icon that you want to be displayed when viewing this contact.{/ts}</p> {/htxt} -{htxt id="id-internal-id-title"} +{htxt id="id-contact-id-title"} {ts}Contact ID{/ts} {/htxt} -{htxt id="id-internal-id"} +{htxt id="id-contact-id"} <p>{ts}Every contact in CiviCRM has a unique ID number. This number will never change and is the most accurate way of identifying a contact.{/ts}</p> {/htxt} diff --git a/civicrm/templates/CRM/Contact/Form/Contact.tpl b/civicrm/templates/CRM/Contact/Form/Contact.tpl index 4849891d35..bdb352af04 100644 --- a/civicrm/templates/CRM/Contact/Form/Contact.tpl +++ b/civicrm/templates/CRM/Contact/Form/Contact.tpl @@ -63,7 +63,7 @@ </td> {if $contactId} <td> - <label for="internal_identifier_display">{ts}Contact ID{/ts} {help id="id-internal-id"}</label><br /> + <label for="internal_identifier_display">{ts}Contact ID{/ts} {help id="id-contact-id"}</label><br /> <input id="internal_identifier_display" type="text" class="crm-form-text six" size="6" readonly="readonly" value="{$contactId}"> </td> {/if} diff --git a/civicrm/templates/CRM/Contribute/Form/Selector.tpl b/civicrm/templates/CRM/Contribute/Form/Selector.tpl index 41d19cedce..144d6544db 100644 --- a/civicrm/templates/CRM/Contribute/Form/Selector.tpl +++ b/civicrm/templates/CRM/Contribute/Form/Selector.tpl @@ -61,19 +61,12 @@ <td><a href="{crmURL p='civicrm/contact/view' q="reset=1&cid=`$row.contact_id`"}">{$row.sort_name}</a></td> {/if} <td class="crm-contribution-amount"> - {if !$row.contribution_soft_credit_amount} <a class="nowrap bold crm-expand-row" title="{ts}view payments{/ts}" href="{crmURL p='civicrm/payment' q="view=transaction&component=contribution&action=browse&cid=`$row.contact_id`&id=`$row.contribution_id`&selector=1"}"> {$row.total_amount|crmMoney:$row.currency} </a> - {/if} {if $row.amount_level }<br/>({$row.amount_level}){/if} {if $row.contribution_recur_id}<br/>{ts}(Recurring){/ts}{/if} </td> - {if $softCreditColumns} - <td class="right bold crm-contribution-soft_credit_amount"> - <span class="nowrap">{$row.contribution_soft_credit_amount|crmMoney:$row.currency}</span> - </td> - {/if} {foreach from=$columnHeaders item=column} {assign var='columnName' value=$column.field_name} {if !$columnName}{* if field_name has not been set skip, this helps with not changing anything not specifically edited *} diff --git a/civicrm/templates/CRM/Contribute/Page/ContributionTotals.tpl b/civicrm/templates/CRM/Contribute/Page/ContributionTotals.tpl index d5735b74f0..e98e57f954 100644 --- a/civicrm/templates/CRM/Contribute/Page/ContributionTotals.tpl +++ b/civicrm/templates/CRM/Contribute/Page/ContributionTotals.tpl @@ -41,20 +41,9 @@ {if $contributionSummary } <tr> {if $contributionSummary.total.amount} - {if $contributionSummary.total.currencyCount gt 1} - <th class="contriTotalLeft right">{ts}Total{/ts} – {$contributionSummary.total.amount}</th> - <th class="left contriTotalRight"> {ts}# Completed{/ts} – {$contributionSummary.total.count}</th> - </tr><tr> - <th class="contriTotalLeft">{ts}Avg{/ts} – {$contributionSummary.total.avg}</th> - <th class="right"> {ts}Median{/ts} – {$contributionSummary.total.median}</th> - <th class="right contriTotalRight"> {ts}Mode{/ts} – {$contributionSummary.total.mode}</th> - {else} - <th class="contriTotalLeft right">{ts}Total{/ts} – {$contributionSummary.total.amount}</th> - <th class="right"> {ts}# Completed{/ts} – {$contributionSummary.total.count}</th> - <th class="right"> {ts}Avg{/ts} – {$contributionSummary.total.avg}</th> - <th class="right"> {ts}Median{/ts} – {$contributionSummary.total.median}</th> - <th class="right contriTotalRight"> {ts}Mode{/ts} – {$contributionSummary.total.mode}</th> - {/if} + <th class="contriTotalLeft right">{ts}Total{/ts} – {$contributionSummary.total.amount}</th> + <th class="right"> {ts}# Completed{/ts} – {$contributionSummary.total.count}</th> + <th class="right contriTotalRight"> {ts}Avg{/ts} – {$contributionSummary.total.avg}</th> {/if} {if $contributionSummary.cancel.amount} <th class="disabled right contriTotalRight"> {ts}Cancelled/Refunded{/ts} – {$contributionSummary.cancel.amount}</th> diff --git a/civicrm/templates/CRM/Contribute/Page/UserDashboard.tpl b/civicrm/templates/CRM/Contribute/Page/UserDashboard.tpl index 182dd22679..0c25b8f393 100644 --- a/civicrm/templates/CRM/Contribute/Page/UserDashboard.tpl +++ b/civicrm/templates/CRM/Contribute/Page/UserDashboard.tpl @@ -58,6 +58,7 @@ <td>{$row.contribution_status}</td> {if $invoicing && $invoices} <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='contact_id' value=$row.contact_id} {assign var='urlParams' value="reset=1&id=$id&cid=$contact_id"} @@ -75,6 +76,7 @@ </td> {/if} {if $defaultInvoicePage && $row.contribution_status_name == 'Pending' } + {* @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*} <td> {assign var='checksum_url' value=""} {if $userChecksum} diff --git a/civicrm/templates/CRM/Core/AgeRange.tpl b/civicrm/templates/CRM/Core/AgeRange.tpl index a76ad74a97..beddf36277 100644 --- a/civicrm/templates/CRM/Core/AgeRange.tpl +++ b/civicrm/templates/CRM/Core/AgeRange.tpl @@ -37,22 +37,22 @@ {$form.$maxName.html} </span> </span> -</td> -<td> <span class="crm-age-range-asofdate"> - {assign var=dateName value=$fieldName|cat:$date} - {$form.$dateName.label} - {include file="CRM/common/jcalendar.tpl" elementName=$dateName} + {assign var=dateName value=$fieldName|cat:$date} + {$form.$dateName.label} + {$form.$dateName.html} </span> {literal} <script type="text/javascript"> - cj(".crm-age-range").change(function() { - if (cj('.crm-age-range-min :text').val() || cj('.crm-age-range-max :text').val()) { - cj(".crm-age-range-asofdate").show(); - } else { - cj(".crm-age-range-asofdate").hide(); + CRM.$(function($) { + var $form = $('form.{/literal}{$form.formClass}{literal}'); + function toggleDate() { + $(".crm-age-range-asofdate").toggle(!!($('.crm-age-range-min input', $form).val() || $('.crm-age-range-max input', $form).val())); } - }).change(); + $('.crm-age-range input', $form).on('keyup change', toggleDate); + toggleDate(); + }); + </script> {/literal} </td> diff --git a/civicrm/templates/CRM/Core/Form/Field.tpl b/civicrm/templates/CRM/Core/Form/Field.tpl index 210454b575..cc2a90472f 100644 --- a/civicrm/templates/CRM/Core/Form/Field.tpl +++ b/civicrm/templates/CRM/Core/Form/Field.tpl @@ -33,7 +33,7 @@ {/capture}{help id=$help.id file=$help.file}{/if} {if $action == 2 && $fieldSpec.is_add_translate_dialog}{include file='CRM/Core/I18n/Dialog.tpl' table=$entityTable field=$fieldName id=$entityID}{/if} </td> - <td>{$fieldSpec.pre_html_text}{if $form.$fieldName.html}{if $fieldSpec.formatter === 'crmMoney'}{$form.$fieldName.html|crmMoney}{else}{$form.$fieldName.html}{/if}{else}{$fieldSpec.place_holder}{/if}{$fieldSpec.post_html_text}<br /> + <td>{$fieldSpec.pre_html_text}{if $form.$fieldName.html}{if $fieldSpec.formatter === 'crmMoney'}{$form.$fieldName.html|crmMoney:$fieldSpec.formatterParam}{else}{$form.$fieldName.html}{/if}{else}{$fieldSpec.place_holder}{/if}{$fieldSpec.post_html_text}<br /> {if $fieldSpec.description}<span class="description">{$fieldSpec.description}</span>{/if} {if $fieldSpec.documentation_link}{docURL page=$fieldSpec.documentation_link.page resource=$fieldSpec.documentation_link.resource}{/if} </td> diff --git a/civicrm/templates/CRM/Event/Form/Registration/Register.tpl b/civicrm/templates/CRM/Event/Form/Registration/Register.tpl index b1fdec72a7..756d377dff 100644 --- a/civicrm/templates/CRM/Event/Form/Registration/Register.tpl +++ b/civicrm/templates/CRM/Event/Form/Registration/Register.tpl @@ -145,7 +145,7 @@ {include file='CRM/Core/BillingBlockWrapper.tpl'} {/if} - <div class="crm-public-form-item crm-section custom_pre-section"> + <div class="crm-public-form-item crm-section custom_post-section"> {include file="CRM/UF/Form/Block.tpl" fields=$customPost} </div> diff --git a/civicrm/templates/CRM/Group/Form/Search.tpl b/civicrm/templates/CRM/Group/Form/Search.tpl index d9da5ed296..f73fd4b10e 100644 --- a/civicrm/templates/CRM/Group/Form/Search.tpl +++ b/civicrm/templates/CRM/Group/Form/Search.tpl @@ -78,15 +78,18 @@ <div class="css_right"> <a class="crm-hover-button action-item" href="{crmURL q="reset=1&update_smart_groups=1"}">{ts}Update Smart Group Counts{/ts}</a> {help id="update_smart_groups"} </div> +{if call_user_func(array('CRM_Core_Permission','check'), 'edit groups')} + {assign var='editableClass' value='crm-editable'} +{/if} <table class="crm-group-selector crm-ajax-table" data-order='[[0,"asc"]]'> <thead> <tr> - <th data-data="title" cell-class="crm-group-name crm-editable crmf-title" class='crm-group-name'>{ts}Name{/ts}</th> + <th data-data="title" cell-class="crm-group-name {$editableClass} crmf-title" class='crm-group-name'>{ts}Name{/ts}</th> <th data-data="count" cell-class="crm-group-count right" class='crm-group-count'>{ts}Count{/ts}</th> <th data-data="created_by" cell-class="crm-group-created_by" class='crm-group-created_by'>{ts}Created By{/ts}</th> - <th data-data="description" data-orderable="false" cell-class="crm-group-description crmf-description crm-editable" class='crm-group-description'>{ts}Description{/ts}</th> + <th data-data="description" data-orderable="false" cell-class="crm-group-description crmf-description {$editableClass}" class='crm-group-description'>{ts}Description{/ts}</th> <th data-data="group_type" cell-class="crm-group-group_type" class='crm-group-group_type'>{ts}Group Type{/ts}</th> - <th data-data="visibility" cell-class="crm-group-visibility crmf-visibility crm-editable" cell-data-type="select" class='crm-group-visibility'>{ts}Visibility{/ts}</th> + <th data-data="visibility" cell-class="crm-group-visibility crmf-visibility {$editableClass}" cell-data-type="select" class='crm-group-visibility'>{ts}Visibility{/ts}</th> {if $showOrgInfo} <th data-data="org_info" data-orderable="false" cell-class="crm-group-org_info" class='crm-group-org_info'>{ts}Organization{/ts}</th> {/if} @@ -228,16 +231,16 @@ $.each( response.data, function( i, val ) { appendHTML += '<tr id="row_'+val.group_id+'_'+parent_id+'" data-entity="group" data-id="'+val.group_id+'" class="crm-entity parent_is_'+parent_id+' crm-row-child">'; if ( val.is_parent ) { - appendHTML += '<td class="crm-group-name crmf-title ' + levelClass + '">' + '{/literal}<span class="collapsed show-children" title="{ts}show child groups{/ts}"/></span><div class="crmf-title crm-editable" style="display:inline">{literal}' + val.title + '</div></td>'; + appendHTML += '<td class="crm-group-name crmf-title ' + levelClass + '">' + '{/literal}<span class="collapsed show-children" title="{ts}show child groups{/ts}"/></span><div class="crmf-title {$editableClass}" style="display:inline">{literal}' + val.title + '</div></td>'; } else { - appendHTML += '<td class="crm-group-name crmf-title crm-editable ' + levelClass + '"><span class="crm-no-children"></span>' + val.title + '</td>'; + appendHTML += '<td class="crm-group-name crmf-title {/literal}{$editableClass}{literal} ' + levelClass + '"><span class="crm-no-children"></span>' + val.title + '</td>'; } appendHTML += '<td class="right">' + val.count + "</td>"; appendHTML += "<td>" + val.created_by + "</td>"; - appendHTML += '<td class="crm-editable crmf-description">' + (val.description || '') + "</td>"; + appendHTML += '<td class="{/literal}{$editableClass}{literal} crmf-description">' + (val.description || '') + "</td>"; appendHTML += "<td>" + val.group_type + "</td>"; - appendHTML += '<td class="crm-editable crmf-visibility" data-type="select">' + val.visibility + "</td>"; + appendHTML += '<td class="{/literal}{$editableClass}{literal} crmf-visibility" data-type="select">' + val.visibility + "</td>"; if (showOrgInfo) { appendHTML += "<td>" + val.org_info + "</td>"; } diff --git a/civicrm/templates/CRM/common/CMSPrint.tpl b/civicrm/templates/CRM/common/CMSPrint.tpl index 03ec8cdce5..f091432f47 100644 --- a/civicrm/templates/CRM/common/CMSPrint.tpl +++ b/civicrm/templates/CRM/common/CMSPrint.tpl @@ -29,8 +29,6 @@ <div id="crm-container" class="crm-container{if $urlIsPublic} crm-public{/if}" lang="{$config->lcMessages|truncate:2:"":true}" xml:lang="{$config->lcMessages|truncate:2:"":true}"> -{crmNavigationMenu is_default=1} - {if $breadcrumb} <div class="breadcrumb"> {foreach from=$breadcrumb item=crumb key=key} diff --git a/civicrm/templates/CRM/common/accesskeys.hlp b/civicrm/templates/CRM/common/accesskeys.hlp index da9a8501f4..2db8fc0506 100644 --- a/civicrm/templates/CRM/common/accesskeys.hlp +++ b/civicrm/templates/CRM/common/accesskeys.hlp @@ -23,14 +23,35 @@ | see the CiviCRM license FAQ at http://civicrm.org/licensing | +--------------------------------------------------------------------+ *} -{htxt id="accesskeys-title"} - {ts}Access Keys{/ts} -{/htxt} {htxt id="accesskeys"} -<p></p> -<ul> - <li>ALT+SHIFT+E - <em>{ts}Edit Contact (View Contact Summary Page){/ts}</em></li> - <li>ALT+SHIFT+S - <em>{ts}Save Button{/ts}</em></li> - <li>ALT+SHIFT+N - <em>{ts}Add a new record in each tab (Activities, Tags,..etc){/ts}</em></li> -</ul> + {php} + $ua = strtolower($_SERVER['HTTP_USER_AGENT']); + if (strstr($ua, 'mac')) { + $key = '<span>CTRL</span>+<span>ALT</span>'; + } + else { + $key = strstr($ua, 'firefox') ? '<span>ALT</span>+<span>SHIFT</span>' : '<span>ALT</span>'; + } + $this->assign('accessKey', $key); + {/php} + <p></p> + <ul id="crmAccessKeyList"> + <li>{$accessKey}+<span>E</span> - {ts}Edit Contact (View Contact Summary Page){/ts}</li> + <li>{$accessKey}+<span>S</span> - {ts}Save Button{/ts}</li> + <li>{$accessKey}+<span>N</span> - {ts}Add a new record in each tab (Activities, Tags,..etc){/ts}</li> + <li>{$accessKey}+<span>M</span> - {ts}Open the CiviCRM menubar{/ts}</li> + <li>{$accessKey}+<span>Q</span> - {ts}Quicksearch{/ts}</li> + </ul> + {literal}<style type="text/css"> + #crmAccessKeyList li { + margin-top: 5px; + } + #crmAccessKeyList span { + display: inline-block; + background: grey; + font-size: 80%; + border: 2px groove #eee; + padding: 0 4px; + } + </style>{/literal} {/htxt} diff --git a/civicrm/templates/CRM/common/accesskeys.tpl b/civicrm/templates/CRM/common/accesskeys.tpl index 025b3d4675..8da5207ae3 100644 --- a/civicrm/templates/CRM/common/accesskeys.tpl +++ b/civicrm/templates/CRM/common/accesskeys.tpl @@ -24,7 +24,9 @@ +--------------------------------------------------------------------+ *} {if not $urlIsPublic} - <div class="footer" id="access"> - {ts}Access Keys:{/ts}{help id='accesskeys' file='CRM/common/accesskeys'} - </div> + <div class="footer" id="access"> + {capture assign='accessKeysHelpTitle'}{ts}Access Keys{/ts}{/capture} + {ts}Access Keys:{/ts} + {help id='accesskeys' file='CRM/common/accesskeys' title=$accessKeysHelpTitle} + </div> {/if} diff --git a/civicrm/templates/CRM/common/joomla.tpl b/civicrm/templates/CRM/common/joomla.tpl index d3b81f5a62..71f11c2b84 100644 --- a/civicrm/templates/CRM/common/joomla.tpl +++ b/civicrm/templates/CRM/common/joomla.tpl @@ -29,10 +29,6 @@ <div id="crm-container" class="crm-container{if $urlIsPublic} crm-public{/if}" lang="{$config->lcMessages|truncate:2:"":true}" xml:lang="{$config->lcMessages|truncate:2:"":true}"> -{* Joomla-only container to hold the civicrm menu *} -<div id="crm-nav-menu-container"></div> -{crmNavigationMenu is_default=1} - <table border="0" cellpadding="0" cellspacing="0" id="crm-content"> <tr> {if $sidebarLeft} diff --git a/civicrm/templates/CRM/common/l10n.js.tpl b/civicrm/templates/CRM/common/l10n.js.tpl index 2ee5fb3a25..27338c8dfc 100644 --- a/civicrm/templates/CRM/common/l10n.js.tpl +++ b/civicrm/templates/CRM/common/l10n.js.tpl @@ -30,6 +30,8 @@ CRM.config.userFramework = {$config->userFramework|@json_encode}; CRM.config.resourceBase = {$config->userFrameworkResourceURL|@json_encode}; CRM.config.lcMessages = {$config->lcMessages|@json_encode}; + CRM.config.locale = {$locale|@json_encode}; + CRM.config.cid = {$cid|@json_encode}; $.datepicker._defaults.dateFormat = CRM.config.dateInputFormat = {$config->dateInputFormat|@json_encode}; CRM.config.timeIs24Hr = {if $config->timeInputFormat eq 2}true{else}false{/if}; CRM.config.ajaxPopupsEnabled = {$ajaxPopupsEnabled|@json_encode}; diff --git a/civicrm/vendor/autoload.php b/civicrm/vendor/autoload.php index 928c1adfe6..f9ab5bfec5 100644 --- a/civicrm/vendor/autoload.php +++ b/civicrm/vendor/autoload.php @@ -4,4 +4,4 @@ require_once __DIR__ . '/composer/autoload_real.php'; -return ComposerAutoloaderInit1b1584de67d2926d88597d9255555455::getLoader(); +return ComposerAutoloaderInitb6eeee9efd71930d70a508b3cab70b62::getLoader(); diff --git a/civicrm/vendor/composer/autoload_namespaces.php b/civicrm/vendor/composer/autoload_namespaces.php index b60ff8adc9..e17ceaeb69 100644 --- a/civicrm/vendor/composer/autoload_namespaces.php +++ b/civicrm/vendor/composer/autoload_namespaces.php @@ -14,10 +14,13 @@ return array( 'PEAR' => array($vendorDir . '/pear/pear_exception'), 'Net' => array($vendorDir . '/phpseclib/phpseclib/phpseclib', $vendorDir . '/pear/net_socket', $vendorDir . '/pear/net_smtp'), 'Math' => array($vendorDir . '/phpseclib/phpseclib/phpseclib'), + 'Mail' => array($vendorDir . '/pear/mail'), 'File' => array($vendorDir . '/phpseclib/phpseclib/phpseclib'), 'Crypt' => array($vendorDir . '/phpseclib/phpseclib/phpseclib'), + 'Console' => array($vendorDir . '/pear/console_getopt'), 'Civi\\' => array($baseDir . '/', $baseDir . '/tests/phpunit'), 'Civi' => array($baseDir . '/'), 'CA_Config' => array($vendorDir . '/totten/ca-config/src'), 'Auth' => array($vendorDir . '/pear/auth_sasl'), + '' => array($vendorDir . '/pear/pear-core-minimal/src'), ); diff --git a/civicrm/vendor/composer/autoload_psr4.php b/civicrm/vendor/composer/autoload_psr4.php index 43d6d941ac..e620c757ff 100644 --- a/civicrm/vendor/composer/autoload_psr4.php +++ b/civicrm/vendor/composer/autoload_psr4.php @@ -6,6 +6,7 @@ $vendorDir = dirname(dirname(__FILE__)); $baseDir = dirname($vendorDir); return array( + 'cweagans\\Composer\\' => array($vendorDir . '/cweagans/composer-patches/src'), 'Zend\\Validator\\' => array($vendorDir . '/zendframework/zend-validator/src'), 'Zend\\Stdlib\\' => array($vendorDir . '/zendframework/zend-stdlib/src'), 'Zend\\Escaper\\' => array($vendorDir . '/zendframework/zend-escaper/src'), diff --git a/civicrm/vendor/composer/autoload_real.php b/civicrm/vendor/composer/autoload_real.php index 8b8f583f98..fc3223cc1f 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 ComposerAutoloaderInit1b1584de67d2926d88597d9255555455 +class ComposerAutoloaderInitb6eeee9efd71930d70a508b3cab70b62 { private static $loader; @@ -19,9 +19,9 @@ class ComposerAutoloaderInit1b1584de67d2926d88597d9255555455 return self::$loader; } - spl_autoload_register(array('ComposerAutoloaderInit1b1584de67d2926d88597d9255555455', 'loadClassLoader'), true, true); + spl_autoload_register(array('ComposerAutoloaderInitb6eeee9efd71930d70a508b3cab70b62', 'loadClassLoader'), true, true); self::$loader = $loader = new \Composer\Autoload\ClassLoader(); - spl_autoload_unregister(array('ComposerAutoloaderInit1b1584de67d2926d88597d9255555455', 'loadClassLoader')); + spl_autoload_unregister(array('ComposerAutoloaderInitb6eeee9efd71930d70a508b3cab70b62', 'loadClassLoader')); $includePaths = require __DIR__ . '/include_paths.php'; $includePaths[] = get_include_path(); @@ -31,7 +31,7 @@ class ComposerAutoloaderInit1b1584de67d2926d88597d9255555455 if ($useStaticLoader) { require_once __DIR__ . '/autoload_static.php'; - call_user_func(\Composer\Autoload\ComposerStaticInit1b1584de67d2926d88597d9255555455::getInitializer($loader)); + call_user_func(\Composer\Autoload\ComposerStaticInitb6eeee9efd71930d70a508b3cab70b62::getInitializer($loader)); } else { $map = require __DIR__ . '/autoload_namespaces.php'; foreach ($map as $namespace => $path) { @@ -52,19 +52,19 @@ class ComposerAutoloaderInit1b1584de67d2926d88597d9255555455 $loader->register(true); if ($useStaticLoader) { - $includeFiles = Composer\Autoload\ComposerStaticInit1b1584de67d2926d88597d9255555455::$files; + $includeFiles = Composer\Autoload\ComposerStaticInitb6eeee9efd71930d70a508b3cab70b62::$files; } else { $includeFiles = require __DIR__ . '/autoload_files.php'; } foreach ($includeFiles as $fileIdentifier => $file) { - composerRequire1b1584de67d2926d88597d9255555455($fileIdentifier, $file); + composerRequireb6eeee9efd71930d70a508b3cab70b62($fileIdentifier, $file); } return $loader; } } -function composerRequire1b1584de67d2926d88597d9255555455($fileIdentifier, $file) +function composerRequireb6eeee9efd71930d70a508b3cab70b62($fileIdentifier, $file) { if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) { require $file; diff --git a/civicrm/vendor/composer/autoload_static.php b/civicrm/vendor/composer/autoload_static.php index f57792d713..c8b7907ca2 100644 --- a/civicrm/vendor/composer/autoload_static.php +++ b/civicrm/vendor/composer/autoload_static.php @@ -4,7 +4,7 @@ namespace Composer\Autoload; -class ComposerStaticInit1b1584de67d2926d88597d9255555455 +class ComposerStaticInitb6eeee9efd71930d70a508b3cab70b62 { public static $files = array ( '320cde22f66dd4f5d3fd621d3e88b98f' => __DIR__ . '/..' . '/symfony/polyfill-ctype/bootstrap.php', @@ -18,6 +18,10 @@ class ComposerStaticInit1b1584de67d2926d88597d9255555455 ); public static $prefixLengthsPsr4 = array ( + 'c' => + array ( + 'cweagans\\Composer\\' => 18, + ), 'Z' => array ( 'Zend\\Validator\\' => 15, @@ -69,6 +73,10 @@ class ComposerStaticInit1b1584de67d2926d88597d9255555455 ); public static $prefixDirsPsr4 = array ( + 'cweagans\\Composer\\' => + array ( + 0 => __DIR__ . '/..' . '/cweagans/composer-patches/src', + ), 'Zend\\Validator\\' => array ( 0 => __DIR__ . '/..' . '/zendframework/zend-validator/src', @@ -216,6 +224,10 @@ class ComposerStaticInit1b1584de67d2926d88597d9255555455 array ( 0 => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib', ), + 'Mail' => + array ( + 0 => __DIR__ . '/..' . '/pear/mail', + ), ), 'F' => array ( @@ -230,6 +242,10 @@ class ComposerStaticInit1b1584de67d2926d88597d9255555455 array ( 0 => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib', ), + 'Console' => + array ( + 0 => __DIR__ . '/..' . '/pear/console_getopt', + ), 'Civi\\' => array ( 0 => __DIR__ . '/../..' . '/', @@ -253,6 +269,10 @@ class ComposerStaticInit1b1584de67d2926d88597d9255555455 ), ); + public static $fallbackDirsPsr0 = array ( + 0 => __DIR__ . '/..' . '/pear/pear-core-minimal/src', + ); + public static $classMap = array ( 'Callback' => __DIR__ . '/..' . '/electrolinux/phpquery/phpQuery/phpQuery/Callback.php', 'CallbackBody' => __DIR__ . '/..' . '/electrolinux/phpquery/phpQuery/phpQuery/Callback.php', @@ -398,10 +418,11 @@ class ComposerStaticInit1b1584de67d2926d88597d9255555455 public static function getInitializer(ClassLoader $loader) { return \Closure::bind(function () use ($loader) { - $loader->prefixLengthsPsr4 = ComposerStaticInit1b1584de67d2926d88597d9255555455::$prefixLengthsPsr4; - $loader->prefixDirsPsr4 = ComposerStaticInit1b1584de67d2926d88597d9255555455::$prefixDirsPsr4; - $loader->prefixesPsr0 = ComposerStaticInit1b1584de67d2926d88597d9255555455::$prefixesPsr0; - $loader->classMap = ComposerStaticInit1b1584de67d2926d88597d9255555455::$classMap; + $loader->prefixLengthsPsr4 = ComposerStaticInitb6eeee9efd71930d70a508b3cab70b62::$prefixLengthsPsr4; + $loader->prefixDirsPsr4 = ComposerStaticInitb6eeee9efd71930d70a508b3cab70b62::$prefixDirsPsr4; + $loader->prefixesPsr0 = ComposerStaticInitb6eeee9efd71930d70a508b3cab70b62::$prefixesPsr0; + $loader->fallbackDirsPsr0 = ComposerStaticInitb6eeee9efd71930d70a508b3cab70b62::$fallbackDirsPsr0; + $loader->classMap = ComposerStaticInitb6eeee9efd71930d70a508b3cab70b62::$classMap; }, null, ClassLoader::class); } diff --git a/civicrm/vendor/composer/include_paths.php b/civicrm/vendor/composer/include_paths.php index ccc4ea5bb5..bd1c7b7fd9 100644 --- a/civicrm/vendor/composer/include_paths.php +++ b/civicrm/vendor/composer/include_paths.php @@ -10,6 +10,9 @@ return array( $vendorDir . '/phpseclib/phpseclib/phpseclib', $vendorDir . '/pear/pear_exception', $vendorDir . '/pear/auth_sasl', + $vendorDir . '/pear/console_getopt', + $vendorDir . '/pear/pear-core-minimal/src', + $vendorDir . '/pear/mail', $vendorDir . '/pear/net_socket', $vendorDir . '/pear/net_smtp', $vendorDir . '/pear/validate_finance_creditcard', diff --git a/civicrm/vendor/composer/installed.json b/civicrm/vendor/composer/installed.json index a3991807e7..a68018bf95 100644 --- a/civicrm/vendor/composer/installed.json +++ b/civicrm/vendor/composer/installed.json @@ -77,6 +77,52 @@ ], "description": "CiviCRM installation library" }, + { + "name": "cweagans/composer-patches", + "version": "1.6.5", + "version_normalized": "1.6.5.0", + "source": { + "type": "git", + "url": "https://github.com/cweagans/composer-patches.git", + "reference": "2ec4f00ff5fb64de584c8c4aea53bf9053ecb0b3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/cweagans/composer-patches/zipball/2ec4f00ff5fb64de584c8c4aea53bf9053ecb0b3", + "reference": "2ec4f00ff5fb64de584c8c4aea53bf9053ecb0b3", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^1.0", + "php": ">=5.3.0" + }, + "require-dev": { + "composer/composer": "~1.0", + "phpunit/phpunit": "~4.6" + }, + "time": "2018-05-11T18:00:16+00:00", + "type": "composer-plugin", + "extra": { + "class": "cweagans\\Composer\\Patches" + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "cweagans\\Composer\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Cameron Eagans", + "email": "me@cweagans.net" + } + ], + "description": "Provides a way to patch Composer packages." + }, { "name": "dompdf/dompdf", "version": "v0.8.0", @@ -109,9 +155,6 @@ "extra": { "branch-alias": { "dev-develop": "0.7-dev" - }, - "patches_applied": { - "Fix Fatal error: Uncaught Dompdf Exception: No block-level parent found.": "tools/scripts/composer/patches/dompdf_no_block_level_parent_fix.patch" } }, "installation-source": "dist", @@ -516,6 +559,115 @@ ], "description": "Abstraction of various SASL mechanism responses" }, + { + "name": "pear/console_getopt", + "version": "v1.4.1", + "version_normalized": "1.4.1.0", + "source": { + "type": "git", + "url": "https://github.com/pear/Console_Getopt.git", + "reference": "82f05cd1aa3edf34e19aa7c8ca312ce13a6a577f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/pear/Console_Getopt/zipball/82f05cd1aa3edf34e19aa7c8ca312ce13a6a577f", + "reference": "82f05cd1aa3edf34e19aa7c8ca312ce13a6a577f", + "shasum": "" + }, + "time": "2015-07-20T20:28:12+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-0": { + "Console": "./" + } + }, + "notification-url": "https://packagist.org/downloads/", + "include-path": [ + "./" + ], + "license": [ + "BSD-2-Clause" + ], + "authors": [ + { + "name": "Greg Beaver", + "email": "cellog@php.net", + "role": "Helper" + }, + { + "name": "Andrei Zmievski", + "email": "andrei@php.net", + "role": "Lead" + }, + { + "name": "Stig Bakken", + "email": "stig@php.net", + "role": "Developer" + } + ], + "description": "More info available on: http://pear.php.net/package/Console_Getopt" + }, + { + "name": "pear/mail", + "version": "v1.4.1", + "version_normalized": "1.4.1.0", + "source": { + "type": "git", + "url": "https://github.com/pear/Mail.git", + "reference": "9609ed5e42ac5b221dfd9af85de005c59d418ee7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/pear/Mail/zipball/9609ed5e42ac5b221dfd9af85de005c59d418ee7", + "reference": "9609ed5e42ac5b221dfd9af85de005c59d418ee7", + "shasum": "" + }, + "require": { + "pear/pear-core-minimal": "~1.9", + "php": ">=5.2.1" + }, + "require-dev": { + "pear/pear": "*" + }, + "suggest": { + "pear/net_smtp": "Install optionally via your project's composer.json" + }, + "time": "2017-04-11T17:27:29+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-0": { + "Mail": "./" + } + }, + "notification-url": "https://packagist.org/downloads/", + "include-path": [ + "./" + ], + "license": [ + "BSD-2-Clause" + ], + "authors": [ + { + "name": "Chuck Hagenbuch", + "email": "chuck@horde.org", + "role": "Lead" + }, + { + "name": "Richard Heyes", + "email": "richard@phpguru.org", + "role": "Developer" + }, + { + "name": "Aleksander Machniak", + "email": "alec@alec.pl", + "role": "Developer" + } + ], + "description": "Class that provides multiple interfaces for sending emails.", + "homepage": "http://pear.php.net/package/Mail" + }, { "name": "pear/net_smtp", "version": "1.6.3", @@ -544,14 +696,6 @@ }, "time": "2015-08-02T17:20:17+00:00", "type": "library", - "extra": { - "patches_applied": { - "CRM-8744 Display CiviCRM Specific error message": "tools/scripts/composer/patches/net-smtp-patch.patch", - "Fix PHP7 Compliance": "tools/scripts/composer/patches/net-smtp-php7-patch.patch", - "Fix Pass by reference issues": "tools/scripts/composer/patches/net-smtp-ref-patch.patch", - "Fix TLS support issue in PHP5.6": "tools/scripts/composer/patches/net-smtp-tls-patch.patch" - } - }, "installation-source": "dist", "autoload": { "psr-0": { @@ -641,6 +785,52 @@ ], "description": "More info available on: http://pear.php.net/package/Net_Socket" }, + { + "name": "pear/pear-core-minimal", + "version": "v1.10.7", + "version_normalized": "1.10.7.0", + "source": { + "type": "git", + "url": "https://github.com/pear/pear-core-minimal.git", + "reference": "19a3e0fcd50492c4357372f623f55f1b144346da" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/pear/pear-core-minimal/zipball/19a3e0fcd50492c4357372f623f55f1b144346da", + "reference": "19a3e0fcd50492c4357372f623f55f1b144346da", + "shasum": "" + }, + "require": { + "pear/console_getopt": "~1.4", + "pear/pear_exception": "~1.0" + }, + "replace": { + "rsky/pear-core-min": "self.version" + }, + "time": "2018-12-05T20:03:52+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-0": { + "": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "include-path": [ + "src/" + ], + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Christian Weiske", + "email": "cweiske@php.net", + "role": "Lead" + } + ], + "description": "Minimal set of PEAR core files to be used as composer dependency" + }, { "name": "pear/pear_exception", "version": "v1.0.0", @@ -824,17 +1014,17 @@ }, { "name": "phpoffice/common", - "version": "v0.2.6", - "version_normalized": "0.2.6.0", + "version": "0.2.9", + "version_normalized": "0.2.9.0", "source": { "type": "git", "url": "https://github.com/PHPOffice/Common.git", - "reference": "c9be70c80637c28c728be78e66aad4878a34f8dd" + "reference": "edb5d32b1e3400a35a5c91e2539ed6f6ce925e4d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHPOffice/Common/zipball/c9be70c80637c28c728be78e66aad4878a34f8dd", - "reference": "c9be70c80637c28c728be78e66aad4878a34f8dd", + "url": "https://api.github.com/repos/PHPOffice/Common/zipball/edb5d32b1e3400a35a5c91e2539ed6f6ce925e4d", + "reference": "edb5d32b1e3400a35a5c91e2539ed6f6ce925e4d", "shasum": "" }, "require": { @@ -845,12 +1035,17 @@ "phpdocumentor/phpdocumentor": "2.*", "phploc/phploc": "2.*", "phpmd/phpmd": "2.*", - "phpunit/phpunit": "3.7.*", + "phpunit/phpunit": "^4.8.36 || ^7.0", "sebastian/phpcpd": "2.*", "squizlabs/php_codesniffer": "2.*" }, - "time": "2016-07-07T17:26:55+00:00", + "time": "2018-07-13T14:12:34+00:00", "type": "library", + "extra": { + "patches_applied": { + "Fix handling of libxml_disable_entity_loader": "tools/scripts/composer/patches/phpoffice-common-xml-entity-fix.patch" + } + }, "installation-source": "dist", "autoload": { "psr-4": { @@ -881,35 +1076,36 @@ }, { "name": "phpoffice/phpword", - "version": "v0.14.0", - "version_normalized": "0.14.0.0", + "version": "0.15.0", + "version_normalized": "0.15.0.0", "source": { "type": "git", "url": "https://github.com/PHPOffice/PHPWord.git", - "reference": "b614497ae6dd44280be1c2dda56772198bcd25ae" + "reference": "dfa2f36cad2b632b7ab1c56473e4f5db9a7caf7f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHPOffice/PHPWord/zipball/b614497ae6dd44280be1c2dda56772198bcd25ae", - "reference": "b614497ae6dd44280be1c2dda56772198bcd25ae", + "url": "https://api.github.com/repos/PHPOffice/PHPWord/zipball/dfa2f36cad2b632b7ab1c56473e4f5db9a7caf7f", + "reference": "dfa2f36cad2b632b7ab1c56473e4f5db9a7caf7f", "shasum": "" }, "require": { "ext-xml": "*", "php": "^5.3.3 || ^7.0", - "phpoffice/common": "^0.2", - "zendframework/zend-escaper": "^2.2", - "zendframework/zend-stdlib": "^2.2 || ^3.0" + "phpoffice/common": "^0.2.9", + "zendframework/zend-escaper": "^2.2" }, "require-dev": { "dompdf/dompdf": "0.8.*", - "friendsofphp/php-cs-fixer": "^2.0", - "mpdf/mpdf": "5.* || 6.* || 7.*", - "phpdocumentor/phpdocumentor": "2.*", + "ext-gd": "*", + "ext-zip": "*", + "friendsofphp/php-cs-fixer": "^2.2", + "mpdf/mpdf": "5.7.4 || 6.* || 7.*", + "php-coveralls/php-coveralls": "1.1.0 || ^2.0", "phploc/phploc": "2.* || 3.* || 4.*", "phpmd/phpmd": "2.*", - "phpunit/phpunit": "^4.8.36 || ^5.0", - "squizlabs/php_codesniffer": "^2.7", + "phpunit/phpunit": "^4.8.36 || ^7.0", + "squizlabs/php_codesniffer": "^2.9", "tecnickcom/tcpdf": "6.*" }, "suggest": { @@ -919,8 +1115,16 @@ "ext-xsl": "Allows applying XSL style sheet to headers, to main document part, and to footers of an OOXML template", "ext-zip": "Allows writing OOXML and ODF" }, - "time": "2017-12-29T01:30:53+00:00", + "time": "2018-07-14T16:59:43+00:00", "type": "library", + "extra": { + "branch-alias": { + "dev-develop": "0.16-dev" + }, + "patches_applied": { + "Fix handling of libxml_disable_entity_loader": "tools/scripts/composer/patches/phpword-libxml-fix-global-handling.patch" + } + }, "installation-source": "dist", "autoload": { "psr-4": { diff --git a/civicrm/vendor/cweagans/composer-patches/.editorconfig b/civicrm/vendor/cweagans/composer-patches/.editorconfig new file mode 100644 index 0000000000..8e82594112 --- /dev/null +++ b/civicrm/vendor/cweagans/composer-patches/.editorconfig @@ -0,0 +1,11 @@ +# This is the top-most .editorconfig file; do not search in parent directories. +root = true + +# All files. +[*] +end_of_line = LF +indent_style = space +indent_size = 2 +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true diff --git a/civicrm/vendor/cweagans/composer-patches/.gitignore b/civicrm/vendor/cweagans/composer-patches/.gitignore new file mode 100644 index 0000000000..48b8bf9072 --- /dev/null +++ b/civicrm/vendor/cweagans/composer-patches/.gitignore @@ -0,0 +1 @@ +vendor/ diff --git a/civicrm/vendor/cweagans/composer-patches/LICENSE.md b/civicrm/vendor/cweagans/composer-patches/LICENSE.md new file mode 100644 index 0000000000..d0dad3df74 --- /dev/null +++ b/civicrm/vendor/cweagans/composer-patches/LICENSE.md @@ -0,0 +1,9 @@ +Copyright 2013 Cameron Eagans + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. +3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/civicrm/vendor/cweagans/composer-patches/README.md b/civicrm/vendor/cweagans/composer-patches/README.md new file mode 100644 index 0000000000..ff09eb60e0 --- /dev/null +++ b/civicrm/vendor/cweagans/composer-patches/README.md @@ -0,0 +1,161 @@ +# composer-patches + +Simple patches plugin for Composer. Applies a patch from a local or remote file to any package required with composer. + +Note that the 1.x versions of Composer Patches are supported on a best-effort +basis due to the imminent release of 2.0.0. You may still be interested in +using 1.x if you need Composer to cooperate with earlier PHP versions. No new +features will be added to 1.x releases, but any security or bug fixes will +still be accepted. + +## Usage + +Example composer.json: + +```json +{ + "require": { + "cweagans/composer-patches": "~1.0", + "drupal/drupal": "~8.2" + }, + "config": { + "preferred-install": "source" + }, + "extra": { + "patches": { + "drupal/drupal": { + "Add startup configuration for PHP server": "https://www.drupal.org/files/issues/add_a_startup-1543858-30.patch" + } + } + } +} + +``` + +## Using an external patch file + +Instead of a patches key in your root composer.json, use a patches-file key. + +```json +{ + "require": { + "cweagans/composer-patches": "~1.0", + "drupal/drupal": "~8.2" + }, + "config": { + "preferred-install": "source" + }, + "extra": { + "patches-file": "local/path/to/your/composer.patches.json" + } +} + +``` + +Then your `composer.patches.json` should look like this: + +``` +{ + "patches": { + "vendor/project": { + "Patch title": "http://example.com/url/to/patch.patch" + } + } +} +``` + +## Allowing patches to be applied from dependencies + +If you want your project to accept patches from dependencies, you must have the following in your composer file: + +```json +{ + "require": { + "cweagans/composer-patches": "^1.5.0" + }, + "extra": { + "enable-patching": true + } +} +``` + +## Ignoring patches + +There may be situations in which you want to ignore a patch supplied by a dependency. For example: + +- You use a different more recent version of a dependency, and now a patch isn't applying. +- You have a more up to date patch than the dependency, and want to use yours instead of theirs. +- A dependency's patch adds a feature to a project that you don't need. +- Your patches conflict with a dependency's patches. + +```json +{ + "require": { + "cweagans/composer-patches": "~1.0", + "drupal/drupal": "~8.2", + "drupal/lightning": "~8.1" + }, + "config": { + "preferred-install": "source" + }, + "extra": { + "patches": { + "drupal/drupal": { + "Add startup configuration for PHP server": "https://www.drupal.org/files/issues/add_a_startup-1543858-30.patch" + } + }, + "patches-ignore": { + "drupal/lightning": { + "drupal/panelizer": { + "This patch has known conflicts with our Quick Edit integration": "https://www.drupal.org/files/issues/2664682-49.patch" + } + } + } + } +} +``` + +## Using patches from HTTP URLs + +Composer [blocks](https://getcomposer.org/doc/06-config.md#secure-http) you from downloading anything from HTTP URLs, you can disable this for your project by adding a `secure-http` setting in the config section of your `composer.json`. Note that the `config` section should be under the root of your `composer.json`. + +```json +{ + "config": { + "secure-http": false + } +} +``` + +However, it's always advised to setup HTTPS to prevent MITM code injection. + +## Patches containing modifications to composer.json files + +Because patching occurs _after_ Composer calculates dependencies and installs packages, changes to an underlying dependency's `composer.json` file introduced in a patch will have _no effect_ on installed packages. + +If you need to modify a dependency's `composer.json` or its underlying dependencies, you cannot use this plugin. Instead, you must do one of the following: +- Work to get the underlying issue resolved in the upstream package. +- Fork the package and [specify your fork as the package repository](https://getcomposer.org/doc/05-repositories.md#vcs) in your root `composer.json` +- Specify compatible package version requirements in your root `composer.json` + +## Error handling + +If a patch cannot be applied (hunk failed, different line endings, etc.) a message will be shown and the patch will be skipped. + +To enforce throwing an error and stopping package installation/update immediately, you have two available options: + +1. Add `"composer-exit-on-patch-failure": true` option to the `extra` section of your composer.json file. +1. Export `COMPOSER_EXIT_ON_PATCH_FAILURE=1` + +By default, failed patches are skipped. + +## Difference between this and netresearch/composer-patches-plugin + +- This plugin is much more simple to use and maintain +- This plugin doesn't require you to specify which package version you're patching +- This plugin is easy to use with Drupal modules (which don't use semantic versioning). +- This plugin will gather patches from all dependencies and apply them as if they were in the root composer.json + +## Credits + +A ton of this code is adapted or taken straight from https://github.com/jpstacey/composer-patcher, which is abandoned in favor of https://github.com/netresearch/composer-patches-plugin, which is (IMHO) overly complex and difficult to use. diff --git a/civicrm/vendor/cweagans/composer-patches/composer.json b/civicrm/vendor/cweagans/composer-patches/composer.json new file mode 100644 index 0000000000..1cdcd76625 --- /dev/null +++ b/civicrm/vendor/cweagans/composer-patches/composer.json @@ -0,0 +1,30 @@ +{ + "name": "cweagans/composer-patches", + "description": "Provides a way to patch Composer packages.", + "minimum-stability": "dev", + "license": "BSD-3-Clause", + "type": "composer-plugin", + "extra": { + "class": "cweagans\\Composer\\Patches" + }, + "authors": [ + { + "name": "Cameron Eagans", + "email": "me@cweagans.net" + } + ], + "require": { + "php": ">=5.3.0", + "composer-plugin-api": "^1.0" + }, + "require-dev": { + "composer/composer": "~1.0", + "phpunit/phpunit": "~4.6" + }, + "autoload": { + "psr-4": {"cweagans\\Composer\\": "src"} + }, + "autoload-dev": { + "psr-4": {"cweagans\\Composer\\Tests\\": "tests"} + } +} diff --git a/civicrm/vendor/cweagans/composer-patches/composer.lock b/civicrm/vendor/cweagans/composer-patches/composer.lock new file mode 100644 index 0000000000..2ca41b42d1 --- /dev/null +++ b/civicrm/vendor/cweagans/composer-patches/composer.lock @@ -0,0 +1,1564 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", + "This file is @generated automatically" + ], + "hash": "a2cd6826c202b7ebefe3050efc2a7b7f", + "content-hash": "0ed9361502c0f5f22a5b440c16640193", + "packages": [], + "packages-dev": [ + { + "name": "composer/composer", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/composer/composer.git", + "reference": "a54f84f05f915c6d42bed94de0cdcb4406a4707b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/composer/zipball/f2d606ae0c705907d8bfa1c6f884bced1255b827", + "reference": "a54f84f05f915c6d42bed94de0cdcb4406a4707b", + "shasum": "" + }, + "require": { + "composer/semver": "^1.0", + "composer/spdx-licenses": "^1.0", + "justinrainbow/json-schema": "^1.4.4", + "php": ">=5.3.2", + "seld/cli-prompt": "~1.0", + "seld/jsonlint": "~1.0", + "seld/phar-utils": "~1.0", + "symfony/console": "~2.5", + "symfony/filesystem": "~2.5", + "symfony/finder": "~2.2", + "symfony/process": "~2.1" + }, + "require-dev": { + "phpunit/phpunit": "~4.5|^5.0.5", + "phpunit/phpunit-mock-objects": "2.3.0|~3.0" + }, + "suggest": { + "ext-openssl": "Enabling the openssl extension allows you to access https URLs for repositories and packages", + "ext-zip": "Enabling the zip extension allows you to unzip archives, and allows gzip compression of all internet traffic" + }, + "bin": [ + "bin/composer" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "psr-0": { + "Composer": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nils Adermann", + "email": "naderman@naderman.de", + "homepage": "http://www.naderman.de" + }, + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + } + ], + "description": "Composer helps you declare, manage and install dependencies of PHP projects, ensuring you have the right stack everywhere.", + "homepage": "https://getcomposer.org/", + "keywords": [ + "autoload", + "dependency", + "package" + ], + "time": "2015-10-13 13:09:04" + }, + { + "name": "composer/semver", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/composer/semver.git", + "reference": "d0e1ccc6d44ab318b758d709e19176037da6b1ba" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/semver/zipball/d0e1ccc6d44ab318b758d709e19176037da6b1ba", + "reference": "d0e1ccc6d44ab318b758d709e19176037da6b1ba", + "shasum": "" + }, + "require": { + "php": ">=5.3.2" + }, + "require-dev": { + "phpunit/phpunit": "~4.5", + "phpunit/phpunit-mock-objects": "~2.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "0.1-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\Semver\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Rob Bast", + "email": "rob.bast@gmail.com" + }, + { + "name": "Nils Adermann", + "email": "naderman@naderman.de", + "homepage": "http://www.naderman.de" + }, + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + } + ], + "description": "Semver library that offers utilities, version constraint parsing and validation.", + "keywords": [ + "semantic", + "semver", + "validation", + "versioning" + ], + "time": "2015-09-21 09:42:36" + }, + { + "name": "composer/spdx-licenses", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/composer/spdx-licenses.git", + "reference": "b2dbc76d1c3f81f33857cdd49c0be6ce7b87897d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/spdx-licenses/zipball/022fc25ca664f612b1e7007e0d87642ef489f000", + "reference": "b2dbc76d1c3f81f33857cdd49c0be6ce7b87897d", + "shasum": "" + }, + "require": { + "php": ">=5.3.2" + }, + "require-dev": { + "phpunit/phpunit": "~4.5", + "phpunit/phpunit-mock-objects": "~2.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\Spdx\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nils Adermann", + "email": "naderman@naderman.de", + "homepage": "http://www.naderman.de" + }, + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + }, + { + "name": "Rob Bast", + "email": "rob.bast@gmail.com", + "homepage": "http://robbast.nl" + } + ], + "description": "SPDX licenses list and validation library.", + "keywords": [ + "license", + "spdx", + "validator" + ], + "time": "2015-10-05 11:33:06" + }, + { + "name": "doctrine/instantiator", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/doctrine/instantiator.git", + "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/8e884e78f9f0eb1329e445619e04456e64d8051d", + "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d", + "shasum": "" + }, + "require": { + "php": ">=5.3,<8.0-DEV" + }, + "require-dev": { + "athletic/athletic": "~0.1.8", + "ext-pdo": "*", + "ext-phar": "*", + "phpunit/phpunit": "~4.0", + "squizlabs/php_codesniffer": "~2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com", + "homepage": "http://ocramius.github.com/" + } + ], + "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", + "homepage": "https://github.com/doctrine/instantiator", + "keywords": [ + "constructor", + "instantiate" + ], + "time": "2015-06-14 21:17:01" + }, + { + "name": "justinrainbow/json-schema", + "version": "1.5.0", + "source": { + "type": "git", + "url": "https://github.com/justinrainbow/json-schema.git", + "reference": "a4bee9f4b344b66e0a0d96c7afae1e92edf385fe" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/justinrainbow/json-schema/zipball/a4bee9f4b344b66e0a0d96c7afae1e92edf385fe", + "reference": "a4bee9f4b344b66e0a0d96c7afae1e92edf385fe", + "shasum": "" + }, + "require": { + "php": ">=5.3.2" + }, + "require-dev": { + "json-schema/json-schema-test-suite": "1.1.0", + "phpdocumentor/phpdocumentor": "~2", + "phpunit/phpunit": "~3.7" + }, + "bin": [ + "bin/validate-json" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4.x-dev" + } + }, + "autoload": { + "psr-4": { + "JsonSchema\\": "src/JsonSchema/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Bruno Prieto Reis", + "email": "bruno.p.reis@gmail.com" + }, + { + "name": "Justin Rainbow", + "email": "justin.rainbow@gmail.com" + }, + { + "name": "Igor Wiedler", + "email": "igor@wiedler.ch" + }, + { + "name": "Robert Schönthal", + "email": "seroscho@googlemail.com" + } + ], + "description": "A library to validate a json schema.", + "homepage": "https://github.com/justinrainbow/json-schema", + "keywords": [ + "json", + "schema" + ], + "time": "2015-09-08 22:28:04" + }, + { + "name": "phpdocumentor/reflection-docblock", + "version": "2.0.4", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", + "reference": "d68dbdc53dc358a816f00b300704702b2eaff7b8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/d68dbdc53dc358a816f00b300704702b2eaff7b8", + "reference": "d68dbdc53dc358a816f00b300704702b2eaff7b8", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.0" + }, + "suggest": { + "dflydev/markdown": "~1.0", + "erusev/parsedown": "~1.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-0": { + "phpDocumentor": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "mike.vanriel@naenius.com" + } + ], + "time": "2015-02-03 12:10:50" + }, + { + "name": "phpspec/prophecy", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/phpspec/prophecy.git", + "reference": "4f9b1eaf0a7da77c362f8d91cbc68ab1f4718d62" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/b02221e42163be673f9b44a0bc92a8b4907a7c6d", + "reference": "4f9b1eaf0a7da77c362f8d91cbc68ab1f4718d62", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.0.2", + "phpdocumentor/reflection-docblock": "~2.0", + "sebastian/comparator": "~1.1" + }, + "require-dev": { + "phpspec/phpspec": "~2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.5.x-dev" + } + }, + "autoload": { + "psr-0": { + "Prophecy\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Konstantin Kudryashov", + "email": "ever.zet@gmail.com", + "homepage": "http://everzet.com" + }, + { + "name": "Marcello Duarte", + "email": "marcello.duarte@gmail.com" + } + ], + "description": "Highly opinionated mocking framework for PHP 5.3+", + "homepage": "https://github.com/phpspec/prophecy", + "keywords": [ + "Double", + "Dummy", + "fake", + "mock", + "spy", + "stub" + ], + "time": "2015-09-22 14:49:23" + }, + { + "name": "phpunit/php-code-coverage", + "version": "2.2.x-dev", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-code-coverage.git", + "reference": "eabf68b476ac7d0f73793aada060f1c1a9bf8979" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/eabf68b476ac7d0f73793aada060f1c1a9bf8979", + "reference": "eabf68b476ac7d0f73793aada060f1c1a9bf8979", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "phpunit/php-file-iterator": "~1.3", + "phpunit/php-text-template": "~1.2", + "phpunit/php-token-stream": "~1.3", + "sebastian/environment": "^1.3.2", + "sebastian/version": "~1.0" + }, + "require-dev": { + "ext-xdebug": ">=2.1.4", + "phpunit/phpunit": "~4" + }, + "suggest": { + "ext-dom": "*", + "ext-xdebug": ">=2.2.1", + "ext-xmlwriter": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.2.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", + "homepage": "https://github.com/sebastianbergmann/php-code-coverage", + "keywords": [ + "coverage", + "testing", + "xunit" + ], + "time": "2015-10-06 15:47:00" + }, + { + "name": "phpunit/php-file-iterator", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-file-iterator.git", + "reference": "6150bf2c35d3fc379e50c7602b75caceaa39dbf0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/6150bf2c35d3fc379e50c7602b75caceaa39dbf0", + "reference": "6150bf2c35d3fc379e50c7602b75caceaa39dbf0", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "FilterIterator implementation that filters files based on a list of suffixes.", + "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", + "keywords": [ + "filesystem", + "iterator" + ], + "time": "2015-06-21 13:08:43" + }, + { + "name": "phpunit/php-text-template", + "version": "1.2.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-text-template.git", + "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686", + "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Simple template engine.", + "homepage": "https://github.com/sebastianbergmann/php-text-template/", + "keywords": [ + "template" + ], + "time": "2015-06-21 13:50:34" + }, + { + "name": "phpunit/php-timer", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-timer.git", + "reference": "3e82f4e9fc92665fafd9157568e4dcb01d014e5b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3e82f4e9fc92665fafd9157568e4dcb01d014e5b", + "reference": "3e82f4e9fc92665fafd9157568e4dcb01d014e5b", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "Utility class for timing", + "homepage": "https://github.com/sebastianbergmann/php-timer/", + "keywords": [ + "timer" + ], + "time": "2015-06-21 08:01:12" + }, + { + "name": "phpunit/php-token-stream", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-token-stream.git", + "reference": "cab6c6fefee93d7b7c3a01292a0fe0884ea66644" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/cab6c6fefee93d7b7c3a01292a0fe0884ea66644", + "reference": "cab6c6fefee93d7b7c3a01292a0fe0884ea66644", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Wrapper around PHP's tokenizer extension.", + "homepage": "https://github.com/sebastianbergmann/php-token-stream/", + "keywords": [ + "tokenizer" + ], + "time": "2015-09-23 14:46:55" + }, + { + "name": "phpunit/phpunit", + "version": "4.8.x-dev", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit.git", + "reference": "be067d6105286b74272facefc2697038f8807b77" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/264188ddf4d3586c80ea615f8ec8eaea34e652a1", + "reference": "be067d6105286b74272facefc2697038f8807b77", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-json": "*", + "ext-pcre": "*", + "ext-reflection": "*", + "ext-spl": "*", + "php": ">=5.3.3", + "phpspec/prophecy": "^1.3.1", + "phpunit/php-code-coverage": "~2.1", + "phpunit/php-file-iterator": "~1.4", + "phpunit/php-text-template": "~1.2", + "phpunit/php-timer": ">=1.0.6", + "phpunit/phpunit-mock-objects": "~2.3", + "sebastian/comparator": "~1.1", + "sebastian/diff": "~1.2", + "sebastian/environment": "~1.3", + "sebastian/exporter": "~1.2", + "sebastian/global-state": "~1.0", + "sebastian/version": "~1.0", + "symfony/yaml": "~2.1|~3.0" + }, + "suggest": { + "phpunit/php-invoker": "~1.1" + }, + "bin": [ + "phpunit" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.8.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "The PHP Unit Testing framework.", + "homepage": "https://phpunit.de/", + "keywords": [ + "phpunit", + "testing", + "xunit" + ], + "time": "2015-10-14 13:49:40" + }, + { + "name": "phpunit/phpunit-mock-objects", + "version": "2.3.x-dev", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", + "reference": "ac8e7a3db35738d56ee9a76e78a4e03d97628983" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/ac8e7a3db35738d56ee9a76e78a4e03d97628983", + "reference": "ac8e7a3db35738d56ee9a76e78a4e03d97628983", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.0.2", + "php": ">=5.3.3", + "phpunit/php-text-template": "~1.2", + "sebastian/exporter": "~1.2" + }, + "require-dev": { + "phpunit/phpunit": "~4.4" + }, + "suggest": { + "ext-soap": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.3.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "Mock Object library for PHPUnit", + "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/", + "keywords": [ + "mock", + "xunit" + ], + "time": "2015-10-02 06:51:40" + }, + { + "name": "sebastian/comparator", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/comparator.git", + "reference": "937efb279bd37a375bcadf584dec0726f84dbf22" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/937efb279bd37a375bcadf584dec0726f84dbf22", + "reference": "937efb279bd37a375bcadf584dec0726f84dbf22", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "sebastian/diff": "~1.2", + "sebastian/exporter": "~1.2" + }, + "require-dev": { + "phpunit/phpunit": "~4.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides the functionality to compare PHP values for equality", + "homepage": "http://www.github.com/sebastianbergmann/comparator", + "keywords": [ + "comparator", + "compare", + "equality" + ], + "time": "2015-07-26 15:48:44" + }, + { + "name": "sebastian/diff", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "6899b3e33bfbd386d88b5eea5f65f563e8793051" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/13edfd8706462032c2f52b4b862974dd46b71c9e", + "reference": "6899b3e33bfbd386d88b5eea5f65f563e8793051", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.3-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Diff implementation", + "homepage": "http://www.github.com/sebastianbergmann/diff", + "keywords": [ + "diff" + ], + "time": "2015-06-22 14:15:55" + }, + { + "name": "sebastian/environment", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/environment.git", + "reference": "6324c907ce7a52478eeeaede764f48733ef5ae44" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/dc7a29032cf72b54f36dac15a1ca5b3a1b6029bf", + "reference": "6324c907ce7a52478eeeaede764f48733ef5ae44", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.3.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides functionality to handle HHVM/PHP environments", + "homepage": "http://www.github.com/sebastianbergmann/environment", + "keywords": [ + "Xdebug", + "environment", + "hhvm" + ], + "time": "2015-08-03 06:14:51" + }, + { + "name": "sebastian/exporter", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/exporter.git", + "reference": "f88f8936517d54ae6d589166810877fb2015d0a2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/f88f8936517d54ae6d589166810877fb2015d0a2", + "reference": "f88f8936517d54ae6d589166810877fb2015d0a2", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "sebastian/recursion-context": "~1.0" + }, + "require-dev": { + "ext-mbstring": "*", + "phpunit/phpunit": "~4.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.3.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + } + ], + "description": "Provides the functionality to export PHP variables for visualization", + "homepage": "http://www.github.com/sebastianbergmann/exporter", + "keywords": [ + "export", + "exporter" + ], + "time": "2015-08-09 04:23:41" + }, + { + "name": "sebastian/global-state", + "version": "1.1.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/global-state.git", + "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bc37d50fea7d017d3d340f230811c9f1d7280af4", + "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.2" + }, + "suggest": { + "ext-uopz": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Snapshotting of global state", + "homepage": "http://www.github.com/sebastianbergmann/global-state", + "keywords": [ + "global state" + ], + "time": "2015-10-12 03:26:01" + }, + { + "name": "sebastian/recursion-context", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/recursion-context.git", + "reference": "994d4a811bafe801fb06dccbee797863ba2792ba" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/7ff5b1b3dcc55b8ab8ae61ef99d4730940856ee7", + "reference": "994d4a811bafe801fb06dccbee797863ba2792ba", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + } + ], + "description": "Provides functionality to recursively process PHP variables", + "homepage": "http://www.github.com/sebastianbergmann/recursion-context", + "time": "2015-06-21 08:04:50" + }, + { + "name": "sebastian/version", + "version": "1.0.6", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/version.git", + "reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/58b3a85e7999757d6ad81c787a1fbf5ff6c628c6", + "reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6", + "shasum": "" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that helps with managing the version number of Git-hosted PHP projects", + "homepage": "https://github.com/sebastianbergmann/version", + "time": "2015-06-21 13:59:46" + }, + { + "name": "seld/cli-prompt", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/Seldaek/cli-prompt.git", + "reference": "fe114c7a6ac5cb0ce76932ae4017024d9842a49c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Seldaek/cli-prompt/zipball/b27db1514f7d7bb7a366ad95d4eb2b17140a0691", + "reference": "fe114c7a6ac5cb0ce76932ae4017024d9842a49c", + "shasum": "" + }, + "require": { + "php": ">=5.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Seld\\CliPrompt\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be" + } + ], + "description": "Allows you to prompt for user input on the command line, and optionally hide the characters they type", + "keywords": [ + "cli", + "console", + "hidden", + "input", + "prompt" + ], + "time": "2015-04-30 20:24:49" + }, + { + "name": "seld/jsonlint", + "version": "1.3.1", + "source": { + "type": "git", + "url": "https://github.com/Seldaek/jsonlint.git", + "reference": "863ae85c6d3ef60ca49cb12bd051c4a0648c40c4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Seldaek/jsonlint/zipball/863ae85c6d3ef60ca49cb12bd051c4a0648c40c4", + "reference": "863ae85c6d3ef60ca49cb12bd051c4a0648c40c4", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "bin": [ + "bin/jsonlint" + ], + "type": "library", + "autoload": { + "psr-4": { + "Seld\\JsonLint\\": "src/Seld/JsonLint/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + } + ], + "description": "JSON Linter", + "keywords": [ + "json", + "linter", + "parser", + "validator" + ], + "time": "2015-01-04 21:18:15" + }, + { + "name": "seld/phar-utils", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/Seldaek/phar-utils.git", + "reference": "7009b5139491975ef6486545a39f3e6dad5ac30a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Seldaek/phar-utils/zipball/7009b5139491975ef6486545a39f3e6dad5ac30a", + "reference": "7009b5139491975ef6486545a39f3e6dad5ac30a", + "shasum": "" + }, + "require": { + "php": ">=5.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Seld\\PharUtils\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be" + } + ], + "description": "PHAR file format utilities, for when PHP phars you up", + "keywords": [ + "phra" + ], + "time": "2015-10-13 18:44:15" + }, + { + "name": "symfony/console", + "version": "2.8.x-dev", + "source": { + "type": "git", + "url": "https://github.com/symfony/console.git", + "reference": "89a795226477f66745e8ea10415e769304114920" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/console/zipball/56cc5caf051189720b8de974e4746090aaa10d44", + "reference": "89a795226477f66745e8ea10415e769304114920", + "shasum": "" + }, + "require": { + "php": ">=5.3.9" + }, + "require-dev": { + "psr/log": "~1.0", + "symfony/event-dispatcher": "~2.1|~3.0.0", + "symfony/process": "~2.1|~3.0.0" + }, + "suggest": { + "psr/log": "For using the console logger", + "symfony/event-dispatcher": "", + "symfony/process": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.8-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Console\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Console Component", + "homepage": "https://symfony.com", + "time": "2015-10-12 10:31:17" + }, + { + "name": "symfony/filesystem", + "version": "2.8.x-dev", + "source": { + "type": "git", + "url": "https://github.com/symfony/filesystem.git", + "reference": "fc3fe52fef85e1f3e7775ffad92539e16c20e0af" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/65cb36b6539b1d446527d60457248f30d045464d", + "reference": "fc3fe52fef85e1f3e7775ffad92539e16c20e0af", + "shasum": "" + }, + "require": { + "php": ">=5.3.9" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.8-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Filesystem\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Filesystem Component", + "homepage": "https://symfony.com", + "time": "2015-10-11 08:29:26" + }, + { + "name": "symfony/finder", + "version": "2.8.x-dev", + "source": { + "type": "git", + "url": "https://github.com/symfony/finder.git", + "reference": "dcd5aaba34ca332abb7f33ec554ebd4d829cb202" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/finder/zipball/877bb4b16ea573cc8c024e9590888fcf7eb7e0f7", + "reference": "dcd5aaba34ca332abb7f33ec554ebd4d829cb202", + "shasum": "" + }, + "require": { + "php": ">=5.3.9" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.8-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Finder\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Finder Component", + "homepage": "https://symfony.com", + "time": "2015-10-11 08:29:26" + }, + { + "name": "symfony/process", + "version": "2.8.x-dev", + "source": { + "type": "git", + "url": "https://github.com/symfony/process.git", + "reference": "4e1daf58b375ea7c506d525dc7801df1c9a6ebbd" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/process/zipball/7dedd5b60550f33dca16dd7e94ef8aca8b67bbfe", + "reference": "4e1daf58b375ea7c506d525dc7801df1c9a6ebbd", + "shasum": "" + }, + "require": { + "php": ">=5.3.9" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.8-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Process\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Process Component", + "homepage": "https://symfony.com", + "time": "2015-10-11 08:29:26" + }, + { + "name": "symfony/yaml", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/symfony/yaml.git", + "reference": "8d32eb597b531eb915b4fee3dc582ade5ae1fe6a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/yaml/zipball/ab0314f7544d600ea7917f02cdad774358b81113", + "reference": "8d32eb597b531eb915b4fee3dc582ade5ae1fe6a", + "shasum": "" + }, + "require": { + "php": ">=5.5.9" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Yaml\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Yaml Component", + "homepage": "https://symfony.com", + "time": "2015-10-13 16:01:35" + } + ], + "aliases": [], + "minimum-stability": "dev", + "stability-flags": [], + "prefer-stable": false, + "prefer-lowest": false, + "platform": { + "php": ">=5.3.0" + }, + "platform-dev": [] +} diff --git a/civicrm/vendor/cweagans/composer-patches/phpunit.xml.dist b/civicrm/vendor/cweagans/composer-patches/phpunit.xml.dist new file mode 100644 index 0000000000..62409b3b43 --- /dev/null +++ b/civicrm/vendor/cweagans/composer-patches/phpunit.xml.dist @@ -0,0 +1,18 @@ +<!--?xml version="1.0" encoding="UTF-8"?--> + +<phpunit colors="true" bootstrap="vendor/autoload.php"> + <testsuites> + <testsuite name="composer-patches"> + <directory>./tests/</directory> + </testsuite> + </testsuites> + <!-- Filter for coverage reports. --> + <filter> + <whitelist> + <directory>src/</directory> + </whitelist> + <blacklist> + <directory>vendor/</directory> + </blacklist> + </filter> +</phpunit> diff --git a/civicrm/vendor/cweagans/composer-patches/src/PatchEvent.php b/civicrm/vendor/cweagans/composer-patches/src/PatchEvent.php new file mode 100644 index 0000000000..31d36f89f5 --- /dev/null +++ b/civicrm/vendor/cweagans/composer-patches/src/PatchEvent.php @@ -0,0 +1,70 @@ +<?php + +/** + * @file + * Dispatch events when patches are applied. + */ + +namespace cweagans\Composer; + +use Composer\EventDispatcher\Event; +use Composer\Package\PackageInterface; + +class PatchEvent extends Event { + + /** + * @var PackageInterface $package + */ + protected $package; + /** + * @var string $url + */ + protected $url; + /** + * @var string $description + */ + protected $description; + + /** + * Constructs a PatchEvent object. + * + * @param string $eventName + * @param PackageInterface $package + * @param string $url + * @param string $description + */ + public function __construct($eventName, PackageInterface $package, $url, $description) { + parent::__construct($eventName); + $this->package = $package; + $this->url = $url; + $this->description = $description; + } + + /** + * Returns the package that is patched. + * + * @return PackageInterface + */ + public function getPackage() { + return $this->package; + } + + /** + * Returns the url of the patch. + * + * @return string + */ + public function getUrl() { + return $this->url; + } + + /** + * Returns the description of the patch. + * + * @return string + */ + public function getDescription() { + return $this->description; + } + +} diff --git a/civicrm/vendor/cweagans/composer-patches/src/PatchEvents.php b/civicrm/vendor/cweagans/composer-patches/src/PatchEvents.php new file mode 100644 index 0000000000..ecee947682 --- /dev/null +++ b/civicrm/vendor/cweagans/composer-patches/src/PatchEvents.php @@ -0,0 +1,30 @@ +<?php + +/** + * @file + * Dispatch events when patches are applied. + */ + +namespace cweagans\Composer; + +class PatchEvents { + + /** + * The PRE_PATCH_APPLY event occurs before a patch is applied. + * + * The event listener method receives a cweagans\Composer\PatchEvent instance. + * + * @var string + */ + const PRE_PATCH_APPLY = 'pre-patch-apply'; + + /** + * The POST_PATCH_APPLY event occurs after a patch is applied. + * + * The event listener method receives a cweagans\Composer\PatchEvent instance. + * + * @var string + */ + const POST_PATCH_APPLY = 'post-patch-apply'; + +} diff --git a/civicrm/vendor/cweagans/composer-patches/src/Patches.php b/civicrm/vendor/cweagans/composer-patches/src/Patches.php new file mode 100644 index 0000000000..70c5b83421 --- /dev/null +++ b/civicrm/vendor/cweagans/composer-patches/src/Patches.php @@ -0,0 +1,550 @@ +<?php + +/** + * @file + * Provides a way to patch Composer packages after installation. + */ + +namespace cweagans\Composer; + +use Composer\Composer; +use Composer\DependencyResolver\Operation\InstallOperation; +use Composer\DependencyResolver\Operation\UninstallOperation; +use Composer\DependencyResolver\Operation\UpdateOperation; +use Composer\DependencyResolver\Operation\OperationInterface; +use Composer\EventDispatcher\EventSubscriberInterface; +use Composer\IO\IOInterface; +use Composer\Package\AliasPackage; +use Composer\Package\PackageInterface; +use Composer\Plugin\PluginInterface; +use Composer\Installer\PackageEvents; +use Composer\Script\Event; +use Composer\Script\ScriptEvents; +use Composer\Installer\PackageEvent; +use Composer\Util\ProcessExecutor; +use Composer\Util\RemoteFilesystem; +use Symfony\Component\Process\Process; + +class Patches implements PluginInterface, EventSubscriberInterface { + + /** + * @var Composer $composer + */ + protected $composer; + /** + * @var IOInterface $io + */ + protected $io; + /** + * @var EventDispatcher $eventDispatcher + */ + protected $eventDispatcher; + /** + * @var ProcessExecutor $executor + */ + protected $executor; + /** + * @var array $patches + */ + protected $patches; + + /** + * Apply plugin modifications to composer + * + * @param Composer $composer + * @param IOInterface $io + */ + public function activate(Composer $composer, IOInterface $io) { + $this->composer = $composer; + $this->io = $io; + $this->eventDispatcher = $composer->getEventDispatcher(); + $this->executor = new ProcessExecutor($this->io); + $this->patches = array(); + $this->installedPatches = array(); + } + + /** + * Returns an array of event names this subscriber wants to listen to. + */ + public static function getSubscribedEvents() { + return array( + ScriptEvents::PRE_INSTALL_CMD => array('checkPatches'), + ScriptEvents::PRE_UPDATE_CMD => array('checkPatches'), + PackageEvents::PRE_PACKAGE_INSTALL => array('gatherPatches'), + PackageEvents::PRE_PACKAGE_UPDATE => array('gatherPatches'), + // The following is a higher weight for compatibility with + // https://github.com/AydinHassan/magento-core-composer-installer and more generally for compatibility with + // every Composer plugin which deploys downloaded packages to other locations. + // In such cases you want that those plugins deploy patched files so they have to run after + // the "composer-patches" plugin. + // @see: https://github.com/cweagans/composer-patches/pull/153 + PackageEvents::POST_PACKAGE_INSTALL => array('postInstall', 10), + PackageEvents::POST_PACKAGE_UPDATE => array('postInstall', 10), + ); + } + + /** + * Before running composer install, + * @param Event $event + */ + public function checkPatches(Event $event) { + if (!$this->isPatchingEnabled()) { + return; + } + + try { + $repositoryManager = $this->composer->getRepositoryManager(); + $localRepository = $repositoryManager->getLocalRepository(); + $installationManager = $this->composer->getInstallationManager(); + $packages = $localRepository->getPackages(); + + $extra = $this->composer->getPackage()->getExtra(); + $patches_ignore = isset($extra['patches-ignore']) ? $extra['patches-ignore'] : array(); + + $tmp_patches = $this->grabPatches(); + foreach ($packages as $package) { + $extra = $package->getExtra(); + if (isset($extra['patches'])) { + if (isset($patches_ignore[$package->getName()])) { + foreach ($patches_ignore[$package->getName()] as $package_name => $patches) { + if (isset($extra['patches'][$package_name])) { + $extra['patches'][$package_name] = array_diff($extra['patches'][$package_name], $patches); + } + } + } + $this->installedPatches[$package->getName()] = $extra['patches']; + } + $patches = isset($extra['patches']) ? $extra['patches'] : array(); + $tmp_patches = array_merge_recursive($tmp_patches, $patches); + } + + if ($tmp_patches == FALSE) { + $this->io->write('<info>No patches supplied.</info>'); + return; + } + + // Remove packages for which the patch set has changed. + foreach ($packages as $package) { + if (!($package instanceof AliasPackage)) { + $package_name = $package->getName(); + $extra = $package->getExtra(); + $has_patches = isset($tmp_patches[$package_name]); + $has_applied_patches = isset($extra['patches_applied']); + if (($has_patches && !$has_applied_patches) + || (!$has_patches && $has_applied_patches) + || ($has_patches && $has_applied_patches && $tmp_patches[$package_name] !== $extra['patches_applied'])) { + $uninstallOperation = new UninstallOperation($package, 'Removing package so it can be re-installed and re-patched.'); + $this->io->write('<info>Removing package ' . $package_name . ' so that it can be re-installed and re-patched.</info>'); + $installationManager->uninstall($localRepository, $uninstallOperation); + } + } + } + } + // If the Locker isn't available, then we don't need to do this. + // It's the first time packages have been installed. + catch (\LogicException $e) { + return; + } + } + + /** + * Gather patches from dependencies and store them for later use. + * + * @param PackageEvent $event + */ + public function gatherPatches(PackageEvent $event) { + // If we've already done this, then don't do it again. + if (isset($this->patches['_patchesGathered'])) { + $this->io->write('<info>Patches already gathered. Skipping</info>', TRUE, IOInterface::VERBOSE); + return; + } + // If patching has been disabled, bail out here. + elseif (!$this->isPatchingEnabled()) { + $this->io->write('<info>Patching is disabled. Skipping.</info>', TRUE, IOInterface::VERBOSE); + return; + } + + $this->patches = $this->grabPatches(); + if (empty($this->patches)) { + $this->io->write('<info>No patches supplied.</info>'); + } + + $extra = $this->composer->getPackage()->getExtra(); + $patches_ignore = isset($extra['patches-ignore']) ? $extra['patches-ignore'] : array(); + + // Now add all the patches from dependencies that will be installed. + $operations = $event->getOperations(); + $this->io->write('<info>Gathering patches for dependencies. This might take a minute.</info>'); + foreach ($operations as $operation) { + if ($operation->getJobType() == 'install' || $operation->getJobType() == 'update') { + $package = $this->getPackageFromOperation($operation); + $extra = $package->getExtra(); + if (isset($extra['patches'])) { + if (isset($patches_ignore[$package->getName()])) { + foreach ($patches_ignore[$package->getName()] as $package_name => $patches) { + if (isset($extra['patches'][$package_name])) { + $extra['patches'][$package_name] = array_diff($extra['patches'][$package_name], $patches); + } + } + } + $this->patches = $this->arrayMergeRecursiveDistinct($this->patches, $extra['patches']); + } + // Unset installed patches for this package + if(isset($this->installedPatches[$package->getName()])) { + unset($this->installedPatches[$package->getName()]); + } + } + } + + // Merge installed patches from dependencies that did not receive an update. + foreach ($this->installedPatches as $patches) { + $this->patches = array_merge_recursive($this->patches, $patches); + } + + // If we're in verbose mode, list the projects we're going to patch. + if ($this->io->isVerbose()) { + foreach ($this->patches as $package => $patches) { + $number = count($patches); + $this->io->write('<info>Found ' . $number . ' patches for ' . $package . '.</info>'); + } + } + + // Make sure we don't gather patches again. Extra keys in $this->patches + // won't hurt anything, so we'll just stash it there. + $this->patches['_patchesGathered'] = TRUE; + } + + /** + * Get the patches from root composer or external file + * @return Patches + * @throws \Exception + */ + public function grabPatches() { + // First, try to get the patches from the root composer.json. + $extra = $this->composer->getPackage()->getExtra(); + if (isset($extra['patches'])) { + $this->io->write('<info>Gathering patches for root package.</info>'); + $patches = $extra['patches']; + return $patches; + } + // If it's not specified there, look for a patches-file definition. + elseif (isset($extra['patches-file'])) { + $this->io->write('<info>Gathering patches from patch file.</info>'); + $patches = file_get_contents($extra['patches-file']); + $patches = json_decode($patches, TRUE); + $error = json_last_error(); + if ($error != 0) { + switch ($error) { + case JSON_ERROR_DEPTH: + $msg = ' - Maximum stack depth exceeded'; + break; + case JSON_ERROR_STATE_MISMATCH: + $msg = ' - Underflow or the modes mismatch'; + break; + case JSON_ERROR_CTRL_CHAR: + $msg = ' - Unexpected control character found'; + break; + case JSON_ERROR_SYNTAX: + $msg = ' - Syntax error, malformed JSON'; + break; + case JSON_ERROR_UTF8: + $msg = ' - Malformed UTF-8 characters, possibly incorrectly encoded'; + break; + default: + $msg = ' - Unknown error'; + break; + } + throw new \Exception('There was an error in the supplied patches file:' . $msg); + } + if (isset($patches['patches'])) { + $patches = $patches['patches']; + return $patches; + } + elseif(!$patches) { + throw new \Exception('There was an error in the supplied patch file'); + } + } + else { + return array(); + } + } + + /** + * @param PackageEvent $event + * @throws \Exception + */ + public function postInstall(PackageEvent $event) { + + // Check if we should exit in failure. + $extra = $this->composer->getPackage()->getExtra(); + $exitOnFailure = getenv('COMPOSER_EXIT_ON_PATCH_FAILURE') || !empty($extra['composer-exit-on-patch-failure']); + + // Get the package object for the current operation. + $operation = $event->getOperation(); + /** @var PackageInterface $package */ + $package = $this->getPackageFromOperation($operation); + $package_name = $package->getName(); + + if (!isset($this->patches[$package_name])) { + if ($this->io->isVerbose()) { + $this->io->write('<info>No patches found for ' . $package_name . '.</info>'); + } + return; + } + $this->io->write(' - Applying patches for <info>' . $package_name . '</info>'); + + // Get the install path from the package object. + $manager = $event->getComposer()->getInstallationManager(); + $install_path = $manager->getInstaller($package->getType())->getInstallPath($package); + + // Set up a downloader. + $downloader = new RemoteFilesystem($this->io, $this->composer->getConfig()); + + // Track applied patches in the package info in installed.json + $localRepository = $this->composer->getRepositoryManager()->getLocalRepository(); + $localPackage = $localRepository->findPackage($package_name, $package->getVersion()); + $extra = $localPackage->getExtra(); + $extra['patches_applied'] = array(); + + foreach ($this->patches[$package_name] as $description => $url) { + $this->io->write(' <info>' . $url . '</info> (<comment>' . $description. '</comment>)'); + try { + $this->eventDispatcher->dispatch(NULL, new PatchEvent(PatchEvents::PRE_PATCH_APPLY, $package, $url, $description)); + $this->getAndApplyPatch($downloader, $install_path, $url, $package); + $this->eventDispatcher->dispatch(NULL, new PatchEvent(PatchEvents::POST_PATCH_APPLY, $package, $url, $description)); + $extra['patches_applied'][$description] = $url; + } + catch (\Exception $e) { + $this->io->write(' <error>Could not apply patch! Skipping. The error was: ' . $e->getMessage() . '</error>'); + if ($exitOnFailure) { + throw new \Exception("Cannot apply patch $description ($url)!"); + } + } + } + $localPackage->setExtra($extra); + + $this->io->write(''); + $this->writePatchReport($this->patches[$package_name], $install_path); + } + + /** + * Get a Package object from an OperationInterface object. + * + * @param OperationInterface $operation + * @return PackageInterface + * @throws \Exception + */ + protected function getPackageFromOperation(OperationInterface $operation) { + if ($operation instanceof InstallOperation) { + $package = $operation->getPackage(); + } + elseif ($operation instanceof UpdateOperation) { + $package = $operation->getTargetPackage(); + } + else { + throw new \Exception('Unknown operation: ' . get_class($operation)); + } + + return $package; + } + + /** + * Apply a patch on code in the specified directory. + * + * @param RemoteFilesystem $downloader + * @param $install_path + * @param $patch_url + * @param PackageInterface $package + * @throws \Exception + */ + protected function getAndApplyPatch(RemoteFilesystem $downloader, $install_path, $patch_url, PackageInterface $package) { + + // Local patch file. + if (file_exists($patch_url)) { + $filename = realpath($patch_url); + } + else { + // Generate random (but not cryptographically so) filename. + $filename = uniqid(sys_get_temp_dir().'/') . ".patch"; + + // Download file from remote filesystem to this location. + $hostname = parse_url($patch_url, PHP_URL_HOST); + $downloader->copy($hostname, $patch_url, $filename, FALSE); + } + + // The order here is intentional. p1 is most likely to apply with git apply. + // p0 is next likely. p2 is extremely unlikely, but for some special cases, + // it might be useful. p4 is useful for Magento 2 patches + $patch_levels = array('-p1', '-p0', '-p2', '-p4'); + + // Check for specified patch level for this package. + if (!empty($this->composer->getPackage()->getExtra()['patchLevel'][$package->getName()])){ + $patch_levels = array($this->composer->getPackage()->getExtra()['patchLevel'][$package->getName()]); + } + // Attempt to apply with git apply. + $patched = $this->applyPatchWithGit($install_path, $patch_levels, $filename); + + // In some rare cases, git will fail to apply a patch, fallback to using + // the 'patch' command. + if (!$patched) { + foreach ($patch_levels as $patch_level) { + // --no-backup-if-mismatch here is a hack that fixes some + // differences between how patch works on windows and unix. + if ($patched = $this->executeCommand("patch %s --no-backup-if-mismatch -d %s < %s", $patch_level, $install_path, $filename)) { + break; + } + } + } + + // Clean up the temporary patch file. + if (isset($hostname)) { + unlink($filename); + } + // If the patch *still* isn't applied, then give up and throw an Exception. + // Otherwise, let the user know it worked. + if (!$patched) { + throw new \Exception("Cannot apply patch $patch_url"); + } + } + + /** + * Checks if the root package enables patching. + * + * @return bool + * Whether patching is enabled. Defaults to TRUE. + */ + protected function isPatchingEnabled() { + $extra = $this->composer->getPackage()->getExtra(); + + if (empty($extra['patches']) && empty($extra['patches-ignore']) && !isset($extra['patches-file'])) { + // The root package has no patches of its own, so only allow patching if + // it has specifically opted in. + return isset($extra['enable-patching']) ? $extra['enable-patching'] : FALSE; + } + else { + return TRUE; + } + } + + /** + * Writes a patch report to the target directory. + * + * @param array $patches + * @param string $directory + */ + protected function writePatchReport($patches, $directory) { + $output = "This file was automatically generated by Composer Patches (https://github.com/cweagans/composer-patches)\n"; + $output .= "Patches applied to this directory:\n\n"; + foreach ($patches as $description => $url) { + $output .= $description . "\n"; + $output .= 'Source: ' . $url . "\n\n\n"; + } + file_put_contents($directory . "/PATCHES.txt", $output); + } + + /** + * Executes a shell command with escaping. + * + * @param string $cmd + * @return bool + */ + protected function executeCommand($cmd) { + // Shell-escape all arguments except the command. + $args = func_get_args(); + foreach ($args as $index => $arg) { + if ($index !== 0) { + $args[$index] = escapeshellarg($arg); + } + } + + // And replace the arguments. + $command = call_user_func_array('sprintf', $args); + $output = ''; + if ($this->io->isVerbose()) { + $this->io->write('<comment>' . $command . '</comment>'); + $io = $this->io; + $output = function ($type, $data) use ($io) { + if ($type == Process::ERR) { + $io->write('<error>' . $data . '</error>'); + } + else { + $io->write('<comment>' . $data . '</comment>'); + } + }; + } + return ($this->executor->execute($command, $output) == 0); + } + + /** + * Recursively merge arrays without changing data types of values. + * + * Does not change the data types of the values in the arrays. Matching keys' + * values in the second array overwrite those in the first array, as is the + * case with array_merge. + * + * @param array $array1 + * The first array. + * @param array $array2 + * The second array. + * @return array + * The merged array. + * + * @see http://php.net/manual/en/function.array-merge-recursive.php#92195 + */ + protected function arrayMergeRecursiveDistinct(array $array1, array $array2) { + $merged = $array1; + + foreach ($array2 as $key => &$value) { + if (is_array($value) && isset($merged[$key]) && is_array($merged[$key])) { + $merged[$key] = $this->arrayMergeRecursiveDistinct($merged[$key], $value); + } + else { + $merged[$key] = $value; + } + } + + return $merged; + } + + /** + * Attempts to apply a patch with git apply. + * + * @param $install_path + * @param $patch_levels + * @param $filename + * + * @return bool + * TRUE if patch was applied, FALSE otherwise. + */ + protected function applyPatchWithGit($install_path, $patch_levels, $filename) { + // Do not use git apply unless the install path is itself a git repo + // @see https://stackoverflow.com/a/27283285 + if (!is_dir($install_path . '/.git')) { + return FALSE; + } + + $patched = FALSE; + foreach ($patch_levels as $patch_level) { + if ($this->io->isVerbose()) { + $comment = 'Testing ability to patch with git apply.'; + $comment .= ' This command may produce errors that can be safely ignored.'; + $this->io->write('<comment>' . $comment . '</comment>'); + } + $checked = $this->executeCommand('git -C %s apply --check -v %s %s', $install_path, $patch_level, $filename); + $output = $this->executor->getErrorOutput(); + if (substr($output, 0, 7) == 'Skipped') { + // Git will indicate success but silently skip patches in some scenarios. + // + // @see https://github.com/cweagans/composer-patches/pull/165 + $checked = FALSE; + } + if ($checked) { + // Apply the first successful style. + $patched = $this->executeCommand('git -C %s apply %s %s', $install_path, $patch_level, $filename); + break; + } + } + return $patched; + } + +} diff --git a/civicrm/vendor/pear/console_getopt/.gitignore b/civicrm/vendor/pear/console_getopt/.gitignore new file mode 100644 index 0000000000..783582816c --- /dev/null +++ b/civicrm/vendor/pear/console_getopt/.gitignore @@ -0,0 +1,6 @@ +# composer related +composer.lock +composer.phar +vendor +README.html +dist/ diff --git a/civicrm/vendor/pear/console_getopt/.travis.yml b/civicrm/vendor/pear/console_getopt/.travis.yml new file mode 100644 index 0000000000..2711415f56 --- /dev/null +++ b/civicrm/vendor/pear/console_getopt/.travis.yml @@ -0,0 +1,9 @@ +language: php +php: + - 7 + - 5.6 + - 5.5 + - 5.4 +sudo: false +script: + - pear run-tests -r tests/ diff --git a/civicrm/packages/Console/Getopt.php b/civicrm/vendor/pear/console_getopt/Console/Getopt.php similarity index 54% rename from civicrm/packages/Console/Getopt.php rename to civicrm/vendor/pear/console_getopt/Console/Getopt.php index bb9d69ca22..0da88585d7 100644 --- a/civicrm/packages/Console/Getopt.php +++ b/civicrm/vendor/pear/console_getopt/Console/Getopt.php @@ -1,32 +1,40 @@ <?php /* vim: set expandtab tabstop=4 shiftwidth=4: */ -// +----------------------------------------------------------------------+ -// | PHP Version 5 | -// +----------------------------------------------------------------------+ -// | Copyright (c) 1997-2004 The PHP Group | -// +----------------------------------------------------------------------+ -// | This source file is subject to version 3.0 of the PHP license, | -// | that is bundled with this package in the file LICENSE, and is | -// | available through the world-wide-web at the following url: | -// | http://www.php.net/license/3_0.txt. | -// | If you did not receive a copy of the PHP license and are unable to | -// | obtain it through the world-wide-web, please send a note to | -// | license@php.net so we can mail you a copy immediately. | -// +----------------------------------------------------------------------+ -// | Author: Andrei Zmievski <andrei@php.net> | -// +----------------------------------------------------------------------+ -// -// $Id: Getopt.php,v 1.4 2007/06/12 14:58:56 cellog Exp $ +/** + * PHP Version 5 + * + * Copyright (c) 1997-2004 The PHP Group + * + * This source file is subject to version 3.0 of the PHP license, + * that is bundled with this package in the file LICENSE, and is + * available through the world-wide-web at the following url: + * http://www.php.net/license/3_0.txt. + * If you did not receive a copy of the PHP license and are unable to + * obtain it through the world-wide-web, please send a note to + * license@php.net so we can mail you a copy immediately. + * + * @category Console + * @package Console_Getopt + * @author Andrei Zmievski <andrei@php.net> + * @license http://www.php.net/license/3_0.txt PHP 3.0 + * @version CVS: $Id$ + * @link http://pear.php.net/package/Console_Getopt + */ require_once 'PEAR.php'; /** * Command-line options parsing class. * - * @author Andrei Zmievski <andrei@php.net> - * + * @category Console + * @package Console_Getopt + * @author Andrei Zmievski <andrei@php.net> + * @license http://www.php.net/license/3_0.txt PHP 3.0 + * @link http://pear.php.net/package/Console_Getopt */ -class Console_Getopt { +class Console_Getopt +{ + /** * Parses the command-line options. * @@ -53,45 +61,59 @@ class Console_Getopt { * * Most of the semantics of this function are based on GNU getopt_long(). * - * @param array $args an array of command-line arguments - * @param string $short_options specifies the list of allowed short options - * @param array $long_options specifies the list of allowed long options + * @param array $args an array of command-line arguments + * @param string $short_options specifies the list of allowed short options + * @param array $long_options specifies the list of allowed long options + * @param boolean $skip_unknown suppresses Console_Getopt: unrecognized option * * @return array two-element array containing the list of parsed options and * the non-option arguments - * - * @access public - * */ - function getopt2($args, $short_options, $long_options = null) + public static function getopt2($args, $short_options, $long_options = null, $skip_unknown = false) { - return Console_Getopt::doGetopt(2, $args, $short_options, $long_options); + return Console_Getopt::doGetopt(2, $args, $short_options, $long_options, $skip_unknown); } /** * This function expects $args to start with the script name (POSIX-style). * Preserved for backwards compatibility. + * + * @param array $args an array of command-line arguments + * @param string $short_options specifies the list of allowed short options + * @param array $long_options specifies the list of allowed long options + * * @see getopt2() - */ - function getopt($args, $short_options, $long_options = null) + * @return array two-element array containing the list of parsed options and + * the non-option arguments + */ + public static function getopt($args, $short_options, $long_options = null, $skip_unknown = false) { - return Console_Getopt::doGetopt(1, $args, $short_options, $long_options); + return Console_Getopt::doGetopt(1, $args, $short_options, $long_options, $skip_unknown); } /** * The actual implementation of the argument parsing code. + * + * @param int $version Version to use + * @param array $args an array of command-line arguments + * @param string $short_options specifies the list of allowed short options + * @param array $long_options specifies the list of allowed long options + * @param boolean $skip_unknown suppresses Console_Getopt: unrecognized option + * + * @return array */ - function doGetopt($version, $args, $short_options, $long_options = null) + public static function doGetopt($version, $args, $short_options, $long_options = null, $skip_unknown = false) { // in case you pass directly readPHPArgv() as the first arg if (PEAR::isError($args)) { return $args; } + if (empty($args)) { return array(array(), array()); } - $opts = array(); - $non_opts = array(); + + $non_opts = $opts = array(); settype($args, 'array'); @@ -111,7 +133,6 @@ class Console_Getopt { reset($args); while (list($i, $arg) = each($args)) { - /* The special element '--' means explicit end of options. Treat the rest of the arguments as non-options and end the loop. */ @@ -124,17 +145,27 @@ class Console_Getopt { $non_opts = array_merge($non_opts, array_slice($args, $i)); break; } elseif (strlen($arg) > 1 && $arg{1} == '-') { - $error = Console_Getopt::_parseLongOption(substr($arg, 2), $long_options, $opts, $args); - if (PEAR::isError($error)) + $error = Console_Getopt::_parseLongOption(substr($arg, 2), + $long_options, + $opts, + $args, + $skip_unknown); + if (PEAR::isError($error)) { return $error; + } } elseif ($arg == '-') { // - is stdin $non_opts = array_merge($non_opts, array_slice($args, $i)); break; } else { - $error = Console_Getopt::_parseShortOption(substr($arg, 1), $short_options, $opts, $args); - if (PEAR::isError($error)) + $error = Console_Getopt::_parseShortOption(substr($arg, 1), + $short_options, + $opts, + $args, + $skip_unknown); + if (PEAR::isError($error)) { return $error; + } } } @@ -142,19 +173,30 @@ class Console_Getopt { } /** - * @access private + * Parse short option + * + * @param string $arg Argument + * @param string[] $short_options Available short options + * @param string[][] &$opts + * @param string[] &$args + * @param boolean $skip_unknown suppresses Console_Getopt: unrecognized option * + * @return void */ - function _parseShortOption($arg, $short_options, &$opts, &$args) + protected static function _parseShortOption($arg, $short_options, &$opts, &$args, $skip_unknown) { for ($i = 0; $i < strlen($arg); $i++) { - $opt = $arg{$i}; + $opt = $arg{$i}; $opt_arg = null; /* Try to find the short option in the specifier string. */ - if (($spec = strstr($short_options, $opt)) === false || $arg{$i} == ':') - { - return PEAR::raiseError("Console_Getopt: unrecognized option -- $opt"); + if (($spec = strstr($short_options, $opt)) === false || $arg{$i} == ':') { + if ($skip_unknown === true) { + break; + } + + $msg = "Console_Getopt: unrecognized option -- $opt"; + return PEAR::raiseError($msg); } if (strlen($spec) > 1 && $spec{1} == ':') { @@ -173,11 +215,14 @@ class Console_Getopt { break; } else if (list(, $opt_arg) = each($args)) { /* Else use the next argument. */; - if (Console_Getopt::_isShortOpt($opt_arg) || Console_Getopt::_isLongOpt($opt_arg)) { - return PEAR::raiseError("Console_Getopt: option requires an argument -- $opt"); + if (Console_Getopt::_isShortOpt($opt_arg) + || Console_Getopt::_isLongOpt($opt_arg)) { + $msg = "option requires an argument --$opt"; + return PEAR::raiseError("Console_Getopt: " . $msg); } } else { - return PEAR::raiseError("Console_Getopt: option requires an argument -- $opt"); + $msg = "option requires an argument --$opt"; + return PEAR::raiseError("Console_Getopt: " . $msg); } } } @@ -187,36 +232,51 @@ class Console_Getopt { } /** - * @access private + * Checks if an argument is a short option * + * @param string $arg Argument to check + * + * @return bool */ - function _isShortOpt($arg) + protected static function _isShortOpt($arg) { - return strlen($arg) == 2 && $arg[0] == '-' && preg_match('/[a-zA-Z]/', $arg[1]); + return strlen($arg) == 2 && $arg[0] == '-' + && preg_match('/[a-zA-Z]/', $arg[1]); } /** - * @access private + * Checks if an argument is a long option + * + * @param string $arg Argument to check * + * @return bool */ - function _isLongOpt($arg) + protected static function _isLongOpt($arg) { return strlen($arg) > 2 && $arg[0] == '-' && $arg[1] == '-' && - preg_match('/[a-zA-Z]+$/', substr($arg, 2)); + preg_match('/[a-zA-Z]+$/', substr($arg, 2)); } /** - * @access private + * Parse long option + * + * @param string $arg Argument + * @param string[] $long_options Available long options + * @param string[][] &$opts + * @param string[] &$args * + * @return void|PEAR_Error */ - function _parseLongOption($arg, $long_options, &$opts, &$args) + protected static function _parseLongOption($arg, $long_options, &$opts, &$args, $skip_unknown) { @list($opt, $opt_arg) = explode('=', $arg, 2); + $opt_len = strlen($opt); for ($i = 0; $i < count($long_options); $i++) { $long_opt = $long_options[$i]; $opt_start = substr($long_opt, 0, $opt_len); + $long_opt_name = str_replace('=', '', $long_opt); /* Option doesn't match. Go on to the next one. */ @@ -224,7 +284,7 @@ class Console_Getopt { continue; } - $opt_rest = substr($long_opt, $opt_len); + $opt_rest = substr($long_opt, $opt_len); /* Check that the options uniquely matches one of the allowed options. */ @@ -233,12 +293,15 @@ class Console_Getopt { } else { $next_option_rest = ''; } + if ($opt_rest != '' && $opt{0} != '=' && $i + 1 < count($long_options) && $opt == substr($long_options[$i+1], 0, $opt_len) && $next_option_rest != '' && $next_option_rest{0} != '=') { - return PEAR::raiseError("Console_Getopt: option --$opt is ambiguous"); + + $msg = "Console_Getopt: option --$opt is ambiguous"; + return PEAR::raiseError($msg); } if (substr($long_opt, -1) == '=') { @@ -246,37 +309,46 @@ class Console_Getopt { /* Long option requires an argument. Take the next argument if one wasn't specified. */; if (!strlen($opt_arg) && !(list(, $opt_arg) = each($args))) { - return PEAR::raiseError("Console_Getopt: option --$opt requires an argument"); + $msg = "Console_Getopt: option requires an argument --$opt"; + return PEAR::raiseError($msg); } - if (Console_Getopt::_isShortOpt($opt_arg) || Console_Getopt::_isLongOpt($opt_arg)) { - return PEAR::raiseError("Console_Getopt: option requires an argument --$opt"); + + if (Console_Getopt::_isShortOpt($opt_arg) + || Console_Getopt::_isLongOpt($opt_arg)) { + $msg = "Console_Getopt: option requires an argument --$opt"; + return PEAR::raiseError($msg); } } } else if ($opt_arg) { - return PEAR::raiseError("Console_Getopt: option --$opt doesn't allow an argument"); + $msg = "Console_Getopt: option --$opt doesn't allow an argument"; + return PEAR::raiseError($msg); } $opts[] = array('--' . $opt, $opt_arg); return; } + if ($skip_unknown === true) { + return; + } + return PEAR::raiseError("Console_Getopt: unrecognized option --$opt"); } /** - * Safely read the $argv PHP array across different PHP configurations. - * Will take care on register_globals and register_argc_argv ini directives - * - * @access public - * @return mixed the $argv PHP array or PEAR error if not registered - */ - function readPHPArgv() + * Safely read the $argv PHP array across different PHP configurations. + * Will take care on register_globals and register_argc_argv ini directives + * + * @return mixed the $argv PHP array or PEAR error if not registered + */ + public static function readPHPArgv() { global $argv; if (!is_array($argv)) { if (!@is_array($_SERVER['argv'])) { if (!@is_array($GLOBALS['HTTP_SERVER_VARS']['argv'])) { - return PEAR::raiseError("Console_Getopt: Could not read cmd args (register_argc_argv=Off?)"); + $msg = "Could not read cmd args (register_argc_argv=Off?)"; + return PEAR::raiseError("Console_Getopt: " . $msg); } return $GLOBALS['HTTP_SERVER_VARS']['argv']; } @@ -285,6 +357,4 @@ class Console_Getopt { return $argv; } -} - -?> +} \ No newline at end of file diff --git a/civicrm/vendor/pear/console_getopt/LICENSE b/civicrm/vendor/pear/console_getopt/LICENSE new file mode 100644 index 0000000000..452b08839b --- /dev/null +++ b/civicrm/vendor/pear/console_getopt/LICENSE @@ -0,0 +1,25 @@ +Copyright (c) 2001-2015, The PEAR developers +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + +1. Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/civicrm/vendor/pear/console_getopt/composer.json b/civicrm/vendor/pear/console_getopt/composer.json new file mode 100644 index 0000000000..4dc7e7cca4 --- /dev/null +++ b/civicrm/vendor/pear/console_getopt/composer.json @@ -0,0 +1,35 @@ +{ + "authors": [ + { + "email": "andrei@php.net", + "name": "Andrei Zmievski", + "role": "Lead" + }, + { + "email": "stig@php.net", + "name": "Stig Bakken", + "role": "Developer" + }, + { + "email": "cellog@php.net", + "name": "Greg Beaver", + "role": "Helper" + } + ], + "autoload": { + "psr-0": { + "Console": "./" + } + }, + "description": "More info available on: http://pear.php.net/package/Console_Getopt", + "include-path": [ + "./" + ], + "license": "BSD-2-Clause", + "name": "pear/console_getopt", + "support": { + "issues": "http://pear.php.net/bugs/search.php?cmd=display&package_name[]=Console_Getopt", + "source": "https://github.com/pear/Console_Getopt" + }, + "type": "library" +} diff --git a/civicrm/vendor/pear/mail/.gitignore b/civicrm/vendor/pear/mail/.gitignore new file mode 100644 index 0000000000..869f498584 --- /dev/null +++ b/civicrm/vendor/pear/mail/.gitignore @@ -0,0 +1,4 @@ +# composer related +composer.lock +composer.phar +vendor diff --git a/civicrm/vendor/pear/mail/.travis.yml b/civicrm/vendor/pear/mail/.travis.yml new file mode 100644 index 0000000000..c150272953 --- /dev/null +++ b/civicrm/vendor/pear/mail/.travis.yml @@ -0,0 +1,19 @@ +language: php +sudo: false +php: + - 5.4 + - 5.5 + - 5.6 + - 7.0 + - 7.1 + - nightly +install: + - pear list + - pear channel-update pear.php.net + - pear upgrade --force pear/pear + - pear list + - pear upgrade --force xml_util + - pear install --force --alldeps package.xml + - pear list +script: + - pear run-tests -d tests/ diff --git a/civicrm/vendor/pear/mail/LICENSE b/civicrm/vendor/pear/mail/LICENSE new file mode 100644 index 0000000000..9aee685efa --- /dev/null +++ b/civicrm/vendor/pear/mail/LICENSE @@ -0,0 +1,29 @@ +Copyright (c) 1997-2017, Chuck Hagenbuch +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/civicrm/packages/Mail.php b/civicrm/vendor/pear/mail/Mail.php similarity index 85% rename from civicrm/packages/Mail.php rename to civicrm/vendor/pear/mail/Mail.php index a900628dbd..0e7da0027a 100644 --- a/civicrm/packages/Mail.php +++ b/civicrm/vendor/pear/mail/Mail.php @@ -1,32 +1,34 @@ <?php /** - * PEAR's Mail:: interface. + * PEAR's Mail:: interface. * - * PHP versions 4 and 5 + * PHP version 5 * * LICENSE: * - * Copyright (c) 2002-2007, Richard Heyes + * Copyright (c) 1997-2017, Chuck Hagenbuch & Richard Heyes * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * - * o Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * o Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * o The names of the authors may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY @@ -37,9 +39,9 @@ * @category Mail * @package Mail * @author Chuck Hagenbuch <chuck@horde.org> - * @copyright 1997-2010 Chuck Hagenbuch - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Mail.php 294747 2010-02-08 08:18:33Z clockwerx $ + * @copyright 1997-2017 Chuck Hagenbuch + * @license http://opensource.org/licenses/BSD-3-Clause New BSD License + * @version CVS: $Id$ * @link http://pear.php.net/package/Mail/ */ @@ -50,8 +52,7 @@ require_once 'PEAR.php'; * mailers under the PEAR hierarchy, and provides supporting functions * useful in multiple mailer backends. * - * @access public - * @version $Revision: 294747 $ + * @version $Revision$ * @package Mail */ class Mail @@ -60,7 +61,7 @@ class Mail * Line terminator used for separating header lines. * @var string */ - var $sep = "\r\n"; + public $sep = "\r\n"; /** * Provides an interface for generating Mail:: objects of various @@ -68,10 +69,10 @@ class Mail * * @param string $driver The kind of Mail:: object to instantiate. * @param array $params The parameters to pass to the Mail:: object. + * * @return object Mail a instance of the driver class or if fails a PEAR Error - * @access public */ - static function &factory($driver, $params = array()) + public static function factory($driver, $params = array()) { $driver = strtolower($driver); @include_once 'Mail/' . $driver . '.php'; @@ -108,10 +109,9 @@ class Mail * containing a descriptive error message on * failure. * - * @access public * @deprecated use Mail_mail::send instead */ - function send($recipients, $headers, $body) + public function send($recipients, $headers, $body) { if (!is_array($headers)) { return PEAR::raiseError('$headers must be an array'); @@ -147,10 +147,8 @@ class Mail * filter is to prevent mail injection attacks. * * @param array $headers The associative array of headers to sanitize. - * - * @access private */ - function _sanitizeHeaders(&$headers) + protected function _sanitizeHeaders(&$headers) { foreach ($headers as $key => $value) { $headers[$key] = @@ -177,9 +175,8 @@ class Mail * otherwise returns an array containing two * elements: Any From: address found in the headers, * and the plain text version of the headers. - * @access private */ - function prepareHeaders($headers) + protected function prepareHeaders($headers) { $lines = array(); $from = null; @@ -239,9 +236,8 @@ class Mail * * @return mixed An array of forward paths (bare addresses) or a PEAR_Error * object if the address list could not be parsed. - * @access private */ - function parseRecipients($recipients) + protected function parseRecipients($recipients) { include_once 'Mail/RFC822.php'; @@ -254,9 +250,8 @@ class Mail // Parse recipients, leaving out all personal info. This is // for smtp recipients, etc. All relevant personal information // should already be in the headers. - - $mail_object = new Mail_RFC822($recipients, 'localhost', false); - $addresses = $mail_object->parseAddressList(); + $Mail_RFC822 = new Mail_RFC822(); + $addresses = $Mail_RFC822->parseAddressList($recipients, 'localhost', false); // If parseAddressList() returned a PEAR_Error object, just return it. if (is_a($addresses, 'PEAR_Error')) { diff --git a/civicrm/packages/Mail/RFC822.php b/civicrm/vendor/pear/mail/Mail/RFC822.php similarity index 91% rename from civicrm/packages/Mail/RFC822.php rename to civicrm/vendor/pear/mail/Mail/RFC822.php index 8754c3d601..e0748f586e 100644 --- a/civicrm/packages/Mail/RFC822.php +++ b/civicrm/vendor/pear/mail/Mail/RFC822.php @@ -2,31 +2,33 @@ /** * RFC 822 Email address list validation Utility * - * PHP versions 4 and 5 + * PHP version 5 * * LICENSE: * - * Copyright (c) 2001-2010, Richard Heyes + * Copyright (c) 2001-2017, Chuck Hagenbuch & Richard Heyes * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * - * o Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * o Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * o The names of the authors may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY @@ -38,9 +40,9 @@ * @package Mail * @author Richard Heyes <richard@phpguru.org> * @author Chuck Hagenbuch <chuck@horde.org - * @copyright 2001-2010 Richard Heyes - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: RFC822.php 294749 2010-02-08 08:22:25Z clockwerx $ + * @copyright 2001-2017 Richard Heyes + * @license http://opensource.org/licenses/BSD-3-Clause New BSD License + * @version CVS: $Id$ * @link http://pear.php.net/package/Mail/ */ @@ -63,7 +65,7 @@ * * @author Richard Heyes <richard@phpguru.org> * @author Chuck Hagenbuch <chuck@horde.org> - * @version $Revision: 294749 $ + * @version $Revision$ * @license BSD * @package Mail */ @@ -141,7 +143,6 @@ class Mail_RFC822 { * Sets up the object. The address must either be set here or when * calling parseAddressList(). One or the other. * - * @access public * @param string $address The address(es) to validate. * @param string $default_domain Default domain/host etc. If not supplied, will be set to localhost. * @param boolean $nest_groups Whether to return the structure with groups nested for easier viewing. @@ -149,7 +150,7 @@ class Mail_RFC822 { * * @return object Mail_RFC822 A new Mail_RFC822 object. */ - function __construct($address = null, $default_domain = null, $nest_groups = null, $validate = null, $limit = null) + public function __construct($address = null, $default_domain = null, $nest_groups = null, $validate = null, $limit = null) { if (isset($address)) $this->address = $address; if (isset($default_domain)) $this->default_domain = $default_domain; @@ -162,7 +163,6 @@ class Mail_RFC822 { * Starts the whole process. The address must either be set here * or when creating the object. One or the other. * - * @access public * @param string $address The address(es) to validate. * @param string $default_domain Default domain/host etc. * @param boolean $nest_groups Whether to return the structure with groups nested for easier viewing. @@ -170,7 +170,7 @@ class Mail_RFC822 { * * @return array A structured array of addresses. */ - function parseAddressList($address = null, $default_domain = null, $nest_groups = null, $validate = null, $limit = null) + public function parseAddressList($address = null, $default_domain = null, $nest_groups = null, $validate = null, $limit = null) { if (!isset($this) || !isset($this->mailRFC822)) { $obj = new Mail_RFC822($address, $default_domain, $nest_groups, $validate, $limit); @@ -222,11 +222,10 @@ class Mail_RFC822 { /** * Splits an address into separate addresses. * - * @access private * @param string $address The addresses to split. * @return boolean Success or failure. */ - function _splitAddresses($address) + protected function _splitAddresses($address) { if (!empty($this->limit) && count($this->addresses) == $this->limit) { return ''; @@ -298,11 +297,10 @@ class Mail_RFC822 { /** * Checks for a group at the start of the string. * - * @access private * @param string $address The address to check. * @return boolean Whether or not there is a group at the start of the string. */ - function _isGroup($address) + protected function _isGroup($address) { // First comma not in quotes, angles or escaped: $parts = explode(',', $address); @@ -322,12 +320,11 @@ class Mail_RFC822 { /** * A common function that will check an exploded string. * - * @access private * @param array $parts The exloded string. * @param string $char The char that was exploded on. * @return mixed False if the string contains unclosed quotes/brackets, or the string on success. */ - function _splitCheck($parts, $char) + protected function _splitCheck($parts, $char) { $string = $parts[0]; @@ -355,12 +352,11 @@ class Mail_RFC822 { /** * Checks if a string has unclosed quotes or not. * - * @access private * @param string $string The string to check. * @return boolean True if there are unclosed quotes inside the string, * false otherwise. */ - function _hasUnclosedQuotes($string) + protected function _hasUnclosedQuotes($string) { $string = trim($string); $iMax = strlen($string); @@ -392,12 +388,11 @@ class Mail_RFC822 { * Checks if a string has an unclosed brackets or not. IMPORTANT: * This function handles both angle brackets and square brackets; * - * @access private * @param string $string The string to check. * @param string $chars The characters to check for. * @return boolean True if there are unclosed brackets inside the string, false otherwise. */ - function _hasUnclosedBrackets($string, $chars) + protected function _hasUnclosedBrackets($string, $chars) { $num_angle_start = substr_count($string, $chars[0]); $num_angle_end = substr_count($string, $chars[1]); @@ -416,13 +411,12 @@ class Mail_RFC822 { /** * Sub function that is used only by hasUnclosedBrackets(). * - * @access private * @param string $string The string to check. * @param integer &$num The number of occurences. * @param string $char The character to count. * @return integer The number of occurences of $char in $string, adjusted for backslashes. */ - function _hasUnclosedBracketsSub($string, &$num, $char) + protected function _hasUnclosedBracketsSub($string, &$num, $char) { $parts = explode($char, $string); for ($i = 0; $i < count($parts); $i++){ @@ -438,11 +432,10 @@ class Mail_RFC822 { /** * Function to begin checking the address. * - * @access private * @param string $address The address to validate. * @return mixed False on failure, or a structured array of address information on success. */ - function _validateAddress($address) + protected function _validateAddress($address) { $is_group = false; $addresses = array(); @@ -483,14 +476,6 @@ class Mail_RFC822 { $addresses[] = $address['address']; } - // Check that $addresses is set, if address like this: - // Groupname:; - // Then errors were appearing. - if (!count($addresses)){ - $this->error = 'Empty group.'; - return false; - } - // Trim the whitespace from all of the address strings. array_map('trim', $addresses); @@ -531,11 +516,10 @@ class Mail_RFC822 { /** * Function to validate a phrase. * - * @access private * @param string $phrase The phrase to check. * @return boolean Success or failure. */ - function _validatePhrase($phrase) + protected function _validatePhrase($phrase) { // Splits on one or more Tab or space. $parts = preg_split('/[ \\x09]+/', $phrase, -1, PREG_SPLIT_NO_EMPTY); @@ -572,11 +556,10 @@ class Mail_RFC822 { * can split a list of addresses up before encoding personal names * (umlauts, etc.), for example. * - * @access private * @param string $atom The string to check. * @return boolean Success or failure. */ - function _validateAtom($atom) + protected function _validateAtom($atom) { if (!$this->validate) { // Validation has been turned off; assume the atom is okay. @@ -605,11 +588,10 @@ class Mail_RFC822 { * Function to validate quoted string, which is: * quoted-string = <"> *(qtext/quoted-pair) <"> * - * @access private * @param string $qstring The string to check * @return boolean Success or failure. */ - function _validateQuotedString($qstring) + protected function _validateQuotedString($qstring) { // Leading and trailing " $qstring = substr($qstring, 1, -1); @@ -623,11 +605,10 @@ class Mail_RFC822 { * mailbox = addr-spec ; simple address * / phrase route-addr ; name and route-addr * - * @access public * @param string &$mailbox The string to check. * @return boolean Success or failure. */ - function validateMailbox(&$mailbox) + public function validateMailbox(&$mailbox) { // A couple of defaults. $phrase = ''; @@ -712,11 +693,10 @@ class Mail_RFC822 { * Angle brackets have already been removed at the point of * getting to this function. * - * @access private * @param string $route_addr The string to check. * @return mixed False on failure, or an array containing validated address/route information on success. */ - function _validateRouteAddr($route_addr) + protected function _validateRouteAddr($route_addr) { // Check for colon. if (strpos($route_addr, ':') !== false) { @@ -762,11 +742,10 @@ class Mail_RFC822 { * Function to validate a route, which is: * route = 1#("@" domain) ":" * - * @access private * @param string $route The string to check. * @return mixed False on failure, or the validated $route on success. */ - function _validateRoute($route) + protected function _validateRoute($route) { // Split on comma. $domains = explode(',', trim($route)); @@ -785,11 +764,10 @@ class Mail_RFC822 { * * domain = sub-domain *("." sub-domain) * - * @access private * @param string $domain The string to check. * @return mixed False on failure, or the validated domain on success. */ - function _validateDomain($domain) + protected function _validateDomain($domain) { // Note the different use of $subdomains and $sub_domains $subdomains = explode('.', $domain); @@ -813,11 +791,10 @@ class Mail_RFC822 { * Function to validate a subdomain: * subdomain = domain-ref / domain-literal * - * @access private * @param string $subdomain The string to check. * @return boolean Success or failure. */ - function _validateSubdomain($subdomain) + protected function _validateSubdomain($subdomain) { if (preg_match('|^\[(.*)]$|', $subdomain, $arr)){ if (!$this->_validateDliteral($arr[1])) return false; @@ -833,13 +810,12 @@ class Mail_RFC822 { * Function to validate a domain literal: * domain-literal = "[" *(dtext / quoted-pair) "]" * - * @access private * @param string $dliteral The string to check. * @return boolean Success or failure. */ - function _validateDliteral($dliteral) + protected function _validateDliteral($dliteral) { - return !preg_match('/(.)[][\x0D\\\\]/', $dliteral, $matches) && $matches[1] != '\\'; + return !preg_match('/(.)[][\x0D\\\\]/', $dliteral, $matches) && ((! isset($matches[1])) || $matches[1] != '\\'); } /** @@ -847,11 +823,10 @@ class Mail_RFC822 { * * addr-spec = local-part "@" domain * - * @access private * @param string $addr_spec The string to check. * @return mixed False on failure, or the validated addr-spec on success. */ - function _validateAddrSpec($addr_spec) + protected function _validateAddrSpec($addr_spec) { $addr_spec = trim($addr_spec); @@ -878,17 +853,16 @@ class Mail_RFC822 { * Function to validate the local part of an address: * local-part = word *("." word) * - * @access private * @param string $local_part * @return mixed False on failure, or the validated local part on success. */ - function _validateLocalPart($local_part) + protected function _validateLocalPart($local_part) { $parts = explode('.', $local_part); $words = array(); // Split the local_part into words. - while (count($parts) > 0){ + while (count($parts) > 0) { $words[] = $this->_splitCheck($parts, '.'); for ($i = 0; $i < $this->index + 1; $i++) { array_shift($parts); @@ -897,6 +871,10 @@ class Mail_RFC822 { // Validate each word. foreach ($words as $word) { + // word cannot be empty (#17317) + if ($word === '') { + return false; + } // If this word contains an unquoted space, it is invalid. (6.2.4) if (strpos($word, ' ') && $word[0] !== '"') { @@ -920,7 +898,7 @@ class Mail_RFC822 { * @param string $data Addresses to count * @return int Approximate count */ - function approximateCount($data) + public function approximateCount($data) { return count(preg_split('/(?<!\\\\),/', $data)); } @@ -938,7 +916,7 @@ class Mail_RFC822 { * @return mixed False if it fails, an indexed array * username/domain if it matches */ - function isValidInetAddress($data, $strict = false) + public function isValidInetAddress($data, $strict = false) { $regex = $strict ? '/^([.0-9a-z_+-]+)@(([0-9a-z-]+\.)+[0-9a-z]{2,})$/i' : '/^([*+!.&#$|\'\\%\/0-9a-z^_`{}=?~:-]+)@(([0-9a-z-]+\.)+[0-9a-z]{2,})$/i'; if (preg_match($regex, trim($data), $matches)) { diff --git a/civicrm/packages/Mail/mail.php b/civicrm/vendor/pear/mail/Mail/mail.php similarity index 80% rename from civicrm/packages/Mail/mail.php rename to civicrm/vendor/pear/mail/Mail/mail.php index 1c6ee09ea9..ae6e2e8fb6 100644 --- a/civicrm/packages/Mail/mail.php +++ b/civicrm/vendor/pear/mail/Mail/mail.php @@ -2,31 +2,33 @@ /** * internal PHP-mail() implementation of the PEAR Mail:: interface. * - * PHP versions 4 and 5 + * PHP version 5 * * LICENSE: * - * Copyright (c) 2010 Chuck Hagenbuch + * Copyright (c) 2010-2017, Chuck Hagenbuch * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * - * o Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * o Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * o The names of the authors may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY @@ -37,16 +39,16 @@ * @category Mail * @package Mail * @author Chuck Hagenbuch <chuck@horde.org> - * @copyright 2010 Chuck Hagenbuch - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: mail.php 294747 2010-02-08 08:18:33Z clockwerx $ + * @copyright 2010-2017 Chuck Hagenbuch + * @license http://opensource.org/licenses/BSD-3-Clause New BSD License + * @version CVS: $Id$ * @link http://pear.php.net/package/Mail/ */ /** * internal PHP-mail() implementation of the PEAR Mail:: interface. * @package Mail - * @version $Revision: 294747 $ + * @version $Revision$ */ class Mail_mail extends Mail { @@ -64,7 +66,7 @@ class Mail_mail extends Mail { * * @param array $params Extra arguments for the mail() function. */ - function __construct($params = null) + public function __construct($params = null) { // The other mail implementations accept parameters as arrays. // In the interest of being consistent, explode an array into @@ -109,17 +111,15 @@ class Mail_mail extends Mail { * @return mixed Returns true on success, or a PEAR_Error * containing a descriptive error message on * failure. - * - * @access public */ - function send($recipients, $headers, $body) + public function send($recipients, $headers, $body) { if (defined('CIVICRM_MAIL_LOG')) { - CRM_Utils_Mail::logger($recipients, $headers, $body); - // Note: "CIVICRM_MAIL_LOG_AND SEND" (space not underscore) was a typo that existed for some years, so kept here for compatibility, but it should not be used. - if(!defined('CIVICRM_MAIL_LOG_AND_SEND') && !defined('CIVICRM_MAIL_LOG_AND SEND')) { - return true; - } + CRM_Utils_Mail::logger($recipients, $headers, $body); + // Note: "CIVICRM_MAIL_LOG_AND SEND" (space not underscore) was a typo that existed for some years, so kept here for compatibility, but it should not be used. + if (!defined('CIVICRM_MAIL_LOG_AND_SEND') && !defined('CIVICRM_MAIL_LOG_AND SEND')) { + return true; + } } if (!is_array($headers)) { @@ -154,7 +154,6 @@ class Mail_mail extends Mail { return $headerElements; } list($from, $text_headers) = $headerElements; - // use Return-Path for SMTP envelope’s FROM address (if set), CRM-5946 if (!empty($headers['Return-Path'])) { $from = $headers['Return-Path']; diff --git a/civicrm/packages/Mail/mock.php b/civicrm/vendor/pear/mail/Mail/mock.php similarity index 77% rename from civicrm/packages/Mail/mock.php rename to civicrm/vendor/pear/mail/Mail/mock.php index a1bf9b803d..24d46a8555 100644 --- a/civicrm/packages/Mail/mock.php +++ b/civicrm/vendor/pear/mail/Mail/mock.php @@ -2,31 +2,33 @@ /** * Mock implementation * - * PHP versions 4 and 5 + * PHP version 5 * * LICENSE: * - * Copyright (c) 2010 Chuck Hagenbuch + * Copyright (c) 2010-2017, Chuck Hagenbuch * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * - * o Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * o Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * o The names of the authors may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY @@ -37,9 +39,9 @@ * @category Mail * @package Mail * @author Chuck Hagenbuch <chuck@horde.org> - * @copyright 2010 Chuck Hagenbuch - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: mock.php 294747 2010-02-08 08:18:33Z clockwerx $ + * @copyright 2010-2017 Chuck Hagenbuch + * @license http://opensource.org/licenses/BSD-3-Clause New BSD License + * @version CVS: $Id$ * @link http://pear.php.net/package/Mail/ */ @@ -47,7 +49,7 @@ * Mock implementation of the PEAR Mail:: interface for testing. * @access public * @package Mail - * @version $Revision: 294747 $ + * @version $Revision$ */ class Mail_mock extends Mail { @@ -55,23 +57,22 @@ class Mail_mock extends Mail { * Array of messages that have been sent with the mock. * * @var array - * @access public */ - var $sentMessages = array(); + public $sentMessages = array(); /** * Callback before sending mail. * * @var callback */ - var $_preSendCallback; + protected $_preSendCallback; /** * Callback after sending mai. * * @var callback */ - var $_postSendCallback; + protected $_postSendCallback; /** * Constructor. @@ -82,9 +83,8 @@ class Mail_mock extends Mail { * postSendCallback Called after an email would have been sent. * * @param array Hash containing any parameters. - * @access public */ - function __construct($params) + public function __construct($params) { if (isset($params['preSendCallback']) && is_callable($params['preSendCallback'])) { @@ -120,9 +120,8 @@ class Mail_mock extends Mail { * @return mixed Returns true on success, or a PEAR_Error * containing a descriptive error message on * failure. - * @access public */ - function send($recipients, $headers, $body) + public function send($recipients, $headers, $body) { if ($this->_preSendCallback) { call_user_func_array($this->_preSendCallback, diff --git a/civicrm/packages/Mail/null.php b/civicrm/vendor/pear/mail/Mail/null.php similarity index 71% rename from civicrm/packages/Mail/null.php rename to civicrm/vendor/pear/mail/Mail/null.php index f8d58272ee..5e3ecb6f97 100644 --- a/civicrm/packages/Mail/null.php +++ b/civicrm/vendor/pear/mail/Mail/null.php @@ -2,31 +2,33 @@ /** * Null implementation of the PEAR Mail interface * - * PHP versions 4 and 5 + * PHP version 5 * * LICENSE: * - * Copyright (c) 2010 Phil Kernick + * Copyright (c) 2010-2017, Phil Kernick * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * - * o Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * o Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * o The names of the authors may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY @@ -37,9 +39,9 @@ * @category Mail * @package Mail * @author Phil Kernick <philk@rotfl.com.au> - * @copyright 2010 Phil Kernick - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: null.php 294747 2010-02-08 08:18:33Z clockwerx $ + * @copyright 2010-2017 Phil Kernick + * @license http://opensource.org/licenses/BSD-3-Clause New BSD License + * @version CVS: $Id$ * @link http://pear.php.net/package/Mail/ */ @@ -47,7 +49,7 @@ * Null implementation of the PEAR Mail:: interface. * @access public * @package Mail - * @version $Revision: 294747 $ + * @version $Revision$ */ class Mail_null extends Mail { @@ -74,9 +76,8 @@ class Mail_null extends Mail { * @return mixed Returns true on success, or a PEAR_Error * containing a descriptive error message on * failure. - * @access public */ - function send($recipients, $headers, $body) + public function send($recipients, $headers, $body) { return true; } diff --git a/civicrm/packages/Mail/sendmail.php b/civicrm/vendor/pear/mail/Mail/sendmail.php similarity index 68% rename from civicrm/packages/Mail/sendmail.php rename to civicrm/vendor/pear/mail/Mail/sendmail.php index c6e642620f..e0300a0b05 100644 --- a/civicrm/packages/Mail/sendmail.php +++ b/civicrm/vendor/pear/mail/Mail/sendmail.php @@ -1,26 +1,56 @@ <?php -// -// +----------------------------------------------------------------------+ -// | PHP Version 4 | -// +----------------------------------------------------------------------+ -// | Copyright (c) 1997-2003 The PHP Group | -// +----------------------------------------------------------------------+ -// | This source file is subject to version 2.02 of the PHP license, | -// | that is bundled with this package in the file LICENSE, and is | -// | available at through the world-wide-web at | -// | http://www.php.net/license/2_02.txt. | -// | If you did not receive a copy of the PHP license and are unable to | -// | obtain it through the world-wide-web, please send a note to | -// | license@php.net so we can mail you a copy immediately. | -// +----------------------------------------------------------------------+ -// | Author: Chuck Hagenbuch <chuck@horde.org> | -// +----------------------------------------------------------------------+ +/** + * Sendmail implementation of the PEAR Mail interface. + * + * PHP version 5 + * + * LICENSE: + * + * Copyright (c) 2010-2017, Chuck Hagenbuch & Jon Parise + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * @category Mail + * @package Mail + * @author Jon Parise <jon@php.net> + * @author Chuck Hagenbuch <chuck@horde.org> + * @copyright 2010-2017 Chuck Hagenbuch + * @license http://opensource.org/licenses/BSD-3-Clause New BSD License + * @version CVS: $Id$ + * @link http://pear.php.net/package/Mail/ + */ /** * Sendmail implementation of the PEAR Mail:: interface. * @access public * @package Mail - * @version $Revision: 294744 $ + * @version $Revision$ */ class Mail_sendmail extends Mail { @@ -54,9 +84,8 @@ class Mail_sendmail extends Mail { * * @param array $params Hash containing any parameters different from the * defaults. - * @access public */ - function __construct($params) + public function __construct($params) { if (isset($params['sendmail_path'])) { $this->sendmail_path = $params['sendmail_path']; @@ -100,16 +129,15 @@ class Mail_sendmail extends Mail { * @return mixed Returns true on success, or a PEAR_Error * containing a descriptive error message on * failure. - * @access public */ - function send($recipients, $headers, $body) + public function send($recipients, $headers, $body) { if (defined('CIVICRM_MAIL_LOG')) { - CRM_Utils_Mail::logger($recipients, $headers, $body); - // Note: "CIVICRM_MAIL_LOG_AND SEND" (space not underscore) was a typo that existed for some years, so kept here for compatibility, but it should not be used. - if(!defined('CIVICRM_MAIL_LOG_AND_SEND') && !defined('CIVICRM_MAIL_LOG_AND SEND')) { - return true; - } + CRM_Utils_Mail::logger($recipients, $headers, $body); + // Note: "CIVICRM_MAIL_LOG_AND SEND" (space not underscore) was a typo that existed for some years, so kept here for compatibility, but it should not be used. + if (!defined('CIVICRM_MAIL_LOG_AND_SEND') && !defined('CIVICRM_MAIL_LOG_AND SEND')) { + return true; + } } if (!is_array($headers)) { diff --git a/civicrm/packages/Mail/smtp.php b/civicrm/vendor/pear/mail/Mail/smtp.php similarity index 82% rename from civicrm/packages/Mail/smtp.php rename to civicrm/vendor/pear/mail/Mail/smtp.php index bda1acfd1c..5f057e2a8b 100644 --- a/civicrm/packages/Mail/smtp.php +++ b/civicrm/vendor/pear/mail/Mail/smtp.php @@ -2,31 +2,33 @@ /** * SMTP implementation of the PEAR Mail interface. Requires the Net_SMTP class. * - * PHP versions 4 and 5 + * PHP version 5 * * LICENSE: * - * Copyright (c) 2010, Chuck Hagenbuch + * Copyright (c) 2010-2017, Chuck Hagenbuch & Jon Parise * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * - * o Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * o Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * o The names of the authors may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY @@ -38,9 +40,9 @@ * @package HTTP_Request * @author Jon Parise <jon@php.net> * @author Chuck Hagenbuch <chuck@horde.org> - * @copyright 2010 Chuck Hagenbuch - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: smtp.php 294747 2010-02-08 08:18:33Z clockwerx $ + * @copyright 2010-2017 Chuck Hagenbuch + * @license http://opensource.org/licenses/BSD-3-Clause New BSD License + * @version CVS: $Id$ * @link http://pear.php.net/package/Mail/ */ @@ -69,7 +71,7 @@ define('PEAR_MAIL_SMTP_ERROR_DATA', 10006); * SMTP implementation of the PEAR Mail interface. Requires the Net_SMTP class. * @access public * @package Mail - * @version $Revision: 294747 $ + * @version $Revision$ */ class Mail_smtp extends Mail { @@ -84,18 +86,21 @@ class Mail_smtp extends Mail { /** * The list of service extension parameters to pass to the Net_SMTP * mailFrom() command. + * * @var array */ var $_extparams = array(); /** * The SMTP host to connect to. + * * @var string */ var $host = 'localhost'; /** * The port the SMTP server is on. + * * @var integer */ var $port = 25; @@ -115,12 +120,14 @@ class Mail_smtp extends Mail { /** * The username to use if the SMTP server requires authentication. + * * @var string */ var $username = ''; /** * The password to use if the SMTP server requires authentication. + * * @var string */ var $password = ''; @@ -159,10 +166,18 @@ class Mail_smtp extends Mail { * Use SMTP command pipelining (specified in RFC 2920) if the SMTP server * supports it. This speeds up delivery over high-latency connections. By * default, use the default value supplied by Net_SMTP. - * @var bool + * + * @var boolean */ var $pipelining; + /** + * The list of socket options + * + * @var array + */ + var $socket_options = array(); + /** * Constructor. * @@ -186,9 +201,8 @@ class Mail_smtp extends Mail { * * @param array Hash containing any parameters different from the * defaults. - * @access public */ - function __construct($params) + public function __construct($params) { if (isset($params['host'])) $this->host = $params['host']; if (isset($params['port'])) $this->port = $params['port']; @@ -200,20 +214,18 @@ class Mail_smtp extends Mail { if (isset($params['debug'])) $this->debug = (bool)$params['debug']; if (isset($params['persist'])) $this->persist = (bool)$params['persist']; if (isset($params['pipelining'])) $this->pipelining = (bool)$params['pipelining']; - + if (isset($params['socket_options'])) $this->socket_options = $params['socket_options']; // Deprecated options if (isset($params['verp'])) { $this->addServiceExtensionParameter('XVERP', is_bool($params['verp']) ? null : $params['verp']); } - - register_shutdown_function(array(&$this, '_Mail_smtp')); } /** * Destructor implementation to ensure that we disconnect from any * potentially-alive persistent SMTP connections. */ - function _Mail_smtp() + public function __destruct() { $this->disconnect(); } @@ -240,20 +252,31 @@ class Mail_smtp extends Mail { * @return mixed Returns true on success, or a PEAR_Error * containing a descriptive error message on * failure. - * @access public */ - function send($recipients, $headers, $body) + public function send($recipients, $headers, $body) { if (defined('CIVICRM_MAIL_LOG')) { - CRM_Utils_Mail::logger($recipients, $headers, $body); - // Note: "CIVICRM_MAIL_LOG_AND SEND" (space not underscore) was a typo that existed for some years, so kept here for compatibility, but it should not be used. - if(!defined('CIVICRM_MAIL_LOG_AND_SEND') && !defined('CIVICRM_MAIL_LOG_AND SEND')) { - return true; - } + CRM_Utils_Mail::logger($recipients, $headers, $body); + // Note: "CIVICRM_MAIL_LOG_AND SEND" (space not underscore) was a typo that existed for some years, so kept here for compatibility, but it should not be used. + if (!defined('CIVICRM_MAIL_LOG_AND_SEND') && !defined('CIVICRM_MAIL_LOG_AND SEND')) { + return true; + } } + $result = $this->send_or_fail($recipients, $headers, $body); + + /* If persistent connections are disabled, destroy our SMTP object. */ + if ($this->persist === false) { + $this->disconnect(); + } + + return $result; + } + + protected function send_or_fail($recipients, $headers, $body) + { /* If we don't already have an SMTP object, create one. */ - $result = &$this->getSMTPObject(); + $result = $this->getSMTPObject(); if (PEAR::isError($result)) { return $result; } @@ -312,16 +335,16 @@ class Mail_smtp extends Mail { } /* Send the message's headers and the body as SMTP data. */ - $res = $this->_smtp->data($textHeaders . "\r\n\r\n" . $body); - list(,$args) = $this->_smtp->getResponse(); + $res = $this->_smtp->data($body, $textHeaders); + list(,$args) = $this->_smtp->getResponse(); - if (preg_match("/Ok: queued as (.*)/", $args, $queued)) { - $this->queued_as = $queued[1]; - } + if (preg_match("/ queued as (.*)/", $args, $queued)) { + $this->queued_as = $queued[1]; + } - /* we need the greeting; from it we can extract the authorative name of the mail server we've really connected to. - * ideal if we're connecting to a round-robin of relay servers and need to track which exact one took the email */ - $this->greeting = $this->_smtp->getGreeting(); + /* we need the greeting; from it we can extract the authorative name of the mail server we've really connected to. + * ideal if we're connecting to a round-robin of relay servers and need to track which exact one took the email */ + $this->greeting = $this->_smtp->getGreeting(); if (is_a($res, 'PEAR_Error')) { $error = $this->_error('Failed to send data', $res); @@ -329,11 +352,6 @@ class Mail_smtp extends Mail { return PEAR::raiseError($error, PEAR_MAIL_SMTP_ERROR_DATA); } - /* If persistent connections are disabled, destroy our SMTP object. */ - if ($this->persist === false) { - $this->disconnect(); - } - return true; } @@ -345,9 +363,8 @@ class Mail_smtp extends Mail { * failure. * * @since 1.2.0 - * @access public */ - function &getSMTPObject() + public function getSMTPObject() { if (is_object($this->_smtp) !== false) { return $this->_smtp; @@ -356,7 +373,10 @@ class Mail_smtp extends Mail { include_once 'Net/SMTP.php'; $this->_smtp = new Net_SMTP($this->host, $this->port, - $this->localhost); + $this->localhost, + $this->pipelining, + 0, + $this->socket_options); /* If we still don't have an SMTP object at this point, fail. */ if (is_object($this->_smtp) === false) { @@ -401,9 +421,8 @@ class Mail_smtp extends Mail { * @param string Any value the keyword needs. * * @since 1.2.0 - * @access public */ - function addServiceExtensionParameter($keyword, $value = null) + public function addServiceExtensionParameter($keyword, $value = null) { $this->_extparams[$keyword] = $value; } @@ -414,9 +433,8 @@ class Mail_smtp extends Mail { * @return boolean True if the SMTP connection no longer exists. * * @since 1.1.9 - * @access public */ - function disconnect() + public function disconnect() { /* If we have an SMTP object, disconnect and destroy it. */ if (is_object($this->_smtp) && $this->_smtp->disconnect()) { @@ -436,9 +454,8 @@ class Mail_smtp extends Mail { * @return string A string describing the current SMTP error. * * @since 1.1.7 - * @access private */ - function _error($text, &$error) + protected function _error($text, $error) { /* Split the SMTP response into a code and a response string. */ list($code, $response) = $this->_smtp->getResponse(); diff --git a/civicrm/packages/Mail/smtpmx.php b/civicrm/vendor/pear/mail/Mail/smtpmx.php similarity index 93% rename from civicrm/packages/Mail/smtpmx.php rename to civicrm/vendor/pear/mail/Mail/smtpmx.php index 3f738ac8c2..e26db1be80 100644 --- a/civicrm/packages/Mail/smtpmx.php +++ b/civicrm/vendor/pear/mail/Mail/smtpmx.php @@ -1,4 +1,4 @@ -<?PHP +<?php /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ /** @@ -6,31 +6,33 @@ * * SMTP MX implementation of the PEAR Mail interface. Requires the Net_SMTP class. * - * PHP versions 4 and 5 + * PHP version 5 * * LICENSE: * - * Copyright (c) 2010, gERD Schaufelberger + * Copyright (c) 2010-2017 gERD Schaufelberger * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * - * o Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * o Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * o The names of the authors may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY @@ -41,9 +43,9 @@ * @category Mail * @package Mail_smtpmx * @author gERD Schaufelberger <gerd@php-tools.net> - * @copyright 2010 gERD Schaufelberger - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: smtpmx.php 294747 2010-02-08 08:18:33Z clockwerx $ + * @copyright 2010-2017 gERD Schaufelberger + * @license http://opensource.org/licenses/BSD-3-Clause New BSD License + * @version CVS: $Id$ * @link http://pear.php.net/package/Mail/ */ @@ -56,7 +58,7 @@ require_once 'Net/SMTP.php'; * @access public * @author gERD Schaufelberger <gerd@php-tools.net> * @package Mail - * @version $Revision: 294747 $ + * @version $Revision$ */ class Mail_smtpmx extends Mail { @@ -243,12 +245,12 @@ class Mail_smtpmx extends Mail { * @access public * @param array Hash containing any parameters different from the defaults * @see __construct() - * + */ function Mail_smtpmx($params) { $this->__construct($params); register_shutdown_function(array(&$this, '__destruct')); - }*/ + } /** * Destructor implementation to ensure that we disconnect from any @@ -386,7 +388,7 @@ class Mail_smtpmx extends Mail { } // Send data - $res = $this->_smtp->data("$textHeaders\r\n$body"); + $res = $this->_smtp->data($body, $textHeaders); if (is_a($res, 'PEAR_Error')) { $info = array('rcpt' => $rcpt); return $this->_raiseError('failed_send_data', $info); diff --git a/civicrm/vendor/pear/mail/composer.json b/civicrm/vendor/pear/mail/composer.json new file mode 100644 index 0000000000..a167cc6660 --- /dev/null +++ b/civicrm/vendor/pear/mail/composer.json @@ -0,0 +1,46 @@ +{ + "authors": [ + { + "email": "chuck@horde.org", + "name": "Chuck Hagenbuch", + "role": "Lead" + }, + { + "email": "richard@phpguru.org", + "name": "Richard Heyes", + "role": "Developer" + }, + { + "email": "alec@alec.pl", + "name": "Aleksander Machniak", + "role": "Developer" + } + ], + "autoload": { + "psr-0": { + "Mail": "./" + } + }, + "description": "Class that provides multiple interfaces for sending emails.", + "homepage": "http://pear.php.net/package/Mail", + "include-path": [ + "./" + ], + "license": "BSD-2-Clause", + "name": "pear/mail", + "support": { + "issues": "http://pear.php.net/bugs/search.php?cmd=display&package_name[]=Mail", + "source": "https://github.com/pear/Mail" + }, + "type": "library", + "require": { + "php": ">=5.2.1", + "pear/pear-core-minimal": "~1.9" + }, + "require-dev": { + "pear/pear": "*" + }, + "suggest": { + "pear/net_smtp": "Install optionally via your project's composer.json" + } +} diff --git a/civicrm/vendor/pear/pear-core-minimal/composer.json b/civicrm/vendor/pear/pear-core-minimal/composer.json new file mode 100644 index 0000000000..d805f56ae8 --- /dev/null +++ b/civicrm/vendor/pear/pear-core-minimal/composer.json @@ -0,0 +1,32 @@ +{ + "name": "pear/pear-core-minimal", + "description": "Minimal set of PEAR core files to be used as composer dependency", + "license": "BSD-3-Clause", + "authors": [ + { + "email": "cweiske@php.net", + "name": "Christian Weiske", + "role": "Lead" + } + ], + "autoload": { + "psr-0": { + "": "src/" + } + }, + "include-path": [ + "src/" + ], + "support": { + "issues": "http://pear.php.net/bugs/search.php?cmd=display&package_name[]=PEAR", + "source": "https://github.com/pear/pear-core-minimal" + }, + "type": "library", + "require": { + "pear/console_getopt": "~1.4", + "pear/pear_exception": "~1.0" + }, + "replace": { + "rsky/pear-core-min": "self.version" + } +} diff --git a/civicrm/vendor/pear/pear-core-minimal/src/OS/Guess.php b/civicrm/vendor/pear/pear-core-minimal/src/OS/Guess.php new file mode 100644 index 0000000000..c45e84f155 --- /dev/null +++ b/civicrm/vendor/pear/pear-core-minimal/src/OS/Guess.php @@ -0,0 +1,337 @@ +<?php +/** + * The OS_Guess class + * + * PHP versions 4 and 5 + * + * @category pear + * @package PEAR + * @author Stig Bakken <ssb@php.net> + * @author Gregory Beaver <cellog@php.net> + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @link http://pear.php.net/package/PEAR + * @since File available since PEAR 0.1 + */ + +// {{{ uname examples + +// php_uname() without args returns the same as 'uname -a', or a PHP-custom +// string for Windows. +// PHP versions prior to 4.3 return the uname of the host where PHP was built, +// as of 4.3 it returns the uname of the host running the PHP code. +// +// PC RedHat Linux 7.1: +// Linux host.example.com 2.4.2-2 #1 Sun Apr 8 20:41:30 EDT 2001 i686 unknown +// +// PC Debian Potato: +// Linux host 2.4.17 #2 SMP Tue Feb 12 15:10:04 CET 2002 i686 unknown +// +// PC FreeBSD 3.3: +// FreeBSD host.example.com 3.3-STABLE FreeBSD 3.3-STABLE #0: Mon Feb 21 00:42:31 CET 2000 root@example.com:/usr/src/sys/compile/CONFIG i386 +// +// PC FreeBSD 4.3: +// FreeBSD host.example.com 4.3-RELEASE FreeBSD 4.3-RELEASE #1: Mon Jun 25 11:19:43 EDT 2001 root@example.com:/usr/src/sys/compile/CONFIG i386 +// +// PC FreeBSD 4.5: +// FreeBSD host.example.com 4.5-STABLE FreeBSD 4.5-STABLE #0: Wed Feb 6 23:59:23 CET 2002 root@example.com:/usr/src/sys/compile/CONFIG i386 +// +// PC FreeBSD 4.5 w/uname from GNU shellutils: +// FreeBSD host.example.com 4.5-STABLE FreeBSD 4.5-STABLE #0: Wed Feb i386 unknown +// +// HP 9000/712 HP-UX 10: +// HP-UX iq B.10.10 A 9000/712 2008429113 two-user license +// +// HP 9000/712 HP-UX 10 w/uname from GNU shellutils: +// HP-UX host B.10.10 A 9000/712 unknown +// +// IBM RS6000/550 AIX 4.3: +// AIX host 3 4 000003531C00 +// +// AIX 4.3 w/uname from GNU shellutils: +// AIX host 3 4 000003531C00 unknown +// +// SGI Onyx IRIX 6.5 w/uname from GNU shellutils: +// IRIX64 host 6.5 01091820 IP19 mips +// +// SGI Onyx IRIX 6.5: +// IRIX64 host 6.5 01091820 IP19 +// +// SparcStation 20 Solaris 8 w/uname from GNU shellutils: +// SunOS host.example.com 5.8 Generic_108528-12 sun4m sparc +// +// SparcStation 20 Solaris 8: +// SunOS host.example.com 5.8 Generic_108528-12 sun4m sparc SUNW,SPARCstation-20 +// +// Mac OS X (Darwin) +// Darwin home-eden.local 7.5.0 Darwin Kernel Version 7.5.0: Thu Aug 5 19:26:16 PDT 2004; root:xnu/xnu-517.7.21.obj~3/RELEASE_PPC Power Macintosh +// +// Mac OS X early versions +// + +// }}} + +/* TODO: + * - define endianness, to allow matchSignature("bigend") etc. + */ + +/** + * Retrieves information about the current operating system + * + * This class uses php_uname() to grok information about the current OS + * + * @category pear + * @package PEAR + * @author Stig Bakken <ssb@php.net> + * @author Gregory Beaver <cellog@php.net> + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: @package_version@ + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 0.1 + */ +class OS_Guess +{ + var $sysname; + var $nodename; + var $cpu; + var $release; + var $extra; + + function __construct($uname = null) + { + list($this->sysname, + $this->release, + $this->cpu, + $this->extra, + $this->nodename) = $this->parseSignature($uname); + } + + function parseSignature($uname = null) + { + static $sysmap = array( + 'HP-UX' => 'hpux', + 'IRIX64' => 'irix', + ); + static $cpumap = array( + 'i586' => 'i386', + 'i686' => 'i386', + 'ppc' => 'powerpc', + ); + if ($uname === null) { + $uname = php_uname(); + } + $parts = preg_split('/\s+/', trim($uname)); + $n = count($parts); + + $release = $machine = $cpu = ''; + $sysname = $parts[0]; + $nodename = $parts[1]; + $cpu = $parts[$n-1]; + $extra = ''; + if ($cpu == 'unknown') { + $cpu = $parts[$n - 2]; + } + + switch ($sysname) { + case 'AIX' : + $release = "$parts[3].$parts[2]"; + break; + case 'Windows' : + switch ($parts[1]) { + case '95/98': + $release = '9x'; + break; + default: + $release = $parts[1]; + break; + } + $cpu = 'i386'; + break; + case 'Linux' : + $extra = $this->_detectGlibcVersion(); + // use only the first two digits from the kernel version + $release = preg_replace('/^([0-9]+\.[0-9]+).*/', '\1', $parts[2]); + break; + case 'Mac' : + $sysname = 'darwin'; + $nodename = $parts[2]; + $release = $parts[3]; + if ($cpu == 'Macintosh') { + if ($parts[$n - 2] == 'Power') { + $cpu = 'powerpc'; + } + } + break; + case 'Darwin' : + if ($cpu == 'Macintosh') { + if ($parts[$n - 2] == 'Power') { + $cpu = 'powerpc'; + } + } + $release = preg_replace('/^([0-9]+\.[0-9]+).*/', '\1', $parts[2]); + break; + default: + $release = preg_replace('/-.*/', '', $parts[2]); + break; + } + + if (isset($sysmap[$sysname])) { + $sysname = $sysmap[$sysname]; + } else { + $sysname = strtolower($sysname); + } + if (isset($cpumap[$cpu])) { + $cpu = $cpumap[$cpu]; + } + return array($sysname, $release, $cpu, $extra, $nodename); + } + + function _detectGlibcVersion() + { + static $glibc = false; + if ($glibc !== false) { + return $glibc; // no need to run this multiple times + } + $major = $minor = 0; + include_once "System.php"; + // Use glibc's <features.h> header file to + // get major and minor version number: + if (@file_exists('/usr/include/features.h') && + @is_readable('/usr/include/features.h')) { + if (!@file_exists('/usr/bin/cpp') || !@is_executable('/usr/bin/cpp')) { + $features_file = fopen('/usr/include/features.h', 'rb'); + while (!feof($features_file)) { + $line = fgets($features_file, 8192); + if (!$line || (strpos($line, '#define') === false)) { + continue; + } + if (strpos($line, '__GLIBC__')) { + // major version number #define __GLIBC__ version + $line = preg_split('/\s+/', $line); + $glibc_major = trim($line[2]); + if (isset($glibc_minor)) { + break; + } + continue; + } + + if (strpos($line, '__GLIBC_MINOR__')) { + // got the minor version number + // #define __GLIBC_MINOR__ version + $line = preg_split('/\s+/', $line); + $glibc_minor = trim($line[2]); + if (isset($glibc_major)) { + break; + } + continue; + } + } + fclose($features_file); + if (!isset($glibc_major) || !isset($glibc_minor)) { + return $glibc = ''; + } + return $glibc = 'glibc' . trim($glibc_major) . "." . trim($glibc_minor) ; + } // no cpp + + $tmpfile = System::mktemp("glibctest"); + $fp = fopen($tmpfile, "w"); + fwrite($fp, "#include <features.h>\n__GLIBC__ __GLIBC_MINOR__\n"); + fclose($fp); + $cpp = popen("/usr/bin/cpp $tmpfile", "r"); + while ($line = fgets($cpp, 1024)) { + if ($line{0} == '#' || trim($line) == '') { + continue; + } + + if (list($major, $minor) = explode(' ', trim($line))) { + break; + } + } + pclose($cpp); + unlink($tmpfile); + } // features.h + + if (!($major && $minor) && @is_link('/lib/libc.so.6')) { + // Let's try reading the libc.so.6 symlink + if (preg_match('/^libc-(.*)\.so$/', basename(readlink('/lib/libc.so.6')), $matches)) { + list($major, $minor) = explode('.', $matches[1]); + } + } + + if (!($major && $minor)) { + return $glibc = ''; + } + + return $glibc = "glibc{$major}.{$minor}"; + } + + function getSignature() + { + if (empty($this->extra)) { + return "{$this->sysname}-{$this->release}-{$this->cpu}"; + } + return "{$this->sysname}-{$this->release}-{$this->cpu}-{$this->extra}"; + } + + function getSysname() + { + return $this->sysname; + } + + function getNodename() + { + return $this->nodename; + } + + function getCpu() + { + return $this->cpu; + } + + function getRelease() + { + return $this->release; + } + + function getExtra() + { + return $this->extra; + } + + function matchSignature($match) + { + $fragments = is_array($match) ? $match : explode('-', $match); + $n = count($fragments); + $matches = 0; + if ($n > 0) { + $matches += $this->_matchFragment($fragments[0], $this->sysname); + } + if ($n > 1) { + $matches += $this->_matchFragment($fragments[1], $this->release); + } + if ($n > 2) { + $matches += $this->_matchFragment($fragments[2], $this->cpu); + } + if ($n > 3) { + $matches += $this->_matchFragment($fragments[3], $this->extra); + } + return ($matches == $n); + } + + function _matchFragment($fragment, $value) + { + if (strcspn($fragment, '*?') < strlen($fragment)) { + $reg = '/^' . str_replace(array('*', '?', '/'), array('.*', '.', '\\/'), $fragment) . '\\z/'; + return preg_match($reg, $value); + } + return ($fragment == '*' || !strcasecmp($fragment, $value)); + } + +} +/* + * Local Variables: + * indent-tabs-mode: nil + * c-basic-offset: 4 + * End: + */ diff --git a/civicrm/packages/PEAR.php b/civicrm/vendor/pear/pear-core-minimal/src/PEAR.php similarity index 96% rename from civicrm/packages/PEAR.php rename to civicrm/vendor/pear/pear-core-minimal/src/PEAR.php index 13dcc1ff1e..89568a0e5b 100644 --- a/civicrm/packages/PEAR.php +++ b/civicrm/vendor/pear/pear-core-minimal/src/PEAR.php @@ -75,7 +75,7 @@ $GLOBALS['_PEAR_error_handler_stack'] = array(); * @author Greg Beaver <cellog@php.net> * @copyright 1997-2006 The PHP Group * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.10.0 + * @version Release: @package_version@ * @link http://pear.php.net/package/PEAR * @see PEAR_Error * @since Class available since PHP 4.0.2 @@ -170,7 +170,7 @@ class PEAR $destructor = "_$classname"; if (method_exists($this, $destructor)) { global $_PEAR_destructor_object_list; - $_PEAR_destructor_object_list[] = &$this; + $_PEAR_destructor_object_list[] = $this; if (!isset($GLOBALS['_PEAR_SHUTDOWN_REGISTERED'])) { register_shutdown_function("_PEAR_call_destructors"); $GLOBALS['_PEAR_SHUTDOWN_REGISTERED'] = true; @@ -191,7 +191,7 @@ class PEAR */ public function PEAR($error_class = null) { - $this->__construct($error_class); + self::__construct($error_class); } /** @@ -450,7 +450,7 @@ class PEAR } /** - * This method deletes all occurences of the specified element from + * This method deletes all occurrences of the specified element from * the expected error codes stack. * * @param mixed $error_code error code that should be deleted @@ -598,11 +598,11 @@ class PEAR protected static function _throwError($object, $message = null, $code = null, $userinfo = null) { if ($object !== null) { - $a = &$object->raiseError($message, $code, null, null, $userinfo); + $a = $object->raiseError($message, $code, null, null, $userinfo); return $a; } - $a = &PEAR::raiseError($message, $code, null, null, $userinfo); + $a = PEAR::raiseError($message, $code, null, null, $userinfo); return $a; } @@ -782,7 +782,7 @@ function _PEAR_call_destructors() $_PEAR_destructor_object_list = array_reverse($_PEAR_destructor_object_list); } - while (list($k, $objref) = each($_PEAR_destructor_object_list)) { + foreach ($_PEAR_destructor_object_list as $k => $objref) { $classname = get_class($objref); while ($classname) { $destructor = "_$classname"; @@ -823,7 +823,7 @@ function _PEAR_call_destructors() * @author Gregory Beaver <cellog@php.net> * @copyright 1997-2006 The PHP Group * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.10.0 + * @version Release: @package_version@ * @link http://pear.php.net/manual/en/core.pear.pear-error.php * @see PEAR::raiseError(), PEAR::throwError() * @since Class available since PHP 4.0.2 @@ -914,7 +914,8 @@ class PEAR_Error } else { $format = $options; } - die(sprintf($format, $msg)); + printf($format, $msg); + exit($code); } if ($this->mode & PEAR_ERROR_CALLBACK && is_callable($this->callback)) { @@ -923,10 +924,28 @@ class PEAR_Error if ($this->mode & PEAR_ERROR_EXCEPTION) { trigger_error("PEAR_ERROR_EXCEPTION is obsolete, use class PEAR_Exception for exceptions", E_USER_WARNING); - throw new Exception($this->message, $this->code); + eval('$e = new Exception($this->message, $this->code);throw($e);'); } } + /** + * Only here for backwards compatibility. + * + * Class "Cache_Error" still uses it, among others. + * + * @param string $message Message + * @param int $code Error code + * @param int $mode Error mode + * @param mixed $options See __construct() + * @param string $userinfo Additional user/debug info + */ + public function PEAR_Error( + $message = 'unknown error', $code = null, $mode = null, + $options = null, $userinfo = null + ) { + self::__construct($message, $code, $mode, $options, $userinfo); + } + /** * Get the error mode from an error object. * diff --git a/civicrm/vendor/pear/pear-core-minimal/src/PEAR/Error.php b/civicrm/vendor/pear/pear-core-minimal/src/PEAR/Error.php new file mode 100644 index 0000000000..96efff75da --- /dev/null +++ b/civicrm/vendor/pear/pear-core-minimal/src/PEAR/Error.php @@ -0,0 +1,14 @@ +<?php +/** + * Dummy file to make autoloaders work + * + * PHP version 5 + * + * @category PEAR + * @package PEAR + * @author Christian Weiske <cweiske@php.net> + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @link http://pear.php.net/package/PEAR + */ +require_once __DIR__ . '/../PEAR.php'; +?> \ No newline at end of file diff --git a/civicrm/packages/PEAR/ErrorStack.php b/civicrm/vendor/pear/pear-core-minimal/src/PEAR/ErrorStack.php similarity index 99% rename from civicrm/packages/PEAR/ErrorStack.php rename to civicrm/vendor/pear/pear-core-minimal/src/PEAR/ErrorStack.php index ada8593f8f..7af45bfae6 100644 --- a/civicrm/packages/PEAR/ErrorStack.php +++ b/civicrm/vendor/pear/pear-core-minimal/src/PEAR/ErrorStack.php @@ -131,7 +131,7 @@ define('PEAR_ERRORSTACK_ERR_OBJTOSTRING', 2); * $local_stack = new PEAR_ErrorStack('MyPackage'); * </code> * @author Greg Beaver <cellog@php.net> - * @version 1.10.0 + * @version @package_version@ * @package PEAR_ErrorStack * @category Debugging * @copyright 2004-2008 Greg Beaver diff --git a/civicrm/packages/System.php b/civicrm/vendor/pear/pear-core-minimal/src/System.php similarity index 88% rename from civicrm/packages/System.php rename to civicrm/vendor/pear/pear-core-minimal/src/System.php index 5193cb97a1..aefc85b3f9 100644 --- a/civicrm/packages/System.php +++ b/civicrm/vendor/pear/pear-core-minimal/src/System.php @@ -9,7 +9,6 @@ * @author Tomas V.V.Cox <cox@idecnet.com> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: System.php 276386 2009-02-24 23:52:56Z dufuz $ * @link http://pear.php.net/package/PEAR * @since File available since Release 0.1 */ @@ -23,7 +22,7 @@ require_once 'Console/Getopt.php'; $GLOBALS['_System_temp_files'] = array(); /** -* System offers cross plattform compatible system functions +* System offers cross platform compatible system functions * * Static functions for different operations. Should work under * Unix and Windows. The names and usage has been taken from its respectively @@ -51,7 +50,7 @@ $GLOBALS['_System_temp_files'] = array(); * @author Tomas V.V. Cox <cox@idecnet.com> * @copyright 1997-2006 The PHP Group * @license http://opensource.org/licenses/bsd-license.php New BSD License -* @version Release: 1.9.0 +* @version Release: @package_version@ * @link http://pear.php.net/package/PEAR * @since Class available since Release 0.1 * @static @@ -65,15 +64,39 @@ class System * @param string $short_options the allowed option short-tags * @param string $long_options the allowed option long-tags * @return array the given options and there values - * @static - * @access private */ - function _parseArgs($argv, $short_options, $long_options = null) + public static function _parseArgs($argv, $short_options, $long_options = null) { if (!is_array($argv) && $argv !== null) { - $argv = preg_split('/\s+/', $argv, -1, PREG_SPLIT_NO_EMPTY); + /* + // Quote all items that are a short option + $av = preg_split('/(\A| )--?[a-z0-9]+[ =]?((?<!\\\\)((,\s*)|((?<!,)\s+))?)/i', $argv, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_OFFSET_CAPTURE); + $offset = 0; + foreach ($av as $a) { + $b = trim($a[0]); + if ($b{0} == '"' || $b{0} == "'") { + continue; + } + + $escape = escapeshellarg($b); + $pos = $a[1] + $offset; + $argv = substr_replace($argv, $escape, $pos, strlen($b)); + $offset += 2; + } + */ + + // Find all items, quoted or otherwise + preg_match_all("/(?:[\"'])(.*?)(?:['\"])|([^\s]+)/", $argv, $av); + $argv = $av[1]; + foreach ($av[2] as $k => $a) { + if (empty($a)) { + continue; + } + $argv[$k] = trim($a) ; + } } - return Console_Getopt::getopt2($argv, $short_options); + + return Console_Getopt::getopt2($argv, $short_options, $long_options); } /** @@ -82,10 +105,8 @@ class System * * @param mixed $error a PEAR error or a string with the error message * @return bool false - * @static - * @access private */ - function raiseError($error) + protected static function raiseError($error) { if (PEAR::isError($error)) { $error = $error->getMessage(); @@ -116,10 +137,8 @@ class System * @param integer $aktinst starting deep of the lookup * @param bool $silent if true, do not emit errors. * @return array the structure of the dir - * @static - * @access private */ - function _dirToStruct($sPath, $maxinst, $aktinst = 0, $silent = false) + protected static function _dirToStruct($sPath, $maxinst, $aktinst = 0, $silent = false) { $struct = array('dirs' => array(), 'files' => array()); if (($dir = @opendir($sPath)) === false) { @@ -162,7 +181,7 @@ class System * @static * @see System::_dirToStruct() */ - function _multipleToStruct($files) + protected static function _multipleToStruct($files) { $struct = array('dirs' => array(), 'files' => array()); settype($files, 'array'); @@ -188,7 +207,7 @@ class System * @static * @access public */ - function rm($args) + public static function rm($args) { $opts = System::_parseArgs($args, 'rf'); // "f" does nothing but I like it :-) if (PEAR::isError($opts)) { @@ -231,10 +250,8 @@ class System * The -p option will create parent directories * @param string $args the name of the director(y|ies) to create * @return bool True for success - * @static - * @access public */ - function mkDir($args) + public static function mkDir($args) { $opts = System::_parseArgs($args, 'pm:'); if (PEAR::isError($opts)) { @@ -298,14 +315,12 @@ class System * 2) System::cat('sample.txt test.txt > final.txt'); * 3) System::cat('sample.txt test.txt >> final.txt'); * - * Note: as the class use fopen, urls should work also (test that) + * Note: as the class use fopen, urls should work also * * @param string $args the arguments * @return boolean true on success - * @static - * @access public */ - function &cat($args) + public static function &cat($args) { $ret = null; $files = array(); @@ -376,10 +391,8 @@ class System * @param string $args The arguments * @return mixed the full path of the created (file|dir) or false * @see System::tmpdir() - * @static - * @access public */ - function mktemp($args = null) + public static function mktemp($args = null) { static $first_time = true; $opts = System::_parseArgs($args, 't:d'); @@ -428,11 +441,8 @@ class System /** * Remove temporary files created my mkTemp. This function is executed * at script shutdown time - * - * @static - * @access private */ - function _removeTmpFiles() + public static function _removeTmpFiles() { if (count($GLOBALS['_System_temp_files'])) { $delete = $GLOBALS['_System_temp_files']; @@ -448,10 +458,9 @@ class System * Note: php.ini-recommended removes the "E" from the variables_order setting, * making unavaible the $_ENV array, that s why we do tests with _ENV * - * @static * @return string The temporary directory on the system */ - static function tmpdir() + public static function tmpdir() { if (OS_WINDOWS) { if ($var = isset($_ENV['TMP']) ? $_ENV['TMP'] : getenv('TMP')) { @@ -481,10 +490,9 @@ class System * @param mixed $fallback Value to return if $program is not found * * @return mixed A string with the full path or false if not found - * @static * @author Stig Bakken <ssb@php.net> */ - static function which($program, $fallback = false) + public static function which($program, $fallback = false) { // enforce API if (!is_string($program) || '' == $program) { @@ -496,13 +504,11 @@ class System $path_elements[] = dirname($program); $program = basename($program); } else { - // Honor safe mode - if (!ini_get('safe_mode') || !$path = ini_get('safe_mode_exec_dir')) { - $path = getenv('PATH'); - if (!$path) { - $path = getenv('Path'); // some OSes are just stupid enough to do this - } + $path = getenv('PATH'); + if (!$path) { + $path = getenv('Path'); // some OSes are just stupid enough to do this } + $path_elements = explode(PATH_SEPARATOR, $path); } @@ -514,18 +520,21 @@ class System if (strpos($program, '.') !== false) { array_unshift($exe_suffixes, ''); } - // is_executable() is not available on windows for PHP4 - $pear_is_executable = (function_exists('is_executable')) ? 'is_executable' : 'is_file'; } else { $exe_suffixes = array(''); - $pear_is_executable = 'is_executable'; } foreach ($exe_suffixes as $suff) { foreach ($path_elements as $dir) { $file = $dir . DIRECTORY_SEPARATOR . $program . $suff; - if (@$pear_is_executable($file)) { + // It's possible to run a .bat on Windows that is_executable + // would return false for. The is_executable check is meaningless... + if (OS_WINDOWS) { return $file; + } else { + if (is_executable($file)) { + return $file; + } } } } @@ -544,7 +553,7 @@ class System * System::find("$dir -name *.php -name *.htm*"); * System::find("$dir -maxdepth 1"); * - * Params implmented: + * Params implemented: * $dir -> Start the search at this directory * -type d -> return only directories * -type f -> return only files @@ -553,10 +562,8 @@ class System * * @param mixed Either array or string with the command line * @return array Array of found files - * @static - * */ - function find($args) + public static function find($args) { if (!is_array($args)) { $args = preg_split('/\s+/', $args, -1, PREG_SPLIT_NO_EMPTY); @@ -618,4 +625,4 @@ class System } return $files; } -} \ No newline at end of file +} diff --git a/civicrm/vendor/phpoffice/common/.travis.yml b/civicrm/vendor/phpoffice/common/.travis.yml index 77eecfc8ed..e5f01f1afc 100644 --- a/civicrm/vendor/phpoffice/common/.travis.yml +++ b/civicrm/vendor/phpoffice/common/.travis.yml @@ -1,16 +1,18 @@ language: php php: - - 5.3 - 5.4 - 5.5 - 5.6 - 7.0 + - 7.1 + - 7.2 - hhvm matrix: allow_failures: - - php: 7.0 + - php: 7.1 + - php: 7.2 - php: hhvm env: diff --git a/civicrm/vendor/phpoffice/common/CHANGELOG.md b/civicrm/vendor/phpoffice/common/CHANGELOG.md index 1042e8fda5..9ab6d68856 100644 --- a/civicrm/vendor/phpoffice/common/CHANGELOG.md +++ b/civicrm/vendor/phpoffice/common/CHANGELOG.md @@ -42,4 +42,20 @@ ## 0.2.6 ### Changes -- `\PhpOffice\Common\Text::utf8ToUnicode()` became `public`. \ No newline at end of file +- `\PhpOffice\Common\Text::utf8ToUnicode()` became `public`. + +## 0.2.7 + +### Features +- Added `\PhpOffice\Common\File::fileGetContents()` (with support of zip://) +- Added Support for PHP 7.1 + +## 0.2.8 + +### Features +- Added possibility to register namespaces to DOMXpath +- Added Utility to get an Office compatible hash of a password +- Write attribute's value of type float independently of locale + +## 0.2.9 +- Fix XML Entity injection vulnerability \ No newline at end of file diff --git a/civicrm/vendor/phpoffice/common/PATCHES.txt b/civicrm/vendor/phpoffice/common/PATCHES.txt new file mode 100644 index 0000000000..0ad62830da --- /dev/null +++ b/civicrm/vendor/phpoffice/common/PATCHES.txt @@ -0,0 +1,7 @@ +This file was automatically generated by Composer Patches (https://github.com/cweagans/composer-patches) +Patches applied to this directory: + +Fix handling of libxml_disable_entity_loader +Source: tools/scripts/composer/patches/phpoffice-common-xml-entity-fix.patch + + diff --git a/civicrm/vendor/phpoffice/common/VERSION b/civicrm/vendor/phpoffice/common/VERSION index a53741c09b..d81f1c3fc7 100644 --- a/civicrm/vendor/phpoffice/common/VERSION +++ b/civicrm/vendor/phpoffice/common/VERSION @@ -1 +1 @@ -0.2.6 \ No newline at end of file +0.2.9 \ No newline at end of file diff --git a/civicrm/vendor/phpoffice/common/composer.json b/civicrm/vendor/phpoffice/common/composer.json index eed7fad024..2a75a30c80 100644 --- a/civicrm/vendor/phpoffice/common/composer.json +++ b/civicrm/vendor/phpoffice/common/composer.json @@ -19,7 +19,7 @@ "pclzip/pclzip": "^2.8" }, "require-dev": { - "phpunit/phpunit": "3.7.*", + "phpunit/phpunit": "^4.8.36 || ^7.0", "phpdocumentor/phpdocumentor":"2.*", "phpmd/phpmd": "2.*", "sebastian/phpcpd": "2.*", diff --git a/civicrm/vendor/phpoffice/common/phpunit.xml.dist b/civicrm/vendor/phpoffice/common/phpunit.xml.dist index 2beeaba458..7b09d34828 100644 --- a/civicrm/vendor/phpoffice/common/phpunit.xml.dist +++ b/civicrm/vendor/phpoffice/common/phpunit.xml.dist @@ -6,8 +6,7 @@ convertNoticesToExceptions="true" convertWarningsToExceptions="true" processIsolation="false" - stopOnFailure="false" - syntaxCheck="false"> + stopOnFailure="false"> <testsuites> <testsuite name="PhpOffice Common Test Suite"> <directory>./tests/Common</directory> @@ -19,7 +18,7 @@ </whitelist> </filter> <logging> - <log type="coverage-html" target="./build/coverage" charset="UTF-8" highlight="true" /> + <log type="coverage-html" target="./build/coverage" /> <log type="coverage-clover" target="./build/logs/clover.xml" /> </logging> </phpunit> \ No newline at end of file diff --git a/civicrm/vendor/phpoffice/common/src/Common/Adapter/Zip/PclZipAdapter.php b/civicrm/vendor/phpoffice/common/src/Common/Adapter/Zip/PclZipAdapter.php index 92d73f12a9..053531f111 100644 --- a/civicrm/vendor/phpoffice/common/src/Common/Adapter/Zip/PclZipAdapter.php +++ b/civicrm/vendor/phpoffice/common/src/Common/Adapter/Zip/PclZipAdapter.php @@ -15,10 +15,6 @@ class PclZipAdapter implements ZipInterface */ protected $tmpDir; - /** - * @param $filename - * @return $this - */ public function open($filename) { $this->oPclZip = new PclZip($filename); @@ -26,20 +22,11 @@ class PclZipAdapter implements ZipInterface return $this; } - /** - * @return $this - */ public function close() { return $this; } - /** - * @param $localname - * @param $contents - * @return $this - * @throws \Exception - */ public function addFromString($localname, $contents) { $pathData = pathinfo($localname); diff --git a/civicrm/vendor/phpoffice/common/src/Common/Adapter/Zip/ZipArchiveAdapter.php b/civicrm/vendor/phpoffice/common/src/Common/Adapter/Zip/ZipArchiveAdapter.php index b7d67873d9..da2c34626e 100644 --- a/civicrm/vendor/phpoffice/common/src/Common/Adapter/Zip/ZipArchiveAdapter.php +++ b/civicrm/vendor/phpoffice/common/src/Common/Adapter/Zip/ZipArchiveAdapter.php @@ -16,11 +16,6 @@ class ZipArchiveAdapter implements ZipInterface */ protected $filename; - /** - * @param string $filename - * @throws \Exception Could not open $this->filename for writing. - * @return mixed - */ public function open($filename) { $this->filename = $filename; @@ -35,10 +30,6 @@ class ZipArchiveAdapter implements ZipInterface throw new \Exception("Could not open $this->filename for writing."); } - /** - * @return $this - * @throws \Exception Could not close zip file $this->filename. - */ public function close() { if ($this->oZipArchive->close() === false) { @@ -47,13 +38,12 @@ class ZipArchiveAdapter implements ZipInterface return $this; } - /** - * @param $localname - * @param $contents - * @return bool - */ public function addFromString($localname, $contents) { - return $this->oZipArchive->addFromString($localname, $contents); + if ($this->oZipArchive->addFromString($localname, $contents) === false) { + throw new \Exception("Error zipping files : " . $localname); + } + + return $this; } } diff --git a/civicrm/vendor/phpoffice/common/src/Common/Adapter/Zip/ZipInterface.php b/civicrm/vendor/phpoffice/common/src/Common/Adapter/Zip/ZipInterface.php index b830fb8049..e8dbc8c285 100644 --- a/civicrm/vendor/phpoffice/common/src/Common/Adapter/Zip/ZipInterface.php +++ b/civicrm/vendor/phpoffice/common/src/Common/Adapter/Zip/ZipInterface.php @@ -4,7 +4,27 @@ namespace PhpOffice\Common\Adapter\Zip; interface ZipInterface { + /** + * Open a ZIP file archive + * @param string $filename + * @return $this + * @throws \Exception + */ public function open($filename); + + /** + * Close the active archive (opened or newly created) + * @return $this + * @throws \Exception + */ public function close(); + + /** + * Add a file to a ZIP archive using its contents + * @param string $localname The name of the entry to create. + * @param string $contents The contents to use to create the entry. It is used in a binary safe mode. + * @return $this + * @throws \Exception + */ public function addFromString($localname, $contents); } diff --git a/civicrm/vendor/phpoffice/common/src/Common/File.php b/civicrm/vendor/phpoffice/common/src/Common/File.php index 072d17bd87..8cb5907e21 100644 --- a/civicrm/vendor/phpoffice/common/src/Common/File.php +++ b/civicrm/vendor/phpoffice/common/src/Common/File.php @@ -43,13 +43,40 @@ class File $zip->close(); return $returnValue; - } else { - return false; } - } else { - // Regular file_exists - return file_exists($pFilename); + + return false; + } + + // Regular file_exists + return file_exists($pFilename); + } + /** + * Returns the content of a file + * + * @param string $pFilename Filename + * @return string + */ + public static function fileGetContents($pFilename) + { + if (!self::fileExists($pFilename)) { + return false; + } + if (strtolower(substr($pFilename, 0, 3)) == 'zip') { + // Open ZIP file and verify if the file exists + $zipFile = substr($pFilename, 6, strpos($pFilename, '#') - 6); + $archiveFile = substr($pFilename, strpos($pFilename, '#') + 1); + + $zip = new \ZipArchive(); + if ($zip->open($zipFile) === true) { + $returnValue = $zip->getFromName($archiveFile); + $zip->close(); + return $returnValue; + } + return false; } + // Regular file contents + return file_get_contents($pFilename); } /** diff --git a/civicrm/vendor/phpoffice/common/src/Common/Microsoft/OLERead.php b/civicrm/vendor/phpoffice/common/src/Common/Microsoft/OLERead.php index 5be8f2454f..fa1df12d90 100644 --- a/civicrm/vendor/phpoffice/common/src/Common/Microsoft/OLERead.php +++ b/civicrm/vendor/phpoffice/common/src/Common/Microsoft/OLERead.php @@ -186,26 +186,26 @@ class OLERead } return $streamData; - } else { - $numBlocks = $this->props[$stream]['size'] / self::BIG_BLOCK_SIZE; - if ($this->props[$stream]['size'] % self::BIG_BLOCK_SIZE != 0) { - ++$numBlocks; - } + } - if ($numBlocks == 0) { - return ''; - } + $numBlocks = $this->props[$stream]['size'] / self::BIG_BLOCK_SIZE; + if ($this->props[$stream]['size'] % self::BIG_BLOCK_SIZE != 0) { + ++$numBlocks; + } - $block = $this->props[$stream]['startBlock']; + if ($numBlocks == 0) { + return ''; + } - while ($block != -2) { - $pos = ($block + 1) * self::BIG_BLOCK_SIZE; - $streamData .= substr($this->data, $pos, self::BIG_BLOCK_SIZE); - $block = self::getInt4d($this->bigBlockChain, $block*4); - } + $block = $this->props[$stream]['startBlock']; - return $streamData; + while ($block != -2) { + $pos = ($block + 1) * self::BIG_BLOCK_SIZE; + $streamData .= substr($this->data, $pos, self::BIG_BLOCK_SIZE); + $block = self::getInt4d($this->bigBlockChain, $block*4); } + + return $streamData; } /** @@ -259,10 +259,10 @@ class OLERead 'type' => $type, 'startBlock' => $startBlock, 'size' => $size); - + // tmp helper to simplify checks $upName = strtoupper($name); - + switch ($upName) { case 'ROOT ENTRY': case 'R': diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Shared/Microsoft/PasswordEncoder.php b/civicrm/vendor/phpoffice/common/src/Common/Microsoft/PasswordEncoder.php similarity index 95% rename from civicrm/vendor/phpoffice/phpword/src/PhpWord/Shared/Microsoft/PasswordEncoder.php rename to civicrm/vendor/phpoffice/common/src/Common/Microsoft/PasswordEncoder.php index 1c7b4c6c8e..f620f4c7a9 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Shared/Microsoft/PasswordEncoder.php +++ b/civicrm/vendor/phpoffice/common/src/Common/Microsoft/PasswordEncoder.php @@ -1,21 +1,20 @@ <?php /** - * This file is part of PHPWord - A pure PHP library for reading and writing - * word processing documents. + * This file is part of PHPOffice Common * - * PHPWord is free software distributed under the terms of the GNU Lesser + * PHPOffice Common is free software distributed under the terms of the GNU Lesser * General Public License version 3 as published by the Free Software Foundation. * * For the full copyright and license information, please read the LICENSE * file that was distributed with this source code. For the full list of - * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. + * contributors, visit https://github.com/PHPOffice/Common/contributors. * - * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @link https://github.com/PHPOffice/Common + * @copyright 2009-2016 PHPOffice Common contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ -namespace PhpOffice\PhpWord\Shared\Microsoft; +namespace PhpOffice\Common\Microsoft; /** * Password encoder for microsoft office applications diff --git a/civicrm/vendor/phpoffice/common/src/Common/Text.php b/civicrm/vendor/phpoffice/common/src/Common/Text.php index 9d4c9e136a..91c790ae99 100644 --- a/civicrm/vendor/phpoffice/common/src/Common/Text.php +++ b/civicrm/vendor/phpoffice/common/src/Common/Text.php @@ -64,7 +64,7 @@ class Text return str_replace(array_values(self::$controlCharacters), array_keys(self::$controlCharacters), $value); } - + /** * Return a number formatted for being integrated in xml files * @param float $number @@ -74,7 +74,7 @@ class Text { return number_format($number, $decimals, '.', ''); } - + /** * @param int $dec * @link http://stackoverflow.com/a/7153133/2235790 @@ -115,14 +115,12 @@ class Text /** * Check if a string contains UTF-8 data * - * @deprecated 0.2.4 Use `Zend\Stdlib\StringUtils::isValidUtf8` instead. - * * @param string $value * @return boolean */ public static function isUTF8($value = '') { - return $value === '' || preg_match('/^./su', $value) === 1; + return is_string($value) && ($value === '' || preg_match('/^./su', $value) == 1); } /** diff --git a/civicrm/vendor/phpoffice/common/src/Common/XMLReader.php b/civicrm/vendor/phpoffice/common/src/Common/XMLReader.php index dc9ba747b2..5592b1ce7a 100644 --- a/civicrm/vendor/phpoffice/common/src/Common/XMLReader.php +++ b/civicrm/vendor/phpoffice/common/src/Common/XMLReader.php @@ -58,9 +58,9 @@ class XMLReader if ($content === false) { return false; - } else { - return $this->getDomFromString($content); } + + return $this->getDomFromString($content); } /** @@ -71,9 +71,11 @@ class XMLReader */ public function getDomFromString($content) { + $original = libxml_disable_entity_loader(); + libxml_disable_entity_loader(true); $this->dom = new \DOMDocument(); $this->dom->loadXML($content); - + libxml_disable_entity_loader($original); return $this->dom; } @@ -95,9 +97,28 @@ class XMLReader if (is_null($contextNode)) { return $this->xpath->query($path); - } else { - return $this->xpath->query($path, $contextNode); } + + return $this->xpath->query($path, $contextNode); + } + + /** + * Registers the namespace with the DOMXPath object + * + * @param string $prefix The prefix + * @param string $namespaceURI The URI of the namespace + * @return bool true on success or false on failure + * @throws \InvalidArgumentException If called before having loaded the DOM document + */ + public function registerNamespace($prefix, $namespaceURI) + { + if ($this->dom === null) { + throw new \InvalidArgumentException('Dom needs to be loaded before registering a namespace'); + } + if ($this->xpath === null) { + $this->xpath = new \DOMXpath($this->dom); + } + return $this->xpath->registerNamespace($prefix, $namespaceURI); } /** @@ -112,9 +133,9 @@ class XMLReader $elements = $this->getElements($path, $contextNode); if ($elements->length > 0) { return $elements->item(0); - } else { - return null; } + + return null; } /** @@ -156,9 +177,9 @@ class XMLReader $elements = $this->getElements($path, $contextNode); if ($elements->length > 0) { return $elements->item(0)->nodeValue; - } else { - return null; } + + return null; } /** diff --git a/civicrm/vendor/phpoffice/common/src/Common/XMLWriter.php b/civicrm/vendor/phpoffice/common/src/Common/XMLWriter.php index 7fbf6285d8..43e5b6657c 100644 --- a/civicrm/vendor/phpoffice/common/src/Common/XMLWriter.php +++ b/civicrm/vendor/phpoffice/common/src/Common/XMLWriter.php @@ -27,7 +27,6 @@ namespace PhpOffice\Common; * @method bool startDocument(string $version = 1.0, string $encoding = null, string $standalone = null) * @method bool startElement(string $name) * @method bool text(string $content) - * @method bool writeAttribute(string $name, mixed $value) * @method bool writeCData(string $content) * @method bool writeComment(string $content) * @method bool writeElement(string $name, string $content = null) @@ -100,10 +99,10 @@ class XMLWriter extends \XMLWriter { if ($this->tempFileName == '') { return $this->outputMemory(true); - } else { - $this->flush(); - return file_get_contents($this->tempFileName); } + + $this->flush(); + return file_get_contents($this->tempFileName); } @@ -167,4 +166,17 @@ class XMLWriter extends \XMLWriter $this->writeAttribute($attribute, $value); } } + + /** + * @param string $name + * @param mixed $value + * @return bool + */ + public function writeAttribute($name, $value) + { + if (is_float($value)) { + $value = json_encode($value); + } + return parent::writeAttribute($name, $value); + } } diff --git a/civicrm/vendor/phpoffice/phpword/.gitignore b/civicrm/vendor/phpoffice/phpword/.gitignore deleted file mode 100644 index 2ac6e2b5c7..0000000000 --- a/civicrm/vendor/phpoffice/phpword/.gitignore +++ /dev/null @@ -1,23 +0,0 @@ -.DS_Store -._* -.Spotlight-V100 -.Trashes -Thumbs.db -Desktop.ini -.idea -_build -/build -phpunit.xml -composer.lock -composer.phar -vendor -/report -/build -/samples/resources -/samples/results -/.settings -phpword.ini -/.buildpath -/.project -/nbproject -/.php_cs.cache diff --git a/civicrm/vendor/phpoffice/phpword/.scrutinizer.yml b/civicrm/vendor/phpoffice/phpword/.scrutinizer.yml deleted file mode 100644 index c8fe57cf63..0000000000 --- a/civicrm/vendor/phpoffice/phpword/.scrutinizer.yml +++ /dev/null @@ -1,24 +0,0 @@ -filter: - excluded_paths: [ 'vendor/*', 'tests/*', 'samples/*', 'src/PhpWord/Shared/PCLZip/*' ] - -before_commands: - - "composer install --prefer-source --dev" - -tools: - php_code_sniffer: - enabled: true - config: - standard: PSR2 - php_mess_detector: - enabled: true - config: - ruleset: phpmd.xml.dist - external_code_coverage: - enabled: true - timeout: 1200 - php_cpd: true - # php_sim: # Temporarily disabled to allow focus on things other than duplicates - # min_mass: 40 - php_pdepend: true - php_analyzer: true - sensiolabs_security_checker: true diff --git a/civicrm/vendor/phpoffice/phpword/.travis.yml b/civicrm/vendor/phpoffice/phpword/.travis.yml deleted file mode 100644 index d63b7bb22c..0000000000 --- a/civicrm/vendor/phpoffice/phpword/.travis.yml +++ /dev/null @@ -1,64 +0,0 @@ -language: php - -dist: precise - -php: - - 5.3 - - 5.4 - - 5.5 - - 5.6 - - 7.0 - - 7.1 - - 7.2 - -matrix: - include: - - php: 5.6 - env: COVERAGE=1 - allow_failures: - - php: 7.2 - -cache: - directories: - - vendor - - $HOME/.composer/cache - - .php-cs.cache - -env: - global: - - secure: "Sq+6bVtnPsu0mWX8DWQ+9bGAjxMcGorksUiHc4YIXEJsuDfVmVlH8tTD547IeCjDAx9MxXerZ2Z4HSjxTB70VEnJPvZMHI/EZn4Ny31YLHEthdZbV5Gd1h0TGp8VOzPKGShvGrtGBX6MvMfgpK4zuieVWbSfdKeecm8ZNLMpUd4=" - -before_install: - ## Packages - - sudo apt-get update -qq - - sudo apt-get install -y graphviz - -before_script: - ## Deactivate xdebug if we don't do code coverage - - if [ -z "$COVERAGE" ]; then phpenv config-rm xdebug.ini ; fi - ## Composer - - composer self-update - - composer install --prefer-source - ## PHPDocumentor - - mkdir -p build/docs - - mkdir -p build/coverage - -script: - ## PHP_CodeSniffer - - if [ -z "$COVERAGE" ]; then ./vendor/bin/phpcs src/ tests/ --standard=PSR2 -n --ignore=src/PhpWord/Shared/PCLZip ; fi - ## PHP-CS-Fixer - - if [ -n "$COVERAGE" ]; then ./vendor/bin/php-cs-fixer fix --diff --verbose --dry-run ; fi - ## PHP Mess Detector - - if [ -z "$COVERAGE" ]; then ./vendor/bin/phpmd src/,tests/ text ./phpmd.xml.dist --exclude pclzip.lib.php ; fi - ## PHPUnit - - ./vendor/bin/phpunit -c ./ $(if [ -n "$COVERAGE" ]; then echo --coverage-text; else echo --no-coverage; fi) - ## PHPLOC - - if [ -z "$COVERAGE" ]; then ./vendor/bin/phploc src/ ; fi - ## PHPDocumentor - - if [ -z "$COVERAGE" ]; then ./vendor/bin/phpdoc -q -d ./src -t ./build/docs --ignore "*/src/PhpWord/Shared/*/*" --template="responsive-twig" ; fi - -after_script: - ## PHPDocumentor - - bash .travis_shell_after_success.sh - ## Scrutinizer - - if [ -n "$COVERAGE" ]; then wget https://scrutinizer-ci.com/ocular.phar && php ocular.phar code-coverage:upload --format=php-clover build/logs/clover.xml ; fi diff --git a/civicrm/vendor/phpoffice/phpword/.travis_shell_after_success.sh b/civicrm/vendor/phpoffice/phpword/.travis_shell_after_success.sh deleted file mode 100644 index 1272852619..0000000000 --- a/civicrm/vendor/phpoffice/phpword/.travis_shell_after_success.sh +++ /dev/null @@ -1,39 +0,0 @@ -#!/bin/bash - -echo "--DEBUG--" -echo "TRAVIS_REPO_SLUG: $TRAVIS_REPO_SLUG" -echo "TRAVIS_PHP_VERSION: $TRAVIS_PHP_VERSION" -echo "TRAVIS_PULL_REQUEST: $TRAVIS_PULL_REQUEST" - -if [ "$TRAVIS_REPO_SLUG" == "PHPOffice/PHPWord" ] && [ "$TRAVIS_PULL_REQUEST" == "false" ] && [ "$TRAVIS_PHP_VERSION" == "5.6" ]; then - - echo -e "Publishing PHPDoc...\n" - - cp -R build/docs $HOME/docs-latest - cp -R build/coverage $HOME/coverage-latest - - cd $HOME - git config --global user.email "travis@travis-ci.org" - git config --global user.name "travis-ci" - git clone --quiet --branch=gh-pages https://${GH_TOKEN}@github.com/PHPOffice/PHPWord gh-pages > /dev/null - - cd gh-pages - echo "--DEBUG : Suppression" - git rm -rf ./docs/$TRAVIS_BRANCH - - echo "--DEBUG : Dossier" - mkdir -p docs/$TRAVIS_BRANCH - mkdir -p coverage/$TRAVIS_BRANCH - - echo "--DEBUG : Copie" - cp -Rf $HOME/docs-latest/* ./docs/$TRAVIS_BRANCH/ - cp -Rf $HOME/coverage-latest/* ./coverage/$TRAVIS_BRANCH/ - - echo "--DEBUG : Git" - git add -f . - git commit -m "PHPDocumentor (Travis Build: $TRAVIS_BUILD_NUMBER - Branch: $TRAVIS_BRANCH)" - git push -fq origin gh-pages > /dev/null - - echo -e "Published PHPDoc to gh-pages.\n" - -fi diff --git a/civicrm/vendor/phpoffice/phpword/CHANGELOG.md b/civicrm/vendor/phpoffice/phpword/CHANGELOG.md index 93945189a9..a166345cba 100644 --- a/civicrm/vendor/phpoffice/phpword/CHANGELOG.md +++ b/civicrm/vendor/phpoffice/phpword/CHANGELOG.md @@ -3,6 +3,52 @@ Change Log All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/). +v0.15.0 (14 Jul 2018) +---------------------- +### Added +- Parsing of `align` HTML attribute - @troosan #1231 +- Parse formatting inside HTML lists - @troosan @samimussbach #1239 #945 #1215 #508 +- Parsing of CSS `direction` instruction, HTML `lang` attribute, formatting inside table cell - @troosan #1273 #1252 #1254 +- Add support for Track changes @Cip @troosan #354 #1262 +- Add support for fixed Table Layout @aoloe @ekopach @troosan #841 #1276 +- Add support for Cell Spacing @dox07 @troosan #1040 +- Add parsing of formatting inside lists @atomicalnet @troosan #594 +- Added support for Vertically Raised or Lowered Text (w:position) @anrikun @troosan #640 +- Add support for MACROBUTTON field @phryneas @troosan #1021 +- Add support for Hyphenation @Trainmaster #1282 (Document: `autoHyphenation`, `consecutiveHyphenLimit`, `hyphenationZone`, `doNotHyphenateCaps`, Paragraph: `suppressAutoHyphens`) +- Added support for Floating Table Positioning (tblpPr) @anrikun #639 +- Added support for Image text wrapping distance @troosan #1310 +- Added parsing of CSS line-height and text-indent in HTML reader @troosan #1316 +- Added the ability to enable gridlines and axislabels on charts @FrankMeyer #576 +- Add support for table indent (tblInd) @Trainmaster #1343 +- Added parsing of internal links in HTML reader @lalop #1336 +- Several improvements to charts @JAEK-S #1332 +- Add parsing of html image in base64 format @jgpATs2w #1382 +- Added Support for Indentation & Tabs on RTF Writer. @smaug1985 #1405 +- Allows decimal numbers in HTML line-height style @jgpATs2w #1413 + +### Fixed +- Fix reading of docx default style - @troosan #1238 +- Fix the size unit of when parsing html images - @troosan #1254 +- Fixed HTML parsing of nested lists - @troosan #1265 +- Save PNG alpha information when using remote images. @samsullivan #779 +- Fix parsing of `<w:br/>` tag. @troosan #1274 +- Bookmark are not writton as internal link in html writer @troosan #1263 +- It should be possible to add a Footnote in a ListItemRun @troosan #1287 #1287 +- Fix colspan and rowspan for tables in HTML Writer @mattbolt #1292 +- Fix parsing of Heading and Title formating @troosan @gthomas2 #465 +- Fix Dateformat typo, fix hours casing, add Month-Day-Year formats @ComputerTinker #591 +- Support reading of w:drawing for documents produced by word 2011+ @gthomas2 #464 #1324 +- Fix missing column width in ODText writer @potofcoffee #413 +- Disable entity loader before parsing XML to avoid XXE injection @Tom4t0 #1427 + +### Changed +- Remove zend-stdlib dependency @Trainmaster #1284 +- The default unit for `\PhpOffice\PhpWord\Style\Image` changed from `px` to `pt`. + +### Miscelaneous +- Drop GitHub pages, switch to coveralls for code coverage analysis @czosel #1360 + v0.14.0 (29 Dec 2017) ---------------------- This release fixes several bugs and adds some new features. @@ -30,7 +76,8 @@ This version brings compatibility with PHP 7.0 & 7.1 ### Fixed - Loosen dependency to Zend - Images are not being printed when generating PDF - @hubertinio #1074 #431 -- Fixed some PHP 7 warnings - @likeuntomurphy #927 +- Fixed some PHP 7 warnings - @ likeuntomurphy #927 +- Fixed PHP 7.2 compatibility (renamed `Object` class names to `ObjectElement`) - @SailorMax #1185 - Fixed Word 97 reader - @alsofronie @Benpxpx @mario-rivera #912 #920 #892 - Fixed image loading over https - @troosan #988 - Impossibility to set different even and odd page headers - @troosan #981 @@ -50,6 +97,8 @@ This version brings compatibility with PHP 7.0 & 7.1 ### Deprecated - PhpWord->getProtection(), get it from the settings instead PhpWord->getSettings()->getDocumentProtection(); + + v0.13.0 (31 July 2016) ------------------- This release brings several improvements in `TemplateProcessor`, automatic output escaping feature for OOXML, ODF, HTML, and RTF (turned off, by default). @@ -69,7 +118,7 @@ Manual installation feature has been dropped since the release. Please, use [Com - Improved error message for the case when `autoload.php` is not found. - @RomanSyroeshko #371 - Renamed the `align` option of `NumberingLevel`, `Frame`, `Table`, and `Paragraph` styles into `alignment`. - @RomanSyroeshko - Improved performance of `TemplateProcessor::setValue()`. - @kazitanvirahsan #614, #617 -- Fixed some HTML tags not rendering any output (p, header & table) - #257, #324 - @twmobius and @garethellis +- Fixed some HTML tags not rendering any output (p, header & table) - #257, #324 - @twmobius and @garethellis ### Deprecated - `getAlign` and `setAlign` methods of `NumberingLevel`, `Frame`, `Table`, and `Paragraph` styles. @@ -447,4 +496,4 @@ This is the first release after a long development hiatus in [CodePlex](https:// - Basic CI with Travis - @Progi1984 - Added PHPWord_Exception and exception when could not copy the template - @Progi1984 - IMPROVED: Moved examples out of Classes directory - @Progi1984 -- IMPROVED: Advanced string replace in setValue for Template - @Esmeraldo [#49](http://phpword.codeplex.com/workitem/49) \ No newline at end of file +- IMPROVED: Advanced string replace in setValue for Template - @Esmeraldo [#49](http://phpword.codeplex.com/workitem/49) diff --git a/civicrm/vendor/phpoffice/phpword/CONTRIBUTING.md b/civicrm/vendor/phpoffice/phpword/CONTRIBUTING.md index 335ad2d519..e62f2e6f04 100644 --- a/civicrm/vendor/phpoffice/phpword/CONTRIBUTING.md +++ b/civicrm/vendor/phpoffice/phpword/CONTRIBUTING.md @@ -6,7 +6,7 @@ We want to create a high quality document writer and reader library that people - **Be brief, but be bold**. State your issues briefly. But speak out your ideas loudly, even if you can't or don't know how to implement it right away. The world will be better with limitless innovations. - **Follow PHP-FIG standards**. We follow PHP Standards Recommendations (PSRs) by [PHP Framework Interoperability Group](http://www.php-fig.org/). If you're not familiar with these standards, please, [familiarize yourself now](https://github.com/php-fig/fig-standards). Also, please, use [PHPCodeSniffer](http://pear.php.net/package/PHP_CodeSniffer/) to validate your code against PSRs. -- **Test your code**. Nobody else knows your code better than you. So, it's completely yours mission to test the changes you made before pull request submission. We use [PHPUnit](https://phpunit.de/) for our testing purposes and recommend you using this tool too. [Here](https://phpunit.de/presentations.html) you can find PHPUnit best practices and additional information on effective unit testing, which helps us making PHPWord better day to day. Do not hesitate to smoke it carefully. It's a great investment in quality of your work, and it saves you years of life. +- **Test your code**. Nobody else knows your code better than you. So, it's completely your mission to test the changes you made before pull request submission. We use [PHPUnit](https://phpunit.de/) for our testing purposes and recommend you using this tool too. [Here](https://phpunit.de/presentations.html) you can find PHPUnit best practices and additional information on effective unit testing, which helps us making PHPWord better day to day. Do not hesitate to smoke it carefully. It's a great investment in quality of your work, and it saves you years of life. - **Request pull in separate branch**. Do not submit your request to the master branch. But create a separate branch named specifically for the issue that you addressed. Read [GitHub manual](https://help.github.com/articles/using-pull-requests) to find out more about this. If you are new to GitHub, read [this short manual](https://help.github.com/articles/fork-a-repo) to get yourself familiar with forks and how git works in general. [This video](http://www.youtube.com/watch?v=-zvHQXnBO6c) explains how to synchronize your Github Fork with the Branch of PHPWord. That's it. Thank you for your interest in PHPWord, and welcome! diff --git a/civicrm/vendor/phpoffice/phpword/PATCHES.txt b/civicrm/vendor/phpoffice/phpword/PATCHES.txt new file mode 100644 index 0000000000..0489e69c3a --- /dev/null +++ b/civicrm/vendor/phpoffice/phpword/PATCHES.txt @@ -0,0 +1,7 @@ +This file was automatically generated by Composer Patches (https://github.com/cweagans/composer-patches) +Patches applied to this directory: + +Fix handling of libxml_disable_entity_loader +Source: tools/scripts/composer/patches/phpword-libxml-fix-global-handling.patch + + diff --git a/civicrm/vendor/phpoffice/phpword/README.md b/civicrm/vendor/phpoffice/phpword/README.md index ac5f3b958b..7531a6bc11 100644 --- a/civicrm/vendor/phpoffice/phpword/README.md +++ b/civicrm/vendor/phpoffice/phpword/README.md @@ -3,14 +3,14 @@ [](https://packagist.org/packages/phpoffice/phpword) [](https://travis-ci.org/PHPOffice/PHPWord) [](https://scrutinizer-ci.com/g/PHPOffice/PHPWord/) -[](https://scrutinizer-ci.com/g/PHPOffice/PHPWord/) +[](https://coveralls.io/github/PHPOffice/PHPWord?branch=develop) [](https://packagist.org/packages/phpoffice/phpword) [](https://packagist.org/packages/phpoffice/phpword) [](https://gitter.im/PHPOffice/PHPWord) PHPWord is a library written in pure PHP that provides a set of classes to write to and read from different document file formats. The current version of PHPWord supports Microsoft [Office Open XML](http://en.wikipedia.org/wiki/Office_Open_XML) (OOXML or OpenXML), OASIS [Open Document Format for Office Applications](http://en.wikipedia.org/wiki/OpenDocument) (OpenDocument or ODF), [Rich Text Format](http://en.wikipedia.org/wiki/Rich_Text_Format) (RTF), HTML, and PDF. -PHPWord is an open source project licensed under the terms of [LGPL version 3](https://github.com/PHPOffice/PHPWord/blob/develop/COPYING.LESSER). PHPWord is aimed to be a high quality software product by incorporating [continuous integration](https://travis-ci.org/PHPOffice/PHPWord) and [unit testing](http://phpoffice.github.io/PHPWord/coverage/develop/). You can learn more about PHPWord by reading the [Developers' Documentation](http://phpword.readthedocs.org/) and the [API Documentation](http://phpoffice.github.io/PHPWord/docs/develop/). +PHPWord is an open source project licensed under the terms of [LGPL version 3](https://github.com/PHPOffice/PHPWord/blob/develop/COPYING.LESSER). PHPWord is aimed to be a high quality software product by incorporating [continuous integration](https://travis-ci.org/PHPOffice/PHPWord) and [unit testing](http://phpoffice.github.io/PHPWord/coverage/develop/). You can learn more about PHPWord by reading the [Developers' Documentation](http://phpword.readthedocs.org/). If you have any questions, please ask on [StackOverFlow](https://stackoverflow.com/questions/tagged/phpword) @@ -22,7 +22,6 @@ Read more about PHPWord: - [Getting started](#getting-started) - [Contributing](#contributing) - [Developers' Documentation](http://phpword.readthedocs.org/) -- [API Documentation](http://phpoffice.github.io/PHPWord/docs/master/) ## Features @@ -161,7 +160,8 @@ $objWriter->save('helloWorld.html'); /* Note: we skip PDF, because "HTML-to-PDF" approach is used to create PDF documents. */ ``` -More examples are provided in the [samples folder](samples/). You can also read the [Developers' Documentation](http://phpword.readthedocs.org/) and the [API Documentation](http://phpoffice.github.io/PHPWord/docs/master/) for more detail. +More examples are provided in the [samples folder](samples/). For an easy access to those samples launch `php -S localhost:8000` in the samples directory then browse to [http://localhost:8000](http://localhost:8000) to view the samples. +You can also read the [Developers' Documentation](http://phpword.readthedocs.org/) and the [API Documentation](http://phpoffice.github.io/PHPWord/docs/master/) for more detail. ## Contributing diff --git a/civicrm/vendor/phpoffice/phpword/VERSION b/civicrm/vendor/phpoffice/phpword/VERSION deleted file mode 100644 index 51de3305bb..0000000000 --- a/civicrm/vendor/phpoffice/phpword/VERSION +++ /dev/null @@ -1 +0,0 @@ -0.13.0 \ No newline at end of file diff --git a/civicrm/vendor/phpoffice/phpword/bootstrap.php b/civicrm/vendor/phpoffice/phpword/bootstrap.php index 362e8b74e9..740e3d044c 100644 --- a/civicrm/vendor/phpoffice/phpword/bootstrap.php +++ b/civicrm/vendor/phpoffice/phpword/bootstrap.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. test bootstrap * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/composer.json b/civicrm/vendor/phpoffice/phpword/composer.json index 3cc4b131cf..5d8a855b53 100644 --- a/civicrm/vendor/phpoffice/phpword/composer.json +++ b/civicrm/vendor/phpoffice/phpword/composer.json @@ -35,33 +35,46 @@ } ], "scripts": { + "test": [ + "phpunit --color=always" + ], + "test-no-coverage": [ + "phpunit --color=always --no-coverage" + ], "check": [ - "./vendor/bin/php-cs-fixer fix --ansi --dry-run --diff", - "./vendor/bin/phpcs --report-width=200 --report-summary --report-full samples/ src/ tests/ --ignore=src/PhpWord/Shared/PCLZip --standard=PSR2 -n", - "./vendor/bin/phpmd src/,tests/ text ./phpmd.xml.dist --exclude pclzip.lib.php", - "./vendor/bin/phpunit --color=always" + "php-cs-fixer fix --ansi --dry-run --diff", + "phpcs --report-width=200 --report-summary --report-full samples/ src/ tests/ --ignore=src/PhpWord/Shared/PCLZip --standard=PSR2 -n", + "phpmd src/,tests/ text ./phpmd.xml.dist --exclude pclzip.lib.php", + "@test" ], "fix": [ - "./vendor/bin/php-cs-fixer fix --ansi" + "php-cs-fixer fix --ansi" ] }, + "scripts-descriptions": { + "test": "Runs all unit tests", + "test-no-coverage": "Runs all unit tests, without code coverage", + "check": "Runs PHP CheckStyle and PHP Mess detector", + "fix": "Fixes issues found by PHP-CS" + }, "require": { "php": "^5.3.3 || ^7.0", "ext-xml": "*", "zendframework/zend-escaper": "^2.2", - "zendframework/zend-stdlib": "^2.2 || ^3.0", - "phpoffice/common": "^0.2" + "phpoffice/common": "^0.2.9" }, "require-dev": { - "phpunit/phpunit": "^4.8.36 || ^5.0", - "phpdocumentor/phpdocumentor":"2.*", - "squizlabs/php_codesniffer": "^2.7", - "friendsofphp/php-cs-fixer": "^2.0", + "ext-zip": "*", + "ext-gd": "*", + "phpunit/phpunit": "^4.8.36 || ^7.0", + "squizlabs/php_codesniffer": "^2.9", + "friendsofphp/php-cs-fixer": "^2.2", "phpmd/phpmd": "2.*", "phploc/phploc": "2.* || 3.* || 4.*", "dompdf/dompdf":"0.8.*", "tecnickcom/tcpdf": "6.*", - "mpdf/mpdf": "5.* || 6.* || 7.*" + "mpdf/mpdf": "5.7.4 || 6.* || 7.*", + "php-coveralls/php-coveralls": "1.1.0 || ^2.0" }, "suggest": { "ext-zip": "Allows writing OOXML and ODF", @@ -74,5 +87,10 @@ "psr-4": { "PhpOffice\\PhpWord\\": "src/PhpWord" } + }, + "extra": { + "branch-alias": { + "dev-develop": "0.16-dev" + } } } diff --git a/civicrm/vendor/phpoffice/phpword/phpmd.xml.dist b/civicrm/vendor/phpoffice/phpword/phpmd.xml.dist deleted file mode 100644 index 44b3efdf66..0000000000 --- a/civicrm/vendor/phpoffice/phpword/phpmd.xml.dist +++ /dev/null @@ -1,33 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<ruleset name="PHPWord PHP Mess Detector Rule Set" - xmlns="http://pmd.sf.net/ruleset/1.0.0" - xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:schemaLocation="http://pmd.sf.net/ruleset/1.0.0 http://pmd.sf.net/ruleset_xml_schema.xsd" - xsi:noNamespaceSchemaLocation="http://pmd.sf.net/ruleset_xml_schema.xsd"> - <rule ref="rulesets/naming.xml"> - <exclude name="LongVariable" /> - </rule> - <rule ref="rulesets/naming.xml/LongVariable"> - <properties> - <property name="maximum" value="32" /> - </properties> - </rule> - <rule ref="rulesets/design.xml/ExitExpression" /> - <rule ref="rulesets/design.xml/EvalExpression" /> - <rule ref="rulesets/design.xml/GotoStatement" /> - <rule ref="rulesets/design.xml/DepthOfInheritance" /> - <rule ref="rulesets/design.xml/CouplingBetweenObjects"> - <!-- AbstractContainer needs more coupling (default: 13) --> - <properties> - <property name="minimum" value="20" /> - </properties> - </rule> - <rule ref="rulesets/design.xml/NumberOfChildren"> - <!-- AbstractStyle needs more children (default: 15) --> - <properties> - <property name="minimum" value="30" /> - </properties> - </rule> - <rule ref="rulesets/unusedcode.xml" /> - <rule ref="rulesets/controversial.xml" /> -</ruleset> \ No newline at end of file diff --git a/civicrm/vendor/phpoffice/phpword/phpstan.neon b/civicrm/vendor/phpoffice/phpword/phpstan.neon deleted file mode 100644 index 5ae6d0f28a..0000000000 --- a/civicrm/vendor/phpoffice/phpword/phpstan.neon +++ /dev/null @@ -1,13 +0,0 @@ -includes: - - vendor/phpstan/phpstan/conf/config.level1.neon -parameters: - memory-limit: 200000 - autoload_directories: - - tests - autoload_files: - - tests/bootstrap.php - excludes_analyse: - - */pclzip.lib.php - - src/PhpWord/Shared/OLERead.php - - src/PhpWord/Reader/MsDoc.php - - src/PhpWord/Writer/PDF/MPDF.php \ No newline at end of file diff --git a/civicrm/vendor/phpoffice/phpword/phpunit.xml.dist b/civicrm/vendor/phpoffice/phpword/phpunit.xml.dist deleted file mode 100644 index 015dd2edd1..0000000000 --- a/civicrm/vendor/phpoffice/phpword/phpunit.xml.dist +++ /dev/null @@ -1,28 +0,0 @@ -<phpunit backupGlobals="false" - backupStaticAttributes="false" - bootstrap="./tests/bootstrap.php" - colors="true" - convertErrorsToExceptions="true" - convertNoticesToExceptions="true" - convertWarningsToExceptions="true" - processIsolation="false" - stopOnFailure="false" - syntaxCheck="false"> - <testsuites> - <testsuite name="PhpWord Test Suite"> - <directory>./tests/PhpWord</directory> - </testsuite> - </testsuites> - <filter> - <whitelist> - <directory suffix=".php">./src</directory> - <exclude> - <directory suffix=".php">./src/PhpWord/Shared/PCLZip</directory> - </exclude> - </whitelist> - </filter> - <logging> - <log type="coverage-html" target="./build/coverage" charset="UTF-8" highlight="true" /> - <log type="coverage-clover" target="./build/logs/clover.xml" /> - </logging> -</phpunit> \ No newline at end of file diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Collection/AbstractCollection.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Collection/AbstractCollection.php index 61709a5001..899ec28756 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Collection/AbstractCollection.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Collection/AbstractCollection.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ @@ -27,14 +27,14 @@ abstract class AbstractCollection /** * Items * - * @var array + * @var \PhpOffice\PhpWord\Element\AbstractContainer[] */ private $items = array(); /** * Get items * - * @return array + * @return \PhpOffice\PhpWord\Element\AbstractContainer[] */ public function getItems() { @@ -45,7 +45,7 @@ abstract class AbstractCollection * Get item by index * * @param int $index - * @return mixed + * @return \PhpOffice\PhpWord\Element\AbstractContainer */ public function getItem($index) { @@ -60,7 +60,7 @@ abstract class AbstractCollection * Set item. * * @param int $index - * @param mixed $item + * @param \PhpOffice\PhpWord\Element\AbstractContainer $item */ public function setItem($index, $item) { @@ -72,7 +72,7 @@ abstract class AbstractCollection /** * Add new item * - * @param mixed $item + * @param \PhpOffice\PhpWord\Element\AbstractContainer $item * @return int */ public function addItem($item) diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Collection/Bookmarks.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Collection/Bookmarks.php index 7210fb034e..b5ffd5f40a 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Collection/Bookmarks.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Collection/Bookmarks.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Collection/Charts.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Collection/Charts.php index 56d92c9411..aa807d1e58 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Collection/Charts.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Collection/Charts.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Collection/Comments.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Collection/Comments.php index f2fe82d921..b6c02d392f 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Collection/Comments.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Collection/Comments.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Collection/Endnotes.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Collection/Endnotes.php index 52a56d3130..db01b408db 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Collection/Endnotes.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Collection/Endnotes.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Collection/Footnotes.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Collection/Footnotes.php index 63989f53cd..a0a31ca494 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Collection/Footnotes.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Collection/Footnotes.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Collection/Titles.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Collection/Titles.php index 9e4f12cd60..1ea58ec0d6 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Collection/Titles.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Collection/Titles.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/ComplexType/FootnoteProperties.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/ComplexType/FootnoteProperties.php index 8cb3a869ee..e42c9f9d40 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/ComplexType/FootnoteProperties.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/ComplexType/FootnoteProperties.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/ComplexType/ProofState.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/ComplexType/ProofState.php index 6a915da1ba..4f8dafe3aa 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/ComplexType/ProofState.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/ComplexType/ProofState.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/ComplexType/TblWidth.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/ComplexType/TblWidth.php new file mode 100644 index 0000000000..0d1a2419a7 --- /dev/null +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/ComplexType/TblWidth.php @@ -0,0 +1,59 @@ +<?php +/** + * This file is part of PHPWord - A pure PHP library for reading and writing + * word processing documents. + * + * PHPWord is free software distributed under the terms of the GNU Lesser + * General Public License version 3 as published by the Free Software Foundation. + * + * For the full copyright and license information, please read the LICENSE + * file that was distributed with this source code. For the full list of + * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. + * + * @see https://github.com/PHPOffice/PHPWord + * @copyright 2010-2018 PHPWord contributors + * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 + */ + +namespace PhpOffice\PhpWord\ComplexType; + +use PhpOffice\PhpWord\SimpleType\TblWidth as TblWidthSimpleType; + +/** + * @see http://www.datypic.com/sc/ooxml/t-w_CT_TblWidth.html + */ +final class TblWidth +{ + /** @var string */ + private $type; + + /** @var int */ + private $value; + + /** + * @param int $value If omitted, then its value shall be assumed to be 0 + * @param string $type If omitted, then its value shall be assumed to be dxa + */ + public function __construct($value = 0, $type = TblWidthSimpleType::TWIP) + { + $this->value = $value; + TblWidthSimpleType::validate($type); + $this->type = $type; + } + + /** + * @return string + */ + public function getType() + { + return $this->type; + } + + /** + * @return int + */ + public function getValue() + { + return $this->value; + } +} diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/ComplexType/TrackChangesView.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/ComplexType/TrackChangesView.php index 3fc16298c1..92ea05eab3 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/ComplexType/TrackChangesView.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/ComplexType/TrackChangesView.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/AbstractContainer.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/AbstractContainer.php index e3022b50f2..204d4a7399 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/AbstractContainer.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/AbstractContainer.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ @@ -33,11 +33,10 @@ namespace PhpOffice\PhpWord\Element; * @method CheckBox addCheckBox(string $name, $text, mixed $fStyle = null, mixed $pStyle = null) * @method Title addTitle(string $text, int $depth = 1) * @method TOC addTOC(mixed $fontStyle = null, mixed $tocStyle = null, int $minDepth = 1, int $maxDepth = 9) - * * @method PageBreak addPageBreak() * @method Table addTable(mixed $style = null) - * @method Image addImage(string $source, mixed $style = null, bool $isWatermark = false) - * @method \PhpOffice\PhpWord\Element\Object addObject(string $source, mixed $style = null) + * @method Image addImage(string $source, mixed $style = null, bool $isWatermark = false, $name = null) + * @method OLEObject addOLEObject(string $source, mixed $style = null) * @method TextBox addTextBox(mixed $style = null) * @method Field addField(string $type = null, array $properties = array(), array $options = array(), mixed $text = null) * @method Line addLine(mixed $lineStyle = null) @@ -46,6 +45,8 @@ namespace PhpOffice\PhpWord\Element; * @method FormField addFormField(string $type, mixed $fStyle = null, mixed $pStyle = null) * @method SDT addSDT(string $type) * + * @method \PhpOffice\PhpWord\Element\OLEObject addObject(string $source, mixed $style = null) deprecated, use addOLEObject instead + * * @since 0.10.0 */ abstract class AbstractContainer extends AbstractElement @@ -53,7 +54,7 @@ abstract class AbstractContainer extends AbstractElement /** * Elements collection * - * @var array + * @var \PhpOffice\PhpWord\Element\AbstractElement[] */ protected $elements = array(); @@ -80,14 +81,14 @@ abstract class AbstractContainer extends AbstractElement { $elements = array( 'Text', 'TextRun', 'Bookmark', 'Link', 'PreserveText', 'TextBreak', - 'ListItem', 'ListItemRun', 'Table', 'Image', 'Object', + 'ListItem', 'ListItemRun', 'Table', 'Image', 'Object', 'OLEObject', 'Footnote', 'Endnote', 'CheckBox', 'TextBox', 'Field', 'Line', 'Shape', 'Title', 'TOC', 'PageBreak', 'Chart', 'FormField', 'SDT', 'Comment', ); $functions = array(); foreach ($elements as $element) { - $functions['add' . strtolower($element)] = $element; + $functions['add' . strtolower($element)] = $element == 'Object' ? 'OLEObject' : $element; } // Run valid `add` command @@ -156,13 +157,48 @@ abstract class AbstractContainer extends AbstractElement /** * Get all elements * - * @return array + * @return \PhpOffice\PhpWord\Element\AbstractElement[] */ public function getElements() { return $this->elements; } + /** + * Returns the element at the requested position + * + * @param int $index + * @return \PhpOffice\PhpWord\Element\AbstractElement|null + */ + public function getElement($index) + { + if (array_key_exists($index, $this->elements)) { + return $this->elements[$index]; + } + + return null; + } + + /** + * Removes the element at requested index + * + * @param int|\PhpOffice\PhpWord\Element\AbstractElement $toRemove + */ + public function removeElement($toRemove) + { + if (is_int($toRemove) && array_key_exists($toRemove, $this->elements)) { + unset($this->elements[$toRemove]); + } elseif ($toRemove instanceof \PhpOffice\PhpWord\Element\AbstractElement) { + foreach ($this->elements as $key => $element) { + if ($element->getElementId() === $toRemove->getElementId()) { + unset($this->elements[$key]); + + return; + } + } + } + } + /** * Count elements * @@ -193,20 +229,20 @@ abstract class AbstractContainer extends AbstractElement 'Link' => $generalContainers, 'TextBreak' => $generalContainers, 'Image' => $generalContainers, - 'Object' => $generalContainers, + 'OLEObject' => $generalContainers, 'Field' => $generalContainers, 'Line' => $generalContainers, 'Shape' => $generalContainers, 'FormField' => $generalContainers, 'SDT' => $generalContainers, 'TrackChange' => $generalContainers, - 'TextRun' => array('Section', 'Header', 'Footer', 'Cell', 'TextBox', 'TrackChange'), + 'TextRun' => array('Section', 'Header', 'Footer', 'Cell', 'TextBox', 'TrackChange', 'ListItemRun'), 'ListItem' => array('Section', 'Header', 'Footer', 'Cell', 'TextBox'), 'ListItemRun' => array('Section', 'Header', 'Footer', 'Cell', 'TextBox'), 'Table' => array('Section', 'Header', 'Footer', 'Cell', 'TextBox'), 'CheckBox' => array('Section', 'Header', 'Footer', 'Cell', 'TextRun'), 'TextBox' => array('Section', 'Header', 'Footer', 'Cell'), - 'Footnote' => array('Section', 'TextRun', 'Cell'), + 'Footnote' => array('Section', 'TextRun', 'Cell', 'ListItemRun'), 'Endnote' => array('Section', 'TextRun', 'Cell'), 'PreserveText' => array('Section', 'Header', 'Footer', 'Cell'), 'Title' => array('Section', 'Cell'), diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/AbstractElement.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/AbstractElement.php index a65c50f4d2..e3e54ed426 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/AbstractElement.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/AbstractElement.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ @@ -93,6 +93,20 @@ abstract class AbstractElement */ private $nestedLevel = 0; + /** + * A reference to the parent + * + * @var \PhpOffice\PhpWord\Element\AbstractElement + */ + private $parent; + + /** + * changed element info + * + * @var TrackChange + */ + private $trackChange; + /** * Parent container type * @@ -321,6 +335,11 @@ abstract class AbstractElement $this->commentRangeEnd->setEndElement($this); } + public function getParent() + { + return $this->parent; + } + /** * Set parent container * @@ -328,9 +347,10 @@ abstract class AbstractElement * * @param \PhpOffice\PhpWord\Element\AbstractElement $container */ - public function setParentContainer(AbstractElement $container) + public function setParentContainer(self $container) { $this->parentContainer = substr(get_class($container), strrpos(get_class($container), '\\') + 1); + $this->parent = $container; // Set nested level $this->nestedLevel = $container->getNestedLevel(); @@ -358,11 +378,14 @@ abstract class AbstractElement */ private function setMediaRelation() { - if (!$this instanceof Link && !$this instanceof Image && !$this instanceof Object) { + if (!$this instanceof Link && !$this instanceof Image && !$this instanceof OLEObject) { return; } $elementName = substr(get_class($this), strrpos(get_class($this), '\\') + 1); + if ($elementName == 'OLEObject') { + $elementName = 'Object'; + } $mediaPart = $this->getMediaPart(); $source = $this->getSource(); $image = null; @@ -372,7 +395,7 @@ abstract class AbstractElement $rId = Media::addElement($mediaPart, strtolower($elementName), $source, $image); $this->setRelationId($rId); - if ($this instanceof Object) { + if ($this instanceof OLEObject) { $icon = $this->getIcon(); $rId = Media::addElement($mediaPart, 'image', $icon, new Image($icon)); $this->setImageRelationId($rId); @@ -422,6 +445,38 @@ abstract class AbstractElement return $style; } + /** + * Sets the trackChange information + * + * @param TrackChange $trackChange + */ + public function setTrackChange(TrackChange $trackChange) + { + $this->trackChange = $trackChange; + } + + /** + * Gets the trackChange information + * + * @return TrackChange + */ + public function getTrackChange() + { + return $this->trackChange; + } + + /** + * Set changed + * + * @param string $type INSERTED|DELETED + * @param string $author + * @param null|int|\DateTime $date allways in UTC + */ + public function setChangeInfo($type, $author, $date = null) + { + $this->trackChange = new TrackChange($type, $author, $date); + } + /** * Set enum value * diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/Bookmark.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/Bookmark.php index 2eceb5ed89..16b020d741 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/Bookmark.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/Bookmark.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ @@ -43,7 +43,7 @@ class Bookmark extends AbstractElement * * @param string $name */ - public function __construct($name) + public function __construct($name = '') { $this->name = CommonText::toUTF8($name); } diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/Cell.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/Cell.php index b5250cd6c3..68f5df6255 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/Cell.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/Cell.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/Chart.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/Chart.php index c340da4058..92152c877d 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/Chart.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/Chart.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ @@ -61,11 +61,12 @@ class Chart extends AbstractElement * @param array $categories * @param array $values * @param array $style + * @param null|mixed $seriesName */ - public function __construct($type, $categories, $values, $style = null) + public function __construct($type, $categories, $values, $style = null, $seriesName = null) { $this->setType($type); - $this->addSeries($categories, $values); + $this->addSeries($categories, $values, $seriesName); $this->style = $this->setNewStyle(new ChartStyle(), $style, true); } @@ -86,7 +87,7 @@ class Chart extends AbstractElement */ public function setType($value) { - $enum = array('pie', 'doughnut', 'line', 'bar', 'column', 'area', 'radar', 'scatter'); + $enum = array('pie', 'doughnut', 'line', 'bar', 'stacked_bar', 'percent_stacked_bar', 'column', 'stacked_column', 'percent_stacked_column', 'area', 'radar', 'scatter'); $this->type = $this->setEnumVal($value, $enum, 'pie'); } @@ -95,10 +96,15 @@ class Chart extends AbstractElement * * @param array $categories * @param array $values + * @param null|mixed $name */ - public function addSeries($categories, $values) + public function addSeries($categories, $values, $name = null) { - $this->series[] = array('categories' => $categories, 'values' => $values); + $this->series[] = array( + 'categories' => $categories, + 'values' => $values, + 'name' => $name, + ); } /** diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/CheckBox.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/CheckBox.php index e0a94fdfcd..f3e87176ef 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/CheckBox.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/CheckBox.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/Comment.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/Comment.php index 188369292c..96ad15ef4e 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/Comment.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/Comment.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ @@ -55,12 +55,12 @@ class Comment extends TrackChange * Create a new Comment Element * * @param string $author - * @param \DateTime $date + * @param null|\DateTime $date * @param string $initials */ public function __construct($author, $date = null, $initials = null) { - parent::__construct($author, $date); + parent::__construct(null, $author, $date); $this->initials = $initials; } diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/Endnote.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/Endnote.php index b6e94fba14..b962719502 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/Endnote.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/Endnote.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/Field.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/Field.php index 7b33a4799d..2efc6b0b9f 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/Field.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/Field.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ @@ -48,12 +48,28 @@ class Field extends AbstractElement ), 'DATE' => array( 'properties' => array( - 'dateformat' => array('d-M-yyyy', 'dddd d MMMM yyyy', 'd MMMM yyyy', 'd-M-yy', 'yyyy-MM-dd', - 'd-MMM-yy', 'd/M/yyyy', 'd MMM. yy', 'd/M/yy', 'MMM-yy', 'd-M-yyy H:mm', 'd-M-yyyy H:mm:ss', - 'h:mm am/pm', 'h:mm:ss am/pm', 'HH:mm', 'HH:mm:ss', ), + 'dateformat' => array( + /* Generic formats */ + 'yyyy-MM-dd', 'yyyy-MM', 'MMM-yy', 'MMM-yyyy', 'h:mm am/pm', 'h:mm:ss am/pm', 'HH:mm', 'HH:mm:ss', + /* Day-Month-Year formats */ + 'dddd d MMMM yyyy', 'd MMMM yyyy', 'd-MMM-yy', 'd MMM. yy', + 'd-M-yy', 'd-M-yy h:mm', 'd-M-yy h:mm:ss', 'd-M-yy h:mm am/pm', 'd-M-yy h:mm:ss am/pm', 'd-M-yy HH:mm', 'd-M-yy HH:mm:ss', + 'd/M/yy', 'd/M/yy h:mm', 'd/M/yy h:mm:ss', 'd/M/yy h:mm am/pm', 'd/M/yy h:mm:ss am/pm', 'd/M/yy HH:mm', 'd/M/yy HH:mm:ss', + 'd-M-yyyy', 'd-M-yyyy h:mm', 'd-M-yyyy h:mm:ss', 'd-M-yyyy h:mm am/pm', 'd-M-yyyy h:mm:ss am/pm', 'd-M-yyyy HH:mm', 'd-M-yyyy HH:mm:ss', + 'd/M/yyyy', 'd/M/yyyy h:mm', 'd/M/yyyy h:mm:ss', 'd/M/yyyy h:mm am/pm', 'd/M/yyyy h:mm:ss am/pm', 'd/M/yyyy HH:mm', 'd/M/yyyy HH:mm:ss', + /* Month-Day-Year formats */ + 'dddd, MMMM d yyyy', 'MMMM d yyyy', 'MMM-d-yy', 'MMM. d yy', + 'M-d-yy', 'M-d-yy h:mm', 'M-d-yy h:mm:ss', 'M-d-yy h:mm am/pm', 'M-d-yy h:mm:ss am/pm', 'M-d-yy HH:mm', 'M-d-yy HH:mm:ss', + 'M/d/yy', 'M/d/yy h:mm', 'M/d/yy h:mm:ss', 'M/d/yy h:mm am/pm', 'M/d/yy h:mm:ss am/pm', 'M/d/yy HH:mm', 'M/d/yy HH:mm:ss', + 'M-d-yyyy', 'M-d-yyyy h:mm', 'M-d-yyyy h:mm:ss', 'M-d-yyyy h:mm am/pm', 'M-d-yyyy h:mm:ss am/pm', 'M-d-yyyy HH:mm', 'M-d-yyyy HH:mm:ss', + 'M/d/yyyy', 'M/d/yyyy h:mm', 'M/d/yyyy h:mm:ss', 'M/d/yyyy h:mm am/pm', 'M/d/yyyy h:mm:ss am/pm', 'M/d/yyyy HH:mm', 'M/d/yyyy HH:mm:ss', + ), ), 'options' => array('PreserveFormat', 'LunarCalendar', 'SakaEraCalendar', 'LastUsedFormat'), ), + 'MACROBUTTON' => array( + 'properties' => array('macroname' => ''), + ), 'XE' => array( 'properties' => array(), 'options' => array('Bold', 'Italic'), @@ -62,6 +78,10 @@ class Field extends AbstractElement 'properties' => array(), 'options' => array('PreserveFormat'), ), + 'STYLEREF' => array( + 'properties' => array('StyleIdentifier' => ''), + 'options' => array('PreserveFormat'), + ), ); /** @@ -92,6 +112,13 @@ class Field extends AbstractElement */ protected $options = array(); + /** + * Font style + * + * @var \PhpOffice\PhpWord\Style\Font + */ + protected $fontStyle; + /** * Create a new Field Element * diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/Footer.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/Footer.php index 08ff525a1f..0290d7c1de 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/Footer.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/Footer.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/Footnote.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/Footnote.php index e9a1bfc266..90aabccca9 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/Footnote.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/Footnote.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/FormField.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/FormField.php index 598d61dc2f..f937df59c4 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/FormField.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/FormField.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/Header.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/Header.php index ee8208773a..8a01946ea9 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/Header.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/Header.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/Image.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/Image.php index f1f6bab542..bae87ff5d8 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/Image.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/Image.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ @@ -65,6 +65,13 @@ class Image extends AbstractElement */ private $watermark; + /** + * Name of image + * + * @var string + */ + private $name; + /** * Image type * @@ -127,15 +134,17 @@ class Image extends AbstractElement * @param string $source * @param mixed $style * @param bool $watermark + * @param string $name * * @throws \PhpOffice\PhpWord\Exception\InvalidImageException * @throws \PhpOffice\PhpWord\Exception\UnsupportedImageTypeException */ - public function __construct($source, $style = null, $watermark = false) + public function __construct($source, $style = null, $watermark = false, $name = null) { $this->source = $source; - $this->setIsWatermark($watermark); $this->style = $this->setNewStyle(new ImageStyle(), $style, true); + $this->setIsWatermark($watermark); + $this->setName($name); $this->checkImage(); } @@ -170,6 +179,26 @@ class Image extends AbstractElement return $this->sourceType; } + /** + * Sets the image name + * + * @param string $value + */ + public function setName($value) + { + $this->name = $value; + } + + /** + * Get image name + * + * @return null|string + */ + public function getName() + { + return $this->name; + } + /** * Get image media ID * @@ -313,7 +342,7 @@ class Image extends AbstractElement $zip = new ZipArchive(); if ($zip->open($zipFilename) !== false) { - if ($zip->locateName($imageFilename)) { + if ($zip->locateName($imageFilename) !== false) { $isTemp = true; $zip->extractTo(Settings::getTempDir(), $imageFilename); $actualSource = Settings::getTempDir() . DIRECTORY_SEPARATOR . $imageFilename; @@ -334,6 +363,10 @@ class Image extends AbstractElement // Read image binary data and convert to hex/base64 string if ($this->sourceType == self::SOURCE_GD) { $imageResource = call_user_func($this->imageCreateFunc, $actualSource); + if ($this->imageType === 'image/png') { + // PNG images need to preserve alpha channel information + imagesavealpha($imageResource, true); + } ob_start(); call_user_func($this->imageFunc, $imageResource); $imageBinary = ob_get_contents(); @@ -454,7 +487,7 @@ class Image extends AbstractElement $zip = new ZipArchive(); if ($zip->open($zipFilename) !== false) { - if ($zip->locateName($imageFilename)) { + if ($zip->locateName($imageFilename) !== false) { $imageContent = $zip->getFromName($imageFilename); if ($imageContent !== false) { file_put_contents($tempFilename, $imageContent); diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/Line.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/Line.php index eba664730f..7e40b9402d 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/Line.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/Line.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/Link.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/Link.php index 4637120ab5..2bec32ddc4 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/Link.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/Link.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/ListItem.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/ListItem.php index 7f665b1b9f..8b064c47b5 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/ListItem.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/ListItem.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ @@ -62,7 +62,7 @@ class ListItem extends AbstractElement // Version >= 0.10.0 will pass numbering style name. Older version will use old method if (!is_null($listStyle) && is_string($listStyle)) { - $this->style = new ListItemStyle($listStyle); + $this->style = new ListItemStyle($listStyle); // @codeCoverageIgnore } else { $this->style = $this->setNewStyle(new ListItemStyle(), $listStyle, true); } diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/ListItemRun.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/ListItemRun.php index e311dc2470..6e48a69012 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/ListItemRun.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/ListItemRun.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord -* @copyright 2010-2017 PHPWord contributors +* @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/Object.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/OLEObject.php similarity index 96% rename from civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/Object.php rename to civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/OLEObject.php index 8fe83224bb..1a17b74753 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/Object.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/OLEObject.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ @@ -21,9 +21,9 @@ use PhpOffice\PhpWord\Exception\InvalidObjectException; use PhpOffice\PhpWord\Style\Image as ImageStyle; /** - * Object element + * OLEObject element */ -class Object extends AbstractElement +class OLEObject extends AbstractElement { /** * Ole-Object Src @@ -83,7 +83,7 @@ class Object extends AbstractElement $this->style = $this->setNewStyle(new ImageStyle(), $style, true); $this->icon = realpath(__DIR__ . "/../resources/{$ext}.png"); - return $this; + return; } throw new InvalidObjectException(); diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/PageBreak.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/PageBreak.php index e41e807bef..1e2ada80ad 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/PageBreak.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/PageBreak.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/PreserveText.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/PreserveText.php index ad20d7a30e..374f1a9984 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/PreserveText.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/PreserveText.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ @@ -29,7 +29,7 @@ class PreserveText extends AbstractElement /** * Text content * - * @var string + * @var string|array */ private $text; @@ -64,8 +64,6 @@ class PreserveText extends AbstractElement if (isset($matches[0])) { $this->text = $matches; } - - return $this; } /** @@ -91,7 +89,7 @@ class PreserveText extends AbstractElement /** * Get Text content * - * @return string + * @return string|array */ public function getText() { diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/Row.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/Row.php index 2e89b35495..da4dfe5d73 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/Row.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/Row.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/SDT.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/SDT.php index 86f445cc46..a866d1bdac 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/SDT.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/SDT.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/Section.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/Section.php index 06acf1f9b2..d612fc0172 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/Section.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/Section.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/Shape.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/Shape.php index b553a4ac5e..d143c9b694 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/Shape.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/Shape.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/TOC.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/TOC.php index e3ca0a08c2..c51d0e6be3 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/TOC.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/TOC.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/Table.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/Table.php index 3a045031aa..44fe3744bd 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/Table.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/Table.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ @@ -135,18 +135,40 @@ class Table extends AbstractElement public function countColumns() { $columnCount = 0; - if (is_array($this->rows)) { - $rowCount = count($this->rows); - for ($i = 0; $i < $rowCount; $i++) { - /** @var \PhpOffice\PhpWord\Element\Row $row Type hint */ - $row = $this->rows[$i]; - $cellCount = count($row->getCells()); - if ($columnCount < $cellCount) { - $columnCount = $cellCount; - } + + $rowCount = count($this->rows); + for ($i = 0; $i < $rowCount; $i++) { + /** @var \PhpOffice\PhpWord\Element\Row $row Type hint */ + $row = $this->rows[$i]; + $cellCount = count($row->getCells()); + if ($columnCount < $cellCount) { + $columnCount = $cellCount; } } return $columnCount; } + + /** + * The first declared cell width for each column + * + * @return int[] + */ + public function findFirstDefinedCellWidths() + { + $cellWidths = array(); + + foreach ($this->rows as $row) { + $cells = $row->getCells(); + if (count($cells) <= count($cellWidths)) { + continue; + } + $cellWidths = array(); + foreach ($cells as $cell) { + $cellWidths[] = $cell->getWidth(); + } + } + + return $cellWidths; + } } diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/Text.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/Text.php index 4de12176ca..f4d7f08185 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/Text.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/Text.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/TextBox.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/TextBox.php index 8058d0c983..b9f274d6b8 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/TextBox.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/TextBox.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/TextBreak.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/TextBreak.php index 4cf65f35c1..385fec5a84 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/TextBreak.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/TextBreak.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/TextRun.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/TextRun.php index 6d9ae9f4a1..9af55d4687 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/TextRun.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/TextRun.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/Title.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/Title.php index 808af55ebb..d01f7f339d 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/Title.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/Title.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ @@ -28,7 +28,7 @@ class Title extends AbstractElement /** * Title Text content * - * @var string + * @var string|TextRun */ private $text; @@ -56,18 +56,24 @@ class Title extends AbstractElement /** * Create a new Title Element * - * @param string $text + * @param string|TextRun $text * @param int $depth */ public function __construct($text, $depth = 1) { - $this->text = CommonText::toUTF8($text); - $this->depth = $depth; - if (array_key_exists("Heading_{$this->depth}", Style::getStyles())) { - $this->style = "Heading{$this->depth}"; + if (is_string($text)) { + $this->text = CommonText::toUTF8($text); + } elseif ($text instanceof TextRun) { + $this->text = $text; + } else { + throw new \InvalidArgumentException('Invalid text, should be a string or a TextRun'); } - return $this; + $this->depth = $depth; + $styleName = $depth === 0 ? 'Title' : "Heading_{$this->depth}"; + if (array_key_exists($styleName, Style::getStyles())) { + $this->style = str_replace('_', '', $styleName); + } } /** diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/TrackChange.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/TrackChange.php index 44327f263f..410ffb7c9e 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/TrackChange.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Element/TrackChange.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ @@ -20,14 +20,25 @@ namespace PhpOffice\PhpWord\Element; /** * TrackChange element * @see http://datypic.com/sc/ooxml/t-w_CT_TrackChange.html + * @see http://datypic.com/sc/ooxml/t-w_CT_RunTrackChange.html */ class TrackChange extends AbstractContainer { + const INSERTED = 'INSERTED'; + const DELETED = 'DELETED'; + /** * @var string Container type */ protected $container = 'TrackChange'; + /** + * The type of change, (insert or delete), not applicable for PhpOffice\PhpWord\Element\Comment + * + * @var string + */ + private $changeType; + /** * Author * @@ -45,13 +56,17 @@ class TrackChange extends AbstractContainer /** * Create a new TrackChange Element * + * @param string $changeType * @param string $author - * @param \DateTime $date + * @param null|int|\DateTime $date */ - public function __construct($author, \DateTime $date = null) + public function __construct($changeType = null, $author = null, $date = null) { + $this->changeType = $changeType; $this->author = $author; - $this->date = $date; + if ($date !== null) { + $this->date = ($date instanceof \DateTime) ? $date : new \DateTime('@' . $date); + } } /** @@ -73,4 +88,14 @@ class TrackChange extends AbstractContainer { return $this->date; } + + /** + * Get the Change type + * + * @return string + */ + public function getChangeType() + { + return $this->changeType; + } } diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Escaper/AbstractEscaper.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Escaper/AbstractEscaper.php index 8207e2c67f..1575c069e2 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Escaper/AbstractEscaper.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Escaper/AbstractEscaper.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Escaper/EscaperInterface.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Escaper/EscaperInterface.php index 1ef35c1b06..deb2cfbc0e 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Escaper/EscaperInterface.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Escaper/EscaperInterface.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Escaper/RegExp.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Escaper/RegExp.php index 2f4e12ecde..f69aad8217 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Escaper/RegExp.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Escaper/RegExp.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Escaper/Rtf.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Escaper/Rtf.php index 35f91ada5b..b8e0b2169c 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Escaper/Rtf.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Escaper/Rtf.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Escaper/Xml.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Escaper/Xml.php index 81cedaa956..a769c5e189 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Escaper/Xml.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Escaper/Xml.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Exception/CopyFileException.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Exception/CopyFileException.php index a5c1da6a84..d1c3bd0123 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Exception/CopyFileException.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Exception/CopyFileException.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Exception/CreateTemporaryFileException.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Exception/CreateTemporaryFileException.php index fafc8dac5a..c8a06429d8 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Exception/CreateTemporaryFileException.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Exception/CreateTemporaryFileException.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Exception/Exception.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Exception/Exception.php index b94ed1befb..d874625cdc 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Exception/Exception.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Exception/Exception.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Exception/InvalidImageException.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Exception/InvalidImageException.php index 0a7b8fedd4..07c966815a 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Exception/InvalidImageException.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Exception/InvalidImageException.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Exception/InvalidObjectException.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Exception/InvalidObjectException.php index 540155065d..d8fef9613e 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Exception/InvalidObjectException.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Exception/InvalidObjectException.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Exception/InvalidStyleException.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Exception/InvalidStyleException.php index e697f6cff6..58c1961ddd 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Exception/InvalidStyleException.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Exception/InvalidStyleException.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Exception/UnsupportedImageTypeException.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Exception/UnsupportedImageTypeException.php index 73b41d049c..ee27065345 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Exception/UnsupportedImageTypeException.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Exception/UnsupportedImageTypeException.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/IOFactory.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/IOFactory.php index eed1f1630f..3929f485e4 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/IOFactory.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/IOFactory.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Media.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Media.php index d987901054..cc1b290312 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Media.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Media.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Metadata/Compatibility.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Metadata/Compatibility.php index 69f6f98a70..bf0363aa1a 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Metadata/Compatibility.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Metadata/Compatibility.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Metadata/DocInfo.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Metadata/DocInfo.php index 09714f9e0c..27ef89aecb 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Metadata/DocInfo.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Metadata/DocInfo.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Metadata/Protection.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Metadata/Protection.php index 39ebc3dead..15aa3ff189 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Metadata/Protection.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Metadata/Protection.php @@ -11,13 +11,13 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ namespace PhpOffice\PhpWord\Metadata; -use PhpOffice\PhpWord\Shared\Microsoft\PasswordEncoder; +use PhpOffice\Common\Microsoft\PasswordEncoder; use PhpOffice\PhpWord\SimpleType\DocProtect; /** @@ -113,7 +113,7 @@ class Protection /** * Set password * - * @param $password + * @param string $password * @return self */ public function setPassword($password) @@ -136,7 +136,7 @@ class Protection /** * Set count for hash iterations * - * @param $spinCount + * @param int $spinCount * @return self */ public function setSpinCount($spinCount) @@ -159,7 +159,7 @@ class Protection /** * Set algorithm * - * @param $algorithm + * @param string $algorithm * @return self */ public function setAlgorithm($algorithm) diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Metadata/Settings.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Metadata/Settings.php index 728cc823fd..b1552e0210 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Metadata/Settings.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Metadata/Settings.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ @@ -130,6 +130,32 @@ class Settings */ private $decimalSymbol = '.'; + /** + * Automatically hyphenate document contents when displayed + * + * @var bool|null + */ + private $autoHyphenation; + + /** + * Maximum number of consecutively hyphenated lines + * + * @var int|null + */ + private $consecutiveHyphenLimit; + + /** + * The allowed amount of whitespace before hyphenation is applied + * @var float|null + */ + private $hyphenationZone; + + /** + * Do not hyphenate words in all capital letters + * @var bool|null + */ + private $doNotHyphenateCaps; + /** * @return Protection */ @@ -387,4 +413,68 @@ class Settings { $this->decimalSymbol = $decimalSymbol; } + + /** + * @return bool|null + */ + public function hasAutoHyphenation() + { + return $this->autoHyphenation; + } + + /** + * @param bool $autoHyphenation + */ + public function setAutoHyphenation($autoHyphenation) + { + $this->autoHyphenation = (bool) $autoHyphenation; + } + + /** + * @return int|null + */ + public function getConsecutiveHyphenLimit() + { + return $this->consecutiveHyphenLimit; + } + + /** + * @param int $consecutiveHyphenLimit + */ + public function setConsecutiveHyphenLimit($consecutiveHyphenLimit) + { + $this->consecutiveHyphenLimit = (int) $consecutiveHyphenLimit; + } + + /** + * @return float|null + */ + public function getHyphenationZone() + { + return $this->hyphenationZone; + } + + /** + * @param float $hyphenationZone Measurement unit is twip + */ + public function setHyphenationZone($hyphenationZone) + { + $this->hyphenationZone = $hyphenationZone; + } + + /** + * @return null|bool + */ + public function hasDoNotHyphenateCaps() + { + return $this->doNotHyphenateCaps; + } + + /** + * @param bool $doNotHyphenateCaps + */ + public function setDoNotHyphenateCaps($doNotHyphenateCaps) + { + $this->doNotHyphenateCaps = (bool) $doNotHyphenateCaps; + } } diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/PhpWord.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/PhpWord.php index d7c2348a63..a78df2c4e5 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/PhpWord.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/PhpWord.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ @@ -35,10 +35,10 @@ use PhpOffice\PhpWord\Exception\Exception; * @method int addChart(Element\Chart $chart) * @method int addComment(Element\Comment $comment) * - * @method Style\Paragraph addParagraphStyle(string $styleName, array $styles) + * @method Style\Paragraph addParagraphStyle(string $styleName, mixed $styles) * @method Style\Font addFontStyle(string $styleName, mixed $fontStyle, mixed $paragraphStyle = null) * @method Style\Font addLinkStyle(string $styleName, mixed $styles) - * @method Style\Font addTitleStyle(int $depth, mixed $fontStyle, mixed $paragraphStyle = null) + * @method Style\Font addTitleStyle(mixed $depth, mixed $fontStyle, mixed $paragraphStyle = null) * @method Style\Table addTableStyle(string $styleName, mixed $styleTable, mixed $styleFirstRow = null) * @method Style\Numbering addNumberingStyle(string $styleName, mixed $styles) */ @@ -52,8 +52,17 @@ class PhpWord * @const string|int */ const DEFAULT_FONT_NAME = Settings::DEFAULT_FONT_NAME; + /** + * @deprecated 0.11.0 Use Settings constants + */ const DEFAULT_FONT_SIZE = Settings::DEFAULT_FONT_SIZE; + /** + * @deprecated 0.11.0 Use Settings constants + */ const DEFAULT_FONT_COLOR = Settings::DEFAULT_FONT_COLOR; + /** + * @deprecated 0.11.0 Use Settings constants + */ const DEFAULT_FONT_CONTENT_TYPE = Settings::DEFAULT_FONT_CONTENT_TYPE; /** @@ -85,6 +94,10 @@ class PhpWord */ public function __construct() { + // Reset Media and styles + Media::resetElements(); + Style::resetStyles(); + // Collection $collections = array('Bookmarks', 'Titles', 'Footnotes', 'Endnotes', 'Charts', 'Comments'); foreach ($collections as $collection) { @@ -212,6 +225,21 @@ class PhpWord return $this->sections; } + /** + * Returns the section at the requested position + * + * @param int $index + * @return \PhpOffice\PhpWord\Element\Section|null + */ + public function getSection($index) + { + if (array_key_exists($index, $this->sections)) { + return $this->sections[$index]; + } + + return null; + } + /** * Create new section * @@ -227,6 +255,17 @@ class PhpWord return $section; } + /** + * Sorts the sections using the callable passed + * + * @see http://php.net/manual/en/function.usort.php for usage + * @param callable $sorter + */ + public function sortSections($sorter) + { + usort($this->sections, $sorter); + } + /** * Get default font name * diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Reader/AbstractReader.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Reader/AbstractReader.php index f59a955683..7db285f758 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Reader/AbstractReader.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Reader/AbstractReader.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Reader/HTML.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Reader/HTML.php index 4e8b5e8227..db9f20891c 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Reader/HTML.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Reader/HTML.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Reader/MsDoc.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Reader/MsDoc.php index c134377ad7..d494522955 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Reader/MsDoc.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Reader/MsDoc.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Reader/ODText.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Reader/ODText.php index 5a22b4bac0..0b58dc50e1 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Reader/ODText.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Reader/ODText.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Reader/ODText/AbstractPart.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Reader/ODText/AbstractPart.php index bdac3b6fdb..ff664e01fa 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Reader/ODText/AbstractPart.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Reader/ODText/AbstractPart.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Reader/ODText/Content.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Reader/ODText/Content.php index 8843d8a276..9dfd645320 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Reader/ODText/Content.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Reader/ODText/Content.php @@ -11,13 +11,14 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ namespace PhpOffice\PhpWord\Reader\ODText; use PhpOffice\Common\XMLReader; +use PhpOffice\PhpWord\Element\TrackChange; use PhpOffice\PhpWord\PhpWord; /** @@ -37,6 +38,8 @@ class Content extends AbstractPart $xmlReader = new XMLReader(); $xmlReader->getDomFromZip($this->docFile, $this->xmlFile); + $trackedChanges = array(); + $nodes = $xmlReader->getElements('office:body/office:text/*'); if ($nodes->length > 0) { $section = $phpWord->addSection(); @@ -48,7 +51,37 @@ class Content extends AbstractPart $section->addTitle($node->nodeValue, $depth); break; case 'text:p': // Paragraph - $section->addText($node->nodeValue); + $children = $node->childNodes; + foreach ($children as $child) { + switch ($child->nodeName) { + case 'text:change-start': + $changeId = $child->getAttribute('text:change-id'); + if (isset($trackedChanges[$changeId])) { + $changed = $trackedChanges[$changeId]; + } + break; + case 'text:change-end': + unset($changed); + break; + case 'text:change': + $changeId = $child->getAttribute('text:change-id'); + if (isset($trackedChanges[$changeId])) { + $changed = $trackedChanges[$changeId]; + } + break; + } + } + + $element = $section->addText($node->nodeValue); + if (isset($changed) && is_array($changed)) { + $element->setTrackChange($changed['changed']); + if (isset($changed['textNodes'])) { + foreach ($changed['textNodes'] as $changedNode) { + $element = $section->addText($changedNode->nodeValue); + $element->setTrackChange($changed['changed']); + } + } + } break; case 'text:list': // List $listItems = $xmlReader->getElements('text:list-item/text:p', $node); @@ -57,6 +90,21 @@ class Content extends AbstractPart $section->addListItem($listItem->nodeValue, 0); } break; + case 'text:tracked-changes': + $changedRegions = $xmlReader->getElements('text:changed-region', $node); + foreach ($changedRegions as $changedRegion) { + $type = ($changedRegion->firstChild->nodeName == 'text:insertion') ? TrackChange::INSERTED : TrackChange::DELETED; + $creatorNode = $xmlReader->getElements('office:change-info/dc:creator', $changedRegion->firstChild); + $author = $creatorNode[0]->nodeValue; + $dateNode = $xmlReader->getElements('office:change-info/dc:date', $changedRegion->firstChild); + $date = $dateNode[0]->nodeValue; + $date = preg_replace('/\.\d+$/', '', $date); + $date = \DateTime::createFromFormat('Y-m-d\TH:i:s', $date); + $changed = new TrackChange($type, $author, $date); + $textNodes = $xmlReader->getElements('text:deletion/text:p', $changedRegion); + $trackedChanges[$changedRegion->getAttribute('text:id')] = array('changed' => $changed, 'textNodes'=> $textNodes); + } + break; } } } diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Reader/ODText/Meta.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Reader/ODText/Meta.php index 98832d175c..8801a5439a 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Reader/ODText/Meta.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Reader/ODText/Meta.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Reader/RTF.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Reader/RTF.php index 2d09a04d2c..620252ffd7 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Reader/RTF.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Reader/RTF.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Reader/RTF/Document.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Reader/RTF/Document.php index be16d707ba..b9509d71fe 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Reader/RTF/Document.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Reader/RTF/Document.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Reader/ReaderInterface.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Reader/ReaderInterface.php index 3b2e357b71..4024cdb3d6 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Reader/ReaderInterface.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Reader/ReaderInterface.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Reader/Word2007.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Reader/Word2007.php index 6c2178ad9a..deed3ce39c 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Reader/Word2007.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Reader/Word2007.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Reader/Word2007/AbstractPart.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Reader/Word2007/AbstractPart.php index 6a48fd4681..5e5eb1d6a8 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Reader/Word2007/AbstractPart.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Reader/Word2007/AbstractPart.php @@ -11,13 +11,17 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ namespace PhpOffice\PhpWord\Reader\Word2007; use PhpOffice\Common\XMLReader; +use PhpOffice\PhpWord\ComplexType\TblWidth as TblWidthComplexType; +use PhpOffice\PhpWord\Element\AbstractContainer; +use PhpOffice\PhpWord\Element\TextRun; +use PhpOffice\PhpWord\Element\TrackChange; use PhpOffice\PhpWord\PhpWord; /** @@ -93,7 +97,7 @@ abstract class AbstractPart * * @param \PhpOffice\Common\XMLReader $xmlReader * @param \DOMElement $domNode - * @param mixed $parent + * @param \PhpOffice\PhpWord\Element\AbstractContainer $parent * @param string $docPart * * @todo Get font style for preserve text @@ -102,12 +106,10 @@ abstract class AbstractPart { // Paragraph style $paragraphStyle = null; - $headingMatches = array(); + $headingDepth = null; if ($xmlReader->elementExists('w:pPr', $domNode)) { $paragraphStyle = $this->readParagraphStyle($xmlReader, $domNode); - if (is_array($paragraphStyle) && isset($paragraphStyle['styleName'])) { - preg_match('/Heading(\d)/', $paragraphStyle['styleName'], $headingMatches); - } + $headingDepth = $this->getHeadingDepth($paragraphStyle); } // PreserveText @@ -134,50 +136,75 @@ abstract class AbstractPart } } } - $parent->addPreserveText($textContent, $fontStyle, $paragraphStyle); + $parent->addPreserveText(htmlspecialchars($textContent, ENT_QUOTES, 'UTF-8'), $fontStyle, $paragraphStyle); } elseif ($xmlReader->elementExists('w:pPr/w:numPr', $domNode)) { // List item - $textContent = ''; $numId = $xmlReader->getAttribute('w:val', $domNode, 'w:pPr/w:numPr/w:numId'); $levelId = $xmlReader->getAttribute('w:val', $domNode, 'w:pPr/w:numPr/w:ilvl'); - $nodes = $xmlReader->getElements('w:r', $domNode); + $nodes = $xmlReader->getElements('*', $domNode); + + $listItemRun = $parent->addListItemRun($levelId, "PHPWordList{$numId}", $paragraphStyle); + foreach ($nodes as $node) { - $textContent .= $xmlReader->getValue('w:t', $node); + $this->readRun($xmlReader, $node, $listItemRun, $docPart, $paragraphStyle); } - $parent->addListItem($textContent, $levelId, null, "PHPWordList{$numId}", $paragraphStyle); - } elseif (!empty($headingMatches)) { - // Heading - $textContent = ''; + } elseif ($headingDepth !== null) { + // Heading or Title + $textContent = null; $nodes = $xmlReader->getElements('w:r', $domNode); - foreach ($nodes as $node) { - $textContent .= $xmlReader->getValue('w:t', $node); + if ($nodes->length === 1) { + $textContent = htmlspecialchars($xmlReader->getValue('w:t', $nodes->item(0)), ENT_QUOTES, 'UTF-8'); + } else { + $textContent = new TextRun($paragraphStyle); + foreach ($nodes as $node) { + $this->readRun($xmlReader, $node, $textContent, $docPart, $paragraphStyle); + } } - $parent->addTitle($textContent, $headingMatches[1]); + $parent->addTitle($textContent, $headingDepth); } else { // Text and TextRun - $runCount = $xmlReader->countElements('w:r', $domNode); - $linkCount = $xmlReader->countElements('w:hyperlink', $domNode); - $runLinkCount = $runCount + $linkCount; - if (0 == $runLinkCount) { + $textRunContainers = $xmlReader->countElements('w:r|w:ins|w:del|w:hyperlink|w:smartTag', $domNode); + if (0 === $textRunContainers) { $parent->addTextBreak(null, $paragraphStyle); } else { $nodes = $xmlReader->getElements('*', $domNode); - if ($runLinkCount > 1) { - $parent = $parent->addTextRun($paragraphStyle); - } + $paragraph = $parent->addTextRun($paragraphStyle); foreach ($nodes as $node) { - $this->readRun($xmlReader, $node, $parent, $docPart, $paragraphStyle); + $this->readRun($xmlReader, $node, $paragraph, $docPart, $paragraphStyle); } } } } + /** + * Returns the depth of the Heading, returns 0 for a Title + * + * @param array $paragraphStyle + * @return number|null + */ + private function getHeadingDepth(array $paragraphStyle = null) + { + if (is_array($paragraphStyle) && isset($paragraphStyle['styleName'])) { + if ('Title' === $paragraphStyle['styleName']) { + return 0; + } + + $headingMatches = array(); + preg_match('/Heading(\d)/', $paragraphStyle['styleName'], $headingMatches); + if (!empty($headingMatches)) { + return $headingMatches[1]; + } + } + + return null; + } + /** * Read w:r. * * @param \PhpOffice\Common\XMLReader $xmlReader * @param \DOMElement $domNode - * @param mixed $parent + * @param \PhpOffice\PhpWord\Element\AbstractContainer $parent * @param string $docPart * @param mixed $paragraphStyle * @@ -185,51 +212,101 @@ abstract class AbstractPart */ protected function readRun(XMLReader $xmlReader, \DOMElement $domNode, $parent, $docPart, $paragraphStyle = null) { - if (!in_array($domNode->nodeName, array('w:r', 'w:hyperlink'))) { - return; + if (in_array($domNode->nodeName, array('w:ins', 'w:del', 'w:smartTag', 'w:hyperlink'))) { + $nodes = $xmlReader->getElements('*', $domNode); + foreach ($nodes as $node) { + $this->readRun($xmlReader, $node, $parent, $docPart, $paragraphStyle); + } + } elseif ($domNode->nodeName == 'w:r') { + $fontStyle = $this->readFontStyle($xmlReader, $domNode); + $nodes = $xmlReader->getElements('*', $domNode); + foreach ($nodes as $node) { + $this->readRunChild($xmlReader, $node, $parent, $docPart, $paragraphStyle, $fontStyle); + } } - $fontStyle = $this->readFontStyle($xmlReader, $domNode); + } - // Link - if ('w:hyperlink' == $domNode->nodeName) { - $rId = $xmlReader->getAttribute('r:id', $domNode); - $textContent = $xmlReader->getValue('w:r/w:t', $domNode); + /** + * Parses nodes under w:r + * + * @param XMLReader $xmlReader + * @param \DOMElement $node + * @param AbstractContainer $parent + * @param string $docPart + * @param mixed $paragraphStyle + * @param mixed $fontStyle + */ + protected function readRunChild(XMLReader $xmlReader, \DOMElement $node, AbstractContainer $parent, $docPart, $paragraphStyle = null, $fontStyle = null) + { + $runParent = $node->parentNode->parentNode; + if ($node->nodeName == 'w:footnoteReference') { + // Footnote + $wId = $xmlReader->getAttribute('w:id', $node); + $footnote = $parent->addFootnote(); + $footnote->setRelationId($wId); + } elseif ($node->nodeName == 'w:endnoteReference') { + // Endnote + $wId = $xmlReader->getAttribute('w:id', $node); + $endnote = $parent->addEndnote(); + $endnote->setRelationId($wId); + } elseif ($node->nodeName == 'w:pict') { + // Image + $rId = $xmlReader->getAttribute('r:id', $node, 'v:shape/v:imagedata'); $target = $this->getMediaTarget($docPart, $rId); if (!is_null($target)) { - $parent->addLink($target, $textContent, $fontStyle, $paragraphStyle); - } - } else { - if ($xmlReader->elementExists('w:footnoteReference', $domNode)) { - // Footnote - $parent->addFootnote(); - } elseif ($xmlReader->elementExists('w:endnoteReference', $domNode)) { - // Endnote - $parent->addEndnote(); - } elseif ($xmlReader->elementExists('w:pict', $domNode)) { - // Image - $rId = $xmlReader->getAttribute('r:id', $domNode, 'w:pict/v:shape/v:imagedata'); - $target = $this->getMediaTarget($docPart, $rId); - if (!is_null($target)) { - if ('External' == $this->getTargetMode($docPart, $rId)) { - $imageSource = $target; - } else { - $imageSource = "zip://{$this->docFile}#{$target}"; - } - $parent->addImage($imageSource); + if ('External' == $this->getTargetMode($docPart, $rId)) { + $imageSource = $target; + } else { + $imageSource = "zip://{$this->docFile}#{$target}"; } - } elseif ($xmlReader->elementExists('w:object', $domNode)) { - // Object - $rId = $xmlReader->getAttribute('r:id', $domNode, 'w:object/o:OLEObject'); - // $rIdIcon = $xmlReader->getAttribute('r:id', $domNode, 'w:object/v:shape/v:imagedata'); + $parent->addImage($imageSource); + } + } elseif ($node->nodeName == 'w:drawing') { + // Office 2011 Image + $xmlReader->registerNamespace('wp', 'http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing'); + $xmlReader->registerNamespace('r', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships'); + $xmlReader->registerNamespace('pic', 'http://schemas.openxmlformats.org/drawingml/2006/picture'); + $xmlReader->registerNamespace('a', 'http://schemas.openxmlformats.org/drawingml/2006/main'); + + $name = $xmlReader->getAttribute('name', $node, 'wp:inline/a:graphic/a:graphicData/pic:pic/pic:nvPicPr/pic:cNvPr'); + $embedId = $xmlReader->getAttribute('r:embed', $node, 'wp:inline/a:graphic/a:graphicData/pic:pic/pic:blipFill/a:blip'); + $target = $this->getMediaTarget($docPart, $embedId); + if (!is_null($target)) { + $imageSource = "zip://{$this->docFile}#{$target}"; + $parent->addImage($imageSource, null, false, $name); + } + } elseif ($node->nodeName == 'w:object') { + // Object + $rId = $xmlReader->getAttribute('r:id', $node, 'o:OLEObject'); + // $rIdIcon = $xmlReader->getAttribute('r:id', $domNode, 'w:object/v:shape/v:imagedata'); + $target = $this->getMediaTarget($docPart, $rId); + if (!is_null($target)) { + $textContent = "<Object: {$target}>"; + $parent->addText($textContent, $fontStyle, $paragraphStyle); + } + } elseif ($node->nodeName == 'w:br') { + $parent->addTextBreak(); + } elseif ($node->nodeName == 'w:tab') { + $parent->addText("\t"); + } elseif ($node->nodeName == 'w:t' || $node->nodeName == 'w:delText') { + // TextRun + $textContent = htmlspecialchars($xmlReader->getValue('.', $node), ENT_QUOTES, 'UTF-8'); + + if ($runParent->nodeName == 'w:hyperlink') { + $rId = $xmlReader->getAttribute('r:id', $runParent); $target = $this->getMediaTarget($docPart, $rId); if (!is_null($target)) { - $textContent = "<Object: {$target}>"; - $parent->addText($textContent, $fontStyle, $paragraphStyle); + $parent->addLink($target, $textContent, $fontStyle, $paragraphStyle); } } else { - // TextRun - $textContent = $xmlReader->getValue('w:t', $domNode); - $parent->addText($textContent, $fontStyle, $paragraphStyle); + /** @var AbstractElement $element */ + $element = $parent->addText($textContent, $fontStyle, $paragraphStyle); + if (in_array($runParent->nodeName, array('w:ins', 'w:del'))) { + $type = ($runParent->nodeName == 'w:del') ? TrackChange::DELETED : TrackChange::INSERTED; + $author = $runParent->getAttribute('w:author'); + $date = \DateTime::createFromFormat('Y-m-d\TH:i:s\Z', $runParent->getAttribute('w:date')); + $element->setChangeInfo($type, $author, $date); + } } } } @@ -307,20 +384,21 @@ abstract class AbstractPart $styleNode = $xmlReader->getElement('w:pPr', $domNode); $styleDefs = array( - 'styleName' => array(self::READ_VALUE, 'w:pStyle'), - 'alignment' => array(self::READ_VALUE, 'w:jc'), - 'basedOn' => array(self::READ_VALUE, 'w:basedOn'), - 'next' => array(self::READ_VALUE, 'w:next'), - 'indent' => array(self::READ_VALUE, 'w:ind', 'w:left'), - 'hanging' => array(self::READ_VALUE, 'w:ind', 'w:hanging'), - 'spaceAfter' => array(self::READ_VALUE, 'w:spacing', 'w:after'), - 'spaceBefore' => array(self::READ_VALUE, 'w:spacing', 'w:before'), - 'widowControl' => array(self::READ_FALSE, 'w:widowControl'), - 'keepNext' => array(self::READ_TRUE, 'w:keepNext'), - 'keepLines' => array(self::READ_TRUE, 'w:keepLines'), - 'pageBreakBefore' => array(self::READ_TRUE, 'w:pageBreakBefore'), - 'contextualSpacing' => array(self::READ_TRUE, 'w:contextualSpacing'), - 'bidi' => array(self::READ_TRUE, 'w:bidi'), + 'styleName' => array(self::READ_VALUE, array('w:pStyle', 'w:name')), + 'alignment' => array(self::READ_VALUE, 'w:jc'), + 'basedOn' => array(self::READ_VALUE, 'w:basedOn'), + 'next' => array(self::READ_VALUE, 'w:next'), + 'indent' => array(self::READ_VALUE, 'w:ind', 'w:left'), + 'hanging' => array(self::READ_VALUE, 'w:ind', 'w:hanging'), + 'spaceAfter' => array(self::READ_VALUE, 'w:spacing', 'w:after'), + 'spaceBefore' => array(self::READ_VALUE, 'w:spacing', 'w:before'), + 'widowControl' => array(self::READ_FALSE, 'w:widowControl'), + 'keepNext' => array(self::READ_TRUE, 'w:keepNext'), + 'keepLines' => array(self::READ_TRUE, 'w:keepLines'), + 'pageBreakBefore' => array(self::READ_TRUE, 'w:pageBreakBefore'), + 'contextualSpacing' => array(self::READ_TRUE, 'w:contextualSpacing'), + 'bidi' => array(self::READ_TRUE, 'w:bidi'), + 'suppressAutoHyphens' => array(self::READ_TRUE, 'w:suppressAutoHyphens'), ); return $this->readStyleDefs($xmlReader, $styleNode, $styleDefs); @@ -349,9 +427,9 @@ abstract class AbstractPart $styleNode = $xmlReader->getElement('w:rPr', $domNode); $styleDefs = array( 'styleName' => array(self::READ_VALUE, 'w:rStyle'), - 'name' => array(self::READ_VALUE, 'w:rFonts', 'w:ascii'), + 'name' => array(self::READ_VALUE, 'w:rFonts', array('w:ascii', 'w:hAnsi', 'w:eastAsia', 'w:cs')), 'hint' => array(self::READ_VALUE, 'w:rFonts', 'w:hint'), - 'size' => array(self::READ_SIZE, 'w:sz'), + 'size' => array(self::READ_SIZE, array('w:sz', 'w:szCs')), 'color' => array(self::READ_VALUE, 'w:color'), 'underline' => array(self::READ_VALUE, 'w:u'), 'bold' => array(self::READ_TRUE, 'w:b'), @@ -364,9 +442,8 @@ abstract class AbstractPart 'subScript' => array(self::READ_EQUAL, 'w:vertAlign', 'w:val', 'subscript'), 'fgColor' => array(self::READ_VALUE, 'w:highlight'), 'rtl' => array(self::READ_TRUE, 'w:rtl'), - 'font-latin' => array(self::READ_VALUE, 'w:font', 'w:val'), - 'font-eastAsia' => array(self::READ_VALUE, 'w:font', 'w:eastAsia'), - 'font-bidi' => array(self::READ_VALUE, 'w:font', 'w:bidi'), + 'lang' => array(self::READ_VALUE, 'w:lang'), + 'position' => array(self::READ_VALUE, 'w:position'), ); return $this->readStyleDefs($xmlReader, $styleNode, $styleDefs); @@ -400,14 +477,70 @@ abstract class AbstractPart $ucfSide = ucfirst($side); $styleDefs["border{$ucfSide}Size"] = array(self::READ_VALUE, "w:tblBorders/w:$side", 'w:sz'); $styleDefs["border{$ucfSide}Color"] = array(self::READ_VALUE, "w:tblBorders/w:$side", 'w:color'); + $styleDefs["border{$ucfSide}Style"] = array(self::READ_VALUE, "w:tblBorders/w:$side", 'w:val'); } + $styleDefs['layout'] = array(self::READ_VALUE, 'w:tblLayout', 'w:type'); + $styleDefs['cellSpacing'] = array(self::READ_VALUE, 'w:tblCellSpacing', 'w:w'); $style = $this->readStyleDefs($xmlReader, $styleNode, $styleDefs); + + $tablePositionNode = $xmlReader->getElement('w:tblpPr', $styleNode); + if ($tablePositionNode !== null) { + $style['position'] = $this->readTablePosition($xmlReader, $tablePositionNode); + } + + $indentNode = $xmlReader->getElement('w:tblInd', $styleNode); + if ($indentNode !== null) { + $style['indent'] = $this->readTableIndent($xmlReader, $indentNode); + } } } return $style; } + /** + * Read w:tblpPr + * + * @param \PhpOffice\Common\XMLReader $xmlReader + * @param \DOMElement $domNode + * @return array + */ + private function readTablePosition(XMLReader $xmlReader, \DOMElement $domNode) + { + $styleDefs = array( + 'leftFromText' => array(self::READ_VALUE, '.', 'w:leftFromText'), + 'rightFromText' => array(self::READ_VALUE, '.', 'w:rightFromText'), + 'topFromText' => array(self::READ_VALUE, '.', 'w:topFromText'), + 'bottomFromText' => array(self::READ_VALUE, '.', 'w:bottomFromText'), + 'vertAnchor' => array(self::READ_VALUE, '.', 'w:vertAnchor'), + 'horzAnchor' => array(self::READ_VALUE, '.', 'w:horzAnchor'), + 'tblpXSpec' => array(self::READ_VALUE, '.', 'w:tblpXSpec'), + 'tblpX' => array(self::READ_VALUE, '.', 'w:tblpX'), + 'tblpYSpec' => array(self::READ_VALUE, '.', 'w:tblpYSpec'), + 'tblpY' => array(self::READ_VALUE, '.', 'w:tblpY'), + ); + + return $this->readStyleDefs($xmlReader, $domNode, $styleDefs); + } + + /** + * Read w:tblInd + * + * @param \PhpOffice\Common\XMLReader $xmlReader + * @param \DOMElement $domNode + * @return TblWidthComplexType + */ + private function readTableIndent(XMLReader $xmlReader, \DOMElement $domNode) + { + $styleDefs = array( + 'value' => array(self::READ_VALUE, '.', 'w:w'), + 'type' => array(self::READ_VALUE, '.', 'w:type'), + ); + $styleDefs = $this->readStyleDefs($xmlReader, $domNode, $styleDefs); + + return new TblWidthComplexType((int) $styleDefs['value'], $styleDefs['type']); + } + /** * Read w:tcPr * @@ -428,6 +561,54 @@ abstract class AbstractPart return $this->readStyleDefs($xmlReader, $domNode, $styleDefs); } + /** + * Returns the first child element found + * + * @param XMLReader $xmlReader + * @param \DOMElement $parentNode + * @param string|array $elements + * @return string|null + */ + private function findPossibleElement(XMLReader $xmlReader, \DOMElement $parentNode = null, $elements) + { + if (is_array($elements)) { + //if element is an array, we take the first element that exists in the XML + foreach ($elements as $possibleElement) { + if ($xmlReader->elementExists($possibleElement, $parentNode)) { + return $possibleElement; + } + } + } else { + return $elements; + } + + return null; + } + + /** + * Returns the first attribute found + * + * @param XMLReader $xmlReader + * @param \DOMElement $node + * @param string|array $attributes + * @return string|null + */ + private function findPossibleAttribute(XMLReader $xmlReader, \DOMElement $node, $attributes) + { + //if attribute is an array, we take the first attribute that exists in the XML + if (is_array($attributes)) { + foreach ($attributes as $possibleAttribute) { + if ($xmlReader->getAttribute($possibleAttribute, $node)) { + return $possibleAttribute; + } + } + + return null; + } + + return $attributes; + } + /** * Read style definition * @@ -442,11 +623,18 @@ abstract class AbstractPart $styles = array(); foreach ($styleDefs as $styleProp => $styleVal) { - @list($method, $element, $attribute, $expected) = $styleVal; + list($method, $element, $attribute, $expected) = array_pad($styleVal, 4, null); + + $element = $this->findPossibleElement($xmlReader, $parentNode, $element); + if ($element === null) { + continue; + } if ($xmlReader->elementExists($element, $parentNode)) { $node = $xmlReader->getElement($element, $parentNode); + $attribute = $this->findPossibleAttribute($xmlReader, $node, $attribute); + // Use w:val as default if no attribute assigned $attribute = ($attribute === null) ? 'w:val' : $attribute; $attributeValue = $xmlReader->getAttribute($attribute, $node); @@ -466,7 +654,7 @@ abstract class AbstractPart * * @param string $method * @ignoreScrutinizerPatch - * @param mixed $attributeValue + * @param string|null $attributeValue * @param mixed $expected * @return mixed */ @@ -496,7 +684,7 @@ abstract class AbstractPart */ private function isOn($value = null) { - return $value == null || $value == '1' || $value == 'true' || $value == 'on'; + return $value === null || $value === '1' || $value === 'true' || $value === 'on'; } /** diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Reader/Word2007/DocPropsApp.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Reader/Word2007/DocPropsApp.php index df34c9c37b..decc510390 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Reader/Word2007/DocPropsApp.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Reader/Word2007/DocPropsApp.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Reader/Word2007/DocPropsCore.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Reader/Word2007/DocPropsCore.php index f82c6b4bf5..36eecebeae 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Reader/Word2007/DocPropsCore.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Reader/Word2007/DocPropsCore.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Reader/Word2007/DocPropsCustom.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Reader/Word2007/DocPropsCustom.php index a3d6b90bd2..a6835aacc1 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Reader/Word2007/DocPropsCustom.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Reader/Word2007/DocPropsCustom.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Reader/Word2007/Document.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Reader/Word2007/Document.php index ff094bcc29..4e37541b70 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Reader/Word2007/Document.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Reader/Word2007/Document.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Reader/Word2007/Endnotes.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Reader/Word2007/Endnotes.php index 0f46cb2f47..aa8b65d750 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Reader/Word2007/Endnotes.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Reader/Word2007/Endnotes.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Reader/Word2007/Footnotes.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Reader/Word2007/Footnotes.php index 61988723d9..634f473910 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Reader/Word2007/Footnotes.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Reader/Word2007/Footnotes.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ @@ -48,9 +48,6 @@ class Footnotes extends AbstractPart */ public function read(PhpWord $phpWord) { - $getMethod = "get{$this->collection}"; - $collection = $phpWord->$getMethod()->getItems(); - $xmlReader = new XMLReader(); $xmlReader->getDomFromZip($this->docFile, $this->xmlFile); $nodes = $xmlReader->getElements('*'); @@ -60,17 +57,41 @@ class Footnotes extends AbstractPart $type = $xmlReader->getAttribute('w:type', $node); // Avoid w:type "separator" and "continuationSeparator" - // Only look for <footnote> or <endnote> without w:type attribute - if (is_null($type) && isset($collection[$id])) { - $element = $collection[$id]; - $pNodes = $xmlReader->getElements('w:p/*', $node); - foreach ($pNodes as $pNode) { - $this->readRun($xmlReader, $pNode, $element, $this->collection); + // Only look for <footnote> or <endnote> without w:type attribute, or with w:type = normal + if ((is_null($type) || $type === 'normal')) { + $element = $this->getElement($phpWord, $id); + if ($element !== null) { + $pNodes = $xmlReader->getElements('w:p/*', $node); + foreach ($pNodes as $pNode) { + $this->readRun($xmlReader, $pNode, $element, $this->collection); + } + $addMethod = "add{$this->element}"; + $phpWord->$addMethod($element); } - $addMethod = "add{$this->element}"; - $phpWord->$addMethod($element); } } } } + + /** + * Searches for the element with the given relationId + * + * @param PhpWord $phpWord + * @param int $relationId + * @return \PhpOffice\PhpWord\Element\AbstractContainer|null + */ + private function getElement(PhpWord $phpWord, $relationId) + { + $getMethod = "get{$this->collection}"; + $collection = $phpWord->$getMethod()->getItems(); + + //not found by key, looping to search by relationId + foreach ($collection as $collectionElement) { + if ($collectionElement->getRelationId() == $relationId) { + return $collectionElement; + } + } + + return null; + } } diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Reader/Word2007/Numbering.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Reader/Word2007/Numbering.php index c2a81dd5ac..3f57cbf8be 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Reader/Word2007/Numbering.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Reader/Word2007/Numbering.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Reader/Word2007/Settings.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Reader/Word2007/Settings.php index ccdbed2542..3084943b37 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Reader/Word2007/Settings.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Reader/Word2007/Settings.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ @@ -29,7 +29,18 @@ use PhpOffice\PhpWord\Style\Language; */ class Settings extends AbstractPart { - private static $booleanProperties = array('hideSpellingErrors', 'hideGrammaticalErrors', 'trackRevisions', 'doNotTrackMoves', 'doNotTrackFormatting', 'evenAndOddHeaders'); + private static $booleanProperties = array( + 'mirrorMargins', + 'hideSpellingErrors', + 'hideGrammaticalErrors', + 'trackRevisions', + 'doNotTrackMoves', + 'doNotTrackFormatting', + 'evenAndOddHeaders', + 'updateFields', + 'autoHyphenation', + 'doNotHyphenateCaps', + ); /** * Read settings.xml. @@ -70,7 +81,7 @@ class Settings extends AbstractPart * * @param XMLReader $xmlReader * @param PhpWord $phpWord - * @param \DOMNode $node + * @param \DOMElement $node */ protected function setThemeFontLang(XMLReader $xmlReader, PhpWord $phpWord, \DOMElement $node) { @@ -80,8 +91,8 @@ class Settings extends AbstractPart $themeFontLang = new Language(); $themeFontLang->setLatin($val); - $themeFontLang->setLatin($eastAsia); - $themeFontLang->setLatin($bidi); + $themeFontLang->setEastAsia($eastAsia); + $themeFontLang->setBidirectional($bidi); $phpWord->getSettings()->setThemeFontLang($themeFontLang); } @@ -91,14 +102,16 @@ class Settings extends AbstractPart * * @param XMLReader $xmlReader * @param PhpWord $phpWord - * @param \DOMNode $node + * @param \DOMElement $node */ protected function setDocumentProtection(XMLReader $xmlReader, PhpWord $phpWord, \DOMElement $node) { $documentProtection = $phpWord->getSettings()->getDocumentProtection(); $edit = $xmlReader->getAttribute('w:edit', $node); - $documentProtection->setEditing($edit); + if ($edit !== null) { + $documentProtection->setEditing($edit); + } } /** @@ -106,7 +119,7 @@ class Settings extends AbstractPart * * @param XMLReader $xmlReader * @param PhpWord $phpWord - * @param \DOMNode $node + * @param \DOMElement $node */ protected function setProofState(XMLReader $xmlReader, PhpWord $phpWord, \DOMElement $node) { @@ -128,7 +141,7 @@ class Settings extends AbstractPart * * @param XMLReader $xmlReader * @param PhpWord $phpWord - * @param \DOMNode $node + * @param \DOMElement $node */ protected function setZoom(XMLReader $xmlReader, PhpWord $phpWord, \DOMElement $node) { @@ -145,7 +158,7 @@ class Settings extends AbstractPart * * @param XMLReader $xmlReader * @param PhpWord $phpWord - * @param \DOMNode $node + * @param \DOMElement $node */ protected function setRevisionView(XMLReader $xmlReader, PhpWord $phpWord, \DOMElement $node) { @@ -157,4 +170,32 @@ class Settings extends AbstractPart $revisionView->setInkAnnotations(filter_var($xmlReader->getAttribute('w:inkAnnotations', $node), FILTER_VALIDATE_BOOLEAN)); $phpWord->getSettings()->setRevisionView($revisionView); } + + /** + * @param XMLReader $xmlReader + * @param PhpWord $phpWord + * @param \DOMElement $node + */ + protected function setConsecutiveHyphenLimit(XMLReader $xmlReader, PhpWord $phpWord, \DOMElement $node) + { + $value = $xmlReader->getAttribute('w:val', $node); + + if ($value !== null) { + $phpWord->getSettings()->setConsecutiveHyphenLimit($value); + } + } + + /** + * @param XMLReader $xmlReader + * @param PhpWord $phpWord + * @param \DOMElement $node + */ + protected function setHyphenationZone(XMLReader $xmlReader, PhpWord $phpWord, \DOMElement $node) + { + $value = $xmlReader->getAttribute('w:val', $node); + + if ($value !== null) { + $phpWord->getSettings()->setHyphenationZone($value); + } + } } diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Reader/Word2007/Styles.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Reader/Word2007/Styles.php index b8e6f22bfa..f343ad9296 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Reader/Word2007/Styles.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Reader/Word2007/Styles.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ @@ -19,6 +19,7 @@ namespace PhpOffice\PhpWord\Reader\Word2007; use PhpOffice\Common\XMLReader; use PhpOffice\PhpWord\PhpWord; +use PhpOffice\PhpWord\Style\Language; /** * Styles reader @@ -37,6 +38,28 @@ class Styles extends AbstractPart $xmlReader = new XMLReader(); $xmlReader->getDomFromZip($this->docFile, $this->xmlFile); + $fontDefaults = $xmlReader->getElement('w:docDefaults/w:rPrDefault'); + if ($fontDefaults !== null) { + $fontDefaultStyle = $this->readFontStyle($xmlReader, $fontDefaults); + if (array_key_exists('name', $fontDefaultStyle)) { + $phpWord->setDefaultFontName($fontDefaultStyle['name']); + } + if (array_key_exists('size', $fontDefaultStyle)) { + $phpWord->setDefaultFontSize($fontDefaultStyle['size']); + } + if (array_key_exists('lang', $fontDefaultStyle)) { + $phpWord->getSettings()->setThemeFontLang(new Language($fontDefaultStyle['lang'])); + } + } + + $paragraphDefaults = $xmlReader->getElement('w:docDefaults/w:pPrDefault'); + if ($paragraphDefaults !== null) { + $paragraphDefaultStyle = $this->readParagraphStyle($xmlReader, $paragraphDefaults); + if ($paragraphDefaultStyle != null) { + $phpWord->setDefaultParagraphStyle($paragraphDefaultStyle); + } + } + $nodes = $xmlReader->getElements('w:style'); if ($nodes->length > 0) { foreach ($nodes as $node) { diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Settings.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Settings.php index 22b8ba1f5e..8de1a8df80 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Settings.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Settings.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Shared/AbstractEnum.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Shared/AbstractEnum.php index 442d8251b3..f2375d876e 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Shared/AbstractEnum.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Shared/AbstractEnum.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Shared/Converter.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Shared/Converter.php index 56687c986a..c53f0030ce 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Shared/Converter.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Shared/Converter.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Shared/Html.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Shared/Html.php index d8a10b5702..6e90a0a746 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Shared/Html.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Shared/Html.php @@ -11,17 +11,18 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ namespace PhpOffice\PhpWord\Shared; use PhpOffice\PhpWord\Element\AbstractContainer; -use PhpOffice\PhpWord\Element\Cell; use PhpOffice\PhpWord\Element\Row; use PhpOffice\PhpWord\Element\Table; +use PhpOffice\PhpWord\Settings; use PhpOffice\PhpWord\SimpleType\Jc; +use PhpOffice\PhpWord\SimpleType\NumberFormat; /** * Common Html functions @@ -30,22 +31,32 @@ use PhpOffice\PhpWord\SimpleType\Jc; */ class Html { + private static $listIndex = 0; + private static $xpath; + private static $options; + /** * Add HTML parts. * * Note: $stylesheet parameter is removed to avoid PHPMD error for unused parameter + * Warning: Do not pass user-generated HTML here, as that would allow an attacker to read arbitrary + * files or perform server-side request forgery by passing local file paths or URLs in <img>. * * @param \PhpOffice\PhpWord\Element\AbstractContainer $element Where the parts need to be added * @param string $html The code to parse * @param bool $fullHTML If it's a full HTML, no need to add 'body' tag * @param bool $preserveWhiteSpace If false, the whitespaces between nodes will be removed + * @param array $options: + * + IMG_SRC_SEARCH: optional to speed up images loading from remote url when files can be found locally + * + IMG_SRC_REPLACE: optional to speed up images loading from remote url when files can be found locally */ - public static function addHtml($element, $html, $fullHTML = false, $preserveWhiteSpace = true) + public static function addHtml($element, $html, $fullHTML = false, $preserveWhiteSpace = true, $options = null) { /* * @todo parse $stylesheet for default styles. Should result in an array based on id, class and element, * which could be applied when such an element occurs in the parseNode function. */ + self::$options = $options; // Preprocess: remove all line ends, decode HTML entity, // fix ampersand and angle brackets and add body tag for HTML fragments @@ -60,12 +71,16 @@ class Html } // Load DOM + $orignalLibEntityLoader = libxml_disable_entity_loader(); + libxml_disable_entity_loader(true); $dom = new \DOMDocument(); $dom->preserveWhiteSpace = $preserveWhiteSpace; $dom->loadXML($html); + self::$xpath = new \DOMXPath($dom); $node = $dom->getElementsByTagName('body'); self::parseNode($node->item(0), $element); + libxml_disable_entity_loader($orignalLibEntityLoader); } /** @@ -85,6 +100,12 @@ class Html case 'style': $styles = self::parseStyle($attribute, $styles); break; + case 'align': + $styles['alignment'] = self::mapAlign($attribute->value); + break; + case 'lang': + $styles['lang'] = $attribute->value; + break; } } } @@ -129,15 +150,17 @@ class Html 'sup' => array('Property', null, null, $styles, null, 'superScript', true), 'sub' => array('Property', null, null, $styles, null, 'subScript', true), 'span' => array('Span', $node, null, $styles, null, null, null), + 'font' => array('Span', $node, null, $styles, null, null, null), 'table' => array('Table', $node, $element, $styles, null, null, null), 'tr' => array('Row', $node, $element, $styles, null, null, null), 'td' => array('Cell', $node, $element, $styles, null, null, null), 'th' => array('Cell', $node, $element, $styles, null, null, null), - 'ul' => array('List', null, null, $styles, $data, 3, null), - 'ol' => array('List', null, null, $styles, $data, 7, null), + 'ul' => array('List', $node, $element, $styles, $data, null, null), + 'ol' => array('List', $node, $element, $styles, $data, null, null), 'li' => array('ListItem', $node, $element, $styles, $data, null, null), 'img' => array('Image', $node, $element, $styles, null, null, null), 'br' => array('LineBreak', null, $element, $styles, null, null, null), + 'a' => array('Link', $node, $element, $styles, null, null, null), ); $newElement = null; @@ -241,7 +264,7 @@ class Html $styles['font'] = self::recursiveParseStylesInHierarchy($node, $styles['font']); //alignment applies on paragraph, not on font. Let's copy it there - if (isset($styles['font']['alignment'])) { + if (isset($styles['font']['alignment']) && is_array($styles['paragraph'])) { $styles['paragraph']['alignment'] = $styles['font']['alignment']; } @@ -328,7 +351,7 @@ class Html * @param \DOMNode $node * @param \PhpOffice\PhpWord\Element\Table $element * @param array &$styles - * @return Cell $element + * @return \PhpOffice\PhpWord\Element\Cell|\PhpOffice\PhpWord\Element\TextRun $element */ private static function parseCell($node, $element, &$styles) { @@ -338,8 +361,29 @@ class Html if (!empty($colspan)) { $cellStyles['gridSpan'] = $colspan - 0; } + $cell = $element->addCell(null, $cellStyles); + + if (self::shouldAddTextRun($node)) { + return $cell->addTextRun(self::parseInlineStyle($node, $styles['paragraph'])); + } + + return $cell; + } + + /** + * Checks if $node contains an HTML element that cannot be added to TextRun + * + * @param \DOMNode $node + * @return bool Returns true if the node contains an HTML element that cannot be added to TextRun + */ + private static function shouldAddTextRun(\DOMNode $node) + { + $containsBlockElement = self::$xpath->query('.//table|./p|./ul|./ol', $node)->length > 0; + if ($containsBlockElement) { + return false; + } - return $element->addCell(null, $cellStyles); + return true; } /** @@ -363,18 +407,63 @@ class Html /** * Parse list node * + * @param \DOMNode $node + * @param \PhpOffice\PhpWord\Element\AbstractContainer $element * @param array &$styles * @param array &$data - * @param string $argument1 List type */ - private static function parseList(&$styles, &$data, $argument1) + private static function parseList($node, $element, &$styles, &$data) { + $isOrderedList = $node->nodeName === 'ol'; if (isset($data['listdepth'])) { $data['listdepth']++; } else { $data['listdepth'] = 0; + $styles['list'] = 'listStyle_' . self::$listIndex++; + $element->getPhpWord()->addNumberingStyle($styles['list'], self::getListStyle($isOrderedList)); + } + if ($node->parentNode->nodeName === 'li') { + return $element->getParent(); } - $styles['list']['listType'] = $argument1; + } + + /** + * @param bool $isOrderedList + * @return array + */ + private static function getListStyle($isOrderedList) + { + if ($isOrderedList) { + return array( + 'type' => 'multilevel', + 'levels' => array( + array('format' => NumberFormat::DECIMAL, 'text' => '%1.', 'alignment' => 'left', 'tabPos' => 720, 'left' => 720, 'hanging' => 360), + array('format' => NumberFormat::LOWER_LETTER, 'text' => '%2.', 'alignment' => 'left', 'tabPos' => 1440, 'left' => 1440, 'hanging' => 360), + array('format' => NumberFormat::LOWER_ROMAN, 'text' => '%3.', 'alignment' => 'right', 'tabPos' => 2160, 'left' => 2160, 'hanging' => 180), + array('format' => NumberFormat::DECIMAL, 'text' => '%4.', 'alignment' => 'left', 'tabPos' => 2880, 'left' => 2880, 'hanging' => 360), + array('format' => NumberFormat::LOWER_LETTER, 'text' => '%5.', 'alignment' => 'left', 'tabPos' => 3600, 'left' => 3600, 'hanging' => 360), + array('format' => NumberFormat::LOWER_ROMAN, 'text' => '%6.', 'alignment' => 'right', 'tabPos' => 4320, 'left' => 4320, 'hanging' => 180), + array('format' => NumberFormat::DECIMAL, 'text' => '%7.', 'alignment' => 'left', 'tabPos' => 5040, 'left' => 5040, 'hanging' => 360), + array('format' => NumberFormat::LOWER_LETTER, 'text' => '%8.', 'alignment' => 'left', 'tabPos' => 5760, 'left' => 5760, 'hanging' => 360), + array('format' => NumberFormat::LOWER_ROMAN, 'text' => '%9.', 'alignment' => 'right', 'tabPos' => 6480, 'left' => 6480, 'hanging' => 180), + ), + ); + } + + return array( + 'type' => 'hybridMultilevel', + 'levels' => array( + array('format' => NumberFormat::BULLET, 'text' => 'ï‚·', 'alignment' => 'left', 'tabPos' => 720, 'left' => 720, 'hanging' => 360, 'font' => 'Symbol', 'hint' => 'default'), + array('format' => NumberFormat::BULLET, 'text' => 'o', 'alignment' => 'left', 'tabPos' => 1440, 'left' => 1440, 'hanging' => 360, 'font' => 'Courier New', 'hint' => 'default'), + array('format' => NumberFormat::BULLET, 'text' => '', 'alignment' => 'left', 'tabPos' => 2160, 'left' => 2160, 'hanging' => 360, 'font' => 'Wingdings', 'hint' => 'default'), + array('format' => NumberFormat::BULLET, 'text' => 'ï‚·', 'alignment' => 'left', 'tabPos' => 2880, 'left' => 2880, 'hanging' => 360, 'font' => 'Symbol', 'hint' => 'default'), + array('format' => NumberFormat::BULLET, 'text' => 'o', 'alignment' => 'left', 'tabPos' => 3600, 'left' => 3600, 'hanging' => 360, 'font' => 'Courier New', 'hint' => 'default'), + array('format' => NumberFormat::BULLET, 'text' => '', 'alignment' => 'left', 'tabPos' => 4320, 'left' => 4320, 'hanging' => 360, 'font' => 'Wingdings', 'hint' => 'default'), + array('format' => NumberFormat::BULLET, 'text' => 'ï‚·', 'alignment' => 'left', 'tabPos' => 5040, 'left' => 5040, 'hanging' => 360, 'font' => 'Symbol', 'hint' => 'default'), + array('format' => NumberFormat::BULLET, 'text' => 'o', 'alignment' => 'left', 'tabPos' => 5760, 'left' => 5760, 'hanging' => 360, 'font' => 'Courier New', 'hint' => 'default'), + array('format' => NumberFormat::BULLET, 'text' => '', 'alignment' => 'left', 'tabPos' => 6480, 'left' => 6480, 'hanging' => 360, 'font' => 'Wingdings', 'hint' => 'default'), + ), + ); } /** @@ -392,17 +481,10 @@ class Html { $cNodes = $node->childNodes; if (!empty($cNodes)) { - $text = ''; + $listRun = $element->addListItemRun($data['listdepth'], $styles['list'], $styles['paragraph']); foreach ($cNodes as $cNode) { - if ($cNode->nodeName == '#text') { - $text = $cNode->nodeValue; - } - } - //ideally we should be parsing child nodes for any style, for now just take the text - if ('' == trim($text) && '' != trim($node->textContent)) { - $text = trim($node->textContent); + self::parseNode($cNode, $listRun, $styles, $data); } - $element->addListItem($text, $data['listdepth'], $styles['font'], $styles['list'], $styles['paragraph']); } } @@ -416,8 +498,9 @@ class Html private static function parseStyle($attribute, $styles) { $properties = explode(';', trim($attribute->value, " \t\n\r\0\x0B;")); + foreach ($properties as $property) { - list($cKey, $cValue) = explode(':', $property, 2); + list($cKey, $cValue) = array_pad(explode(':', $property, 2), 2, null); $cValue = trim($cValue); switch (trim($cKey)) { case 'text-decoration': @@ -431,20 +514,10 @@ class Html } break; case 'text-align': - switch ($cValue) { - case 'left': - $styles['alignment'] = Jc::START; - break; - case 'right': - $styles['alignment'] = Jc::END; - break; - case 'center': - $styles['alignment'] = Jc::CENTER; - break; - case 'justify': - $styles['alignment'] = Jc::BOTH; - break; - } + $styles['alignment'] = self::mapAlign($cValue); + break; + case 'direction': + $styles['rtl'] = $cValue === 'rtl'; break; case 'font-size': $styles['size'] = Converter::cssToPoint($cValue); @@ -459,6 +532,23 @@ class Html case 'background-color': $styles['bgColor'] = trim($cValue, '#'); break; + case 'line-height': + if (preg_match('/([0-9]+\.?[0-9]*[a-z]+)/', $cValue, $matches)) { + $spacingLineRule = \PhpOffice\PhpWord\SimpleType\LineSpacingRule::EXACT; + $spacing = Converter::cssToTwip($matches[1]) / \PhpOffice\PhpWord\Style\Paragraph::LINE_HEIGHT; + } elseif (preg_match('/([0-9]+)%/', $cValue, $matches)) { + $spacingLineRule = \PhpOffice\PhpWord\SimpleType\LineSpacingRule::AUTO; + $spacing = ((int) $matches[1]) / 100; + } else { + $spacingLineRule = \PhpOffice\PhpWord\SimpleType\LineSpacingRule::AUTO; + $spacing = $cValue; + } + $styles['spacingLineRule'] = $spacingLineRule; + $styles['lineHeight'] = $spacing; + break; + case 'text-indent': + $styles['indentation']['firstLine'] = Converter::cssToTwip($cValue); + break; case 'font-weight': $tValue = false; if (preg_match('#bold#', $cValue)) { @@ -473,6 +563,12 @@ class Html } $styles['italic'] = $tValue; break; + case 'margin-top': + $styles['spaceBefore'] = Converter::cssToPoint($cValue); + break; + case 'margin-bottom': + $styles['spaceAfter'] = Converter::cssToPoint($cValue); + break; case 'border-color': $styles['color'] = trim($cValue, '#'); break; @@ -485,13 +581,13 @@ class Html case 'width': if (preg_match('/([0-9]+[a-z]+)/', $cValue, $matches)) { $styles['width'] = Converter::cssToTwip($matches[1]); - $styles['unit'] = \PhpOffice\PhpWord\Style\Table::WIDTH_TWIP; + $styles['unit'] = \PhpOffice\PhpWord\SimpleType\TblWidth::TWIP; } elseif (preg_match('/([0-9]+)%/', $cValue, $matches)) { $styles['width'] = $matches[1] * 50; - $styles['unit'] = \PhpOffice\PhpWord\Style\Table::WIDTH_PERCENT; + $styles['unit'] = \PhpOffice\PhpWord\SimpleType\TblWidth::PERCENT; } elseif (preg_match('/([0-9]+)/', $cValue, $matches)) { $styles['width'] = $matches[1]; - $styles['unit'] = \PhpOffice\PhpWord\Style\Table::WIDTH_AUTO; + $styles['unit'] = \PhpOffice\PhpWord\SimpleType\TblWidth::AUTO; } break; case 'border': @@ -527,10 +623,12 @@ class Html case 'width': $width = $attribute->value; $style['width'] = $width; + $style['unit'] = \PhpOffice\PhpWord\Style\Image::UNIT_PX; break; case 'height': $height = $attribute->value; $style['height'] = $height; + $style['unit'] = \PhpOffice\PhpWord\Style\Image::UNIT_PX; break; case 'style': $styleattr = explode(';', $attribute->value); @@ -560,7 +658,52 @@ class Html break; } } - $newElement = $element->addImage($src, $style); + $originSrc = $src; + if (strpos($src, 'data:image') !== false) { + $tmpDir = Settings::getTempDir() . '/'; + + $match = array(); + preg_match('/data:image\/(\w+);base64,(.+)/', $src, $match); + + $src = $imgFile = $tmpDir . uniqid() . '.' . $match[1]; + + $ifp = fopen($imgFile, 'wb'); + + if ($ifp !== false) { + fwrite($ifp, base64_decode($match[2])); + fclose($ifp); + } + } + $src = urldecode($src); + + if (!is_file($src) + && !is_null(self::$options) + && isset(self::$options['IMG_SRC_SEARCH']) + && isset(self::$options['IMG_SRC_REPLACE'])) { + $src = str_replace(self::$options['IMG_SRC_SEARCH'], self::$options['IMG_SRC_REPLACE'], $src); + } + + if (!is_file($src)) { + if ($imgBlob = @file_get_contents($src)) { + $tmpDir = Settings::getTempDir() . '/'; + $match = array(); + preg_match('/.+\.(\w+)$/', $src, $match); + $src = $tmpDir . uniqid() . '.' . $match[1]; + + $ifp = fopen($src, 'wb'); + + if ($ifp !== false) { + fwrite($ifp, $imgBlob); + fclose($ifp); + } + } + } + + if (is_file($src)) { + $newElement = $element->addImage($src, $style); + } else { + throw new \Exception("Could not load image $originSrc"); + } return $newElement; } @@ -584,6 +727,28 @@ class Html } } + /** + * Transforms a HTML/CSS alignment into a \PhpOffice\PhpWord\SimpleType\Jc + * + * @param string $cssAlignment + * @return string|null + */ + private static function mapAlign($cssAlignment) + { + switch ($cssAlignment) { + case 'right': + return Jc::END; + case 'center': + return Jc::CENTER; + case 'justify': + return Jc::BOTH; + default: + return Jc::START; + } + + return null; + } + /** * Parse line break * @@ -593,4 +758,30 @@ class Html { $element->addTextBreak(); } + + /** + * Parse link node + * + * @param \DOMNode $node + * @param \PhpOffice\PhpWord\Element\AbstractContainer $element + * @param array $styles + */ + private static function parseLink($node, $element, &$styles) + { + $target = null; + foreach ($node->attributes as $attribute) { + switch ($attribute->name) { + case 'href': + $target = $attribute->value; + break; + } + } + $styles['font'] = self::parseInlineStyle($node, $styles['font']); + + if (strpos($target, '#') === 0) { + return $element->addLink(substr($target, 1), $node->textContent, $styles['font'], $styles['paragraph'], true); + } + + return $element->addLink($target, $node->textContent, $styles['font'], $styles['paragraph']); + } } diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Shared/OLERead.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Shared/OLERead.php index bcdda0c379..2e6a899e57 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Shared/OLERead.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Shared/OLERead.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ namespace PhpOffice\PhpWord\Shared; diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Shared/ZipArchive.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Shared/ZipArchive.php index 3d8d0a4133..2783e17e1c 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Shared/ZipArchive.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Shared/ZipArchive.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/SimpleType/DocProtect.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/SimpleType/DocProtect.php index cffa0003ed..e386913d53 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/SimpleType/DocProtect.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/SimpleType/DocProtect.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/SimpleType/Jc.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/SimpleType/Jc.php index 5d0ee33b83..e55f824d14 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/SimpleType/Jc.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/SimpleType/Jc.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/SimpleType/JcTable.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/SimpleType/JcTable.php index 71e073977c..924a4f2014 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/SimpleType/JcTable.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/SimpleType/JcTable.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/SimpleType/LineSpacingRule.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/SimpleType/LineSpacingRule.php index f2cc5e638b..8fd8340c43 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/SimpleType/LineSpacingRule.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/SimpleType/LineSpacingRule.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/SimpleType/NumberFormat.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/SimpleType/NumberFormat.php index 480d85399a..83da66fa3f 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/SimpleType/NumberFormat.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/SimpleType/NumberFormat.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/SimpleType/TblWidth.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/SimpleType/TblWidth.php new file mode 100644 index 0000000000..7fd753deb0 --- /dev/null +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/SimpleType/TblWidth.php @@ -0,0 +1,42 @@ +<?php +/** + * This file is part of PHPWord - A pure PHP library for reading and writing + * word processing documents. + * + * PHPWord is free software distributed under the terms of the GNU Lesser + * General Public License version 3 as published by the Free Software Foundation. + * + * For the full copyright and license information, please read the LICENSE + * file that was distributed with this source code. For the full list of + * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. + * + * @see https://github.com/PHPOffice/PHPWord + * @copyright 2010-2018 PHPWord contributors + * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 + */ + +namespace PhpOffice\PhpWord\SimpleType; + +use PhpOffice\PhpWord\Shared\AbstractEnum; + +/** + * Table Width Units + * + * @since 0.15.0 + * + * @see http://www.datypic.com/sc/ooxml/t-w_ST_TblWidth.html + */ +final class TblWidth extends AbstractEnum +{ + //No Width + const NIL = 'nil'; + + //Automatically Determined Width + const AUTO = 'auto'; + + //Width in Fiftieths of a Percent + const PERCENT = 'pct'; + + //Width in Twentieths of a Point + const TWIP = 'dxa'; +} diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/SimpleType/TextAlignment.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/SimpleType/TextAlignment.php index de36b10852..838b0c5e0e 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/SimpleType/TextAlignment.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/SimpleType/TextAlignment.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/SimpleType/Zoom.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/SimpleType/Zoom.php index 111e4ea16d..02c38fdb6a 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/SimpleType/Zoom.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/SimpleType/Zoom.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Style.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Style.php index 1939aabac6..62783b6301 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Style.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Style.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ @@ -39,7 +39,7 @@ class Style * Add paragraph style * * @param string $styleName - * @param array $styles + * @param array|\PhpOffice\PhpWord\Style\AbstractStyle $styles * @return \PhpOffice\PhpWord\Style\Paragraph */ public static function addParagraphStyle($styleName, $styles) @@ -51,8 +51,8 @@ class Style * Add font style * * @param string $styleName - * @param array $fontStyle - * @param array $paragraphStyle + * @param array|\PhpOffice\PhpWord\Style\AbstractStyle $fontStyle + * @param array|\PhpOffice\PhpWord\Style\AbstractStyle $paragraphStyle * @return \PhpOffice\PhpWord\Style\Font */ public static function addFontStyle($styleName, $fontStyle, $paragraphStyle = null) @@ -64,7 +64,7 @@ class Style * Add link style * * @param string $styleName - * @param array $styles + * @param array|\PhpOffice\PhpWord\Style\AbstractStyle $styles * @return \PhpOffice\PhpWord\Style\Font */ public static function addLinkStyle($styleName, $styles) @@ -76,7 +76,7 @@ class Style * Add numbering style * * @param string $styleName - * @param array $styleValues + * @param array|\PhpOffice\PhpWord\Style\AbstractStyle $styleValues * @return \PhpOffice\PhpWord\Style\Numbering * @since 0.10.0 */ @@ -88,14 +88,20 @@ class Style /** * Add title style * - * @param int $depth - * @param array $fontStyle - * @param array $paragraphStyle + * @param int|null $depth Provide null to set title font + * @param array|\PhpOffice\PhpWord\Style\AbstractStyle $fontStyle + * @param array|\PhpOffice\PhpWord\Style\AbstractStyle $paragraphStyle * @return \PhpOffice\PhpWord\Style\Font */ public static function addTitleStyle($depth, $fontStyle, $paragraphStyle = null) { - return self::setStyleValues("Heading_{$depth}", new Font('title', $paragraphStyle), $fontStyle); + if (empty($depth)) { + $styleName = 'Title'; + } else { + $styleName = "Heading_{$depth}"; + } + + return self::setStyleValues($styleName, new Font('title', $paragraphStyle), $fontStyle); } /** @@ -135,7 +141,7 @@ class Style /** * Set default paragraph style * - * @param array $styles Paragraph style definition + * @param array|\PhpOffice\PhpWord\Style\AbstractStyle $styles Paragraph style definition * @return \PhpOffice\PhpWord\Style\Paragraph */ public static function setDefaultParagraphStyle($styles) diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Style/AbstractStyle.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Style/AbstractStyle.php index 76ebd591c5..8edbe80bff 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Style/AbstractStyle.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Style/AbstractStyle.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Style/Border.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Style/Border.php index ab6aef18b9..d032d07faa 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Style/Border.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Style/Border.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Style/Cell.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Style/Cell.php index c281f99872..e609e190ff 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Style/Cell.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Style/Cell.php @@ -11,12 +11,14 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ namespace PhpOffice\PhpWord\Style; +use PhpOffice\PhpWord\SimpleType\TblWidth; + /** * Table cell style */ @@ -123,7 +125,7 @@ class Cell extends Border * * @var string */ - private $unit = Table::WIDTH_TWIP; + private $unit = TblWidth::TWIP; /** * Get vertical align. @@ -308,7 +310,7 @@ class Cell extends Border */ public function setUnit($value) { - $this->unit = $this->setEnumVal($value, array(Table::WIDTH_AUTO, Table::WIDTH_PERCENT, Table::WIDTH_TWIP), Table::WIDTH_TWIP); + $this->unit = $this->setEnumVal($value, array(TblWidth::AUTO, TblWidth::PERCENT, TblWidth::TWIP), TblWidth::TWIP); return $this; } diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Style/Chart.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Style/Chart.php index 694fcddccc..5b02e63631 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Style/Chart.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Style/Chart.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ @@ -45,6 +45,81 @@ class Chart extends AbstractStyle */ private $is3d = false; + /** + * A list of colors to use in the chart + * + * @var array + */ + private $colors = array(); + + /** + * A list of display options for data labels + * + * @var array + */ + private $dataLabelOptions = array( + 'showVal' => true, // value + 'showCatName' => true, // category name + 'showLegendKey' => false, //show the cart legend + 'showSerName' => false, // series name + 'showPercent' => false, + 'showLeaderLines' => false, + 'showBubbleSize' => false, + ); + + /** + * A string that tells the writer where to write chart labels or to skip + * "nextTo" - sets labels next to the axis (bar graphs on the left) (default) + * "low" - labels on the left side of the graph + * "high" - labels on the right side of the graph + * + * @var string + */ + private $categoryLabelPosition = 'nextTo'; + + /** + * A string that tells the writer where to write chart labels or to skip + * "nextTo" - sets labels next to the axis (bar graphs on the bottom) (default) + * "low" - labels are below the graph + * "high" - labels above the graph + * + * @var string + */ + private $valueLabelPosition = 'nextTo'; + + /** + * @var string + */ + private $categoryAxisTitle; + + /** + * @var string + */ + private $valueAxisTitle; + + private $majorTickMarkPos = 'none'; + + /* + * Show labels for axis + * + * @var bool + */ + private $showAxisLabels = false; + + /** + * Show Gridlines for Y-Axis + * + * @var bool + */ + private $gridY = false; + + /** + * Show Gridlines for X-Axis + * + * @var bool + */ + private $gridX = false; + /** * Create a new instance * @@ -123,4 +198,231 @@ class Chart extends AbstractStyle return $this; } + + /** + * Get the list of colors to use in a chart. + * + * @return array + */ + public function getColors() + { + return $this->colors; + } + + /** + * Set the colors to use in a chart. + * + * @param array $value a list of colors to use in the chart + */ + public function setColors($value = array()) + { + $this->colors = $value; + + return $this; + } + + /* + * Show labels for axis + * + * @return bool + */ + public function showAxisLabels() + { + return $this->showAxisLabels; + } + + /** + * Set show Gridlines for Y-Axis + * + * @param bool $value + * @return self + */ + public function setShowAxisLabels($value = true) + { + $this->showAxisLabels = $this->setBoolVal($value, $this->showAxisLabels); + + return $this; + } + + /** + * get the list of options for data labels + * + * @return array + */ + public function getDataLabelOptions() + { + return $this->dataLabelOptions; + } + + /** + * Set values for data label options. + * This will only change values for options defined in $this->dataLabelOptions, and cannot create new ones. + * + * @param array $values [description] + */ + public function setDataLabelOptions($values = array()) + { + foreach (array_keys($this->dataLabelOptions) as $option) { + if (isset($values[$option])) { + $this->dataLabelOptions[$option] = $this->setBoolVal($values[$option], $this->dataLabelOptions[$option]); + } + } + } + + /* + * Show Gridlines for Y-Axis + * + * @return bool + */ + public function showGridY() + { + return $this->gridY; + } + + /** + * Set show Gridlines for Y-Axis + * + * @param bool $value + * @return self + */ + public function setShowGridY($value = true) + { + $this->gridY = $this->setBoolVal($value, $this->gridY); + + return $this; + } + + /** + * Get the categoryLabelPosition setting + * + * @return string + */ + public function getCategoryLabelPosition() + { + return $this->categoryLabelPosition; + } + + /** + * Set the categoryLabelPosition setting + * "none" - skips writing labels + * "nextTo" - sets labels next to the (bar graphs on the left) + * "low" - labels on the left side of the graph + * "high" - labels on the right side of the graph + * + * @param mixed $labelPosition + * @return self + */ + public function setCategoryLabelPosition($labelPosition) + { + $enum = array('nextTo', 'low', 'high'); + $this->categoryLabelPosition = $this->setEnumVal($labelPosition, $enum, $this->categoryLabelPosition); + + return $this; + } + + /** + * Get the valueAxisLabelPosition setting + * + * @return string + */ + public function getValueLabelPosition() + { + return $this->valueLabelPosition; + } + + /** + * Set the valueLabelPosition setting + * "none" - skips writing labels + * "nextTo" - sets labels next to the value + * "low" - sets labels are below the graph + * "high" - sets labels above the graph + * + * @param string + * @param mixed $labelPosition + */ + public function setValueLabelPosition($labelPosition) + { + $enum = array('nextTo', 'low', 'high'); + $this->valueLabelPosition = $this->setEnumVal($labelPosition, $enum, $this->valueLabelPosition); + + return $this; + } + + /** + * Get the categoryAxisTitle + * @return string + */ + public function getCategoryAxisTitle() + { + return $this->categoryAxisTitle; + } + + /** + * Set the title that appears on the category side of the chart + * @param string $axisTitle + */ + public function setCategoryAxisTitle($axisTitle) + { + $this->categoryAxisTitle = $axisTitle; + + return $this; + } + + /** + * Get the valueAxisTitle + * @return string + */ + public function getValueAxisTitle() + { + return $this->valueAxisTitle; + } + + /** + * Set the title that appears on the value side of the chart + * @param string $axisTitle + */ + public function setValueAxisTitle($axisTitle) + { + $this->valueAxisTitle = $axisTitle; + + return $this; + } + + public function getMajorTickPosition() + { + return $this->majorTickMarkPos; + } + + /** + * set the position for major tick marks + * @param string $position [description] + */ + public function setMajorTickPosition($position) + { + $enum = array('in', 'out', 'cross', 'none'); + $this->majorTickMarkPos = $this->setEnumVal($position, $enum, $this->majorTickMarkPos); + } + + /* + * Show Gridlines for X-Axis + * + * @return bool + */ + public function showGridX() + { + return $this->gridX; + } + + /** + * Set show Gridlines for X-Axis + * + * @param bool $value + * @return self + */ + public function setShowGridX($value = true) + { + $this->gridX = $this->setBoolVal($value, $this->gridX); + + return $this; + } } diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Style/Extrusion.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Style/Extrusion.php index 11c03edada..4c860bcd63 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Style/Extrusion.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Style/Extrusion.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Style/Fill.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Style/Fill.php index 9b4730093b..360bcf3f0c 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Style/Fill.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Style/Fill.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Style/Font.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Style/Font.php index 8bfb3ac5d0..e9f3c9d672 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Style/Font.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Style/Font.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ @@ -232,21 +232,39 @@ class Font extends AbstractStyle /** * Right to left languages + * * @var bool */ private $rtl = false; + /** + * noProof (disables AutoCorrect) + * + * @var bool + * http://www.datypic.com/sc/ooxml/e-w_noProof-1.html + */ + private $noProof = false; + /** * Languages + * * @var \PhpOffice\PhpWord\Style\Language */ private $lang; + /** + * Vertically Raised or Lowered Text + * + * @var int Signed Half-Point Measurement + * @see http://www.datypic.com/sc/ooxml/e-w_position-1.html + */ + private $position; + /** * Create new font style * * @param string $type Type of font - * @param array $paragraph Paragraph styles definition + * @param array|string|\PhpOffice\PhpWord\Style\AbstractStyle $paragraph Paragraph styles definition */ public function __construct($type = 'text', $paragraph = null) { @@ -286,6 +304,7 @@ class Font extends AbstractStyle 'scale' => $this->getScale(), 'spacing' => $this->getSpacing(), 'kerning' => $this->getKerning(), + 'position' => $this->getPosition(), ), 'paragraph' => $this->getParagraph(), 'rtl' => $this->isRTL(), @@ -706,6 +725,29 @@ class Font extends AbstractStyle return $this; } + /** + * Get noProof (disables autocorrect) + * + * @return bool + */ + public function isNoProof() + { + return $this->noProof; + } + + /** + * Set noProof (disables autocorrect) + * + * @param bool $value + * @return $this + */ + public function setNoProof($value = false) + { + $this->noProof = $value; + + return $this; + } + /** * Get line height * @@ -895,4 +937,27 @@ class Font extends AbstractStyle { return $this->getParagraph(); } + + /** + * Get position + * + * @return int + */ + public function getPosition() + { + return $this->position; + } + + /** + * Set position + * + * @param int $value + * @return self + */ + public function setPosition($value = null) + { + $this->position = $this->setIntVal($value, null); + + return $this; + } } diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Style/Frame.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Style/Frame.php index a8e1c69d20..e87b7a803a 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Style/Frame.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Style/Frame.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ @@ -171,6 +171,42 @@ class Frame extends AbstractStyle */ private $wrap; + /** + * Top wrap distance + * + * @var float + */ + private $wrapDistanceTop; + + /** + * Bottom wrap distance + * + * @var float + */ + private $wrapDistanceBottom; + + /** + * Left wrap distance + * + * @var float + */ + private $wrapDistanceLeft; + + /** + * Right wrap distance + * + * @var float + */ + private $wrapDistanceRight; + + /** + * Vertically raised or lowered text + * + * @var int + * @see http://www.datypic.com/sc/ooxml/e-w_position-1.html + */ + private $position; + /** * Create a new instance * @@ -538,4 +574,119 @@ class Frame extends AbstractStyle return $this; } + + /** + * Get top distance from text wrap + * + * @return float + */ + public function getWrapDistanceTop() + { + return $this->wrapDistanceTop; + } + + /** + * Set top distance from text wrap + * + * @param int $value + * @return self + */ + public function setWrapDistanceTop($value = null) + { + $this->wrapDistanceTop = $this->setFloatVal($value, null); + + return $this; + } + + /** + * Get bottom distance from text wrap + * + * @return float + */ + public function getWrapDistanceBottom() + { + return $this->wrapDistanceBottom; + } + + /** + * Set bottom distance from text wrap + * + * @param float $value + * @return self + */ + public function setWrapDistanceBottom($value = null) + { + $this->wrapDistanceBottom = $this->setFloatVal($value, null); + + return $this; + } + + /** + * Get left distance from text wrap + * + * @return float + */ + public function getWrapDistanceLeft() + { + return $this->wrapDistanceLeft; + } + + /** + * Set left distance from text wrap + * + * @param float $value + * @return self + */ + public function setWrapDistanceLeft($value = null) + { + $this->wrapDistanceLeft = $this->setFloatVal($value, null); + + return $this; + } + + /** + * Get right distance from text wrap + * + * @return float + */ + public function getWrapDistanceRight() + { + return $this->wrapDistanceRight; + } + + /** + * Set right distance from text wrap + * + * @param float $value + * @return self + */ + public function setWrapDistanceRight($value = null) + { + $this->wrapDistanceRight = $this->setFloatVal($value, null); + + return $this; + } + + /** + * Get position + * + * @return int + */ + public function getPosition() + { + return $this->position; + } + + /** + * Set position + * + * @param int $value + * @return self + */ + public function setPosition($value = null) + { + $this->position = $this->setIntVal($value, null); + + return $this; + } } diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Style/Image.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Style/Image.php index e0b972158d..70aafe12cd 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Style/Image.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Style/Image.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Style/Indentation.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Style/Indentation.php index 9621714c74..e422395c80 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Style/Indentation.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Style/Indentation.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Style/Language.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Style/Language.php index e09421e05e..d7a76f78f3 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Style/Language.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Style/Language.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ @@ -47,6 +47,9 @@ final class Language extends AbstractStyle const HE_IL = 'he-IL'; const HE_IL_ID = 1037; + const IT_IT = 'it-IT'; + const IT_IT_ID = 1040; + const JA_JP = 'ja-JP'; const JA_JP_ID = 1041; @@ -59,6 +62,9 @@ final class Language extends AbstractStyle const HI_IN = 'hi-IN'; const HI_IN_ID = 1081; + const PT_BR = 'pt-BR'; + const PT_BR_ID = 1046; + /** * Language ID, used for RTF document generation * @@ -117,8 +123,7 @@ final class Language extends AbstractStyle */ public function setLatin($latin) { - $this->validateLocale($latin); - $this->latin = $latin; + $this->latin = $this->validateLocale($latin); return $this; } @@ -167,8 +172,7 @@ final class Language extends AbstractStyle */ public function setEastAsia($eastAsia) { - $this->validateLocale($eastAsia); - $this->eastAsia = $eastAsia; + $this->eastAsia = $this->validateLocale($eastAsia); return $this; } @@ -192,8 +196,7 @@ final class Language extends AbstractStyle */ public function setBidirectional($bidirectional) { - $this->validateLocale($bidirectional); - $this->bidirectional = $bidirectional; + $this->bidirectional = $this->validateLocale($bidirectional); return $this; } @@ -212,12 +215,18 @@ final class Language extends AbstractStyle * Validates that the language passed is in the format xx-xx * * @param string $locale - * @return bool + * @return string */ private function validateLocale($locale) { + if (strlen($locale) === 2) { + return strtolower($locale) . '-' . strtoupper($locale); + } + if ($locale !== null && strstr($locale, '-') === false) { throw new \InvalidArgumentException($locale . ' is not a valid language code'); } + + return $locale; } } diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Style/Line.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Style/Line.php index 16d15950a2..a9952eec0b 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Style/Line.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Style/Line.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Style/LineNumbering.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Style/LineNumbering.php index b5f3c263e7..451252d87a 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Style/LineNumbering.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Style/LineNumbering.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Style/ListItem.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Style/ListItem.php index 444341dc19..306ecff305 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Style/ListItem.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Style/ListItem.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Style/Numbering.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Style/Numbering.php index 80ed5dca66..f7855cfa20 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Style/Numbering.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Style/Numbering.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Style/NumberingLevel.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Style/NumberingLevel.php index 33c151e490..e9b32f0135 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Style/NumberingLevel.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Style/NumberingLevel.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Style/Outline.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Style/Outline.php index fb7e028a8b..a04ad974c0 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Style/Outline.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Style/Outline.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Style/Paper.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Style/Paper.php index 09e4769e90..3c93ed8f2f 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Style/Paper.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Style/Paper.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Style/Paragraph.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Style/Paragraph.php index c00dc97c1c..ac58768695 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Style/Paragraph.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Style/Paragraph.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ @@ -20,7 +20,6 @@ namespace PhpOffice\PhpWord\Style; use PhpOffice\Common\Text; use PhpOffice\PhpWord\Exception\InvalidStyleException; use PhpOffice\PhpWord\SimpleType\Jc; -use PhpOffice\PhpWord\SimpleType\LineSpacingRule; use PhpOffice\PhpWord\SimpleType\TextAlignment; /** @@ -181,6 +180,13 @@ class Paragraph extends Border */ private $textAlignment; + /** + * Suppress hyphenation for paragraph + * + * @var bool + */ + private $suppressAutoHyphens = false; + /** * Set Style value * @@ -213,27 +219,28 @@ class Paragraph extends Border public function getStyleValues() { $styles = array( - 'name' => $this->getStyleName(), - 'basedOn' => $this->getBasedOn(), - 'next' => $this->getNext(), - 'alignment' => $this->getAlignment(), - 'indentation' => $this->getIndentation(), - 'spacing' => $this->getSpace(), - 'pagination' => array( - 'widowControl' => $this->hasWidowControl(), - 'keepNext' => $this->isKeepNext(), - 'keepLines' => $this->isKeepLines(), - 'pageBreak' => $this->hasPageBreakBefore(), + 'name' => $this->getStyleName(), + 'basedOn' => $this->getBasedOn(), + 'next' => $this->getNext(), + 'alignment' => $this->getAlignment(), + 'indentation' => $this->getIndentation(), + 'spacing' => $this->getSpace(), + 'pagination' => array( + 'widowControl' => $this->hasWidowControl(), + 'keepNext' => $this->isKeepNext(), + 'keepLines' => $this->isKeepLines(), + 'pageBreak' => $this->hasPageBreakBefore(), ), - 'numbering' => array( - 'style' => $this->getNumStyle(), - 'level' => $this->getNumLevel(), + 'numbering' => array( + 'style' => $this->getNumStyle(), + 'level' => $this->getNumLevel(), ), - 'tabs' => $this->getTabs(), - 'shading' => $this->getShading(), - 'contextualSpacing' => $this->hasContextualSpacing(), - 'bidi' => $this->isBidi(), - 'textAlignment' => $this->getTextAlignment(), + 'tabs' => $this->getTabs(), + 'shading' => $this->getShading(), + 'contextualSpacing' => $this->hasContextualSpacing(), + 'bidi' => $this->isBidi(), + 'textAlignment' => $this->getTextAlignment(), + 'suppressAutoHyphens' => $this->hasSuppressAutoHyphens(), ); return $styles; @@ -849,4 +856,20 @@ class Paragraph extends Border return $this; } + + /** + * @return bool + */ + public function hasSuppressAutoHyphens() + { + return $this->suppressAutoHyphens; + } + + /** + * @param bool $suppressAutoHyphens + */ + public function setSuppressAutoHyphens($suppressAutoHyphens) + { + $this->suppressAutoHyphens = (bool) $suppressAutoHyphens; + } } diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Style/Row.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Style/Row.php index b56c6f5fa9..ad801af6e2 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Style/Row.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Style/Row.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Style/Section.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Style/Section.php index 476846f5f2..162e08e0bc 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Style/Section.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Style/Section.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Style/Shading.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Style/Shading.php index eeb055b2c8..154df26c7a 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Style/Shading.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Style/Shading.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Style/Shadow.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Style/Shadow.php index 71d1e3e009..1379a32096 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Style/Shadow.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Style/Shadow.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Style/Shape.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Style/Shape.php index fc84241d75..0c3f817982 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Style/Shape.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Style/Shape.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Style/Spacing.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Style/Spacing.php index 489eb5d707..9bfb22822b 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Style/Spacing.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Style/Spacing.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Style/TOC.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Style/TOC.php index 938e6de166..2efd54a4a4 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Style/TOC.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Style/TOC.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Style/Tab.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Style/Tab.php index 09e49e02c0..d3cf5bd7f4 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Style/Tab.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Style/Tab.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Style/Table.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Style/Table.php index a3d454f3aa..0f7bf7dc3b 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Style/Table.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Style/Table.php @@ -11,24 +11,46 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ namespace PhpOffice\PhpWord\Style; +use PhpOffice\PhpWord\ComplexType\TblWidth as TblWidthComplexType; use PhpOffice\PhpWord\SimpleType\Jc; use PhpOffice\PhpWord\SimpleType\JcTable; +use PhpOffice\PhpWord\SimpleType\TblWidth; class Table extends Border { /** - * @const string Table width units http://www.schemacentral.com/sc/ooxml/t-w_ST_TblWidth.html + * @deprecated Use \PhpOffice\PhpWord\SimpleType\TblWidth::AUTO instead */ const WIDTH_AUTO = 'auto'; // Automatically determined width + /** + * @deprecated Use \PhpOffice\PhpWord\SimpleType\TblWidth::PERCENT instead + */ const WIDTH_PERCENT = 'pct'; // Width in fiftieths (1/50) of a percent (1% = 50 unit) + /** + * @deprecated Use \PhpOffice\PhpWord\SimpleType\TblWidth::TWIP instead + */ const WIDTH_TWIP = 'dxa'; // Width in twentieths (1/20) of a point (twip) + //values for http://www.datypic.com/sc/ooxml/t-w_ST_TblLayoutType.html + /** + * AutoFit Table Layout + * + * @var string + */ + const LAYOUT_AUTO = 'autofit'; + /** + * Fixed Width Table Layout + * + * @var string + */ + const LAYOUT_FIXED = 'fixed'; + /** * Is this a first row style? * @@ -119,7 +141,34 @@ class Table extends Border /** * @var string Width unit */ - private $unit = self::WIDTH_AUTO; + private $unit = TblWidth::AUTO; + + /** + * @var int|float cell spacing value + */ + protected $cellSpacing = null; + + /** + * @var string Table Layout + */ + private $layout = self::LAYOUT_AUTO; + + /** + * Position + * + * @var \PhpOffice\PhpWord\Style\TablePosition + */ + private $position; + + /** @var TblWidthComplexType|null */ + private $indent; + + /** + * The width of each column, computed based on the max cell width of each column + * + * @var int[] + */ + private $columnWidths; /** * Create new table style @@ -133,7 +182,7 @@ class Table extends Border if ($firstRowStyle !== null && is_array($firstRowStyle)) { $this->firstRowStyle = clone $this; $this->firstRowStyle->isFirstRow = true; - unset($this->firstRowStyle->firstRowStyle, $this->firstRowStyle->borderInsideHSize, $this->firstRowStyle->borderInsideHColor, $this->firstRowStyle->borderInsideVSize, $this->firstRowStyle->borderInsideVColor, $this->firstRowStyle->cellMarginTop, $this->firstRowStyle->cellMarginLeft, $this->firstRowStyle->cellMarginRight, $this->firstRowStyle->cellMarginBottom); + unset($this->firstRowStyle->firstRowStyle, $this->firstRowStyle->borderInsideHSize, $this->firstRowStyle->borderInsideHColor, $this->firstRowStyle->borderInsideVSize, $this->firstRowStyle->borderInsideVColor, $this->firstRowStyle->cellMarginTop, $this->firstRowStyle->cellMarginLeft, $this->firstRowStyle->cellMarginRight, $this->firstRowStyle->cellMarginBottom, $this->firstRowStyle->cellSpacing); $this->firstRowStyle->setStyleByArray($firstRowStyle); } @@ -142,6 +191,22 @@ class Table extends Border } } + /** + * @param float|int $cellSpacing + */ + public function setCellSpacing($cellSpacing = null) + { + $this->cellSpacing = $cellSpacing; + } + + /** + * @return float|int + */ + public function getCellSpacing() + { + return $this->cellSpacing; + } + /** * Set first row * @@ -576,8 +641,32 @@ class Table extends Border */ public function setUnit($value = null) { - $enum = array(self::WIDTH_AUTO, self::WIDTH_PERCENT, self::WIDTH_TWIP); - $this->unit = $this->setEnumVal($value, $enum, $this->unit); + TblWidth::validate($value); + $this->unit = $value; + + return $this; + } + + /** + * Get layout + * + * @return string + */ + public function getLayout() + { + return $this->layout; + } + + /** + * Set layout + * + * @param string $value + * @return self + */ + public function setLayout($value = null) + { + $enum = array(self::LAYOUT_AUTO, self::LAYOUT_FIXED); + $this->layout = $this->setEnumVal($value, $enum, $this->layout); return $this; } @@ -623,4 +712,67 @@ class Table extends Border return $this; } + + /** + * Get position + * + * @return \PhpOffice\PhpWord\Style\TablePosition + */ + public function getPosition() + { + return $this->position; + } + + /** + * Set position + * + * @param mixed $value + * @return self + */ + public function setPosition($value = null) + { + $this->setObjectVal($value, 'TablePosition', $this->position); + + return $this; + } + + /** + * @return TblWidthComplexType + */ + public function getIndent() + { + return $this->indent; + } + + /** + * @param TblWidthComplexType $indent + * @return self + * @see http://www.datypic.com/sc/ooxml/e-w_tblInd-1.html + */ + public function setIndent(TblWidthComplexType $indent) + { + $this->indent = $indent; + + return $this; + } + + /** + * Get the columnWidths + * + * @return number[] + */ + public function getColumnWidths() + { + return $this->columnWidths; + } + + /** + * The column widths + * + * @param int[] $value + */ + public function setColumnWidths(array $value = null) + { + $this->columnWidths = $value; + } } diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Style/TablePosition.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Style/TablePosition.php new file mode 100644 index 0000000000..d4b7083102 --- /dev/null +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Style/TablePosition.php @@ -0,0 +1,410 @@ +<?php +/** + * This file is part of PHPWord - A pure PHP library for reading and writing + * word processing documents. + * + * PHPWord is free software distributed under the terms of the GNU Lesser + * General Public License version 3 as published by the Free Software Foundation. + * + * For the full copyright and license information, please read the LICENSE + * file that was distributed with this source code. For the full list of + * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. + * + * @see https://github.com/PHPOffice/PHPWord + * @copyright 2010-2018 PHPWord contributors + * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 + */ + +namespace PhpOffice\PhpWord\Style; + +/** + * TablePosition style + * + * @see http://www.datypic.com/sc/ooxml/e-w_tblpPr-1.html + */ +class TablePosition extends AbstractStyle +{ + /** + * Vertical anchor constants + * + * @const string + * @see http://www.datypic.com/sc/ooxml/t-w_ST_VAnchor.html + */ + const VANCHOR_TEXT = 'text'; // Relative to vertical text extents + const VANCHOR_MARGIN = 'margin'; // Relative to margin + const VANCHOR_PAGE = 'page'; // Relative to page + + /** + * Horizontal anchor constants + * + * @const string + * @see http://www.datypic.com/sc/ooxml/t-w_ST_HAnchor.html + */ + const HANCHOR_TEXT = 'text'; // Relative to text extents + const HANCHOR_MARGIN = 'margin'; // Relative to margin + const HANCHOR_PAGE = 'page'; // Relative to page + + /** + * Horizontal alignment constants + * + * @const string + * @see http://www.datypic.com/sc/ooxml/t-w_ST_XAlign.html + */ + const XALIGN_LEFT = 'left'; // Left aligned horizontally + const XALIGN_CENTER = 'center'; // Centered horizontally + const XALIGN_RIGHT = 'right'; // Right aligned horizontally + const XALIGN_INSIDE = 'inside'; // Inside + const XALIGN_OUTSIDE = 'outside'; // Outside + + /** + * Vertical alignment constants + * + * @const string + * @see http://www.datypic.com/sc/ooxml/t-w_ST_YAlign.html + */ + const YALIGN_INLINE = 'inline'; // In line with text + const YALIGN_TOP = 'top'; // Top + const YALIGN_CENTER = 'center'; // Centered vertically + const YALIGN_BOTTOM = 'bottom'; // Bottom + const YALIGN_INSIDE = 'inside'; // Inside Anchor Extents + const YALIGN_OUTSIDE = 'outside'; // Centered vertically + + /** + * Distance from left of table to text + * + * @var int + */ + private $leftFromText; + + /** + * Distance from right of table to text + * + * @var int + */ + private $rightFromText; + + /** + * Distance from top of table to text + * + * @var int + */ + private $topFromText; + + /** + * Distance from bottom of table to text + * + * @var int + */ + private $bottomFromText; + + /** + * Table vertical anchor + * + * @var string + * @see http://www.datypic.com/sc/ooxml/t-w_ST_VAnchor.html + */ + private $vertAnchor; + + /** + * Table horizontal anchor + * + * @var string + * @see http://www.datypic.com/sc/ooxml/t-w_ST_HAnchor.html + */ + private $horzAnchor; + + /** + * Relative horizontal alignment from anchor + * + * @var string + * @see http://www.datypic.com/sc/ooxml/t-w_ST_XAlign.html + */ + private $tblpXSpec; + + /** + * Absolute horizontal distance from anchor + * + * @var int + */ + private $tblpX; + + /** + * Relative vertical alignment from anchor + * + * @var string + * @see http://www.datypic.com/sc/ooxml/t-w_ST_YAlign.html + */ + private $tblpYSpec; + + /** + * Absolute vertical distance from anchor + * + * @var int + */ + private $tblpY; + + /** + * Create a new instance + * + * @param array $style + */ + public function __construct($style = array()) + { + $this->setStyleByArray($style); + } + + /** + * Get distance from left of table to text + * + * @return int + */ + public function getLeftFromText() + { + return $this->leftFromText; + } + + /** + * Set distance from left of table to text + * + * @param int $value + * @return self + */ + public function setLeftFromText($value = null) + { + $this->leftFromText = $this->setNumericVal($value, $this->leftFromText); + + return $this; + } + + /** + * Get distance from right of table to text + * + * @return int + */ + public function getRightFromText() + { + return $this->rightFromText; + } + + /** + * Set distance from right of table to text + * + * @param int $value + * @return self + */ + public function setRightFromText($value = null) + { + $this->rightFromText = $this->setNumericVal($value, $this->rightFromText); + + return $this; + } + + /** + * Get distance from top of table to text + * + * @return int + */ + public function getTopFromText() + { + return $this->topFromText; + } + + /** + * Set distance from top of table to text + * + * @param int $value + * @return self + */ + public function setTopFromText($value = null) + { + $this->topFromText = $this->setNumericVal($value, $this->topFromText); + + return $this; + } + + /** + * Get distance from bottom of table to text + * + * @return int + */ + public function getBottomFromText() + { + return $this->bottomFromText; + } + + /** + * Set distance from bottom of table to text + * + * @param int $value + * @return self + */ + public function setBottomFromText($value = null) + { + $this->bottomFromText = $this->setNumericVal($value, $this->bottomFromText); + + return $this; + } + + /** + * Get table vertical anchor + * + * @return string + */ + public function getVertAnchor() + { + return $this->vertAnchor; + } + + /** + * Set table vertical anchor + * + * @param string $value + * @return self + */ + public function setVertAnchor($value = null) + { + $enum = array( + self::VANCHOR_TEXT, + self::VANCHOR_MARGIN, + self::VANCHOR_PAGE, + ); + $this->vertAnchor = $this->setEnumVal($value, $enum, $this->vertAnchor); + + return $this; + } + + /** + * Get table horizontal anchor + * + * @return string + */ + public function getHorzAnchor() + { + return $this->horzAnchor; + } + + /** + * Set table horizontal anchor + * + * @param string $value + * @return self + */ + public function setHorzAnchor($value = null) + { + $enum = array( + self::HANCHOR_TEXT, + self::HANCHOR_MARGIN, + self::HANCHOR_PAGE, + ); + $this->horzAnchor = $this->setEnumVal($value, $enum, $this->horzAnchor); + + return $this; + } + + /** + * Get relative horizontal alignment from anchor + * + * @return string + */ + public function getTblpXSpec() + { + return $this->tblpXSpec; + } + + /** + * Set relative horizontal alignment from anchor + * + * @param string $value + * @return self + */ + public function setTblpXSpec($value = null) + { + $enum = array( + self::XALIGN_LEFT, + self::XALIGN_CENTER, + self::XALIGN_RIGHT, + self::XALIGN_INSIDE, + self::XALIGN_OUTSIDE, + ); + $this->tblpXSpec = $this->setEnumVal($value, $enum, $this->tblpXSpec); + + return $this; + } + + /** + * Get absolute horizontal distance from anchor + * + * @return int + */ + public function getTblpX() + { + return $this->tblpX; + } + + /** + * Set absolute horizontal distance from anchor + * + * @param int $value + * @return self + */ + public function setTblpX($value = null) + { + $this->tblpX = $this->setNumericVal($value, $this->tblpX); + + return $this; + } + + /** + * Get relative vertical alignment from anchor + * + * @return string + */ + public function getTblpYSpec() + { + return $this->tblpYSpec; + } + + /** + * Set relative vertical alignment from anchor + * + * @param string $value + * @return self + */ + public function setTblpYSpec($value = null) + { + $enum = array( + self::YALIGN_INLINE, + self::YALIGN_TOP, + self::YALIGN_CENTER, + self::YALIGN_BOTTOM, + self::YALIGN_INSIDE, + self::YALIGN_OUTSIDE, + ); + $this->tblpYSpec = $this->setEnumVal($value, $enum, $this->tblpYSpec); + + return $this; + } + + /** + * Get absolute vertical distance from anchor + * + * @return int + */ + public function getTblpY() + { + return $this->tblpY; + } + + /** + * Set absolute vertical distance from anchor + * + * @param int $value + * @return self + */ + public function setTblpY($value = null) + { + $this->tblpY = $this->setNumericVal($value, $this->tblpY); + + return $this; + } +} diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Style/TextBox.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Style/TextBox.php index 91adc0afd2..e9c0f0c064 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Style/TextBox.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Style/TextBox.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Template.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Template.php index a4769927a0..c42696f08c 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Template.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Template.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/TemplateProcessor.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/TemplateProcessor.php index c46038ee9f..c5826167ea 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/TemplateProcessor.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/TemplateProcessor.php @@ -11,19 +11,19 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ namespace PhpOffice\PhpWord; +use PhpOffice\Common\Text; use PhpOffice\PhpWord\Escaper\RegExp; use PhpOffice\PhpWord\Escaper\Xml; use PhpOffice\PhpWord\Exception\CopyFileException; use PhpOffice\PhpWord\Exception\CreateTemporaryFileException; use PhpOffice\PhpWord\Exception\Exception; use PhpOffice\PhpWord\Shared\ZipArchive; -use Zend\Stdlib\StringUtils; class TemplateProcessor { @@ -113,6 +113,8 @@ class TemplateProcessor */ protected function transformSingleXml($xml, $xsltProcessor) { + $orignalLibEntityLoader = libxml_disable_entity_loader(); + libxml_disable_entity_loader(true); $domDocument = new \DOMDocument(); if (false === $domDocument->loadXML($xml)) { throw new Exception('Could not load the given XML document.'); @@ -122,6 +124,7 @@ class TemplateProcessor if (false === $transformedXml) { throw new Exception('Could not transform the given XML document.'); } + libxml_disable_entity_loader($orignalLibEntityLoader); return $transformedXml; } @@ -192,7 +195,7 @@ class TemplateProcessor */ protected static function ensureUtf8Encoded($subject) { - if (!StringUtils::isValidUtf8($subject)) { + if (!Text::isUTF8($subject)) { $subject = utf8_encode($subject); } @@ -422,7 +425,7 @@ class TemplateProcessor } /* - * Note: we do not use `rename` function here, because it looses file ownership data on Windows platform. + * Note: we do not use `rename` function here, because it loses file ownership data on Windows platform. * As a result, user cannot open the file directly getting "Access denied" message. * * @see https://github.com/PHPOffice/PHPWord/issues/532 diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/AbstractWriter.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/AbstractWriter.php index 884769d724..7e0d511a55 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/AbstractWriter.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/AbstractWriter.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ @@ -216,7 +216,7 @@ abstract class AbstractWriter implements WriterInterface protected function getTempFile($filename) { // Temporary directory - $this->setTempDir(Settings::getTempDir() . uniqid('/PHPWordWriter_') . '/'); + $this->setTempDir(Settings::getTempDir() . uniqid('/PHPWordWriter_', true) . '/'); // Temporary file $this->originalFilename = $filename; @@ -352,6 +352,10 @@ abstract class AbstractWriter implements WriterInterface // Retrive GD image content or get local media if (isset($element['isMemImage']) && $element['isMemImage']) { $image = call_user_func($element['createFunction'], $element['source']); + if ($element['imageType'] === 'image/png') { + // PNG images need to preserve alpha channel information + imagesavealpha($image, true); + } ob_start(); call_user_func($element['imageFunction'], $image); $imageContents = ob_get_contents(); diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/HTML.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/HTML.php index 9b098dd8cd..7f55b9d3e6 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/HTML.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/HTML.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/HTML/Element/AbstractElement.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/HTML/Element/AbstractElement.php index 47f0f93cb9..dc5ccfaadc 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/HTML/Element/AbstractElement.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/HTML/Element/AbstractElement.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/HTML/Element/Bookmark.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/HTML/Element/Bookmark.php new file mode 100644 index 0000000000..082bd76073 --- /dev/null +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/HTML/Element/Bookmark.php @@ -0,0 +1,45 @@ +<?php +/** + * This file is part of PHPWord - A pure PHP library for reading and writing + * word processing documents. + * + * PHPWord is free software distributed under the terms of the GNU Lesser + * General Public License version 3 as published by the Free Software Foundation. + * + * For the full copyright and license information, please read the LICENSE + * file that was distributed with this source code. For the full list of + * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. + * + * @see https://github.com/PHPOffice/PHPWord + * @copyright 2010-2018 PHPWord contributors + * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 + */ + +namespace PhpOffice\PhpWord\Writer\HTML\Element; + +/** + * Bookmark element HTML writer + * + * @since 0.15.0 + */ +class Bookmark extends Text +{ + /** + * Write bookmark + * + * @return string + */ + public function write() + { + if (!$this->element instanceof \PhpOffice\PhpWord\Element\Bookmark) { + return ''; + } + + $content = ''; + $content .= $this->writeOpening(); + $content .= "<a name=\"{$this->element->getName()}\"/>"; + $content .= $this->writeClosing(); + + return $content; + } +} diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/HTML/Element/Container.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/HTML/Element/Container.php index 677b6173b4..006b588918 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/HTML/Element/Container.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/HTML/Element/Container.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/HTML/Element/Endnote.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/HTML/Element/Endnote.php index c4a3e4365a..2252dc3af8 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/HTML/Element/Endnote.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/HTML/Element/Endnote.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/HTML/Element/Footnote.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/HTML/Element/Footnote.php index 60b246f878..ed14db1e04 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/HTML/Element/Footnote.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/HTML/Element/Footnote.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/HTML/Element/Image.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/HTML/Element/Image.php index 3e516b53a1..7c22a1663d 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/HTML/Element/Image.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/HTML/Element/Image.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/HTML/Element/Link.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/HTML/Element/Link.php index bdea985a18..f6dae5cdd3 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/HTML/Element/Link.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/HTML/Element/Link.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ @@ -37,12 +37,12 @@ class Link extends Text return ''; } - $content = ''; - $content .= $this->writeOpening(); + $prefix = $this->element->isInternal() ? '#' : ''; + $content = $this->writeOpening(); if (Settings::isOutputEscapingEnabled()) { - $content .= "<a href=\"{$this->escaper->escapeHtmlAttr($this->element->getSource())}\">{$this->escaper->escapeHtml($this->element->getText())}</a>"; + $content .= "<a href=\"{$prefix}{$this->escaper->escapeHtmlAttr($this->element->getSource())}\">{$this->escaper->escapeHtml($this->element->getText())}</a>"; } else { - $content .= "<a href=\"{$this->element->getSource()}\">{$this->element->getText()}</a>"; + $content .= "<a href=\"{$prefix}{$this->element->getSource()}\">{$this->element->getText()}</a>"; } $content .= $this->writeClosing(); diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/HTML/Element/ListItem.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/HTML/Element/ListItem.php index 02b25eb98a..384b3ef165 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/HTML/Element/ListItem.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/HTML/Element/ListItem.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/HTML/Element/PageBreak.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/HTML/Element/PageBreak.php index 5cab272479..f9998e3793 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/HTML/Element/PageBreak.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/HTML/Element/PageBreak.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/HTML/Element/Table.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/HTML/Element/Table.php index c7d8670b16..844066f49e 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/HTML/Element/Table.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/HTML/Element/Table.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ @@ -40,18 +40,60 @@ class Table extends AbstractElement $rowCount = count($rows); if ($rowCount > 0) { $content .= '<table>' . PHP_EOL; - foreach ($rows as $row) { + for ($i = 0; $i < $rowCount; $i++) { /** @var $row \PhpOffice\PhpWord\Element\Row Type hint */ - $rowStyle = $row->getStyle(); + $rowStyle = $rows[$i]->getStyle(); // $height = $row->getHeight(); $tblHeader = $rowStyle->isTblHeader(); $content .= '<tr>' . PHP_EOL; - foreach ($row->getCells() as $cell) { - $writer = new Container($this->parentWriter, $cell); - $cellTag = $tblHeader ? 'th' : 'td'; - $content .= "<{$cellTag}>" . PHP_EOL; - $content .= $writer->write(); - $content .= "</{$cellTag}>" . PHP_EOL; + $rowCells = $rows[$i]->getCells(); + $rowCellCount = count($rowCells); + for ($j = 0; $j < $rowCellCount; $j++) { + $cellStyle = $rowCells[$j]->getStyle(); + $cellColSpan = $cellStyle->getGridSpan(); + $cellRowSpan = 1; + $cellVMerge = $cellStyle->getVMerge(); + // If this is the first cell of the vertical merge, find out how man rows it spans + if ($cellVMerge === 'restart') { + for ($k = $i + 1; $k < $rowCount; $k++) { + $kRowCells = $rows[$k]->getCells(); + if (isset($kRowCells[$j])) { + if ($kRowCells[$j]->getStyle()->getVMerge() === 'continue') { + $cellRowSpan++; + } else { + break; + } + } else { + break; + } + } + } + // Ignore cells that are merged vertically with previous rows + if ($cellVMerge !== 'continue') { + $cellTag = $tblHeader ? 'th' : 'td'; + $cellColSpanAttr = (is_numeric($cellColSpan) && ($cellColSpan > 1) ? " colspan=\"{$cellColSpan}\"" : ''); + $cellRowSpanAttr = ($cellRowSpan > 1 ? " rowspan=\"{$cellRowSpan}\"" : ''); + $content .= "<{$cellTag}{$cellColSpanAttr}{$cellRowSpanAttr}>" . PHP_EOL; + $writer = new Container($this->parentWriter, $rowCells[$j]); + $content .= $writer->write(); + if ($cellRowSpan > 1) { + // There shouldn't be any content in the subsequent merged cells, but lets check anyway + for ($k = $i + 1; $k < $rowCount; $k++) { + $kRowCells = $rows[$k]->getCells(); + if (isset($kRowCells[$j])) { + if ($kRowCells[$j]->getStyle()->getVMerge() === 'continue') { + $writer = new Container($this->parentWriter, $kRowCells[$j]); + $content .= $writer->write(); + } else { + break; + } + } else { + break; + } + } + } + $content .= "</{$cellTag}>" . PHP_EOL; + } } $content .= '</tr>' . PHP_EOL; } diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/HTML/Element/Text.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/HTML/Element/Text.php index 71cb75669a..04d76a8327 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/HTML/Element/Text.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/HTML/Element/Text.php @@ -11,12 +11,13 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ namespace PhpOffice\PhpWord\Writer\HTML\Element; +use PhpOffice\PhpWord\Element\TrackChange; use PhpOffice\PhpWord\Settings; use PhpOffice\PhpWord\Style\Font; use PhpOffice\PhpWord\Style\Paragraph; @@ -121,6 +122,9 @@ class Text extends AbstractElement $content .= "<p{$style}>"; } + //open track change tag + $content .= $this->writeTrackChangeOpening(); + return $content; } @@ -132,6 +136,10 @@ class Text extends AbstractElement protected function writeClosing() { $content = ''; + + //close track change tag + $content .= $this->writeTrackChangeClosing(); + if (!$this->withoutP) { if (Settings::isOutputEscapingEnabled()) { $content .= $this->escaper->escapeHtml($this->closingText); @@ -145,6 +153,63 @@ class Text extends AbstractElement return $content; } + /** + * writes the track change opening tag + * + * @return string the HTML, an empty string if no track change information + */ + private function writeTrackChangeOpening() + { + $changed = $this->element->getTrackChange(); + if ($changed == null) { + return ''; + } + + $content = ''; + if (($changed->getChangeType() == TrackChange::INSERTED)) { + $content .= '<ins data-phpword-prop=\''; + } elseif ($changed->getChangeType() == TrackChange::DELETED) { + $content .= '<del data-phpword-prop=\''; + } + + $changedProp = array('changed' => array('author'=> $changed->getAuthor(), 'id' => $this->element->getElementId())); + if ($changed->getDate() != null) { + $changedProp['changed']['date'] = $changed->getDate()->format('Y-m-d\TH:i:s\Z'); + } + $content .= json_encode($changedProp); + $content .= '\' '; + $content .= 'title="' . $changed->getAuthor(); + if ($changed->getDate() != null) { + $dateUser = $changed->getDate()->format('Y-m-d H:i:s'); + $content .= ' - ' . $dateUser; + } + $content .= '">'; + + return $content; + } + + /** + * writes the track change closing tag + * + * @return string the HTML, an empty string if no track change information + */ + private function writeTrackChangeClosing() + { + $changed = $this->element->getTrackChange(); + if ($changed == null) { + return ''; + } + + $content = ''; + if (($changed->getChangeType() == TrackChange::INSERTED)) { + $content .= '</ins>'; + } elseif ($changed->getChangeType() == TrackChange::DELETED) { + $content .= '</del>'; + } + + return $content; + } + /** * Write paragraph style * diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/HTML/Element/TextBreak.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/HTML/Element/TextBreak.php index 93ab924a50..6ff092dbf7 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/HTML/Element/TextBreak.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/HTML/Element/TextBreak.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/HTML/Element/TextRun.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/HTML/Element/TextRun.php index d7461539d9..b2deaf25d8 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/HTML/Element/TextRun.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/HTML/Element/TextRun.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/HTML/Element/Title.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/HTML/Element/Title.php index ee8f271b19..7307ce0c17 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/HTML/Element/Title.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/HTML/Element/Title.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ @@ -38,11 +38,17 @@ class Title extends AbstractElement } $tag = 'h' . $this->element->getDepth(); - if (Settings::isOutputEscapingEnabled()) { - $text = $this->escaper->escapeHtml($this->element->getText()); - } else { - $text = $this->element->getText(); + + $text = $this->element->getText(); + if (is_string($text)) { + if (Settings::isOutputEscapingEnabled()) { + $text = $this->escaper->escapeHtml($text); + } + } elseif ($text instanceof \PhpOffice\PhpWord\Element\AbstractContainer) { + $writer = new Container($this->parentWriter, $this->element); + $text = $writer->write(); } + $content = "<{$tag}>{$text}</{$tag}>" . PHP_EOL; return $content; diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/HTML/Part/AbstractPart.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/HTML/Part/AbstractPart.php index 7b6e0c3ea3..2d86f399b0 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/HTML/Part/AbstractPart.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/HTML/Part/AbstractPart.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/HTML/Part/Body.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/HTML/Part/Body.php index eea173500d..a029f96534 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/HTML/Part/Body.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/HTML/Part/Body.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/HTML/Part/Head.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/HTML/Part/Head.php index f4d630145f..1107becf84 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/HTML/Part/Head.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/HTML/Part/Head.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/HTML/Style/AbstractStyle.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/HTML/Style/AbstractStyle.php index fa27c085ca..cfb54cb8d7 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/HTML/Style/AbstractStyle.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/HTML/Style/AbstractStyle.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/HTML/Style/Font.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/HTML/Style/Font.php index 8daa8823c8..1aeaa347f9 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/HTML/Style/Font.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/HTML/Style/Font.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/HTML/Style/Generic.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/HTML/Style/Generic.php index 73830707b1..ee5d089607 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/HTML/Style/Generic.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/HTML/Style/Generic.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/HTML/Style/Image.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/HTML/Style/Image.php index 178b14348e..93747b4645 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/HTML/Style/Image.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/HTML/Style/Image.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/HTML/Style/Paragraph.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/HTML/Style/Paragraph.php index 57e44e8594..863ef93b14 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/HTML/Style/Paragraph.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/HTML/Style/Paragraph.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/ODText.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/ODText.php index 7158874c11..efd0d6a923 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/ODText.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/ODText.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/ODText/Element/AbstractElement.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/ODText/Element/AbstractElement.php index 481995ff80..9c9fc1c477 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/ODText/Element/AbstractElement.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/ODText/Element/AbstractElement.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/ODText/Element/Container.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/ODText/Element/Container.php index 112e71e87f..6ba8124f0f 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/ODText/Element/Container.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/ODText/Element/Container.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/ODText/Element/Image.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/ODText/Element/Image.php index 2c0b4727d2..add45e1044 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/ODText/Element/Image.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/ODText/Element/Image.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/ODText/Element/Link.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/ODText/Element/Link.php index 34d72c1ac7..d6fec50777 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/ODText/Element/Link.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/ODText/Element/Link.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/ODText/Element/PageBreak.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/ODText/Element/PageBreak.php index 6eee6cfc94..ecf4760740 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/ODText/Element/PageBreak.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/ODText/Element/PageBreak.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/ODText/Element/Table.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/ODText/Element/Table.php index cdc2a0e3cd..088330ae5f 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/ODText/Element/Table.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/ODText/Element/Table.php @@ -11,12 +11,16 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ namespace PhpOffice\PhpWord\Writer\ODText\Element; +use PhpOffice\Common\XMLWriter; +use PhpOffice\PhpWord\Element\Row as RowElement; +use PhpOffice\PhpWord\Element\Table as TableElement; + /** * Table element writer * @@ -36,32 +40,59 @@ class Table extends AbstractElement } $rows = $element->getRows(); $rowCount = count($rows); - $colCount = $element->countColumns(); if ($rowCount > 0) { $xmlWriter->startElement('table:table'); $xmlWriter->writeAttribute('table:name', $element->getElementId()); $xmlWriter->writeAttribute('table:style', $element->getElementId()); - $xmlWriter->startElement('table:table-column'); - $xmlWriter->writeAttribute('table:number-columns-repeated', $colCount); - $xmlWriter->endElement(); // table:table-column + // Write columns + $this->writeColumns($xmlWriter, $element); + // Write rows foreach ($rows as $row) { - $xmlWriter->startElement('table:table-row'); - /** @var $row \PhpOffice\PhpWord\Element\Row Type hint */ - foreach ($row->getCells() as $cell) { - $xmlWriter->startElement('table:table-cell'); - $xmlWriter->writeAttribute('office:value-type', 'string'); - - $containerWriter = new Container($xmlWriter, $cell); - $containerWriter->write(); - - $xmlWriter->endElement(); // table:table-cell - } - $xmlWriter->endElement(); // table:table-row + $this->writeRow($xmlWriter, $row); } $xmlWriter->endElement(); // table:table } } + + /** + * Write column. + * + * @param \PhpOffice\Common\XMLWriter $xmlWriter + * @param \PhpOffice\PhpWord\Element\Table $element + */ + private function writeColumns(XMLWriter $xmlWriter, TableElement $element) + { + $colCount = $element->countColumns(); + + for ($i = 0; $i < $colCount; $i++) { + $xmlWriter->startElement('table:table-column'); + $xmlWriter->writeAttribute('table:style-name', $element->getElementId() . '.' . $i); + $xmlWriter->endElement(); + } + } + + /** + * Write row. + * + * @param \PhpOffice\Common\XMLWriter $xmlWriter + * @param \PhpOffice\PhpWord\Element\Row $row + */ + private function writeRow(XMLWriter $xmlWriter, RowElement $row) + { + $xmlWriter->startElement('table:table-row'); + /** @var $row \PhpOffice\PhpWord\Element\Row Type hint */ + foreach ($row->getCells() as $cell) { + $xmlWriter->startElement('table:table-cell'); + $xmlWriter->writeAttribute('office:value-type', 'string'); + + $containerWriter = new Container($xmlWriter, $cell); + $containerWriter->write(); + + $xmlWriter->endElement(); // table:table-cell + } + $xmlWriter->endElement(); // table:table-row + } } diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/ODText/Element/Text.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/ODText/Element/Text.php index 1fc0b80028..7dcd28a013 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/ODText/Element/Text.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/ODText/Element/Text.php @@ -11,12 +11,13 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ namespace PhpOffice\PhpWord\Writer\ODText\Element; +use PhpOffice\PhpWord\Element\TrackChange; use PhpOffice\PhpWord\Exception\Exception; /** @@ -51,29 +52,50 @@ class Text extends AbstractElement if (!$this->withoutP) { $xmlWriter->startElement('text:p'); // text:p } - if (empty($fontStyle)) { - if (empty($paragraphStyle)) { - $xmlWriter->writeAttribute('text:style-name', 'P1'); - } elseif (is_string($paragraphStyle)) { - $xmlWriter->writeAttribute('text:style-name', $paragraphStyle); - } - $this->writeText($element->getText()); + if ($element->getTrackChange() != null && $element->getTrackChange()->getChangeType() == TrackChange::DELETED) { + $xmlWriter->startElement('text:change'); + $xmlWriter->writeAttribute('text:change-id', $element->getTrackChange()->getElementId()); + $xmlWriter->endElement(); } else { - if (empty($paragraphStyle)) { - $xmlWriter->writeAttribute('text:style-name', 'Standard'); - } elseif (is_string($paragraphStyle)) { - $xmlWriter->writeAttribute('text:style-name', $paragraphStyle); - } - // text:span - $xmlWriter->startElement('text:span'); - if (is_string($fontStyle)) { - $xmlWriter->writeAttribute('text:style-name', $fontStyle); + if (empty($fontStyle)) { + if (empty($paragraphStyle)) { + $xmlWriter->writeAttribute('text:style-name', 'P1'); + } elseif (is_string($paragraphStyle)) { + $xmlWriter->writeAttribute('text:style-name', $paragraphStyle); + } + $this->writeChangeInsertion(true, $element->getTrackChange()); + $this->writeText($element->getText()); + $this->writeChangeInsertion(false, $element->getTrackChange()); + } else { + if (empty($paragraphStyle)) { + $xmlWriter->writeAttribute('text:style-name', 'Standard'); + } elseif (is_string($paragraphStyle)) { + $xmlWriter->writeAttribute('text:style-name', $paragraphStyle); + } + // text:span + $xmlWriter->startElement('text:span'); + if (is_string($fontStyle)) { + $xmlWriter->writeAttribute('text:style-name', $fontStyle); + } + $this->writeChangeInsertion(true, $element->getTrackChange()); + $this->writeText($element->getText()); + $this->writeChangeInsertion(false, $element->getTrackChange()); + $xmlWriter->endElement(); } - $this->writeText($element->getText()); - $xmlWriter->endElement(); } if (!$this->withoutP) { $xmlWriter->endElement(); // text:p } } + + private function writeChangeInsertion($start = true, TrackChange $trackChange = null) + { + if ($trackChange == null || $trackChange->getChangeType() != TrackChange::INSERTED) { + return; + } + $xmlWriter = $this->getXmlWriter(); + $xmlWriter->startElement('text:change-' . ($start ? 'start' : 'end')); + $xmlWriter->writeAttribute('text:change-id', $trackChange->getElementId()); + $xmlWriter->endElement(); + } } diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/ODText/Element/TextBreak.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/ODText/Element/TextBreak.php index f7642e3b28..80cd13870a 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/ODText/Element/TextBreak.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/ODText/Element/TextBreak.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/ODText/Element/TextRun.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/ODText/Element/TextRun.php index f5c855fe33..78e5a8adae 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/ODText/Element/TextRun.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/ODText/Element/TextRun.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/ODText/Element/Title.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/ODText/Element/Title.php index 769d293f5d..8b9440ab8c 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/ODText/Element/Title.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/ODText/Element/Title.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ @@ -37,7 +37,13 @@ class Title extends AbstractElement $xmlWriter->startElement('text:h'); $xmlWriter->writeAttribute('text:outline-level', $element->getDepth()); - $this->writeText($element->getText()); + $text = $element->getText(); + if (is_string($text)) { + $this->writeText($text); + } elseif ($text instanceof \PhpOffice\PhpWord\Element\AbstractContainer) { + $containerWriter = new Container($xmlWriter, $text); + $containerWriter->write(); + } $xmlWriter->endElement(); // text:h } } diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/ODText/Part/AbstractPart.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/ODText/Part/AbstractPart.php index 74412fd42b..f2844de6f0 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/ODText/Part/AbstractPart.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/ODText/Part/AbstractPart.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/ODText/Part/Content.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/ODText/Part/Content.php index 8ae4dca9c7..99ee93536e 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/ODText/Part/Content.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/ODText/Part/Content.php @@ -11,17 +11,19 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ namespace PhpOffice\PhpWord\Writer\ODText\Part; use PhpOffice\Common\XMLWriter; +use PhpOffice\PhpWord\Element\AbstractContainer; use PhpOffice\PhpWord\Element\Image; use PhpOffice\PhpWord\Element\Table; use PhpOffice\PhpWord\Element\Text; use PhpOffice\PhpWord\Element\TextRun; +use PhpOffice\PhpWord\Element\TrackChange; use PhpOffice\PhpWord\PhpWord; use PhpOffice\PhpWord\Style; use PhpOffice\PhpWord\Style\Font; @@ -74,6 +76,40 @@ class Content extends AbstractPart $xmlWriter->startElement('office:body'); $xmlWriter->startElement('office:text'); + // Tracked changes declarations + $trackedChanges = array(); + $sections = $phpWord->getSections(); + foreach ($sections as $section) { + $this->collectTrackedChanges($section, $trackedChanges); + } + $xmlWriter->startElement('text:tracked-changes'); + foreach ($trackedChanges as $trackedElement) { + $trackedChange = $trackedElement->getTrackChange(); + $xmlWriter->startElement('text:changed-region'); + $trackedChange->setElementId(); + $xmlWriter->writeAttribute('text:id', $trackedChange->getElementId()); + + if (($trackedChange->getChangeType() == TrackChange::INSERTED)) { + $xmlWriter->startElement('text:insertion'); + } elseif ($trackedChange->getChangeType() == TrackChange::DELETED) { + $xmlWriter->startElement('text:deletion'); + } + + $xmlWriter->startElement('office:change-info'); + $xmlWriter->writeElement('dc:creator', $trackedChange->getAuthor()); + if ($trackedChange->getDate() != null) { + $xmlWriter->writeElement('dc:date', $trackedChange->getDate()->format('Y-m-d\TH:i:s\Z')); + } + $xmlWriter->endElement(); // office:change-info + if ($trackedChange->getChangeType() == TrackChange::DELETED) { + $xmlWriter->writeElement('text:p', $trackedElement->getText()); + } + + $xmlWriter->endElement(); // text:insertion|text:deletion + $xmlWriter->endElement(); // text:changed-region + } + $xmlWriter->endElement(); // text:tracked-changes + // Sequence declarations $sequences = array('Illustration', 'Table', 'Text', 'Drawing'); $xmlWriter->startElement('text:sequence-decls'); @@ -186,8 +222,8 @@ class Content extends AbstractPart * Table style can be null or string of the style name * * @param \PhpOffice\PhpWord\Element\AbstractContainer $container - * @param int &$paragraphStyleCount - * @param int &$fontStyleCount + * @param int $paragraphStyleCount + * @param int $fontStyleCount * @todo Simplify the logic */ private function getContainerStyle($container, &$paragraphStyleCount, &$fontStyleCount) @@ -203,6 +239,7 @@ class Content extends AbstractPart $style->setStyleName('fr' . $element->getMediaIndex()); $this->autoStyles['Image'][] = $style; } elseif ($element instanceof Table) { + /** @var \PhpOffice\PhpWord\Style\Table $style */ $style = $element->getStyle(); if ($style === null) { $style = new TableStyle(); @@ -210,6 +247,7 @@ class Content extends AbstractPart $style = Style::getStyle($style); } $style->setStyleName($element->getElementId()); + $style->setColumnWidths($element->findFirstDefinedCellWidths()); $this->autoStyles['Table'][] = $style; } } @@ -218,9 +256,9 @@ class Content extends AbstractPart /** * Get style of individual element * - * @param \PhpOffice\PhpWord\Element\Text &$element - * @param int &$paragraphStyleCount - * @param int &$fontStyleCount + * @param \PhpOffice\PhpWord\Element\Text $element + * @param int $paragraphStyleCount + * @param int $fontStyleCount */ private function getElementStyle(&$element, &$paragraphStyleCount, &$fontStyleCount) { @@ -242,4 +280,23 @@ class Content extends AbstractPart $element->setParagraphStyle("P{$paragraphStyleCount}"); } } + + /** + * Finds all tracked changes + * + * @param AbstractContainer $container + * @param \PhpOffice\PhpWord\Element\AbstractElement[] $trackedChanges + */ + private function collectTrackedChanges(AbstractContainer $container, &$trackedChanges = array()) + { + $elements = $container->getElements(); + foreach ($elements as $element) { + if ($element->getTrackChange() != null) { + $trackedChanges[] = $element; + } + if (is_callable(array($element, 'getElements'))) { + $this->collectTrackedChanges($element, $trackedChanges); + } + } + } } diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/ODText/Part/Manifest.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/ODText/Part/Manifest.php index d916ccdfb4..f952b4c072 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/ODText/Part/Manifest.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/ODText/Part/Manifest.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/ODText/Part/Meta.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/ODText/Part/Meta.php index f592c5f034..f38ad01d56 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/ODText/Part/Meta.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/ODText/Part/Meta.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/ODText/Part/Mimetype.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/ODText/Part/Mimetype.php index 6e45b8485f..552f54403a 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/ODText/Part/Mimetype.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/ODText/Part/Mimetype.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/ODText/Part/Styles.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/ODText/Part/Styles.php index e49fa25e34..e7635e9854 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/ODText/Part/Styles.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/ODText/Part/Styles.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/ODText/Style/AbstractStyle.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/ODText/Style/AbstractStyle.php index 26b9905bd5..f7679ab22c 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/ODText/Style/AbstractStyle.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/ODText/Style/AbstractStyle.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/ODText/Style/Font.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/ODText/Style/Font.php index 50de32adad..7c7d20ddd2 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/ODText/Style/Font.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/ODText/Style/Font.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/ODText/Style/Image.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/ODText/Style/Image.php index b85d4d70a6..13005a7f03 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/ODText/Style/Image.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/ODText/Style/Image.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/ODText/Style/Paragraph.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/ODText/Style/Paragraph.php index 14a811a52d..223d02f047 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/ODText/Style/Paragraph.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/ODText/Style/Paragraph.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/ODText/Style/Section.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/ODText/Style/Section.php index bef023e9f3..92d8891170 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/ODText/Style/Section.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/ODText/Style/Section.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/ODText/Style/Table.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/ODText/Style/Table.php index 7d66899ac7..5ddee25a3c 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/ODText/Style/Table.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/ODText/Style/Table.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ @@ -45,5 +45,19 @@ class Table extends AbstractStyle $xmlWriter->writeAttribute('table:align', 'center'); $xmlWriter->endElement(); // style:table-properties $xmlWriter->endElement(); // style:style + + $cellWidths = $style->getColumnWidths(); + $countCellWidths = count($cellWidths); + + for ($i = 0; $i < $countCellWidths; $i++) { + $width = $cellWidths[$i]; + $xmlWriter->startElement('style:style'); + $xmlWriter->writeAttribute('style:name', $style->getStyleName() . '.' . $i); + $xmlWriter->writeAttribute('style:family', 'table-column'); + $xmlWriter->startElement('style:table-column-properties'); + $xmlWriter->writeAttribute('style:column-width', number_format($width * 0.0017638889, 2, '.', '') . 'cm'); + $xmlWriter->endElement(); // style:table-column-properties + $xmlWriter->endElement(); // style:style + } } } diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/PDF.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/PDF.php index 45fe8f3518..64dcc7898d 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/PDF.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/PDF.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PhpWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/PDF/AbstractRenderer.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/PDF/AbstractRenderer.php index 7b668e0b89..5f9e3b3a8c 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/PDF/AbstractRenderer.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/PDF/AbstractRenderer.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PhpWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/PDF/DomPDF.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/PDF/DomPDF.php index be282d2026..5fa8f75dbb 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/PDF/DomPDF.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/PDF/DomPDF.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PhpWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/PDF/MPDF.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/PDF/MPDF.php index e238057b1f..e63f5dfd68 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/PDF/MPDF.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/PDF/MPDF.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PhpWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ @@ -29,6 +29,12 @@ use PhpOffice\PhpWord\Writer\WriterInterface; */ class MPDF extends AbstractRenderer implements WriterInterface { + /** + * Overridden to set the correct includefile, only needed for MPDF 5 + * + * @codeCoverageIgnore + * @param PhpWord $phpWord + */ public function __construct(PhpWord $phpWord) { if (file_exists(Settings::getPdfRendererPath() . '/mpdf.php')) { @@ -52,13 +58,8 @@ class MPDF extends AbstractRenderer implements WriterInterface $orientation = strtoupper('portrait'); // Create PDF - if ($this->includeFile != null) { - // MPDF version 5.* - $pdf = new \mpdf(); - } else { - // MPDF version > 6.* - $pdf = new \Mpdf\Mpdf(); - } + $mPdfClass = $this->getMPdfClassName(); + $pdf = new $mPdfClass(); $pdf->_setPageSize($paperSize, $orientation); $pdf->addPage($orientation); @@ -78,4 +79,21 @@ class MPDF extends AbstractRenderer implements WriterInterface parent::restoreStateAfterSave($fileHandle); } + + /** + * Return classname of MPDF to instantiate + * + * @codeCoverageIgnore + * @return string + */ + private function getMPdfClassName() + { + if ($this->includeFile != null) { + // MPDF version 5.* + return '\mpdf'; + } + + // MPDF version > 6.* + return '\Mpdf\Mpdf'; + } } diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/PDF/TCPDF.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/PDF/TCPDF.php index 85e3614c08..badab0460e 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/PDF/TCPDF.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/PDF/TCPDF.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PhpWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/RTF.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/RTF.php index 7756253ab7..0604e8b56b 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/RTF.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/RTF.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/RTF/Element/AbstractElement.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/RTF/Element/AbstractElement.php index 1013ee3685..cf1aa391c5 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/RTF/Element/AbstractElement.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/RTF/Element/AbstractElement.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/RTF/Element/Container.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/RTF/Element/Container.php index 4850c8bf2d..58c19256dc 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/RTF/Element/Container.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/RTF/Element/Container.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/RTF/Element/Image.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/RTF/Element/Image.php index fb96baffe5..f1e727007b 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/RTF/Element/Image.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/RTF/Element/Image.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/RTF/Element/Link.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/RTF/Element/Link.php index 91a75720dc..25954ed878 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/RTF/Element/Link.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/RTF/Element/Link.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/RTF/Element/ListItem.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/RTF/Element/ListItem.php index e628bffd36..29e7f6607d 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/RTF/Element/ListItem.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/RTF/Element/ListItem.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/RTF/Element/PageBreak.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/RTF/Element/PageBreak.php index 0adbe06e96..6b08c9cc44 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/RTF/Element/PageBreak.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/RTF/Element/PageBreak.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/RTF/Element/Table.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/RTF/Element/Table.php index d0bc08457e..8154aa7cf5 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/RTF/Element/Table.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/RTF/Element/Table.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/RTF/Element/Text.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/RTF/Element/Text.php index 2fac052088..b9e56e890b 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/RTF/Element/Text.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/RTF/Element/Text.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ @@ -34,7 +34,7 @@ class Text extends AbstractElement /** @var \PhpOffice\PhpWord\Element\Text $element Type hint */ $element = $this->element; $elementClass = str_replace('\\Writer\\RTF', '', get_class($this)); - if (!$element instanceof $elementClass) { + if (!$element instanceof $elementClass || !is_string($element->getText())) { return ''; } diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/RTF/Element/TextBreak.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/RTF/Element/TextBreak.php index 2009fcfff1..4aab27677a 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/RTF/Element/TextBreak.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/RTF/Element/TextBreak.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/RTF/Element/TextRun.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/RTF/Element/TextRun.php index d4e5676552..bfd161f08a 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/RTF/Element/TextRun.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/RTF/Element/TextRun.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/RTF/Element/Title.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/RTF/Element/Title.php index 18bad9fd6a..a9940ca99a 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/RTF/Element/Title.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/RTF/Element/Title.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/RTF/Part/AbstractPart.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/RTF/Part/AbstractPart.php index 7569a105aa..8171b0d228 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/RTF/Part/AbstractPart.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/RTF/Part/AbstractPart.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/RTF/Part/Document.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/RTF/Part/Document.php index 465872eade..d4bfadb4c5 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/RTF/Part/Document.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/RTF/Part/Document.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/RTF/Part/Header.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/RTF/Part/Header.php index 73f1351f8a..01439bc6ad 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/RTF/Part/Header.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/RTF/Part/Header.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/RTF/Style/AbstractStyle.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/RTF/Style/AbstractStyle.php index 8052361092..57aa6bb9f7 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/RTF/Style/AbstractStyle.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/RTF/Style/AbstractStyle.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/RTF/Style/Border.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/RTF/Style/Border.php index 0ba9f60254..08dcf01810 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/RTF/Style/Border.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/RTF/Style/Border.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/RTF/Style/Font.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/RTF/Style/Font.php index 3338368ad4..8c729425d1 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/RTF/Style/Font.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/RTF/Style/Font.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/RTF/Style/Indentation.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/RTF/Style/Indentation.php new file mode 100644 index 0000000000..dd52230ee8 --- /dev/null +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/RTF/Style/Indentation.php @@ -0,0 +1,45 @@ +<?php +/** + * This file is part of PHPWord - A pure PHP library for reading and writing + * word processing documents. + * + * PHPWord is free software distributed under the terms of the GNU Lesser + * General Public License version 3 as published by the Free Software Foundation. + * + * For the full copyright and license information, please read the LICENSE + * file that was distributed with this source code. For the full list of + * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. + * + * @see https://github.com/PHPOffice/PHPWord + * @copyright 2010-2018 PHPWord contributors + * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 + */ + +namespace PhpOffice\PhpWord\Writer\RTF\Style; + +/** + * RTF indentation style writer + * + * @since 0.11.0 + */ +class Indentation extends AbstractStyle +{ + /** + * Write style + * + * @return string + */ + public function write() + { + $style = $this->getStyle(); + if (!$style instanceof \PhpOffice\PhpWord\Style\Indentation) { + return ''; + } + + $content = '\fi' . $style->getFirstLine(); + $content .= '\li' . $style->getLeft(); + $content .= '\ri' . $style->getRight(); + + return $content . ' '; + } +} diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/RTF/Style/Paragraph.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/RTF/Style/Paragraph.php index 61b61fd73c..cb50a31b02 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/RTF/Style/Paragraph.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/RTF/Style/Paragraph.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ @@ -64,9 +64,49 @@ class Paragraph extends AbstractStyle if (isset($alignments[$style->getAlignment()])) { $content .= $alignments[$style->getAlignment()]; } + $content .= $this->writeIndentation($style->getIndentation()); $content .= $this->getValueIf($spaceBefore !== null, '\sb' . $spaceBefore); $content .= $this->getValueIf($spaceAfter !== null, '\sa' . $spaceAfter); + $styles = $style->getStyleValues(); + $content .= $this->writeTabs($styles['tabs']); + + return $content; + } + + /** + * Writes an \PhpOffice\PhpWord\Style\Indentation + * + * @param null|\PhpOffice\PhpWord\Style\Indentation $indent + * @return string + */ + private function writeIndentation($indent = null) + { + if (isset($indent) && $indent instanceof \PhpOffice\PhpWord\Style\Indentation) { + $writer = new Indentation($indent); + + return $writer->write(); + } + + return ''; + } + + /** + * Writes tabs + * + * @param \PhpOffice\PhpWord\Style\Tab[] $tabs + * @return string + */ + private function writeTabs($tabs = null) + { + $content = ''; + if (!empty($tabs)) { + foreach ($tabs as $tab) { + $styleWriter = new Tab($tab); + $content .= $styleWriter->write(); + } + } + return $content; } diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/RTF/Style/Section.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/RTF/Style/Section.php index 8f073716ba..5c34fa8683 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/RTF/Style/Section.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/RTF/Style/Section.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/RTF/Style/Tab.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/RTF/Style/Tab.php new file mode 100644 index 0000000000..fe1f9363eb --- /dev/null +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/RTF/Style/Tab.php @@ -0,0 +1,49 @@ +<?php +/** + * This file is part of PHPWord - A pure PHP library for reading and writing + * word processing documents. + * + * PHPWord is free software distributed under the terms of the GNU Lesser + * General Public License version 3 as published by the Free Software Foundation. + * + * For the full copyright and license information, please read the LICENSE + * file that was distributed with this source code. For the full list of + * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. + * + * @see https://github.com/PHPOffice/PHPWord + * @copyright 2010-2018 PHPWord contributors + * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 + */ + +namespace PhpOffice\PhpWord\Writer\RTF\Style; + +/** + * Line numbering style writer + * + * @since 0.10.0 + */ +class Tab extends AbstractStyle +{ + /** + * Write style. + */ + public function write() + { + $style = $this->getStyle(); + if (!$style instanceof \PhpOffice\PhpWord\Style\Tab) { + return; + } + $tabs = array( + \PhpOffice\PhpWord\Style\Tab::TAB_STOP_RIGHT => '\tqr', + \PhpOffice\PhpWord\Style\Tab::TAB_STOP_CENTER => '\tqc', + \PhpOffice\PhpWord\Style\Tab::TAB_STOP_DECIMAL => '\tqdec', + ); + $content = ''; + if (isset($tabs[$style->getType()])) { + $content .= $tabs[$style->getType()]; + } + $content .= '\tx' . $style->getPosition(); + + return $content; + } +} diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007.php index fcef982fe2..eee215bef0 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Element/AbstractElement.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Element/AbstractElement.php index 8c9f0bb7a6..63f45a761f 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Element/AbstractElement.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Element/AbstractElement.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Element/Bookmark.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Element/Bookmark.php index 4b0b78a73a..04eaacf37c 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Element/Bookmark.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Element/Bookmark.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Element/Chart.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Element/Chart.php index 591799ab5b..f88ca2d252 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Element/Chart.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Element/Chart.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Element/CheckBox.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Element/CheckBox.php index ab888f6757..05692a074d 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Element/CheckBox.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Element/CheckBox.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Element/Container.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Element/Container.php index 47dae29be0..892da051ad 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Element/Container.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Element/Container.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ @@ -46,7 +46,7 @@ class Container extends AbstractElement return; } $containerClass = substr(get_class($container), strrpos(get_class($container), '\\') + 1); - $withoutP = in_array($containerClass, array('TextRun', 'Footnote', 'Endnote', 'ListItemRun')) ? true : false; + $withoutP = in_array($containerClass, array('TextRun', 'Footnote', 'Endnote', 'ListItemRun')); $xmlWriter = $this->getXmlWriter(); // Loop through elements diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Element/Endnote.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Element/Endnote.php index ebfe35c18d..9a2eb3ffab 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Element/Endnote.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Element/Endnote.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Element/Field.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Element/Field.php index 75d4983fef..e79dd24a90 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Element/Field.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Element/Field.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ @@ -29,12 +29,22 @@ class Field extends Text */ public function write() { - $xmlWriter = $this->getXmlWriter(); $element = $this->getElement(); if (!$element instanceof \PhpOffice\PhpWord\Element\Field) { return; } + $methodName = 'write' . ucfirst(strtolower($element->getType())); + if (method_exists($this, $methodName)) { + $this->$methodName($element); + } else { + $this->writeDefault($element); + } + } + + private function writeDefault(\PhpOffice\PhpWord\Element\Field $element) + { + $xmlWriter = $this->getXmlWriter(); $this->startElementP(); $xmlWriter->startElement('w:r'); @@ -104,6 +114,51 @@ class Field extends Text $this->endElementP(); // w:p } + /** + * Writes a macrobutton field + * + * //TODO A lot of code duplication with general method, should maybe be refactored + * @param \PhpOffice\PhpWord\Element\Field $element + */ + protected function writeMacrobutton(\PhpOffice\PhpWord\Element\Field $element) + { + $xmlWriter = $this->getXmlWriter(); + $this->startElementP(); + + $xmlWriter->startElement('w:r'); + $xmlWriter->startElement('w:fldChar'); + $xmlWriter->writeAttribute('w:fldCharType', 'begin'); + $xmlWriter->endElement(); // w:fldChar + $xmlWriter->endElement(); // w:r + + $instruction = ' ' . $element->getType() . ' ' . $this->buildPropertiesAndOptions($element); + if (is_string($element->getText())) { + $instruction .= $element->getText() . ' '; + } + + $xmlWriter->startElement('w:r'); + $xmlWriter->startElement('w:instrText'); + $xmlWriter->writeAttribute('xml:space', 'preserve'); + $xmlWriter->text($instruction); + $xmlWriter->endElement(); // w:instrText + $xmlWriter->endElement(); // w:r + + if ($element->getText() != null) { + if ($element->getText() instanceof \PhpOffice\PhpWord\Element\TextRun) { + $containerWriter = new Container($xmlWriter, $element->getText(), true); + $containerWriter->write(); + } + } + + $xmlWriter->startElement('w:r'); + $xmlWriter->startElement('w:fldChar'); + $xmlWriter->writeAttribute('w:fldCharType', 'end'); + $xmlWriter->endElement(); // w:fldChar + $xmlWriter->endElement(); // w:r + + $this->endElementP(); // w:p + } + private function buildPropertiesAndOptions(\PhpOffice\PhpWord\Element\Field $element) { $propertiesAndOptions = ''; @@ -119,6 +174,12 @@ class Field extends Text case 'dateformat': $propertiesAndOptions .= '\@ "' . $propval . '" '; break; + case 'macroname': + $propertiesAndOptions .= $propval . ' '; + break; + default: + $propertiesAndOptions .= '"' . $propval . '" '; + break; } } diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Element/Footnote.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Element/Footnote.php index 65ef40c7f4..56a5332f07 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Element/Footnote.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Element/Footnote.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Element/FormField.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Element/FormField.php index c77ca37898..b59cf58f89 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Element/FormField.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Element/FormField.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Element/Image.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Element/Image.php index 7e33f75e4f..3614ec184f 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Element/Image.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Element/Image.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ @@ -19,6 +19,9 @@ namespace PhpOffice\PhpWord\Writer\Word2007\Element; use PhpOffice\Common\XMLWriter; use PhpOffice\PhpWord\Element\Image as ImageElement; +use PhpOffice\PhpWord\Style\Font as FontStyle; +use PhpOffice\PhpWord\Style\Frame as FrameStyle; +use PhpOffice\PhpWord\Writer\Word2007\Style\Font as FontStyleWriter; use PhpOffice\PhpWord\Writer\Word2007\Style\Image as ImageStyleWriter; /** @@ -62,6 +65,16 @@ class Image extends AbstractElement $this->writeCommentRangeStart(); $xmlWriter->startElement('w:r'); + + // Write position + $position = $style->getPosition(); + if ($position && $style->getWrap() == FrameStyle::WRAP_INLINE) { + $fontStyle = new FontStyle('text'); + $fontStyle->setPosition($position); + $fontStyleWriter = new FontStyleWriter($xmlWriter, $fontStyle); + $fontStyleWriter->write(); + } + $xmlWriter->startElement('w:pict'); $xmlWriter->startElement('v:shape'); $xmlWriter->writeAttribute('type', '#_x0000_t75'); diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Element/Line.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Element/Line.php index 9b1a160d4e..a114be6006 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Element/Line.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Element/Line.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Element/Link.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Element/Link.php index dc708a618d..f0adf851e3 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Element/Link.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Element/Link.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Element/ListItem.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Element/ListItem.php index c1aa0ce3e5..ef738e10d7 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Element/ListItem.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Element/ListItem.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Element/ListItemRun.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Element/ListItemRun.php index e6ed2b46d2..765d2ee0f9 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Element/ListItemRun.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Element/ListItemRun.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Element/Object.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Element/OLEObject.php similarity index 93% rename from civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Element/Object.php rename to civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Element/OLEObject.php index 8231ec0c43..c55ff6cd8c 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Element/Object.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Element/OLEObject.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ @@ -20,11 +20,11 @@ namespace PhpOffice\PhpWord\Writer\Word2007\Element; use PhpOffice\PhpWord\Writer\Word2007\Style\Image as ImageStyleWriter; /** - * Object element writer + * OLEObject element writer * * @since 0.10.0 */ -class Object extends AbstractElement +class OLEObject extends AbstractElement { /** * Write object element. @@ -33,7 +33,7 @@ class Object extends AbstractElement { $xmlWriter = $this->getXmlWriter(); $element = $this->getElement(); - if (!$element instanceof \PhpOffice\PhpWord\Element\Object) { + if (!$element instanceof \PhpOffice\PhpWord\Element\OLEObject) { return; } diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Element/PageBreak.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Element/PageBreak.php index 04ff29d487..0801e4d3c4 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Element/PageBreak.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Element/PageBreak.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Element/ParagraphAlignment.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Element/ParagraphAlignment.php index 0dafa4a057..5563f6075d 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Element/ParagraphAlignment.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Element/ParagraphAlignment.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Element/PreserveText.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Element/PreserveText.php index 138878663c..94ce6eded7 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Element/PreserveText.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Element/PreserveText.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Element/SDT.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Element/SDT.php index 6a2025649b..21020a0f9e 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Element/SDT.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Element/SDT.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Element/Shape.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Element/Shape.php index e384db0665..250d5c1d0d 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Element/Shape.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Element/Shape.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ @@ -154,12 +154,12 @@ class Shape extends AbstractElement case 'arc': case 'line': $points = explode(' ', $value); - @list($start, $end) = $points; + list($start, $end) = array_pad($points, 2, null); $points = array('start' => $start, 'end' => $end); break; case 'curve': $points = explode(' ', $value); - @list($start, $end, $point1, $point2) = $points; + list($start, $end, $point1, $point2) = array_pad($points, 4, null); $points = array('start' => $start, 'end' => $end, 'point1' => $point1, 'point2' => $point2); break; } diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Element/TOC.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Element/TOC.php index 36ed7f88bc..94437cbf0d 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Element/TOC.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Element/TOC.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Element/Table.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Element/Table.php index c0590772bf..c365b028ab 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Element/Table.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Element/Table.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ @@ -76,21 +76,7 @@ class Table extends AbstractElement */ private function writeColumns(XMLWriter $xmlWriter, TableElement $element) { - $rows = $element->getRows(); - $rowCount = count($rows); - - $cellWidths = array(); - for ($i = 0; $i < $rowCount; $i++) { - $row = $rows[$i]; - $cells = $row->getCells(); - if (count($cells) <= count($cellWidths)) { - continue; - } - $cellWidths = array(); - foreach ($cells as $cell) { - $cellWidths[] = $cell->getWidth(); - } - } + $cellWidths = $element->findFirstDefinedCellWidths(); $xmlWriter->startElement('w:tblGrid'); foreach ($cellWidths as $width) { diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Element/TableAlignment.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Element/TableAlignment.php index 44450fd63b..f44e9ebe42 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Element/TableAlignment.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Element/TableAlignment.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Element/Text.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Element/Text.php index e714943222..f421c1afe8 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Element/Text.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Element/Text.php @@ -11,12 +11,14 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ namespace PhpOffice\PhpWord\Writer\Word2007\Element; +use PhpOffice\PhpWord\Element\TrackChange; + /** * Text element writer * @@ -37,16 +39,66 @@ class Text extends AbstractElement $this->startElementP(); + $this->writeOpeningTrackChange(); + $xmlWriter->startElement('w:r'); $this->writeFontStyle(); - $xmlWriter->startElement('w:t'); + $textElement = 'w:t'; + //'w:delText' in case of deleted text + $changed = $element->getTrackChange(); + if ($changed != null && $changed->getChangeType() == TrackChange::DELETED) { + $textElement = 'w:delText'; + } + $xmlWriter->startElement($textElement); + $xmlWriter->writeAttribute('xml:space', 'preserve'); $this->writeText($this->getText($element->getText())); $xmlWriter->endElement(); $xmlWriter->endElement(); // w:r + $this->writeClosingTrackChange(); + $this->endElementP(); // w:p } + + /** + * Write opening of changed element + */ + protected function writeOpeningTrackChange() + { + $changed = $this->getElement()->getTrackChange(); + if ($changed == null) { + return; + } + + $xmlWriter = $this->getXmlWriter(); + + if (($changed->getChangeType() == TrackChange::INSERTED)) { + $xmlWriter->startElement('w:ins'); + } elseif ($changed->getChangeType() == TrackChange::DELETED) { + $xmlWriter->startElement('w:del'); + } + $xmlWriter->writeAttribute('w:author', $changed->getAuthor()); + if ($changed->getDate() != null) { + $xmlWriter->writeAttribute('w:date', $changed->getDate()->format('Y-m-d\TH:i:s\Z')); + } + $xmlWriter->writeAttribute('w:id', $this->getElement()->getElementId()); + } + + /** + * Write ending + */ + protected function writeClosingTrackChange() + { + $changed = $this->getElement()->getTrackChange(); + if ($changed == null) { + return; + } + + $xmlWriter = $this->getXmlWriter(); + + $xmlWriter->endElement(); // w:ins|w:del + } } diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Element/TextBox.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Element/TextBox.php index 3780c698f0..9dd4bc3e57 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Element/TextBox.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Element/TextBox.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Element/TextBreak.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Element/TextBreak.php index 161a528e01..7b3d999706 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Element/TextBreak.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Element/TextBreak.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Element/TextRun.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Element/TextRun.php index 9fd70b135f..e46ad3f527 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Element/TextRun.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Element/TextRun.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Element/Title.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Element/Title.php index f204ab1617..6a05a34d6f 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Element/Title.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Element/Title.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ @@ -47,27 +47,37 @@ class Title extends AbstractElement $xmlWriter->endElement(); } - $rId = $element->getRelationId(); - $bookmarkRId = $element->getPhpWord()->addBookmark(); + $bookmarkRId = null; + if ($element->getDepth() !== 0) { + $rId = $element->getRelationId(); + $bookmarkRId = $element->getPhpWord()->addBookmark(); - // Bookmark start for TOC - $xmlWriter->startElement('w:bookmarkStart'); - $xmlWriter->writeAttribute('w:id', $bookmarkRId); - $xmlWriter->writeAttribute('w:name', "_Toc{$rId}"); - $xmlWriter->endElement(); + // Bookmark start for TOC + $xmlWriter->startElement('w:bookmarkStart'); + $xmlWriter->writeAttribute('w:id', $bookmarkRId); + $xmlWriter->writeAttribute('w:name', "_Toc{$rId}"); + $xmlWriter->endElement(); //w:bookmarkStart + } // Actual text - $xmlWriter->startElement('w:r'); - $xmlWriter->startElement('w:t'); - $this->writeText($this->getText($element->getText())); - $xmlWriter->endElement(); // w:t - $xmlWriter->endElement(); // w:r - - // Bookmark end - $xmlWriter->startElement('w:bookmarkEnd'); - $xmlWriter->writeAttribute('w:id', $bookmarkRId); - $xmlWriter->endElement(); + $text = $element->getText(); + if (is_string($text)) { + $xmlWriter->startElement('w:r'); + $xmlWriter->startElement('w:t'); + $this->writeText($text); + $xmlWriter->endElement(); // w:t + $xmlWriter->endElement(); // w:r + } elseif ($text instanceof \PhpOffice\PhpWord\Element\AbstractContainer) { + $containerWriter = new Container($xmlWriter, $text); + $containerWriter->write(); + } - $xmlWriter->endElement(); + if ($element->getDepth() !== 0) { + // Bookmark end + $xmlWriter->startElement('w:bookmarkEnd'); + $xmlWriter->writeAttribute('w:id', $bookmarkRId); + $xmlWriter->endElement(); //w:bookmarkEnd + } + $xmlWriter->endElement(); //w:p } } diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Part/AbstractPart.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Part/AbstractPart.php index 038eb21dc8..ce4e41cbd4 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Part/AbstractPart.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Part/AbstractPart.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Part/Chart.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Part/Chart.php index c3703f9f6d..5a3ef27678 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Part/Chart.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Part/Chart.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ @@ -41,14 +41,18 @@ class Chart extends AbstractPart * @var array */ private $types = array( - 'pie' => array('type' => 'pie', 'colors' => 1), - 'doughnut' => array('type' => 'doughnut', 'colors' => 1, 'hole' => 75, 'no3d' => true), - 'bar' => array('type' => 'bar', 'colors' => 0, 'axes' => true, 'bar' => 'bar'), - 'column' => array('type' => 'bar', 'colors' => 0, 'axes' => true, 'bar' => 'col'), - 'line' => array('type' => 'line', 'colors' => 0, 'axes' => true), - 'area' => array('type' => 'area', 'colors' => 0, 'axes' => true), - 'radar' => array('type' => 'radar', 'colors' => 0, 'axes' => true, 'radar' => 'standard', 'no3d' => true), - 'scatter' => array('type' => 'scatter', 'colors' => 0, 'axes' => true, 'scatter' => 'marker', 'no3d' => true), + 'pie' => array('type' => 'pie', 'colors' => 1), + 'doughnut' => array('type' => 'doughnut', 'colors' => 1, 'hole' => 75, 'no3d' => true), + 'bar' => array('type' => 'bar', 'colors' => 0, 'axes' => true, 'bar' => 'bar', 'grouping' => 'clustered'), + 'stacked_bar' => array('type' => 'bar', 'colors' => 0, 'axes' => true, 'bar' => 'bar', 'grouping' => 'stacked'), + 'percent_stacked_bar' => array('type' => 'bar', 'colors' => 0, 'axes' => true, 'bar' => 'bar', 'grouping' => 'percentStacked'), + 'column' => array('type' => 'bar', 'colors' => 0, 'axes' => true, 'bar' => 'col', 'grouping' => 'clustered'), + 'stacked_column' => array('type' => 'bar', 'colors' => 0, 'axes' => true, 'bar' => 'col', 'grouping' => 'stacked'), + 'percent_stacked_column' => array('type' => 'bar', 'colors' => 0, 'axes' => true, 'bar' => 'col', 'grouping' => 'percentStacked'), + 'line' => array('type' => 'line', 'colors' => 0, 'axes' => true), + 'area' => array('type' => 'area', 'colors' => 0, 'axes' => true), + 'radar' => array('type' => 'radar', 'colors' => 0, 'axes' => true, 'radar' => 'standard', 'no3d' => true), + 'scatter' => array('type' => 'scatter', 'colors' => 0, 'axes' => true, 'scatter' => 'marker', 'no3d' => true), ); /** @@ -145,7 +149,7 @@ class Chart extends AbstractPart } if (isset($this->options['bar'])) { $xmlWriter->writeElementBlock('c:barDir', 'val', $this->options['bar']); // bar|col - $xmlWriter->writeElementBlock('c:grouping', 'val', 'clustered'); // 3d; standard = percentStacked + $xmlWriter->writeElementBlock('c:grouping', 'val', $this->options['grouping']); // 3d; standard = percentStacked } if (isset($this->options['radar'])) { $xmlWriter->writeElementBlock('c:radarStyle', 'val', $this->options['radar']); @@ -157,6 +161,8 @@ class Chart extends AbstractPart // Series $this->writeSeries($xmlWriter, isset($this->options['scatter'])); + $xmlWriter->writeElementBlock('c:overlap', 'val', '100'); + // Axes if (isset($this->options['axes'])) { $xmlWriter->writeElementBlock('c:axId', 'val', 1); @@ -183,6 +189,8 @@ class Chart extends AbstractPart private function writeSeries(XMLWriter $xmlWriter, $scatter = false) { $series = $this->element->getSeries(); + $style = $this->element->getStyle(); + $colors = $style->getColors(); $index = 0; foreach ($series as $seriesItem) { @@ -194,6 +202,32 @@ class Chart extends AbstractPart $xmlWriter->writeElementBlock('c:idx', 'val', $index); $xmlWriter->writeElementBlock('c:order', 'val', $index); + if (!is_null($seriesItem['name']) && $seriesItem['name'] != '') { + $xmlWriter->startElement('c:tx'); + $xmlWriter->startElement('c:strRef'); + $xmlWriter->startElement('c:strCache'); + $xmlWriter->writeElementBlock('c:ptCount', 'val', 1); + $xmlWriter->startElement('c:pt'); + $xmlWriter->writeAttribute('idx', 0); + $xmlWriter->startElement('c:v'); + $xmlWriter->writeRaw($seriesItem['name']); + $xmlWriter->endElement(); // c:v + $xmlWriter->endElement(); // c:pt + $xmlWriter->endElement(); // c:strCache + $xmlWriter->endElement(); // c:strRef + $xmlWriter->endElement(); // c:tx + } + + // The c:dLbls was added to make word charts look more like the reports in SurveyGizmo + // This section needs to be made configurable before a pull request is made + $xmlWriter->startElement('c:dLbls'); + + foreach ($style->getDataLabelOptions() as $option => $val) { + $xmlWriter->writeElementBlock("c:{$option}", 'val', (int) $val); + } + + $xmlWriter->endElement(); // c:dLbls + if (isset($this->options['scatter'])) { $this->writeShape($xmlWriter); } @@ -204,6 +238,26 @@ class Chart extends AbstractPart } else { $this->writeSeriesItem($xmlWriter, 'cat', $categories); $this->writeSeriesItem($xmlWriter, 'val', $values); + + // setting the chart colors was taken from https://github.com/PHPOffice/PHPWord/issues/494 + if (is_array($colors) && count($colors)) { + // This is a workaround to make each series in a stack chart use a different color + if ($this->options['type'] == 'bar' && stristr($this->options['grouping'], 'stacked')) { + array_shift($colors); + } + $colorIndex = 0; + foreach ($colors as $color) { + $xmlWriter->startElement('c:dPt'); + $xmlWriter->writeElementBlock('c:idx', 'val', $colorIndex); + $xmlWriter->startElement('c:spPr'); + $xmlWriter->startElement('a:solidFill'); + $xmlWriter->writeElementBlock('a:srgbClr', 'val', $color); + $xmlWriter->endElement(); // a:solidFill + $xmlWriter->endElement(); // c:spPr + $xmlWriter->endElement(); // c:dPt + $colorIndex++; + } + } } $xmlWriter->endElement(); // c:ser @@ -230,14 +284,19 @@ class Chart extends AbstractPart $xmlWriter->startElement($itemType); $xmlWriter->startElement($itemLit); + $xmlWriter->writeElementBlock('c:ptCount', 'val', count($values)); $index = 0; foreach ($values as $value) { $xmlWriter->startElement('c:pt'); $xmlWriter->writeAttribute('idx', $index); - $xmlWriter->startElement('c:v'); - $this->writeText($value); - $xmlWriter->endElement(); // c:v + if (\PhpOffice\PhpWord\Settings::isOutputEscapingEnabled()) { + $xmlWriter->writeElement('c:v', $value); + } else { + $xmlWriter->startElement('c:v'); + $xmlWriter->writeRaw($value); + $xmlWriter->endElement(); // c:v + } $xmlWriter->endElement(); // c:pt $index++; } @@ -255,6 +314,7 @@ class Chart extends AbstractPart */ private function writeAxis(XMLWriter $xmlWriter, $type) { + $style = $this->element->getStyle(); $types = array( 'cat' => array('c:catAx', 1, 'b', 2), 'val' => array('c:valAx', 2, 'l', 1), @@ -265,17 +325,39 @@ class Chart extends AbstractPart $xmlWriter->writeElementBlock('c:axId', 'val', $axisId); $xmlWriter->writeElementBlock('c:axPos', 'val', $axisPos); + + $categoryAxisTitle = $style->getCategoryAxisTitle(); + $valueAxisTitle = $style->getValueAxisTitle(); + + if ($axisType == 'c:catAx') { + if (!is_null($categoryAxisTitle)) { + $this->writeAxisTitle($xmlWriter, $categoryAxisTitle); + } + } elseif ($axisType == 'c:valAx') { + if (!is_null($valueAxisTitle)) { + $this->writeAxisTitle($xmlWriter, $valueAxisTitle); + } + } + $xmlWriter->writeElementBlock('c:crossAx', 'val', $axisCross); $xmlWriter->writeElementBlock('c:auto', 'val', 1); if (isset($this->options['axes'])) { $xmlWriter->writeElementBlock('c:delete', 'val', 0); - $xmlWriter->writeElementBlock('c:majorTickMark', 'val', 'none'); + $xmlWriter->writeElementBlock('c:majorTickMark', 'val', $style->getMajorTickPosition()); $xmlWriter->writeElementBlock('c:minorTickMark', 'val', 'none'); - $xmlWriter->writeElementBlock('c:tickLblPos', 'val', 'none'); // nextTo + if ($style->showAxisLabels()) { + if ($axisType == 'c:catAx') { + $xmlWriter->writeElementBlock('c:tickLblPos', 'val', $style->getCategoryLabelPosition()); + } else { + $xmlWriter->writeElementBlock('c:tickLblPos', 'val', $style->getValueLabelPosition()); + } + } else { + $xmlWriter->writeElementBlock('c:tickLblPos', 'val', 'none'); + } $xmlWriter->writeElementBlock('c:crosses', 'val', 'autoZero'); } - if (isset($this->options['radar'])) { + if (isset($this->options['radar']) || ($type == 'cat' && $style->showGridX()) || ($type == 'val' && $style->showGridY())) { $xmlWriter->writeElement('c:majorGridlines'); } @@ -307,4 +389,30 @@ class Chart extends AbstractPart $xmlWriter->endElement(); // a:ln $xmlWriter->endElement(); // c:spPr } + + private function writeAxisTitle(XMLWriter $xmlWriter, $title) + { + $xmlWriter->startElement('c:title'); //start c:title + $xmlWriter->startElement('c:tx'); //start c:tx + $xmlWriter->startElement('c:rich'); // start c:rich + $xmlWriter->writeElement('a:bodyPr'); + $xmlWriter->writeElement('a:lstStyle'); + $xmlWriter->startElement('a:p'); + $xmlWriter->startElement('a:pPr'); + $xmlWriter->writeElement('a:defRPr'); + $xmlWriter->endElement(); // end a:pPr + $xmlWriter->startElement('a:r'); + $xmlWriter->writeElementBlock('a:rPr', 'lang', 'en-US'); + + $xmlWriter->startElement('a:t'); + $xmlWriter->writeRaw($title); + $xmlWriter->endElement(); //end a:t + + $xmlWriter->endElement(); // end a:r + $xmlWriter->endElement(); //end a:p + $xmlWriter->endElement(); //end c:rich + $xmlWriter->endElement(); // end c:tx + $xmlWriter->writeElementBlock('c:overlay', 'val', '0'); + $xmlWriter->endElement(); // end c:title + } } diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Part/Comments.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Part/Comments.php index 2b8f9267a2..33c9f59e6a 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Part/Comments.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Part/Comments.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Part/ContentTypes.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Part/ContentTypes.php index 9be988d345..28a2d29449 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Part/ContentTypes.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Part/ContentTypes.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Part/DocPropsApp.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Part/DocPropsApp.php index dbd551873f..3452d86496 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Part/DocPropsApp.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Part/DocPropsApp.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Part/DocPropsCore.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Part/DocPropsCore.php index fdabee36d0..caefbd8625 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Part/DocPropsCore.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Part/DocPropsCore.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Part/DocPropsCustom.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Part/DocPropsCustom.php index 8ee2f0284e..478075d30e 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Part/DocPropsCustom.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Part/DocPropsCustom.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Part/Document.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Part/Document.php index 72e4fcd8d1..986b498570 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Part/Document.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Part/Document.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Part/Endnotes.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Part/Endnotes.php index 289119db74..ce3a46bfb7 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Part/Endnotes.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Part/Endnotes.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Part/FontTable.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Part/FontTable.php index 065a318ec0..1161a951e6 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Part/FontTable.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Part/FontTable.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Part/Footer.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Part/Footer.php index cfc9dd40fa..97b4779042 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Part/Footer.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Part/Footer.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Part/Footnotes.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Part/Footnotes.php index c9e3bcac20..59bf183096 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Part/Footnotes.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Part/Footnotes.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Part/Header.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Part/Header.php index 5853d92fe3..b58df1f9df 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Part/Header.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Part/Header.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Part/Numbering.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Part/Numbering.php index 6233a6b7b1..61e5cc2341 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Part/Numbering.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Part/Numbering.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Part/Rels.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Part/Rels.php index 154c7e8943..661a4fa862 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Part/Rels.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Part/Rels.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Part/RelsDocument.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Part/RelsDocument.php index 505aa22382..2a0c5e1117 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Part/RelsDocument.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Part/RelsDocument.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Part/RelsPart.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Part/RelsPart.php index e639c041cb..ac61a0c2c7 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Part/RelsPart.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Part/RelsPart.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Part/Settings.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Part/Settings.php index e56e2612bd..b764642a6a 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Part/Settings.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Part/Settings.php @@ -11,15 +11,15 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ namespace PhpOffice\PhpWord\Writer\Word2007\Part; +use PhpOffice\Common\Microsoft\PasswordEncoder; use PhpOffice\PhpWord\ComplexType\ProofState; use PhpOffice\PhpWord\ComplexType\TrackChangesView; -use PhpOffice\PhpWord\Shared\Microsoft\PasswordEncoder; use PhpOffice\PhpWord\Style\Language; /** @@ -149,12 +149,16 @@ class Settings extends AbstractPart $this->setOnOffValue('w:doNotTrackFormatting', $documentSettings->hasDoNotTrackFormatting()); $this->setOnOffValue('w:evenAndOddHeaders', $documentSettings->hasEvenAndOddHeaders()); $this->setOnOffValue('w:updateFields', $documentSettings->hasUpdateFields()); + $this->setOnOffValue('w:autoHyphenation', $documentSettings->hasAutoHyphenation()); + $this->setOnOffValue('w:doNotHyphenateCaps', $documentSettings->hasDoNotHyphenateCaps()); $this->setThemeFontLang($documentSettings->getThemeFontLang()); $this->setRevisionView($documentSettings->getRevisionView()); $this->setDocumentProtection($documentSettings->getDocumentProtection()); $this->setProofState($documentSettings->getProofState()); $this->setZoom($documentSettings->getZoom()); + $this->setConsecutiveHyphenLimit($documentSettings->getConsecutiveHyphenLimit()); + $this->setHyphenationZone($documentSettings->getHyphenationZone()); $this->setCompatibility(); } @@ -162,17 +166,16 @@ class Settings extends AbstractPart * Adds a boolean attribute to the settings array * * @param string $settingName - * @param bool $booleanValue + * @param bool|null $booleanValue */ private function setOnOffValue($settingName, $booleanValue) { - if ($booleanValue !== null && is_bool($booleanValue)) { - if ($booleanValue) { - $this->settings[$settingName] = array('@attributes' => array()); - } else { - $this->settings[$settingName] = array('@attributes' => array('w:val' => 'false')); - } + if (!is_bool($booleanValue)) { + return; } + + $value = $booleanValue ? 'true' : 'false'; + $this->settings[$settingName] = array('@attributes' => array('w:val' => $value)); } /** @@ -278,6 +281,34 @@ class Settings extends AbstractPart } } + /** + * @param int|null $consecutiveHyphenLimit + */ + private function setConsecutiveHyphenLimit($consecutiveHyphenLimit) + { + if ($consecutiveHyphenLimit === null) { + return; + } + + $this->settings['w:consecutiveHyphenLimit'] = array( + '@attributes' => array('w:val' => $consecutiveHyphenLimit), + ); + } + + /** + * @param float|null $hyphenationZone + */ + private function setHyphenationZone($hyphenationZone) + { + if ($hyphenationZone === null) { + return; + } + + $this->settings['w:hyphenationZone'] = array( + '@attributes' => array('w:val' => $hyphenationZone), + ); + } + /** * Get compatibility setting. */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Part/Styles.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Part/Styles.php index 126cda4fd1..d05338c77d 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Part/Styles.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Part/Styles.php @@ -11,14 +11,13 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ namespace PhpOffice\PhpWord\Writer\Word2007\Part; use PhpOffice\Common\XMLWriter; -use PhpOffice\PhpWord\Settings as PhpWordSettings; use PhpOffice\PhpWord\Style; use PhpOffice\PhpWord\Style\Font as FontStyle; use PhpOffice\PhpWord\Style\Paragraph as ParagraphStyle; @@ -82,9 +81,10 @@ class Styles extends AbstractPart */ private function writeDefaultStyles(XMLWriter $xmlWriter, $styles) { - $fontName = PhpWordSettings::getDefaultFontName(); - $fontSize = PhpWordSettings::getDefaultFontSize(); - $language = $this->getParentWriter()->getPhpWord()->getSettings()->getThemeFontLang(); + $phpWord = $this->getParentWriter()->getPhpWord(); + $fontName = $phpWord->getDefaultFontName(); + $fontSize = $phpWord->getDefaultFontSize(); + $language = $phpWord->getSettings()->getThemeFontLang(); $latinLanguage = ($language == null || $language->getLatin() === null) ? 'en-US' : $language->getLatin(); // Default font @@ -123,7 +123,18 @@ class Styles extends AbstractPart $xmlWriter->writeAttribute('w:val', 'Normal'); $xmlWriter->endElement(); // w:name if (isset($styles['Normal'])) { - $styleWriter = new ParagraphStyleWriter($xmlWriter, $styles['Normal']); + $normalStyle = $styles['Normal']; + // w:pPr + if ($normalStyle instanceof Fontstyle && $normalStyle->getParagraph() != null) { + $styleWriter = new ParagraphStyleWriter($xmlWriter, $normalStyle->getParagraph()); + $styleWriter->write(); + } elseif ($normalStyle instanceof ParagraphStyle) { + $styleWriter = new ParagraphStyleWriter($xmlWriter, $normalStyle); + $styleWriter->write(); + } + + // w:rPr + $styleWriter = new FontStyleWriter($xmlWriter, $normalStyle); $styleWriter->write(); } $xmlWriter->endElement(); // w:style @@ -169,9 +180,15 @@ class Styles extends AbstractPart // Heading style if ($styleType == 'title') { $arrStyle = explode('_', $styleName); - $styleId = 'Heading' . $arrStyle[1]; - $styleName = 'heading ' . $arrStyle[1]; - $styleLink = 'Heading' . $arrStyle[1] . 'Char'; + if (count($arrStyle) > 1) { + $styleId = 'Heading' . $arrStyle[1]; + $styleName = 'heading ' . $arrStyle[1]; + $styleLink = 'Heading' . $arrStyle[1] . 'Char'; + } else { + $styleId = $styleName; + $styleName = strtolower($styleName); + $styleLink = $styleName . 'Char'; + } $xmlWriter->writeAttribute('w:styleId', $styleId); $xmlWriter->startElement('w:link'); diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Part/Theme.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Part/Theme.php index c264140e94..f4ef478ebf 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Part/Theme.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Part/Theme.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Part/WebSettings.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Part/WebSettings.php index 9f18e3566c..46252e8701 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Part/WebSettings.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Part/WebSettings.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Style/AbstractStyle.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Style/AbstractStyle.php index d775693351..3236cead0b 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Style/AbstractStyle.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Style/AbstractStyle.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Style/Cell.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Style/Cell.php index b889aa551e..733b7b434e 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Style/Cell.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Style/Cell.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Style/Extrusion.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Style/Extrusion.php index e3a86a587c..193993485d 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Style/Extrusion.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Style/Extrusion.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Style/Fill.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Style/Fill.php index de64313bbf..53d039742b 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Style/Fill.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Style/Fill.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Style/Font.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Style/Font.php index 9c2714dc71..58282d1558 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Style/Font.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Style/Font.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ @@ -90,6 +90,10 @@ class Font extends AbstractStyle $xmlWriter->writeAttributeIf($language->getLatin() !== null, 'w:val', $language->getLatin()); $xmlWriter->writeAttributeIf($language->getEastAsia() !== null, 'w:eastAsia', $language->getEastAsia()); $xmlWriter->writeAttributeIf($language->getBidirectional() !== null, 'w:bidi', $language->getBidirectional()); + //if bidi is not set but we are writing RTL, write the latin language in the bidi tag + if ($style->isRTL() && $language->getBidirectional() === null && $language->getLatin() !== null) { + $xmlWriter->writeAttribute('w:bidi', $language->getLatin()); + } $xmlWriter->endElement(); } @@ -131,6 +135,9 @@ class Font extends AbstractStyle $xmlWriter->writeElementIf($style->getSpacing() !== null, 'w:spacing', 'w:val', $style->getSpacing()); $xmlWriter->writeElementIf($style->getKerning() !== null, 'w:kern', 'w:val', $style->getKerning() * 2); + // noProof + $xmlWriter->writeElementIf($style->isNoProof() !== false, 'w:noProof'); + // Background-Color $shading = $style->getShading(); if (!is_null($shading)) { @@ -144,6 +151,9 @@ class Font extends AbstractStyle $xmlWriter->writeElementIf($styleName === null && $style->isRTL(), 'w:rtl'); } + // Position + $xmlWriter->writeElementIf($style->getPosition() !== null, 'w:position', 'w:val', $style->getPosition()); + $xmlWriter->endElement(); } diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Style/Frame.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Style/Frame.php index 9bd5db6622..ea5abf780a 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Style/Frame.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Style/Frame.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ @@ -45,10 +45,14 @@ class Frame extends AbstractStyle $zIndices = array(FrameStyle::WRAP_INFRONT => $maxZIndex, FrameStyle::WRAP_BEHIND => -$maxZIndex); $properties = array( - 'width' => 'width', - 'height' => 'height', - 'left' => 'margin-left', - 'top' => 'margin-top', + 'width' => 'width', + 'height' => 'height', + 'left' => 'margin-left', + 'top' => 'margin-top', + 'wrapDistanceTop' => 'mso-wrap-distance-top', + 'wrapDistanceBottom' => 'mso-wrap-distance-bottom', + 'wrapDistanceLeft' => 'mso-wrap-distance-left', + 'wrapDistanceRight' => 'mso-wrap-distance-right', ); $sizeStyles = $this->getStyles($style, $properties, $style->getUnit()); @@ -57,7 +61,6 @@ class Frame extends AbstractStyle 'hPos' => 'mso-position-horizontal', 'vPos' => 'mso-position-vertical', 'hPosRelTo' => 'mso-position-horizontal-relative', - 'vPosRelTo' => 'mso-position-vertical-relative', ); $posStyles = $this->getStyles($style, $properties); diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Style/Image.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Style/Image.php index 271b99dfec..ef23ed103c 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Style/Image.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Style/Image.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Style/Indentation.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Style/Indentation.php index c5a598ffb5..961e770fbd 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Style/Indentation.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Style/Indentation.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Style/Line.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Style/Line.php index f065e52115..154a42c13d 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Style/Line.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Style/Line.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Style/LineNumbering.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Style/LineNumbering.php index 3ed577c62a..4bf08b65ab 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Style/LineNumbering.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Style/LineNumbering.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Style/MarginBorder.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Style/MarginBorder.php index 5c3ecde2e2..f5c4b0153b 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Style/MarginBorder.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Style/MarginBorder.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Style/Outline.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Style/Outline.php index 9ae61f396a..ae4c1da386 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Style/Outline.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Style/Outline.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Style/Paragraph.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Style/Paragraph.php index 424b87f8c8..6761608608 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Style/Paragraph.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Style/Paragraph.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ @@ -109,9 +109,12 @@ class Paragraph extends AbstractStyle //Paragraph contextualSpacing $xmlWriter->writeElementIf($styles['contextualSpacing'] === true, 'w:contextualSpacing'); - //Paragraph contextualSpacing + //Paragraph textAlignment $xmlWriter->writeElementIf($styles['textAlignment'] !== null, 'w:textAlignment', 'w:val', $styles['textAlignment']); + // Hyphenation + $xmlWriter->writeElementIf($styles['suppressAutoHyphens'] === true, 'w:suppressAutoHyphens'); + // Child style: alignment, indentation, spacing, and shading $this->writeChildStyle($xmlWriter, 'Indentation', $styles['indentation']); $this->writeChildStyle($xmlWriter, 'Spacing', $styles['spacing']); diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Style/Row.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Style/Row.php index f57094db6c..82028d24c4 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Style/Row.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Style/Row.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Style/Section.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Style/Section.php index ef50c111e5..af77396de1 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Style/Section.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Style/Section.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Style/Shading.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Style/Shading.php index 0068068791..0f9d6ccc08 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Style/Shading.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Style/Shading.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Style/Shadow.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Style/Shadow.php index 5efc38c437..7fcb12a960 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Style/Shadow.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Style/Shadow.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Style/Shape.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Style/Shape.php index aad42ae754..2def6842a9 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Style/Shape.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Style/Shape.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Style/Spacing.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Style/Spacing.php index c18339bdbb..0185cbcc7a 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Style/Spacing.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Style/Spacing.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Style/Tab.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Style/Tab.php index 7b0a0ab55d..b41653f6c4 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Style/Tab.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Style/Tab.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Style/Table.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Style/Table.php index 620e4fbf62..7f49be7c38 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Style/Table.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Style/Table.php @@ -11,13 +11,14 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ namespace PhpOffice\PhpWord\Writer\Word2007\Style; use PhpOffice\Common\XMLWriter; +use PhpOffice\PhpWord\SimpleType\TblWidth; use PhpOffice\PhpWord\Style\Table as TableStyle; use PhpOffice\PhpWord\Writer\Word2007\Element\TableAlignment; @@ -49,7 +50,7 @@ class Table extends AbstractStyle $xmlWriter->writeAttribute('w:val', $style); $xmlWriter->endElement(); if (null !== $this->width) { - $this->writeWidth($xmlWriter, $this->width, 'pct'); + $this->writeTblWidth($xmlWriter, 'w:tblW', TblWidth::PERCENT, $this->width); } $xmlWriter->endElement(); } @@ -76,7 +77,15 @@ class Table extends AbstractStyle $xmlWriter->endElement(); } - $this->writeWidth($xmlWriter, $style->getWidth(), $style->getUnit()); + $this->writeTblWidth($xmlWriter, 'w:tblW', $style->getUnit(), $style->getWidth()); + $this->writeTblWidth($xmlWriter, 'w:tblCellSpacing', TblWidth::TWIP, $style->getCellSpacing()); + $this->writeIndent($xmlWriter, $style); + $this->writeLayout($xmlWriter, $style->getLayout()); + + // Position + $styleWriter = new TablePosition($xmlWriter, $style->getPosition()); + $styleWriter->write(); + $this->writeMargin($xmlWriter, $style); $this->writeBorder($xmlWriter, $style); @@ -92,18 +101,16 @@ class Table extends AbstractStyle } /** - * Write width. + * Enable/Disable automatic resizing of the table * * @param \PhpOffice\Common\XMLWriter $xmlWriter - * @param int $width - * @param string $unit + * @param string $layout autofit / fixed */ - private function writeWidth(XMLWriter $xmlWriter, $width, $unit) + private function writeLayout(XMLWriter $xmlWriter, $layout) { - $xmlWriter->startElement('w:tblW'); - $xmlWriter->writeAttribute('w:w', $width); - $xmlWriter->writeAttribute('w:type', $unit); - $xmlWriter->endElement(); // w:tblW + $xmlWriter->startElement('w:tblLayout'); + $xmlWriter->writeAttribute('w:type', $layout); + $xmlWriter->endElement(); // w:tblLayout } /** @@ -145,6 +152,25 @@ class Table extends AbstractStyle } } + /** + * Writes a table width + * + * @param \PhpOffice\Common\XMLWriter $xmlWriter + * @param string $elementName + * @param string $unit + * @param int|float $width + */ + private function writeTblWidth(XMLWriter $xmlWriter, $elementName, $unit, $width = null) + { + if (null === $width) { + return; + } + $xmlWriter->startElement($elementName); + $xmlWriter->writeAttributeIf(null !== $width, 'w:w', $width); + $xmlWriter->writeAttribute('w:type', $unit); + $xmlWriter->endElement(); + } + /** * Write row style. * @@ -191,4 +217,19 @@ class Table extends AbstractStyle { $this->width = $value; } + + /** + * @param XMLWriter $xmlWriter + * @param TableStyle $style + */ + private function writeIndent(XMLWriter $xmlWriter, TableStyle $style) + { + $indent = $style->getIndent(); + + if ($indent === null) { + return; + } + + $this->writeTblWidth($xmlWriter, 'w:tblInd', $indent->getType(), $indent->getValue()); + } } diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Style/TablePosition.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Style/TablePosition.php new file mode 100644 index 0000000000..fa57b93c2f --- /dev/null +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Style/TablePosition.php @@ -0,0 +1,65 @@ +<?php +/** + * This file is part of PHPWord - A pure PHP library for reading and writing + * word processing documents. + * + * PHPWord is free software distributed under the terms of the GNU Lesser + * General Public License version 3 as published by the Free Software Foundation. + * + * For the full copyright and license information, please read the LICENSE + * file that was distributed with this source code. For the full list of + * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. + * + * @see https://github.com/PHPOffice/PHPWord + * @copyright 2010-2018 PHPWord contributors + * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 + */ + +namespace PhpOffice\PhpWord\Writer\Word2007\Style; + +/** + * TablePosition style writer + */ +class TablePosition extends AbstractStyle +{ + /** + * Write style. + */ + public function write() + { + $style = $this->getStyle(); + if (!$style instanceof \PhpOffice\PhpWord\Style\TablePosition) { + return; + } + + $values = array(); + $properties = array( + 'leftFromText', + 'rightFromText', + 'topFromText', + 'bottomFromText', + 'vertAnchor', + 'horzAnchor', + 'tblpXSpec', + 'tblpX', + 'tblpYSpec', + 'tblpY', + ); + foreach ($properties as $property) { + $method = 'get' . $property; + if (method_exists($style, $method)) { + $values[$property] = $style->$method(); + } + } + $values = array_filter($values); + + if ($values) { + $xmlWriter = $this->getXmlWriter(); + $xmlWriter->startElement('w:tblpPr'); + foreach ($values as $property => $value) { + $xmlWriter->writeAttribute('w:' . $property, $value); + } + $xmlWriter->endElement(); + } + } +} diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Style/TextBox.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Style/TextBox.php index cd92f84550..627d0c86e5 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Style/TextBox.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007/Style/TextBox.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/WriterInterface.php b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/WriterInterface.php index b5f08199d2..499cde3bb1 100644 --- a/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/WriterInterface.php +++ b/civicrm/vendor/phpoffice/phpword/src/PhpWord/Writer/WriterInterface.php @@ -11,7 +11,7 @@ * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * * @see https://github.com/PHPOffice/PHPWord - * @copyright 2010-2017 PHPWord contributors + * @copyright 2010-2018 PHPWord contributors * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ diff --git a/civicrm/xml/schema/Contribute/Contribution.xml b/civicrm/xml/schema/Contribute/Contribution.xml index 5ea0ccc0fd..63b8d13023 100644 --- a/civicrm/xml/schema/Contribute/Contribution.xml +++ b/civicrm/xml/schema/Contribute/Contribution.xml @@ -31,8 +31,8 @@ <dataPattern>/^\d+$/</dataPattern> <comment>FK to Contact ID</comment> <html> - <type>EntityRef</type> - </html> + <type>EntityRef</type> + </html> <add>1.3</add> </field> <foreignKey> diff --git a/civicrm/xml/schema/Contribute/ContributionRecur.xml b/civicrm/xml/schema/Contribute/ContributionRecur.xml index 9a8e4ba9eb..9e9145cf8a 100644 --- a/civicrm/xml/schema/Contribute/ContributionRecur.xml +++ b/civicrm/xml/schema/Contribute/ContributionRecur.xml @@ -19,11 +19,14 @@ </primaryKey> <field> <name>contact_id</name> - <title>Contact ID</title> + <title>Contact</title> <type>int unsigned</type> <required>true</required> - <comment>Foreign key to civicrm_contact.id .</comment> + <comment>Foreign key to civicrm_contact.id.</comment> <add>1.6</add> + <html> + <type>EntityRef</type> + </html> </field> <foreignKey> <name>contact_id</name> @@ -100,42 +103,42 @@ </field> <field> <name>start_date</name> - <title>Recurring Contribution Started Date</title> + <title>Start Date</title> <type>datetime</type> <required>true</required> <comment>The date the first scheduled recurring contribution occurs.</comment> <add>1.6</add> <html> <type>Select Date</type> - <formatType>activityDate</formatType> + <formatType>activityDateTime</formatType> </html> </field> <field> <name>create_date</name> - <title>Recurring Contribution Created Date</title> + <title>Created Date</title> <type>datetime</type> <required>true</required> <comment>When this recurring contribution record was created.</comment> <add>1.6</add> <html> <type>Select Date</type> - <formatType>activityDate</formatType> + <formatType>activityDateTime</formatType> </html> </field> <field> <name>modified_date</name> - <title>Recurring Contribution Modified Date</title> + <title>Modified Date</title> <type>datetime</type> <comment>Last updated date for this record. mostly the last time a payment was received</comment> <add>1.6</add> <html> <type>Select Date</type> - <formatType>activityDate</formatType> + <formatType>activityDateTime</formatType> </html> </field> <field> <name>cancel_date</name> - <title>Recurring Contribution Cancel Date</title> + <title>Cancel Date</title> <type>datetime</type> <comment>Date this recurring contribution was cancelled by contributor- if we can get access to it</comment> <add>1.6</add> @@ -162,6 +165,9 @@ <length>255</length> <comment>Possibly needed to store a unique identifier for this recurring payment order - if this is available from the processor??</comment> <add>1.6</add> + <html> + <type>Text</type> + </html> </field> <field> <name>payment_token_id</name> @@ -184,6 +190,9 @@ <length>255</length> <comment>unique transaction id. may be processor id, bank id + trans id, or account number + check number... depending on payment_method</comment> <add>1.6</add> + <html> + <type>Text</type> + </html> </field> <field> <name>invoice_id</name> @@ -192,6 +201,9 @@ <length>255</length> <comment>unique invoice id, system generated or passed in</comment> <add>1.6</add> + <html> + <type>Text</type> + </html> </field> <index> <name>UI_contrib_trxn_id</name> @@ -207,7 +219,7 @@ </index> <field> <name>contribution_status_id</name> - <title>Recurring Contribution Status</title> + <title>Status</title> <type>int unsigned</type> <default>1</default> <import>true</import> @@ -215,6 +227,9 @@ <pseudoconstant> <optionGroupName>contribution_status</optionGroupName> </pseudoconstant> + <html> + <type>Select</type> + </html> </field> <index> <name>index_contribution_status</name> @@ -233,7 +248,7 @@ </field> <field> <name>cycle_day</name> - <title>Number of Cycle Day</title> + <title>Cycle Day</title> <type>int unsigned</type> <default>1</default> <required>true</required> @@ -301,6 +316,14 @@ <type>int unsigned</type> <comment>Foreign key to civicrm_payment_processor.id</comment> <add>3.3</add> + <pseudoconstant> + <table>civicrm_payment_processor</table> + <keyColumn>id</keyColumn> + <labelColumn>name</labelColumn> + </pseudoconstant> + <html> + <type>Select</type> + </html> </field> <foreignKey> <name>payment_processor_id</name> @@ -338,6 +361,9 @@ <keyColumn>id</keyColumn> <labelColumn>name</labelColumn> </pseudoconstant> + <html> + <type>Select</type> + </html> </field> <foreignKey> <name>financial_type_id</name> @@ -377,6 +403,9 @@ <labelColumn>title</labelColumn> </pseudoconstant> <add>4.1</add> + <html> + <type>Select</type> + </html> </field> <foreignKey> <name>campaign_id</name> diff --git a/civicrm/xml/schema/Dedupe/Exception.xml b/civicrm/xml/schema/Dedupe/Exception.xml index bf65f319de..77afb22248 100644 --- a/civicrm/xml/schema/Dedupe/Exception.xml +++ b/civicrm/xml/schema/Dedupe/Exception.xml @@ -23,6 +23,7 @@ <type>int unsigned</type> <comment>FK to Contact ID</comment> <add>3.3</add> + <required>TRUE</required> </field> <foreignKey> <name>contact_id1</name> @@ -37,6 +38,7 @@ <type>int unsigned</type> <comment>FK to Contact ID</comment> <add>3.3</add> + <required>TRUE</required> </field> <foreignKey> <name>contact_id2</name> diff --git a/civicrm/xml/templates/message_templates/payment_or_refund_notification_html.tpl b/civicrm/xml/templates/message_templates/payment_or_refund_notification_html.tpl index 709d7915d9..6095b4d23f 100644 --- a/civicrm/xml/templates/message_templates/payment_or_refund_notification_html.tpl +++ b/civicrm/xml/templates/message_templates/payment_or_refund_notification_html.tpl @@ -12,7 +12,6 @@ {capture assign=emptyBlockStyle }style="padding: 10px; border-bottom: 1px solid #999;background-color: #f7f7f7;"{/capture} {capture assign=emptyBlockValueStyle }style="padding: 10px; border-bottom: 1px solid #999;"{/capture} -<p>Dear {$contactDisplayName}</p> <center> <table width="620" border="0" cellpadding="0" cellspacing="0" id="crm-event_receipt" style="font-family: Arial, Verdana, sans-serif; text-align: left;"> @@ -21,7 +20,7 @@ <!-- END HEADER --> <!-- BEGIN CONTENT --> - + {if $emailGreeting}<tr><td>{$emailGreeting},</td></tr>{/if} <tr> <td> {if $isRefund} @@ -29,7 +28,6 @@ {else} <p>{ts}A payment has been received.{/ts}</p> {/if} - <p>{ts}Please print this confirmation for your records.{/ts}</p> </td> </tr> <tr> @@ -147,7 +145,7 @@ <tr> <td> <table style="border: 1px solid #999; margin: 1em 0em 1em; border-collapse: collapse; width:100%;"> - {if $contributeMode eq 'direct' and !$isAmountzero} + {if $billingName || $address} <tr> <th {$headerStyle}> {ts}Billing Name and Address{/ts} @@ -160,7 +158,7 @@ </td> </tr> {/if} - {if $contributeMode eq'direct' and !$isAmountzero} + {if $credit_card_number} <tr> <th {$headerStyle}> {ts}Credit Card Information{/ts} diff --git a/civicrm/xml/templates/message_templates/payment_or_refund_notification_text.tpl b/civicrm/xml/templates/message_templates/payment_or_refund_notification_text.tpl index c713864c05..2f166dd3d4 100644 --- a/civicrm/xml/templates/message_templates/payment_or_refund_notification_text.tpl +++ b/civicrm/xml/templates/message_templates/payment_or_refund_notification_text.tpl @@ -1,12 +1,10 @@ -Dear {$contactDisplayName} -{if $isRefund} +{if $emailGreeting}{$emailGreeting}, +{/if}{if $isRefund} {ts}A refund has been issued based on changes in your registration selections.{/ts} {else} {ts}A payment has been received.{/ts} {/if} -{ts}Please print this confirmation for your records.{/ts} - {if $isRefund} =============================================================================== @@ -46,7 +44,7 @@ Dear {$contactDisplayName} {if $checkNumber} {ts}Check Number{/ts}: {$checkNumber} {/if} -{if $contributeMode eq 'direct' and !$isAmountzero} +{if $billingName || $address} =============================================================================== @@ -58,7 +56,7 @@ Dear {$contactDisplayName} {$address} {/if} -{if $contributeMode eq 'direct' and !$isAmountzero} +{if $credit_card_number} =========================================================== {ts}Credit Card Information{/ts} diff --git a/civicrm/xml/version.xml b/civicrm/xml/version.xml index 6ab7130f75..e441192fec 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.11.0</version_no> + <version_no>5.12.0</version_no> </version> diff --git a/wp-cli/civicrm.php b/wp-cli/civicrm.php index f093e165ec..60ecaa3229 100644 --- a/wp-cli/civicrm.php +++ b/wp-cli/civicrm.php @@ -26,1302 +26,1309 @@ +--------------------------------------------------------------------+ */ if ( ! defined( 'CIVICRM_WPCLI_LOADED' ) ) { - define( 'CIVICRM_WPCLI_LOADED', 1 ); - - /** - * WP-CLI port of drush-civicrm integration - * andyw@circle, 08/03/2014 - * - * Distributed under the GNU Affero General Public License, version 3 - * http://www.gnu.org/licenses/agpl-3.0.html - */ - - class CiviCRM_Command extends WP_CLI_Command { - - private $args, $assoc_args; - - /** - * WP-CLI integration with CiviCRM. - * - * wp civicrm api - * =============== - * Command for accessing CiviCRM APIs. Syntax is identical to drush cvap. - * - * wp civicrm cache-clear - * =============== - * Command for accessing clearing cache. Equivilant of running civicrm/admin/setting/updateConfigBackend&reset=1 - * - * wp civicrm enable-debug - * =============== - * Command for to turn debug on. - * - * wp civicrm disable-debug - * =============== - * Command for to turn debug off. - * - * wp civicrm member-records - * =============== - * Run the CiviMember UpdateMembershipRecord cron ( civicrm member-records ). - * - * wp civicrm process-mail-queue - * =============== - * Process pending CiviMail mailing jobs. - * Example: - * wp civicrm process-mail-queue -u admin - * - * wp civicrm rest - * =============== - * Rest interface for accessing CiviCRM APIs. It can return xml or json formatted data. - * - * wp civicrm restore - * ================== - * Restore CiviCRM codebase and database back from the specified backup directory - * - * wp civicrm sql-conf - * =================== - * Show civicrm database connection details. - * - * wp civicrm sql-connect - * ====================== - * A string which connects to the civicrm database. - * - * wp civicrm sql-cli - * ================== - * Quickly enter the mysql command line. - * - * wp civicrm sql-dump - * =================== - * Prints the whole CiviCRM database to STDOUT or save to a file. - * - * wp civicrm sql-query - * ==================== - * Usage: wp civicrm sql-query <query> <options>... - * <query> is a SQL statement, which can alternatively be passed via STDIN. Any additional arguments are passed to the mysql command directly."; - * - * wp civicrm update-cfg - * ===================== - * Update config_backend to correct config settings, especially when the CiviCRM site has been cloned / migrated. - * - * wp civicrm upgrade - * ================== - * Take backups, replace CiviCRM codebase with new specified tarfile and upgrade database by executing the CiviCRM upgrade process - civicrm/upgrade?reset=1. Use civicrm-restore to revert to previous state in case anything goes wrong. - * - * wp civicrm upgrade-db - * ===================== - * Run civicrm/upgrade?reset=1 just as a web browser would. - * - * wp civicrm install - * =============== - * Command for to install CiviCRM. The install command requires that you have downloaded a tarball or zip file first. - * Options: - * --dbhost MySQL host for your WordPress/CiviCRM database. Defaults to localhost. - * --dbname MySQL database name of your WordPress/CiviCRM database. - * --dbpass MySQL password for your WordPress/CiviCRM database. - * --dbuser MySQL username for your WordPress/CiviCRM database. - * --lang Default language to use for installation. - * --langtarfile Path to your l10n tar.gz file. - * --site_url Base Url for your WordPress/CiviCRM website without http ( e.g. mysite.com ) - * --ssl Using ssl for your WordPress/CiviCRM website if set to on ( e.g. --ssl=on ) - * --tarfile Path to your CiviCRM tar.gz file. - * - */ - - public function __invoke( $args, $assoc_args ) { - - $this->args = $args; - $this->assoc_args = $assoc_args; - - # define command router - $command_router = array( - 'api' => 'api', - 'cache-clear' => 'cacheClear', - 'enable-debug' => 'enableDebug', - 'disable-debug' => 'disableDebug', - 'install' => 'install', - 'member-records' => 'memberRecords', - 'process-mail-queue' => 'processMailQueue', - 'rest' => 'rest', - 'restore' => 'restore', - 'sql-cli' => 'sqlCLI', - 'sql-conf' => 'sqlConf', - 'sql-connect' => 'sqlConnect', - 'sql-dump' => 'sqlDump', - 'sql-query' => 'sqlQuery', - 'update-cfg' => 'updateConfig', - 'upgrade' => 'upgrade', - 'upgrade-db' => 'upgradeDB', - ); - - # get command - $command = array_shift( $args ); - - # check for existence of Civi ( except for command 'install' ) - if ( ! function_exists( 'civicrm_initialize' ) and 'install' != $command ) { - return WP_CLI::error( 'Unable to find CiviCRM install.' ); - } - - # check existence of router entry / handler method - if ( ! isset( $command_router[ $command ] ) or ! method_exists( $this, $command_router[ $command ] ) ) { - return WP_CLI::error( "Unrecognized command - '$command'" ); - } - - # run command - return $this->{$command_router[ $command ]}(); - - } - - /** - * Implementation of command 'api' - */ - private function api() { - - $defaults = array( 'version' => 3 ); - - array_shift( $this->args ); - list( $entity, $action ) = explode( '.', $this->args[0] ); - array_shift( $this->args ); - - # parse $params - $format = $this->getOption( 'in', 'args' ); - switch ( $format ) { - - # input params supplied via args .. - case 'args': - $params = $defaults; - foreach ( $this->args as $arg ) { - preg_match( '/^([^=]+)=(.*)$/', $arg, $matches ); - $params[ $matches[1] ] = $matches[2]; - } - break; - - # input params supplied via json .. - case 'json': - $json = stream_get_contents( STDIN ); - $params = ( empty( $json ) ? $defaults : array_merge( $defaults, json_decode( $json, true ) ) ); - break; - - default: - WP_CLI::error( 'Unknown format: ' . $format ); - break; - } - - civicrm_initialize(); - - // CRM-18062: Set CiviCRM timezone if any - $wp_base_timezone = date_default_timezone_get(); - $wp_user_timezone = $this->getOption( 'timezone', get_option( 'timezone_string' ) ); - if ( $wp_user_timezone ) { - date_default_timezone_set( $wp_user_timezone ); - CRM_Core_Config::singleton()->userSystem->setMySQLTimeZone(); - } - - $result = civicrm_api( $entity, $action, $params ); - - // restore WP's timezone - if ( $wp_base_timezone ) { - date_default_timezone_set( $wp_base_timezone ); - } - - switch ( $this->getOption( 'out', 'pretty' ) ) { - - # pretty-print output ( default ) - case 'pretty': - WP_CLI::line( print_r( $result, true ) ); - break; - - # display output as json - case 'json': - WP_CLI::line( json_encode( $result ) ); - break; - - default: - return WP_CLI::error( 'Unknown format: ' . $format ); - - } - - } - - /** - * Implementation of command 'cache-clear' - */ - private function cacheClear() { - - civicrm_initialize(); - require_once 'CRM/Core/Config.php'; - $config = CRM_Core_Config::singleton(); - - # clear db caching - $config->clearDBCache(); - - # also cleanup the templates_c directory - $config->cleanup( 1, false ); - - # also cleanup the session object - $session = CRM_Core_Session::singleton(); - $session->reset( 1 ); - - } - - /** - * Implementation of command 'enable-debug' - */ - private function enableDebug() { - civicrm_initialize(); - Civi::settings()->add( array( - 'debug_enabled' => 1, - 'backtrace' => 1, - ) ); - WP_CLI::success( 'Debug setting enabled.' ); - } - - /** - * Implementation of command 'disable-debug' - */ - private function disableDebug() { - civicrm_initialize(); - Civi::settings()->add( array( - 'debug_enabled' => 0, - 'backtrace' => 0, - ) ); - WP_CLI::success( 'Debug setting disabled.' ); - } - - /** - * Implementation of command 'install' - */ - private function install() { - - # validate - - if ( ! $dbuser = $this->getOption( 'dbuser', false ) ) { - return WP_CLI::error( 'CiviCRM database username not specified.' ); - } - - if ( ! $dbpass = $this->getOption( 'dbpass', false ) ) { - return WP_CLI::error( 'CiviCRM database password not specified.' ); - } - - if ( ! $dbhost = $this->getOption( 'dbhost', false ) ) { - return WP_CLI::error( 'CiviCRM database host not specified.' ); - } - - if ( ! $dbname = $this->getOption( 'dbname', false ) ) { - return WP_CLI::error( 'CiviCRM database name not specified.' ); - } - - if ( $lang = $this->getOption( 'lang', false ) and ! $langtarfile = $this->getOption( 'langtarfile', false ) ) { - return WP_CLI::error( 'CiviCRM language tarfile not specified.' ); - } - - # begin install - - if ( $plugin_path = $this->getOption( 'destination', false ) ) { - $plugin_path = ABSPATH . $plugin_path; - } else { - $plugin_path = WP_PLUGIN_DIR . '/civicrm'; - } - - global $crmPath; - $crmPath = "$plugin_path/civicrm"; - $crm_files_present = is_dir( $crmPath ); - - # extract the archive - if ( $this->getOption( 'tarfile', false ) ) { - # should probably never get to here as Wordpress Civi comes in a zip file, but - # just in case that ever changes .. - if ( $crm_files_present ) { - return WP_CLI::error( 'Existing CiviCRM found. No action taken.' ); - } - - if ( ! $this->untar( dirname( $plugin_path ) ) ) { - return WP_CLI::error( 'Error extracting tarfile' ); - } - } elseif ( $this->getOption( 'zipfile', false ) ) { - if ( $crm_files_present ) { - return WP_CLI::error( 'Existing CiviCRM found. No action taken.' ); - } - - if ( ! $this->unzip( dirname( $plugin_path ) ) ) { - return WP_CLI::error( 'Error extracting zipfile' ); - } - } elseif ( $crm_files_present ) { - // Site is already extracted (which is how we're running this - // script); we just need to run the installer. - - } else { - return WP_CLI::error( 'No zipfile specified, use --zipfile=path/to/zipfile or extract file ahead of time' ); - } - - # include civicrm installer helper file - $civicrm_installer_helper = "$crmPath/install/civicrm.php"; - - if ( ! file_exists( $civicrm_installer_helper ) ) { - return WP_CLI::error( 'Archive could not be unpacked OR CiviCRM installer helper file is missing.' ); - } - - if ( $crm_files_present ) { - // We were using a directory that was already there. - WP_CLI::success( 'Using installer files found on the site.' ); - } else { - // We must've just unpacked the archive because it wasn't there - // before. - WP_CLI::success( 'Archive unpacked.' ); - } - require_once $civicrm_installer_helper; - - if ( '' != $lang ) { - if ( ! $this->untar( $plugin_path, 'langtarfile' ) ) { - return WP_CLI::error( 'No language tarfile specified, use --langtarfile=path/to/tarfile' ); - } - } - - # create files dirs - $upload_dir = wp_upload_dir(); - $settings_dir = $upload_dir['basedir'] . DIRECTORY_SEPARATOR . 'civicrm' . DIRECTORY_SEPARATOR; - civicrm_setup( $upload_dir['basedir'] . DIRECTORY_SEPARATOR ); - WP_CLI::launch( "chmod 0755 $settings_dir -R" ); - - # now we've got some files in place, require PEAR DB and check db setup - $dsn = "mysql://{$dbuser}:{$dbpass}@{$dbhost}/{$dbname}?new_link=true"; - $dsn_nodb = "mysql://{$dbuser}:{$dbpass}@{$dbhost}"; - - if ( ! defined( 'DB_DSN_MODE' ) ) { - define( 'DB_DSN_MODE', 'auto' ); - } - - require_once "$crmPath/packages/DB.php"; - - $db = DB::connect( $dsn ); - if ( DB::iserror( $db ) ) { - $db = DB::connect( $dsn_nodb ); - if ( DB::iserror( $db ) ) { - return WP_CLI::error( 'Unable to connect to database. Please re-check credentials.' ); - } - $db->query( "CREATE DATABASE $dbname" ); - if ( DB::iserror( $db ) ) { - return WP_CLI::error( 'CiviCRM database was not found. Failed to create one.' ); - } - $db->disconnect(); - } - - # install db - global $sqlPath; - - # setup database with civicrm structure and data - WP_CLI::line( 'Loading CiviCRM database structure ..' ); - civicrm_source( $dsn, $sqlPath . '/civicrm.mysql' ); - WP_CLI::line( 'Loading CiviCRM database with required data ..' ); - - # testing the translated sql files availability - $data_file = $sqlPath . '/civicrm_data.mysql'; - $acl_file = $sqlPath . '/civicrm_acl.mysql'; - - if ( '' != $lang ) { - - if ( file_exists( $sqlPath . '/civicrm_data.' . $lang . '.mysql' ) - and file_exists( $sqlPath . '/civicrm_acl.' . $lang . '.mysql' ) - and '' != $lang - ) { - $data_file = $sqlPath . '/civicrm_data.' . $lang . '.mysql'; - $acl_file = $sqlPath . '/civicrm_acl.' . $lang . '.mysql'; - } else { - WP_CLI::warning( "No sql files could be retrieved for '$lang' using default language." ); - } - } - - civicrm_source( $dsn, $data_file ); - civicrm_source( $dsn, $acl_file ); - - WP_CLI::success( 'CiviCRM database loaded successfully.' ); - - # generate civicrm.settings.php file - global $tplPath; - if ( ! file_exists( $tplPath . 'civicrm.settings.php.template' ) ) { - return WP_CLI::error( 'Could not find CiviCRM settings template and therefore could not create settings file.' ); - } - - WP_CLI::line( 'Generating civicrm settings file ..' ); - - if ( $base_url = $this->getOption( 'site_url', false ) ) { - $ssl = $this->getOption( 'ssl', false ); - $protocol = ( 'on' == $ssl ? 'https' : 'http' ); - } - - $base_url = ! $base_url ? get_bloginfo( 'url' ) : $protocol . '://' . $base_url; - if ( substr( $base_url, -1 ) != '/' ) { - $base_url .= '/'; - } - $params = array( - 'crmRoot' => $crmPath . '/', - 'templateCompileDir' => "{$settings_dir}templates_c", - 'frontEnd' => 0, - 'cms' => 'WordPress', - 'baseURL' => $base_url, - 'dbUser' => $dbuser, - 'dbPass' => $dbpass, - 'dbHost' => $dbhost, - 'dbName' => $dbname, - 'CMSdbUser' => DB_USER, - 'CMSdbPass' => DB_PASSWORD, - 'CMSdbHost' => DB_HOST, - 'CMSdbName' => DB_NAME, - 'siteKey' => md5(rand() . mt_rand() . rand() . uniqid('', TRUE) . $params['baseURL']), - ); - - $str = file_get_contents( $tplPath . 'civicrm.settings.php.template' ); - foreach ( $params as $key => $value ) { - $str = str_replace( '%%' . $key . '%%', $value, $str ); - } - - $str = trim( $str ); - - $config_file = "{$settings_dir}civicrm.settings.php"; - civicrm_write_file( $config_file, $str ); - WP_CLI::launch( "chmod 0644 $config_file" ); - WP_CLI::success( sprintf( 'Settings file generated: %s', $config_file ) ); - - # activate plugin and we're done - @WP_CLI::run_command( array( 'plugin', 'activate', 'civicrm' ), array() ); - WP_CLI::success( 'CiviCRM installed.' ); - - } - - /** - * Implementation of command 'member-records' - */ - private function memberRecords() { - - civicrm_initialize(); - - if ( substr( CRM_Utils_System::version(), 0, 3 ) >= '4.3' ) { - - $job = new CRM_Core_JobManager(); - $job->executeJobByAction( 'job', 'process_membership' ); - WP_CLI::success( "Executed 'process_membership' job." ); - - } else { - - $_REQUEST['name'] = $this->getOption( 'civicrm_cron_username', null ); - $_REQUEST['pass'] = $this->getOption( 'civicrm_cron_password', null ); - $_REQUEST['key'] = $this->getOption( 'civicrm_sitekey', null ); - - global $argv; - $argv = array( - 0 => 'drush', - 1 => '-u' . $_REQUEST['name'], - 2 => '-p' . $_REQUEST['pass'], - 3 => '-s' . $this->getOption( 'uri', false ), - ); - - # if ( !defined( 'CIVICRM_CONFDIR' ) ) { - # $plugins_dir = plugin_dir_path( __FILE__ ); - # define( 'CIVICRM_CONFDIR', $plugins_dir ); - # } - - include 'bin/UpdateMembershipRecord.php'; - - } - - } - - /** - * Implementation of command 'process-mail-queue' - */ - private function processMailQueue() { + define( 'CIVICRM_WPCLI_LOADED', 1 ); + + /** + * WP-CLI port of drush-civicrm integration + * andyw@circle, 08/03/2014 + * + * Distributed under the GNU Affero General Public License, version 3 + * http://www.gnu.org/licenses/agpl-3.0.html + */ + + class CiviCRM_Command extends WP_CLI_Command { + + private $args, $assoc_args; + + /** + * WP-CLI integration with CiviCRM. + * + * wp civicrm api + * =============== + * Command for accessing CiviCRM APIs. Syntax is identical to drush cvap. + * + * wp civicrm cache-clear + * =============== + * Command for accessing clearing cache. Equivilant of running civicrm/admin/setting/updateConfigBackend&reset=1 + * + * wp civicrm enable-debug + * =============== + * Command for to turn debug on. + * + * wp civicrm disable-debug + * =============== + * Command for to turn debug off. + * + * wp civicrm member-records + * =============== + * Run the CiviMember UpdateMembershipRecord cron ( civicrm member-records ). + * + * wp civicrm process-mail-queue + * =============== + * Process pending CiviMail mailing jobs. + * Example: + * wp civicrm process-mail-queue -u admin + * + * wp civicrm rest + * =============== + * Rest interface for accessing CiviCRM APIs. It can return xml or json formatted data. + * + * wp civicrm restore + * ================== + * Restore CiviCRM codebase and database back from the specified backup directory + * + * wp civicrm sql-conf + * =================== + * Show civicrm database connection details. + * + * wp civicrm sql-connect + * ====================== + * A string which connects to the civicrm database. + * + * wp civicrm sql-cli + * ================== + * Quickly enter the mysql command line. + * + * wp civicrm sql-dump + * =================== + * Prints the whole CiviCRM database to STDOUT or save to a file. + * + * wp civicrm sql-query + * ==================== + * Usage: wp civicrm sql-query <query> <options>... + * <query> is a SQL statement, which can alternatively be passed via STDIN. Any additional arguments are passed to the mysql command directly."; + * + * wp civicrm update-cfg + * ===================== + * Update config_backend to correct config settings, especially when the CiviCRM site has been cloned / migrated. + * + * wp civicrm upgrade + * ================== + * Take backups, replace CiviCRM codebase with new specified tarfile and upgrade database by executing the CiviCRM upgrade process - civicrm/upgrade?reset=1. Use civicrm-restore to revert to previous state in case anything goes wrong. + * + * wp civicrm upgrade-db + * ===================== + * Run civicrm/upgrade?reset=1 just as a web browser would. + * + * wp civicrm install + * =============== + * Command for to install CiviCRM. The install command requires that you have downloaded a tarball or zip file first. + * Options: + * --dbhost MySQL host for your WordPress/CiviCRM database. Defaults to localhost. + * --dbname MySQL database name of your WordPress/CiviCRM database. + * --dbpass MySQL password for your WordPress/CiviCRM database. + * --dbuser MySQL username for your WordPress/CiviCRM database. + * --lang Default language to use for installation. + * --langtarfile Path to your l10n tar.gz file. + * --site_url Base Url for your WordPress/CiviCRM website without http ( e.g. mysite.com ) + * --ssl Using ssl for your WordPress/CiviCRM website if set to on ( e.g. --ssl=on ) + * --tarfile Path to your CiviCRM tar.gz file. + * + */ + + public function __invoke( $args, $assoc_args ) { + + $this->args = $args; + $this->assoc_args = $assoc_args; + + # define command router + $command_router = array( + 'api' => 'api', + 'cache-clear' => 'cacheClear', + 'enable-debug' => 'enableDebug', + 'disable-debug' => 'disableDebug', + 'install' => 'install', + 'member-records' => 'memberRecords', + 'process-mail-queue' => 'processMailQueue', + 'rest' => 'rest', + 'restore' => 'restore', + 'sql-cli' => 'sqlCLI', + 'sql-conf' => 'sqlConf', + 'sql-connect' => 'sqlConnect', + 'sql-dump' => 'sqlDump', + 'sql-query' => 'sqlQuery', + 'update-cfg' => 'updateConfig', + 'upgrade' => 'upgrade', + 'upgrade-db' => 'upgradeDB', + ); + + # get command + $command = array_shift( $args ); + + # check for existence of Civi ( except for command 'install' ) + if ( ! function_exists( 'civicrm_initialize' ) and 'install' != $command ) { + return WP_CLI::error( 'Unable to find CiviCRM install.' ); + } + + # check existence of router entry / handler method + if ( ! isset( $command_router[ $command ] ) or ! method_exists( $this, $command_router[ $command ] ) ) { + return WP_CLI::error( "Unrecognized command - '$command'" ); + } + + # if --path is set, save for later use by Civi + global $civicrm_paths; + $wp_cli_config = WP_CLI::get_config(); + if (!empty($wp_cli_config['path'])) { + $civicrm_paths['cms.root']['path'] = $wp_cli_config['path']; + } + + # run command + return $this->{$command_router[ $command ]}(); + + } + + /** + * Implementation of command 'api' + */ + private function api() { + + $defaults = array( 'version' => 3 ); + + array_shift( $this->args ); + list( $entity, $action ) = explode( '.', $this->args[0] ); + array_shift( $this->args ); + + # parse $params + $format = $this->getOption( 'in', 'args' ); + switch ( $format ) { + + # input params supplied via args .. + case 'args': + $params = $defaults; + foreach ( $this->args as $arg ) { + preg_match( '/^([^=]+)=(.*)$/', $arg, $matches ); + $params[ $matches[1] ] = $matches[2]; + } + break; + + # input params supplied via json .. + case 'json': + $json = stream_get_contents( STDIN ); + $params = ( empty( $json ) ? $defaults : array_merge( $defaults, json_decode( $json, true ) ) ); + break; + + default: + WP_CLI::error( 'Unknown format: ' . $format ); + break; + } + + civicrm_initialize(); + + // CRM-18062: Set CiviCRM timezone if any + $wp_base_timezone = date_default_timezone_get(); + $wp_user_timezone = $this->getOption( 'timezone', get_option( 'timezone_string' ) ); + if ( $wp_user_timezone ) { + date_default_timezone_set( $wp_user_timezone ); + CRM_Core_Config::singleton()->userSystem->setMySQLTimeZone(); + } + + $result = civicrm_api( $entity, $action, $params ); + + // restore WP's timezone + if ( $wp_base_timezone ) { + date_default_timezone_set( $wp_base_timezone ); + } + + switch ( $this->getOption( 'out', 'pretty' ) ) { + + # pretty-print output ( default ) + case 'pretty': + WP_CLI::line( print_r( $result, true ) ); + break; + + # display output as json + case 'json': + WP_CLI::line( json_encode( $result ) ); + break; + + default: + return WP_CLI::error( 'Unknown format: ' . $format ); + + } + + } + + /** + * Implementation of command 'cache-clear' + */ + private function cacheClear() { + + civicrm_initialize(); + require_once 'CRM/Core/Config.php'; + $config = CRM_Core_Config::singleton(); + + # clear db caching + $config->clearDBCache(); + + # also cleanup the templates_c directory + $config->cleanup( 1, false ); + + # also cleanup the session object + $session = CRM_Core_Session::singleton(); + $session->reset( 1 ); + + } + + /** + * Implementation of command 'enable-debug' + */ + private function enableDebug() { + civicrm_initialize(); + Civi::settings()->add( array( + 'debug_enabled' => 1, + 'backtrace' => 1, + ) ); + WP_CLI::success( 'Debug setting enabled.' ); + } + + /** + * Implementation of command 'disable-debug' + */ + private function disableDebug() { + civicrm_initialize(); + Civi::settings()->add( array( + 'debug_enabled' => 0, + 'backtrace' => 0, + ) ); + WP_CLI::success( 'Debug setting disabled.' ); + } + + /** + * Implementation of command 'install' + */ + private function install() { + + # validate + + if ( ! $dbuser = $this->getOption( 'dbuser', false ) ) { + return WP_CLI::error( 'CiviCRM database username not specified.' ); + } + + if ( ! $dbpass = $this->getOption( 'dbpass', false ) ) { + return WP_CLI::error( 'CiviCRM database password not specified.' ); + } + + if ( ! $dbhost = $this->getOption( 'dbhost', false ) ) { + return WP_CLI::error( 'CiviCRM database host not specified.' ); + } + + if ( ! $dbname = $this->getOption( 'dbname', false ) ) { + return WP_CLI::error( 'CiviCRM database name not specified.' ); + } + + if ( $lang = $this->getOption( 'lang', false ) and ! $langtarfile = $this->getOption( 'langtarfile', false ) ) { + return WP_CLI::error( 'CiviCRM language tarfile not specified.' ); + } + + # begin install + + if ( $plugin_path = $this->getOption( 'destination', false ) ) { + $plugin_path = ABSPATH . $plugin_path; + } else { + $plugin_path = WP_PLUGIN_DIR . '/civicrm'; + } + + global $crmPath; + $crmPath = "$plugin_path/civicrm"; + $crm_files_present = is_dir( $crmPath ); + + # extract the archive + if ( $this->getOption( 'tarfile', false ) ) { + # should probably never get to here as Wordpress Civi comes in a zip file, but + # just in case that ever changes .. + if ( $crm_files_present ) { + return WP_CLI::error( 'Existing CiviCRM found. No action taken.' ); + } + + if ( ! $this->untar( dirname( $plugin_path ) ) ) { + return WP_CLI::error( 'Error extracting tarfile' ); + } + } elseif ( $this->getOption( 'zipfile', false ) ) { + if ( $crm_files_present ) { + return WP_CLI::error( 'Existing CiviCRM found. No action taken.' ); + } + + if ( ! $this->unzip( dirname( $plugin_path ) ) ) { + return WP_CLI::error( 'Error extracting zipfile' ); + } + } elseif ( $crm_files_present ) { + // Site is already extracted (which is how we're running this + // script); we just need to run the installer. + + } else { + return WP_CLI::error( 'No zipfile specified, use --zipfile=path/to/zipfile or extract file ahead of time' ); + } + + # include civicrm installer helper file + $civicrm_installer_helper = "$crmPath/install/civicrm.php"; + + if ( ! file_exists( $civicrm_installer_helper ) ) { + return WP_CLI::error( 'Archive could not be unpacked OR CiviCRM installer helper file is missing.' ); + } + + if ( $crm_files_present ) { + // We were using a directory that was already there. + WP_CLI::success( 'Using installer files found on the site.' ); + } else { + // We must've just unpacked the archive because it wasn't there + // before. + WP_CLI::success( 'Archive unpacked.' ); + } + require_once $civicrm_installer_helper; + + if ( '' != $lang ) { + if ( ! $this->untar( $plugin_path, 'langtarfile' ) ) { + return WP_CLI::error( 'No language tarfile specified, use --langtarfile=path/to/tarfile' ); + } + } + + # create files dirs + $upload_dir = wp_upload_dir(); + $settings_dir = $upload_dir['basedir'] . DIRECTORY_SEPARATOR . 'civicrm' . DIRECTORY_SEPARATOR; + civicrm_setup( $upload_dir['basedir'] . DIRECTORY_SEPARATOR ); + WP_CLI::launch( "chmod 0755 $settings_dir -R" ); + + # now we've got some files in place, require PEAR DB and check db setup + $dsn = "mysql://{$dbuser}:{$dbpass}@{$dbhost}/{$dbname}?new_link=true"; + $dsn_nodb = "mysql://{$dbuser}:{$dbpass}@{$dbhost}"; + + if ( ! defined( 'DB_DSN_MODE' ) ) { + define( 'DB_DSN_MODE', 'auto' ); + } + + require_once "$crmPath/packages/DB.php"; + + $db = DB::connect( $dsn ); + if ( DB::iserror( $db ) ) { + $db = DB::connect( $dsn_nodb ); + if ( DB::iserror( $db ) ) { + return WP_CLI::error( 'Unable to connect to database. Please re-check credentials.' ); + } + $db->query( "CREATE DATABASE $dbname" ); + if ( DB::iserror( $db ) ) { + return WP_CLI::error( 'CiviCRM database was not found. Failed to create one.' ); + } + $db->disconnect(); + } + + # install db + global $sqlPath; + + # setup database with civicrm structure and data + WP_CLI::line( 'Loading CiviCRM database structure ..' ); + civicrm_source( $dsn, $sqlPath . '/civicrm.mysql' ); + WP_CLI::line( 'Loading CiviCRM database with required data ..' ); + + # testing the translated sql files availability + $data_file = $sqlPath . '/civicrm_data.mysql'; + $acl_file = $sqlPath . '/civicrm_acl.mysql'; + + if ( '' != $lang ) { + + if ( file_exists( $sqlPath . '/civicrm_data.' . $lang . '.mysql' ) + and file_exists( $sqlPath . '/civicrm_acl.' . $lang . '.mysql' ) + and '' != $lang + ) { + $data_file = $sqlPath . '/civicrm_data.' . $lang . '.mysql'; + $acl_file = $sqlPath . '/civicrm_acl.' . $lang . '.mysql'; + } else { + WP_CLI::warning( "No sql files could be retrieved for '$lang' using default language." ); + } + } + + civicrm_source( $dsn, $data_file ); + civicrm_source( $dsn, $acl_file ); + + WP_CLI::success( 'CiviCRM database loaded successfully.' ); + + # generate civicrm.settings.php file + global $tplPath; + if ( ! file_exists( $tplPath . 'civicrm.settings.php.template' ) ) { + return WP_CLI::error( 'Could not find CiviCRM settings template and therefore could not create settings file.' ); + } + + WP_CLI::line( 'Generating civicrm settings file ..' ); + + if ( $base_url = $this->getOption( 'site_url', false ) ) { + $ssl = $this->getOption( 'ssl', false ); + $protocol = ( 'on' == $ssl ? 'https' : 'http' ); + } + + $base_url = ! $base_url ? get_bloginfo( 'url' ) : $protocol . '://' . $base_url; + if ( substr( $base_url, -1 ) != '/' ) { + $base_url .= '/'; + } + $params = array( + 'crmRoot' => $crmPath . '/', + 'templateCompileDir' => "{$settings_dir}templates_c", + 'frontEnd' => 0, + 'cms' => 'WordPress', + 'baseURL' => $base_url, + 'dbUser' => $dbuser, + 'dbPass' => $dbpass, + 'dbHost' => $dbhost, + 'dbName' => $dbname, + 'CMSdbUser' => DB_USER, + 'CMSdbPass' => DB_PASSWORD, + 'CMSdbHost' => DB_HOST, + 'CMSdbName' => DB_NAME, + 'siteKey' => md5(rand() . mt_rand() . rand() . uniqid('', TRUE) . $params['baseURL']), + ); + + $str = file_get_contents( $tplPath . 'civicrm.settings.php.template' ); + foreach ( $params as $key => $value ) { + $str = str_replace( '%%' . $key . '%%', $value, $str ); + } + + $str = trim( $str ); + + $config_file = "{$settings_dir}civicrm.settings.php"; + civicrm_write_file( $config_file, $str ); + WP_CLI::launch( "chmod 0644 $config_file" ); + WP_CLI::success( sprintf( 'Settings file generated: %s', $config_file ) ); + + # activate plugin and we're done + @WP_CLI::run_command( array( 'plugin', 'activate', 'civicrm' ), array() ); + WP_CLI::success( 'CiviCRM installed.' ); + + } + + /** + * Implementation of command 'member-records' + */ + private function memberRecords() { + + civicrm_initialize(); + + if ( substr( CRM_Utils_System::version(), 0, 3 ) >= '4.3' ) { + + $job = new CRM_Core_JobManager(); + $job->executeJobByAction( 'job', 'process_membership' ); + WP_CLI::success( "Executed 'process_membership' job." ); + + } else { + + $_REQUEST['name'] = $this->getOption( 'civicrm_cron_username', null ); + $_REQUEST['pass'] = $this->getOption( 'civicrm_cron_password', null ); + $_REQUEST['key'] = $this->getOption( 'civicrm_sitekey', null ); + + global $argv; + $argv = array( + 0 => 'drush', + 1 => '-u' . $_REQUEST['name'], + 2 => '-p' . $_REQUEST['pass'], + 3 => '-s' . $this->getOption( 'uri', false ), + ); + + # if ( !defined( 'CIVICRM_CONFDIR' ) ) { + # $plugins_dir = plugin_dir_path( __FILE__ ); + # define( 'CIVICRM_CONFDIR', $plugins_dir ); + # } + + include 'bin/UpdateMembershipRecord.php'; + + } + + } + + /** + * Implementation of command 'process-mail-queue' + */ + private function processMailQueue() { - civicrm_initialize(); + civicrm_initialize(); - if ( substr( CRM_Utils_System::version(), 0, 3 ) >= '4.3' ) { - - $job = new CRM_Core_JobManager(); - $job->executeJobByAction( 'job', 'process_mailing' ); - WP_CLI::success( "Executed 'process_mailing' job." ); + if ( substr( CRM_Utils_System::version(), 0, 3 ) >= '4.3' ) { + + $job = new CRM_Core_JobManager(); + $job->executeJobByAction( 'job', 'process_mailing' ); + WP_CLI::success( "Executed 'process_mailing' job." ); - } else { + } else { - $result = civicrm_api( 'Mailing', 'Process', array( 'version' => 3 ) ); - if ( $result['is_error'] ) { - WP_CLI::error( $result['error_message'] ); - } - } - - } - - /** - * Implementation of command 'rest' - */ - private function rest() { + $result = civicrm_api( 'Mailing', 'Process', array( 'version' => 3 ) ); + if ( $result['is_error'] ) { + WP_CLI::error( $result['error_message'] ); + } + } + + } + + /** + * Implementation of command 'rest' + */ + private function rest() { - civicrm_initialize(); + civicrm_initialize(); - if ( ! $query = $this->getOption( 'query', false ) ) { - return WP_CLI::error( 'query not specified.' ); - } + if ( ! $query = $this->getOption( 'query', false ) ) { + return WP_CLI::error( 'query not specified.' ); + } - $query = explode( '&', $query ); - $_GET['q'] = array_shift( $query ); + $query = explode( '&', $query ); + $_GET['q'] = array_shift( $query ); - foreach ( $query as $key_val ) { - list( $key, $val ) = explode( '=', $key_val ); - $_REQUEST[ $key ] = $val; - $_GET[ $key ] = $val; - } + foreach ( $query as $key_val ) { + list( $key, $val ) = explode( '=', $key_val ); + $_REQUEST[ $key ] = $val; + $_GET[ $key ] = $val; + } - require_once 'CRM/Utils/REST.php'; - $rest = new CRM_Utils_REST(); + require_once 'CRM/Utils/REST.php'; + $rest = new CRM_Utils_REST(); - require_once 'CRM/Core/Config.php'; - $config = CRM_Core_Config::singleton(); + require_once 'CRM/Core/Config.php'; + $config = CRM_Core_Config::singleton(); - global $civicrm_root; - // adding dummy script, since based on this api file path is computed. - $_SERVER['SCRIPT_FILENAME'] = "$civicrm_root/extern/rest.php"; + global $civicrm_root; + // adding dummy script, since based on this api file path is computed. + $_SERVER['SCRIPT_FILENAME'] = "$civicrm_root/extern/rest.php"; - if ( isset( $_GET['json'] ) && $_GET['json'] ) { - header( 'Content-Type: text/javascript' ); - } else { - header( 'Content-Type: text/xml' ); - } + if ( isset( $_GET['json'] ) && $_GET['json'] ) { + header( 'Content-Type: text/javascript' ); + } else { + header( 'Content-Type: text/xml' ); + } - echo $rest->run( $config ); + echo $rest->run( $config ); - } + } - /** - * Implementation of command 'restore' - */ - private function restore() { + /** + * Implementation of command 'restore' + */ + private function restore() { - # validate .. - $restore_dir = $this->getOption( 'restore-dir', false ); - $restore_dir = rtrim( $restore_dir, '/' ); - if ( ! $restore_dir ) { - return WP_CLI::error( 'Restore-dir not specified.' ); - } + # validate .. + $restore_dir = $this->getOption( 'restore-dir', false ); + $restore_dir = rtrim( $restore_dir, '/' ); + if ( ! $restore_dir ) { + return WP_CLI::error( 'Restore-dir not specified.' ); + } - $sql_file = $restore_dir . '/civicrm.sql'; - if ( ! file_exists( $sql_file ) ) { - return WP_CLI::error( 'Could not locate civicrm.sql file in the restore directory.' ); - } + $sql_file = $restore_dir . '/civicrm.sql'; + if ( ! file_exists( $sql_file ) ) { + return WP_CLI::error( 'Could not locate civicrm.sql file in the restore directory.' ); + } - $code_dir = $restore_dir . '/civicrm'; - if ( ! is_dir( $code_dir ) ) { - return WP_CLI::error( 'Could not locate civicrm directory inside restore-dir.' ); - } elseif ( ! file_exists( "$code_dir/civicrm/civicrm-version.txt" ) and ! file_exists( "$code_dir/civicrm/civicrm-version.php" ) ) { - return WP_CLI::error( 'civicrm directory inside restore-dir, doesn\'t look to be a valid civicrm codebase.' ); - } + $code_dir = $restore_dir . '/civicrm'; + if ( ! is_dir( $code_dir ) ) { + return WP_CLI::error( 'Could not locate civicrm directory inside restore-dir.' ); + } elseif ( ! file_exists( "$code_dir/civicrm/civicrm-version.txt" ) and ! file_exists( "$code_dir/civicrm/civicrm-version.php" ) ) { + return WP_CLI::error( 'civicrm directory inside restore-dir, doesn\'t look to be a valid civicrm codebase.' ); + } - # prepare to restore .. - $date = date( 'YmdHis' ); + # prepare to restore .. + $date = date( 'YmdHis' ); - civicrm_initialize(); - global $civicrm_root; + civicrm_initialize(); + global $civicrm_root; - $civicrm_root_base = explode( '/', $civicrm_root ); - array_pop( $civicrm_root_base ); - $civicrm_root_base = implode( '/', $civicrm_root_base ) . '/'; + $civicrm_root_base = explode( '/', $civicrm_root ); + array_pop( $civicrm_root_base ); + $civicrm_root_base = implode( '/', $civicrm_root_base ) . '/'; - $basepath = explode( '/', $civicrm_root ); + $basepath = explode( '/', $civicrm_root ); - if ( ! end( $basepath ) ) { - array_pop( $basepath ); - } + if ( ! end( $basepath ) ) { + array_pop( $basepath ); + } - array_pop( $basepath ); - $project_path = implode( '/', $basepath ) . '/'; + array_pop( $basepath ); + $project_path = implode( '/', $basepath ) . '/'; - $wp_root = ABSPATH; - $restore_backup_dir = $this->getOption( 'backup-dir', $wp_root . '/../backup' ); - $restore_backup_dir = rtrim( $restore_backup_dir, '/' ); + $wp_root = ABSPATH; + $restore_backup_dir = $this->getOption( 'backup-dir', $wp_root . '/../backup' ); + $restore_backup_dir = rtrim( $restore_backup_dir, '/' ); - # get confirmation from user - + # get confirmation from user - - if ( ! defined( 'CIVICRM_DSN' ) ) { - WP_CLI::error( 'CIVICRM_DSN is not defined.' ); - } + if ( ! defined( 'CIVICRM_DSN' ) ) { + WP_CLI::error( 'CIVICRM_DSN is not defined.' ); + } - $db_spec = DB::parseDSN( CIVICRM_DSN ); - WP_CLI::line( '' ); - WP_CLI::line( 'Process involves:' ); - WP_CLI::line( sprintf( "1. Restoring '\$restore-dir/civicrm' directory to '%s'.", $civicrm_root_base ) ); - WP_CLI::line( sprintf( "2. Dropping and creating '%s' database.", $db_spec['database'] ) ); - WP_CLI::line( "3. Loading '\$restore-dir/civicrm.sql' file into the database." ); - WP_CLI::line( '' ); - WP_CLI::line( sprintf( "Note: Before restoring a backup will be taken in '%s' directory.", "$restore_backup_dir/plugins/restore" ) ); - WP_CLI::line( '' ); + $db_spec = DB::parseDSN( CIVICRM_DSN ); + WP_CLI::line( '' ); + WP_CLI::line( 'Process involves:' ); + WP_CLI::line( sprintf( "1. Restoring '\$restore-dir/civicrm' directory to '%s'.", $civicrm_root_base ) ); + WP_CLI::line( sprintf( "2. Dropping and creating '%s' database.", $db_spec['database'] ) ); + WP_CLI::line( "3. Loading '\$restore-dir/civicrm.sql' file into the database." ); + WP_CLI::line( '' ); + WP_CLI::line( sprintf( "Note: Before restoring a backup will be taken in '%s' directory.", "$restore_backup_dir/plugins/restore" ) ); + WP_CLI::line( '' ); - WP_CLI::confirm( 'Do you really want to continue?' ); + WP_CLI::confirm( 'Do you really want to continue?' ); - $restore_backup_dir .= '/plugins/restore/' . $date; + $restore_backup_dir .= '/plugins/restore/' . $date; - if ( ! mkdir( $restore_backup_dir, 0755, true ) ) { - return WP_CLI::error( 'Failed creating directory: ' . $restore_backup_dir ); - } + if ( ! mkdir( $restore_backup_dir, 0755, true ) ) { + return WP_CLI::error( 'Failed creating directory: ' . $restore_backup_dir ); + } - # 1. backup and restore codebase - WP_CLI::line( 'Restoring civicrm codebase ..' ); - if ( is_dir( $project_path ) && ! rename( $project_path, $restore_backup_dir . '/civicrm' ) ) { - return WP_CLI::error( sprintf( "Failed to take backup for '%s' directory", $project_path ) ); - } + # 1. backup and restore codebase + WP_CLI::line( 'Restoring civicrm codebase ..' ); + if ( is_dir( $project_path ) && ! rename( $project_path, $restore_backup_dir . '/civicrm' ) ) { + return WP_CLI::error( sprintf( "Failed to take backup for '%s' directory", $project_path ) ); + } - if ( ! rename( $code_dir, $project_path ) ) { - return WP_CLI::error( "Failed to restore civicrm directory '%s' to '%s'", $code_dir, $project_path ); - } + if ( ! rename( $code_dir, $project_path ) ) { + return WP_CLI::error( "Failed to restore civicrm directory '%s' to '%s'", $code_dir, $project_path ); + } - WP_CLI::success( 'Codebase restored.' ); + WP_CLI::success( 'Codebase restored.' ); - # 2. backup, drop and create database - WP_CLI::run_command( - array( 'civicrm', 'sql-dump' ), - array( 'result-file' => $restore_backup_dir . '/civicrm.sql' ) - ); + # 2. backup, drop and create database + WP_CLI::run_command( + array( 'civicrm', 'sql-dump' ), + array( 'result-file' => $restore_backup_dir . '/civicrm.sql' ) + ); - WP_CLI::success( 'Database backed up.' ); + WP_CLI::success( 'Database backed up.' ); - # prepare a mysql command-line string for issuing - # db drop / create commands - $command = sprintf( - 'mysql --user=%s --password=%s', - $db_spec['username'], - $db_spec['password'] - ); + # prepare a mysql command-line string for issuing + # db drop / create commands + $command = sprintf( + 'mysql --user=%s --password=%s', + $db_spec['username'], + $db_spec['password'] + ); - if ( isset( $db_spec['hostspec'] ) ) { - $command .= ' --host=' . $db_spec['hostspec']; - } + if ( isset( $db_spec['hostspec'] ) ) { + $command .= ' --host=' . $db_spec['hostspec']; + } - if ( isset( $dsn['port'] ) and ! mpty( $dsn['port'] ) ) { - $command .= ' --port=' . $db_spec['port']; - } + if ( isset( $dsn['port'] ) and ! mpty( $dsn['port'] ) ) { + $command .= ' --port=' . $db_spec['port']; + } - # attempt to drop old database - if ( system( $command . sprintf( ' --execute="DROP DATABASE IF EXISTS %s"', $db_spec['database'] ) ) ) { - return WP_CLI::error( 'Could not drop database: ' . $db_spec['database'] ); - } + # attempt to drop old database + if ( system( $command . sprintf( ' --execute="DROP DATABASE IF EXISTS %s"', $db_spec['database'] ) ) ) { + return WP_CLI::error( 'Could not drop database: ' . $db_spec['database'] ); + } - WP_CLI::success( 'Database dropped.' ); + WP_CLI::success( 'Database dropped.' ); - # attempt to create new database - if ( system( $command . sprintf( ' --execute="CREATE DATABASE %s"', $db_spec['database'] ) ) ) { - WP_CLI::error( 'Could not create new database: ' . $db_spec['database'] ); - } + # attempt to create new database + if ( system( $command . sprintf( ' --execute="CREATE DATABASE %s"', $db_spec['database'] ) ) ) { + WP_CLI::error( 'Could not create new database: ' . $db_spec['database'] ); + } - WP_CLI::success( 'Database created.' ); + WP_CLI::success( 'Database created.' ); - # 3. restore database - WP_CLI::line( 'Loading civicrm.sql file from restore-dir ..' ); - system( $command . ' ' . $db_spec['database'] . ' < ' . $sql_file ); + # 3. restore database + WP_CLI::line( 'Loading civicrm.sql file from restore-dir ..' ); + system( $command . ' ' . $db_spec['database'] . ' < ' . $sql_file ); - WP_CLI::success( 'Database restored.' ); + WP_CLI::success( 'Database restored.' ); - WP_CLI::line( 'Clearing caches..' ); - WP_CLI::run_command( array( 'civicrm', 'cache-clear' ) ); + WP_CLI::line( 'Clearing caches..' ); + WP_CLI::run_command( array( 'civicrm', 'cache-clear' ) ); - WP_CLI::success( 'Restore process completed.' ); + WP_CLI::success( 'Restore process completed.' ); - } + } - /** - * Implementation of command 'sql-conf' - */ - private function sqlConf() { + /** + * Implementation of command 'sql-conf' + */ + private function sqlConf() { - civicrm_initialize(); - if ( ! defined( 'CIVICRM_DSN' ) ) { - WP_CLI::error( 'CIVICRM_DSN is not defined.' ); - } + civicrm_initialize(); + if ( ! defined( 'CIVICRM_DSN' ) ) { + WP_CLI::error( 'CIVICRM_DSN is not defined.' ); + } - WP_CLI::line( print_r( DB::parseDSN( CIVICRM_DSN ), true ) ); + WP_CLI::line( print_r( DB::parseDSN( CIVICRM_DSN ), true ) ); - } + } - /** - * Implementation of command 'sql-connect' - */ - private function sqlConnect() { + /** + * Implementation of command 'sql-connect' + */ + private function sqlConnect() { - civicrm_initialize(); - if ( ! defined( 'CIVICRM_DSN' ) ) { - return WP_CLI::error( 'CIVICRM_DSN is not defined.' ); - } + civicrm_initialize(); + if ( ! defined( 'CIVICRM_DSN' ) ) { + return WP_CLI::error( 'CIVICRM_DSN is not defined.' ); + } - $dsn = DB::parseDSN( CIVICRM_DSN ); + $dsn = DB::parseDSN( CIVICRM_DSN ); - $command = sprintf( - 'mysql --database=%s --host=%s --user=%s --password=%s', - $dsn['database'], - $dsn['hostspec'], - $dsn['username'], - $dsn['password'] - ); + $command = sprintf( + 'mysql --database=%s --host=%s --user=%s --password=%s', + $dsn['database'], + $dsn['hostspec'], + $dsn['username'], + $dsn['password'] + ); - if ( isset( $dsn['port'] ) and ! empty( $dsn['port'] ) ) { - $command .= ' --port=' . $dsn['port']; - } + if ( isset( $dsn['port'] ) and ! empty( $dsn['port'] ) ) { + $command .= ' --port=' . $dsn['port']; + } - return WP_CLI::line( $command ); + return WP_CLI::line( $command ); - } + } - /** - * Implementation of command 'sql-dump' - */ + /** + * Implementation of command 'sql-dump' + */ - private function sqlDump() { + private function sqlDump() { - # bootstrap Civi when we're not being called as part of an upgrade - if ( ! defined( 'CIVICRM_UPGRADE_ACTIVE' ) ) { - civicrm_initialize(); - } + # bootstrap Civi when we're not being called as part of an upgrade + if ( ! defined( 'CIVICRM_UPGRADE_ACTIVE' ) ) { + civicrm_initialize(); + } - if ( ! defined( 'CIVICRM_DSN' ) and ! defined( 'CIVICRM_OLD_DSN' ) ) { - WP_CLI::error( 'DSN is not defined.' ); - } + if ( ! defined( 'CIVICRM_DSN' ) and ! defined( 'CIVICRM_OLD_DSN' ) ) { + WP_CLI::error( 'DSN is not defined.' ); + } - $dsn = self::parseDSN( defined( 'CIVICRM_DSN' ) ? CIVICRM_DSN : CIVICRM_OLD_DSN ); + $dsn = self::parseDSN( defined( 'CIVICRM_DSN' ) ? CIVICRM_DSN : CIVICRM_OLD_DSN ); - $assoc_args = $this->assoc_args; - $stdout = ! isset( $assoc_args['result-file'] ); - $command = "mysqldump --no-defaults --host={$dsn['hostspec']} --user={$dsn['username']} --password='{$dsn['password']}' %s"; - $command_esc_args = array( $dsn['database'] ); + $assoc_args = $this->assoc_args; + $stdout = ! isset( $assoc_args['result-file'] ); + $command = "mysqldump --no-defaults --host={$dsn['hostspec']} --user={$dsn['username']} --password='{$dsn['password']}' %s"; + $command_esc_args = array( $dsn['database'] ); - if ( isset( $assoc_args['tables'] ) ) { - $tables = explode( ',', $assoc_args['tables'] ); - unset( $assoc_args['tables'] ); - $command .= ' --tables'; - foreach ( $tables as $table ) { - $command .= ' %s'; - $command_esc_args[] = trim( $table ); - } - } + if ( isset( $assoc_args['tables'] ) ) { + $tables = explode( ',', $assoc_args['tables'] ); + unset( $assoc_args['tables'] ); + $command .= ' --tables'; + foreach ( $tables as $table ) { + $command .= ' %s'; + $command_esc_args[] = trim( $table ); + } + } - $escaped_command = call_user_func_array( - '\WP_CLI\Utils\esc_cmd', - array_merge( - array( $command ), - $command_esc_args - ) - ); + $escaped_command = call_user_func_array( + '\WP_CLI\Utils\esc_cmd', + array_merge( + array( $command ), + $command_esc_args + ) + ); - \WP_CLI\Utils\run_mysql_command( $escaped_command, $assoc_args ); + \WP_CLI\Utils\run_mysql_command( $escaped_command, $assoc_args ); - if ( ! $stdout ) { - WP_CLI::success( sprintf( 'Exported to %s', $assoc_args['result-file'] ) ); - } + if ( ! $stdout ) { + WP_CLI::success( sprintf( 'Exported to %s', $assoc_args['result-file'] ) ); + } - } + } - /** - * Implementation of command 'sql-query' - */ - private function sqlQuery() { + /** + * Implementation of command 'sql-query' + */ + private function sqlQuery() { - if ( ! isset( $this->args[0] ) ) { - WP_CLI::error( 'No query specified.' ); - return; - } + if ( ! isset( $this->args[0] ) ) { + WP_CLI::error( 'No query specified.' ); + return; + } - $query = $this->args[0]; - - civicrm_initialize(); - if ( ! defined( 'CIVICRM_DSN' ) ) { - WP_CLI::error( 'CIVICRM_DSN is not defined.' ); - } - - $dsn = DB::parseDSN( CIVICRM_DSN ); - - $mysql_args = array( - 'host' => $dsn['hostspec'], - 'database' => $dsn['database'], - 'user' => $dsn['username'], - 'password' => $dsn['password'], - 'execute' => $query, - ); - - \WP_CLI\Utils\run_mysql_command( 'mysql --no-defaults', $mysql_args ); - - } - - /** - * Implementation of command 'sql-cli' - */ - private function sqlCLI() { - - civicrm_initialize(); - if ( ! defined( 'CIVICRM_DSN' ) ) { - WP_CLI::error( 'CIVICRM_DSN is not defined.' ); - } - - $dsn = DB::parseDSN( CIVICRM_DSN ); - - $mysql_args = array( - 'host' => $dsn['hostspec'], - 'database' => $dsn['database'], - 'user' => $dsn['username'], - 'password' => $dsn['password'], - ); - - \WP_CLI\Utils\run_mysql_command( 'mysql --no-defaults', $mysql_args ); - - } - - /** - * Implementation of command 'update-cfg' - */ - private function updateConfig() { - - civicrm_initialize(); - - $default_values = array(); - $states = array( 'old', 'new' ); - - for ( $i = 1; $i <= 3; $i++ ) { - foreach ( $states as $state ) { - $name = "{$state}Val_{$i}"; - $value = $this->getOption( $name, null ); - if ( $value ) { - $default_values[ $name ] = $value; - } - } - } - - $webserver_user = $this->getWebServerUser(); - $webserver_group = $this->getWebServerGroup(); - - require_once 'CRM/Core/I18n.php'; - require_once 'CRM/Core/BAO/ConfigSetting.php'; - $result = CRM_Core_BAO_ConfigSetting::doSiteMove( $default_values ); - - if ( $result ) { - - # attempt to preserve webserver ownership of templates_c, civicrm/upload - if ( $webserver_user and $webserver_group ) { - $upload_dir = wp_upload_dir(); - $civicrm_files_dir = $upload_dir['basedir'] . DIRECTORY_SEPARATOR . 'civicrm' . DIRECTORY_SEPARATOR; - system( sprintf( 'chown -R %s:%s %s/templates_c', $webserver_user, $webserver_group, $civicrm_files_dir ) ); - system( sprintf( 'chown -R %s:%s %s/upload', $webserver_user, $webserver_group, $civicrm_files_dir ) ); - } - - WP_CLI::success( 'Config successfully updated.' ); - - } else { - WP_CLI::error( 'Config update failed.' ); - } - - } - - /** - * Implementation of command 'upgrade' - */ - private function upgrade() { - - # todo: use wp-cli to download tarfile. - # todo: if tarfile is not specified, see if the code already exists and use that instead. - if ( ! $this->getOption( 'tarfile', false ) and ! $this->getOption( 'zipfile', false ) ) { - return WP_CLI::error( 'Must specify either --tarfile or --zipfile' ); - } - - # fixme: throw error if tarfile is not in a valid format. - if ( ! defined( 'CIVICRM_UPGRADE_ACTIVE' ) ) { - define( 'CIVICRM_UPGRADE_ACTIVE', 1 ); - } - - $wp_root = ABSPATH; - $plugins_dir = plugin_dir_path( __FILE__ ); - $legacy_settings_file = $plugins_dir . '/civicrm.settings.php'; - $upload_dir = wp_upload_dir(); - $settings_file = $upload_dir['basedir'] . DIRECTORY_SEPARATOR . 'civicrm' . DIRECTORY_SEPARATOR . 'civicrm.settings.php'; - if ( ! file_exists( $legacy_settings_file ) || ! file_exists( $settings_file ) ) { - return WP_CLI::error( 'Unable to locate settings file at ' . $legacy_settings_file . 'or at ' . $settings_file ); - } - - # nb: we don't want to require civicrm.settings.php here, because .. - # - # a ) this is the old environment we're going to replace - # b ) upgrade-db needs to bootstrap the new environment, so requiring the file - # now will create multiple inclusion problems later on - # - # however, all we're really after is $civicrm_root and CIVICRM_DSN, so we're going to - # pull out the lines we need using a regex and run them - yes, it's pretty silly .. - # don't try this at home, kids. - - $legacy_settings = file_get_contents( $legacy_settings_file ); - $legacy_settings = str_replace( "\r", '', $legacy_settings ); - $legacy_settings = explode( "\n", $legacy_settings ); - $settings = file_get_contents( $settings_file ); - $settings = str_replace( "\r", '', $settings ); - $settings = explode( "\n", $settings ); - - if ( $civicrm_root_code = reset( preg_grep( '/^\s*\$civicrm_root\s*=.*$/', $legacy_settings ) ) ) { - eval( $civicrm_root_code ); - } elseif ( $civicrm_root_code = reset( preg_grep( '/^\s*\$civicrm_root\s*=.*$/', $settings ) ) ) { - eval( $civicrm_root_code ); - } else { - return WP_CLI::error( 'Unable to read $civicrm_root from civicrm.settings.php' ); - } - - if ( $civicrm_dsn_code = reset( preg_grep( '/^\s*define.*CIVICRM_DSN.*$/', $settings ) ) ) { - $civicrm_dsn_code = str_replace( 'CIVICRM_DSN', 'CIVICRM_OLD_DSN', $civicrm_dsn_code ); - eval( $civicrm_dsn_code ); - } else { - return WP_CLI::error( 'Unable to read CIVICRM_DSN from civicrm.settings.php' ); - } - - if ( ! defined( 'CIVICRM_OLD_DSN' ) ) { - return WP_CLI::error( 'Unable to set CIVICRM_OLD_DSN' ); - } - - $date = date( 'YmdHis' ); - $backup_file = 'civicrm'; - - $basepath = explode( '/', $civicrm_root ); - - if ( ! end( $basepath ) ) { - array_pop( $basepath ); - } - - array_pop( $basepath ); - $project_path = implode( '/', $basepath ) . '/'; - array_pop( $basepath ); - $plugin_path = implode( '/', $basepath ) . '/'; - - $backup_dir = $this->getOption( 'backup-dir', $wp_root . '../backup' ); - $backup_dir = rtrim( $backup_dir, '/' ); - - WP_CLI::line( "\nThe upgrade process involves - " ); - WP_CLI::line( sprintf( '1. Backing up current CiviCRM code as => %s', "$backup_dir/plugins/$date/$backup_file" ) ); - WP_CLI::line( sprintf( '2. Backing up database as => %s', "$backup_dir/plugins/$date/$backup_file.sql" ) ); - WP_CLI::line( sprintf( '3. Unpacking tarfile to => %s', $plugin_path ) ); - WP_CLI::line( "4. Executing civicrm/upgrade?reset=1 just as a browser would.\n" ); - - WP_CLI::confirm( 'Do you really want to continue?' ); - - # begin upgrade - - $backup_dir .= '/plugins/' . $date; - if ( ! mkdir( $backup_dir, 0755, true ) ) { - return WP_CLI::error( 'Failed creating directory: ' . $backup_dir ); - } - - $backup_target = $backup_dir . '/' . $backup_file; - - if ( ! rename( $project_path, $backup_target ) ) { - return WP_CLI::error( sprintf( - 'Failed to backup CiviCRM project directory %s to %s', - $project_path, - $backup_target - ) ); - } - - WP_CLI::line(); - WP_CLI::success( '1. Code backed up.' ); - - WP_CLI::run_command( - array( 'civicrm', 'sql-dump' ), - array( 'result-file' => $backup_target . '.sql' ) - ); - - WP_CLI::success( '2. Database backed up.' ); - - # decompress - if ( $this->getOption( 'tarfile', false ) ) { - # should probably never get to here, as looks like Wordpress Civi comes - # in a zip file - if ( ! $this->untar( $plugin_path ) ) { - return WP_CLI::error( 'Error extracting tarfile' ); - } - } elseif ( $this->getOption( 'zipfile', false ) ) { - if ( ! $this->unzip( $plugin_path ) ) { - return WP_CLI::error( 'Error extracting zipfile' ); - } - } else { - return WP_CLI::error( 'No zipfile specified, use --zipfile=path/to/zipfile' ); - } - - WP_CLI::success( '3. Archive unpacked.' ); - - WP_CLI::line( 'Copying civicrm.settings.php to ' . $project_path . '..' ); - define( 'CIVICRM_SETTINGS_PATH', $project_path . 'civicrm.settings.php' ); - - if ( ! copy( $backup_dir . '/civicrm/civicrm.settings.php', CIVICRM_SETTINGS_PATH ) ) { - return WP_CLI::error( 'Failed to copy file' ); - } - - WP_CLI::success( '4. ' ); - - WP_CLI::run_command( array( 'civicrm', 'upgrade-db' ), array() ); - - WP_CLI::success( 'Process completed.' ); - - } - - /** - * Implementation of command 'upgrade-db' - */ - private function upgradeDB() { - - civicrm_initialize(); - - if ( class_exists( 'CRM_Upgrade_Headless' ) ) { - # Note: CRM_Upgrade_Headless introduced in 4.2 -- at the same time as class auto-loading - try { - $upgrade_headless = new CRM_Upgrade_Headless(); - $result = $upgrade_headless->run(); - WP_CLI::line( 'Upgrade outputs: ' . '"' . $result['message'] . '"' ); - } catch ( Exception $e ) { - WP_CLI::error( $e->getMessage() ); - } - - } else { - - require_once 'CRM/Core/Smarty.php'; - $template = CRM_Core_Smarty::singleton(); - - require_once( 'CRM/Upgrade/Page/Upgrade.php' ); - $upgrade = new CRM_Upgrade_Page_Upgrade(); - - // new since CiviCRM 4.1 - if ( is_callable( array( $upgrade, 'setPrint' ) ) ) { - $upgrade->setPrint( true ); - } - - # to suppress html output /w source code. - ob_start(); - $upgrade->run(); - # capture the required message. - $result = $template->get_template_vars( 'message' ); - ob_end_clean(); - WP_CLI::line( 'Upgrade outputs: ' . "\"$result\"" ); - - } - - } - - /** - * DSN parser - this has been stolen from PEAR DB since we don't always have a - * bootstrapped environment we can access this from, eg: when doing an upgrade - * @param $dsn ( string ) - * @return array containing db connection details - */ - private static function parseDSN( $dsn ) { - - $parsed = array( - 'phptype' => false, - 'dbsyntax' => false, - 'username' => false, - 'password' => false, - 'protocol' => false, - 'hostspec' => false, - 'port' => false, - 'socket' => false, - 'database' => false, - ); - - if ( is_array( $dsn ) ) { - $dsn = array_merge( $parsed, $dsn ); - if ( ! $dsn['dbsyntax'] ) { - $dsn['dbsyntax'] = $dsn['phptype']; - } - return $dsn; - } - - // Find phptype and dbsyntax - if ( ( $pos = strpos( $dsn, '://' ) ) !== false ) { - $str = substr( $dsn, 0, $pos ); - $dsn = substr( $dsn, $pos + 3 ); - } else { - $str = $dsn; - $dsn = null; - } - - // Get phptype and dbsyntax - // $str => phptype( dbsyntax ) - if ( preg_match( '|^(.+?)\((.*?)\)$|', $str, $arr ) ) { - $parsed['phptype'] = $arr[1]; - $parsed['dbsyntax'] = ! $arr[2] ? $arr[1] : $arr[2]; - } else { - $parsed['phptype'] = $str; - $parsed['dbsyntax'] = $str; - } - - if ( empty( $dsn ) ) { - return $parsed; - } - - // Get ( if found ): username and password - // $dsn => username:password@protocol+hostspec/database - if ( ( $at = strrpos( $dsn,'@' ) ) !== false ) { - $str = substr( $dsn, 0, $at ); - $dsn = substr( $dsn, $at + 1 ); - if ( ( $pos = strpos( $str, ':' ) ) !== false ) { - $parsed['username'] = rawurldecode( substr( $str, 0, $pos ) ); - $parsed['password'] = rawurldecode( substr( $str, $pos + 1 ) ); - } else { - $parsed['username'] = rawurldecode( $str ); - } - } - - // Find protocol and hostspec - - if ( preg_match( '|^([^(]+)\((.*?)\)/?(.*?)$|', $dsn, $match ) ) { - // $dsn => proto( proto_opts )/database - $proto = $match[1]; - $proto_opts = $match[2] ? $match[2] : false; - $dsn = $match[3]; - - } else { - // $dsn => protocol+hostspec/database ( old format ) - if ( strpos( $dsn, '+' ) !== false ) { - list( $proto, $dsn ) = explode( '+', $dsn, 2 ); - } - if ( strpos( $dsn, '/' ) !== false ) { - list( $proto_opts, $dsn ) = explode( '/', $dsn, 2 ); - } else { - $proto_opts = $dsn; - $dsn = null; - } - } - - // process the different protocol options - $parsed['protocol'] = ( ! empty( $proto ) ) ? $proto : 'tcp'; - $proto_opts = rawurldecode( $proto_opts ); - if ( strpos( $proto_opts, ':' ) !== false ) { - list( $proto_opts, $parsed['port'] ) = explode( ':', $proto_opts ); - } - if ( 'tcp' == $parsed['protocol'] ) { - $parsed['hostspec'] = $proto_opts; - } elseif ( 'unix' == $parsed['protocol'] ) { - $parsed['socket'] = $proto_opts; - } - - // Get dabase if any - // $dsn => database - if ( $dsn ) { - if ( ( $pos = strpos( $dsn, '?' ) ) === false ) { - // /database - $parsed['database'] = rawurldecode( $dsn ); - } else { - // /database?param1=value1¶m2=value2 - $parsed['database'] = rawurldecode( substr( $dsn, 0, $pos ) ); - $dsn = substr( $dsn, $pos + 1 ); - if ( strpos( $dsn, '&' ) !== false ) { - $opts = explode( '&', $dsn ); - } else { // database?param1=value1 - $opts = array( $dsn ); - } - foreach ( $opts as $opt ) { - list( $key, $value ) = explode( '=', $opt ); - if ( ! isset( $parsed[ $key ] ) ) { - // don't allow params overwrite - $parsed[ $key ] = rawurldecode( $value ); - } - } - } - } - - return $parsed; - } - - /** - * Helper function to replicate functionality of drush_get_option - * @param $name ( string ) - * @return mixed - value if found or $default - */ - private function getOption( $name, $default ) { - return isset( $this->assoc_args[ $name ] ) ? $this->assoc_args[ $name ] : $default; - } - - /** - * Get the user the web server runs as, used to preserve file permissions on templates_c, civicrm/upload - * etc when running as root. This is not a very good check, but is good enough for what we want to do, - * which is preserve file permissions - * @return string - the user which owns templates_c / empty string if not found - */ - private function getWebServerUser() { - $plugins_dir = plugin_dir_path( __FILE__ ); - $plugins_dir_root = WP_PLUGIN_DIR; - $upload_dir = wp_upload_dir(); - $tpl_path = $upload_dir['basedir'] . DIRECTORY_SEPARATOR . 'civicrm' . DIRECTORY_SEPARATOR . 'templates_c'; - $legacy_tpl_path = $plugins_dir_root . '/files/civicrm/templates_c'; - if ( is_dir( $legacy_tpl_path ) ) { - $owner = posix_getpwuid( fileowner( $legacy_tpl_path ) ); - if ( isset( $owner['name'] ) ) { - return $owner['name']; - } - } elseif ( is_dir( $tpl_path ) ) { - $owner = posix_getpwuid( fileowner( $tpl_path ) ); - if ( isset( $owner['name'] ) ) { - return $owner['name']; - } - } - return ''; - - } - - /** - * Get the group the webserver runs as - as above, but for group - */ - private function getWebServerGroup() { - $plugins_dir = plugin_dir_path( __FILE__ ); - $plugins_dir_root = WP_PLUGIN_DIR; - $upload_dir = wp_upload_dir(); - $tpl_path = $upload_dir['basedir'] . DIRECTORY_SEPARATOR . 'civicrm' . DIRECTORY_SEPARATOR . 'templates_c'; - $legacy_tpl_path = $plugins_dir_root . '/files/civicrm/templates_c'; - if ( is_dir( $legacy_tpl_path ) ) { - $group = posix_getgrgid( filegroup( $legacy_tpl_path ) ); - if ( isset( $group['name'] ) ) { - return $group['name']; - } - } elseif ( is_dir( $tpl_path ) ) { - $group = posix_getgrgid( filegroup( $tpl_path ) ); - if ( isset( $group['name'] ) ) { - return $group['name']; - } - } - return ''; - - } - - /** - * Extract a tar.gz archive - * @param $destination_path - the path to extract to - * @param $option - command line option to get input filename from, defaults to 'tarfile' - * @return bool - */ - private function untar( $destination_path, $option = 'tarfile' ) { - - if ( $tarfile = $this->getOption( $option, false ) ) { - WP_CLI::launch( "gzip -d $tarfile" ); - $tarfile = substr( $tarfile, 0, strlen( $tarfile ) - 3 ); - WP_CLI::launch( "tar -xf $tarfile -C \"$destination_path\"" ); - return true; - } else { - return false; - } - - } - - /** - * Extract a zip archive - * @param $destination_path - the path to extract to - * @param $option - command line option to get zip filename from, defaults to 'zipfile' - * @return bool - */ - private function unzip( $destination_path, $option = 'zipfile' ) { - - if ( $zipfile = $this->getOption( $option, false ) ) { - WP_CLI::line( 'Extracting zip archive ...' ); - WP_CLI::launch( "unzip -q $zipfile -d $destination_path" ); - return true; - } else { - return false; - } - - } - - } - - WP_CLI::add_command( 'civicrm', 'CiviCRM_Command' ); - WP_CLI::add_command( 'cv', 'CiviCRM_Command' ); + $query = $this->args[0]; + + civicrm_initialize(); + if ( ! defined( 'CIVICRM_DSN' ) ) { + WP_CLI::error( 'CIVICRM_DSN is not defined.' ); + } + + $dsn = DB::parseDSN( CIVICRM_DSN ); + + $mysql_args = array( + 'host' => $dsn['hostspec'], + 'database' => $dsn['database'], + 'user' => $dsn['username'], + 'password' => $dsn['password'], + 'execute' => $query, + ); + + \WP_CLI\Utils\run_mysql_command( 'mysql --no-defaults', $mysql_args ); + + } + + /** + * Implementation of command 'sql-cli' + */ + private function sqlCLI() { + + civicrm_initialize(); + if ( ! defined( 'CIVICRM_DSN' ) ) { + WP_CLI::error( 'CIVICRM_DSN is not defined.' ); + } + + $dsn = DB::parseDSN( CIVICRM_DSN ); + + $mysql_args = array( + 'host' => $dsn['hostspec'], + 'database' => $dsn['database'], + 'user' => $dsn['username'], + 'password' => $dsn['password'], + ); + + \WP_CLI\Utils\run_mysql_command( 'mysql --no-defaults', $mysql_args ); + + } + + /** + * Implementation of command 'update-cfg' + */ + private function updateConfig() { + + civicrm_initialize(); + + $default_values = array(); + $states = array( 'old', 'new' ); + + for ( $i = 1; $i <= 3; $i++ ) { + foreach ( $states as $state ) { + $name = "{$state}Val_{$i}"; + $value = $this->getOption( $name, null ); + if ( $value ) { + $default_values[ $name ] = $value; + } + } + } + + $webserver_user = $this->getWebServerUser(); + $webserver_group = $this->getWebServerGroup(); + + require_once 'CRM/Core/I18n.php'; + require_once 'CRM/Core/BAO/ConfigSetting.php'; + $result = CRM_Core_BAO_ConfigSetting::doSiteMove( $default_values ); + + if ( $result ) { + + # attempt to preserve webserver ownership of templates_c, civicrm/upload + if ( $webserver_user and $webserver_group ) { + $upload_dir = wp_upload_dir(); + $civicrm_files_dir = $upload_dir['basedir'] . DIRECTORY_SEPARATOR . 'civicrm' . DIRECTORY_SEPARATOR; + system( sprintf( 'chown -R %s:%s %s/templates_c', $webserver_user, $webserver_group, $civicrm_files_dir ) ); + system( sprintf( 'chown -R %s:%s %s/upload', $webserver_user, $webserver_group, $civicrm_files_dir ) ); + } + + WP_CLI::success( 'Config successfully updated.' ); + + } else { + WP_CLI::error( 'Config update failed.' ); + } + + } + + /** + * Implementation of command 'upgrade' + */ + private function upgrade() { + + # todo: use wp-cli to download tarfile. + # todo: if tarfile is not specified, see if the code already exists and use that instead. + if ( ! $this->getOption( 'tarfile', false ) and ! $this->getOption( 'zipfile', false ) ) { + return WP_CLI::error( 'Must specify either --tarfile or --zipfile' ); + } + + # fixme: throw error if tarfile is not in a valid format. + if ( ! defined( 'CIVICRM_UPGRADE_ACTIVE' ) ) { + define( 'CIVICRM_UPGRADE_ACTIVE', 1 ); + } + + $wp_root = ABSPATH; + $plugins_dir = plugin_dir_path( __FILE__ ); + $legacy_settings_file = $plugins_dir . '/civicrm.settings.php'; + $upload_dir = wp_upload_dir(); + $settings_file = $upload_dir['basedir'] . DIRECTORY_SEPARATOR . 'civicrm' . DIRECTORY_SEPARATOR . 'civicrm.settings.php'; + if ( ! file_exists( $legacy_settings_file ) || ! file_exists( $settings_file ) ) { + return WP_CLI::error( 'Unable to locate settings file at ' . $legacy_settings_file . 'or at ' . $settings_file ); + } + + # nb: we don't want to require civicrm.settings.php here, because .. + # + # a ) this is the old environment we're going to replace + # b ) upgrade-db needs to bootstrap the new environment, so requiring the file + # now will create multiple inclusion problems later on + # + # however, all we're really after is $civicrm_root and CIVICRM_DSN, so we're going to + # pull out the lines we need using a regex and run them - yes, it's pretty silly .. + # don't try this at home, kids. + + $legacy_settings = file_get_contents( $legacy_settings_file ); + $legacy_settings = str_replace( "\r", '', $legacy_settings ); + $legacy_settings = explode( "\n", $legacy_settings ); + $settings = file_get_contents( $settings_file ); + $settings = str_replace( "\r", '', $settings ); + $settings = explode( "\n", $settings ); + + if ( $civicrm_root_code = reset( preg_grep( '/^\s*\$civicrm_root\s*=.*$/', $legacy_settings ) ) ) { + eval( $civicrm_root_code ); + } elseif ( $civicrm_root_code = reset( preg_grep( '/^\s*\$civicrm_root\s*=.*$/', $settings ) ) ) { + eval( $civicrm_root_code ); + } else { + return WP_CLI::error( 'Unable to read $civicrm_root from civicrm.settings.php' ); + } + + if ( $civicrm_dsn_code = reset( preg_grep( '/^\s*define.*CIVICRM_DSN.*$/', $settings ) ) ) { + $civicrm_dsn_code = str_replace( 'CIVICRM_DSN', 'CIVICRM_OLD_DSN', $civicrm_dsn_code ); + eval( $civicrm_dsn_code ); + } else { + return WP_CLI::error( 'Unable to read CIVICRM_DSN from civicrm.settings.php' ); + } + + if ( ! defined( 'CIVICRM_OLD_DSN' ) ) { + return WP_CLI::error( 'Unable to set CIVICRM_OLD_DSN' ); + } + + $date = date( 'YmdHis' ); + $backup_file = 'civicrm'; + + $basepath = explode( '/', $civicrm_root ); + + if ( ! end( $basepath ) ) { + array_pop( $basepath ); + } + + array_pop( $basepath ); + $project_path = implode( '/', $basepath ) . '/'; + array_pop( $basepath ); + $plugin_path = implode( '/', $basepath ) . '/'; + + $backup_dir = $this->getOption( 'backup-dir', $wp_root . '../backup' ); + $backup_dir = rtrim( $backup_dir, '/' ); + + WP_CLI::line( "\nThe upgrade process involves - " ); + WP_CLI::line( sprintf( '1. Backing up current CiviCRM code as => %s', "$backup_dir/plugins/$date/$backup_file" ) ); + WP_CLI::line( sprintf( '2. Backing up database as => %s', "$backup_dir/plugins/$date/$backup_file.sql" ) ); + WP_CLI::line( sprintf( '3. Unpacking tarfile to => %s', $plugin_path ) ); + WP_CLI::line( "4. Executing civicrm/upgrade?reset=1 just as a browser would.\n" ); + + WP_CLI::confirm( 'Do you really want to continue?' ); + + # begin upgrade + + $backup_dir .= '/plugins/' . $date; + if ( ! mkdir( $backup_dir, 0755, true ) ) { + return WP_CLI::error( 'Failed creating directory: ' . $backup_dir ); + } + + $backup_target = $backup_dir . '/' . $backup_file; + + if ( ! rename( $project_path, $backup_target ) ) { + return WP_CLI::error( sprintf( + 'Failed to backup CiviCRM project directory %s to %s', + $project_path, + $backup_target + ) ); + } + + WP_CLI::line(); + WP_CLI::success( '1. Code backed up.' ); + + WP_CLI::run_command( + array( 'civicrm', 'sql-dump' ), + array( 'result-file' => $backup_target . '.sql' ) + ); + + WP_CLI::success( '2. Database backed up.' ); + + # decompress + if ( $this->getOption( 'tarfile', false ) ) { + # should probably never get to here, as looks like Wordpress Civi comes + # in a zip file + if ( ! $this->untar( $plugin_path ) ) { + return WP_CLI::error( 'Error extracting tarfile' ); + } + } elseif ( $this->getOption( 'zipfile', false ) ) { + if ( ! $this->unzip( $plugin_path ) ) { + return WP_CLI::error( 'Error extracting zipfile' ); + } + } else { + return WP_CLI::error( 'No zipfile specified, use --zipfile=path/to/zipfile' ); + } + + WP_CLI::success( '3. Archive unpacked.' ); + + WP_CLI::line( 'Copying civicrm.settings.php to ' . $project_path . '..' ); + define( 'CIVICRM_SETTINGS_PATH', $project_path . 'civicrm.settings.php' ); + + if ( ! copy( $backup_dir . '/civicrm/civicrm.settings.php', CIVICRM_SETTINGS_PATH ) ) { + return WP_CLI::error( 'Failed to copy file' ); + } + + WP_CLI::success( '4. ' ); + + WP_CLI::run_command( array( 'civicrm', 'upgrade-db' ), array() ); + + WP_CLI::success( 'Process completed.' ); + + } + + /** + * Implementation of command 'upgrade-db' + */ + private function upgradeDB() { + + civicrm_initialize(); + + if ( class_exists( 'CRM_Upgrade_Headless' ) ) { + # Note: CRM_Upgrade_Headless introduced in 4.2 -- at the same time as class auto-loading + try { + $upgrade_headless = new CRM_Upgrade_Headless(); + $result = $upgrade_headless->run(); + WP_CLI::line( 'Upgrade outputs: ' . '"' . $result['message'] . '"' ); + } catch ( Exception $e ) { + WP_CLI::error( $e->getMessage() ); + } + + } else { + + require_once 'CRM/Core/Smarty.php'; + $template = CRM_Core_Smarty::singleton(); + + require_once( 'CRM/Upgrade/Page/Upgrade.php' ); + $upgrade = new CRM_Upgrade_Page_Upgrade(); + + // new since CiviCRM 4.1 + if ( is_callable( array( $upgrade, 'setPrint' ) ) ) { + $upgrade->setPrint( true ); + } + + # to suppress html output /w source code. + ob_start(); + $upgrade->run(); + # capture the required message. + $result = $template->get_template_vars( 'message' ); + ob_end_clean(); + WP_CLI::line( 'Upgrade outputs: ' . "\"$result\"" ); + + } + + } + + /** + * DSN parser - this has been stolen from PEAR DB since we don't always have a + * bootstrapped environment we can access this from, eg: when doing an upgrade + * @param $dsn ( string ) + * @return array containing db connection details + */ + private static function parseDSN( $dsn ) { + + $parsed = array( + 'phptype' => false, + 'dbsyntax' => false, + 'username' => false, + 'password' => false, + 'protocol' => false, + 'hostspec' => false, + 'port' => false, + 'socket' => false, + 'database' => false, + ); + + if ( is_array( $dsn ) ) { + $dsn = array_merge( $parsed, $dsn ); + if ( ! $dsn['dbsyntax'] ) { + $dsn['dbsyntax'] = $dsn['phptype']; + } + return $dsn; + } + + // Find phptype and dbsyntax + if ( ( $pos = strpos( $dsn, '://' ) ) !== false ) { + $str = substr( $dsn, 0, $pos ); + $dsn = substr( $dsn, $pos + 3 ); + } else { + $str = $dsn; + $dsn = null; + } + + // Get phptype and dbsyntax + // $str => phptype( dbsyntax ) + if ( preg_match( '|^(.+?)\((.*?)\)$|', $str, $arr ) ) { + $parsed['phptype'] = $arr[1]; + $parsed['dbsyntax'] = ! $arr[2] ? $arr[1] : $arr[2]; + } else { + $parsed['phptype'] = $str; + $parsed['dbsyntax'] = $str; + } + + if ( empty( $dsn ) ) { + return $parsed; + } + + // Get ( if found ): username and password + // $dsn => username:password@protocol+hostspec/database + if ( ( $at = strrpos( $dsn,'@' ) ) !== false ) { + $str = substr( $dsn, 0, $at ); + $dsn = substr( $dsn, $at + 1 ); + if ( ( $pos = strpos( $str, ':' ) ) !== false ) { + $parsed['username'] = rawurldecode( substr( $str, 0, $pos ) ); + $parsed['password'] = rawurldecode( substr( $str, $pos + 1 ) ); + } else { + $parsed['username'] = rawurldecode( $str ); + } + } + + // Find protocol and hostspec + + if ( preg_match( '|^([^(]+)\((.*?)\)/?(.*?)$|', $dsn, $match ) ) { + // $dsn => proto( proto_opts )/database + $proto = $match[1]; + $proto_opts = $match[2] ? $match[2] : false; + $dsn = $match[3]; + + } else { + // $dsn => protocol+hostspec/database ( old format ) + if ( strpos( $dsn, '+' ) !== false ) { + list( $proto, $dsn ) = explode( '+', $dsn, 2 ); + } + if ( strpos( $dsn, '/' ) !== false ) { + list( $proto_opts, $dsn ) = explode( '/', $dsn, 2 ); + } else { + $proto_opts = $dsn; + $dsn = null; + } + } + + // process the different protocol options + $parsed['protocol'] = ( ! empty( $proto ) ) ? $proto : 'tcp'; + $proto_opts = rawurldecode( $proto_opts ); + if ( strpos( $proto_opts, ':' ) !== false ) { + list( $proto_opts, $parsed['port'] ) = explode( ':', $proto_opts ); + } + if ( 'tcp' == $parsed['protocol'] ) { + $parsed['hostspec'] = $proto_opts; + } elseif ( 'unix' == $parsed['protocol'] ) { + $parsed['socket'] = $proto_opts; + } + + // Get dabase if any + // $dsn => database + if ( $dsn ) { + if ( ( $pos = strpos( $dsn, '?' ) ) === false ) { + // /database + $parsed['database'] = rawurldecode( $dsn ); + } else { + // /database?param1=value1¶m2=value2 + $parsed['database'] = rawurldecode( substr( $dsn, 0, $pos ) ); + $dsn = substr( $dsn, $pos + 1 ); + if ( strpos( $dsn, '&' ) !== false ) { + $opts = explode( '&', $dsn ); + } else { // database?param1=value1 + $opts = array( $dsn ); + } + foreach ( $opts as $opt ) { + list( $key, $value ) = explode( '=', $opt ); + if ( ! isset( $parsed[ $key ] ) ) { + // don't allow params overwrite + $parsed[ $key ] = rawurldecode( $value ); + } + } + } + } + + return $parsed; + } + + /** + * Helper function to replicate functionality of drush_get_option + * @param $name ( string ) + * @return mixed - value if found or $default + */ + private function getOption( $name, $default ) { + return isset( $this->assoc_args[ $name ] ) ? $this->assoc_args[ $name ] : $default; + } + + /** + * Get the user the web server runs as, used to preserve file permissions on templates_c, civicrm/upload + * etc when running as root. This is not a very good check, but is good enough for what we want to do, + * which is preserve file permissions + * @return string - the user which owns templates_c / empty string if not found + */ + private function getWebServerUser() { + $plugins_dir = plugin_dir_path( __FILE__ ); + $plugins_dir_root = WP_PLUGIN_DIR; + $upload_dir = wp_upload_dir(); + $tpl_path = $upload_dir['basedir'] . DIRECTORY_SEPARATOR . 'civicrm' . DIRECTORY_SEPARATOR . 'templates_c'; + $legacy_tpl_path = $plugins_dir_root . '/files/civicrm/templates_c'; + if ( is_dir( $legacy_tpl_path ) ) { + $owner = posix_getpwuid( fileowner( $legacy_tpl_path ) ); + if ( isset( $owner['name'] ) ) { + return $owner['name']; + } + } elseif ( is_dir( $tpl_path ) ) { + $owner = posix_getpwuid( fileowner( $tpl_path ) ); + if ( isset( $owner['name'] ) ) { + return $owner['name']; + } + } + return ''; + + } + + /** + * Get the group the webserver runs as - as above, but for group + */ + private function getWebServerGroup() { + $plugins_dir = plugin_dir_path( __FILE__ ); + $plugins_dir_root = WP_PLUGIN_DIR; + $upload_dir = wp_upload_dir(); + $tpl_path = $upload_dir['basedir'] . DIRECTORY_SEPARATOR . 'civicrm' . DIRECTORY_SEPARATOR . 'templates_c'; + $legacy_tpl_path = $plugins_dir_root . '/files/civicrm/templates_c'; + if ( is_dir( $legacy_tpl_path ) ) { + $group = posix_getgrgid( filegroup( $legacy_tpl_path ) ); + if ( isset( $group['name'] ) ) { + return $group['name']; + } + } elseif ( is_dir( $tpl_path ) ) { + $group = posix_getgrgid( filegroup( $tpl_path ) ); + if ( isset( $group['name'] ) ) { + return $group['name']; + } + } + return ''; + + } + + /** + * Extract a tar.gz archive + * @param $destination_path - the path to extract to + * @param $option - command line option to get input filename from, defaults to 'tarfile' + * @return bool + */ + private function untar( $destination_path, $option = 'tarfile' ) { + + if ( $tarfile = $this->getOption( $option, false ) ) { + WP_CLI::launch( "gzip -d $tarfile" ); + $tarfile = substr( $tarfile, 0, strlen( $tarfile ) - 3 ); + WP_CLI::launch( "tar -xf $tarfile -C \"$destination_path\"" ); + return true; + } else { + return false; + } + + } + + /** + * Extract a zip archive + * @param $destination_path - the path to extract to + * @param $option - command line option to get zip filename from, defaults to 'zipfile' + * @return bool + */ + private function unzip( $destination_path, $option = 'zipfile' ) { + + if ( $zipfile = $this->getOption( $option, false ) ) { + WP_CLI::line( 'Extracting zip archive ...' ); + WP_CLI::launch( "unzip -q $zipfile -d $destination_path" ); + return true; + } else { + return false; + } + + } + + } + + WP_CLI::add_command( 'civicrm', 'CiviCRM_Command' ); + WP_CLI::add_command( 'cv', 'CiviCRM_Command' ); } -- GitLab