Parcourir la source

Import spitzner files

master
Florian Eisenmenger il y a 2 ans
Parent
révision
b3ef4aed85
100 fichiers modifiés avec 13478 ajouts et 0 suppressions
  1. +22
    -0
      src/.editorconfig
  2. +97
    -0
      src/.gitignore
  3. +47
    -0
      src/.php-cs-fixer.dist.php
  4. +4
    -0
      src/.user.ini
  5. +7977
    -0
      src/CHANGELOG.md
  6. +9
    -0
      src/COPYING.txt
  7. +110
    -0
      src/Gruntfile.js.sample
  8. +48
    -0
      src/LICENSE.txt
  9. +48
    -0
      src/LICENSE_AFL.txt
  10. +8
    -0
      src/app/.htaccess
  11. +52
    -0
      src/app/autoload.php
  12. +102
    -0
      src/app/code/Immerce/Email/Plugin/Framework/Mail/Template/TransportBuilder.php
  13. +13
    -0
      src/app/code/Immerce/Email/etc/di.xml
  14. +11
    -0
      src/app/code/Immerce/Email/etc/module.xml
  15. +13
    -0
      src/app/code/Immerce/Email/registration.php
  16. +36
    -0
      src/app/code/MNM/RevocationForm/Block/RevocationForm.php
  17. +148
    -0
      src/app/code/MNM/RevocationForm/Controller/Index/Index.php
  18. +83
    -0
      src/app/code/MNM/RevocationForm/Model/Config.php
  19. +80
    -0
      src/app/code/MNM/RevocationForm/Model/ConfigInterface.php
  20. +119
    -0
      src/app/code/MNM/RevocationForm/Model/Mail.php
  21. +25
    -0
      src/app/code/MNM/RevocationForm/Model/MailInterface.php
  22. +50
    -0
      src/app/code/MNM/RevocationForm/Observer/CheckCaptchaObserver.php
  23. +18
    -0
      src/app/code/MNM/RevocationForm/composer.json
  24. +44
    -0
      src/app/code/MNM/RevocationForm/etc/adminhtml/system.xml
  25. +38
    -0
      src/app/code/MNM/RevocationForm/etc/config.xml
  26. +18
    -0
      src/app/code/MNM/RevocationForm/etc/di.xml
  27. +11
    -0
      src/app/code/MNM/RevocationForm/etc/email_templates.xml
  28. +6
    -0
      src/app/code/MNM/RevocationForm/etc/frontend/events.xml
  29. +13
    -0
      src/app/code/MNM/RevocationForm/etc/frontend/routes.xml
  30. +8
    -0
      src/app/code/MNM/RevocationForm/etc/module.xml
  31. +29
    -0
      src/app/code/MNM/RevocationForm/i18n/de_DE.csv
  32. +29
    -0
      src/app/code/MNM/RevocationForm/i18n/en_US.csv
  33. +7
    -0
      src/app/code/MNM/RevocationForm/registration.php
  34. +13
    -0
      src/app/code/MNM/RevocationForm/view/frontend/email/submitted_customer_form.html
  35. +70
    -0
      src/app/code/MNM/RevocationForm/view/frontend/email/submitted_form.html
  36. +50
    -0
      src/app/code/MNM/RevocationForm/view/frontend/layout/revocation_index_index.xml
  37. +203
    -0
      src/app/code/MNM/RevocationForm/view/frontend/templates/form.phtml
  38. +35
    -0
      src/app/code/MNM/Spitzner/Block/Info/Debitpayment.php
  39. +66
    -0
      src/app/code/MNM/Spitzner/Block/Magento/Customer/Widget/Name.php
  40. +30
    -0
      src/app/code/MNM/Spitzner/Block/Magento/Review/Adminhtml/Edit/Form.php
  41. +236
    -0
      src/app/code/MNM/Spitzner/Block/Topmenu.php
  42. +51
    -0
      src/app/code/MNM/Spitzner/Console/ExportOrders.php
  43. +130
    -0
      src/app/code/MNM/Spitzner/Controller/Cart/Add.php
  44. +40
    -0
      src/app/code/MNM/Spitzner/Cron/ClearCaches.php
  45. +367
    -0
      src/app/code/MNM/Spitzner/Cron/ExportOrders.php
  46. +244
    -0
      src/app/code/MNM/Spitzner/Helper/Data.php
  47. +28
    -0
      src/app/code/MNM/Spitzner/Model/ExportLogEntry.php
  48. +16
    -0
      src/app/code/MNM/Spitzner/Model/ResourceModel/ExportLogEntry.php
  49. +20
    -0
      src/app/code/MNM/Spitzner/Model/ResourceModel/ExportLogEntry/Collection.php
  50. +447
    -0
      src/app/code/MNM/Spitzner/Model/Rule/Condition/CustomerAttributes.php
  51. +71
    -0
      src/app/code/MNM/Spitzner/Observer/AddEmailVariables.php
  52. +67
    -0
      src/app/code/MNM/Spitzner/Observer/Addtocart.php
  53. +61
    -0
      src/app/code/MNM/Spitzner/Observer/CheckOrderAddresses.php
  54. +46
    -0
      src/app/code/MNM/Spitzner/Overwrite/Model/Transport.php
  55. +35
    -0
      src/app/code/MNM/Spitzner/Plugin/AddCheckoutItemPricePerUnit.php
  56. +39
    -0
      src/app/code/MNM/Spitzner/Plugin/AddCustomerNameToPaypalGuestQuote.php
  57. +16
    -0
      src/app/code/MNM/Spitzner/Plugin/AddStockLabel.php
  58. +10
    -0
      src/app/code/MNM/Spitzner/Plugin/Amasty/Promo/PreventResetQtyAllowed.php
  59. +95
    -0
      src/app/code/MNM/Spitzner/Plugin/Cart/AbstractCart.php
  60. +18
    -0
      src/app/code/MNM/Spitzner/Plugin/CategoryChildrenCollection.php
  61. +19
    -0
      src/app/code/MNM/Spitzner/Plugin/ChangeFaqCollection.php
  62. +142
    -0
      src/app/code/MNM/Spitzner/Plugin/Checkout/ShippingInformationManagementPlugin.php
  63. +65
    -0
      src/app/code/MNM/Spitzner/Plugin/CheckoutLayoutAdaption.php
  64. +170
    -0
      src/app/code/MNM/Spitzner/Plugin/Customer/AddressUpdate.php
  65. +57
    -0
      src/app/code/MNM/Spitzner/Plugin/Customer/Api/AddressRepositoryPlugin.php
  66. +33
    -0
      src/app/code/MNM/Spitzner/Plugin/FilterGalleryImages.php
  67. +28
    -0
      src/app/code/MNM/Spitzner/Plugin/FilterproductsSortByProductAttribute.php
  68. +33
    -0
      src/app/code/MNM/Spitzner/Plugin/ForwardSingleProductListToDetailView.php
  69. +18
    -0
      src/app/code/MNM/Spitzner/Plugin/GroupedProductsGetAssociatedProductsCollection.php
  70. +14
    -0
      src/app/code/MNM/Spitzner/Plugin/OfflineShipping/AddTablerateConditionWithoutDiscount.php
  71. +19
    -0
      src/app/code/MNM/Spitzner/Plugin/Payment/Block/Info/Instructions.php
  72. +86
    -0
      src/app/code/MNM/Spitzner/Plugin/Quote/FixMissingHousenumber.php
  73. +59
    -0
      src/app/code/MNM/Spitzner/Plugin/Quote/FixPaypalGuestCheckoutBug.php
  74. +67
    -0
      src/app/code/MNM/Spitzner/Plugin/Quote/Model/Quote/Address/PrefixPatch.php
  75. +23
    -0
      src/app/code/MNM/Spitzner/Plugin/RemoveAmpromoSalesRuleLabel.php
  76. +22
    -0
      src/app/code/MNM/Spitzner/Plugin/ReorderCheckout.php
  77. +51
    -0
      src/app/code/MNM/Spitzner/Plugin/Review/RemoveRequiredFields.php
  78. +54
    -0
      src/app/code/MNM/Spitzner/Plugin/Sales/Model/Order/Address/PrefixPatch.php
  79. +19
    -0
      src/app/code/MNM/Spitzner/Plugin/SaveCheckoutEmailInSession.php
  80. +88
    -0
      src/app/code/MNM/Spitzner/Plugin/Stockstatus/AddDefaultStockWrapper.php
  81. +22
    -0
      src/app/code/MNM/Spitzner/composer.json
  82. +9
    -0
      src/app/code/MNM/Spitzner/etc/adminhtml/menu.xml
  83. +12
    -0
      src/app/code/MNM/Spitzner/etc/adminhtml/system.xml
  84. +20
    -0
      src/app/code/MNM/Spitzner/etc/catalog_attributes.xml
  85. +13
    -0
      src/app/code/MNM/Spitzner/etc/config.xml
  86. +11
    -0
      src/app/code/MNM/Spitzner/etc/crontab.xml
  87. +72
    -0
      src/app/code/MNM/Spitzner/etc/csp_whitelist.xml
  88. +10
    -0
      src/app/code/MNM/Spitzner/etc/db_schema.xml
  89. +146
    -0
      src/app/code/MNM/Spitzner/etc/di.xml
  90. +11
    -0
      src/app/code/MNM/Spitzner/etc/email_templates.xml
  91. +9
    -0
      src/app/code/MNM/Spitzner/etc/events.xml
  92. +13
    -0
      src/app/code/MNM/Spitzner/etc/module.xml
  93. +28
    -0
      src/app/code/MNM/Spitzner/etc/view.xml
  94. +1
    -0
      src/app/code/MNM/Spitzner/i18n/de_DE.csv
  95. +7
    -0
      src/app/code/MNM/Spitzner/registration.php
  96. +72
    -0
      src/app/code/MNM/Spitzner/view/frontend/email/address_update.html
  97. +20
    -0
      src/app/code/MNM/Spitzner/view/frontend/email/new_review.html
  98. +37
    -0
      src/app/code/MNM/Spitzner/view/frontend/layout/checkout_index_index.xml
  99. +44
    -0
      src/app/code/MNM/Spitzner/view/frontend/requirejs-config.js
  100. +27
    -0
      src/app/code/MNM/Spitzner/view/frontend/web/js/action/set-payment-information-mixin.js

+ 22
- 0
src/.editorconfig Voir le fichier

@@ -0,0 +1,22 @@
root = true

[*]
charset = utf-8
end_of_line = lf
indent_size = 4
indent_style = space
insert_final_newline = true
trim_trailing_whitespace = true

[*.md]
trim_trailing_whitespace = false

[*.{yml,yaml,json}]
indent_size = 2

[{composer, auth}.json]
indent_size = 4

[db_schema_whitelist.json]
indent_size = 4
trim_trailing_whitespace = false

+ 97
- 0
src/.gitignore Voir le fichier

@@ -0,0 +1,97 @@
/.buildpath
/.cache
/.metadata
/.project
/.settings
/.vscode
atlassian*
/nbproject
/robots.txt
/pub/robots.txt
/sitemap
/sitemap.xml
/pub/sitemap
/pub/sitemap.xml
/.idea
/.gitattributes
/app/config_sandbox
/app/etc/config.php
/app/etc/env.php
/app/code/Magento/TestModule*
/lib/internal/flex/uploader/.actionScriptProperties
/lib/internal/flex/uploader/.flexProperties
/lib/internal/flex/uploader/.project
/lib/internal/flex/uploader/.settings
/lib/internal/flex/varien/.actionScriptProperties
/lib/internal/flex/varien/.flexLibProperties
/lib/internal/flex/varien/.project
/lib/internal/flex/varien/.settings
/node_modules
/.grunt
/Gruntfile.js
/package.json
/.php_cs
/.php_cs.cache
/.php-cs-fixer.php
/.php-cs-fixer.cache
/grunt-config.json
/pub/media/*.*
!/pub/media/.htaccess
/pub/media/attribute/*
!/pub/media/attribute/.htaccess
/pub/media/analytics/*
/pub/media/catalog/*
!/pub/media/catalog/.htaccess
/pub/media/customer/*
!/pub/media/customer/.htaccess
/pub/media/downloadable/*
!/pub/media/downloadable/.htaccess
/pub/media/favicon/*
/pub/media/import/*
!/pub/media/import/.htaccess
/pub/media/logo/*
/pub/media/custom_options/*
!/pub/media/custom_options/.htaccess
/pub/media/theme/*
/pub/media/theme_customization/*
!/pub/media/theme_customization/.htaccess
/pub/media/wysiwyg/*
!/pub/media/wysiwyg/.htaccess
/pub/media/tmp/*
!/pub/media/tmp/.htaccess
/pub/media/captcha/*
/pub/media/sitemap/*
!/pub/media/sitemap/.htaccess
/pub/static/*
!/pub/static/.htaccess

/var/*
!/var/.htaccess
/vendor/*
!/vendor/.htaccess
/generated/*
!/generated/.htaccess
.DS_Store


#MNM
/.ht*
/export/
/pub/media/amasty
/pub/productexport/
/setup/
/dev/
/lib/
/package.json.sample
/SECURITY.md
/app/bootstrap.php
/app/etc/di.xml
/auth.json
/cron.sh
/nginx.conf.sample
/pub/.user.ini
/pub/errors/default/page.phtml
/pub/errors/processor.php
/pub/get.php
/import/


+ 47
- 0
src/.php-cs-fixer.dist.php Voir le fichier

@@ -0,0 +1,47 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/

/**
* PHP Coding Standards fixer configuration
*/

$finder = PhpCsFixer\Finder::create()
->name('*.phtml')
->exclude('dev/tests/integration/tmp')
->exclude('dev/tests/integration/var')
->exclude('lib/internal/Cm')
->exclude('lib/internal/Credis')
->exclude('lib/internal/Less')
->exclude('lib/internal/LinLibertineFont')
->exclude('pub/media')
->exclude('pub/static')
->exclude('setup/vendor')
->exclude('var');

$config = new PhpCsFixer\Config();
$config->setFinder($finder)
->setRules([
'@PSR2' => true,
'array_syntax' => ['syntax' => 'short'],
'concat_space' => ['spacing' => 'one'],
'include' => true,
'new_with_braces' => true,
'no_empty_statement' => true,
'no_extra_blank_lines' => true,
'no_leading_import_slash' => true,
'no_leading_namespace_whitespace' => true,
'no_multiline_whitespace_around_double_arrow' => true,
'multiline_whitespace_before_semicolons' => true,
'no_singleline_whitespace_before_semicolons' => true,
'no_trailing_comma_in_singleline_array' => true,
'no_unused_imports' => true,
'no_whitespace_in_blank_line' => true,
'object_operator_without_whitespace' => true,
'ordered_imports' => true,
'standardize_not_equals' => true,
'ternary_operator_spaces' => true,
]);
return $config;

+ 4
- 0
src/.user.ini Voir le fichier

@@ -0,0 +1,4 @@
memory_limit = 756M
max_execution_time = 18000
session.auto_start = off
suhosin.session.cryptua = off

+ 7977
- 0
src/CHANGELOG.md
Fichier diff supprimé car celui-ci est trop grand
Voir le fichier


+ 9
- 0
src/COPYING.txt Voir le fichier

@@ -0,0 +1,9 @@
Copyright © 2013-present Magento, Inc.

Each Magento source file included in this distribution is licensed under OSL 3.0 or the Magento Enterprise Edition (MEE) license

http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
Please see LICENSE.txt for the full text of the OSL 3.0 license or contact license@magentocommerce.com for a copy.

Subject to Licensee's payment of fees and compliance with the terms and conditions of the MEE License, the MEE License supersedes the OSL 3.0 license for each source file.
Please see LICENSE_EE.txt for the full text of the MEE License or visit http://magento.com/legal/terms/enterprise.

+ 110
- 0
src/Gruntfile.js.sample Voir le fichier

@@ -0,0 +1,110 @@
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/

// For performance use one level down: 'name/{,*/}*.js'
// If you want to recursively match all subfolders, use: 'name/**/*.js'

module.exports = function (grunt) {
'use strict';

var _ = require('underscore'),
path = require('path'),
filesRouter = require('./dev/tools/grunt/tools/files-router'),
configDir = './dev/tools/grunt/configs',
tasks = grunt.file.expand('./dev/tools/grunt/tasks/*'),
themes;

filesRouter.set('themes', 'dev/tools/grunt/configs/themes');
themes = filesRouter.get('themes');

tasks = _.map(tasks, function (task) {
return task.replace('.js', '');
});
tasks.push('time-grunt');
tasks.forEach(function (task) {
require(task)(grunt);
});

require('load-grunt-config')(grunt, {
configPath: path.join(__dirname, configDir),
init: true,
jitGrunt: {
staticMappings: {
usebanner: 'grunt-banner'
}
}
});

_.each({
/**
* Assembling tasks.
* ToDo: define default tasks.
*/
default: function () {
grunt.log.subhead('I\'m default task and at the moment I\'m empty, sorry :/');
},

/**
* Production preparation task.
*/
prod: function (component) {
var tasks = [
'less',
'cssmin',
'usebanner'
].map(function (task) {
return task + ':' + component;
});

if (typeof component === 'undefined') {
grunt.log.subhead('Tip: Please make sure that u specify prod subtask. By default prod task do nothing');
} else {
grunt.task.run(tasks);
}
},

/**
* Refresh themes.
*/
refresh: function () {
var tasks = [
'clean',
'exec:all'
];
_.each(themes, function (theme, name) {
tasks.push('less:' + name);
});
grunt.task.run(tasks);
},

/**
* Documentation
*/
documentation: [
'replace:documentation',
'less:documentation',
'styledocco:documentation',
'usebanner:documentationCss',
'usebanner:documentationLess',
'usebanner:documentationHtml',
'clean:var',
'clean:pub'
],

'legacy-build': [
'mage-minify:legacy'
],

spec: function (theme) {
var runner = require('./dev/tests/js/jasmine/spec_runner');

runner.init(grunt, { theme: theme });

grunt.task.run(runner.getTasks());
}
}, function (task, name) {
grunt.registerTask(name, task);
});
};

+ 48
- 0
src/LICENSE.txt Voir le fichier

@@ -0,0 +1,48 @@

Open Software License ("OSL") v. 3.0

This Open Software License (the "License") applies to any original work of authorship (the "Original Work") whose owner (the "Licensor") has placed the following licensing notice adjacent to the copyright notice for the Original Work:

Licensed under the Open Software License version 3.0

1. Grant of Copyright License. Licensor grants You a worldwide, royalty-free, non-exclusive, sublicensable license, for the duration of the copyright, to do the following:

1. to reproduce the Original Work in copies, either alone or as part of a collective work;

2. to translate, adapt, alter, transform, modify, or arrange the Original Work, thereby creating derivative works ("Derivative Works") based upon the Original Work;

3. to distribute or communicate copies of the Original Work and Derivative Works to the public, with the proviso that copies of Original Work or Derivative Works that You distribute or communicate shall be licensed under this Open Software License;

4. to perform the Original Work publicly; and

5. to display the Original Work publicly.

2. Grant of Patent License. Licensor grants You a worldwide, royalty-free, non-exclusive, sublicensable license, under patent claims owned or controlled by the Licensor that are embodied in the Original Work as furnished by the Licensor, for the duration of the patents, to make, use, sell, offer for sale, have made, and import the Original Work and Derivative Works.

3. Grant of Source Code License. The term "Source Code" means the preferred form of the Original Work for making modifications to it and all available documentation describing how to modify the Original Work. Licensor agrees to provide a machine-readable copy of the Source Code of the Original Work along with each copy of the Original Work that Licensor distributes. Licensor reserves the right to satisfy this obligation by placing a machine-readable copy of the Source Code in an information repository reasonably calculated to permit inexpensive and convenient access by You for as long as Licensor continues to distribute the Original Work.

4. Exclusions From License Grant. Neither the names of Licensor, nor the names of any contributors to the Original Work, nor any of their trademarks or service marks, may be used to endorse or promote products derived from this Original Work without express prior permission of the Licensor. Except as expressly stated herein, nothing in this License grants any license to Licensor's trademarks, copyrights, patents, trade secrets or any other intellectual property. No patent license is granted to make, use, sell, offer for sale, have made, or import embodiments of any patent claims other than the licensed claims defined in Section 2. No license is granted to the trademarks of Licensor even if such marks are included in the Original Work. Nothing in this License shall be interpreted to prohibit Licensor from licensing under terms different from this License any Original Work that Licensor otherwise would have a right to license.

5. External Deployment. The term "External Deployment" means the use, distribution, or communication of the Original Work or Derivative Works in any way such that the Original Work or Derivative Works may be used by anyone other than You, whether those works are distributed or communicated to those persons or made available as an application intended for use over a network. As an express condition for the grants of license hereunder, You must treat any External Deployment by You of the Original Work or a Derivative Work as a distribution under section 1(c).

6. Attribution Rights. You must retain, in the Source Code of any Derivative Works that You create, all copyright, patent, or trademark notices from the Source Code of the Original Work, as well as any notices of licensing and any descriptive text identified therein as an "Attribution Notice." You must cause the Source Code for any Derivative Works that You create to carry a prominent Attribution Notice reasonably calculated to inform recipients that You have modified the Original Work.

7. Warranty of Provenance and Disclaimer of Warranty. Licensor warrants that the copyright in and to the Original Work and the patent rights granted herein by Licensor are owned by the Licensor or are sublicensed to You under the terms of this License with the permission of the contributor(s) of those copyrights and patent rights. Except as expressly stated in the immediately preceding sentence, the Original Work is provided under this License on an "AS IS" BASIS and WITHOUT WARRANTY, either express or implied, including, without limitation, the warranties of non-infringement, merchantability or fitness for a particular purpose. THE ENTIRE RISK AS TO THE QUALITY OF THE ORIGINAL WORK IS WITH YOU. This DISCLAIMER OF WARRANTY constitutes an essential part of this License. No license to the Original Work is granted by this License except under this disclaimer.

8. Limitation of Liability. Under no circumstances and under no legal theory, whether in tort (including negligence), contract, or otherwise, shall the Licensor be liable to anyone for any indirect, special, incidental, or consequential damages of any character arising as a result of this License or the use of the Original Work including, without limitation, damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses. This limitation of liability shall not apply to the extent applicable law prohibits such limitation.

9. Acceptance and Termination. If, at any time, You expressly assented to this License, that assent indicates your clear and irrevocable acceptance of this License and all of its terms and conditions. If You distribute or communicate copies of the Original Work or a Derivative Work, You must make a reasonable effort under the circumstances to obtain the express assent of recipients to the terms of this License. This License conditions your rights to undertake the activities listed in Section 1, including your right to create Derivative Works based upon the Original Work, and doing so without honoring these terms and conditions is prohibited by copyright law and international treaty. Nothing in this License is intended to affect copyright exceptions and limitations (including 'fair use' or 'fair dealing'). This License shall terminate immediately and You may no longer exercise any of the rights granted to You by this License upon your failure to honor the conditions in Section 1(c).

10. Termination for Patent Action. This License shall terminate automatically and You may no longer exercise any of the rights granted to You by this License as of the date You commence an action, including a cross-claim or counterclaim, against Licensor or any licensee alleging that the Original Work infringes a patent. This termination provision shall not apply for an action alleging patent infringement by combinations of the Original Work with other software or hardware.

11. Jurisdiction, Venue and Governing Law. Any action or suit relating to this License may be brought only in the courts of a jurisdiction wherein the Licensor resides or in which Licensor conducts its primary business, and under the laws of that jurisdiction excluding its conflict-of-law provisions. The application of the United Nations Convention on Contracts for the International Sale of Goods is expressly excluded. Any use of the Original Work outside the scope of this License or after its termination shall be subject to the requirements and penalties of copyright or patent law in the appropriate jurisdiction. This section shall survive the termination of this License.

12. Attorneys' Fees. In any action to enforce the terms of this License or seeking damages relating thereto, the prevailing party shall be entitled to recover its costs and expenses, including, without limitation, reasonable attorneys' fees and costs incurred in connection with such action, including any appeal of such action. This section shall survive the termination of this License.

13. Miscellaneous. If any provision of this License is held to be unenforceable, such provision shall be reformed only to the extent necessary to make it enforceable.

14. Definition of "You" in This License. "You" throughout this License, whether in upper or lower case, means an individual or a legal entity exercising rights under, and complying with all of the terms of, this License. For legal entities, "You" includes any entity that controls, is controlled by, or is under common control with you. For purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.

15. Right to Use. You may use the Original Work in all ways not otherwise restricted or conditioned by this License or by law, and Licensor promises not to interfere with or be responsible for such uses by You.

16. Modification of This License. This License is Copyright (C) 2005 Lawrence Rosen. Permission is granted to copy, distribute, or communicate this License without modification. Nothing in this License permits You to modify this License as applied to the Original Work or to Derivative Works. However, You may modify the text of this License and copy, distribute or communicate your modified version (the "Modified License") and apply it to other original works of authorship subject to the following conditions: (i) You may not indicate in any way that your Modified License is the "Open Software License" or "OSL" and you may not use those names in the name of your Modified License; (ii) You must replace the notice specified in the first paragraph above with the notice "Licensed under <insert your license name here>" or with a notice of your own that is not confusingly similar to the notice in this License; and (iii) You may not claim that your original works are open source software unless your Modified License has been approved by Open Source Initiative (OSI) and You comply with its license review and certification process.

+ 48
- 0
src/LICENSE_AFL.txt Voir le fichier

@@ -0,0 +1,48 @@

Academic Free License ("AFL") v. 3.0

This Academic Free License (the "License") applies to any original work of authorship (the "Original Work") whose owner (the "Licensor") has placed the following licensing notice adjacent to the copyright notice for the Original Work:

Licensed under the Academic Free License version 3.0

1. Grant of Copyright License. Licensor grants You a worldwide, royalty-free, non-exclusive, sublicensable license, for the duration of the copyright, to do the following:

1. to reproduce the Original Work in copies, either alone or as part of a collective work;

2. to translate, adapt, alter, transform, modify, or arrange the Original Work, thereby creating derivative works ("Derivative Works") based upon the Original Work;

3. to distribute or communicate copies of the Original Work and Derivative Works to the public, under any license of your choice that does not contradict the terms and conditions, including Licensor's reserved rights and remedies, in this Academic Free License;

4. to perform the Original Work publicly; and

5. to display the Original Work publicly.

2. Grant of Patent License. Licensor grants You a worldwide, royalty-free, non-exclusive, sublicensable license, under patent claims owned or controlled by the Licensor that are embodied in the Original Work as furnished by the Licensor, for the duration of the patents, to make, use, sell, offer for sale, have made, and import the Original Work and Derivative Works.

3. Grant of Source Code License. The term "Source Code" means the preferred form of the Original Work for making modifications to it and all available documentation describing how to modify the Original Work. Licensor agrees to provide a machine-readable copy of the Source Code of the Original Work along with each copy of the Original Work that Licensor distributes. Licensor reserves the right to satisfy this obligation by placing a machine-readable copy of the Source Code in an information repository reasonably calculated to permit inexpensive and convenient access by You for as long as Licensor continues to distribute the Original Work.

4. Exclusions From License Grant. Neither the names of Licensor, nor the names of any contributors to the Original Work, nor any of their trademarks or service marks, may be used to endorse or promote products derived from this Original Work without express prior permission of the Licensor. Except as expressly stated herein, nothing in this License grants any license to Licensor's trademarks, copyrights, patents, trade secrets or any other intellectual property. No patent license is granted to make, use, sell, offer for sale, have made, or import embodiments of any patent claims other than the licensed claims defined in Section 2. No license is granted to the trademarks of Licensor even if such marks are included in the Original Work. Nothing in this License shall be interpreted to prohibit Licensor from licensing under terms different from this License any Original Work that Licensor otherwise would have a right to license.

5. External Deployment. The term "External Deployment" means the use, distribution, or communication of the Original Work or Derivative Works in any way such that the Original Work or Derivative Works may be used by anyone other than You, whether those works are distributed or communicated to those persons or made available as an application intended for use over a network. As an express condition for the grants of license hereunder, You must treat any External Deployment by You of the Original Work or a Derivative Work as a distribution under section 1(c).

6. Attribution Rights. You must retain, in the Source Code of any Derivative Works that You create, all copyright, patent, or trademark notices from the Source Code of the Original Work, as well as any notices of licensing and any descriptive text identified therein as an "Attribution Notice." You must cause the Source Code for any Derivative Works that You create to carry a prominent Attribution Notice reasonably calculated to inform recipients that You have modified the Original Work.

7. Warranty of Provenance and Disclaimer of Warranty. Licensor warrants that the copyright in and to the Original Work and the patent rights granted herein by Licensor are owned by the Licensor or are sublicensed to You under the terms of this License with the permission of the contributor(s) of those copyrights and patent rights. Except as expressly stated in the immediately preceding sentence, the Original Work is provided under this License on an "AS IS" BASIS and WITHOUT WARRANTY, either express or implied, including, without limitation, the warranties of non-infringement, merchantability or fitness for a particular purpose. THE ENTIRE RISK AS TO THE QUALITY OF THE ORIGINAL WORK IS WITH YOU. This DISCLAIMER OF WARRANTY constitutes an essential part of this License. No license to the Original Work is granted by this License except under this disclaimer.

8. Limitation of Liability. Under no circumstances and under no legal theory, whether in tort (including negligence), contract, or otherwise, shall the Licensor be liable to anyone for any indirect, special, incidental, or consequential damages of any character arising as a result of this License or the use of the Original Work including, without limitation, damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses. This limitation of liability shall not apply to the extent applicable law prohibits such limitation.

9. Acceptance and Termination. If, at any time, You expressly assented to this License, that assent indicates your clear and irrevocable acceptance of this License and all of its terms and conditions. If You distribute or communicate copies of the Original Work or a Derivative Work, You must make a reasonable effort under the circumstances to obtain the express assent of recipients to the terms of this License. This License conditions your rights to undertake the activities listed in Section 1, including your right to create Derivative Works based upon the Original Work, and doing so without honoring these terms and conditions is prohibited by copyright law and international treaty. Nothing in this License is intended to affect copyright exceptions and limitations (including "fair use" or "fair dealing"). This License shall terminate immediately and You may no longer exercise any of the rights granted to You by this License upon your failure to honor the conditions in Section 1(c).

10. Termination for Patent Action. This License shall terminate automatically and You may no longer exercise any of the rights granted to You by this License as of the date You commence an action, including a cross-claim or counterclaim, against Licensor or any licensee alleging that the Original Work infringes a patent. This termination provision shall not apply for an action alleging patent infringement by combinations of the Original Work with other software or hardware.

11. Jurisdiction, Venue and Governing Law. Any action or suit relating to this License may be brought only in the courts of a jurisdiction wherein the Licensor resides or in which Licensor conducts its primary business, and under the laws of that jurisdiction excluding its conflict-of-law provisions. The application of the United Nations Convention on Contracts for the International Sale of Goods is expressly excluded. Any use of the Original Work outside the scope of this License or after its termination shall be subject to the requirements and penalties of copyright or patent law in the appropriate jurisdiction. This section shall survive the termination of this License.

12. Attorneys' Fees. In any action to enforce the terms of this License or seeking damages relating thereto, the prevailing party shall be entitled to recover its costs and expenses, including, without limitation, reasonable attorneys' fees and costs incurred in connection with such action, including any appeal of such action. This section shall survive the termination of this License.

13. Miscellaneous. If any provision of this License is held to be unenforceable, such provision shall be reformed only to the extent necessary to make it enforceable.

14. Definition of "You" in This License. "You" throughout this License, whether in upper or lower case, means an individual or a legal entity exercising rights under, and complying with all of the terms of, this License. For legal entities, "You" includes any entity that controls, is controlled by, or is under common control with you. For purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.

15. Right to Use. You may use the Original Work in all ways not otherwise restricted or conditioned by this License or by law, and Licensor promises not to interfere with or be responsible for such uses by You.

16. Modification of This License. This License is Copyright © 2005 Lawrence Rosen. Permission is granted to copy, distribute, or communicate this License without modification. Nothing in this License permits You to modify this License as applied to the Original Work or to Derivative Works. However, You may modify the text of this License and copy, distribute or communicate your modified version (the "Modified License") and apply it to other original works of authorship subject to the following conditions: (i) You may not indicate in any way that your Modified License is the "Academic Free License" or "AFL" and you may not use those names in the name of your Modified License; (ii) You must replace the notice specified in the first paragraph above with the notice "Licensed under <insert your license name here>" or with a notice of your own that is not confusingly similar to the notice in this License; and (iii) You may not claim that your original works are open source software unless your Modified License has been approved by Open Source Initiative (OSI) and You comply with its license review and certification process.

+ 8
- 0
src/app/.htaccess Voir le fichier

@@ -0,0 +1,8 @@
<IfVersion < 2.4>
order allow,deny
deny from all
</IfVersion>
<IfVersion >= 2.4>
Require all denied
</IfVersion>


+ 52
- 0
src/app/autoload.php Voir le fichier

@@ -0,0 +1,52 @@
<?php
/**
* Register basic autoloader that uses include path
*
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);

use Magento\Framework\Autoload\AutoloaderRegistry;
use Magento\Framework\Autoload\ClassLoaderWrapper;

/**
* Shortcut constant for the root directory
*/
\define('BP', \dirname(__DIR__));

\define('VENDOR_PATH', BP . '/app/etc/vendor_path.php');

if (!\is_readable(VENDOR_PATH)) {
throw new \Exception(
'We can\'t read some files that are required to run the Magento application. '
. 'This usually means file permissions are set incorrectly.'
);
}

$vendorAutoload = (
static function (): ?string {
$vendorDir = require VENDOR_PATH;

$vendorAutoload = BP . "/{$vendorDir}/autoload.php";
if (\is_readable($vendorAutoload)) {
return $vendorAutoload;
}

$vendorAutoload = "{$vendorDir}/autoload.php";
if (\is_readable($vendorAutoload)) {
return $vendorAutoload;
}

return null;
}
)();

if ($vendorAutoload === null) {
throw new \Exception(
'Vendor autoload is not found. Please run \'composer install\' under application root directory.'
);
}

$composerAutoloader = include $vendorAutoload;
AutoloaderRegistry::registerAutoloader(new ClassLoaderWrapper($composerAutoloader));

+ 102
- 0
src/app/code/Immerce/Email/Plugin/Framework/Mail/Template/TransportBuilder.php Voir le fichier

@@ -0,0 +1,102 @@
<?php
/**
* @author Immerce GmbH
* @package Immerce_Email
* @license https://opensource.org/licenses/GPL-3.0
*/
namespace Immerce\Email\Plugin\Framework\Mail\Template;

use Magento\Framework\Mail\Address;
use Magento\Framework\Mail\MimePart;
use Magento\Framework\Mail\Template\TransportBuilder as MageTransportBuilder;
use Zend\Mail\Header\HeaderWrap;

class TransportBuilder
{
/**
* @param MageTransportBuilder $subject
* @param mixed $address
* @param string $name
* @return array
* @see \Magento\Framework\Mail\Template\TransportBuilder::addTo()
*/
public function beforeAddTo(MageTransportBuilder $subject, $address, $name = '')
{
if (is_array($address)) {
$this->encodeAdressArray($address);
}

return [$address, $this->encodeString($name)];
}

/**
* @param MageTransportBuilder $subject
* @param mixed $address
* @param string $name
* @return array
* @see \Magento\Framework\Mail\Template\TransportBuilder::addCc()
*/
public function beforeAddCc(MageTransportBuilder $subject, $address, $name = '')
{
if (is_array($address)) {
$this->encodeAdressArray($address);
}

return [$address, $this->encodeString($name)];
}

/**
* @param MageTransportBuilder $subject
* @param mixed $email
* @param null $name
* @return array
* @see \Magento\Framework\Mail\Template\TransportBuilder::setReplyTo()
*/
public function beforeSetReplyTo(MageTransportBuilder $subject, $email, $name = null)
{
if (is_array($email)) {
$this->encodeAdressArray($email);
}

return [$email, $name !== null ? $this->encodeString($name) : $name];
}

/**
* @param MageTransportBuilder $subject
* @param mixed $address
* @return array
* @see \Magento\Framework\Mail\Template\TransportBuilder::addBcc()
*/
public function beforeAddBcc(MageTransportBuilder $subject, $address)
{
if (is_array($address)) {
$this->encodeAdressArray($address);
}

return [$address];
}

/**
* @param string $input
* @return string
*/
protected function encodeString(string $input)
{
return HeaderWrap::canBeEncoded($input) ? HeaderWrap::mimeEncodeValue($input, MimePart::CHARSET_UTF8) : $input;
}

/**
* @param array $addresses
* @return void
*/
protected function encodeAdressArray(array $addresses)
{
foreach ($addresses as $address) {
if ($address instanceof Address) {
$name = $this->encodeString($address->getName());
$mail = $address->getEmail();
$address->__construct($mail, $name);
}
}
}
}

+ 13
- 0
src/app/code/Immerce/Email/etc/di.xml Voir le fichier

@@ -0,0 +1,13 @@
<?xml version="1.0"?>
<!--
/**
* @author Immerce GmbH
* @package Immerce_Email
* @license https://opensource.org/licenses/GPL-3.0
*/
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<type name="Magento\Framework\Mail\Template\TransportBuilder">
<plugin name="immerce_email_transport_builder" type="Immerce\Email\Plugin\Framework\Mail\Template\TransportBuilder"/>
</type>
</config>

+ 11
- 0
src/app/code/Immerce/Email/etc/module.xml Voir le fichier

@@ -0,0 +1,11 @@
<?xml version="1.0"?>
<!--
/**
* @author Immerce GmbH
* @package Immerce_Email
* @license https://opensource.org/licenses/GPL-3.0
*/
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
<module name="Immerce_Email" setup_version="1.0.0" />
</config>

+ 13
- 0
src/app/code/Immerce/Email/registration.php Voir le fichier

@@ -0,0 +1,13 @@
<?php
/**
* @author Immerce GmbH
* @package Immerce_Email
* @license https://opensource.org/licenses/GPL-3.0
*/
use Magento\Framework\Component\ComponentRegistrar;

ComponentRegistrar::register(
ComponentRegistrar::MODULE,
'Immerce_Email',
__DIR__
);

+ 36
- 0
src/app/code/MNM/RevocationForm/Block/RevocationForm.php Voir le fichier

@@ -0,0 +1,36 @@
<?php

namespace MNM\RevocationForm\Block;

use Magento\Framework\App\Request\DataPersistorInterface;

class RevocationForm extends \Magento\Framework\View\Element\Template {

private $data;

/**
* @var DataPersistorInterface
*/
private $dataPersistor;

public function __construct(\Magento\Framework\View\Element\Template\Context $context,
DataPersistorInterface $dataPersistor)
{
$this->dataPersistor = $dataPersistor;
parent::__construct($context);
}

public function _prepareLayout()
{
return parent::_prepareLayout();
}

public function getPostVar($var) {
if($this->data == null)
{
$this->data = $this->dataPersistor->get('revocation');
}

return $this->data[$var] ?? '';
}
}

+ 148
- 0
src/app/code/MNM/RevocationForm/Controller/Index/Index.php Voir le fichier

@@ -0,0 +1,148 @@
<?php

namespace MNM\RevocationForm\Controller\Index;

use Magento\Framework\App\Request\DataPersistorInterface;
use Magento\Framework\Exception\LocalizedException;
use MNM\RevocationForm\Model\ConfigInterface;
use MNM\RevocationForm\Model\MailInterface;
use Magento\Framework\DataObject;
use Magento\Framework\Registry;
use Magento\Catalog\Model\ResourceModel\Category\CollectionFactory;

class Index extends \Magento\Framework\App\Action\Action {
protected $resultPageFactory;

/**
* @var DataPersistorInterface
*/
private $dataPersistor;

/**
* @var MailInterface
*/
private $mail;

/**
*
* @var bool
*/
private $captchaFalse;

/**
* @var ConfigInterface
*/
private $contactsConfig;

/**
*
* @var CollectionFactory
*/
private $categoryCollectionFactory;

/**
* @var \Magento\Framework\Registry
*/
protected $_registry;

public function __construct(\Magento\Framework\App\Action\Context $context,
\Magento\Framework\View\Result\PageFactory $resultPageFactory,
ConfigInterface $contactsConfig,
MailInterface $mail,
DataPersistorInterface $dataPersistor,
Registry $registry,
CollectionFactory $categoryCollectionFactory)
{
$this->resultPageFactory = $resultPageFactory;
$this->dataPersistor = $dataPersistor;
$this->captchaFalse = false;
$this->mail = $mail;
$this->contactsConfig = $contactsConfig;
$this->_registry = $registry;
$this->categoryCollectionFactory = $categoryCollectionFactory;
parent::__construct($context);
}

public function execute()
{
//set category for menu
if($this->contactsConfig->cmsCategory())
{
// get an instance of CategoryCollection
$categoryCollection = $this->categoryCollectionFactory->create();

// add a filter to get the IDs you need
$categoryCollection->addFieldToFilter('entity_id', [$this->contactsConfig->cmsCategory()]);

// either call getItems() and iterate over it, or do whatever you need
foreach ($categoryCollection->getItems() as $category) {
/** @var \Magento\Catalog\Model\Category\Interceptor $category */

$this->_registry->register('current_category', $category);
}
}

//check if form send
if($this->getRequest()->isPost()) {
try {
$this->sendEmail($this->validatedParams());
$this->messageManager->addSuccessMessage(
__('Thanks for contacting us with your comments and questions. We\'ll respond to you very soon.')
);
$this->dataPersistor->clear('revocation');
} catch (LocalizedException $e) {
$this->messageManager->addErrorMessage($e->getMessage());
$this->dataPersistor->set('revocation', $this->getRequest()->getParams());
} catch (\Exception $e) {
$this->messageManager->addErrorMessage(
__('An error occurred while processing your form. Please try again later.')
);
$this->dataPersistor->set('revocation', $this->getRequest()->getParams());
}
}

return $this->resultPageFactory->create();
}

public function setCaptchaFalse($v) {
$this->captchaFalse = $v;
}

/**
* @param array $post Post data from contact form
* @return void
*/
private function sendEmail($post)
{
$this->mail->send($post['email'], ['data' => new DataObject($post)]);

//send to customer
$this->mail->sendCustomer($post['email'], ['data' => new DataObject($post)]);
}

/**
* @return array
* @throws \Exception
*/
private function validatedParams()
{
$request = $this->getRequest();
if (trim($request->getParam('name')) === '') {
throw new LocalizedException(__('Enter the Name and try again.'));
}
if (trim($request->getParam('comment')) === '') {
throw new LocalizedException(__('Enter the comment and try again.'));
}
if (false === \strpos($request->getParam('email'), '@')) {
throw new LocalizedException(__('The email address is invalid. Verify the email address and try again.'));
}
if (trim($request->getParam('hideit')) !== '') {
throw new \Exception();
}
if($this->captchaFalse) {
throw new LocalizedException(__('Incorrect CAPTCHA'));
}

return $request->getParams();
}
}

+ 83
- 0
src/app/code/MNM/RevocationForm/Model/Config.php Voir le fichier

@@ -0,0 +1,83 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
namespace MNM\RevocationForm\Model;

use Magento\Framework\App\Config\ScopeConfigInterface;
use Magento\Store\Model\ScopeInterface;

/**
* Contact module configuration
*/
class Config implements ConfigInterface
{
/**
* @var ScopeConfigInterface
*/
private $scopeConfig;

/**
* @param ScopeConfigInterface $scopeConfig
*/
public function __construct(ScopeConfigInterface $scopeConfig)
{
$this->scopeConfig = $scopeConfig;
}

/**
* {@inheritdoc}
*/
public function emailTemplate()
{
return $this->scopeConfig->getValue(
ConfigInterface::XML_PATH_EMAIL_TEMPLATE,
ScopeInterface::SCOPE_STORE
);
}

/**
* {@inheritdoc}
*/
public function emailCustomerTemplate()
{
return $this->scopeConfig->getValue(
ConfigInterface::XML_PATH_EMAIL_CUSTOMER_TEMPLATE,
ScopeInterface::SCOPE_STORE
);
}

/**
* {@inheritdoc}
*/
public function emailSender()
{
return $this->scopeConfig->getValue(
ConfigInterface::XML_PATH_EMAIL_SENDER,
ScopeInterface::SCOPE_STORE
);
}

/**
* {@inheritdoc}
*/
public function emailRecipient()
{
return $this->scopeConfig->getValue(
ConfigInterface::XML_PATH_EMAIL_RECIPIENT,
ScopeInterface::SCOPE_STORE
);
}

/**
* {@inheritdoc}
*/
public function cmsCategory()
{
return $this->scopeConfig->getValue(
ConfigInterface::XML_PATH_CMS_CATEGORY,
ScopeInterface::SCOPE_STORE
);
}
}

+ 80
- 0
src/app/code/MNM/RevocationForm/Model/ConfigInterface.php Voir le fichier

@@ -0,0 +1,80 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
namespace MNM\RevocationForm\Model;

/**
* Contact module configuration
*
* @api
* @since 100.2.0
*/
interface ConfigInterface
{
/**
* Recipient email config path
*/
const XML_PATH_EMAIL_RECIPIENT = 'revocation/email/recipient_email';

/**
* Sender email config path
*/
const XML_PATH_EMAIL_SENDER = 'revocation/email/sender_email_identity';

/**
* Email template config path
*/
const XML_PATH_EMAIL_TEMPLATE = 'revocation/email/email_template';

/**
* Email template config path
*/
const XML_PATH_EMAIL_CUSTOMER_TEMPLATE = 'revocation/email/email_customer_template';

/**
* CMS Category config path
*/
const XML_PATH_CMS_CATEGORY = 'revocation/cms/cms_category';

/**
* Return email template identifier
*
* @return string
* @since 100.2.0
*/
public function emailTemplate();

/**
* Return email customer template identifier
*
* @return string
* @since 100.2.0
*/
public function emailCustomerTemplate();

/**
* Return email sender address
*
* @return string
* @since 100.2.0
*/
public function emailSender();

/**
* Return email recipient address
*
* @return string
* @since 100.2.0
*/
public function emailRecipient();

/**
* Return cms category
*
* @return string
* @since 100.2.0
*/
public function cmsCategory();
}

+ 119
- 0
src/app/code/MNM/RevocationForm/Model/Mail.php Voir le fichier

@@ -0,0 +1,119 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
namespace MNM\RevocationForm\Model;

use Magento\Framework\Mail\Template\TransportBuilder;
use Magento\Framework\Translate\Inline\StateInterface;
use Magento\Store\Model\StoreManagerInterface;
use MNM\RevocationForm\Model\ConfigInterface;
use Magento\Framework\App\ObjectManager;
use Magento\Framework\App\Area;

class Mail implements MailInterface
{
/**
* @var ConfigInterface
*/
private $contactsConfig;

/**
* @var TransportBuilder
*/
private $transportBuilder;

/**
* @var StateInterface
*/
private $inlineTranslation;

/**
* @var StoreManagerInterface
*/
private $storeManager;

/**
* Initialize dependencies.
*
* @param ConfigInterface $contactsConfig
* @param TransportBuilder $transportBuilder
* @param StateInterface $inlineTranslation
* @param StoreManagerInterface|null $storeManager
*/
public function __construct(
ConfigInterface $contactsConfig,
TransportBuilder $transportBuilder,
StateInterface $inlineTranslation,
StoreManagerInterface $storeManager = null
) {
$this->contactsConfig = $contactsConfig;
$this->transportBuilder = $transportBuilder;
$this->inlineTranslation = $inlineTranslation;
$this->storeManager = $storeManager ?: ObjectManager::getInstance()->get(StoreManagerInterface::class);
}

/**
* Send email from contact form
*
* @param string $replyTo
* @param array $variables
* @return void
*/
public function send($replyTo, array $variables)
{
/** @see \Magento\Contact\Controller\Index\Post::validatedParams() */
$replyToName = !empty($variables['data']['name']) ? $variables['data']['name'] : null;

$this->inlineTranslation->suspend();
try {
$transport = $this->transportBuilder
->setTemplateIdentifier($this->contactsConfig->emailTemplate())
->setTemplateOptions(
[
'area' => Area::AREA_FRONTEND,
'store' => $this->storeManager->getStore()->getId()
]
)
->setTemplateVars($variables)
->setFrom($this->contactsConfig->emailSender())
->addTo(explode(',', $this->contactsConfig->emailRecipient()))
->setReplyTo($replyTo, $replyToName)
->getTransport();

$transport->sendMessage();
} finally {
$this->inlineTranslation->resume();
}
}

/**
* Send email from contact form <<TO Customer>>
*
* @param array $variables
* @return void
*/
public function sendCustomer($to, array $variables)
{
$this->inlineTranslation->suspend();
try {
$transport = $this->transportBuilder
->setTemplateIdentifier($this->contactsConfig->emailCustomerTemplate())
->setTemplateOptions(
[
'area' => Area::AREA_FRONTEND,
'store' => $this->storeManager->getStore()->getId()
]
)
->setTemplateVars($variables)
->setFrom($this->contactsConfig->emailSender())
->addTo($to)
->getTransport();

$transport->sendMessage();
} finally {
$this->inlineTranslation->resume();
}
}
}

+ 25
- 0
src/app/code/MNM/RevocationForm/Model/MailInterface.php Voir le fichier

@@ -0,0 +1,25 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
namespace MNM\RevocationForm\Model;

/**
* Email from contact form
*
* @api
* @since 100.2.0
*/
interface MailInterface
{
/**
* Send email from contact form
*
* @param string $replyTo Reply-to email address
* @param array $variables Email template variables
* @return void
* @since 100.2.0
*/
public function send($replyTo, array $variables);
}

+ 50
- 0
src/app/code/MNM/RevocationForm/Observer/CheckCaptchaObserver.php Voir le fichier

@@ -0,0 +1,50 @@
<?php

namespace MNM\RevocationForm\Observer;

use Magento\Framework\Event\ObserverInterface;

class CheckCaptchaObserver implements ObserverInterface {

protected $_helper;
protected $_actionFlag;
protected $messageManager;
protected $_session;
protected $_urlManager;
protected $captchaStringResolver;
protected $redirect;

public function __construct(\Magento\Captcha\Helper\Data $helper,
\Magento\Framework\App\ActionFlag $actionFlag,
\Magento\Framework\Message\ManagerInterface $messageManager,
\Magento\Framework\Session\SessionManagerInterface $session,
\Magento\Framework\UrlInterface $urlManager,
\Magento\Framework\App\Response\RedirectInterface $redirect,
\Magento\Captcha\Observer\CaptchaStringResolver $captchaStringResolver
) {
$this->_helper = $helper;
$this->_actionFlag = $actionFlag;
$this->messageManager = $messageManager;
$this->_session = $session;
$this->_urlManager = $urlManager;
$this->redirect = $redirect;
$this->captchaStringResolver = $captchaStringResolver;
}

public function execute(\Magento\Framework\Event\Observer $observer) {
$formId = 'revocation_form'; // this form ID should matched the one defined in the layout xml
$captchaModel = $this->_helper->getCaptcha($formId);

$controller = $observer->getControllerAction();
if (!$captchaModel->isCorrect($this->captchaStringResolver->resolve($controller->getRequest(), $formId))) {
$controller->setCaptchaFalse(true);
/*$this->_actionFlag->set('', \Magento\Framework\App\Action\Action::FLAG_NO_DISPATCH, true);
$this->_session->setCustomerFormData($controller->getRequest()->getPostValue());
$url = $this->_urlManager->getUrl('captchaForm/index/index', ['_nosecret' => true]);
$controller->getResponse()->setRedirect($this->redirect->error($url));*/
}

return $this;
}

}

+ 18
- 0
src/app/code/MNM/RevocationForm/composer.json Voir le fichier

@@ -0,0 +1,18 @@
{
"name" : "MNM/RevocationForm",
"description" : "A revocation form",
"config" : {
"sort-packages" : true
},
"require" : {
"magento/framework" : "*"
},
"type" : "magento2-module",
"autoload": {
"files": [ "registration.php" ],
"psr-4": {
"MNM\\RevocationForm\\": ""
}
},
"version" : "1.0.0"
}

+ 44
- 0
src/app/code/MNM/RevocationForm/etc/adminhtml/system.xml Voir le fichier

@@ -0,0 +1,44 @@
<?xml version="1.0"?>
<!--
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Config:etc/system_file.xsd">
<system>
<section id="revocation" translate="label" type="text" sortOrder="100" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Revocation</label>
<tab>general</tab>
<resource>MNM_RevocationForm::revocation</resource>
<!--group id="cms" translate="label" type="text" sortOrder="40" showInDefault="1" showInWebsite="1" showInStore="1">
<label>CMS Options</label>
<field id="cms_category" translate="label comment" type="select" sortOrder="30" showInDefault="1" showInWebsite="1" showInStore="1" canRestore="1">
<label>Show in category</label>
<comment>Category, the form is shown under. Set this to display the chosen category in menu correct.</comment>
<source_model>Magento\Catalog\Model\Config\Source\Category</source_model>
</field>
</group-->
<group id="email" translate="label" type="text" sortOrder="50" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Email Options</label>
<field id="recipient_email" translate="label" type="text" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1" canRestore="1">
<label>Send Emails To</label>
</field>
<field id="sender_email_identity" translate="label" type="select" sortOrder="20" showInDefault="1" showInWebsite="1" showInStore="1" canRestore="1">
<label>Email Sender</label>
<source_model>Magento\Config\Model\Config\Source\Email\Identity</source_model>
</field>
<field id="email_template" translate="label comment" type="select" sortOrder="30" showInDefault="1" showInWebsite="1" showInStore="1" canRestore="1">
<label>Email Template</label>
<comment>Email template chosen based on theme fallback when "Default" option is selected.</comment>
<source_model>Magento\Config\Model\Config\Source\Email\Template</source_model>
</field>
<field id="email_customer_template" translate="label comment" type="select" sortOrder="30" showInDefault="1" showInWebsite="1" showInStore="1" canRestore="1">
<label>Email Customer Template</label>
<comment>Email template chosen based on theme fallback when "Default" option is selected.</comment>
<source_model>Magento\Config\Model\Config\Source\Email\Template</source_model>
</field>
</group>
</section>
</system>
</config>

+ 38
- 0
src/app/code/MNM/RevocationForm/etc/config.xml Voir le fichier

@@ -0,0 +1,38 @@
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Store:etc/config.xsd">
<default>
<customer>
<captcha>
<shown_to_logged_in_user>
<revocation_form>1</revocation_form>
</shown_to_logged_in_user>
<always_for>
<revocation_form>1</revocation_form>
</always_for>
</captcha>
</customer>
<captcha translate="label">
<frontend>
<areas>
<revocation_form>
<label>Widerrufs-Formular</label>
</revocation_form>
</areas>
</frontend>
</captcha>
<revocation>
<cms>
<!-- Better be chosable, but only root categories possible with catalog source category -->
<cms_category>85</cms_category>
</cms>
<email>
<recipient_email>
<![CDATA[wellness@spitzner.de]]>
</recipient_email>
<sender_email_identity>custom2</sender_email_identity>
<email_template>revocation_email_email_template</email_template>
<email_customer_template>revocation_email_email_customer_template</email_customer_template>
</email>
</revocation>
</default>
</config>

+ 18
- 0
src/app/code/MNM/RevocationForm/etc/di.xml Voir le fichier

@@ -0,0 +1,18 @@
<?xml version="1.0"?>
<!--
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<preference for="MNM\RevocationForm\Model\MailInterface" type="MNM\RevocationForm\Model\Mail" />
<preference for="MNM\RevocationForm\Model\ConfigInterface" type="MNM\RevocationForm\Model\Config" />
<type name="Magento\Config\Model\Config\TypePool">
<arguments>
<argument name="sensitive" xsi:type="array">
<item name="revocation/email/recipient_email" xsi:type="string">1</item>
</argument>
</arguments>
</type>
</config>

+ 11
- 0
src/app/code/MNM/RevocationForm/etc/email_templates.xml Voir le fichier

@@ -0,0 +1,11 @@
<?xml version="1.0"?>
<!--
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Email:etc/email_templates.xsd">
<template id="revocation_email_email_template" label="Revocation Form" file="submitted_form.html" type="html" module="MNM_RevocationForm" area="frontend"/>
<template id="revocation_email_email_customer_template" label="Revocation Customer Form" file="submitted_customer_form.html" type="html" module="MNM_RevocationForm" area="frontend"/>
</config>

+ 6
- 0
src/app/code/MNM/RevocationForm/etc/frontend/events.xml Voir le fichier

@@ -0,0 +1,6 @@
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
<event name="controller_action_predispatch_revocation_index_index">
<observer name="CheckRevocationFormObserver" instance="MNM\RevocationForm\Observer\CheckCaptchaObserver" />
</event>
</config>

+ 13
- 0
src/app/code/MNM/RevocationForm/etc/frontend/routes.xml Voir le fichier

@@ -0,0 +1,13 @@
<?xml version="1.0"?>
<!--
/**
* Copyright © 2016 Magento. All rights reserved. * See COPYING.txt for license details.
*/
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:App/etc/routes.xsd">
<router id="standard">
<route id="revocation" frontName="revocation">
<module name="MNM_RevocationForm" />
</route>
</router>
</config>

+ 8
- 0
src/app/code/MNM/RevocationForm/etc/module.xml Voir le fichier

@@ -0,0 +1,8 @@
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/Module/etc/module.xsd">
<module name="MNM_RevocationForm" setup_version="1.0.0">
<sequence>
<module name="Magento_Store"/>
</sequence>
</module>
</config>

+ 29
- 0
src/app/code/MNM/RevocationForm/i18n/de_DE.csv Voir le fichier

@@ -0,0 +1,29 @@
"Page not found.","Page not found."
"Thanks for contacting us with your comments and questions. We'll respond to you very soon.","Thanks for contacting us with your comments and questions. We'll respond to you very soon."
"An error occurred while processing your form. Please try again later.","An error occurred while processing your form. Please try again later."
"Name is missing","Name is missing"
"Comment is missing","Comment is missing"
"Invalid email address","Invalid email address"
"* Required Fields","* Required Fields"
"Write Us","Write Us"
"Jot us a note and we’ll get back to you as quickly as possible.","Jot us a note and we’ll get back to you as quickly as possible."
Name,Name
Email,Email
"Phone Number","Phone Number"
"What’s on your mind?","What’s on your mind?"
Submit,Submit
"Revocation Form","Widerrufsformular ausgefüllt"
"Name: %name","Name: %name"
"Email: %email","Email: %email"
"Phone Number: %telephone","Phone Number: %telephone"
"Comment: %comment","Comment: %comment"
"Contacts Section","Contacts Section"
Contacts,Contacts
"Contact Us","Contact Us"
"Enable Contact Us","Enable Contact Us"
"Email Options","Email Options"
"Send Emails To","Send Emails To"
"Email Sender","Email Sender"
"Email Template","Email Template"
"Email template chosen based on theme fallback when ""Default"" option is selected.","Email template chosen based on theme fallback when ""Default"" option is selected."
"Email Customer Template","Email Customer Template"

+ 29
- 0
src/app/code/MNM/RevocationForm/i18n/en_US.csv Voir le fichier

@@ -0,0 +1,29 @@
"Page not found.","Page not found."
"Thanks for contacting us with your comments and questions. We'll respond to you very soon.","Thanks for contacting us with your comments and questions. We'll respond to you very soon."
"An error occurred while processing your form. Please try again later.","An error occurred while processing your form. Please try again later."
"Name is missing","Name is missing"
"Comment is missing","Comment is missing"
"Invalid email address","Invalid email address"
"* Required Fields","* Required Fields"
"Write Us","Write Us"
"Jot us a note and we’ll get back to you as quickly as possible.","Jot us a note and we’ll get back to you as quickly as possible."
Name,Name
Email,Email
"Phone Number","Phone Number"
"What’s on your mind?","What’s on your mind?"
Submit,Submit
"Contact Form","Contact Form"
"Name: %name","Name: %name"
"Email: %email","Email: %email"
"Phone Number: %telephone","Phone Number: %telephone"
"Comment: %comment","Comment: %comment"
"Contacts Section","Contacts Section"
Contacts,Contacts
"Contact Us","Contact Us"
"Enable Contact Us","Enable Contact Us"
"Email Options","Email Options"
"Send Emails To","Send Emails To"
"Email Sender","Email Sender"
"Email Template","Email Template"
"Email template chosen based on theme fallback when ""Default"" option is selected.","Email template chosen based on theme fallback when ""Default"" option is selected."
"Email Customer Template","Email Customer Template"

+ 7
- 0
src/app/code/MNM/RevocationForm/registration.php Voir le fichier

@@ -0,0 +1,7 @@
<?php

\Magento\Framework\Component\ComponentRegistrar::register(
\Magento\Framework\Component\ComponentRegistrar::MODULE,
'MNM_RevocationForm',
__DIR__
);

+ 13
- 0
src/app/code/MNM/RevocationForm/view/frontend/email/submitted_customer_form.html Voir le fichier

@@ -0,0 +1,13 @@
<!--
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
-->
<!--@subject {{trans "Revocation Form"}} @-->

{{template config_path="design/email/header_template"}}

<p>{{trans "Vielen Dank für die Übermittlung Ihres Widerrufs. Wir werden uns schnellstmöglich bei Ihnen melden."}}</p>

{{template config_path="design/email/footer_template"}}

+ 70
- 0
src/app/code/MNM/RevocationForm/view/frontend/email/submitted_form.html Voir le fichier

@@ -0,0 +1,70 @@
<!--
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
-->
<!--@subject {{trans "Revocation Form"}} @-->
<!--@vars {
"var data.comment":"Comment",
"var data.email":"Sender Email",
"var data.name":"Sender Name",
"var data.telephone":"Sender Telephone"
} @-->

{{template config_path="design/email/header_template"}}

<table class="message-details">
<tr>
<td><strong>{{trans "Anrede"}}</strong></td>
<td>{{var data.salutation}}</td>
</tr>
<tr>
<td><strong>{{trans "Titel"}}</strong></td>
<td>{{var data.title}}</td>
</tr>
<tr>
<td><strong>{{trans "Name"}}</strong></td>
<td>{{var data.name}}</td>
</tr>
<tr>
<td><strong>{{trans "Firma"}}</strong></td>
<td>{{var data.company}}</td>
</tr>
<tr>
<td><strong>{{trans "Straße und Hausnummer"}}</strong></td>
<td>{{var data.address}}</td>
</tr>
<tr>
<td><strong>{{trans "PLZ"}}</strong></td>
<td>{{var data.zip}}</td>
</tr>
<tr>
<td><strong>{{trans "Ort"}}</strong></td>
<td>{{var data.city}}</td>
</tr>
<tr>
<td><strong>{{trans "Land"}}</strong></td>
<td>{{var data.country}}</td>
</tr>
<tr>
<td><strong>{{trans "Email"}}</strong></td>
<td>{{var data.email}}</td>
</tr>
<tr>
<td><strong>{{trans "Phone"}}</strong></td>
<td>{{var data.telephone}}</td>
</tr>
<tr>
<td><strong>{{trans "Grund für die Rücksendung"}}</strong></td>
<td>{{var data.reason}}</td>
</tr>
<tr>
<td><strong>{{trans "Bestellnummer"}}</strong></td>
<td>{{var data.ordernr}}</td>
</tr>
</table>
<p><strong>{{trans "Kommentar"}}:</strong></p>
<p>{{var data.comment}}</p>

{{template config_path="design/email/footer_template"}}

+ 50
- 0
src/app/code/MNM/RevocationForm/view/frontend/layout/revocation_index_index.xml Voir le fichier

@@ -0,0 +1,50 @@
<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="2columns-left" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<body>
<referenceBlock name="breadcrumbs">
<action method="addCrumb">
<argument name="crumbName" xsi:type="string">Home</argument>
<argument name="crumbInfo" xsi:type="array">
<item name="title" xsi:type="string">Startseite</item>
<item name="label" xsi:type="string">Startseite</item>
<item name="link" xsi:type="string">/</item>
</argument>
</action>
<action method="addCrumb">
<argument name="crumbName" xsi:type="string">Service</argument>
<argument name="crumbInfo" xsi:type="array">
<item name="title" xsi:type="string">Service</item>
<item name="label" xsi:type="string">Service</item>
</argument>
</action>
<action method="addCrumb">
<argument name="crumbName" xsi:type="string">Revocation</argument>
<argument name="crumbInfo" xsi:type="array">
<item name="title" xsi:type="string">Widerrufsformular</item>
<item name="label" xsi:type="string">Widerrufsformular</item>
</argument>
</action>
</referenceBlock>
<referenceContainer name="content">
<block class="MNM\RevocationForm\Block\RevocationForm" name="mnm.revocationform" template="MNM_RevocationForm::form.phtml" cacheable="false">
<container name="form.additional.info" label="Form Additional Info">
<block class="Magento\Captcha\Block\Captcha" name="captcha" after="-" cacheable="false">
<action method="setFormId">
<argument name="formId" xsi:type="string">revocation_form</argument>
</action>
<action method="setImgWidth">
<argument name="width" xsi:type="string">230</argument>
</action>
<action method="setImgHeight">
<argument name="width" xsi:type="string">50</argument>
</action>
</block>
</container>
</block>
</referenceContainer>
<referenceContainer name="sidebar.main">
<block class="Magento\Catalog\Block\Navigation" name="catalog.leftnav" before="-" template="Magento_Catalog::navigation/left.phtml"/>
</referenceContainer>
<referenceBlock name="sale.reorder.sidebar" remove="true"/>
</body>
</page>

+ 203
- 0
src/app/code/MNM/RevocationForm/view/frontend/templates/form.phtml Voir le fichier

@@ -0,0 +1,203 @@
<?php
/**
* Copyright © 2015 Magento. All rights reserved.
* See COPYING.txt for license details.
*/

// @codingStandardsIgnoreFile

?>
<form class="form revocation"
action=""
id="revocation-form"
method="post"
data-hasrequired="<?php echo __('* Required Fields') ?>"
data-mage-init='{"validation":{}}'>
<fieldset class="fieldset">
<h1 class="legend"><?= __('Widerrufsformular') ?></h1>
<p>
<?= $block->escapeHtml(__('Mit folgendem Formular können Sie den Widerruf Ihres Kaufs erklären. Direkt nach dem Absenden des Formulars wird Ihnen eine Kopie Ihrer Nachricht an die von Ihnen angegebene E-Mail-Adresse gesandt. Nach Erhalt der Waren haben Sie 14 Tage lang die Möglichkeit Ihre Bestellung zu widerrufen und die erhaltenen Produkte zurückzusenden. Sie können Ihre Artikel binnen vierzehn Tagen, ohne Angabe von Gründen, an uns zurücksenden. Wenn Sie diesen Service in Anspruch nehmen, beachten Sie bitte Folgendes:')) ?><br>
</p>
<p>
<?= $block->escapeHtml(__('Vom Widerruf ausgeschlossen sind Produkte, deren Versiegelung bereits geöffnet und die bereits benutzt wurden.')) ?><br>
</p>
<p>
<?= $block->escapeHtml(__('Bei Rücksendung von Waren aufgrund von Gewährleistungsansprüchen erfolgt eine Nachbesserung durch Umtausch oder Ersatzlieferung von mangelfreier Ware. Bitte geben Sie hier im Formular den Reklamationsgrund für Ihre Rücksendung an.')) ?><br>
</p>
<fieldset class="fieldset row">
<div class="fields col-md-6">
<div class="field name required">
<label class="label" for="name"><span><?php echo __('Anrede') ?></span></label>
<div class="control">
<select
name="salutation"
id="salutation"
class="input-text required-entry uniform"
data-validate="{required:true}">
<option disabled="disabled">Bitte wählen</option>
<option<?= $block->getPostVar('salutation')=='Frau' ? ' selected="selected"' : '' ?>>Frau</option>
<option<?= $block->getPostVar('salutation')=='Herr' ? ' selected="selected"' : '' ?>>Herr</option>
<option<?= $block->getPostVar('salutation')=='Firma' ? ' selected="selected"' : '' ?>>Firma</option>
</select>
</div>
</div>
</div>
</fieldset>
<fieldset class="fieldset row">
<div class="fields col-md-6">
<div class="field name">
<label class="label" for="name"><span><?php echo __('Titel') ?></span></label>
<div class="control">
<select
name="title"
id=""title""
class="input-text uniform">
<option></option>
<option<?= $block->getPostVar('title')=='Dr' ? ' selected="selected"' : '' ?>>Dr</option>
<option<?= $block->getPostVar('title')=='Prof' ? ' selected="selected"' : '' ?>>Prof</option>
<option<?= $block->getPostVar('title')=='Prof Dr' ? ' selected="selected"' : '' ?>>Prof Dr</option>
</select>
</div>
</div>
</div>
<div class="fields col-md-6">
<div class="field name required">
<label class="label" for="name"><span><?php echo __('Name') ?></span></label>
<div class="control">
<input name="name" id="name" title="<?php echo __('Name') ?>" value="<?php echo $block->escapeHtml($block->getPostVar('name') ? $block->getPostVar('name') : $this->helper('Magento\Contact\Helper\Data')->getUserName()) ?>" class="input-text" type="text" data-validate="{required:true}"/>
</div>
</div>
</div>
</fieldset>
<fieldset class="fieldset row">
<div class="fields col-md-6">
<div class="field company">
<label class="label" for="company"><span><?php echo __('Firma') ?></span></label>
<div class="control">
<input name="company" id="company" title="<?php echo __('Firma') ?>" value="<?= $block->escapeHtml($block->getPostVar('company')) ?>" class="input-text" type="text"/>
</div>
</div>
</div>
<div class="fields col-md-6">
<div class="field address required">
<label class="label" for="address"><span><?php echo __('Straße und Hausnummer') ?></span></label>
<div class="control">
<input name="address" id="address" title="<?php echo __('Straße und Hausnummer') ?>" value="<?= $block->escapeHtml($block->getPostVar('address')) ?>" class="input-text" type="text" data-validate="{required:true}"/>
</div>
</div>
</div>
</fieldset>
<fieldset class="fieldset row">
<div class="fields col-md-2">
<div class="field zip required">
<label class="label" for="zip"><span><?php echo __('PLZ') ?></span></label>
<div class="control">
<input name="zip" id="zip" title="<?php echo __('PLZ') ?>" value="<?= $block->escapeHtml($block->getPostVar('zip')) ?>" class="input-text" type="text" data-validate="{required:true}"/>
</div>
</div>
</div>
<div class="fields col-md-4">
<div class="field city required">
<label class="label" for="city"><span><?php echo __('Ort') ?></span></label>
<div class="control">
<input name="city" id="city" title="<?php echo __('Ort') ?>" value="<?= $block->escapeHtml($block->getPostVar('city')) ?>" class="input-text" type="text" data-validate="{required:true}"/>
</div>
</div>
</div>
<div class="fields col-md-6">
<div class="field country required">
<label class="label" for="country"><span><?php echo __('Land') ?></span></label>
<div class="control">
<select name="country" id="country" class="validate-select" title="Land">
<option value=""> </option>
<option value="Belgien"<?= $block->getPostVar('country')=='Belgien' ? ' selected="selected"' : '' ?>>Belgien</option>
<option value="Deutschland"<?= $block->getPostVar('country') == '' || $block->getPostVar('country') == 'Deutschland' ? ' selected="selected"' : '' ?>>Deutschland</option>
<option value="Frankreich"<?= $block->getPostVar('country')=='Frankreich' ? ' selected="selected"' : '' ?>>Frankreich</option>
<option value="Italien"<?= $block->getPostVar('country')=='Italien' ? ' selected="selected"' : '' ?>>Italien</option>
<option value="Luxemburg"<?= $block->getPostVar('country')=='Luxemburg' ? ' selected="selected"' : '' ?>>Luxemburg</option>
<option value="Niederlande"<?= $block->getPostVar('country')=='Niederlande' ? ' selected="selected"' : '' ?>>Niederlande</option>
<option value="Österreich"<?= $block->getPostVar('country')=='Österreich' ? ' selected="selected"' : '' ?>>Österreich</option>
<option value="Spanien"<?= $block->getPostVar('country')=='Spanien' ? ' selected="selected"' : '' ?>>Spanien</option>
</select>
</div>
</div>
</div>
</fieldset>
<fieldset class="fieldset row">
<div class="fields col-md-6">
<div class="field email required">
<label class="label" for="email"><span><?php echo __('Email') ?></span></label>
<div class="control">
<input name="email" id="email" title="<?php echo __('Email') ?>" value="<?php echo $block->escapeHtml($block->getPostVar('email') ? $block->getPostVar('email') : $this->helper('Magento\Contact\Helper\Data')->getUserEmail()) ?>" class="input-text" type="email" data-validate="{required:true, 'validate-email':true}"/>
</div>
</div>
</div>
<div class="fields col-md-6">
<div class="field telephone">
<label class="label" for="telephone"><span><?php echo __('Phone Number') ?></span></label>
<div class="control">
<input name="telephone" id="telephone" title="<?php echo __('Phone Number') ?>" value="<?= $block->escapeHtml($block->getPostVar('telephone')) ?>" class="input-text" type="text" />
</div>
</div>
</div>
</fieldset>
<fieldset class="fieldset row">
<div class="fields col-md-6">
<div class="field reason">
<label class="label" for="reason"><span><?php echo __('Grund für die Rücksendung') ?></span></label>
<div class="control">
<input name="reason" id="reason" title="<?php echo __('Grund für die Rücksendung') ?>" value="<?= $block->escapeHtml($block->getPostVar('reason')) ?>" class="input-text" type="text"/>
</div>
</div>
</div>
</fieldset>
<fieldset class="fieldset row">
<div class="fields col-md-6">
<div class="field ordernr required">
<label class="label" for="ordernr"><span><?php echo __('Bestellnummer (finden Sie in Ihrer Bestellbestätigung, die Sie per E-Mail erhalten haben)') ?></span></label>
<div class="control">
<input name="ordernr" id="ordernr" title="<?php echo __('Bestellnummer (finden Sie in Ihrer Bestellbestätigung, die Sie per E-Mail erhalten haben)') ?>" value="<?= $block->escapeHtml($block->getPostVar('ordernr')) ?>" class="input-text" type="text" data-validate="{required:true}"/>
</div>
</div>
</div>
</fieldset>
<fieldset class="fieldset row">
<div class="fields col-md-12">
<div class="field comment required">
<label class="label" for="comment"><span><?php echo __('Kommentar') ?></span></label>
<div class="control">
<textarea name="comment" id="comment" title="<?php echo __('Kommentar') ?>" class="input-text" cols="5" rows="8" data-validate="{required:true}"><?= $block->escapeHtml($block->getPostVar('comment') ? $block->getPostVar('comment') : __('Hiermit widerrufe(n) ich/wir den von mir/uns abgeschlossenen Vertrag über den Kauf der folgenden Waren:')) ?></textarea>
</div>
</div>
<?php echo $block->getChildHtml('form.additional.info'); ?>
</div>
</fieldset>
</fieldset>

<small class="required">* <?= __('Pflichtfelder') ?></small>
<br>
<br>

<div class="actions-toolbar">
<div class="primary">
<input type="hidden" name="hideit" id="hideit" value="" />
<button type="submit" title="<?php echo __('Submit') ?>" class="action submit primary">
<span><?php echo __('Submit') ?></span>
</button>
</div>
</div>
</form>

<br>
<br>
<br>
<p>
<?= __('Sie können Ihren Widerruf unter Angabe Ihrer Kontaktdaten, der Bestellnummer und einer Auflistung der von Ihnen zurückzusendenden Ware postalisch, per Fax oder per E-Mail an uns richten:') ?>
</p>
<p>
W. Spitzner Arzneimittelfabrik GmbH<br>
Postfach 763<br>
76261 Ettlingen
</p>
<p>E-Mail: kundenservice@spitzner.de</p>
<p>Fax: +49 (0) 72 43 1 06 87 87</p>

+ 35
- 0
src/app/code/MNM/Spitzner/Block/Info/Debitpayment.php Voir le fichier

@@ -0,0 +1,35 @@
<?php

//MNM: added " ?? ''" in row 27

/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
namespace MNM\Spitzner\Block\Info;

/**
* Block for Bank Transfer payment generic info
*
* @api
* @since 100.0.2
*/
class Debitpayment extends \Threepartment\Debitpayment\Block\Info\Debitpayment
{
public function getDetails(){
$info = $this->getInfo()->getAdditionalInformation();
if(is_array($info)){
if(isset($info['method']) && $info['method']=='debitpayment'){
return array(
'bank_account_owner'=>$info['additional_data']['bank_account_owner'],
'iban'=>$info['additional_data']['iban'],
'bic'=>$info['additional_data']['bic'],
'bank_company'=>$info['additional_data']['bank_company'] ?? ''
);
}
}
return;

}
}


+ 66
- 0
src/app/code/MNM/Spitzner/Block/Magento/Customer/Widget/Name.php Voir le fichier

@@ -0,0 +1,66 @@
<?php

namespace MNM\Spitzner\Block\Magento\Customer\Widget;

use Magento\Customer\Api\AddressMetadataInterface;
use Magento\Customer\Api\CustomerMetadataInterface;
use Magento\Customer\Api\Data\CustomerInterface;
use Magento\Customer\Helper\Address as AddressHelper;
use Magento\Customer\Model\Options;
use Magento\Framework\View\Element\Template\Context;

/**
* Widget for showing customer name.
*
* @method CustomerInterface getObject()
* @method Name setObject(CustomerInterface $customer)
*
* @SuppressWarnings(PHPMD.DepthOfInheritance)
*/
class Name extends \Magento\Customer\Block\Widget\Name
{
/**
* Retrieve name prefix drop-down options
*
* @return array|bool
*/
public function getPrefixOptions()
{
$prefixOptions = $this->options->getNamePrefixOptions();

if ($this->getObject() && !empty($prefixOptions)) {
$prefixOption = $this->getObject()->getPrefix();
//MNM - check before trim
if ($prefixOption !== null) {
//MNM - check before trim
$oldPrefix = $this->escapeHtml(trim($prefixOption));
if ($prefixOption !== null && !isset($prefixOptions[$oldPrefix]) && !isset($prefixOptions[$prefixOption])) {
$prefixOptions[$oldPrefix] = $oldPrefix;
}
}
}
return $prefixOptions;
}

/**
* Retrieve name suffix drop-down options
*
* @return array|bool
*/
public function getSuffixOptions()
{
$suffixOptions = $this->options->getNameSuffixOptions();
if ($this->getObject() && !empty($suffixOptions)) {
$suffixOption = $this->getObject()->getSuffix();
//MNM - check before trim
if ($suffixOption !== null) {
//MNM - check before trim
$oldSuffix = $this->escapeHtml(trim($suffixOption));
if ($suffixOption !== null && !isset($suffixOptions[$oldSuffix]) && !isset($suffixOptions[$suffixOption])) {
$suffixOptions[$oldSuffix] = $oldSuffix;
}
}
}
return $suffixOptions;
}
}

+ 30
- 0
src/app/code/MNM/Spitzner/Block/Magento/Review/Adminhtml/Edit/Form.php Voir le fichier

@@ -0,0 +1,30 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/

namespace MNM\Spitzner\Block\Magento\Review\Adminhtml\Edit;

/**
* Adminhtml Review Edit Form
*/
class Form extends \Magento\Review\Block\Adminhtml\Edit\Form
{
/**
* Prepare edit review form
*
* @return $this
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
*/
protected function _prepareForm()
{
$return = parent::_prepareForm();

//set fields to be non required
$this->getForm()->getElements()->searchById('review_details')->getElements()->searchById('title')->setRequired(false);
$this->getForm()->getElements()->searchById('review_details')->getElements()->searchById('detail')->setRequired(false);

return $return;
}
}

+ 236
- 0
src/app/code/MNM/Spitzner/Block/Topmenu.php Voir le fichier

@@ -0,0 +1,236 @@
<?php

//MNM - added classes and data attribute for menu to make breadcrump work (see https://github.com/magento/magento2/issues/14987)

namespace MNM\Spitzner\Block;

class Topmenu extends \Smartwave\Megamenu\Block\Topmenu
{
/**
* Catalog layer
*
* @var \Magento\Catalog\Model\Layer
*/
protected $_catalogLayer;

public function __construct(
\Magento\Framework\View\Element\Template\Context $context,
\Magento\Catalog\Helper\Category $categoryHelper,
\Smartwave\Megamenu\Helper\Data $helper,
\Magento\Catalog\Model\Indexer\Category\Flat\State $categoryFlatState,
\Magento\Catalog\Model\CategoryFactory $categoryFactory,
\Magento\Theme\Block\Html\Topmenu $topMenu,
\Magento\Cms\Model\Template\FilterProvider $filterProvider,
\Magento\Cms\Model\BlockFactory $blockFactory,
\Magento\Catalog\Model\Layer\Resolver $layerResolver
) {
//MNM
$this->_catalogLayer = $layerResolver->get();
//MNM
parent::__construct(
$context,
$categoryHelper,
$helper,
$categoryFlatState,
$categoryFactory,
$topMenu,
$filterProvider,
$blockFactory);
}

//MNM - added $catPath
public function getSubmenuItemsHtml($children, $level = 1, $max_level = 0, $column_width=12, $menu_type = 'fullwidth', $columns = null, $catPath = '')
{
$html = '';

if(!$max_level || ($max_level && $max_level == 0) || ($max_level && $max_level > 0 && $max_level-1 >= $level)) {
$column_class = "";
if($level == 1 && $columns && ($menu_type == 'fullwidth' || $menu_type == 'staticwidth')) {
$column_class = "col-md-".$column_width." ";
$column_class .= "mega-columns columns".$columns;
}
$html = '<ul class="subchildmenu '.$column_class.'">';
foreach($children as $child) {
$cat_model = $this->getCategoryModel($child->getId());

$sw_menu_hide_item = $cat_model->getData('sw_menu_hide_item');

if (!$sw_menu_hide_item) {
$sub_children = $this->getActiveChildCategories($child);

$sw_menu_cat_label = $cat_model->getData('sw_menu_cat_label');
$sw_menu_icon_img = $cat_model->getData('sw_menu_icon_img');
$sw_menu_font_icon = $cat_model->getData('sw_menu_font_icon');

//MNM - set myPath
$myPath = $catPath.'-'.$child->getId();

$item_class = 'level'.$level.' category-item nav-'.$myPath.' ';
//MNM
if(count($sub_children) > 0)
$item_class .= 'parent ';
$html .= '<li class="ui-menu-item '.$item_class.'">';
if(count($sub_children) > 0) {
$html .= '<div class="open-children-toggle'.($this->isCategoryActive($child) ? ' active' : '').'"></div>';
}
if($level == 1 && $sw_menu_icon_img) {
$html .= '<div class="menu-thumb-img"><a class="menu-thumb-link" href="'.$this->_categoryHelper->getCategoryUrl($child).'"><img src="' . $this->_helper->getBaseUrl().'catalog/category/' . $sw_menu_icon_img . '" alt="'.$child->getName().'"/></a></div>';
}
$html .= '<a href="'.$this->_categoryHelper->getCategoryUrl($child).'" title="'.$child->getName().'"'.($this->isCategoryActive($child) ? ' class="ui-state-active"' : '').'>';
if ($level > 1 && $sw_menu_icon_img)
$html .= '<img class="menu-thumb-icon" src="' . $this->_helper->getBaseUrl().'catalog/category/' . $sw_menu_icon_img . '" alt="'.$child->getName().'"/>';
elseif($sw_menu_font_icon)
$html .= '<em class="menu-thumb-icon '.$sw_menu_font_icon.'"></em>';
$html .= '<span>'.$child->getName();
if($sw_menu_cat_label)
$html .= '<span class="cat-label cat-label-'.$sw_menu_cat_label.'">'.$this->_megamenuConfig['cat_labels'][$sw_menu_cat_label].'</span>';
$html .= '</span></a>';
if(count($sub_children) > 0) {
//MNM
$html .= $this->getSubmenuItemsHtml($sub_children, $level+1, $max_level, $column_width, $menu_type, null, $myPath);
}
$html .= '</li>';
}
}
$html .= '</ul>';
}

return $html;
}

public function getMegamenuHtml()
{
$html = '';

$categories = $this->getStoreCategories(true,false,true);

$this->_megamenuConfig = $this->_helper->getConfig('sw_megamenu');

$max_level = $this->_megamenuConfig['general']['max_level'];
$html .= $this->getCustomBlockHtml('before');
foreach($categories as $category) {
if (!$category->getIsActive()) {
continue;
}

$cat_model = $this->getCategoryModel($category->getId());

$sw_menu_hide_item = $cat_model->getData('sw_menu_hide_item');

if(!$sw_menu_hide_item) {
$children = $this->getActiveChildCategories($category);
$sw_menu_cat_label = $cat_model->getData('sw_menu_cat_label');
$sw_menu_icon_img = $cat_model->getData('sw_menu_icon_img');
$sw_menu_font_icon = $cat_model->getData('sw_menu_font_icon');
$sw_menu_cat_columns = $cat_model->getData('sw_menu_cat_columns');
$sw_menu_float_type = $cat_model->getData('sw_menu_float_type');

if(!$sw_menu_cat_columns){
$sw_menu_cat_columns = 4;
}

$menu_type = $cat_model->getData('sw_menu_type');
if(!$menu_type)
$menu_type = $this->_megamenuConfig['general']['menu_type'];

$custom_style = '';
if($menu_type=="staticwidth")
$custom_style = ' style="width: 500px;"';

$sw_menu_static_width = $cat_model->getData('sw_menu_static_width');
if($menu_type=="staticwidth" && $sw_menu_static_width)
$custom_style = ' style="width: '.$sw_menu_static_width.';"';

$item_class = 'level0 ';
$item_class .= $menu_type.' ';

$menu_top_content = $cat_model->getData('sw_menu_block_top_content');
$menu_left_content = $cat_model->getData('sw_menu_block_left_content');
$menu_left_width = $cat_model->getData('sw_menu_block_left_width');
if(!$menu_left_content || !$menu_left_width)
$menu_left_width = 0;
$menu_right_content = $cat_model->getData('sw_menu_block_right_content');
$menu_right_width = $cat_model->getData('sw_menu_block_right_width');
if(!$menu_right_content || !$menu_right_width)
$menu_right_width = 0;
$menu_bottom_content = $cat_model->getData('sw_menu_block_bottom_content');
if($sw_menu_float_type)
$sw_menu_float_type = 'fl-'.$sw_menu_float_type.' ';
if(count($children) > 0 || (($menu_type=="fullwidth" || $menu_type=="staticwidth") && ($menu_top_content || $menu_left_content || $menu_right_content || $menu_bottom_content)))
$item_class .= 'parent ';
//MNM
$html .= '<li class="ui-menu-item '.$item_class.$sw_menu_float_type.' nav-'.$category->getId().' category-item">';
if(count($children) > 0) {
$html .= '<div class="open-children-toggle'.($this->isCategoryActive($category) ? ' active' : '').'"></div>';
}
$html .= '<a href="'.$this->_categoryHelper->getCategoryUrl($category).'" class="level-top'.($this->isCategoryActive($category) ? ' ui-state-active' : '').'" title="'.$category->getName().'">';
if ($sw_menu_icon_img)
$html .= '<img class="menu-thumb-icon" src="' . $this->_helper->getBaseUrl().'catalog/category/' . $sw_menu_icon_img . '" alt="'.$category->getName().'"/>';
elseif($sw_menu_font_icon)
$html .= '<em class="menu-thumb-icon '.$sw_menu_font_icon.'"></em>';
$html .= '<span>'.$category->getName().'</span>';
if($sw_menu_cat_label)
$html .= '<span class="cat-label cat-label-'.$sw_menu_cat_label.'">'.$this->_megamenuConfig['cat_labels'][$sw_menu_cat_label].'</span>';
$html .= '</a>';
if(count($children) > 0 || (($menu_type=="fullwidth" || $menu_type=="staticwidth") && ($menu_top_content || $menu_left_content || $menu_right_content || $menu_bottom_content))) {
$html .= '<div class="level0 submenu'.($this->isCategoryActive($category) ? ' opened' : '').'"'.$custom_style.'>';
if(($menu_type=="fullwidth" || $menu_type=="staticwidth")) {
$html .= '<div class="container">';
}
if(($menu_type=="fullwidth" || $menu_type=="staticwidth") && $menu_top_content) {
$html .= '<div class="menu-top-block">'.$this->getBlockContent($menu_top_content).'</div>';
}
if(count($children) > 0 || (($menu_type=="fullwidth" || $menu_type=="staticwidth") && ($menu_left_content || $menu_right_content))) {
$html .= '<div class="row">';
if(($menu_type=="fullwidth" || $menu_type=="staticwidth") && $menu_left_content && $menu_left_width > 0) {
$html .= '<div class="menu-left-block col-md-'.$menu_left_width.'">'.$this->getBlockContent($menu_left_content).'</div>';
}
//MNM
$html .= $this->getSubmenuItemsHtml($children, 1, $max_level, 12-$menu_left_width-$menu_right_width, $menu_type, $sw_menu_cat_columns, $category->getId());
if(($menu_type=="fullwidth" || $menu_type=="staticwidth") && $menu_right_content && $menu_right_width > 0) {
$html .= '<div class="menu-right-block col-md-'.$menu_right_width.'">'.$this->getBlockContent($menu_right_content).'</div>';
}
$html .= '</div>';
}
if(($menu_type=="fullwidth" || $menu_type=="staticwidth") && $menu_bottom_content) {
$html .= '<div class="menu-bottom-block">'.$this->getBlockContent($menu_bottom_content).'</div>';
}
if(($menu_type=="fullwidth" || $menu_type=="staticwidth")) {
$html .= '</div>';
}
$html .= '</div>';
}
$html .= '</li>';
}
}
$html .= $this->getCustomBlockHtml('after');

return $html;
}

//MNM
/**
* Check activity of category
*
* @param \Magento\Framework\DataObject $category
* @return bool
*/
public function isCategoryActive($category)
{
if ($this->getCurrentCategory()) {
return in_array($category->getId(), $this->getCurrentCategory()->getPathIds());
}
return false;
}

/**
* Enter description here...
*
* @return Category
*/
public function getCurrentCategory()
{
return $this->_catalogLayer->getCurrentCategory();
}
//MNM
}

+ 51
- 0
src/app/code/MNM/Spitzner/Console/ExportOrders.php Voir le fichier

@@ -0,0 +1,51 @@
<?php

namespace MNM\Spitzner\Console;

use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use MNM\Spitzner\Cron\ExportOrders as ExportOrdersCron;

/**
* Class SomeCommand
*/
class ExportOrders extends Command
{
protected $export;

public function __construct(ExportOrdersCron $export)
{
$this->export = $export;

parent::__construct();
}
/**
* @inheritDoc
*/
protected function configure()
{
$this->setName('spitzner:export');
$this->setDescription('Run order export export.');

parent::configure();
}

/**
* Execute the command
*
* @param InputInterface $input
* @param OutputInterface $output
*
* @return null|int
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$this->export->execute();/*

$output->writeln('<info>Success Message.</info>');
$output->writeln('<error>An error encountered.</error>');
$output->writeln('<comment>Some Comment.</comment>');*/
}
}

+ 130
- 0
src/app/code/MNM/Spitzner/Controller/Cart/Add.php Voir le fichier

@@ -0,0 +1,130 @@
<?php
/**
* Copied from \Magebees\Ajaxaddtocart\Controller\Cart\Add
* to show success message on product detail page
*/
namespace MNM\Spitzner\Controller\Cart;

/**
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
*/
class Add extends \Magebees\Ajaxaddtocart\Controller\Cart\Add
{
public function execute()
{
$popup_block= $this->_objectManager->create('Magebees\Ajaxaddtocart\Block\Popup');
$config=$popup_block->getConfig();
if ($config['enable']==1) {
if (!$this->_formKeyValidator->validate($this->getRequest())) {
return $this->resultRedirectFactory->create()->setPath('*/*/');
}

$params = $this->getRequest()->getParams();
try {
if (isset($params['qty'])) {
$filter = new \Zend_Filter_LocalizedToNormalized(
['locale' => $this->_objectManager->get('Magento\Framework\Locale\ResolverInterface')->getLocale()]
);
$params['qty'] = $filter->filter($params['qty']);
}
$product = $this->_initProduct();
/** check whether display popup or not*/
$productId = (int)$this->getRequest()->getParam('product');
$related = $this->getRequest()->getParam('related_product');
$upsell=$this->getRequest()->getParam('upsell_product');
$crosssell=$this->getRequest()->getParam('crosssell_product');
/**
* Check product availability
*/
if (!$product) {
return $this->goBack();
}

$this->cart->addProduct($product, $params);
if (!empty($related)) {
$this->cart->addProductsByIds(explode(',', $related));
}
$this->cart->save();

/**
* dispatch event [events.xml] after add to cart product and display confirmation content in popup
*/
$this->_eventManager->dispatch(
'ajaxcheckout_cart_add_product_complete',
['product' => $product, 'request' => $this->getRequest(), 'response' => $this->getResponse()]
);
//MNM - copy (and modified) from \Magento\Checkout\Controller\Cart\Add to have message on product detail page
if (!$this->_checkoutSession->getNoCartRedirect(true)) {
if (!$this->cart->getQuote()->getHasError()) {
if ($this->_scopeConfig->isSetFlag(
'checkout/cart/redirect_to_cart',
\Magento\Store\Model\ScopeInterface::SCOPE_STORE)) {
$message = __(
'You added %1 to your shopping cart.',
$product->getName()
);
$this->messageManager->addSuccessMessage($message);
} else {
$this->messageManager->addComplexSuccessMessage(
'addCartSuccessMessage',
[
'product_name' => $product->getName(),
'cart_url' => $this->_url->getUrl('checkout/cart', ['_secure' => true]),
]
);
}
}
// return $this->goBack(null, $product);
}
//MNM
if ($this->getRequest()->isAjax()) {
return;
}

if (!$this->_checkoutSession->getNoCartRedirect(true)) {
if (!$this->cart->getQuote()->getHasError()) {
/* $message = __(
'You added %1 to your shopping cart.',
$product->getName()
);
$this->messageManager->addSuccessMessage($message);*/
}
return $this->goBack(null, $product);
}
} catch (\Magento\Framework\Exception\LocalizedException $e) {
if (preg_match('/requested/', $e->getMessage())) {
$result['popup_content'] = $e->getMessage();
$result['error'] = true;
return $this->getResponse()->representJson($this->_objectManager->get('Magento\Framework\Json\Helper\Data')->jsonEncode($result));
}
$url = $this->_checkoutSession->getRedirectUrl(true);

/* set below condition if in response product page url then display product content in popup */
if ($url) {
$this->getResponse()->setRedirect($url.'?options=ajax');
}
if (!$url) {
$cartUrl = $this->_objectManager->get('Magento\Checkout\Helper\Cart')->getCartUrl();
$url = $this->_redirect->getRedirectUrl($cartUrl);
}

return $this->goBack($url);
} catch (\Exception $e) {
$this->messageManager->addException($e, __('We can\'t add this item to your shopping cart right now.'));
$this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
return $this->goBack();
}
} else {
return parent::execute();
}
}
}

+ 40
- 0
src/app/code/MNM/Spitzner/Cron/ClearCaches.php Voir le fichier

@@ -0,0 +1,40 @@
<?php

namespace MNM\Spitzner\Cron;
use Psr\Log\LoggerInterface;
use Magento\Framework\App\Cache\TypeListInterface;
use Magento\Framework\App\Cache\Frontend\Pool;
class ClearCaches {
protected $cacheTypeList;
protected $cacheFrontendPool;
protected $logger;
public function __construct(TypeListInterface $cacheTypeList, Pool $cacheFrontendPool, LoggerInterface $logger)
{
$this->cacheTypeList = $cacheTypeList;
$this->cacheFrontendPool = $cacheFrontendPool;
$this->logger = $logger;
}
public function execute()
{
/* get all types of cache in system */
$allTypes = array_keys($this->cacheTypeList->getTypes());
/* clean */
foreach ($allTypes as $type)
{
$this->cacheTypeList->cleanType($type);
}
/* flush */
foreach ($this->cacheFrontendPool as $cacheFrontend)
{
$cacheFrontend->getBackend()->clean();
}
$this->logger->info('MNM\Spitzner - ClearCaches - done');
}
}

+ 367
- 0
src/app/code/MNM/Spitzner/Cron/ExportOrders.php Voir le fichier

@@ -0,0 +1,367 @@
<?php

namespace MNM\Spitzner\Cron;

use Psr\Log\LoggerInterface;
use MNM\Spitzner\Model\ExportLogEntryFactory;
use Magento\Sales\Model\OrderFactory;
use Magento\Framework\Filesystem\DirectoryList;
use Magento\Customer\Api\CustomerRepositoryInterface;
use Magento\Catalog\Api\ProductRepositoryInterface;

class ExportOrders {
const STORE_ID = 1;

CONST ORIGINAL_CONTRACT = "HP-PT-001";

private $payment_mapping = array(
'debitpayment' => 'ZS26',
'banktransfer' => 'ZB24',
'paypal_express' => 'ZB95');

protected $logger;
protected $exportLogEntryFactory;
protected $orderFactory;
protected $directoryList;
protected $customerRepository;
protected $productRepository;

public function __construct(LoggerInterface $logger,
ExportLogEntryFactory $exportLogEntryFactory,
OrderFactory $orderFactory,
DirectoryList $dir,
CustomerRepositoryInterface $cri,
ProductRepositoryInterface $pri)
{
$this->logger = $logger;
$this->exportLogEntryFactory = $exportLogEntryFactory;
$this->orderFactory = $orderFactory;
$this->directoryList = $dir;
$this->customerRepository = $cri;
$this->productRepository = $pri;
}

public function execute()
{
$interface_path = $this->directoryList->getRoot().'/export/';
$export_path = $interface_path.'copy/';
$file_name = date("YmdHis") . '_orders_spitzner.csv';
$file_path = $export_path . $file_name;
$new_last_exported_id = 0;
$lastId = 0;

$exportLogEntrys = $this->exportLogEntryFactory->create()->getCollection()
->setPageSize(1)
->setOrder('exportlog_id', 'DESC');

$data = $exportLogEntrys->getFirstItem();

if($data->getId())
{
$lastId = $data->getLastExportedOrderId();

$orders = $this->orderFactory->create()->getCollection()
->addFieldToSelect('*')
->addFieldToFilter('entity_id', ['gt' => $lastId]);

if($orders->count())
{
$file_pointer = fopen($file_path, "w+");
if (!$file_pointer)
{
$this->logger->error('MNM\Spitzner - Exporting orders - unable to write export file');
return;
}

$this->write_csv_head_row($file_pointer);

foreach ($orders as $order) {
$new_last_exported_id = $this->write_order($order, $file_pointer);
}

if ($new_last_exported_id > 0)
{
//save last saved
$entry = $this->exportLogEntryFactory->create();
$entry->setData([
'exported_at' => date('Y-m-d H:i:s'),
'last_exported_order_id' => $new_last_exported_id]);
$entry->save();
}

fclose($file_pointer);
if(!copy($file_path, $interface_path.$file_name))
{
$this->logger->error('MNM\Spitzner - Exporting orders - Could not copy file '.$file_path.' to '.$interface_path.$file_name);
}

if($lastId < $new_last_exported_id)
{
$this->logger->info('MNM\Spitzner - Exporting orders - from '.$lastId.' to '.$new_last_exported_id.' into '.$interface_path.$file_name);
}
}
}
}

protected function write_order($order, $file_pointer)
{
$increment_id = $order->getIncrementId();

$this->logger->info('MNM\Spitzner - Exporting orders - exporting order with ID ' . $increment_id);

/* customer information */
$customer = $order->getCustomer();
if($customer)
{
$customer_id = $customer->getCustomerNumber() ?? ''; // Spitzner Kundennummer
$customer_external_id = $customer->getId(); // Magento Kundennummer
$email = empty($customer->getEmail()) ? $order->getCustomerEmail() : $customer->getEmail();
$day_of_birth = date('Y-m-d', strtotime($customer->getDob()));
$day_of_birth = ($day_of_birth == '1970-01-01') ? "" : $day_of_birth;
}
else
{
$customer_id = '';
$customer_external_id = '';
$email = $order->getCustomerEmail();
$day_of_birth = '';
}

$coupon_code = trim(mb_strtoupper($order->getCouponCode() ?? '', 'UTF-8'));

/* address information */
$billing_address = $order->getBillingAddress();

if (empty($email))
{
$email = $billing_address->getEmail();
}

$billing_salutation = $billing_address->getPrefix();
$billing_title = $billing_address->getSuffix();
$billing_firstname = trim($billing_address->getFirstname());
$billing_lastname = trim($billing_address->getLastname());

$billing_street1 = $billing_street2 = '';
try {
$billing_street1 = trim($billing_address->getStreetLine(1));
$billing_street2 = trim($billing_address->getStreetLine(2));
}
catch(\Exception $e)
{}

$billing_street_string = ($billing_street1 == $billing_street2) ? $billing_street1 : $billing_street1 . " " . $billing_street2;
$billing_street = trim($billing_street_string);
//remove multiple whitespaces
$billing_street = preg_replace('/\s\s+/', ' ', $billing_street);

$billing_zip = trim($billing_address->getPostcode());
$billing_city = trim($billing_address->getCity());
$billing_country = trim($billing_address->getCountryId());
$billing_company = trim($billing_address->getCompany() ?? '');


$shipping_address = $order->getShippingAddress();

$shipping_salutation = $shipping_address->getPrefix();
$shipping_title = $shipping_address->getSuffix();
$shipping_firstname = trim($shipping_address->getFirstname());
$shipping_lastname = trim($shipping_address->getLastname());

$shipping_street1 = trim($shipping_address->getStreetLine(1));
$shipping_street2 = trim($shipping_address->getStreetLine(2));

$shipping_dhlpostnumber = '';
if(strpos($shipping_street1, 'Packstation') === 0)
{
//remove "Nr."
$shipping_street1 = str_replace('Nr. ', '', $shipping_street1);
//set Postnumber
$shipping_dhlpostnumber = $shipping_street2;
$shipping_street2 = '';
}
$shipping_street_string = ($shipping_street1 == $shipping_street2) ? $shipping_street1 : $shipping_street1 . " " . $shipping_street2;
$shipping_street = trim($shipping_street_string);
//remove multiple whitespaces
$shipping_street = preg_replace('/\s\s+/', ' ', $shipping_street);

//$shipping_dhlpostnumber = trim($shipping_address->getDhlPostNumber());

$shipping_zip = trim($shipping_address->getPostcode());
$shipping_city = trim($shipping_address->getCity());
$shipping_country = trim($shipping_address->getCountryId());
$shipping_company = '';
if(!empty($shipping_dhlpostnumber))
{
$shipping_company = $shipping_dhlpostnumber;
}
else
{
$shipping_company = trim($shipping_address->getCompany() ?? '');
}

// only export shipping address if different from billing address
$shipping_same_as_billing = $shipping_firstname == $billing_firstname
&& $shipping_lastname == $billing_lastname
&& $shipping_street == $billing_street
&& $shipping_zip == $billing_zip
&& $shipping_city == $billing_city
&& $shipping_country == $billing_country;

$telephone = $shipping_address->getTelephone();
$fax = $shipping_address->getFax();


/* payment methods */
$payment = $order->getPayment()->getMethodInstance();
$payment_code = $payment->getCode();
$payment_type = isset($this->payment_mapping[$payment_code]) ? $this->payment_mapping[$payment_code] : $payment_code;

$account_owner = $account_number = $account_blz = $account_swift = $account_iban = '';

if($payment_code == 'debitpayment')
{
$info = $payment->getInfoInstance()->getAdditionalInformation();

$account_owner = $info['additional_data']['bank_account_owner'];
$account_swift = $info['additional_data']['bic'];
$account_iban = $info['additional_data']['iban'];
}

/* items */
$export_data = [];
$products = [];

foreach($order->getAllItems() as $item)
{
$sku = $this->productRepository->getById($item->getProductId())->getData('spi_sku');
$quantity = intval($item->getQtyOrdered());

if(!isset($products[$sku]))
{
$products[$sku] = 0;
}

$products[$sku] += $quantity;
}

foreach($products as $sku => $quantity)
{
$export_data[] = array(
self::ORIGINAL_CONTRACT, // Auftrags-Ursprung
$increment_id, // Bestellnummer
$sku, // Artikelnummer
$quantity, // Ab Werk
$customer_id, // Kundennummer
'', // Kontaktart
'', // Kontaktdatum
'', // Lieferdatum
'', // Absprache
'', // Dienstleister
'', // Dialogservice
(empty($coupon_code) ? '' : '#' . $coupon_code), // Änderung (#CouponCode)
$billing_salutation, // Anrede
$billing_title, // Titel
$billing_firstname, // Vorname
$billing_lastname, // Name

$billing_street, // Straße, Hsnr.
$billing_country, // Land
$billing_zip, // PLZ
$billing_city, // Ort
'', // Ortszusatz
$telephone, // Telefon
$fax, // Telefax

$email, // E-Mail
'', // Homepage
$day_of_birth, // Geburtstag
'', // Anschreiben an
$customer_external_id, // Externe-Kundennummer
$payment_type, // Bezahlart
$account_owner, // Kontoinhaber
$account_number, // Kontonummer
$account_blz, // Bankleitzahl
$account_swift, // Swift-BIC
$account_iban, // IBAN

($shipping_same_as_billing) ? '' : $shipping_salutation, // Anrede (Lieferanschrift)
($shipping_same_as_billing) ? '' : $shipping_title, // Titel (Lieferanschrift)
($shipping_same_as_billing) ? '' : $shipping_firstname, // Vorname (Lieferanschrift)
($shipping_same_as_billing) ? '' : $shipping_lastname, // Name (Lieferanschrift)
($shipping_same_as_billing) ? '' : $shipping_street, // Straße, Hsnr. (Lieferanschrift)
($shipping_same_as_billing) ? '' : $shipping_country, // Land (Lieferanschrift)
($shipping_same_as_billing) ? '' : $shipping_zip, // PLZ (Lieferanschrift)
($shipping_same_as_billing) ? '' : $shipping_city, // Ort (Lieferanschrift)
'', // Ortszusatz
'', // Leerfeld
'', // Leerfeld
$billing_company, // Firmenname
$shipping_company, // Firmenname (Lieferanschrift)

'END', // END
);
}

foreach($export_data as $csv)
{
fputcsv($file_pointer, $csv, ';');
}

// return the order id to log the last exported id for differential exports
return $order->getId();
}

protected function write_csv_head_row($file_pointer)
{
fputcsv($file_pointer, array("Auftrags-Ursprung",
"Bestellnummer",
"Artikelnummer",
"Ab Werk",
"Kundennummer",
"Kontaktart",
"Kontaktdatum",
"Lieferdatum",
"Absprache",
"Dienstleister",
"Dialogservice",
"Änderung",
"Anrede",
"Titel",
"Vorname",
"Name",
"Straße, Hsnr.",
"Land",
"PLZ",
"Ort",
"Ortszusatz",
"Telefon",
"Telefax",
"E-Mail",
"Homepage",
"Geburtstag",
"Anschreiben an",
"Externe-Kundennummer",
"Bezahlart",
"Kontoinhaber",
"Kontonummer",
"Bankleitzahl",
"BIC",
"IBAN",
"LA_Anrede",
"LA_Titel",
"LA_Vorname",
"LA_Name",
"LA_Straße, Hsnr.",
"LA_Land",
"LA_PLZ",
"LA_Ort",
"LA_Ortszusatz",
"Leerfeld",
"Leerfeld",
"Firmenname",
"LA_Firmenname",
"END"
), ';');
}
}

+ 244
- 0
src/app/code/MNM/Spitzner/Helper/Data.php Voir le fichier

@@ -0,0 +1,244 @@
<?php
namespace MNM\Spitzner\Helper;

use Magento\Catalog\Pricing\Price;
use Magento\GroupedProduct\Model\Product\Type\Grouped;
use Magento\Catalog\Api\ProductRepositoryInterface;
use Magento\Framework\App\Helper\Context;
use Magento\Framework\View\LayoutInterface;
use Magento\Framework\Mail\Template\TransportBuilder;
use Magento\Framework\Translate\Inline\StateInterface;
use Magento\Store\Model\StoreManagerInterface;
use Magento\Framework\App\ObjectManager;
use Magento\Framework\App\Area;

class Data extends \Magento\Framework\App\Helper\AbstractHelper
{
/**
*
* @var \Magento\Framework\Pricing\Helper\Data
*/
protected $_priceHelper;

/**
* Layout
*
* @var LayoutInterface
*/
protected $_layout;

/**
*
* @var ProductRepositoryInterface
*/
protected $productRepository;

/**
* @var TransportBuilder
*/
protected $transportBuilder;

/**
* @var StateInterface
*/
protected $inlineTranslation;

/**
* @var StoreManagerInterface
*/
protected $storeManager;

/**
*
* @param Context $context
* @param Data $_priceHelper
* @param LayoutInterface $_layout
* @param ProductRepositoryInterface $productRepository
* @param TransportBuilder $transportBuilder
* @param StateInterface $inlineTranslation
* @param StoreManagerInterface|null $storeManager
*/
public function __construct(
Context $context,
\Magento\Framework\Pricing\Helper\Data $_priceHelper,
LayoutInterface $_layout,
ProductRepositoryInterface $productRepository,
TransportBuilder $transportBuilder,
StateInterface $inlineTranslation,
StoreManagerInterface $storeManager = null)
{
$this->_priceHelper = $_priceHelper;
$this->_layout = $_layout;
$this->productRepository = $productRepository;
$this->transportBuilder = $transportBuilder;
$this->inlineTranslation = $inlineTranslation;
$this->storeManager = $storeManager ?: ObjectManager::getInstance()->get(StoreManagerInterface::class);

parent::__construct($context);
}

/**
*
* @param int $productId
* @return string|unknown
*/
public function getSpiInhalt($productId)
{
$return = '';
$volume = $this->getProductAttributeText($productId, 'spi_inhalt');

preg_match('/[\d]+ml/', $volume, $matches);
if(count($matches))
{
$return = str_replace('1000ml', '1L', $volume);
}

return $return;
}

/**
*
* @param int $productId
* @param string $attribute
* @return string|unknown
*/
public function getProductAttributeText($productId, $attribute)
{
$product = $this->productRepository->getById($productId);

return $product->getAttributeText($attribute);
}

/**
*
* @param unknown $product
* @return boolean
*/
public function getProductGrouped($product)
{
if(!is_object($product))
{
$product = $this->productRepository->getById($product);
}

return $product->getTypeId() == Grouped::TYPE_CODE;
}

/**
*
* @param unknown $product
* @return string
*/
public function getProductPricePerUnit($product)
{
if(!is_object($product))
{
$product = $this->productRepository->getById($product);
}

$grouped = $this->getProductGrouped($product);
$normalizedPrice = '';
$return = '';

if(!$grouped)
{
$normalizedPrice = self::getNormalizedPrice($product);
}
else
{
$normalizedPrice = 0;

foreach($product->getTypeInstance()->getAssociatedProducts($product) as $_child)
{
$np = self::getNormalizedPrice($_child);

if(!is_numeric($np))
{
$normalizedPrice = $np;

break;
}
elseif($normalizedPrice == 0 || $np < $normalizedPrice)
{
$normalizedPrice = $np;
}
}
}

$price = $this->_priceHelper->currency($normalizedPrice, true, false);
$unit = $grouped ? '1000' : $product->getData('spi_normalized_volume');
$unit .= is_numeric($product->getData('spi_normalized_volume')) ? 'ml' : '';

return $price.' / '.str_replace('1000ml', '1L', $unit);
}

/**
*
* @param unknown $product
* @return number|string
*/
protected static function getNormalizedPrice($product)
{
$finalPrice = $product->getPriceInfo()->getPrice(Price\FinalPrice::PRICE_CODE)->getAmount()->getValue();
$volume = intval($product->getAttributeText('spi_inhalt'));
$normalizedVolume = $product->getData('spi_normalized_volume');

if($volume > 0 && is_numeric($normalizedVolume))
{
$normalizedVolume = intval($normalizedVolume);
$normalisedPrice = ($finalPrice / $volume) * $normalizedVolume;
}
else
{
$normalisedPrice = $product->getData('spi_normalized_price');
}

return $normalisedPrice;
}

/**
* Create new block
*
* @param string $blockName
* @param string $template
*/
public function getBlock($blockName, $template) {

$block = $this->_layout
->createBlock($blockName)
->setTemplate($template);

return $block;
}

/**
* Send email
*
* @param string $to
* @param string $template
* @param array $variables
* @return void
*/
public function sendMail(string $to, string $template, array $variables = [])
{
$this->inlineTranslation->suspend();

try {
$transport = $this->transportBuilder
->setTemplateIdentifier($template)
->setTemplateOptions(
[
'area' => Area::AREA_FRONTEND,
'store' => $this->storeManager->getStore()->getId()
])
->setTemplateVars($variables)
->setFrom(['name' => 'Spitzner Webshop', 'email' => 'wellness@spitzner.de'])
->addTo($to)
->getTransport();

$transport->sendMessage();
} finally {
$this->inlineTranslation->resume();
}
}
}

+ 28
- 0
src/app/code/MNM/Spitzner/Model/ExportLogEntry.php Voir le fichier

@@ -0,0 +1,28 @@
<?php

namespace MNM\Spitzner\Model;

class ExportLogEntry extends \Magento\Framework\Model\AbstractModel implements \Magento\Framework\DataObject\IdentityInterface {
const CACHE_TAG = 'mnm_spitzner_exportlogentry';

protected $_cacheTag = 'mnm_spitzner_exportlogentry';

protected $_eventPrefix = 'mnm_spitzner_exportlogentry';

protected function _construct()
{
$this->_init('MNM\Spitzner\Model\ResourceModel\ExportLogEntry');
}

public function getIdentities()
{
return [self::CACHE_TAG . '_' . $this->getId()];
}

public function getDefaultValues()
{
$values = [];

return $values;
}
}

+ 16
- 0
src/app/code/MNM/Spitzner/Model/ResourceModel/ExportLogEntry.php Voir le fichier

@@ -0,0 +1,16 @@
<?php
namespace MNM\Spitzner\Model\ResourceModel;

class ExportLogEntry extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb
{
public function __construct(\Magento\Framework\Model\ResourceModel\Db\Context $context)
{
parent::__construct($context);
}

protected function _construct()
{
$this->_init('spitzner_export_log', 'exportlog_id');
}

}

+ 20
- 0
src/app/code/MNM/Spitzner/Model/ResourceModel/ExportLogEntry/Collection.php Voir le fichier

@@ -0,0 +1,20 @@
<?php

namespace MNM\Spitzner\Model\ResourceModel\ExportLogEntry;

class Collection extends \Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection
{
protected $_idFieldName = 'exportlog_id';
protected $_eventPrefix = 'mnm_spitzner_exportlogentry_collection';
protected $_eventObject = 'exportlogentry_collection';

/**
* Define resource model
*
* @return void
*/
protected function _construct()
{
$this->_init('MNM\Spitzner\Model\ExportLogEntry', 'MNM\Spitzner\Model\ResourceModel\ExportLogEntry');
}
}

+ 447
- 0
src/app/code/MNM/Spitzner/Model/Rule/Condition/CustomerAttributes.php Voir le fichier

@@ -0,0 +1,447 @@
<?php
/**
* @author Amasty Team
* @copyright Copyright (c) 2020 Amasty (https://www.amasty.com)
* @package Amasty_Conditions
*/


namespace MNM\Spitzner\Model\Rule\Condition;

use Amasty\Conditions\Model\Constants;

/**
* @method string getAttribute()
* @method string getIsValueParsed()
* @method string setAttributeOption($attributes)
* @method string setValue($value)
* @method string setIsValueParsed($boolean)
*/
class CustomerAttributes extends \Magento\Rule\Model\Condition\AbstractCondition
{
const CUSTOM_ATTRIBUTES_NAME = 'custom_attributes';

/**
* @var array
*/
const NOT_ALLOWED_ATTRIBUTES = [
'lock_expires',
'first_failure',
'group_id',
'default_billing',
'default_shipping',
'failures_num',
'created_in',
'disable_auto_group_change',
'confirmation',
];

/**
* @var array
*/
const AVAILABLE_TYPES = [
'checkbox',
'checkboxes',
'date',
'editablemultiselect',
'editor',
'fieldset',
'file',
'gallery',
'image',
'imagefile',
'multiline',
'multiselect',
'radio',
'radios',
'select',
'text',
'textarea',
'time',
];

/**
* @var array
*/
const INPUT_TYPES = ['string', 'numeric', 'date', 'select', 'multiselect', 'grid', 'boolean'];

const SECONDS_IN_DAY = 60 * 60 * 24;

/**
* @var \Magento\Customer\Model\ResourceModel\Customer
*/
private $resource;

/**
* @var \Magento\Customer\Model\CustomerFactory
*/
private $customerFactory;

/**
* @var \Magento\Customer\Model\Session
*/
private $customerSession;

/**
* @var \Amasty\Conditions\Model\Address
*/
private $address;

//MNM
/**
* @var \Magento\Sales\Model\ResourceModel\Order\CollectionFactory
*/
private $orderCollectionFactory;

/**
* @var \Magento\Checkout\Model\Session
*/
private $checkoutSession;
//MNM

public function __construct(
\Magento\Rule\Model\Condition\Context $context,
\Magento\Customer\Model\ResourceModel\Customer $resource,
\Magento\Customer\Model\CustomerFactory $customerFactory,
\Magento\Customer\Model\Session $customerSession,
\Amasty\Conditions\Model\Address $address,
//MNM
\Magento\Sales\Model\ResourceModel\Order\CollectionFactory $orderCollectionFactory,
\Magento\Checkout\Model\Session $checkoutSession,
//MNM
array $data = []
) {
$this->resource = $resource;
$this->customerFactory = $customerFactory;
$this->customerSession = $customerSession;
//MNM
$this->orderCollectionFactory = $orderCollectionFactory;
$this->checkoutSession = $checkoutSession;
//MNM
parent::__construct($context, $data);
$this->address = $address;
}

/**
* Retrieve attribute object
*
* @return \Magento\Eav\Model\Entity\Attribute\AbstractAttribute
*/
private function getAttributeObject()
{
return $this->resource->getAttribute($this->getAttribute());
}

/**
* @return $this
* @throws \Magento\Framework\Exception\LocalizedException
*/
public function loadAttributeOptions()
{
$customerAttributes = $this->resource
->loadAllAttributes()
->getAttributesByCode();

$attributes = [];

/** @var \Magento\Eav\Model\Entity\Attribute\AbstractAttribute $attribute */
foreach ($customerAttributes as $attribute) {
if (!($attribute->getFrontendLabel()) || !($attribute->getAttributeCode())) {
continue;
}

if (in_array($attribute->getAttributeCode(), self::NOT_ALLOWED_ATTRIBUTES)) {
continue;
}
$attributes[$attribute->getAttributeCode()] = $attribute->getFrontendLabel();
}

$this->addSpecialAttributes($attributes);
//MNM
$attributes['number_of_orders'] = __('Anzahl bisheriger Bestellungen');
//MNM
asort($attributes);
$this->setAttributeOption($attributes);

return $this;
}

/**
* @param array $attributes
*
* @return \Amasty\Conditions\Model\Rule\Condition\CustomerAttributes
*/
private function addSpecialAttributes(array &$attributes)
{
$attributes['id'] = __('Customer ID');
$attributes['membership_days'] = __('Membership Days');

return $this;
}

/**
* @return $this
* @throws \Magento\Framework\Exception\LocalizedException
*/
public function getAttributeElement()
{
$element = parent::getAttributeElement();
$element->setShowAsText(true);

return $element;
}

/**
* @return array
*/
public function getValue()
{
if ($this->getInputType() == 'date' && !$this->getIsValueParsed()) {
// date format intentionally hard-coded
$this->setValue(
(new \DateTime($this->getData('value')))->format('Y-m-d')
);
$this->setIsValueParsed(true);
}

return $this->getData('value');
}

/**
* This value will define which operators will be available for this condition.
*
* Possible values are: string, numeric, date, select, multiselect, grid, boolean
*
* @return string
*/
public function getInputType()
{
if ($this->getAttribute() === 'entity_id' || $this->getAttribute() === 'membership_days'
//MNM
|| $this->getAttribute() === 'number_of_orders'
//MNM
) {
return 'string';
}

$customerAttribute = $this->getAttributeObject();

if (!$customerAttribute) {
return parent::getInputType();
}

return $this->getInputTypeFromAttribute($customerAttribute);
}

/**
* @param \Magento\Eav\Model\Entity\Attribute\AbstractAttribute $customerAttribute
*
* @return string
*/
private function getInputTypeFromAttribute($customerAttribute)
{
if (!is_object($customerAttribute)) {
$customerAttribute = $this->getAttributeObject();
}

if (in_array($customerAttribute->getFrontendInput(), self::INPUT_TYPES)) {
return $customerAttribute->getFrontendInput();
}

switch ($customerAttribute->getFrontendInput()) {
case 'gallery':
case 'media_image':
case 'selectimg': // amasty customer attribute
return 'select';

case 'multiselectimg': // amasty customer attribute
return 'multiselect';
}

return 'string';
}

/**
* @return $this
* @throws \Magento\Framework\Exception\LocalizedException
*/
public function getValueElement()
{
$element = parent::getValueElement();

switch ($this->getInputType()) {
case 'date':
$element->setClass('hasDatepicker');
$element->setExplicitApply(true);
break;
}

return $element;
}

/**
* Value element type will define renderer for condition value element
*
* @see \Magento\Framework\Data\Form\Element
* @return string
*/
public function getValueElementType()
{
$customerAttribute = $this->getAttributeObject();

if ($this->getAttribute() === 'entity_id' || $this->getAttribute() === 'membership_days'
//MNM
|| $this->getAttribute() === 'number_of_orders'
//MNM
) {
return 'text';
}

if (!is_object($customerAttribute)) {
return parent::getValueElementType();
}

if (in_array($customerAttribute->getFrontendInput(), self::AVAILABLE_TYPES)) {
return $customerAttribute->getFrontendInput();
}

switch ($customerAttribute->getFrontendInput()) {
case 'selectimg':
case 'boolean':
return 'select';

case 'multiselectimg':
return 'multiselect';
}

return parent::getValueElementType();
}

/**
* @return array
* @throws \Magento\Framework\Exception\LocalizedException
*/
public function getValueSelectOptions()
{
$selectOptions = [];
$attributeObject = $this->getAttributeObject();

if (is_object($attributeObject) && $attributeObject->usesSource()) {
$addEmptyOption = true;
if ($attributeObject->getFrontendInput() === 'multiselect') {
$addEmptyOption = false;
}
$selectOptions = $attributeObject->getSource()->getAllOptions($addEmptyOption);
}

if (!$this->hasData(Constants::VALUE_SELECT_OPTIONS)) {
$this->setData(Constants::VALUE_SELECT_OPTIONS, $selectOptions);
}

return $this->getData(Constants::VALUE_SELECT_OPTIONS);
}

/**
* Validate Address Rule Condition
*
* @param \Magento\Framework\Model\AbstractModel $model
*
* @return bool
* @throws \Magento\Framework\Exception\LocalizedException
*/
public function validate(\Magento\Framework\Model\AbstractModel $model)
{
$customer = $model;
if (!$customer instanceof \Magento\Customer\Model\Customer) {
$customer = $model->getQuote()->getCustomer();
if (!$customer->getId()) {
$customer = $this->customerSession->getCustomer();
}

$attr = $this->getAttribute();
$allAttr = $customer instanceof \Magento\Customer\Model\Customer
? $customer->getData()
: $customer->__toArray();
$this->addCustomAttributes($allAttr, $model);

if ($attr === 'membership_days') {
$allAttr[$attr] = $this->getMembership($customer->getCreatedAt());
}
//MNM
else if($attr === 'number_of_orders') {
$count = 0;

//get customer email
$email = '';

if($this->customerSession->getCustomerData())
{
$email = $this->customerSession->getCustomerData()->getEmail();
}

if(empty($email))
{
$email = $this->checkoutSession->getSpitznerCheckoutEmail();
}

if(!empty($email))
{
$count = $this->orderCollectionFactory->create()
->addAttributeToFilter('customer_email', $email)
->getSize();
}

$allAttr[$attr] = $count;
}
//MNM

if ($attr !== 'entity_id' && !array_key_exists($attr, $allAttr)) {
if (isset($allAttr[self::CUSTOM_ATTRIBUTES_NAME])
&& array_key_exists($attr, $allAttr[self::CUSTOM_ATTRIBUTES_NAME])
) {
$customAttribute = $this->resource->getAttribute($attr);
$attributeValue = $allAttr[self::CUSTOM_ATTRIBUTES_NAME][$attr]['value'];

if ($customAttribute->getFrontendInput() === 'multiselect') {
$attributeValue = explode(',', $attributeValue);
}

$allAttr[$attr] = $attributeValue;
} else {
$address = $model->getQuote()->getBillingAddress();
$allAttr[$attr] = $address->getData($attr);
}
}

$customer = $this->customerFactory->create()->setData($allAttr);
}

return parent::validate($customer);
}

/**
* @param $allAttr
* @param $customer
*/
private function addCustomAttributes(&$allAttr, $customer)
{
if ($this->address->isAdvancedConditions($customer)) {
$customAttributes = $customer->getExtensionAttributes()->getAdvancedConditions()->getCustomAttributes();
if ($customAttributes) {
foreach ($customAttributes as $customAttribute) {
$allAttr[$customAttribute->getAttributeCode()] = $customAttribute->getValue();
}
}
}
}

/**
* @param $created
*
* @return float
*/
private function getMembership($created)
{
return round((time() - strtotime($created)) / self::SECONDS_IN_DAY);
}
}

+ 71
- 0
src/app/code/MNM/Spitzner/Observer/AddEmailVariables.php Voir le fichier

@@ -0,0 +1,71 @@
<?php
namespace MNM\Spitzner\Observer;

use Magento\Customer\Api\CustomerRepositoryInterface;
use Magento\Framework\Event\ObserverInterface;

class AddEmailVariables implements ObserverInterface
{
protected $customerRepository;

public function __construct(CustomerRepositoryInterface $customerRepository)
{
$this->customerRepository = $customerRepository;
}

public function execute(\Magento\Framework\Event\Observer $observer)
{
/** @var \Magento\Framework\App\Action\Action $controller */
$transport = $observer->getEvent()->getTransport();

if($transport->getOrder() != null)
{
$order = $transport->getOrder();
$customer = null;
if($order->getCustomerId())
{
$customer = $this->customerRepository->getById($transport->getOrder()->getCustomerId());
}

/*if ($customer->getCustomAttribute('username'))
{
$transport['username'] = $customer->getCustomAttribute('username')->getValue();
}*/

//order date
$transport['order_date_long'] = $order->getCreatedAtFormatted(\IntlDateFormatter::LONG);

//payment extra text
$payment_method = $order->getPayment()->getMethodInstance();
$paymentText = '';
switch($payment_method->getTitle())
{
case 'Rechnung': $paymentText = 'Der Rechnungsbetrag wird sofort nach Erhalt der Rechnung fällig, per Überweisung auf das in der Rechnung angegebene Bankkonto. Alle Preise verstehen sich inklusive der gesetzlich gültigen MwSt.';
break;
case 'Paypal': $paymentText = 'Nicht skontierbar.';
break;
case 'Bankeinzug':
case 'Bankeinzug / Lastschrift':
case 'Bankeinzug (3% Skonto)':
$paymentText = 'Wir gewähren Ihnen 3% Skonto.';
break;
}
$transport['payment_text'] = $paymentText;

//customer number
$transport['customer_number_text'] = '';
if($customer)
{
$customerNumber = $customer->getCustomAttribute('customer_number');

if($customerNumber)
{
$transport['customer_number_text'] = "<strong>Kundennummer:</strong> " . $customerNumber->getValue();
}
}

//order
$transport['order_id'] = $order->getId();
}
}
}

+ 67
- 0
src/app/code/MNM/Spitzner/Observer/Addtocart.php Voir le fichier

@@ -0,0 +1,67 @@
<?php
//MNM - overwrite to add translation
namespace MNM\Spitzner\Observer;
use Magento\Framework\Event\Observer;
use Magento\Framework\Event\ObserverInterface;
use Magento\Framework\Registry;
class Addtocart extends \Magebees\Ajaxaddtocart\Observer\Addtocart
{
public function execute(\Magento\Framework\Event\Observer $observer)
{
$config=$this->ajaxPopup->getConfig();
if ($config['enable']==1) {
if ($this->httpRequest->isAjax()) {
$productId=$observer->getProduct()->getId();
$product=$this->catalogModel->load($productId);
$this->_coreRegistry->register('product',$product);
$url=$this->catalogHelper->getImageUrl($product);
$content=$this->ajaxPopup->getConfirmContent();
$dialogConfig=$this->ajaxPopup->getDialogConfig();
//MNM $totalQuantity =$this->cartModel->getQuote()->getItemsQty();
//MNM $subTotal = $this->cartModel->getQuote()->getSubtotal();
//MNM $formated_total=$this->checkoutHelper->formatPrice($subTotal);
$resultPage= $this->pageFactory->create();
$layoutblk = $resultPage->addHandle('ajaxcheckout_cart_index')->getLayout();
$productblk = $resultPage->addHandle('product_section')->getLayout();
//$layoutblk = $resultPage->addHandle('checkout_cart_index')->getLayout();
//MNM - added translate function
$html="<p id=\"success-message\">".sprintf(__("%s added to your cart successfully"), $product->getName()).".</p>
<div class=\"timer active-color\" id=\"timer\">3</div>";
//MNM
if ($dialogConfig['productimage']==1) {
$html.="<img src='".$url."' alt='".$product->getName()."' class='pImage' />";
}
//MNM $html.="<div class='totalRow'>There are <b>".$totalQuantity."</b> item in your cart.<br />Cart Subtotal: <b>".$formated_total."</b></div>".$content;
$html .= $content;
if ($dialogConfig['related']==1) {
$related_content= $productblk->getBlock('catalog.product.related')->toHtml();
$html.=$related_content;
}
if ($dialogConfig['upsell']==1) {
$upsell_content= $productblk->getBlock('product.info.upsell')->toHtml();
$html.=$upsell_content;
}
if ($dialogConfig['crosssell']==1) {
$crosssell_content= $productblk->getBlock('addtocart_crosssell')->toHtml();
$html.=$crosssell_content;
}
$_response=$this->productContent;
$_response->setPopupContent($html);
$referUrl = $this->redirect->getRefererUrl();
if (strpos($referUrl, 'checkout')!== false) {
if ($layoutblk->getBlock('checkout.cart')) {
$cart_content= $layoutblk->getBlock('checkout.cart')->toHtml();
$_response->setCartContent($cart_content);
}
}
$_response->addBlockContent($_response);
$_response->send();
}
}
}
}

+ 61
- 0
src/app/code/MNM/Spitzner/Observer/CheckOrderAddresses.php Voir le fichier

@@ -0,0 +1,61 @@
<?php

namespace MNM\Spitzner\Observer;

/**
* Check if orders/quote billingaddress is set correctly. Correct/copy over from shipping address otherwise.
* Should not happen anyway
*/

use Magento\Framework\Event\ObserverInterface;

use MNM\Spitzner\Plugin\Checkout\ShippingInformationManagementPlugin;

class CheckOrderAddresses implements ObserverInterface
{
public function execute(\Magento\Framework\Event\Observer $observer)
{
$order = $observer->getData('order');

$billingAddress = $order->getBillingAddress();
$shippingAddress = $order->getShippingAddress();

if(empty($billingAddress->getFirstname()) || empty($billingAddress->getLastname()))
{
$billingAddress->setFirstname($shippingAddress->getFirstname());
$billingAddress->setLastname($shippingAddress->getLastname());
$billingAddress->setPrefix($shippingAddress->getPrefix());
$billingAddress->setStreet($shippingAddress->getStreet());
$billingAddress->setPostcode($shippingAddress->getPostcode());
$billingAddress->setCity($shippingAddress->getCity());
$billingAddress->setCountryId($shippingAddress->getCountryId());
}
else
{
$streetShipping = $shippingAddress->getStreet();
$streetBilling = $billingAddress->getStreet();

//check if shipping has housenumber and billing not (bug)
if( $streetBilling[0] != $streetShipping[0]
&& strncasecmp($streetBilling[0], $streetShipping[0], 5) === 0
&& !preg_match('/\d+/', $streetBilling[0])
&& preg_match('/\d+/', $streetShipping[0]))
{
$streetBilling[0] = $streetShipping[0];

$billingAddress->setStreet($streetBilling);
}
}

$repertusType = $shippingAddress->getDataByKey('repertus_address_type');

if(($repertusType == '2' || $repertusType == 2) && strpos($streetShipping[0], 'Packstation') === 0)
{
$streetShipping = [
'Packstation Nr. '.$shippingAddress->getDataByKey('repertus_number'),
__('Postnummer').' '.$shippingAddress->getDataByKey('repertus_post_number')];

$shippingAddress->setStreet($streetShipping);
}
}
}

+ 46
- 0
src/app/code/MNM/Spitzner/Overwrite/Model/Transport.php Voir le fichier

@@ -0,0 +1,46 @@
<?php
/**
* Mail Transport
*/

namespace MNM\Spitzner\Overwrite\Model;

use Magento\Framework\App\Config\ScopeConfigInterface;
use Magento\Framework\Mail\MessageInterface;
use Laminas\Mail\Transport\SmtpOptions;
use Laminas\Mail\Transport\Smtp;

class Transport extends \Sendinblue\Sendinblue\Model\Transport
{
/**
* @param MessageInterface $message
* @param null $parameters
* @throws \InvalidArgumentException
*/
public function __construct(MessageInterface $message, ScopeConfigInterface $scopeConfig ){
$this->_message = $message;
$this->_scopeConfig = $scopeConfig;
$relaySib = $scopeConfig->getValue('sendinblue/relay_data_status', \Magento\Store\Model\ScopeInterface::SCOPE_STORE);
if ($relaySib == 'enabled') {
$smtpHost = "smtp-relay.brevo.com";
$smtpAuthentication = $scopeConfig->getValue('sendinblue/smtp_authentication', \Magento\Store\Model\ScopeInterface::SCOPE_STORE);
$smtpTls = $scopeConfig->getValue('sendinblue/smtp_tls', \Magento\Store\Model\ScopeInterface::SCOPE_STORE);
$smtpPort = $scopeConfig->getValue('sendinblue/smtp_port', \Magento\Store\Model\ScopeInterface::SCOPE_STORE);
$smtpUsername = $scopeConfig->getValue('sendinblue/smtp_username', \Magento\Store\Model\ScopeInterface::SCOPE_STORE);
$smtpPassword = $scopeConfig->getValue('sendinblue/smtp_password', \Magento\Store\Model\ScopeInterface::SCOPE_STORE);
/**MNM updated "instanceof Message" to "instanceof MessageInterface" **/
if ($message instanceof MessageInterface) {
$this->transport = new Smtp(new SmtpOptions([
'host' => $smtpHost,
'port' => $smtpPort,
'connection_class' => $smtpAuthentication,
'connection_config' => [
'username' => $smtpUsername,
'password' => $smtpPassword,
'ssl' => $smtpTls,
],
]));
}
}
}
}

+ 35
- 0
src/app/code/MNM/Spitzner/Plugin/AddCheckoutItemPricePerUnit.php Voir le fichier

@@ -0,0 +1,35 @@
<?php

namespace MNM\Spitzner\Plugin;

class AddCheckoutItemPricePerUnit
{
/**
* @var \MNM\Spitzner\Helper\Data
*/
private $helper;

public function __construct(\MNM\Spitzner\Helper\Data $helper)
{
$this->helper = $helper;
}

/**
* Modify checkout config data.
*
* @param \Magento\Checkout\Model\DefaultConfigProvider $subject
* @param array $config
*
* @return array
*/
public function afterGetConfig(\Magento\Checkout\Model\DefaultConfigProvider $subject, $config)
{
foreach ($config['quoteItemData'] as &$item) {
$item['mnmpriceperunit'] = $this->helper->getProductPricePerUnit($item['product_id']);
$item['mnm_spi_inhalt'] = $this->helper->getSpiInhalt($item['product_id']);
$item['amstockstatus'] = $this->helper->getProductAttributeText($item['product_id'], 'custom_stock_status');
}

return $config;
}
}

+ 39
- 0
src/app/code/MNM/Spitzner/Plugin/AddCustomerNameToPaypalGuestQuote.php Voir le fichier

@@ -0,0 +1,39 @@
<?php

namespace MNM\Spitzner\Plugin;
use Magento\Checkout\Model\Session as CheckoutSession;
class AddCustomerNameToPaypalGuestQuote {
/** @var CheckoutSession */
protected $checkoutSession;
/**
* @param CheckoutSession $checkoutSession
*/
public function __construct(CheckoutSession $checkoutSession) {
$this->checkoutSession = $checkoutSession;
}
/**
*
* @param \Magento\Paypal\Model\Express\Checkout $subject
* @param string $token
* @param string|null $shippingMethodCode
* @return NULL
*/
public function beforePlace(\Magento\Paypal\Model\Express\Checkout $subject, $token, $shippingMethodCode = null)
{
if($subject->getCheckoutMethod() == \Magento\Checkout\Model\Type\Onepage::METHOD_GUEST)
{
/** @var \Magento\Quote\Model\Quote */
$quote = $this->checkoutSession->getQuote();
$quote->setCustomerFirstname($quote->getBillingAddress()->getFirstname())
->setCustomerLastname($quote->getBillingAddress()->getLastname())
->setCustomerPrefix($quote->getBillingAddress()->getPrefix());
}
return null;
}
}

+ 16
- 0
src/app/code/MNM/Spitzner/Plugin/AddStockLabel.php Voir le fichier

@@ -0,0 +1,16 @@
<?php

namespace MNM\Spitzner\Plugin;

class AddStockLabel
{
/**
* @param \Amasty\Stockstatus\Helper\Data $subject
* @param string $result
* @return string
*/
public function afterShowStockStatus(\Amasty\Stockstatus\Helper\Data $subject, $result)
{
return str_replace('<div class="stock">', '<div class="stock">'.__('Verfügbarkeit').': ', $result);
}
}

+ 10
- 0
src/app/code/MNM/Spitzner/Plugin/Amasty/Promo/PreventResetQtyAllowed.php Voir le fichier

@@ -0,0 +1,10 @@
<?php

namespace MNM\Spitzner\Plugin\Amasty\Promo;
class PreventResetQtyAllowed {
public function aroundResetQtyAllowed(\Amasty\Promo\Model\ItemRegistry\PromoItemRegistry $subject, callable $proceed)
{
//dont call method to prevent reseting
}
}

+ 95
- 0
src/app/code/MNM/Spitzner/Plugin/Cart/AbstractCart.php Voir le fichier

@@ -0,0 +1,95 @@
<?php
/**
* MNM
* - copy of Amasty\Stockstatus\Plugin\Cart\AbstractCart
* - removed $status
*/
/**
* @author Amasty Team
* @copyright Copyright (c) 2020 Amasty (https://www.amasty.com)
* @package Amasty_Stockstatus
*/

declare(strict_types=1);

namespace MNM\Spitzner\Plugin\Cart;

use Amasty\Stockstatus\Model\ConfigProvider;
use Amasty\Stockstatus\Model\Stockstatus\Cart\AddStockstatusToCartHtml;
use Amasty\Stockstatus\Model\Stockstatus\Processor;
use Amasty\Stockstatus\Model\Stockstatus\Renderer\Info as InfoRenderer;
use Amasty\Stockstatus\Model\Stockstatus\Renderer\Status as StatusRenderer;
use Closure;
use Magento\Quote\Model\Quote\Item as QuoteItem;

class AbstractCart {
/**
* @var Processor
*/
private $processor;

/**
* @var StatusRenderer
*/
private $statusRenderer;

/**
* @var InfoRenderer
*/
private $infoRenderer;

/**
* @var ConfigProvider
*/
private $configProvider;

/**
* @var AddStockstatusToCartHtml
*/
private $addStockstatusToCartHtml;

public function __construct(
Processor $processor,
StatusRenderer $statusRenderer,
InfoRenderer $infoRenderer,
ConfigProvider $configProvider,
AddStockstatusToCartHtml $addStockstatusToCartHtml
) {
$this->processor = $processor;
$this->statusRenderer = $statusRenderer;
$this->infoRenderer = $infoRenderer;
$this->configProvider = $configProvider;
$this->addStockstatusToCartHtml = $addStockstatusToCartHtml;
}

public function aroundGetItemHtml(
\Magento\Checkout\Block\Cart\AbstractCart $subject,
Closure $proceed,
QuoteItem $item
) {
$result = $proceed($item);

if ($this->configProvider->isDisplayedOnCart() && $item->getProduct()->getData('sku')) {
$product = $item->getProduct();
if ($product->getTypeId() == 'configurable') {
$product = $item->getOptionByCode('simple_product')->getProduct();
}

$this->processor->execute([$product]);
$status = $this->statusRenderer->render($product, false, true);

if ($status) {
//MNM
if(strpos($status, '<div class="amstockstatus-status-container stock ">') === 0 || strpos($status, '<div class="amstockstatus-status-container stock ">') > 0)
{
$status = '<div class="amstockstatus-status-container stock">'.substr($status, strpos($status, '<span class="amstockstatus'));
}
//MNM
$status = '<div class="amstockstatus-cart">' . $status . $this->infoRenderer->render() . '</div>';
$result = $this->addStockstatusToCartHtml->execute($status, $result);
}
}

return $result;
}
}

+ 18
- 0
src/app/code/MNM/Spitzner/Plugin/CategoryChildrenCollection.php Voir le fichier

@@ -0,0 +1,18 @@
<?php
namespace MNM\Spitzner\Plugin;

class CategoryChildrenCollection
{
/**
* @param \Magento\Catalog\Model\ResourceModel\Category $subject
* @param \Magento\Catalog\Model\ResourceModel\Category\Collection $result
* @return string
*/
public function afterGetChildrenCategories(\Magento\Catalog\Model\ResourceModel\Category $subject,
\Magento\Catalog\Model\ResourceModel\Category\Collection $result)
{
$result->addAttributeToSelect('include_in_menu');

return $result;
}
}

+ 19
- 0
src/app/code/MNM/Spitzner/Plugin/ChangeFaqCollection.php Voir le fichier

@@ -0,0 +1,19 @@
<?php
namespace MNM\Spitzner\Plugin;

class ChangeFaqCollection
{
/**
* @param \Mageprince\Faq\Block\Index\Index $subject
* @param \Mageprince\Faq\Model\ResourceModel\Faq\Collection $result
* @param $group
* @return \Mageprince\Faq\Model\ResourceModel\Faq\Collection
*/
public function afterGetFaqCollection(\Mageprince\Faq\Block\Index\Index $subject, \Mageprince\Faq\Model\ResourceModel\Faq\Collection $result, $group)
{
$result->addFieldToFilter('group', ['eq' => intval($group)]);
$result->setOrder('title', 'ASC');

return $result;
}
}

+ 142
- 0
src/app/code/MNM/Spitzner/Plugin/Checkout/ShippingInformationManagementPlugin.php Voir le fichier

@@ -0,0 +1,142 @@
<?php

namespace MNM\Spitzner\Plugin\Checkout;

use Magento\Checkout\Api\Data\ShippingInformationExtensionInterface;
use Magento\Checkout\Api\Data\ShippingInformationInterface;
use Magento\Checkout\Model\ShippingInformationManagement;
use Magento\Quote\Model\QuoteRepository;

class ShippingInformationManagementPlugin
{
protected $quoteRepository;

protected $checkoutSession;

protected $customerSession;

protected $messageManager;

public function __construct(
QuoteRepository $quoteRepository
) {
$this->quoteRepository = $quoteRepository;
}

/**
* @param ShippingInformationManagement $subject
* @param $cartId
* @param ShippingInformationInterface $addressInformation
*
* @throws \Magento\Framework\Exception\NoSuchEntityException
*/
public function beforeSaveAddressInformation(
ShippingInformationManagement $subject,
$cartId,
ShippingInformationInterface $addressInformation)
{
$shippingAddress = $addressInformation->getShippingAddress();
$billingAddress = $addressInformation->getBillingAddress();
$streetShipping = $shippingAddress->getStreet();
$streetBilling = $billingAddress->getStreet();
$quote = $this->quoteRepository->getActive($cartId);
$quoteShippingAddress = $quote->getShippingAddress();
$quoteBillingAddress = $quote->getBillingAddress();
$shippingSameAsBilling = $quoteShippingAddress->getSameAsBilling();

self::removeStreetDuplicates($streetBilling);

if(!$shippingSameAsBilling)
{
$shippingExtensionSttributes = $addressInformation->getExtensionAttributes();
$repertusAddressType = $shippingExtensionSttributes->getRepertusAddressType();
$repertusPostNumber = $shippingExtensionSttributes->getRepertusPostNumber();
$repertusNumber = $shippingExtensionSttributes->getRepertusNumber();

//update labels if is packstation
if( is_array($streetShipping)
&& strpos($streetShipping[0], 'Packstation') === 0)
{
$streetShipping[0] = 'Packstation Nr. '.$repertusNumber;
$streetShipping[1] = __('Postnummer').' '.$repertusPostNumber;
}
else
{
//check if shipping has housenumber and billing not (bug)
if( $streetBilling[0] != $streetShipping[0]
&& strncasecmp($streetBilling[0], $streetShipping[0], 5) === 0
&& !preg_match('/\d+/', $streetBilling[0])
&& preg_match('/\d+/', $streetShipping[0]))
{
$streetBilling[0] = $streetShipping[0];
}

if($repertusAddressType == "2")
{
$streetShipping[0] = 'Packstation Nr. '.$repertusNumber;
$streetShipping[1] = __('Postnummer').' '.$repertusPostNumber;
}
else
{
self::removeStreetDuplicates($streetShipping);
}
}
}
else
{
$streetShipping = $streetBilling;
}

$shippingAddress->setStreet($streetShipping);
$quoteShippingAddress->setStreet($streetShipping);
$billingAddress->setStreet($streetBilling);
$quoteBillingAddress->setStreet($streetBilling);

$addressInformation->setShippingAddress($shippingAddress);
$addressInformation->setBillingAddress($billingAddress);
$quote->setShippingAddress($quoteShippingAddress);
$quote->setBillingAddress($quoteBillingAddress);
}

/**
* remove duplicates
*
* @param unknown $street
*/
protected static function removeStreetDuplicates(&$street)
{
//check if address line 1 and 2 are equal
if(is_array($street) && !empty($street[1]))
{
if($street[0] == $street[1])
{
$street[1] = '';
}
else
{
preg_match('/([^\d]+)\s?(.+)/i', $street[0], $result0);
preg_match('/([^\d]+)\s?(.+)/i', $street[1], $result1);

if(count($result0) > 1 && count($result1) > 1)
{
if( mb_stripos(trim($result1[1]), trim($result0[1])) === 0
&& $result1[2] == $result0[2])
{
$street[1] = '';
}
}
}
}

//remove duplicates in single line
if(is_array($street) && isset($street[0]))
{
$street[0] = implode(' ', array_unique(explode(' ', $street[0])));
}

if(is_array($street) && isset($street[1]))
{
$street[1] = implode(' ', array_unique(explode(' ', $street[1])));
}
}
}

+ 65
- 0
src/app/code/MNM/Spitzner/Plugin/CheckoutLayoutAdaption.php Voir le fichier

@@ -0,0 +1,65 @@
<?php

namespace MNM\Spitzner\Plugin;

class CheckoutLayoutAdaption
{
/**
* @param \Magento\Checkout\Block\Checkout\LayoutProcessor $subject
* @param array $result
* @return array
*/
public function afterProcess(\Magento\Checkout\Block\Checkout\LayoutProcessor $subject, $result)
{
//unset tooltip for telephone
unset($result['components']['checkout']['children']['steps']['children']['shipping-step']['children']['shippingAddress']['children']['shipping-address-fieldset']['children']['telephone']['config']['tooltip']);
unset($result['components']['checkout']['children']['steps']['children']['shipping-step']['children']['shippingAddress']['children']['billing-address-form']['children']['form-fields']['children']['telephone']['config']['tooltip']);
unset($result['components']['checkout']['children']['steps']['children']['billing-step']['children']['payment']['children']['afterMethods']['children']['billing-address-form']['children']['form-fields']['children']['telephone']['config']['tooltip']);

//unset address type post office
array_splice($result['components']['checkout']['children']['steps']['children']['shipping-step']['children']['shippingAddress']['children']['shipping-address-fieldset']['children']['repertus_address_type_group']['children']['address_type_field']['config']['options'], 1, 1);

//add billing address - address helper
$result['components']['checkout']['children']['steps']['children']['billing-step']['children']['payment']['children']['afterMethods']['children']['billing-address-form']['children']['form-fields']['children']['postcode']['component'] = 'MNM_Spitzner/js/form/field/zip';
$result['components']['checkout']['children']['steps']['children']['billing-step']['children']['payment']['children']['afterMethods']['children']['billing-address-form']['children']['form-fields']['children']['postcode']['config']['elementTmpl'] = 'MNM_Spitzner/form/element/input-with-autocomplete';

$result['components']['checkout']['children']['steps']['children']['billing-step']['children']['payment']['children']['afterMethods']['children']['billing-address-form']['children']['form-fields']['children']['street']['children'][0]['component'] = 'MNM_Spitzner/js/form/field/zip';
$result['components']['checkout']['children']['steps']['children']['billing-step']['children']['payment']['children']['afterMethods']['children']['billing-address-form']['children']['form-fields']['children']['street']['children'][0]['config']['elementTmpl'] = 'MNM_Spitzner/form/element/input-with-autocomplete';

//add shipping address - address helper
$result['components']['checkout']['children']['steps']['children']['shipping-step']['children']['shippingAddress']['children']['shipping-address-fieldset']['children']['postcode']['component'] = 'MNM_Spitzner/js/form/field/zip';
$result['components']['checkout']['children']['steps']['children']['shipping-step']['children']['shippingAddress']['children']['shipping-address-fieldset']['children']['postcode']['config']['elementTmpl'] = 'MNM_Spitzner/form/element/input-with-autocomplete';

$result['components']['checkout']['children']['steps']['children']['shipping-step']['children']['shippingAddress']['children']['shipping-address-fieldset']['children']['street']['children'][0]['component'] = 'MNM_Spitzner/js/form/field/zip';
$result['components']['checkout']['children']['steps']['children']['shipping-step']['children']['shippingAddress']['children']['shipping-address-fieldset']['children']['street']['children'][0]['config']['elementTmpl'] = 'MNM_Spitzner/form/element/input-with-autocomplete';

//add street fields for housenumber
$result['components']['checkout']['children']['steps']['children']['billing-step']['children']['payment']['children']['afterMethods']['children']['billing-address-form']['children']['form-fields']['children']['street']['children'][2] =
$result['components']['checkout']['children']['steps']['children']['billing-step']['children']['payment']['children']['afterMethods']['children']['billing-address-form']['children']['form-fields']['children']['street']['children'][1];

$result['components']['checkout']['children']['steps']['children']['billing-step']['children']['payment']['children']['afterMethods']['children']['billing-address-form']['children']['form-fields']['children']['street']['children'][1]['dataScope'] = 2;
$result['components']['checkout']['children']['steps']['children']['billing-step']['children']['payment']['children']['afterMethods']['children']['billing-address-form']['children']['form-fields']['children']['street']['children'][1]['label'] = 'Hausnummer';
$result['components']['checkout']['children']['steps']['children']['billing-step']['children']['payment']['children']['afterMethods']['children']['billing-address-form']['children']['form-fields']['children']['street']['children'][1]['validation'] =
$result['components']['checkout']['children']['steps']['children']['billing-step']['children']['payment']['children']['afterMethods']['children']['billing-address-form']['children']['form-fields']['children']['street']['children'][0]['validation'];

$result['components']['checkout']['children']['steps']['children']['billing-step']['children']['payment']['children']['afterMethods']['children']['billing-address-form']['children']['form-fields']['children']['street']['children'][0]['label'] = 'Straße';

$result['components']['checkout']['children']['steps']['children']['shipping-step']['children']['shippingAddress']['children']['shipping-address-fieldset']['children']['street']['children'][2] =
$result['components']['checkout']['children']['steps']['children']['shipping-step']['children']['shippingAddress']['children']['shipping-address-fieldset']['children']['street']['children'][1];

$result['components']['checkout']['children']['steps']['children']['shipping-step']['children']['shippingAddress']['children']['shipping-address-fieldset']['children']['street']['children'][1]['dataScope'] = 2;
$result['components']['checkout']['children']['steps']['children']['shipping-step']['children']['shippingAddress']['children']['shipping-address-fieldset']['children']['street']['children'][1]['label'] = 'Hausnummer';
$result['components']['checkout']['children']['steps']['children']['shipping-step']['children']['shippingAddress']['children']['shipping-address-fieldset']['children']['street']['children'][1]['validation'] =
$result['components']['checkout']['children']['steps']['children']['shipping-step']['children']['shippingAddress']['children']['shipping-address-fieldset']['children']['street']['children'][0]['validation'];

$result['components']['checkout']['children']['steps']['children']['shipping-step']['children']['shippingAddress']['children']['shipping-address-fieldset']['children']['street']['children'][0]['label'] = 'Straße';

//sort address fields
$result['components']['checkout']['children']['steps']['children']['billing-step']['children']['payment']['children']['afterMethods']['children']['billing-address-form']['children']['form-fields']['children']['suffix']['sortOrder'] = 41;
$result['components']['checkout']['children']['steps']['children']['shipping-step']['children']['shippingAddress']['children']['shipping-address-fieldset']['children']['repertus_post_number']['sortOrder'] = 10;
$result['components']['checkout']['children']['steps']['children']['shipping-step']['children']['shippingAddress']['children']['shipping-address-fieldset']['children']['repertus_number']['sortOrder'] = 11;
$result['components']['checkout']['children']['steps']['children']['shipping-step']['children']['shippingAddress']['children']['shipping-address-fieldset']['children']['suffix']['sortOrder'] = 41;

return $result;
}
}

+ 170
- 0
src/app/code/MNM/Spitzner/Plugin/Customer/AddressUpdate.php Voir le fichier

@@ -0,0 +1,170 @@
<?php

namespace MNM\Spitzner\Plugin\Customer;

use Magento\Customer\Api\Data\AddressInterface;
use Magento\Framework\Mail\Template\TransportBuilder;
use Magento\Framework\Translate\Inline\StateInterface;
use Magento\Store\Model\StoreManagerInterface;
use Magento\Framework\App\ObjectManager;
use Magento\Framework\App\Area;
use Magento\Framework\Reflection\DataObjectProcessor;

class AddressUpdate {
const MAIL_TO = 'wellness@spitzner.de';
const MAIL_TEMPLATE = 'spitzner_email_update_address_template';
/**
* @var TransportBuilder
*/
private $transportBuilder;

/**
* @var StateInterface
*/
private $inlineTranslation;

/**
* @var StoreManagerInterface
*/
private $storeManager;
/**
* @var DataObjectProcessor
*/
private $dataProcessor;

/**
* Initialize dependencies.
*
* @param TransportBuilder $transportBuilder
* @param StateInterface $inlineTranslation
* @param StoreManagerInterface|null $storeManager
* @param DataObjectProcessor $dataProcessor
*/
public function __construct(
TransportBuilder $transportBuilder,
StateInterface $inlineTranslation,
StoreManagerInterface $storeManager = null,
DataObjectProcessor $dataProcessor
) {
$this->transportBuilder = $transportBuilder;
$this->inlineTranslation = $inlineTranslation;
$this->storeManager = $storeManager ?: ObjectManager::getInstance()->get(StoreManagerInterface::class);
$this->dataProcessor = $dataProcessor;
}
/**
*
* @param \Magento\Customer\Model\Address $subject
* @param \Magento\Customer\Api\Data\AddressInterface $address
*
* @return \Magento\Customer\Api\Data\AddressInterface
*/
public function beforeUpdateData(\Magento\Customer\Model\Address $subject, \Magento\Customer\Api\Data\AddressInterface $address)
{
$observedAttributes = [ AddressInterface::PREFIX,
AddressInterface::FIRSTNAME,
AddressInterface::LASTNAME,
AddressInterface::SUFFIX,
AddressInterface::COMPANY,
AddressInterface::STREET,
AddressInterface::POSTCODE,
AddressInterface::CITY,
AddressInterface::COUNTRY_ID];
$update = false;
$oldNotEmpty = false;
// Set all attributes
$attributes = $this->dataProcessor
->buildOutputDataArray($address, \Magento\Customer\Api\Data\AddressInterface::class);
//check for changes
foreach ($attributes as $attributeCode => $attributeData)
{
if (in_array($attributeCode, $observedAttributes))
{
$old = $subject->getDataUsingMethod($attributeCode);
$new = $attributeData;
if( $old != $new
&& ( !is_array($new)
|| count($old) == count($new)
|| ( array_filter($old, function($a) {return !empty($a);}) != $new
&& $old != array_filter($new, function($a) {return !empty($a);}))))
{
$update = true;
if(!is_array($old) && !empty($old))
{
$oldNotEmpty = true;
}
}
}
}
if($update && $oldNotEmpty)
{
$old = [];
$new = [];
foreach($observedAttributes as $attributeCode)
{
$old[$attributeCode] = '';
$new[$attributeCode] = '';
}
foreach ($attributes as $attributeCode => $attributeData)
{
if (in_array($attributeCode, $observedAttributes))
{
$old[$attributeCode] = $subject->getDataUsingMethod($attributeCode);
$new[$attributeCode] = $attributeData;
//make sure street has two entries
if($attributeCode == 'street')
{
$old[$attributeCode] = [$old[$attributeCode][0], $old[$attributeCode][1] ?? ''];
$new[$attributeCode] = [$new[$attributeCode][0], $new[$attributeCode][1] ?? ''];
}
}
}
$this->sendMail([
'customer_id' => $subject->getCustomerId(),
'oldAddress' => $old,
'newAddress' => $new
]);
}
}
/**
* Send email
*
* @param array $variables
* @return void
*/
protected function sendMail(array $variables)
{
$this->inlineTranslation->suspend();

try {
$transport = $this->transportBuilder
->setTemplateIdentifier(self::MAIL_TEMPLATE)
->setTemplateOptions(
[
'area' => Area::AREA_FRONTEND,
'store' => $this->storeManager->getStore()->getId()
]
)
->setTemplateVars($variables)
->setFrom(['name' => 'Spitzner Webshop', 'email' => 'wellness@spitzner.de'])
->addTo(self::MAIL_TO)
->getTransport();

$transport->sendMessage();
} finally {
$this->inlineTranslation->resume();
}
}
}

+ 57
- 0
src/app/code/MNM/Spitzner/Plugin/Customer/Api/AddressRepositoryPlugin.php Voir le fichier

@@ -0,0 +1,57 @@
<?php

namespace MNM\Spitzner\Plugin\Customer\Api;

use Magento\Customer\Api\AddressRepositoryInterface;
use Magento\Customer\Api\Data\AddressInterface;
use Magento\Framework\Message\ManagerInterface;
use Psr\Log\LoggerInterface;

class AddressRepositoryPlugin
{
/** @var LoggerInterface */
private $logger;

/**
* @var \Magento\Framework\Message\ManagerInterface
*/
protected $messageManager;

public function __construct(LoggerInterface $logger, ManagerInterface $messageManager)
{
$this->logger = $logger;
$this->messageManager = $messageManager;
}

public function beforeSave(AddressRepositoryInterface $subject, AddressInterface $address)
{
//MNM - add check if custom attribute exists
$repertus_address_type = $address->getCustomAttribute('repertus_address_type')
? (int)$address->getCustomAttribute('repertus_address_type')->getValue()
: null;
$repertus_post_number = $address->getCustomAttribute('repertus_post_number')
? $address->getCustomAttribute('repertus_post_number')->getValue()
: null;
$repertus_number = $address->getCustomAttribute('repertus_number')
? $address->getCustomAttribute('repertus_number')->getValue()
: null;

$this->logger->debug(__METHOD__, [
'type' => $repertus_address_type,
'post_number' => $repertus_post_number,
'number' => $repertus_number,
]);
//MNM

$repertusAddressType = $address->getCustomAttribute('repertus_address_type') ? (int)$address->getCustomAttribute('repertus_address_type')->getValue() : 0;


if ($repertusAddressType != 0 && $address->isDefaultBilling()) {
$this->logger->debug('Unset defaultBilling cause address is a Packstation or Post Office');

$address->setIsDefaultBilling(false);
$this->messageManager->addNoticeMessage(__('Packstation or Post office can not be saved as billing address.'));
}
// TODO: [mka, 11.03.2020] reset postnumber and number for address
}
}

+ 33
- 0
src/app/code/MNM/Spitzner/Plugin/FilterGalleryImages.php Voir le fichier

@@ -0,0 +1,33 @@
<?php

namespace MNM\Spitzner\Plugin;

class FilterGalleryImages
{
/**
*
* @param \Magento\Catalog\Block\Product\View\Gallery $subject
* @param \Magento\Framework\Data\Collection $images
* @return \Magento\Framework\Data\Collection
*/
public function afterGetGalleryImages(\Magento\Catalog\Block\Product\View\Gallery $subject, \Magento\Framework\Data\Collection $images)
{
$product = $subject->getProduct();

foreach ($images->getItems() as $key => $image) {
foreach (array_keys($product->getMediaAttributes()) as $attribute) {
if ($image->getFile() == $product->getData($attribute)) {
$types = $image->getData('types') ?? [];
$types[] = $attribute;
$image->setData('types', $types);
}
}

if($image->getData('types') && !(count($image->getData('types')) == 0 || in_array('image', $image->getData('types')))) {
$images->removeItemByKey($key);
}
}

return $images;
}
}

+ 28
- 0
src/app/code/MNM/Spitzner/Plugin/FilterproductsSortByProductAttribute.php Voir le fichier

@@ -0,0 +1,28 @@
<?php
namespace MNM\Spitzner\Plugin;

class FilterproductsSortByProductAttribute
{
/**
* @param \Smartwave\Filterproducts\Block\Home\LatestList $subject
* @param \Magento\Catalog\Model\ResourceModel\Product\Collection $result
* @return string
*/
public function afterGetProducts(\Smartwave\Filterproducts\Block\Home\LatestList $subject,
\Magento\Catalog\Model\ResourceModel\Product\Collection $result)
{
//check if attribute set
$sortBy = $subject->getData('sort_by');
if($sortBy)
{
//clear sorting
$result->getSelect()->reset(\Magento\Framework\DB\Select::ORDER);
//set to attribute
$result->addAttributeToSort($sortBy, 'asc');
}
return $result;
}
}

+ 33
- 0
src/app/code/MNM/Spitzner/Plugin/ForwardSingleProductListToDetailView.php Voir le fichier

@@ -0,0 +1,33 @@
<?php

namespace MNM\Spitzner\Plugin;

class ForwardSingleProductListToDetailView {
/**
* @var \Magento\Framework\App\Response\Http
*/
protected $response;

public function __construct(
\Magento\Framework\App\Response\Http $response
)
{
$this->response = $response;
}

/**
* @param \Magento\Eav\Model\Entity\Collection\AbstractCollection $resultCollection
* @param \Magento\Catalog\Block\Product\ListProduct $subject
* @return \Magento\Eav\Model\Entity\Collection\AbstractCollection $resultCollection
*/
public function afterGetLoadedProductCollection(\Magento\Catalog\Block\Product\ListProduct $subject, $resultCollection)
{
if ($resultCollection->count() == 1) {
/** @var \Magento\Catalog\Model\Product $product */
$product = $resultCollection->getFirstItem();
$this->response->setRedirect($product->getProductUrl());
}

return $resultCollection;
}
}

+ 18
- 0
src/app/code/MNM/Spitzner/Plugin/GroupedProductsGetAssociatedProductsCollection.php Voir le fichier

@@ -0,0 +1,18 @@
<?php
namespace MNM\Spitzner\Plugin;

class GroupedProductsGetAssociatedProductsCollection
{
/**
* @param \Magento\GroupedProduct\Model\Product\Type\Grouped $subject
* @param \Magento\Catalog\Model\ResourceModel\Product\Collection $result
* @return string
*/
public function aftergetAssociatedProductCollection(\Magento\GroupedProduct\Model\Product\Type\Grouped $subject,
\Magento\Catalog\Model\ResourceModel\Product\Link\Product\Collection $result)
{
$result->addAttributeToSelect(['spi_inhalt', 'spi_normalized_volume', 'spi_normalized_price', 'spi_aponow_pzn', 'spi_aponow_link']);

return $result;
}
}

+ 14
- 0
src/app/code/MNM/Spitzner/Plugin/OfflineShipping/AddTablerateConditionWithoutDiscount.php Voir le fichier

@@ -0,0 +1,14 @@
<?php

namespace MNM\Spitzner\Plugin\OfflineShipping;

class AddTablerateConditionWithoutDiscount {
public function afterGetCode(\Magento\OfflineShipping\Model\Carrier\Tablerate $subject, $result, $type, $code = '')
{
if ('' === $code) {
$result['package_value'] = __('Price vs. Destination (excl. discount)');
}

return $result;
}
}

+ 19
- 0
src/app/code/MNM/Spitzner/Plugin/Payment/Block/Info/Instructions.php Voir le fichier

@@ -0,0 +1,19 @@
<?php

namespace MNM\Spitzner\Plugin\Payment\Block\Info;

/**
* Bugfix for Extension "Threepartment_Debitpayment"
* https://github.com/magento/magento2/issues/31126
*
* Class Instructions
* @package MNM\Spitzner\Plugin\Payment\Block\Info
*/
class Instructions
{
public function afterGetInstructions(\Magento\Payment\Block\Info\Instructions $subject, $result)
{
if (is_array($result)) { $result = ""; }
return $result;
}
}

+ 86
- 0
src/app/code/MNM/Spitzner/Plugin/Quote/FixMissingHousenumber.php Voir le fichier

@@ -0,0 +1,86 @@
<?php

namespace MNM\Spitzner\Plugin\Quote;

/**
* Try to fix missing housenumber in billing address
*/
class FixMissingHousenumber {
/**
* Set billing address.
*
* @param \Magento\Quote\Model\Quote $quote
* @param \Magento\Quote\Api\Data\AddressInterface $address
* @return \Magento\Quote\Api\Data\AddressInterface
*/
public function beforeSetBillingAddress(\Magento\Quote\Model\Quote $quote,
\Magento\Quote\Api\Data\AddressInterface $address = null)
{
if($address)
{
$street = $address->getStreet();
$old = $quote->getAddressesCollection()->getItemById($address->getId())
?? $quote->getBillingAddress();

//check if address has no housenumber
if(is_array($street) && !preg_match('/\d+/', $street[0]))
{
//check if "old" address has housenumber and street starts with same 4 letters
if(!empty($old)
&& is_array($old->getStreet())
&& preg_match('/\d+/', $old->getStreet()[0])
&& strncasecmp($street[0], $old->getStreet()[0], 5) === 0)
{
$street[0] = $old->getStreet()[0];
$address->setStreet($street);
}
else
{
$shippingAddress = $quote->getShippingAddress();

if(!empty($shippingAddress)
&& is_array($shippingAddress->getStreet())
&& preg_match('/\d+/', $shippingAddress->getStreet()[0])
&& strncasecmp($street[0], $shippingAddress->getStreet()[0], 5) === 0)
{
$street[0] = $shippingAddress->getStreet()[0];
$address->setStreet($street);
}
}
}
}

return [$address];
}

/**
* Set shipping address
*
* @param \Magento\Quote\Model\Quote $quote
* @param \Magento\Quote\Api\Data\AddressInterface $address
* @return \Magento\Quote\Api\Data\AddressInterface
*/
public function beforeSetShippingAddress(\Magento\Quote\Model\Quote $quote,
\Magento\Quote\Api\Data\AddressInterface $address = null)
{
if($address)
{
$street = $address->getStreet();
$billingAddress = $quote->getBillingAddress();
$billingAddressStreet = $billingAddress->getStreet();

//check if address has housenumber and billing street not, but start similar
if( is_array($street)
&& preg_match('/\d+/', $street[0])
&& is_array($billingAddressStreet)
&& !preg_match('/\d+/', $billingAddressStreet[0])
&& strncasecmp($street[0], $billingAddressStreet[0], 5) === 0)
{
$billingAddressStreet[0] = $street[0];
$billingAddress->setStreet($billingAddressStreet);
}
}

return [$address];
}
}

+ 59
- 0
src/app/code/MNM/Spitzner/Plugin/Quote/FixPaypalGuestCheckoutBug.php Voir le fichier

@@ -0,0 +1,59 @@
<?php

namespace MNM\Spitzner\Plugin\Quote;

use Magento\Quote\Observer\Frontend\Quote\Address\CollectTotalsObserver;
use Magento\Quote\Observer\Frontend\Quote\Address\VatValidator;
use Magento\Framework\Event\Observer;

class FixPaypalGuestCheckoutBug {
/**
* @var VatValidator
*/
protected $vatValidator;

/**
* Initialize dependencies.
*
* @param VatValidator $vatValidator
*/
public function __construct(
VatValidator $vatValidator
) {
$this->vatValidator = $vatValidator;
}

/**
*
* @param CollectTotalsObserver $subject
* @param callable $proceed
* @param Observer $observer
* @return void
*/
public function aroundExecute(CollectTotalsObserver $subject, callable $proceed, Observer $observer)
{
$proceed($observer);

/** @var \Magento\Quote\Api\Data\ShippingAssignmentInterface $shippingAssignment */
$shippingAssignment = $observer->getShippingAssignment();
/** @var \Magento\Quote\Model\Quote $quote */
$quote = $observer->getQuote();
/** @var \Magento\Quote\Model\Quote\Address $address */
$address = $shippingAssignment->getShipping()->getAddress();

$customer = $quote->getCustomer();
$storeId = $customer->getStoreId();

if ($customer->getDisableAutoGroupChange()
|| false == $this->vatValidator->isEnabled($address, $storeId)
) {
return;
}

if($quote->getCustomerGroupId() !== null)
{
$customer->setEmail($customer->getEmail() ?: $quote->getCustomerEmail());
$quote->setCustomer($customer);
}
}
}

+ 67
- 0
src/app/code/MNM/Spitzner/Plugin/Quote/Model/Quote/Address/PrefixPatch.php Voir le fichier

@@ -0,0 +1,67 @@
<?php

declare(strict_types=1);

namespace MNM\Spitzner\Plugin\Quote\Model\Quote\Address;

use Magento\Quote\Model\Quote\Address;
use Magento\Customer\Model\Options;

class PrefixPatch
{
protected Options $options;

public function __construct(Options $options)
{
$this->options = $options;
}

public function afterGetData(Address $subject, $result)
{
if (is_array($result) && array_key_exists('prefix', $result)
&& (!empty($result['prefix'])
|| $result['prefix'] === "0")) {
$result['prefix'] = $this->formatPrefix($result['prefix']);
}

if (is_array($result) && array_key_exists('suffix', $result)
&& (!empty($result['suffix'])
|| $result['suffix'] === "0")) {
$result['suffix'] = $this->formatSuffix($result['suffix']);
}

return $result;
}

public function afterGetPrefix(Address $subject, $result)
{
return $this->formatPrefix($result);
}

public function afterGetSuffix(Address $subject, $result)
{
return $this->formatSuffix($result);
}

private function formatPrefix(?string $prefixValue): ?string
{
if($prefixValue == '3' || $prefixValue == 'keine Angabe') {
return '';
}

if (array_key_exists($prefixValue, $prefixOptions = $this->options->getNamePrefixOptions())) {
return $prefixOptions[$prefixValue];
}

return $prefixValue;
}

private function formatSuffix(?string $suffixValue): ?string
{
if (array_key_exists($suffixValue, $suffixOptions = $this->options->getNameSuffixOptions())) {
return $suffixOptions[$suffixValue];
}

return $suffixValue;
}
}

+ 23
- 0
src/app/code/MNM/Spitzner/Plugin/RemoveAmpromoSalesRuleLabel.php Voir le fichier

@@ -0,0 +1,23 @@
<?php

namespace MNM\Spitzner\Plugin;

class RemoveAmpromoSalesRuleLabel
{
/**
* @param \Magento\SalesRule\Model\RulesApplier $subject
* @param callable $result
* @param \Magento\Quote\Model\Quote\Address $address
* @param \Magento\SalesRule\Model\Rule $rule
* @return array
*/
public function aroundAddDiscountDescription(\Magento\SalesRule\Model\RulesApplier $subject, callable $proceed, $address, $rule)
{
if(strpos($rule->getSimpleAction(), 'ampromo_cart') === false)
{
$proceed($address, $rule);
}

return $subject;
}
}

+ 22
- 0
src/app/code/MNM/Spitzner/Plugin/ReorderCheckout.php Voir le fichier

@@ -0,0 +1,22 @@
<?php

namespace MNM\Spitzner\Plugin;

use Amasty\CheckoutCore\Model\ConfigProvider;

class ReorderCheckout
{
/**
* @param ConfigProvider $subject
* @param array $result
* @return array
*/
public function afterGetConfig(ConfigProvider $subject, $result)
{
//move second part of col 3 to col 4
$result[ConfigProvider::CONFIG_KEY][] = [$result[ConfigProvider::CONFIG_KEY][2][1]];
unset($result[ConfigProvider::CONFIG_KEY][2][1]);

return $result;
}
}

+ 51
- 0
src/app/code/MNM/Spitzner/Plugin/Review/RemoveRequiredFields.php Voir le fichier

@@ -0,0 +1,51 @@
<?php

namespace MNM\Spitzner\Plugin\Review;

class RemoveRequiredFields
{
/**
* @var \MNM\Spitzner\Helper\Data
*/
private $helper;

public function __construct(\MNM\Spitzner\Helper\Data $helper)
{
$this->helper = $helper;
}

/**
* Modify validation
*
* @param \Magento\Checkout\Model\DefaultConfigProvider $subject
* @param bool|string[] $errors
*
* @return bool|string[]
*/
public function afterValidate(\Magento\Review\Model\Review $subject, $errors)
{
$errors = [];

/*MNM
if (!\Zend_Validate::is($this->getTitle(), 'NotEmpty')) {
$errors[] = __('Please enter a review summary.');
}*/

if (!\Zend_Validate::is($subject->getNickname(), 'NotEmpty')) {
$errors[] = __('Please enter a nickname.');
}

/*MNM
if (!\Zend_Validate::is($this->getDetail(), 'NotEmpty')) {
$errors[] = __('Please enter a review.');
}*/

if (empty($errors)) {
//MNM
$this->helper->sendMail('susanne.bisch-moser@spitzner.de', 'spitzner_email_new_review');

return true;
}
return $errors;
}
}

+ 54
- 0
src/app/code/MNM/Spitzner/Plugin/Sales/Model/Order/Address/PrefixPatch.php Voir le fichier

@@ -0,0 +1,54 @@
<?php namespace MNM\Spitzner\Plugin\Sales\Model\Order\Address;

use Magento\Sales\Model\Order\Address;
use Magento\Customer\Model\Options;

class PrefixPatch {

protected $options;

public function __construct(
Options $options
) {
$this->options = $options;
}

public function afterGetData(Address $subject, $result)
{
if (is_array($result) && array_key_exists('prefix', $result) && (!empty($result['prefix']) || $result['prefix'] === "0")) {
$result['prefix'] = $this->formatPrefix($result['prefix']);
}
if (is_array($result) && array_key_exists('suffix', $result) && (!empty($result['suffix']) || $result['suffix'] === "0")) {
$result['suffix'] = $this->formatSuffix($result['suffix']);
}
return $result;
}

public function afterGetPrefix(Address $subject, $result)
{
return $this->formatPrefix($result);
}

public function afterGetSuffix(Address $subject, $result)
{
return $this->formatSuffix($result);
}

private function formatPrefix(?string $prefixValue) : ?string {
if($prefixValue == '3' || $prefixValue == 'keine Angabe') {
return '';
}

if (array_key_exists($prefixValue, $prefixOptions = $this->options->getNamePrefixOptions())) {
return $prefixOptions[$prefixValue];
}
return $prefixValue;
}

private function formatSuffix(?string $suffixValue) : ?string {
if (array_key_exists($suffixValue, $suffixOptions = $this->options->getNameSuffixOptions())) {
return $suffixOptions[$suffixValue];
}
return $suffixValue;
}
}

+ 19
- 0
src/app/code/MNM/Spitzner/Plugin/SaveCheckoutEmailInSession.php Voir le fichier

@@ -0,0 +1,19 @@
<?php

namespace MNM\Spitzner\Plugin;

class SaveCheckoutEmailInSession {
private $checkoutSession;

public function __construct(\Magento\Checkout\Model\Session $checkoutSession)
{
$this->checkoutSession = $checkoutSession;
}

public function beforeIsEmailAvailable(\Magento\Customer\Model\AccountManagement $subject, $email, $websiteId = null)
{
$this->checkoutSession->setSpitznerCheckoutEmail($email);

return null;
}
}

+ 88
- 0
src/app/code/MNM/Spitzner/Plugin/Stockstatus/AddDefaultStockWrapper.php Voir le fichier

@@ -0,0 +1,88 @@
<?php

namespace MNM\Spitzner\Plugin\Stockstatus;

class AddDefaultStockWrapper
{
/**
* @var \Magento\CatalogInventory\Api\StockRegistryInterface
*/
private $stockRegistry;
/**
* @var \Magento\Store\Model\StoreManagerInterface
*/
private $storeManager;
/**
*
* @var unknown
*/
private $product;
/**
*
* @param \Magento\CatalogInventory\Api\StockRegistryInterface $stockRegistry
* @param \Magento\Store\Model\StoreManagerInterface $storeManager
*/
public function __construct(\Magento\CatalogInventory\Api\StockRegistryInterface $stockRegistry,
\Magento\Store\Model\StoreManagerInterface $storeManager)
{
$this->stockRegistry = $stockRegistry;
$this->storeManager = $storeManager;
}
/**
* Modify stock status
*
* @param \Amasty\Stockstatus\Helper\Data $subject
* @param callable $proceed
* @param $product
* @param bool $addWrapper
* @param bool $isProductList
* @param $storeId
* @return NULL
*/
public function beforeShowStockStatus(\Amasty\Stockstatus\Helper\Data $subject,
$product,
$addWrapper = false,
$isProductList = false,
$storeId = null)
{
$this->product = $product;
return null;
}
/**
*
* @param \Amasty\Stockstatus\Helper\Data $subject
* @param string $result
* @return string
*/
public function afterShowStockStatus(\Amasty\Stockstatus\Helper\Data $subject, $result)
{
$beginning = '<div class="stock">';
$bl = strlen($beginning);
if(strpos($result, $beginning) === 0)
{
$stockStatus = $this->stockRegistry->getStockStatus($this->product->getId(),
$this->storeManager->getWebsite()->getId());
if(!$stockStatus->getStockStatus())
{
$result = '<div class="stock unavailable">'.'<span class="default-stock">'.substr($result, $bl, strpos($result, '<span') - $bl).'</span></div>';
}
else
{
$result = $beginning.
'<span class="default-stock">'.
substr($result, $bl, strpos($result, '<span') - $bl).
'</span>'.substr($result, strpos($result, '<span'));
}
}
return $result;
}
}

+ 22
- 0
src/app/code/MNM/Spitzner/composer.json Voir le fichier

@@ -0,0 +1,22 @@
{
"name" : "MNM/Spitzner",
"description" : "Providing config for migration",
"config" : {
"sort-packages" : true
},
"require" : {
"magento/framework" : "*",
"smartwave/module-filterproducts" : "*",
"repertus/packstation" : "*",
"amasty/module-single-step-checkout": "*",
"amasty/module-advanced-conditions": "*"
},
"type" : "magento2-module",
"autoload": {
"files": [ "registration.php" ],
"psr-4": {
"MNM\\Spitzner\\": ""
}
},
"version" : "1.0.0"
}

+ 9
- 0
src/app/code/MNM/Spitzner/etc/adminhtml/menu.xml Voir le fichier

@@ -0,0 +1,9 @@
<?xml version="1.0" ?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Backend:etc/menu.xsd">
<menu>
<update id="Mageprince_Faq::menu" title="Inhaltsstoffe"/>
<update id="Mageprince_Faq::faqgroup" title="Gruppe (Buchstaben)"/>
<update id="Mageprince_Faq::faq" title="Inhaltsstoffe"/>
<update id="Mageprince_Faq::configuration" title="Konfiguration"/>
</menu>
</config>

+ 12
- 0
src/app/code/MNM/Spitzner/etc/adminhtml/system.xml Voir le fichier

@@ -0,0 +1,12 @@
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Config:etc/system_file.xsd">
<system>
<section id="payment">
<group id="debitpayment" translate="label" sortOrder="2" showInDefault="1" showInWebsite="1" showInStore="1">
<field id="title" translate="label" type="text" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Title</label>
</field>
</group>
</section>
</system>
</config>

+ 20
- 0
src/app/code/MNM/Spitzner/etc/catalog_attributes.xml Voir le fichier

@@ -0,0 +1,20 @@
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Catalog:etc/catalog_attributes.xsd">
<group name="quote_item">
<attribute name="spi_inhalt" />
<attribute name="spi_sku" />
<attribute name="spi_normalized_volume" />
<attribute name="spi_normalized_price" />
<attribute name="spi_aponow_pzn" />
<attribute name="spi_aponow_link" />
</group>
<group name="catalog_product">
<attribute name="spi_inhalt" />
<attribute name="spi_sku" />
<attribute name="spi_normalized_volume" />
<attribute name="spi_normalized_price" />
<attribute name="spi_aponow_pzn" />
<attribute name="spi_aponow_link" />
</group>
</config>

+ 13
- 0
src/app/code/MNM/Spitzner/etc/config.xml Voir le fichier

@@ -0,0 +1,13 @@
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Store:etc/config.xsd">
<default>
<payment>
<debitpayment>
<sort_order>100</sort_order>
</debitpayment>
<purchaseorder>
<sort_order>1</sort_order>
</purchaseorder>
</payment>
</default>
</config>

+ 11
- 0
src/app/code/MNM/Spitzner/etc/crontab.xml Voir le fichier

@@ -0,0 +1,11 @@
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Cron:etc/crontab.xsd">
<group id="index">
<job name="export_orders_cronjob" instance="MNM\Spitzner\Cron\ExportOrders" method="execute">
<schedule>0,30 * * * *</schedule>
</job>
<job name="clear_caches_cronjob" instance="MNM\Spitzner\Cron\ClearCaches" method="execute">
<schedule>15 3 * * *</schedule>
</job>
</group>
</config>

+ 72
- 0
src/app/code/MNM/Spitzner/etc/csp_whitelist.xml Voir le fichier

@@ -0,0 +1,72 @@
<?xml version="1.0"?>
<csp_whitelist xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Csp/etc/csp_whitelist.xsd">
<policies>
<policy id="script-src">
<values>
<value id="usercentric" type="host">*.usercentrics.eu</value>
<value id="trustedshops" type="host">*.trustedshops.com</value>
<value id="googleanalytics" type="host">*.google-analytics.com</value>
<value id="google" type="host">*.google.com</value>
<value id="bing" type="host">*.bing.com</value>
<value id="doubleclick" type="host">googleads.g.doubleclick.net</value>
<value id="virtualearth" type="host">*.virtualearth.net</value>
<value id="googlestatic" type="host">*.gstatic.com</value>
<value id="postcodeanywhere" type="host">services.postcodeanywhere.co.uk</value>
<value id="googleadservices" type="host">*.googleadservices.com</value>
<value id="sendinblue" type="host">sibforms.com</value>
</values>
</policy>
<policy id="style-src">
<values>
<value id="googlefonts" type="host">fonts.googleapis.com</value>
<value id="bing" type="host">*.bing.com</value>
<value id="sendinblue" type="host">sibforms.com</value>
</values>
</policy>
<policy id="img-src">
<values>
<value id="usercentric" type="host">*.usercentrics.eu</value>
<value id="trustedshops" type="host">*.trustedshops.com</value>
<value id="googleanalytics" type="host">*.google-analytics.com</value>
<value id="bing" type="host">*.bing.com</value>
<value id="google" type="host">*.google.com</value>
<value id="googlede" type="host">*.google.de</value>
<value id="spitzner" type="host">*.spitzner.de</value>
<value id="virtualearth" type="host">*.virtualearth.net</value>
<value id="googletagmanager" type="host">*.googletagmanager.com</value>
</values>
</policy>
<policy id="connect-src">
<values>
<value id="usercentric" type="host">*.usercentrics.eu</value>
<value id="trustedshops" type="host">*.trustedshops.com</value>
<value id="doubleclick" type="host">stats.g.doubleclick.net</value>
<value id="etrusted" type="host">trustbadge.api.etrusted.com</value>
<value id="googleanalytics" type="host">*.google-analytics.com</value>
<value id="bing" type="host">*.bing.com</value>
<value id="google" type="host">*.google.com</value>
<value id="doubleclick" type="host">googleads.g.doubleclick.net</value>
<value id="sendinblue" type="host">*.sibforms.com</value>
</values>
</policy>
<policy id="font-src">
<values>
<value id="googlefontsstatic" type="host">fonts.gstatic.com</value>
<value id="data" type="host">'self' data:</value>
<value id="sendinblue" type="host">assets.sendinblue.com</value>
</values>
</policy>
<policy id="frame-src">
<values>
<value id="youtubenocookies" type="host">*.youtube-nocookie.com</value>
<value id="sendinblue" type="host">*.sibforms.com</value>
</values>
</policy>
<policy id="form-action">
<values>
<value id="mailchimp" type="host">spitzner.us17.list-manage.com</value>
<value id="sendinblue" type="host">*.sibforms.com</value>
</values>
</policy>
</policies>
</csp_whitelist>

+ 10
- 0
src/app/code/MNM/Spitzner/etc/db_schema.xml Voir le fichier

@@ -0,0 +1,10 @@
<schema xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Setup/Declaration/Schema/etc/schema.xsd">
<table name="spitzner_export_log" engine="innodb" resource="default">
<column xsi:type="int" name="exportlog_id" padding="10" unsigned="true" nullable="false" comment="Entity Id" identity="true"/>
<column xsi:type="datetime" name="exported_at"/>
<column xsi:type="int" name="last_exported_order_id" padding="10" unsigned="true" nullable="false"/>
<constraint xsi:type="primary" referenceId="PRIMARY">
<column name="exportlog_id"/>
</constraint>
</table>
</schema>

+ 146
- 0
src/app/code/MNM/Spitzner/etc/di.xml Voir le fichier

@@ -0,0 +1,146 @@
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/ObjectManager/etc/config.xsd">
<type name="Smartwave\Filterproducts\Block\Home\LatestList">
<plugin name="MNM_filterproducts_sort_by_product_attribute"
type="MNM\Spitzner\Plugin\FilterproductsSortByProductAttribute" />
</type>
<type name="Magento\GroupedProduct\Model\Product\Type\Grouped">
<plugin name="MNM_grouped_products_get_associated_products_collection"
type="MNM\Spitzner\Plugin\GroupedProductsGetAssociatedProductsCollection" />
</type>
<type name="Amasty\Stockstatus\Helper\Data">
<plugin name="MNM_add_stock_label"
type="MNM\Spitzner\Plugin\AddStockLabel" />
</type>
<type name="Mageprince\Faq\Block\Index\Index">
<plugin name="MNM_change_faq_collection"
type="MNM\Spitzner\Plugin\ChangeFaqCollection" />
</type>
<type name="\Magento\Checkout\Block\Checkout\LayoutProcessor">
<plugin name="MNM_checkoutlayout_adaption"
type="MNM\Spitzner\Plugin\CheckoutLayoutAdaption"
sortOrder="10" />
</type>
<type name="Amasty\CheckoutCore\Model\ConfigProvider">
<plugin name="MNM_reorder_checkout"
type="MNM\Spitzner\Plugin\ReorderCheckout" />
</type>
<type name="Magento\Checkout\Model\DefaultConfigProvider">
<plugin name="MNM_add_checkout_item_price_per_unit"
type="MNM\Spitzner\Plugin\AddCheckoutItemPricePerUnit" />
</type>
<type name="Magento\Customer\Api\AddressRepositoryInterface">
<plugin name="repertus_packstation_customer_api_address_repository"
type="MNM\Spitzner\Plugin\Customer\Api\AddressRepositoryPlugin" />
</type>
<type name="Magento\Checkout\Block\Cart\AbstractCart">
<plugin name="Amasty_Stockstatus::ShowStatusonCart"
disabled="true" />
<plugin name="mnm_cart_abstract_cart"
type="MNM\Spitzner\Plugin\Cart\AbstractCart" />
</type>
<type name="Amasty\Stockstatus\Helper\Data">
<plugin name="MNM_AddCheckoutItemPricePerUnit"
type="MNM\Spitzner\Plugin\Stockstatus\AddDefaultStockWrapper" />
</type>
<type name="Magento\SalesRule\Model\RulesApplier">
<plugin name="MNM_RemoveAmpromoSalesRuleLabel"
type="MNM\Spitzner\Plugin\RemoveAmpromoSalesRuleLabel" />
</type>
<type name="Magento\Customer\Model\AccountManagement">
<plugin name="MNM_SaveCheckoutEmailInSession"
type="MNM\Spitzner\Plugin\SaveCheckoutEmailInSession" />
</type>
<type name="Magento\Catalog\Block\Product\ListProduct">
<plugin name="MNM_firstproductCategoryMod"
type="MNM\Spitzner\Plugin\ForwardSingleProductListToDetailView" />
</type>
<type name="Magento\Catalog\Block\Product\View\Gallery">
<plugin name="MNM_filtergalleryimages"
type="MNM\Spitzner\Plugin\FilterGalleryImages" />
</type>
<type name="Magento\Checkout\Model\ShippingInformationManagement">
<plugin name="MNM_save_in_quote"
type="MNM\Spitzner\Plugin\Checkout\ShippingInformationManagementPlugin"
sortOrder="2" />
</type>
<type name="Magento\Customer\Model\Address">
<plugin name="MNM_address_update"
type="MNM\Spitzner\Plugin\Customer\AddressUpdate" />
</type>
<type name="Amasty\Promo\Model\ItemRegistry\PromoItemRegistry">
<plugin name="MNM_prevent_reset"
type="MNM\Spitzner\Plugin\Amasty\Promo\PreventResetQtyAllowed" />
</type>
<type name="Magento\Paypal\Model\Express\Checkout">
<plugin name="MNM_paypal_guest_add_name"
type="MNM\Spitzner\Plugin\AddCustomerNameToPaypalGuestQuote" />
</type>
<type name="Magento\Quote\Observer\Frontend\Quote\Address\CollectTotalsObserver">
<plugin name="MNM_fix_paypal_gc_bug"
type="MNM\Spitzner\Plugin\Quote\FixPaypalGuestCheckoutBug" />
</type>
<type name="Magento\Review\Model\Review">
<plugin name="MNM_review_remove_required"
type="MNM\Spitzner\Plugin\Review\RemoveRequiredFields" />
</type>
<type name="Magento\Quote\Model\Quote">
<plugin name="MNM_fix_missing_housenumber"
type="MNM\Spitzner\Plugin\Quote\FixMissingHousenumber" />
</type>
<type name="Magento\Payment\Block\Info\Instructions">
<plugin name="mnm_spitzner_payment_instructions"
type="MNM\Spitzner\Plugin\Payment\Block\Info\Instructions"
sortOrder="10"/>
</type>
<type name="Magento\Sales\Model\Order\Address">
<plugin name="patch_prefix_integers_order"
type="MNM\Spitzner\Plugin\Sales\Model\Order\Address\PrefixPatch" />
</type>
<type name="Magento\Quote\Model\Quote\Address">
<plugin name="patch_prefix_integers_quote"
type="MNM\Spitzner\Plugin\Quote\Model\Quote\Address\PrefixPatch" />
</type>
<type name="Magento\OfflineShipping\Model\Carrier\Tablerate">
<plugin name="mnm_add_tablerate_condition"
type="MNM\Spitzner\Plugin\OfflineShipping\AddTablerateConditionWithoutDiscount" />
</type>

<preference for="Magebees\Ajaxaddtocart\Controller\Cart\Add"
type="MNM\Spitzner\Controller\Cart\Add" />
<preference for="Smartwave\Megamenu\Block\Topmenu"
type="MNM\Spitzner\Block\Topmenu" />
<preference for="Magebees\Ajaxaddtocart\Observer\Addtocart"
type="MNM\Spitzner\Observer\Addtocart" />
<preference for="Amasty\Conditions\Model\Rule\Condition\CustomerAttributes"
type="MNM\Spitzner\Model\Rule\Condition\CustomerAttributes" />
<preference for="Threepartment\Debitpayment\Block\Info\Debitpayment"
type="MNM\Spitzner\Block\Info\Debitpayment" />
<preference for="Magento\Review\Block\Adminhtml\Edit\Form"
type="MNM\Spitzner\Block\Magento\Review\Adminhtml\Edit\Form" />
<preference for="Magento\Customer\Block\Widget\Name"
type="MNM\Spitzner\Block\Magento\Customer\Widget\Name" />
<preference for="Sendinblue\Sendinblue\Model\Transport"
type="MNM\Spitzner\Overwrite\Model\Transport" />

<type name="Magento\Framework\Console\CommandList">
<arguments>
<argument name="commands" xsi:type="array">
<item name="mnm_spitzner_export_orders"
xsi:type="object">MNM\Spitzner\Console\ExportOrders</item>
</argument>
</arguments>
</type>
<!-- Admin theme. Start -->
<type name="Magento\Theme\Model\View\Design">
<arguments>
<argument name="themes" xsi:type="array">
<item name="adminhtml" xsi:type="string">MNM/spitzner</item>
</argument>
</arguments>
</type>
<!-- Admin theme. End -->
</config>

+ 11
- 0
src/app/code/MNM/Spitzner/etc/email_templates.xml Voir le fichier

@@ -0,0 +1,11 @@
<?xml version="1.0"?>
<!--
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Email:etc/email_templates.xsd">
<template id="spitzner_email_update_address_template" label="Update Address Email" file="address_update.html" type="html" module="MNM_Spitzner" area="frontend"/>
<template id="spitzner_email_new_review" label="New Review Email" file="new_review.html" type="html" module="MNM_Spitzner" area="frontend"/>
</config>

+ 9
- 0
src/app/code/MNM/Spitzner/etc/events.xml Voir le fichier

@@ -0,0 +1,9 @@
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
<event name="email_order_set_template_vars_before">
<observer name="mnm_spitzner_email_variables" instance="MNM\Spitzner\Observer\AddEmailVariables" />
</event>
<event name="sales_model_service_quote_submit_before">
<observer name="mnm_spitzner_sales_model_service_quote_submit_before" instance="MNM\Spitzner\Observer\CheckOrderAddresses" />
</event>
</config>

+ 13
- 0
src/app/code/MNM/Spitzner/etc/module.xml Voir le fichier

@@ -0,0 +1,13 @@
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/Module/etc/module.xsd">
<module name="MNM_Spitzner" setup_version="1.0.0">
<sequence>
<module name="Repertus_Packstation"/>
<module name="Amasty_Stockstatus"/>
<module name="Amasty_Checkout"/>
<module name="Amasty_Conditions"/>
<module name="Threepartment_Debitpayment"/>
<module name="Magento_Theme"/>
</sequence>
</module>
</config>

+ 28
- 0
src/app/code/MNM/Spitzner/etc/view.xml Voir le fichier

@@ -0,0 +1,28 @@
<?xml version="1.0"?>
<!--
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
-->
<view xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Config/etc/view.xsd">
<media>
<images module="Magento_Catalog">
<image id="cart_page_product_thumbnail" type="small_image">
<width>100</width>
<height>100</height>
</image>
</images>
</media>
<vars module="Magento_Catalog">
<!-- Gallery and magnifier theme settings. Start -->
<var name="gallery">
<var name="loop">false</var> <!-- Gallery navigation loop (true/false) -->
<var name="keyboard">true</var> <!-- Turn on/off keyboard arrows navigation (true/false) -->
<var name="arrows">false</var> <!-- Turn on/off arrows on the sides preview (true/false) -->
<var name="allowfullscreen">false</var> <!-- Turn on/off fullscreen (true/false) -->
<var name="navarrows">true</var> <!-- Turn on/off on the thumbs navigation sides arrows(true/false) -->
<var name="navtype">slides</var> <!-- Sliding type of thumbnails (slides/thumbs) -->
</var>
</vars>
</view>

+ 1
- 0
src/app/code/MNM/Spitzner/i18n/de_DE.csv Voir le fichier

@@ -0,0 +1 @@
"Adress Update","Adress Update"

+ 7
- 0
src/app/code/MNM/Spitzner/registration.php Voir le fichier

@@ -0,0 +1,7 @@
<?php

\Magento\Framework\Component\ComponentRegistrar::register(
\Magento\Framework\Component\ComponentRegistrar::MODULE,
'MNM_Spitzner',
__DIR__
);

+ 72
- 0
src/app/code/MNM/Spitzner/view/frontend/email/address_update.html Voir le fichier

@@ -0,0 +1,72 @@
<!--
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
-->
<!--@subject Webshop: Kunden Adress Update @-->
<!--@vars {
"var data.comment":"Comment",
"var data.email":"Sender Email",
"var data.name":"Sender Name",
"var data.telephone":"Sender Telephone"
} @-->

{{template config_path="design/email/header_template"}}

<p>Kunde/-in mit ID {{var customer_id}} (Magento) hat folgende Adresse aktualisiert:</p>

<table class="message-details">
<tr>
<th></th>
<th>Bisher</th>
<th>Aktuell</th>
</tr>
<tr>
<td><strong>{{trans "Anrede"}}</strong></td>
<td>{{var oldAddress.prefix}}</td>
<td>{{var newAddress.prefix}}</td>
</tr>
<tr>
<td><strong>{{trans "Titel"}}</strong></td>
<td>{{var oldAddress.suffix}}</td>
<td>{{var newAddress.suffix}}</td>
</tr>
<tr>
<td><strong>{{trans "Vorname"}}</strong></td>
<td>{{var oldAddress.firstname}}</td>
<td>{{var newAddress.firstname}}</td>
</tr>
<tr>
<td><strong>{{trans "Nachname"}}</strong></td>
<td>{{var oldAddress.lastname}}</td>
<td>{{var newAddress.lastname}}</td>
</tr>
<tr>
<td><strong>{{trans "Firma"}}</strong></td>
<td>{{var oldAddress.company}}</td>
<td>{{var newAddress.company}}</td>
</tr>
<tr>
<td><strong>{{trans "Straße und Hausnummer"}}</strong></td>
<td>{{var oldAddress.street.0}}<br>{{var oldAddress.street.1}}</td>
<td>{{var newAddress.street.0}}<br>{{var newAddress.street.1}}</td>
</tr>
<tr>
<td><strong>{{trans "PLZ"}}</strong></td>
<td>{{var oldAddress.postcode}}</td>
<td>{{var newAddress.postcode}}</td>
</tr>
<tr>
<td><strong>{{trans "Ort"}}</strong></td>
<td>{{var oldAddress.city}}</td>
<td>{{var newAddress.city}}</td>
</tr>
<tr>
<td><strong>{{trans "Land"}}</strong></td>
<td>{{var oldAddress.country_id}}</td>
<td>{{var newAddress.country_id}}</td>
</tr>
</table>

{{template config_path="design/email/footer_template"}}

+ 20
- 0
src/app/code/MNM/Spitzner/view/frontend/email/new_review.html Voir le fichier

@@ -0,0 +1,20 @@
<!--
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
-->
<!--@subject Webshop: Neue Produkt-Bewertung @-->
<!--@vars {
"var data.comment":"Comment",
"var data.email":"Sender Email",
"var data.name":"Sender Name",
"var data.telephone":"Sender Telephone"
} @-->

{{template config_path="design/email/header_template"}}

Es wurde eine neue Produkt-Bewertung abgegeben.
Bitte loggen Sie sich im Magento Backend ein und prüfen Sie die Freigabe unter "Marketing" -> "Ausstehende Bewertungen".

{{template config_path="design/email/footer_template"}}

+ 37
- 0
src/app/code/MNM/Spitzner/view/frontend/layout/checkout_index_index.xml Voir le fichier

@@ -0,0 +1,37 @@
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="1column" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<body>
<referenceBlock name="checkout.root">
<arguments>
<argument name="jsLayout" xsi:type="array">
<item name="components" xsi:type="array">
<item name="checkout" xsi:type="array">
<item name="children" xsi:type="array">
<item name="steps" xsi:type="array">
<item name="children" xsi:type="array">
<item name="billing-step" xsi:type="array">
<item name="children" xsi:type="array">
<item name="payment" xsi:type="array">
<item name="children" xsi:type="array">
<item name="additional-payment-validators" xsi:type="array">
<item name="children" xsi:type="array">
<!-- Declare your validation. START -->
<item name="your-validator" xsi:type="array">
<item name="component" xsi:type="string">MNM_Spitzner/js/view/address-validator</item>
</item>
<!-- Declare your validation. END -->
</item>
</item>
</item>
</item>
</item>
</item>
</item>
</item>
</item>
</item>
</item>
</argument>
</arguments>
</referenceBlock>
</body>
</page>

+ 44
- 0
src/app/code/MNM/Spitzner/view/frontend/requirejs-config.js Voir le fichier

@@ -0,0 +1,44 @@
var config = {
map: {
'*' : {
'spitznerReadMore': 'MNM_Spitzner/js/view/read-more'
}
},
config: {
mixins: {
'Magento_Checkout/js/view/shipping': {
'MNM_Spitzner/js/view/shipping-mixin': true
},
'Magento_Checkout/js/action/set-payment-information': {
'MNM_Spitzner/js/action/set-payment-information-mixin': true
},
'Magento_Checkout/js/action/set-shipping-information': {
'MNM_Spitzner/js/action/set-shipping-information-mixin': true
},
'Magento_Checkout/js/model/address-converter': {
'MNM_Spitzner/js/model/address-converter-mixin': true
},
'Magento_Checkout/js/view/cart/shipping-rates': {
'MNM_Spitzner/js/view/cart/shipping-rates-mixin': true
},
'Repertus_Packstation/js/packstation/search-modal-widget': {
'MNM_Spitzner/js/packstation/search-modal-widget-mixin': true
},
'Amasty_Promo/js/popup': {
'MNM_Spitzner/js/popup-mixin': true
},
'Amasty_CheckoutCore/js/view/onepage': {
'MNM_Spitzner/js/view/onepage-mixin': true
},
'Amasty_CheckoutCore/js/view/form/element/email': {
'MNM_Spitzner/js/view/form/element/email-mixin': true
},
'Amasty_CheckoutCore/js/view/checkout/summary/cart-items': {
'MNM_Spitzner/js/view/checkout/summary/cart-items-mixin': true
},
'Threepartment_Debitpayment/js/view/payment/method-renderer/debitpament-method': {
'MNM_Spitzner/js/view/payment/method-renderer/debitpament-method-mixin': true
}
}
}
};

+ 27
- 0
src/app/code/MNM/Spitzner/view/frontend/web/js/action/set-payment-information-mixin.js Voir le fichier

@@ -0,0 +1,27 @@
define([
'jquery',
'mage/utils/wrapper',
'Magento_Checkout/js/model/quote'
], function ($, wrapper, quote) {
'use strict';

return function (setPaymentInformationAction) {
return wrapper.wrap(setPaymentInformationAction, function (originalAction) {
var billingAddress = quote.billingAddress();

if(billingAddress && typeof billingAddress['street'] == 'object' && billingAddress['street'].length > 2)
{
//check if already combined
if(!billingAddress['street'][0].trim().endsWith(billingAddress['street'][2].trim()))
{
//combine street and "housenumber"
billingAddress['street'][0] = billingAddress['street'][0].trim() + ' ' + billingAddress['street'][2].trim();
}
billingAddress['street'].splice(2, 1);
}

// pass execution to original action ('Magento_Checkout/js/action/set-shipping-information')
return originalAction();
});
};
});

Certains fichiers n'ont pas été affichés car il y a eu trop de fichiers modifiés dans ce diff

Chargement…
Annuler
Enregistrer