Repository: boldcommerce/magento2-ordercomments
Branch: master
Commit: 2f0feb02b422
Files: 68
Total size: 78.1 KB
Directory structure:
gitextract_gvlihgyr/
├── Api/
│ ├── Data/
│ │ └── OrderCommentInterface.php
│ ├── GuestOrderCommentManagementInterface.php
│ └── OrderCommentManagementInterface.php
├── Block/
│ └── Order/
│ └── Comment.php
├── Controller/
│ └── Cart/
│ └── UpdateComment.php
├── LICENSE
├── Model/
│ ├── Config/
│ │ └── Source/
│ │ └── Collapse.php
│ ├── Config.php
│ ├── Data/
│ │ └── OrderComment.php
│ ├── GuestOrderCommentManagement.php
│ ├── OrderCommentConfigProvider.php
│ └── OrderCommentManagement.php
├── Observer/
│ └── AddOrderCommentToOrder.php
├── Plugin/
│ ├── Block/
│ │ └── Adminhtml/
│ │ └── SalesOrderViewInfo.php
│ └── Model/
│ └── Order/
│ └── LoadOrderComment.php
├── README.md
├── Setup/
│ ├── InstallData.php
│ └── Uninstall.php
├── Test/
│ ├── Integration/
│ │ ├── Model/
│ │ │ ├── GuestOrderCommentManagementTest.php
│ │ │ └── OrderCommentManagementTest.php
│ │ └── Observer/
│ │ └── AddOrderCommentToOrderTest.php
│ └── Unit/
│ ├── Model/
│ │ ├── GuestOrderCommentManagementTest.php
│ │ └── OrderCommentManagementTest.php
│ └── Observer/
│ └── AddOrderCommentToOrderTest.php
├── ViewModel/
│ └── Comment.php
├── composer.json
├── etc/
│ ├── adminhtml/
│ │ ├── di.xml
│ │ └── system.xml
│ ├── config.xml
│ ├── di.xml
│ ├── events.xml
│ ├── extension_attributes.xml
│ ├── frontend/
│ │ ├── di.xml
│ │ └── routes.xml
│ ├── module.xml
│ └── webapi.xml
├── i18n/
│ ├── ar_SA.csv
│ ├── bn_BD.csv
│ ├── cs_CZ.csv
│ ├── de_CH.csv
│ ├── de_DE.csv
│ ├── el_GR.csv
│ ├── es_ES.csv
│ ├── fr_FR.csv
│ ├── he_IL.csv
│ ├── hu_HU.csv
│ ├── it_IT.csv
│ ├── ja_JP.csv
│ ├── nl_NL.csv
│ ├── pl_PL.csv
│ ├── sl_SI.csv
│ ├── sv_SE.csv
│ └── th_TH.csv
├── registration.php
└── view/
├── adminhtml/
│ ├── layout/
│ │ └── sales_order_view.xml
│ ├── templates/
│ │ └── order/
│ │ └── view/
│ │ └── comments.phtml
│ └── ui_component/
│ └── sales_order_grid.xml
└── frontend/
├── layout/
│ ├── checkout_cart_index.xml
│ ├── checkout_index_index.xml
│ └── sales_order_view.xml
├── templates/
│ ├── cart/
│ │ └── comment.phtml
│ └── order/
│ └── view/
│ └── comment.phtml
└── web/
├── css/
│ └── source/
│ └── _module.less
├── js/
│ ├── model/
│ │ └── checkout/
│ │ └── order-comment-validator.js
│ └── view/
│ └── checkout/
│ ├── order-comment-block.js
│ └── order-comment-validator.js
└── template/
└── checkout/
├── form-content.html
└── order-comment-block.html
================================================
FILE CONTENTS
================================================
================================================
FILE: Api/Data/OrderCommentInterface.php
================================================
<?php
namespace Bold\OrderComment\Api\Data;
interface OrderCommentInterface
{
/**
* @return string|null
*/
public function getComment();
/**
* @param string $comment
* @return null
*/
public function setComment($comment);
}
================================================
FILE: Api/GuestOrderCommentManagementInterface.php
================================================
<?php
namespace Bold\OrderComment\Api;
/**
* Interface for saving the checkout comment to the quote for guest orders
*/
interface GuestOrderCommentManagementInterface
{
/**
* @param string $cartId
* @param \Bold\OrderComment\Api\Data\OrderCommentInterface $orderComment
* @return \Magento\Checkout\Api\Data\PaymentDetailsInterface
*/
public function saveOrderComment(
$cartId,
\Bold\OrderComment\Api\Data\OrderCommentInterface $orderComment
);
}
================================================
FILE: Api/OrderCommentManagementInterface.php
================================================
<?php
namespace Bold\OrderComment\Api;
/**
* Interface for saving the checkout comment to the quote for orders of logged in users
* @api
*/
interface OrderCommentManagementInterface
{
/**
* @param int $cartId
* @param \Bold\OrderComment\Api\Data\OrderCommentInterface $orderComment
* @return string
*/
public function saveOrderComment(
$cartId,
\Bold\OrderComment\Api\Data\OrderCommentInterface $orderComment
);
}
================================================
FILE: Block/Order/Comment.php
================================================
<?php
namespace Bold\OrderComment\Block\Order;
use Bold\OrderComment\Model\Data\OrderComment;
use Magento\Framework\Registry;
use Magento\Framework\View\Element\Template\Context as TemplateContext;
use Magento\Sales\Model\Order;
class Comment extends \Magento\Framework\View\Element\Template
{
/**
* Core registry
*
* @var \Magento\Framework\Registry
*/
protected $coreRegistry = null;
public function __construct(
TemplateContext $context,
Registry $registry,
array $data = []
) {
$this->coreRegistry = $registry;
$this->_isScopePrivate = true;
$this->_template = 'order/view/comment.phtml';
parent::__construct($context, $data);
}
public function getOrder() : Order
{
return $this->coreRegistry->registry('current_order');
}
public function getOrderComment(): string
{
return trim((string) $this->getOrder()->getData(OrderComment::COMMENT_FIELD_NAME));
}
public function hasOrderComment() : bool
{
return strlen($this->getOrderComment()) > 0;
}
public function getOrderCommentHtml() : string
{
return nl2br($this->escapeHtml($this->getOrderComment()));
}
}
================================================
FILE: Controller/Cart/UpdateComment.php
================================================
<?php
/**
* UpdateComment
*
* @copyright Copyright © 2020 Bold Commerce BV. All rights reserved.
* @author dev@boldcommerce.nl
*/
declare(strict_types=1);
namespace Bold\OrderComment\Controller\Cart;
use Bold\OrderComment\Model\Data\OrderCommentFactory;
use Bold\OrderComment\Model\OrderCommentManagement;
use Magento\Checkout\Model\Cart as CustomerCart;
use Magento\Checkout\Model\Session as CheckoutSession;
use Magento\Framework\App\Action\Context;
use Magento\Framework\App\Action\HttpPostActionInterface as HttpPostActionInterface;
use Magento\Framework\App\Config\ScopeConfigInterface;
use Magento\Framework\App\ResponseInterface;
use Magento\Framework\Controller\Result\Redirect;
use Magento\Framework\Controller\ResultInterface;
use Magento\Framework\Data\Form\FormKey\Validator;
use Magento\Framework\Exception\LocalizedException;
use Magento\Store\Model\StoreManagerInterface;
use Psr\Log\LoggerInterface;
class UpdateComment extends \Magento\Checkout\Controller\Cart implements HttpPostActionInterface
{
/**
* @var LoggerInterface
*/
protected $logger;
protected $orderCommentManagement;
protected $orderCommentFactory;
/**
* UpdateComment constructor.
* @param Context $context
* @param ScopeConfigInterface $scopeConfig
* @param CheckoutSession $checkoutSession
* @param StoreManagerInterface $storeManager
* @param Validator $formKeyValidator
* @param CustomerCart $cart
* @param LoggerInterface $logger
* @param OrderCommentManagement $orderCommentManagement
* @param OrderCommentFactory $orderCommentFactory
*/
public function __construct(
Context $context,
ScopeConfigInterface $scopeConfig,
CheckoutSession $checkoutSession,
StoreManagerInterface $storeManager,
Validator $formKeyValidator,
CustomerCart $cart,
LoggerInterface $logger,
OrderCommentManagement $orderCommentManagement,
OrderCommentFactory $orderCommentFactory
) {
parent::__construct($context, $scopeConfig, $checkoutSession, $storeManager, $formKeyValidator, $cart);
$this->logger = $logger;
$this->orderCommentManagement = $orderCommentManagement;
$this->orderCommentFactory = $orderCommentFactory;
}
/**
* Saves the comment to the quote
*
* @return ResponseInterface|Redirect|ResultInterface
*/
public function execute()
{
try {
$comment = trim($this->getRequest()->getParam('order_comment', ''));
$cartQuote = $this->cart->getQuote();
$commentObj = $this->orderCommentFactory->create();
$commentObj->setComment($comment);
$this->orderCommentManagement->saveOrderComment($cartQuote->getId(), $commentObj);
$this->messageManager->addSuccessMessage(
__(
'Your comment has been saved.'
)
);
} catch (LocalizedException $e) {
$this->messageManager->addErrorMessage($e->getMessage());
} catch (\Exception $e) {
$this->messageManager->addErrorMessage(__('There was an error when updating the quote.'));
$this->logger->critical($e->getMessage(), ['exception' => $e->getTraceAsString()]);
}
return $this->_goBack();
}
}
================================================
FILE: LICENSE
================================================
MIT License
Copyright (c) 2017 Bold Commerce BV
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
================================================
FILE: Model/Config/Source/Collapse.php
================================================
<?php
namespace Bold\OrderComment\Model\Config\Source;
class Collapse implements \Magento\Framework\Option\ArrayInterface
{
/**
* Options getter
*
* @return array
*/
public function toOptionArray()
{
$options = $this->toArray();
$result = [];
foreach ($options as $value => $label) {
$result[] = [
'value' => $value, 'label' => $label
];
}
return $result;
}
/**
* Get options in "key-value" format
*
* @return array
*/
public function toArray()
{
return [
0 => __('Starts with field closed'),
1 => __('Starts with field opened'),
2 => __('Render field without collapse')
];
}
}
================================================
FILE: Model/Config.php
================================================
<?php
/**
* Config
*
* @copyright Copyright © 2020 Bold Commerce BV. All rights reserved.
* @author dev@boldcommerce.nl
*/
declare(strict_types=1);
namespace Bold\OrderComment\Model;
use Magento\Framework\App\Config\ScopeConfigInterface;
use Magento\Store\Model\ScopeInterface;
class Config
{
const XML_PATH_CONFIG_MAX_LENGTH = 'sales/ordercomments/max_length';
const XML_PATH_CONFIG_FIELD_COLLAPSE_STATE = 'sales/ordercomments/collapse_state';
const XML_PATH_CONFIG_SHOW_IN_CHECKOUT = 'sales/ordercomments/show_in_checkout';
const XML_PATH_CONFIG_SHOW_IN_ACCOUNT = 'sales/ordercomments/show_in_account';
const XML_PATH_CONFIG_SHOW_IN_CART = 'sales/ordercomments/show_in_cart';
/**
* @var ScopeConfigInterface
*/
private $scopeConfig;
public function __construct(ScopeConfigInterface $scopeConfig)
{
$this->scopeConfig = $scopeConfig;
}
/**
* @param mixed $website
* @return bool
*/
public function canShowInCheckout($website = null): bool
{
return $this->scopeConfig->isSetFlag(self::XML_PATH_CONFIG_SHOW_IN_CHECKOUT, ScopeInterface::SCOPE_WEBSITE, $website);
}
/**
* @param mixed $website
* @return bool
*/
public function canShowInAccount($website = null): bool
{
return $this->scopeConfig->isSetFlag(self::XML_PATH_CONFIG_SHOW_IN_ACCOUNT, ScopeInterface::SCOPE_WEBSITE, $website);
}
/**
* @param mixed $website
* @return bool
*/
public function canShowInCart($website = null): bool
{
return $this->scopeConfig->isSetFlag(self::XML_PATH_CONFIG_SHOW_IN_CART, ScopeInterface::SCOPE_WEBSITE, $website);
}
/**
* @param mixed $website
* @return mixed
*/
public function getMaximumCharacterLength($website = null)
{
return $this->scopeConfig->getValue(self::XML_PATH_CONFIG_MAX_LENGTH, ScopeInterface::SCOPE_WEBSITE, $website);
}
/**
* @param mixed $website
* @return mixed
*/
public function getInitialCollapseState($website = null)
{
return $this->scopeConfig->getValue(self::XML_PATH_CONFIG_FIELD_COLLAPSE_STATE, ScopeInterface::SCOPE_WEBSITE, $website);
}
}
================================================
FILE: Model/Data/OrderComment.php
================================================
<?php
namespace Bold\OrderComment\Model\Data;
use Bold\OrderComment\Api\Data\OrderCommentInterface;
use Magento\Framework\Api\AbstractSimpleObject;
class OrderComment extends AbstractSimpleObject implements OrderCommentInterface
{
const COMMENT_FIELD_NAME = 'bold_order_comment';
/**
* @return string|null
*/
public function getComment()
{
return $this->_get(static::COMMENT_FIELD_NAME);
}
/**
* @param string $comment
* @return $this
*/
public function setComment($comment)
{
return $this->setData(static::COMMENT_FIELD_NAME, $comment);
}
}
================================================
FILE: Model/GuestOrderCommentManagement.php
================================================
<?php
namespace Bold\OrderComment\Model;
use Magento\Quote\Model\QuoteIdMaskFactory;
class GuestOrderCommentManagement implements \Bold\OrderComment\Api\GuestOrderCommentManagementInterface
{
/**
* @var QuoteIdMaskFactory
*/
protected $quoteIdMaskFactory;
/**
* @var \Bold\OrderComment\Api\OrderCommentManagementInterface
*/
protected $orderCommentManagement;
/**
* GuestOrderCommentManagement constructor.
* @param QuoteIdMaskFactory $quoteIdMaskFactory
* @param \Bold\OrderComment\Api\OrderCommentManagementInterface $orderCommentManagement
*/
public function __construct(
QuoteIdMaskFactory $quoteIdMaskFactory,
\Bold\OrderComment\Api\OrderCommentManagementInterface $orderCommentManagement
) {
$this->quoteIdMaskFactory = $quoteIdMaskFactory;
$this->orderCommentManagement = $orderCommentManagement;
}
/**
* {@inheritDoc}
*/
public function saveOrderComment(
$cartId,
\Bold\OrderComment\Api\Data\OrderCommentInterface $orderComment
) {
$quoteIdMask = $this->quoteIdMaskFactory->create()->load($cartId, 'masked_id');
return $this->orderCommentManagement->saveOrderComment($quoteIdMask->getQuoteId(), $orderComment);
}
}
================================================
FILE: Model/OrderCommentConfigProvider.php
================================================
<?php
namespace Bold\OrderComment\Model;
use Bold\OrderComment\Model\Data\OrderComment;
use Magento\Checkout\Model\ConfigProviderInterface;
use Magento\Checkout\Model\Session;
use Magento\Framework\App\Config\ScopeConfigInterface;
use Magento\Store\Model\ScopeInterface;
class OrderCommentConfigProvider implements ConfigProviderInterface
{
/**
* @deprecated
*/
const CONFIG_MAX_LENGTH = 'sales/ordercomments/max_length';
/**
* @deprecated
*/
const CONFIG_FIELD_COLLAPSE_STATE = 'sales/ordercomments/collapse_state';
/**
* @deprecated
*/
const CONFIG_SHOW_IN_CHECKOUT = 'sales/ordercomments/show_in_checkout';
/**
* @var ScopeConfigInterface
*/
private $scopeConfig;
private $checkoutSession;
/**
* OrderCommentConfigProvider constructor.
* @param ScopeConfigInterface $scopeConfig
* @param Session $checkoutSession
*/
public function __construct(ScopeConfigInterface $scopeConfig, Session $checkoutSession)
{
$this->scopeConfig = $scopeConfig;
$this->checkoutSession = $checkoutSession;
}
/**
* Prepare data for use in checkout javascript component
*
* @return array
* @throws \Magento\Framework\Exception\LocalizedException
* @throws \Magento\Framework\Exception\NoSuchEntityException
*/
public function getConfig()
{
$comment = '';
if ($this->checkoutSession->getQuoteId()) {
$comment = $this->checkoutSession->getQuote()->getData(OrderComment::COMMENT_FIELD_NAME) ?: '';
}
return [
'show_in_checkout' => $this->scopeConfig->isSetFlag(self::CONFIG_SHOW_IN_CHECKOUT, ScopeInterface::SCOPE_WEBSITE),
'max_length' => (int) $this->scopeConfig->getValue(self::CONFIG_MAX_LENGTH, ScopeInterface::SCOPE_WEBSITE),
'comment_initial_collapse_state' => (int) $this->scopeConfig->getValue(self::CONFIG_FIELD_COLLAPSE_STATE, ScopeInterface::SCOPE_WEBSITE),
'existing_comment' => $comment
];
}
}
================================================
FILE: Model/OrderCommentManagement.php
================================================
<?php
namespace Bold\OrderComment\Model;
use Bold\OrderComment\Model\Data\OrderComment;
use Magento\Framework\App\Config\ScopeConfigInterface;
use Magento\Framework\Exception\NoSuchEntityException;
use Magento\Framework\Exception\CouldNotSaveException;
use Magento\Framework\Exception\ValidatorException;
class OrderCommentManagement implements \Bold\OrderComment\Api\OrderCommentManagementInterface
{
/**
* Quote repository.
*
* @var \Magento\Quote\Api\CartRepositoryInterface
*/
protected $quoteRepository;
/**
* @var ScopeConfigInterface
*/
protected $scopeConfig;
/**
*
* @param \Magento\Quote\Api\CartRepositoryInterface $quoteRepository Quote repository.
*/
public function __construct(
\Magento\Quote\Api\CartRepositoryInterface $quoteRepository,
ScopeConfigInterface $scopeConfig
) {
$this->quoteRepository = $quoteRepository;
$this->scopeConfig = $scopeConfig;
}
/**
* @param int $cartId
* @param \Bold\OrderComment\Api\Data\OrderCommentInterface $orderComment
* @return null|string
* @throws CouldNotSaveException
* @throws NoSuchEntityException
*/
public function saveOrderComment(
$cartId,
\Bold\OrderComment\Api\Data\OrderCommentInterface $orderComment
) {
$quote = $this->quoteRepository->getActive($cartId);
if (!$quote->getItemsCount()) {
throw new NoSuchEntityException(__('Cart %1 doesn\'t contain products', $cartId));
}
$comment = $orderComment->getComment();
$this->validateComment($comment);
try {
$quote->setData(OrderComment::COMMENT_FIELD_NAME, strip_tags($comment));
$this->quoteRepository->save($quote);
} catch (\Exception $e) {
throw new CouldNotSaveException(__('The order comment could not be saved'));
}
return $comment;
}
/**
* @param string $comment
* @throws ValidatorException
*/
protected function validateComment($comment)
{
$maxLength = $this->scopeConfig->getValue(OrderCommentConfigProvider::CONFIG_MAX_LENGTH);
if ($maxLength && (mb_strlen($comment) > $maxLength)) {
throw new ValidatorException(__('Comment is too long'));
}
}
}
================================================
FILE: Observer/AddOrderCommentToOrder.php
================================================
<?php
namespace Bold\OrderComment\Observer;
use Bold\OrderComment\Model\Data\OrderComment;
class AddOrderCommentToOrder implements \Magento\Framework\Event\ObserverInterface
{
/**
* transfer the order comment from the quote object to the order object during the
* sales_model_service_quote_submit_before event
*
* @param \Magento\Framework\Event\Observer $observer
* @return void
*/
public function execute(\Magento\Framework\Event\Observer $observer)
{
/* @var $order \Magento\Sales\Model\Order */
$order = $observer->getEvent()->getOrder();
/** @var $quote \Magento\Quote\Model\Quote $quote */
$quote = $observer->getEvent()->getQuote();
$order->setData(OrderComment::COMMENT_FIELD_NAME, $quote->getData(OrderComment::COMMENT_FIELD_NAME));
}
}
================================================
FILE: Plugin/Block/Adminhtml/SalesOrderViewInfo.php
================================================
<?php
namespace Bold\OrderComment\Plugin\Block\Adminhtml;
use Bold\OrderComment\Model\Data\OrderComment;
class SalesOrderViewInfo
{
/**
* @param \Magento\Sales\Block\Adminhtml\Order\View\Info $subject
* @param string $result
* @return string
* @throws \Magento\Framework\Exception\LocalizedException
*/
public function afterToHtml(
\Magento\Sales\Block\Adminhtml\Order\View\Info $subject,
$result
) {
$commentBlock = $subject->getLayout()->getBlock('boldcommerce_order_comments');
if ($commentBlock !== false && $subject->getNameInLayout() == 'order_info') {
$commentBlock->setOrderComment($subject->getOrder()->getData(OrderComment::COMMENT_FIELD_NAME));
$result = $result . $commentBlock->toHtml();
}
return $result;
}
}
================================================
FILE: Plugin/Model/Order/LoadOrderComment.php
================================================
<?php
namespace Bold\OrderComment\Plugin\Model\Order;
use Magento\Sales\Api\OrderRepositoryInterface;
use Magento\Sales\Api\Data\OrderInterface;
use Magento\Sales\Model\OrderFactory;
use Magento\Sales\Api\Data\OrderExtensionFactory;
class LoadOrderComment
{
private $orderFactory;
private $orderExtensionFactory;
public function __construct(
OrderFactory $orderFactory,
OrderExtensionFactory $extensionFactory
) {
$this->orderFactory = $orderFactory;
$this->orderExtensionFactory = $extensionFactory;
}
public function afterGet(
OrderRepositoryInterface $subject,
OrderInterface $resultOrder
) {
$this->setOrderComment($resultOrder);
return $resultOrder;
}
public function afterGetList(
OrderRepositoryInterface $subject,
\Magento\Sales\Api\Data\OrderSearchResultInterface $orderSearchResult
) {
foreach ($orderSearchResult->getItems() as $order) {
$this->setOrderComment($order);
}
return $orderSearchResult;
}
public function setOrderComment(OrderInterface $order)
{
if ($order instanceof \Magento\Sales\Model\Order) {
$value = $order->getBoldOrderComment();
} else {
$temp = $this->getOrderFactory()->create();
$temp->load($order->getId());
$value = $temp->getBoldOrderComment();
}
$extensionAttributes = $order->getExtensionAttributes();
$orderExtension = $extensionAttributes ? $extensionAttributes : $this->getOrderExtensionFactory()->create();
$orderExtension->setBoldOrderComment($value);
$order->setExtensionAttributes($orderExtension);
}
public function getOrderFactory()
{
return $this->orderFactory;
}
public function getOrderExtensionFactory()
{
return $this->orderExtensionFactory;
}
}
================================================
FILE: README.md
================================================
# Bold Commerce: Magento 2 Order Comments
## Description
This extension allows customers to place a comment during the checkout.
The comment field is displayed in the billing step right above the place order button.
Additionally, there is also the option of showing the comment field on the cart page.
Store owners can then see these comments in the backend on the order grid and on the order view page.
### Checkout view


### Admin panel

## Emails
Add the "order comment" to new order emails by referencing [the code here](https://github.com/boldcommerce/magento2-ordercomments/issues/6#issuecomment-328515806).
## Configuration
There are several [configuration options](https://github.com/boldcommerce/magento2-ordercomments/blob/master/etc/adminhtml/system.xml) for this extension, which can be found at **STORES > Configuration > SALES > Sales > Order Comments**.
## Installation
```
composer require boldcommerce/magento2-ordercomments
php bin/magento module:enable Bold_OrderComment
php bin/magento setup:upgrade
```
## Changelog
1.8.5
=============
* Third party contribution: PHP 8.1 bugfix `Deprecated Functionality: trim(): Passing null to parameter` when viewing
an order in the my orders section that doesn't have an order comment [#72](https://github.com/boldcommerce/magento2-ordercomments/pull/72)
1.8.4
=============
* Third party contribution: PHP 8.1 support [#71](https://github.com/boldcommerce/magento2-ordercomments/pull/71)
* Third party contribution: Spanish translations [#70](https://github.com/boldcommerce/magento2-ordercomments/pull/70)
* Third party contribution: Thai translations [#67](https://github.com/boldcommerce/magento2-ordercomments/pull/67)
1.8.2
=============
* Third party contribution: Bengali translations [#65](https://github.com/boldcommerce/magento2-ordercomments/pull/65)
1.8.1
=============
* fix bug introduced with 1.8.0 in checkout `Cannot read property 'length' of null`
1.8.0
=============
* new feature: ability to show the comment field on the cart page based on a admin configuration setting.
1.7.1
=============
* upgrade tests to phpunit 6
1.7.0
=============
* Added website scope configuration setting to toggle visibility of comment field. [#59](https://github.com/boldcommerce/magento2-ordercomments/pull/59)
1.6.5
=============
* Third party contribution: PHP 7.4 support added in composer [#55](https://github.com/boldcommerce/magento2-ordercomments/pull/55)
* Third party contribution: Japanese translations added [#52](https://github.com/boldcommerce/magento2-ordercomments/pull/52)
* Third party contribution: Fix typo in Italian translation [#51](https://github.com/boldcommerce/magento2-ordercomments/pull/51)
* Third party contribution: Hungarian Translations added [#50](https://github.com/boldcommerce/magento2-ordercomments/pull/50)
* Third party contribution: New sections added in readme [#48](https://github.com/boldcommerce/magento2-ordercomments/pull/48)
1.6.4
=============
* Third party contribution: php 7.3 support in composer [#45](https://github.com/boldcommerce/magento2-ordercomments/pull/45)
* Third party contribution: French translations [#43](https://github.com/boldcommerce/magento2-ordercomments/pull/43)
* Third party contribution: Polish translations [#40](https://github.com/boldcommerce/magento2-ordercomments/pull/40)
* Third party contribution: Czech translations [#39](https://github.com/boldcommerce/magento2-ordercomments/pull/39)
1.6.3
=============
* Third party contribution: move form selector in order-comment-validator.js to a separate method to improve extensibility through mixins [#36](https://github.com/boldcommerce/magento2-ordercomments/pull/36)
1.6.2
=============
* Third party contribution: fix duplicate comment field on admin sales invoice view [#31](https://github.com/boldcommerce/magento2-ordercomments/pull/31)
* Third party contribution: fix typo and added some code improvements to the install script [#30](https://github.com/boldcommerce/magento2-ordercomments/pull/30)
1.6.1
=============
* Third party contribution: Enabled PHP 7.2 support [#29](https://github.com/boldcommerce/magento2-ordercomments/pull/29)
1.6.0
=============
* Third party contribution: Hebrew translations [#28](https://github.com/boldcommerce/magento2-ordercomments/pull/28)
1.5.0
=============
* Third party contribution: Form selector fallback for compatability with external changes that move the comment field [#24](https://github.com/boldcommerce/magento2-ordercomments/pull/24)
1.4.1
=============
* Third party contribution: Fixed it_IT translation csv [#20](https://github.com/boldcommerce/magento2-ordercomments/pull/20)
1.4.0
=============
* Third party contribution: Made the comment available in the order list web api `V1/orders` [#18](https://github.com/boldcommerce/magento2-ordercomments/pull/18)
1.3.0
=============
* UX changes to the max comment length feature [#15](https://github.com/boldcommerce/magento2-ordercomments/issue/15)
* Made the comment available in the order detail web api `V1/orders/{id}` [#15](https://github.com/boldcommerce/magento2-ordercomments/issue/15)
1.2.0
=============
* added setting to change initial collapse state of comment field (closed/opened/no collapse) [#14](https://github.com/boldcommerce/magento2-ordercomments/issue/14)
1.1.4
=============
* updated composer.json to allow PHP 7.1
1.1.3
=============
* Third party contribution: Dutch translations [#10](https://github.com/boldcommerce/magento2-ordercomments/pull/10)
* Third party contribution: Italian translations [#11](https://github.com/boldcommerce/magento2-ordercomments/pull/11)
1.1.2
=============
* Fix for fatal error on admin order view page when used with some other extensions [#9](https://github.com/boldcommerce/magento2-ordercomments/issues/9)
1.1.1
=============
* Third party contribution: Swedish translations and fixes in German translations [#5](https://github.com/boldcommerce/magento2-ordercomments/pull/5)
1.1.0
=============
* Third party contribution: German translations [#2](https://github.com/boldcommerce/magento2-ordercomments/pull/2)
* Third party contribution: Optional configuration for maximum comment length [#3](https://github.com/boldcommerce/magento2-ordercomments/pull/3)
* Third party contribution: Show order comments in customer account [#4](https://github.com/boldcommerce/magento2-ordercomments/pull/4)
1.0.0
=============
initial version
## Technical
To take in account third party payment extensions using custom implementations of Magento_Checkout/js/action/place-order.js to submit the order, this extension sends
the order comment in a separate request during the validation, before the order is placed. It should therefore work out of
the box.
## Uninstall
If you installed this module through composer, then you can run `php bin/magento module:uninstall Bold_OrderComment` to automatically
remove the code and drop the columns added by this extension.
*note:* the uninstall command seems bugged and might get stuck at `Removing code from Magento codebase:` (It worked fine for me on a 2.1.0 install but not on a 2.1.4 install). When this happens you should
exit with `ctrl+c` and run
```
composer update
php bin/magento maintenance:disable
```
See [github issue 3544](https://github.com/magento/magento2/issues/3544)
Alternatively you can manually remove the extension and remove the column `bold_order_comment` from the tables
* quote
* sales_order
* sales_order_grid
## License
MIT
================================================
FILE: Setup/InstallData.php
================================================
<?php
namespace Bold\OrderComment\Setup;
use Bold\OrderComment\Model\Data\OrderComment;
use Magento\Framework\Setup\InstallDataInterface;
use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Framework\Setup\ModuleDataSetupInterface;
use Magento\Framework\DB\Ddl\Table;
class InstallData implements InstallDataInterface
{
/**
* @var \Magento\Sales\Setup\SalesSetupFactory
*/
protected $salesSetupFactory;
/**
* @var \Magento\Quote\Setup\QuoteSetupFactory
*/
protected $quoteSetupFactory;
/**
* InstallData constructor.
* @param \Magento\Sales\Setup\SalesSetupFactory $salesSetupFactory
* @param \Magento\Quote\Setup\QuoteSetupFactory $quoteSetupFactory
*/
public function __construct(
\Magento\Sales\Setup\SalesSetupFactory $salesSetupFactory,
\Magento\Quote\Setup\QuoteSetupFactory $quoteSetupFactory
) {
$this->salesSetupFactory = $salesSetupFactory;
$this->quoteSetupFactory = $quoteSetupFactory;
}
/**
* @param ModuleDataSetupInterface $setup
* @param ModuleContextInterface $context
* @return void
*/
public function install(ModuleDataSetupInterface $setup, ModuleContextInterface $context)
{
$setup->startSetup();
/** @var \Magento\Quote\Setup\QuoteSetup $quoteInstaller */
$quoteInstaller = $this->quoteSetupFactory->create(['resourceName' => 'quote_setup', 'setup' => $setup]);
/** @var \Magento\Sales\Setup\SalesSetup $salesInstaller */
$salesInstaller = $this->salesSetupFactory->create(['resourceName' => 'sales_setup', 'setup' => $setup]);
$quoteInstaller->addAttribute(
'quote',
OrderComment::COMMENT_FIELD_NAME,
['type' => Table::TYPE_TEXT, 'length' => '64k', 'nullable' => true]
);
$salesInstaller->addAttribute(
'order',
OrderComment::COMMENT_FIELD_NAME,
['type' => Table::TYPE_TEXT, 'length' => '64k', 'nullable' => true, 'grid' => true]
);
$setup->endSetup();
}
}
================================================
FILE: Setup/Uninstall.php
================================================
<?php
namespace Bold\OrderComment\Setup;
use Bold\OrderComment\Model\Data\OrderComment;
use Magento\Framework\Setup\UninstallInterface;
use Magento\Framework\Setup\SchemaSetupInterface;
use Magento\Framework\Setup\ModuleContextInterface;
class Uninstall implements UninstallInterface
{
public function uninstall(SchemaSetupInterface $setup, ModuleContextInterface $context)
{
$setup->startSetup();
$setup->getConnection()->dropColumn(
$setup->getTable('quote'),
OrderComment::COMMENT_FIELD_NAME
);
$setup->getConnection()->dropColumn(
$setup->getTable('sales_order'),
OrderComment::COMMENT_FIELD_NAME
);
$setup->getConnection()->dropColumn(
$setup->getTable('sales_order_grid'),
OrderComment::COMMENT_FIELD_NAME
);
$setup->endSetup();
}
}
================================================
FILE: Test/Integration/Model/GuestOrderCommentManagementTest.php
================================================
<?php
namespace Bold\OrderComment\Test\Integration\Model;
use Bold\OrderComment\Model\Data\OrderComment;
use Magento\TestFramework\Helper\Bootstrap;
use PHPUnit\Framework\TestCase;
/**
* Class GuestOrderCommentManagementTest
* @package Bold\OrderComment\Test\Integration\Model
*
* @magentoDbIsolation enabled
*/
class GuestOrderCommentManagementTest extends TestCase
{
/**
* @magentoDataFixture Magento/Sales/_files/quote_with_bundle.php
* @return void
*/
public function testGuestSaveOrderComment()
{
$objectManager = Bootstrap::getObjectManager();
$comment = 'test comment guest';
/** @var \Magento\Quote\Model\Quote $quote */
$quote = $objectManager->create('\Magento\Quote\Model\Quote');
$quote->load('test01', 'reserved_order_id');
/** @var \Magento\Quote\Model\QuoteIdMask $quoteMask */
$quoteMask = $objectManager->create('\Magento\Quote\Model\QuoteIdMask');
$quoteMask->load($quote->getId(), 'quote_id');
$model = $objectManager->create('\Bold\OrderComment\Api\GuestOrderCommentManagementInterface');
$data = $objectManager->create('\Bold\OrderComment\Api\Data\OrderCommentInterface');
$data->setComment($comment);
$model->saveOrderComment($quoteMask->getMaskedId(), $data);
$quote->load('test01', 'reserved_order_id');
self::assertEquals($comment, $quote->getData(OrderComment::COMMENT_FIELD_NAME));
}
}
================================================
FILE: Test/Integration/Model/OrderCommentManagementTest.php
================================================
<?php
namespace Bold\OrderComment\Test\Integration\Model;
use Bold\OrderComment\Model\Data\OrderComment;
use Magento\TestFramework\Helper\Bootstrap;
use PHPUnit\Framework\TestCase;
/**
* Class OrderCommentManagementTest
* @package Bold\OrderComment\Test\Integration\Model
*
* @magentoDbIsolation enabled
*/
class OrderCommentManagementTest extends TestCase
{
/**
* @magentoDataFixture Magento/Sales/_files/quote_with_bundle.php
* @return void
*/
public function testSaveOrderComment()
{
$objectManager = Bootstrap::getObjectManager();
$comment = 'test comment';
/** @var \Magento\Quote\Model\Quote $quote */
$quote = $objectManager->create('\Magento\Quote\Model\Quote');
$quote->load('test01', 'reserved_order_id');
$model = $objectManager->create('\Bold\OrderComment\Api\OrderCommentManagementInterface');
$data = $objectManager->create('\Bold\OrderComment\Api\Data\OrderCommentInterface');
$data->setComment($comment);
$model->saveOrderComment($quote->getId(), $data);
$quote->load('test01', 'reserved_order_id');
self::assertEquals($comment, $quote->getData(OrderComment::COMMENT_FIELD_NAME));
}
}
================================================
FILE: Test/Integration/Observer/AddOrderCommentToOrderTest.php
================================================
<?php
namespace Bold\OrderComment\Test\Integration\Observer;
use Bold\OrderComment\Model\Data\OrderComment;
use Magento\TestFramework\Helper\Bootstrap;
use PHPUnit\Framework\TestCase;
/**
* Class AddOrderCommentToOrderTest
* @package Bold\OrderComment\Test\Integration\Observer
*
* tests if the comment gets passed from the quote to the order during order creation.
* @magentoDbIsolation enabled
*/
class AddOrderCommentToOrderTest extends TestCase
{
/**
* Create order with product that has child items
*
* @magentoDataFixture Magento/Sales/_files/quote_with_bundle.php
* @return void
*/
public function testExecute()
{
$comment = 'test comment';
$objectManager = Bootstrap::getObjectManager();
/** @var \Magento\Quote\Model\Quote $quote */
$quote = $objectManager->create('\Magento\Quote\Model\Quote');
$quote->load('test01', 'reserved_order_id');
$quote->setData(OrderComment::COMMENT_FIELD_NAME, $comment);
$quote->save();
/** @var \Magento\Quote\Api\CartManagementInterface $model */
$model = $objectManager->create('\Magento\Quote\Api\CartManagementInterface');
/** @var \Magento\Sales\Model\Order $order */
$order = $model->submit($quote);
self::assertEquals($comment, $order->getData(OrderComment::COMMENT_FIELD_NAME));
}
}
================================================
FILE: Test/Unit/Model/GuestOrderCommentManagementTest.php
================================================
<?php
namespace Bold\OrderComment\Test\Unit\Model;
use Magento\Quote\Test\Unit\Model\GuestCart\GuestCartTestHelper;
use PHPUnit\Framework\TestCase;
class GuestOrderCommentManagementTest extends TestCase
{
/**
* @var \Bold\OrderComment\Model\GuestOrderCommentManagement
*/
protected $testObject;
/**
* @var \PHPUnit_Framework_MockObject_MockObject
*/
protected $quoteIdMaskFactoryMock;
/**
* @var \PHPUnit_Framework_MockObject_MockObject
*/
protected $quoteIdMaskMock;
/**
* @var \PHPUnit_Framework_MockObject_MockObject
*/
protected $orderCommentManagementMock;
/**
* @var string
*/
protected $maskedCartId;
/**
* @var int
*/
protected $cartId;
/**
* @var \PHPUnit_Framework_MockObject_MockObject
*/
protected $quoteRepositoryMock;
/**
* @var \PHPUnit_Framework_MockObject_MockObject
*/
protected $quoteMock;
protected function setUp()
{
$objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
$this->quoteRepositoryMock = $this->createMock('\Magento\Quote\Api\CartRepositoryInterface');
$this->quoteMock = $this->createMock(
'\Magento\Quote\Model\Quote',
[
'getItemsCount',
'save',
'__wakeup'
],
[],
'',
false
);
$this->orderCommentManagementMock = $this->createMock(
'Bold\OrderComment\Model\OrderCommentManagement',
[],
[],
'',
false
);
$this->maskedCartId = 'f216207248d65c789b17be8545e0aa73';
$this->cartId = 123;
$guestCartTestHelper = new GuestCartTestHelper($this);
list($this->quoteIdMaskFactoryMock, $this->quoteIdMaskMock) = $guestCartTestHelper->mockQuoteIdMask(
$this->maskedCartId,
$this->cartId
);
$this->testObject = $objectManager->getObject(
'Bold\OrderComment\Model\GuestOrderCommentManagement',
[
'orderCommentManagement' => $this->orderCommentManagementMock,
'quoteIdMaskFactory' => $this->quoteIdMaskFactoryMock
]
);
}
public function testSaveComment()
{
$comment = 'test comment';
$orderCommentMock = $this->getMockBuilder('\Bold\OrderComment\Model\Data\OrderComment')
->disableOriginalConstructor()
->getMock();
$this->orderCommentManagementMock->expects($this->once())
->method('saveOrderComment')
->with($this->cartId, $orderCommentMock)
->willReturn($comment);
$result = $this->testObject->saveOrderComment($this->maskedCartId, $orderCommentMock);
$this->assertEquals($comment, $result);
}
}
================================================
FILE: Test/Unit/Model/OrderCommentManagementTest.php
================================================
<?php
namespace Bold\OrderComment\Test\Unit\Model;
use Bold\OrderComment\Api\Data\OrderCommentInterface;
use Bold\OrderComment\Model\Data\OrderComment;
use Bold\OrderComment\Model\OrderCommentConfigProvider;
use Bold\OrderComment\Model\OrderCommentManagement;
use Magento\Framework\App\Config\ScopeConfigInterface;
use Magento\Quote\Api\CartRepositoryInterface;
use Magento\Quote\Model\Quote;
use Magento\Quote\Model\QuoteRepository;
use PHPUnit\Framework\TestCase;
class OrderCommentManagementTest extends TestCase
{
/**
* @var \PHPUnit_Framework_MockObject_MockObject|QuoteRepository
*/
protected $quoteRepositoryMock;
/**
* @var \PHPUnit_Framework_MockObject_MockObject|Quote
*/
protected $quoteMock;
/**
* @var OrderCommentManagement
*/
protected $testObject;
/**
* @var \PHPUnit_Framework_MockObject_MockObject|ScopeConfigInterface
*/
protected $configMock;
public function setUp()
{
$this->quoteRepositoryMock = $this->createMock(CartRepositoryInterface::class);
$this->quoteMock = $this->createPartialMock(
Quote::class,
[
'getItemsCount',
'save',
'__wakeup'
]
);
$this->configMock = $this->getMockForAbstractClass(
ScopeConfigInterface::class
);
$this->testObject = new OrderCommentManagement($this->quoteRepositoryMock, $this->configMock);
}
/**
* @expectedException \Magento\Framework\Exception\NoSuchEntityException
* @expectedExceptionMessage Cart 123 doesn't contain products
*/
public function testSaveCommentWithEmptyCart()
{
$this->setupQuoteRepositoryMockQueries(123, 0);
$this->testObject->saveOrderComment(123, $this->mockOrderComment());
}
/**
* @expectedException \Magento\Framework\Exception\CouldNotSaveException
* @expectedExceptionMessage The order comment could not be saved
*/
public function testSaveCommentWhenCouldNotSaveQuote()
{
$cartId = 123;
$cartItemCount = 12;
$this->setupQuoteRepositoryMockQueries($cartId, $cartItemCount);
$exceptionMessage = 'The order comment could not be saved';
$exception = new \Magento\Framework\Exception\CouldNotSaveException(__($exceptionMessage));
$this->quoteRepositoryMock->expects($this->once())
->method('save')
->with($this->quoteMock)
->willThrowException($exception);
$this->testObject->saveOrderComment($cartId, $this->mockOrderComment());
}
/**
* @expectedException \Magento\Framework\Exception\ValidatorException
* @expectedExceptionMessage Comment is too long
*/
public function testSaveCommentThatIsTooLong()
{
$cartId = 123;
$cartItemCount = 12;
$comment = '123456789';
$this->configMock
->method('getValue')
->with(OrderCommentConfigProvider::CONFIG_MAX_LENGTH)
->willReturn(8);
$this->setupQuoteRepositoryMockQueries($cartId, $cartItemCount);
$this->quoteRepositoryMock->expects($this->never())
->method('save');
$this->testObject->saveOrderComment($cartId, $this->mockOrderComment($comment));
}
public function testSaveComment()
{
$cartId = 123;
$comment = 'test comment';
$cartItemCount = 12;
$this->setupQuoteRepositoryMockQueries($cartId, $cartItemCount);
$this->quoteRepositoryMock->expects($this->once())
->method('save')
->with($this->quoteMock)
->will($this->returnSelf());
$this->testObject->saveOrderComment($cartId, $this->mockOrderComment($comment));
$this->assertEquals($comment, $this->quoteMock->getData(OrderComment::COMMENT_FIELD_NAME));
}
public function testSaveCommentWithTags()
{
$cartId = 123;
$cartItemCount = 12;
$comment = 'test comment<script>alert("abcd");</script><?php die("qwerty")?>';
$this->setupQuoteRepositoryMockQueries($cartId, $cartItemCount);
$this->quoteRepositoryMock->expects($this->once())
->method('save')
->with($this->quoteMock)
->will($this->returnSelf());
$this->testObject->saveOrderComment($cartId, $this->mockOrderComment($comment));
$this->assertEquals(strip_tags($comment), $this->quoteMock->getData(OrderComment::COMMENT_FIELD_NAME));
}
private function setupQuoteRepositoryMockQueries(int $cartId, int $cartItemCount)
{
$this->quoteRepositoryMock->expects($this->once())
->method('getActive')->with($cartId)->will($this->returnValue($this->quoteMock));
$this->quoteMock->expects($this->once())->method('getItemsCount')->will($this->returnValue($cartItemCount));
}
/**
* @return \PHPUnit_Framework_MockObject_MockObject|OrderCommentInterface
*/
private function mockOrderComment(string $comment = null): \PHPUnit_Framework_MockObject_MockObject
{
$orderCommentMock = $this->getMockBuilder(OrderComment::class)
->disableOriginalConstructor()
->getMock();
if ($comment !== null) {
$orderCommentMock->expects($this->once())
->method('getComment')
->willReturn($comment);
}
return $orderCommentMock;
}
}
================================================
FILE: Test/Unit/Observer/AddOrderCommentToOrderTest.php
================================================
<?php
namespace Bold\OrderComment\Test\Unit\Observer;
use Bold\OrderComment\Observer\AddOrderCommentToOrder;
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
use Bold\OrderComment\Model\Data\OrderComment;
use PHPUnit\Framework\TestCase;
class AddOrderCommentToOrderTest extends TestCase
{
protected $objectManager;
/**
* @var AddOrderCommentToOrder
*/
protected $observer;
public function setUp()
{
$this->objectManager = new ObjectManager($this);
$this->observer = new AddOrderCommentToOrder();
}
public function testExecute()
{
$comment = 'test comment';
$observerMock = $this->createMock('Magento\Framework\Event\Observer');
$eventMock = $this->createPartialMock('Magento\Framework\Event', ['getData']);
$quoteMock = $this->createPartialMock('Magento\Quote\Model\Quote', ['getData']);
$orderMock = $this->createPartialMock('Magento\Sales\Model\Order', []);
$map = [
['quote', null, $quoteMock],
['order', null, $orderMock]
];
$observerMock->expects($this->atLeast(2))
->method('getEvent')
->willReturn($eventMock);
$eventMock->expects($this->atLeast(2))
->method('getData')
->will($this->returnValueMap($map));
$quoteMock->expects($this->atLeastOnce())
->method('getData')
->with(OrderComment::COMMENT_FIELD_NAME)
->willReturn($comment);
$this->observer->execute($observerMock);
$this->assertEquals($comment, $orderMock->getData(OrderComment::COMMENT_FIELD_NAME));
}
}
================================================
FILE: ViewModel/Comment.php
================================================
<?php
/**
* Comment
*
* @copyright Copyright © 2020 Bold Commerce BV. All rights reserved.
* @author dev@boldcommerce.nl
*/
declare(strict_types=1);
namespace Bold\OrderComment\ViewModel;
use Bold\OrderComment\Model\Config;
use Bold\OrderComment\Model\Data\OrderComment;
use Magento\Checkout\Model\Session as CheckoutSession;
use Magento\Framework\View\Element\Block\ArgumentInterface;
class Comment implements ArgumentInterface
{
/**
* @var Config
*/
private $config;
/**
* @var CheckoutSession
*/
private $checkoutSession;
/**
* Comment constructor.
* @param Config $config
* @param CheckoutSession $checkoutSession
*/
public function __construct(Config $config, CheckoutSession $checkoutSession)
{
$this->config = $config;
$this->checkoutSession = $checkoutSession;
}
/**
* Get the current comment from quote
*
* @return string|null
* @throws \Magento\Framework\Exception\LocalizedException
* @throws \Magento\Framework\Exception\NoSuchEntityException
*/
public function getComment(): ?string
{
if ($this->checkoutSession->getQuoteId()) {
return $this->checkoutSession->getQuote()->getData(OrderComment::COMMENT_FIELD_NAME);
}
return null;
}
/**
* Get Max Length validation classes if character restriction is enabled
*
* @return string
*/
public function getExtraClass(): string
{
$class = '';
if ($maxLength = $this->config->getMaximumCharacterLength()) {
$class .= 'validate-length maximum-length-' . $maxLength;
}
return $class;
}
}
================================================
FILE: composer.json
================================================
{
"name": "boldcommerce/magento2-ordercomments",
"description": "Magento 2 Module to add a comment field above the place order button in the checkout",
"require": {
"php": "^7.0.0|^8.0.0"
},
"type": "magento2-module",
"keywords": ["magento2"],
"license": "MIT",
"authors": [
{
"name": "Bold Commerce BV",
"email": "info@boldcommerce.nl"
}
],
"autoload": {
"files": [
"registration.php"
],
"psr-4": {
"Bold\\OrderComment\\": ""
}
}
}
================================================
FILE: etc/adminhtml/di.xml
================================================
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<type name="Magento\Sales\Block\Adminhtml\Order\View\Info">
<plugin name="bold_ordercomment-show_comment" type="Bold\OrderComment\Plugin\Block\Adminhtml\SalesOrderViewInfo" sortOrder="99999" />
</type>
</config>
================================================
FILE: etc/adminhtml/system.xml
================================================
<?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="sales">
<group id="ordercomments" translate="label" type="text" sortOrder="110" showInDefault="1" showInWebsite="1" showInStore="0">
<label>Order Comment</label>
<field id="show_in_checkout" sortOrder="10" type="select" showInDefault="1" showInWebsite="1" showInStore="0">
<label>Show in checkout</label>
<source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
<comment>Toggle visibility of the order comments section in the checkout</comment>
</field>
<field id ="show_in_cart" sortOrder="15" type="select" showInDefault="1" showInWebsite="1" showInStore="0">
<label>Show in cart</label>
<source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
<comment>Toggle visibility of order comments on the cart page</comment>
</field>
<field id="max_length" translate="label" type="text" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="0" canRestore="1">
<label>Maximum length in characters</label>
<comment>Leave empty for no limit</comment>
</field>
<field id="show_in_account" translate="label" type="select" sortOrder="20" showInDefault="1" showInWebsite="1" showInStore="0" canRestore="1">
<label>Show comments in customer account</label>
<source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
</field>
<field id="collapse_state" translate="label" type="select" sortOrder="30" showInDefault="1" showInWebsite="1" showInStore="0" canRestore="1">
<label>Initial collapse state on checkout page</label>
<source_model>Bold\OrderComment\Model\Config\Source\Collapse</source_model>
</field>
</group>
</section>
</system>
</config>
================================================
FILE: etc/config.xml
================================================
<?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>
<sales>
<ordercomments>
<show_in_checkout>1</show_in_checkout>
<show_in_account>1</show_in_account>
<collapse_state>0</collapse_state>
</ordercomments>
</sales>
</default>
</config>
================================================
FILE: etc/di.xml
================================================
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<preference for="Bold\OrderComment\Api\Data\OrderCommentInterface" type="Bold\OrderComment\Model\Data\OrderComment" />
<preference for="Bold\OrderComment\Api\OrderCommentManagementInterface" type="Bold\OrderComment\Model\OrderCommentManagement" />
<preference for="Bold\OrderComment\Api\GuestOrderCommentManagementInterface" type="Bold\OrderComment\Model\GuestOrderCommentManagement" />
<virtualType name="Magento\Sales\Model\ResourceModel\Order\Grid">
<arguments>
<argument name="columns" xsi:type="array">
<item name="bold_order_comment" xsi:type="string">sales_order.bold_order_comment</item>
</argument>
</arguments>
</virtualType>
<type name="Magento\Sales\Api\OrderRepositoryInterface">
<plugin name="bold_load_ordercomment" type="Bold\OrderComment\Plugin\Model\Order\LoadOrderComment"/>
</type>
</config>
================================================
FILE: etc/events.xml
================================================
<?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="sales_model_service_quote_submit_before">
<observer name="bold_ordercomment-add_ordercomment_to_order" instance="Bold\OrderComment\Observer\AddOrderCommentToOrder" />
</event>
</config>
================================================
FILE: etc/extension_attributes.xml
================================================
<?xml version="1.0"?>
<!--
/**
* Copyright © 2013-2017 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:Api/etc/extension_attributes.xsd">
<extension_attributes for="Magento\Sales\Api\Data\OrderInterface">
<attribute code="bold_order_comment" type="string" />
</extension_attributes>
</config>
================================================
FILE: etc/frontend/di.xml
================================================
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<type name="Magento\Checkout\Model\CompositeConfigProvider">
<arguments>
<argument name="configProviders" xsi:type="array">
<item name="ordercomments_config_provider" xsi:type="object">Bold\OrderComment\Model\OrderCommentConfigProvider</item>
</argument>
</arguments>
</type>
</config>
================================================
FILE: etc/frontend/routes.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<!--
/**
* routes.xml
*
* @copyright Copyright © 2020 Bold Commerce BV. All rights reserved.
* @author dev@boldcommerce.nl
*/
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:App/etc/routes.xsd">
<router id="standard">
<route id="bold_ordercomment" frontName="bold_ordercomment">
<module name="Bold_OrderComment" />
</route>
</router>
</config>
================================================
FILE: etc/module.xml
================================================
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
<module name="Bold_OrderComment" setup_version="0.0.1">
<sequence>
<module name="Magento_Sales" />
</sequence>
</module>
</config>
================================================
FILE: etc/webapi.xml
================================================
<?xml version="1.0"?>
<routes xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Webapi:etc/webapi.xsd">
<!-- Managing checkout comment -->
<route url="/V1/guest-carts/:cartId/set-order-comment" method="PUT">
<service class="Bold\OrderComment\Api\GuestOrderCommentManagementInterface" method="saveOrderComment"/>
<resources>
<resource ref="anonymous" />
</resources>
</route>
<!-- Managing checkout comment -->
<route url="/V1/carts/mine/set-order-comment" method="PUT">
<service class="Bold\OrderComment\Api\OrderCommentManagementInterface" method="saveOrderComment"/>
<resources>
<resource ref="self" />
</resources>
<data>
<parameter name="cartId" force="true">%cart_id%</parameter>
</data>
</route>
</routes>
================================================
FILE: i18n/ar_SA.csv
================================================
"Do you have any comments regarding the order?","هل لديك اي تعليق بخصوص لطلبك؟"
"Enter your comment...","اكتب تعليقك"
"Order Comment","تعليق الطلب"
"The order comment could not be saved","تعليق الطلب لا يمكن حفظه"
"Cart %1 doesn't contain products","سلة المشتريات لا تحتوي على منتجات"
================================================
FILE: i18n/bn_BD.csv
================================================
"Do you have any comments regarding the order?","আপনার কি এই অর্ডার সংক্রান্ত কোন মন্তব্য আছে?"
"Enter your comment...","আপনার মন্তব্য লিখুন..."
"Order Comment","অর্ডার মন্তব্য"
"The order comment could not be saved","অর্ডার মন্তব্যটি সংরক্ষণ করা যায়নি"
"Cart %1 doesn't contain products","কার্ট %1 তে কোন পন্য নাই"
================================================
FILE: i18n/cs_CZ.csv
================================================
"Do you have any comments regarding the order?","Máte k objednávce nějakou poznámku?"
"Enter your comment...","Vložte poznámku..."
"Order Comment","Poznámky k objednávce"
"The order comment could not be saved","Poznámka k objednávce nemohla být uložena"
"Cart %1 doesn't contain products","V košíku %1 nejsou žádné produkty"
================================================
FILE: i18n/de_CH.csv
================================================
"Do you have any comments regarding the order?","Haben Sie Anmerkungen zur Bestellung?"
"Enter your comment...","Anmerkungen eingeben..."
"Order Comment","Anmerkungen"
"The order comment could not be saved","Die Anmerkungen zur Bestellung konnten nicht gespeichert werden"
"Cart %1 doesn't contain products","Warenkorb %1 enthält keine Produkte"
================================================
FILE: i18n/de_DE.csv
================================================
"Do you have any comments regarding the order?","Haben Sie Anmerkungen zur Bestellung?"
"Enter your comment...","Anmerkungen eingeben..."
"Order Comment","Anmerkungen"
"The order comment could not be saved","Die Anmerkungen zur Bestellung konnten nicht gespeichert werden"
"Cart %1 doesn't contain products","Warenkorb %1 enthält keine Produkte"
================================================
FILE: i18n/el_GR.csv
================================================
"Do you have any comments regarding the order?","Έχετε παρατηρήσεις σχετικά με την παραγγελία;"
"Enter your comment...","Γράψτε τις παρατηρήσεις σας ..."
"Order Comment","Παρατηρήσεις"
"The order comment could not be saved","Οι παρατηρήσεις σας δεν μπόρεσαν να αποθηκευτούν"
"Cart %1 doesn't contain products","Το καλάθι %1 δεν περιέχει προϊόντα"
================================================
FILE: i18n/es_ES.csv
================================================
"Your comment has been saved.","Se ha guardado el comentario."
"There was an error when updating the quote.","Ha ocurrido un error al actualizar el carrito."
"Starts with field closed","Iniciar con el campo cerrado"
"Starts with field opened","Iniciar con el campo abierto"
"Render field without collapse","Renderizar campo sin que se pueda plegar"
"Cart %1 doesn't contain products","El carrito %1 no contiene productos"
"The order comment could not be saved","No se ha podido guardar el comentario"
"Comment is too long","El comentario es demasiado largo"
"Order Comment","Comentario de pedido"
"Edit Order Comment","Comentario de pedido"
"Do you have any comments regarding the order?","¿Tienes algún comentario sobre el pedido?"
"Enter your comment...","Introduce tu comentario..."
"Save Comment","Guardar comentario"
"Enter comment","Introducir comentario"
"Remaining characters:","Caracteres restantes:"
"Maximum length in characters","Carecteres máximos"
"Show comments in customer account","Mostrar comentario en cuenta de cliente"
"Initial collapse state on checkout page","Estado inicial del campo en el proceso de compra"
================================================
FILE: i18n/fr_FR.csv
================================================
"Do you have any comments regarding the order?","Avez-vous un commentaire à nous transmettre au sujet de cette commande ?"
"Enter your comment...","Saisissez votre commentaire ici..."
"Order Comment","Commentaire de commande"
"The order comment could not be saved","Le commentaire de cette commande ne peut pas être enregistré"
"Cart %1 doesn't contain products","Le panier %1 ne contient aucun article"
"Remaining characters:","Caractères restants :"
================================================
FILE: i18n/he_IL.csv
================================================
"Do you have any comments regarding the order?","האם יש לכם הערה בנוגע להזמנה?"
"Enter your comment...","הוסיפו את ההערה שלכם..."
"Order Comment","הערת הזמנה"
"The order comment could not be saved","לא ניתן לשמור את ההערה"
"Cart %1 doesn't contain products","העגלה %1 לא מכילה מוצרים"
================================================
FILE: i18n/hu_HU.csv
================================================
"Do you have any comments regarding the order?","Üzenet a futárnak:"
"Enter your comment...","Például kapucsengő, kapu, egyéb pontosítás..."
"Order Comment","Rendelés megjegyzés"
"The order comment could not be saved","A rendelés megjegyzést nem lehet elmenteni."
"Cart %1 doesn't contain products","A kosárban nincs %1 termék"
"Remaining characters:","Üzenet hossz:"
================================================
FILE: i18n/it_IT.csv
================================================
"Do you have any comments regarding the order?","Hai delle richieste in merito all'ordine?"
"Enter your comment...","Inserisci qui i commenti..."
"Order Comment","Commenti ordine"
"The order comment could not be saved","La tua richiesta al momento non puo' essere salvata"
"Cart %1 doesn't contain products","Il carrello %1 non contiene prodotti"
================================================
FILE: i18n/ja_JP.csv
================================================
"Do you have any comments regarding the order?","注文に関して何かコメントはありますか?"
"Enter your comment...","コメントを入力してください..."
"Order Comment","注文コメント"
"The order comment could not be saved","注文コメントを保存できませんでした"
"Cart %1 doesn't contain products","カート%1には商品が含まれていません"
================================================
FILE: i18n/nl_NL.csv
================================================
"Do you have any comments regarding the order?","Heb je nog opmerkingen over je bestelling?"
"Enter your comment...","Opmerkingen toevoegen..."
"Order Comment","Opmerkingen"
"The order comment could not be saved","De opmerkingen over je bestelling kunnen niet opgeslagen worden"
"Cart %1 doesn't contain products","Winkelwagen %1 bevat geen producten"
================================================
FILE: i18n/pl_PL.csv
================================================
"Do you have any comments regarding the order?","Dodaj komentarz do zamówienia"
"Enter your comment...","Twój komentarz..."
"Order Comment","Komentarz do zamówienia"
"The order comment could not be saved","Twój komentarz nie został zapisany"
"Cart %1 doesn't contain products","Koszyk %1 nie zawiera produktów"
================================================
FILE: i18n/sl_SI.csv
================================================
"Do you have any comments regarding the order?","Želite dodati komentar k vašemu naročilu?"
"Enter your comment...","Vnesite svoj komentar..."
"Order Comment","Komentar k naročilu"
"The order comment could not be saved","Komentarja naročila ni bilo mogoče shraniti"
"Cart %1 doesn't contain products","Košarica %1 je prazna"
================================================
FILE: i18n/sv_SE.csv
================================================
"Do you have any comments regarding the order?","Vill du lämna en kommentar angående din order?"
"Enter your comment...","Lämna din kommentar..."
"Order Comment","Orderkommentar"
"The order comment could not be saved","Din kommentar kunde inte sparas"
"Cart %1 doesn't contain products","Varukorg %1 innehåller inga produkter"
================================================
FILE: i18n/th_TH.csv
================================================
"Do you have any comments regarding the order?","คุณมีความคิดเห็นเกี่ยวกับคำสั่งซื้อหรือไม่?"
"Enter your comment...","ใส่ความคิดเห็นของคุณที่นี่ ..."
"Order Comment","ความเห็นของคำสั่งซื้อนี้"
"The order comment could not be saved","ไม่สามารถบันทึกความคิดเห็นของคำสั่งซื้อนี้"
"Cart %1 doesn't contain products","รถเข็น %1 ไม่มีสินค้า"
================================================
FILE: registration.php
================================================
<?php
\Magento\Framework\Component\ComponentRegistrar::register(
\Magento\Framework\Component\ComponentRegistrar::MODULE,
'Bold_OrderComment',
__DIR__
);
================================================
FILE: view/adminhtml/layout/sales_order_view.xml
================================================
<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<body>
<block class="Magento\Backend\Block\Template" name="boldcommerce_order_comments" template="Bold_OrderComment::order/view/comments.phtml" />
</body>
</page>
================================================
FILE: view/adminhtml/templates/order/view/comments.phtml
================================================
<?php if($comment = $block->getOrderComment()):?>
<section class="admin__page-section">
<div class="admin__page-section-title">
<span class="title"><?php /* @escapeNotVerified */ echo __('Order Comment') ?></span>
</div>
<div class="admin__page-section-content">
<?php echo nl2br($block->escapeHtml($comment));?>
</div>
</section>
<?php endif; ?>
================================================
FILE: view/adminhtml/ui_component/sales_order_grid.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<listing xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Ui:etc/ui_configuration.xsd">
<columns name="sales_order_columns">
<column name="bold_order_comment">
<argument name="data" xsi:type="array">
<item name="js_config" xsi:type="array">
<item name="component" xsi:type="string">Magento_Ui/js/grid/columns/column</item>
</item>
<item name="config" xsi:type="array">
<item name="filter" xsi:type="string">text</item>
<item name="visible" xsi:type="boolean">true</item>
<item name="label" xsi:type="string" translate="true">Order Comment</item>
</item>
</argument>
</column>
</columns>
</listing>
================================================
FILE: view/frontend/layout/checkout_cart_index.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<!--
/**
* checkout_cart_index.xml
*
* @copyright Copyright © 2020 Bold Commerce BV. All rights reserved.
* @author dev@boldcommerce.nl
*/
-->
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<body>
<referenceContainer name="checkout.cart.container">
<block name="sales.order.comment" after="cart.discount" template="Bold_OrderComment::cart/comment.phtml" ifconfig="sales/ordercomments/show_in_cart">
<arguments>
<argument name="comment_view_model" xsi:type="object">Bold\OrderComment\ViewModel\Comment</argument>
</arguments>
</block>
</referenceContainer>
</body>
</page>
================================================
FILE: view/frontend/layout/checkout_index_index.xml
================================================
<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 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">
<item name="order-comment-validator" xsi:type="array">
<item name="component" xsi:type="string">Bold_OrderComment/js/view/checkout/order-comment-validator</item>
</item>
</item>
</item>
<item name="payments-list" xsi:type="array">
<item name="children" xsi:type="array">
<item name="before-place-order" xsi:type="array">
<item name="children" xsi:type="array">
<item name="comment" xsi:type="array">
<item name="component" xsi:type="string">Bold_OrderComment/js/view/checkout/order-comment-block</item>
</item>
</item>
</item>
</item>
</item>
</item>
</item>
</item>
</item>
</item>
</item>
</item>
</item>
</item>
</argument>
</arguments>
</referenceBlock>
</body>
</page>
================================================
FILE: view/frontend/layout/sales_order_view.xml
================================================
<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<body>
<referenceContainer name="content">
<block ifconfig="sales/ordercomments/show_in_account" class="Bold\OrderComment\Block\Order\Comment" as="ordercomment" name="sales.order.comment" after="sales.order.info"/>
</referenceContainer>
</body>
</page>
================================================
FILE: view/frontend/templates/cart/comment.phtml
================================================
<?php
/** @var \Bold\OrderComment\ViewModel\Comment $viewModel */
$viewModel = $block->getData('comment_view_model');
$oldComment = $viewModel ? $viewModel->getComment() : '';
$hasComment = !!$oldComment;
$extraValidationClasses = $viewModel ? $viewModel->getExtraClass() : '';
?>
<div class="cart-order-comment">
<div class="block order-comment"
id="block-order-comment"
data-mage-init='{"collapsible":{"active": <?= $hasComment ? 'true' : 'false' ?>, "openedState": "active", "saveState": false}}'>
<div class="title" data-role="title">
<strong id="block-order-comment-heading" role="heading" aria-level="2"><?= $block->escapeHtml(__('Edit Order Comment')) ?></strong>
</div>
<div class="content" data-role="content" aria-labelledby="block-order-comment-heading">
<form id="order-comment-form"
action="<?= $block->escapeUrl($block->getUrl('bold_ordercomment/cart/updateComment')) ?>"
data-mage-init='{"validation": {}}'
method="post">
<div class="fieldset order-comment<?= $hasComment ? ' applied' : '' ?>">
<input type="hidden" name="remove" id="remove-comment" value="0" />
<div class="field">
<label for="order_comment" class="label"><span><?= $block->escapeHtml(__('Do you have any comments regarding the order?')) ?></span></label>
<div class="control">
<textarea class="input-text order-comment order-comment-input<?= $extraValidationClasses ? ' ' . $extraValidationClasses : ''?>"
name="order_comment"
rows="4"
placeholder="<?= $block->escapeHtml(__('Enter your comment...')) ?>"
><?= $oldComment ?></textarea>
</div>
</div>
<div class="actions-toolbar">
<div class="primary">
<button class="action apply-comment primary" type="submit" value="<?= $block->escapeHtmlAttr(__('Save Comment')) ?>">
<span><?= $block->escapeHtml(__('Save Comment')) ?></span>
</button>
</div>
</div>
</div>
</form>
</div>
</div>
</div>
================================================
FILE: view/frontend/templates/order/view/comment.phtml
================================================
<?php
/** @var \Bold\OrderComment\Block\Order\Comment $block */
?>
<?php if($comment = $block->getOrderComment()):?>
<div class="block block-order-details-view">
<div class="block-content">
<div class="box box-order-comment">
<strong class="box-title"><span><?php /* @escapeNotVerified */ echo __('Order Comment') ?></span></strong>
<div class="box-content">
<?php echo $block->getOrderCommentHtml();?>
</div>
</div>
</div>
</div>
<?php endif; ?>
================================================
FILE: view/frontend/web/css/source/_module.less
================================================
._error {
.order-comment-input {
outline: none;
border: 2px solid @checkout-field-validation__border-color;
&:focus {
outline: none;
border: 2px solid @checkout-field-validation__border-color;
box-shadow: 0 0 3px @checkout-field-validation__border-color;
}
}
}
.checkout-payment-method {
.payment-option._collapsible.comment {
.payment-option-content {
display: block;
}
}
}
& when (@media-common = true) {
.cart-order-comment {
border-bottom: @border-width__base solid @border-color__base;
clear: left;
&:extend(.abs-discount-block all);
.fieldset.order-comment {
display: block;
&>div {
display: block;
}
}
}
}
//mobile
.media-width(@extremum, @break) when (@extremum = 'max') and (@break = @screen__m) {
.cart-order-comment {
border-bottom: @border-width__base solid @border-color__base;
.block>.title {
border: 0;
}
}
}
//desktop
.media-width(@extremum, @break) when (@extremum = 'min') and (@break = @screen__m) {
.cart-order-comment {
&:extend(.abs-discount-block-desktop all);
.lib-layout-column(2, 1, @layout-column-checkout__width-main);
border: 0;
box-sizing: border-box;
padding-right: 4%;
.block {
.title {
padding: 10px 0;
&:after {
display: inline;
margin-left: @indent__s;
position: static;
}
}
&.order-comment {
width: 100%;
border-bottom: @border-width__base solid @border-color__base;
border-top: @border-width__base solid @border-color__base;
}
}
}
}
================================================
FILE: view/frontend/web/js/model/checkout/order-comment-validator.js
================================================
define(
[
'jquery',
'Magento_Customer/js/model/customer',
'Magento_Checkout/js/model/quote',
'Magento_Checkout/js/model/url-builder',
'mage/url',
'Magento_Checkout/js/model/error-processor',
'Magento_Ui/js/model/messageList',
'mage/translate'
],
function ($, customer, quote, urlBuilder, urlFormatter, errorProcessor, messageContainer, __) {
'use strict';
return {
/**
* Make an ajax PUT request to store the order comment in the quote.
*
* @returns {Boolean}
*/
validate: function () {
var isCustomer = customer.isLoggedIn();
var form = this.getForm();
var comment = form.find('.input-text.order-comment').val();
if (this.hasMaxLength() && comment.length > this.getMaxLength()) {
messageContainer.addErrorMessage({ message: __("Comment is too long") });
return false;
}
var quoteId = quote.getQuoteId();
var url;
if (isCustomer) {
url = urlBuilder.createUrl('/carts/mine/set-order-comment', {})
} else {
url = urlBuilder.createUrl('/guest-carts/:cartId/set-order-comment', {cartId: quoteId});
}
var payload = {
cartId: quoteId,
orderComment: {
comment: comment
}
};
if (!payload.orderComment.comment) {
return true;
}
var result = true;
$.ajax({
url: urlFormatter.build(url),
data: JSON.stringify(payload),
global: false,
contentType: 'application/json',
type: 'PUT',
async: false
}).done(
function (response) {
result = true;
}
).fail(
function (response) {
result = false;
errorProcessor.process(response);
}
);
return result;
},
getForm: function () {
var form = $('.payment-method input[name="payment[method]"]:checked')
.parents('.payment-method')
.find('form.order-comment-form');
// Compatibility for Rubic_CleanCheckout
if (!form.length) {
form = $('form.order-comment-form');
}
return form;
},
hasMaxLength: function () {
return window.checkoutConfig.max_length > 0;
},
getMaxLength: function () {
return window.checkoutConfig.max_length;
}
};
}
);
================================================
FILE: view/frontend/web/js/view/checkout/order-comment-block.js
================================================
define(
[
'jquery',
'uiComponent',
'knockout'
],
function ($, Component, ko) {
'use strict';
ko.extenders.maxOrderCommentLength = function (target, maxLength) {
var timer;
var result = ko.computed({
read: target,
write: function (val) {
if (maxLength > 0) {
clearTimeout(timer);
if (val.length > maxLength) {
var limitedVal = val.substring(0, maxLength);
if (target() === limitedVal) {
target.notifySubscribers();
} else {
target(limitedVal);
}
result.css("_error");
timer = setTimeout(function () { result.css(""); }, 800);
} else {
target(val);
result.css("");
}
} else {
target(val);
}
}
}).extend({ notify: 'always' });
result.css = ko.observable();
result(target());
return result;
};
function getExistingComment() {
return window.checkoutConfig.existing_comment;
}
return Component.extend({
defaults: {
template: 'Bold_OrderComment/checkout/order-comment-block'
},
initialize: function() {
this._super();
var self = this;
this.comment = ko.observable(getExistingComment()).extend({maxOrderCommentLength: this.getMaxLength()});
this.remainingCharacters = ko.computed(function(){
return self.getMaxLength() - self.comment().length;
});
},
showInCheckout: function() {
return window.checkoutConfig.show_in_checkout;
},
hasMaxLength: function() {
return window.checkoutConfig.max_length > 0;
},
getMaxLength: function () {
return window.checkoutConfig.max_length;
},
getInitialCollapseState: function() {
return window.checkoutConfig.comment_initial_collapse_state;
},
isInitialStateOpened: function() {
return this.getInitialCollapseState() === 1
}
});
}
);
================================================
FILE: view/frontend/web/js/view/checkout/order-comment-validator.js
================================================
define(
[
'uiComponent',
'Magento_Checkout/js/model/payment/additional-validators',
'Bold_OrderComment/js/model/checkout/order-comment-validator'
],
function (Component, additionalValidators, commentValidator) {
'use strict';
additionalValidators.registerValidator(commentValidator);
return Component.extend({});
}
);
================================================
FILE: view/frontend/web/template/checkout/form-content.html
================================================
<form class="form form-discount order-comment-form" data-bind="mageInit: { 'validation':[]}">
<div class="payment-option-inner">
<div class="field" data-bind="css: comment.css()">
<label class="label">
<span data-bind="i18n: 'Enter comment'"></span>
</label>
<div class="control">
<textarea class="input-text order-comment order-comment-input" name="comment-code" rows="4" data-bind="value: comment,valueUpdate: 'afterkeydown',attr:{placeholder: $t('Enter your comment...')} " ></textarea>
<p data-bind="if: hasMaxLength()"><span data-bind="i18n: 'Remaining characters:'"></span> <span class="order-comment-form__characters" data-bind="text: remainingCharacters"></span></p>
</div>
</div>
</div>
</form>
================================================
FILE: view/frontend/web/template/checkout/order-comment-block.html
================================================
<!-- ko if: showInCheckout() -->
<!-- ko if: getInitialCollapseState() == 2 -->
<div class="payment-option opc-payment-additional comment last">
<div class="payment-option-title field choice">
<span data-bind="i18n: 'Do you have any comments regarding the order?'"></span>
</div>
<div class="payment-option-content">
<!-- ko template: 'Bold_OrderComment/checkout/form-content' --><!-- /ko -->
</div>
</div>
<!-- /ko -->
<!-- ko if: getInitialCollapseState() != 2 -->
<div class="payment-option _collapsible opc-payment-additional comment last"
data-bind="mageInit: {'collapsible':{'openedState': '_active', 'active': isInitialStateOpened()}}">
<div class="payment-option-title field choice" data-role="title">
<span class="action action-toggle" role="heading" aria-level="2">
<!-- ko i18n: 'Do you have any comments regarding the order?'--><!-- /ko -->
</span>
</div>
<div class="payment-option-content" data-role="content">
<!-- ko template: 'Bold_OrderComment/checkout/form-content' --><!-- /ko -->
</div>
</div>
<!-- /ko -->
<!-- /ko -->
gitextract_gvlihgyr/
├── Api/
│ ├── Data/
│ │ └── OrderCommentInterface.php
│ ├── GuestOrderCommentManagementInterface.php
│ └── OrderCommentManagementInterface.php
├── Block/
│ └── Order/
│ └── Comment.php
├── Controller/
│ └── Cart/
│ └── UpdateComment.php
├── LICENSE
├── Model/
│ ├── Config/
│ │ └── Source/
│ │ └── Collapse.php
│ ├── Config.php
│ ├── Data/
│ │ └── OrderComment.php
│ ├── GuestOrderCommentManagement.php
│ ├── OrderCommentConfigProvider.php
│ └── OrderCommentManagement.php
├── Observer/
│ └── AddOrderCommentToOrder.php
├── Plugin/
│ ├── Block/
│ │ └── Adminhtml/
│ │ └── SalesOrderViewInfo.php
│ └── Model/
│ └── Order/
│ └── LoadOrderComment.php
├── README.md
├── Setup/
│ ├── InstallData.php
│ └── Uninstall.php
├── Test/
│ ├── Integration/
│ │ ├── Model/
│ │ │ ├── GuestOrderCommentManagementTest.php
│ │ │ └── OrderCommentManagementTest.php
│ │ └── Observer/
│ │ └── AddOrderCommentToOrderTest.php
│ └── Unit/
│ ├── Model/
│ │ ├── GuestOrderCommentManagementTest.php
│ │ └── OrderCommentManagementTest.php
│ └── Observer/
│ └── AddOrderCommentToOrderTest.php
├── ViewModel/
│ └── Comment.php
├── composer.json
├── etc/
│ ├── adminhtml/
│ │ ├── di.xml
│ │ └── system.xml
│ ├── config.xml
│ ├── di.xml
│ ├── events.xml
│ ├── extension_attributes.xml
│ ├── frontend/
│ │ ├── di.xml
│ │ └── routes.xml
│ ├── module.xml
│ └── webapi.xml
├── i18n/
│ ├── ar_SA.csv
│ ├── bn_BD.csv
│ ├── cs_CZ.csv
│ ├── de_CH.csv
│ ├── de_DE.csv
│ ├── el_GR.csv
│ ├── es_ES.csv
│ ├── fr_FR.csv
│ ├── he_IL.csv
│ ├── hu_HU.csv
│ ├── it_IT.csv
│ ├── ja_JP.csv
│ ├── nl_NL.csv
│ ├── pl_PL.csv
│ ├── sl_SI.csv
│ ├── sv_SE.csv
│ └── th_TH.csv
├── registration.php
└── view/
├── adminhtml/
│ ├── layout/
│ │ └── sales_order_view.xml
│ ├── templates/
│ │ └── order/
│ │ └── view/
│ │ └── comments.phtml
│ └── ui_component/
│ └── sales_order_grid.xml
└── frontend/
├── layout/
│ ├── checkout_cart_index.xml
│ ├── checkout_index_index.xml
│ └── sales_order_view.xml
├── templates/
│ ├── cart/
│ │ └── comment.phtml
│ └── order/
│ └── view/
│ └── comment.phtml
└── web/
├── css/
│ └── source/
│ └── _module.less
├── js/
│ ├── model/
│ │ └── checkout/
│ │ └── order-comment-validator.js
│ └── view/
│ └── checkout/
│ ├── order-comment-block.js
│ └── order-comment-validator.js
└── template/
└── checkout/
├── form-content.html
└── order-comment-block.html
SYMBOL INDEX (81 symbols across 24 files)
FILE: Api/Data/OrderCommentInterface.php
type OrderCommentInterface (line 4) | interface OrderCommentInterface
method getComment (line 9) | public function getComment();
method setComment (line 15) | public function setComment($comment);
FILE: Api/GuestOrderCommentManagementInterface.php
type GuestOrderCommentManagementInterface (line 7) | interface GuestOrderCommentManagementInterface
method saveOrderComment (line 14) | public function saveOrderComment(
FILE: Api/OrderCommentManagementInterface.php
type OrderCommentManagementInterface (line 8) | interface OrderCommentManagementInterface
method saveOrderComment (line 15) | public function saveOrderComment(
FILE: Block/Order/Comment.php
class Comment (line 10) | class Comment extends \Magento\Framework\View\Element\Template
method __construct (line 19) | public function __construct(
method getOrder (line 30) | public function getOrder() : Order
method getOrderComment (line 35) | public function getOrderComment(): string
method hasOrderComment (line 40) | public function hasOrderComment() : bool
method getOrderCommentHtml (line 45) | public function getOrderCommentHtml() : string
FILE: Controller/Cart/UpdateComment.php
class UpdateComment (line 27) | class UpdateComment extends \Magento\Checkout\Controller\Cart implements...
method __construct (line 50) | public function __construct(
method execute (line 72) | public function execute()
FILE: Model/Config.php
class Config (line 15) | class Config
method __construct (line 32) | public function __construct(ScopeConfigInterface $scopeConfig)
method canShowInCheckout (line 41) | public function canShowInCheckout($website = null): bool
method canShowInAccount (line 50) | public function canShowInAccount($website = null): bool
method canShowInCart (line 59) | public function canShowInCart($website = null): bool
method getMaximumCharacterLength (line 68) | public function getMaximumCharacterLength($website = null)
method getInitialCollapseState (line 77) | public function getInitialCollapseState($website = null)
FILE: Model/Config/Source/Collapse.php
class Collapse (line 5) | class Collapse implements \Magento\Framework\Option\ArrayInterface
method toOptionArray (line 12) | public function toOptionArray()
method toArray (line 31) | public function toArray()
FILE: Model/Data/OrderComment.php
class OrderComment (line 7) | class OrderComment extends AbstractSimpleObject implements OrderCommentI...
method getComment (line 14) | public function getComment()
method setComment (line 23) | public function setComment($comment)
FILE: Model/GuestOrderCommentManagement.php
class GuestOrderCommentManagement (line 6) | class GuestOrderCommentManagement implements \Bold\OrderComment\Api\Gues...
method __construct (line 24) | public function __construct(
method saveOrderComment (line 35) | public function saveOrderComment(
FILE: Model/OrderCommentConfigProvider.php
class OrderCommentConfigProvider (line 11) | class OrderCommentConfigProvider implements ConfigProviderInterface
method __construct (line 40) | public function __construct(ScopeConfigInterface $scopeConfig, Session...
method getConfig (line 53) | public function getConfig()
FILE: Model/OrderCommentManagement.php
class OrderCommentManagement (line 10) | class OrderCommentManagement implements \Bold\OrderComment\Api\OrderComm...
method __construct (line 28) | public function __construct(
method saveOrderComment (line 43) | public function saveOrderComment(
method validateComment (line 69) | protected function validateComment($comment)
FILE: Observer/AddOrderCommentToOrder.php
class AddOrderCommentToOrder (line 6) | class AddOrderCommentToOrder implements \Magento\Framework\Event\Observe...
method execute (line 15) | public function execute(\Magento\Framework\Event\Observer $observer)
FILE: Plugin/Block/Adminhtml/SalesOrderViewInfo.php
class SalesOrderViewInfo (line 6) | class SalesOrderViewInfo
method afterToHtml (line 14) | public function afterToHtml(
FILE: Plugin/Model/Order/LoadOrderComment.php
class LoadOrderComment (line 9) | class LoadOrderComment
method __construct (line 15) | public function __construct(
method afterGet (line 23) | public function afterGet(
method afterGetList (line 31) | public function afterGetList(
method setOrderComment (line 41) | public function setOrderComment(OrderInterface $order)
method getOrderFactory (line 57) | public function getOrderFactory()
method getOrderExtensionFactory (line 62) | public function getOrderExtensionFactory()
FILE: Setup/InstallData.php
class InstallData (line 12) | class InstallData implements InstallDataInterface
method __construct (line 29) | public function __construct(
method install (line 42) | public function install(ModuleDataSetupInterface $setup, ModuleContext...
FILE: Setup/Uninstall.php
class Uninstall (line 9) | class Uninstall implements UninstallInterface
method uninstall (line 11) | public function uninstall(SchemaSetupInterface $setup, ModuleContextIn...
FILE: Test/Integration/Model/GuestOrderCommentManagementTest.php
class GuestOrderCommentManagementTest (line 14) | class GuestOrderCommentManagementTest extends TestCase
method testGuestSaveOrderComment (line 20) | public function testGuestSaveOrderComment()
FILE: Test/Integration/Model/OrderCommentManagementTest.php
class OrderCommentManagementTest (line 14) | class OrderCommentManagementTest extends TestCase
method testSaveOrderComment (line 20) | public function testSaveOrderComment()
FILE: Test/Integration/Observer/AddOrderCommentToOrderTest.php
class AddOrderCommentToOrderTest (line 15) | class AddOrderCommentToOrderTest extends TestCase
method testExecute (line 23) | public function testExecute()
FILE: Test/Unit/Model/GuestOrderCommentManagementTest.php
class GuestOrderCommentManagementTest (line 7) | class GuestOrderCommentManagementTest extends TestCase
method setUp (line 49) | protected function setUp()
method testSaveComment (line 93) | public function testSaveComment()
FILE: Test/Unit/Model/OrderCommentManagementTest.php
class OrderCommentManagementTest (line 14) | class OrderCommentManagementTest extends TestCase
method setUp (line 36) | public function setUp()
method testSaveCommentWithEmptyCart (line 59) | public function testSaveCommentWithEmptyCart()
method testSaveCommentWhenCouldNotSaveQuote (line 69) | public function testSaveCommentWhenCouldNotSaveQuote()
method testSaveCommentThatIsTooLong (line 90) | public function testSaveCommentThatIsTooLong()
method testSaveComment (line 107) | public function testSaveComment()
method testSaveCommentWithTags (line 124) | public function testSaveCommentWithTags()
method setupQuoteRepositoryMockQueries (line 141) | private function setupQuoteRepositoryMockQueries(int $cartId, int $car...
method mockOrderComment (line 151) | private function mockOrderComment(string $comment = null): \PHPUnit_Fr...
FILE: Test/Unit/Observer/AddOrderCommentToOrderTest.php
class AddOrderCommentToOrderTest (line 9) | class AddOrderCommentToOrderTest extends TestCase
method setUp (line 18) | public function setUp()
method testExecute (line 25) | public function testExecute()
FILE: ViewModel/Comment.php
class Comment (line 17) | class Comment implements ArgumentInterface
method __construct (line 35) | public function __construct(Config $config, CheckoutSession $checkoutS...
method getComment (line 48) | public function getComment(): ?string
method getExtraClass (line 61) | public function getExtraClass(): string
FILE: view/frontend/web/js/view/checkout/order-comment-block.js
function getExistingComment (line 40) | function getExistingComment() {
Condensed preview — 68 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (89K chars).
[
{
"path": "Api/Data/OrderCommentInterface.php",
"chars": 267,
"preview": "<?php\nnamespace Bold\\OrderComment\\Api\\Data;\n\ninterface OrderCommentInterface\n{\n /**\n * @return string|null\n *"
},
{
"path": "Api/GuestOrderCommentManagementInterface.php",
"chars": 497,
"preview": "<?php\nnamespace Bold\\OrderComment\\Api;\n\n/**\n * Interface for saving the checkout comment to the quote for guest orders\n "
},
{
"path": "Api/OrderCommentManagementInterface.php",
"chars": 466,
"preview": "<?php\nnamespace Bold\\OrderComment\\Api;\n\n/**\n * Interface for saving the checkout comment to the quote for orders of logg"
},
{
"path": "Block/Order/Comment.php",
"chars": 1243,
"preview": "<?php\n\nnamespace Bold\\OrderComment\\Block\\Order;\n\nuse Bold\\OrderComment\\Model\\Data\\OrderComment;\nuse Magento\\Framework\\Re"
},
{
"path": "Controller/Cart/UpdateComment.php",
"chars": 3365,
"preview": "<?php\n/**\n * UpdateComment\n *\n * @copyright Copyright © 2020 Bold Commerce BV. All rights reserved.\n * @author dev@bo"
},
{
"path": "LICENSE",
"chars": 1072,
"preview": "MIT License\n\nCopyright (c) 2017 Bold Commerce BV\n\nPermission is hereby granted, free of charge, to any person obtaining "
},
{
"path": "Model/Config/Source/Collapse.php",
"chars": 787,
"preview": "<?php\n\nnamespace Bold\\OrderComment\\Model\\Config\\Source;\n\nclass Collapse implements \\Magento\\Framework\\Option\\ArrayInterf"
},
{
"path": "Model/Config.php",
"chars": 2234,
"preview": "<?php\n/**\n * Config\n *\n * @copyright Copyright © 2020 Bold Commerce BV. All rights reserved.\n * @author dev@boldcomme"
},
{
"path": "Model/Data/OrderComment.php",
"chars": 627,
"preview": "<?php\nnamespace Bold\\OrderComment\\Model\\Data;\n\nuse Bold\\OrderComment\\Api\\Data\\OrderCommentInterface;\nuse Magento\\Framewo"
},
{
"path": "Model/GuestOrderCommentManagement.php",
"chars": 1295,
"preview": "<?php\nnamespace Bold\\OrderComment\\Model;\n\nuse Magento\\Quote\\Model\\QuoteIdMaskFactory;\n\nclass GuestOrderCommentManagement"
},
{
"path": "Model/OrderCommentConfigProvider.php",
"chars": 2069,
"preview": "<?php\n\nnamespace Bold\\OrderComment\\Model;\n\nuse Bold\\OrderComment\\Model\\Data\\OrderComment;\nuse Magento\\Checkout\\Model\\Con"
},
{
"path": "Model/OrderCommentManagement.php",
"chars": 2339,
"preview": "<?php\nnamespace Bold\\OrderComment\\Model;\n\nuse Bold\\OrderComment\\Model\\Data\\OrderComment;\nuse Magento\\Framework\\App\\Confi"
},
{
"path": "Observer/AddOrderCommentToOrder.php",
"chars": 844,
"preview": "<?php\nnamespace Bold\\OrderComment\\Observer;\n\nuse Bold\\OrderComment\\Model\\Data\\OrderComment;\n\nclass AddOrderCommentToOrde"
},
{
"path": "Plugin/Block/Adminhtml/SalesOrderViewInfo.php",
"chars": 847,
"preview": "<?php\nnamespace Bold\\OrderComment\\Plugin\\Block\\Adminhtml;\n\nuse Bold\\OrderComment\\Model\\Data\\OrderComment;\n\nclass SalesOr"
},
{
"path": "Plugin/Model/Order/LoadOrderComment.php",
"chars": 1926,
"preview": "<?php\nnamespace Bold\\OrderComment\\Plugin\\Model\\Order;\n\nuse Magento\\Sales\\Api\\OrderRepositoryInterface;\nuse Magento\\Sales"
},
{
"path": "README.md",
"chars": 7644,
"preview": "# Bold Commerce: Magento 2 Order Comments\n\n## Description\nThis extension allows customers to place a comment during the "
},
{
"path": "Setup/InstallData.php",
"chars": 2108,
"preview": "<?php\n\nnamespace Bold\\OrderComment\\Setup;\n\nuse Bold\\OrderComment\\Model\\Data\\OrderComment;\nuse Magento\\Framework\\Setup\\In"
},
{
"path": "Setup/Uninstall.php",
"chars": 893,
"preview": "<?php\nnamespace Bold\\OrderComment\\Setup;\n\nuse Bold\\OrderComment\\Model\\Data\\OrderComment;\nuse Magento\\Framework\\Setup\\Uni"
},
{
"path": "Test/Integration/Model/GuestOrderCommentManagementTest.php",
"chars": 1480,
"preview": "<?php\nnamespace Bold\\OrderComment\\Test\\Integration\\Model;\n\nuse Bold\\OrderComment\\Model\\Data\\OrderComment;\nuse Magento\\Te"
},
{
"path": "Test/Integration/Model/OrderCommentManagementTest.php",
"chars": 1250,
"preview": "<?php\nnamespace Bold\\OrderComment\\Test\\Integration\\Model;\n\nuse Bold\\OrderComment\\Model\\Data\\OrderComment;\nuse Magento\\Te"
},
{
"path": "Test/Integration/Observer/AddOrderCommentToOrderTest.php",
"chars": 1398,
"preview": "<?php\nnamespace Bold\\OrderComment\\Test\\Integration\\Observer;\n\nuse Bold\\OrderComment\\Model\\Data\\OrderComment;\nuse Magento"
},
{
"path": "Test/Unit/Model/GuestOrderCommentManagementTest.php",
"chars": 2942,
"preview": "<?php\nnamespace Bold\\OrderComment\\Test\\Unit\\Model;\n\nuse Magento\\Quote\\Test\\Unit\\Model\\GuestCart\\GuestCartTestHelper;\nuse"
},
{
"path": "Test/Unit/Model/OrderCommentManagementTest.php",
"chars": 5480,
"preview": "<?php\nnamespace Bold\\OrderComment\\Test\\Unit\\Model;\n\nuse Bold\\OrderComment\\Api\\Data\\OrderCommentInterface;\nuse Bold\\Order"
},
{
"path": "Test/Unit/Observer/AddOrderCommentToOrderTest.php",
"chars": 1689,
"preview": "<?php\nnamespace Bold\\OrderComment\\Test\\Unit\\Observer;\n\nuse Bold\\OrderComment\\Observer\\AddOrderCommentToOrder;\nuse Magent"
},
{
"path": "ViewModel/Comment.php",
"chars": 1706,
"preview": "<?php\n/**\n * Comment\n *\n * @copyright Copyright © 2020 Bold Commerce BV. All rights reserved.\n * @author dev@boldcomm"
},
{
"path": "composer.json",
"chars": 508,
"preview": "{\n \"name\": \"boldcommerce/magento2-ordercomments\",\n \"description\": \"Magento 2 Module to add a comment field above the "
},
{
"path": "etc/adminhtml/di.xml",
"chars": 395,
"preview": "<?xml version=\"1.0\"?>\n<config xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"urn:m"
},
{
"path": "etc/adminhtml/system.xml",
"chars": 2237,
"preview": "<?xml version=\"1.0\"?>\n<config xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"urn:m"
},
{
"path": "etc/config.xml",
"chars": 453,
"preview": "<?xml version=\"1.0\"?>\n<config xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"urn:m"
},
{
"path": "etc/di.xml",
"chars": 1077,
"preview": "<?xml version=\"1.0\"?>\n<config xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"urn:m"
},
{
"path": "etc/events.xml",
"chars": 374,
"preview": "<?xml version=\"1.0\"?>\n<config xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"urn:m"
},
{
"path": "etc/extension_attributes.xml",
"chars": 460,
"preview": "<?xml version=\"1.0\"?>\n<!--\n/**\n * Copyright © 2013-2017 Magento, Inc. All rights reserved.\n * See COPYING.txt for licens"
},
{
"path": "etc/frontend/di.xml",
"chars": 517,
"preview": "<?xml version=\"1.0\"?>\n<config xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"urn:m"
},
{
"path": "etc/frontend/routes.xml",
"chars": 498,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n/**\n * routes.xml\n *\n * @copyright Copyright © 2020 Bold Commerce BV. All ri"
},
{
"path": "etc/module.xml",
"chars": 328,
"preview": "<?xml version=\"1.0\"?>\n<config xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"urn:m"
},
{
"path": "etc/webapi.xml",
"chars": 899,
"preview": "<?xml version=\"1.0\"?>\n<routes xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"urn:m"
},
{
"path": "i18n/ar_SA.csv",
"chars": 284,
"preview": "\"Do you have any comments regarding the order?\",\"هل لديك اي تعليق بخصوص لطلبك؟\"\n\"Enter your comment...\",\"اكتب تعليقك\"\n\"O"
},
{
"path": "i18n/bn_BD.csv",
"chars": 317,
"preview": "\"Do you have any comments regarding the order?\",\"আপনার কি এই অর্ডার সংক্রান্ত কোন মন্তব্য আছে?\"\n\"Enter your comment...\","
},
{
"path": "i18n/cs_CZ.csv",
"chars": 325,
"preview": "\"Do you have any comments regarding the order?\",\"Máte k objednávce nějakou poznámku?\"\n\"Enter your comment...\",\"Vložte po"
},
{
"path": "i18n/de_CH.csv",
"chars": 346,
"preview": "\"Do you have any comments regarding the order?\",\"Haben Sie Anmerkungen zur Bestellung?\"\n\"Enter your comment...\",\"Anmerku"
},
{
"path": "i18n/de_DE.csv",
"chars": 346,
"preview": "\"Do you have any comments regarding the order?\",\"Haben Sie Anmerkungen zur Bestellung?\"\n\"Enter your comment...\",\"Anmerku"
},
{
"path": "i18n/el_GR.csv",
"chars": 347,
"preview": "\"Do you have any comments regarding the order?\",\"Έχετε παρατηρήσεις σχετικά με την παραγγελία;\"\n\"Enter your comment...\","
},
{
"path": "i18n/es_ES.csv",
"chars": 1132,
"preview": "\"Your comment has been saved.\",\"Se ha guardado el comentario.\"\n\"There was an error when updating the quote.\",\"Ha ocurrid"
},
{
"path": "i18n/fr_FR.csv",
"chars": 452,
"preview": "\"Do you have any comments regarding the order?\",\"Avez-vous un commentaire à nous transmettre au sujet de cette commande "
},
{
"path": "i18n/he_IL.csv",
"chars": 285,
"preview": "\"Do you have any comments regarding the order?\",\"האם יש לכם הערה בנוגע להזמנה?\"\n\"Enter your comment...\",\"הוסיפו את ההערה"
},
{
"path": "i18n/hu_HU.csv",
"chars": 368,
"preview": "\"Do you have any comments regarding the order?\",\"Üzenet a futárnak:\"\n\"Enter your comment...\",\"Például kapucsengő, kapu, "
},
{
"path": "i18n/it_IT.csv",
"chars": 347,
"preview": "\"Do you have any comments regarding the order?\",\"Hai delle richieste in merito all'ordine?\"\n\"Enter your comment...\",\"Ins"
},
{
"path": "i18n/ja_JP.csv",
"chars": 253,
"preview": "\"Do you have any comments regarding the order?\",\"注文に関して何かコメントはありますか?\"\n\"Enter your comment...\",\"コメントを入力してください...\"\n\"Order "
},
{
"path": "i18n/nl_NL.csv",
"chars": 352,
"preview": "\"Do you have any comments regarding the order?\",\"Heb je nog opmerkingen over je bestelling?\"\n\"Enter your comment...\",\"Op"
},
{
"path": "i18n/pl_PL.csv",
"chars": 311,
"preview": "\"Do you have any comments regarding the order?\",\"Dodaj komentarz do zamówienia\"\n\"Enter your comment...\",\"Twój komentarz."
},
{
"path": "i18n/sl_SI.csv",
"chars": 325,
"preview": "\"Do you have any comments regarding the order?\",\"Želite dodati komentar k vašemu naročilu?\"\n\"Enter your comment...\",\"Vne"
},
{
"path": "i18n/sv_SE.csv",
"chars": 327,
"preview": "\"Do you have any comments regarding the order?\",\"Vill du lämna en kommentar angående din order?\"\n\"Enter your comment...\""
},
{
"path": "i18n/th_TH.csv",
"chars": 337,
"preview": "\"Do you have any comments regarding the order?\",\"คุณมีความคิดเห็นเกี่ยวกับคำสั่งซื้อหรือไม่?\"\n\"Enter your comment...\",\"ใ"
},
{
"path": "registration.php",
"chars": 186,
"preview": "<?php\n \\Magento\\Framework\\Component\\ComponentRegistrar::register(\n \\Magento\\Framework\\Component\\ComponentRegis"
},
{
"path": "view/adminhtml/layout/sales_order_view.xml",
"chars": 355,
"preview": "<?xml version=\"1.0\"?>\n<page xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"urn:mag"
},
{
"path": "view/adminhtml/templates/order/view/comments.phtml",
"chars": 411,
"preview": "<?php if($comment = $block->getOrderComment()):?>\n <section class=\"admin__page-section\">\n <div class=\"admin__p"
},
{
"path": "view/adminhtml/ui_component/sales_order_grid.xml",
"chars": 891,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<listing xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSch"
},
{
"path": "view/frontend/layout/checkout_cart_index.xml",
"chars": 826,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n/**\n * checkout_cart_index.xml\n *\n * @copyright Copyright © 2020 Bold Commer"
},
{
"path": "view/frontend/layout/checkout_index_index.xml",
"chars": 3286,
"preview": "<?xml version=\"1.0\"?>\n<page xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"urn:mag"
},
{
"path": "view/frontend/layout/sales_order_view.xml",
"chars": 465,
"preview": "<?xml version=\"1.0\"?>\n<page xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"urn:mag"
},
{
"path": "view/frontend/templates/cart/comment.phtml",
"chars": 2502,
"preview": "<?php\n /** @var \\Bold\\OrderComment\\ViewModel\\Comment $viewModel */\n $viewModel = $block->getData('comment_view_mod"
},
{
"path": "view/frontend/templates/order/view/comment.phtml",
"chars": 521,
"preview": "<?php\n/** @var \\Bold\\OrderComment\\Block\\Order\\Comment $block */\n?>\n<?php if($comment = $block->getOrderComment()):?>\n<di"
},
{
"path": "view/frontend/web/css/source/_module.less",
"chars": 1843,
"preview": "._error {\n .order-comment-input {\n outline: none;\n border: 2px solid @checkout-field-validation__border-color;\n "
},
{
"path": "view/frontend/web/js/model/checkout/order-comment-validator.js",
"chars": 3100,
"preview": "define(\n [\n 'jquery',\n 'Magento_Customer/js/model/customer',\n 'Magento_Checkout/js/model/quote',"
},
{
"path": "view/frontend/web/js/view/checkout/order-comment-block.js",
"chars": 2625,
"preview": "define(\n [\n 'jquery',\n 'uiComponent',\n 'knockout'\n ],\n function ($, Component, ko) {\n "
},
{
"path": "view/frontend/web/js/view/checkout/order-comment-validator.js",
"chars": 383,
"preview": "define(\n [\n 'uiComponent',\n 'Magento_Checkout/js/model/payment/additional-validators',\n 'Bold_Or"
},
{
"path": "view/frontend/web/template/checkout/form-content.html",
"chars": 824,
"preview": "<form class=\"form form-discount order-comment-form\" data-bind=\"mageInit: { 'validation':[]}\">\n <div class=\"payment-op"
},
{
"path": "view/frontend/web/template/checkout/order-comment-block.html",
"chars": 1134,
"preview": "<!-- ko if: showInCheckout() -->\n\n<!-- ko if: getInitialCollapseState() == 2 -->\n<div class=\"payment-option opc-payment-"
}
]
About this extraction
This page contains the full source code of the boldcommerce/magento2-ordercomments GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 68 files (78.1 KB), approximately 19.9k tokens, and a symbol index with 81 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.