Developer Manual¶
In addition to the possible use in a TYPO3, the extension serves in particular to show how an own product table can be linked to EXT:cart.
You need a form and an add to cart finisher for the conversion. The form is sent to a controller of EXT:cart. In order to decide which finisher to use, a unique product type must be passed. Furthermore the form has to transmit the information that the AddToCartFinisher needs to load the correct product and prepare it for the shopping cart.
Note
Thereby one is not directed to a TYPO3 database. The product can be created from the transferred information or loaded via an API.
The Form¶
The form itself needs two pieces of information. First, the page ID of the cart page and the PageType, if the products are to be added to the shopping cart via AJAX request. Both information have to be configured for EXT:cart anyway and can be loaded in the controller via the ConfigurationManager, or as in this example copied into the TypoScript configuration of EXT:news.
<f:form id="news-{newsItem.uid}"
class="add-to-cart-form"
pageUid="{settings.cart.pid}"
extensionName="Cart"
pluginName="Cart"
controller="Cart\Product"
action="add"
method="post"
pageType="{f:if(condition:'{settings.addToCartByAjax}', then:'{settings.addToCartByAjax}', else:'')}"
additionalAttributes="{data-ajax: '{f:if(condition: \'{settings.addToCartByAjax}\', then: \'1\', else: \'0\')}', data-type: 'news', data-id: '{newsItem.uid}'}">
...
</form>
The form then contains a field for the number. In theory, this could also be a non-visible field with a fixed number. Two other non-visible form fields transmit the product type “CartNews” and the ID of the news item.
<input type="hidden" name="tx_cart_cart[productType]" value="CartNews">
<input type="hidden" name="tx_cart_cart[newsItem]" value="{newsItem.uid}">
<input class="form-control" type="text"name="tx_cart_cart[quantity]" value="1">
<input type="submit" class="btn btn-secondary" value="{f:translate(key:'tx_cartnews.add_to_cart', extensionName: 'CartNews')}">
The Finisher¶
So that the controller of EXT:cart can decide which finisher is responsible for
this product type, it must be registered in the ext_localconf.php
of the own
product extension or in the SitePackage.
// Cart AddToCartFinisher
if (TYPO3_MODE === 'FE') {
$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['cart']['CartNews']['Cart']['AddToCartFinisher'] =
\Extcode\CartNews\Domain\Finisher\Cart\AddToCartFinisher::class;
}
The class registered here must implement the interface
\Extcode\Cart\Domain\Finisher\Cart\AddToCartFinisherInterface
.
This interface has two methods. One checkAvailability
is called to check in
different places if there are enough products in the stock. Since this
extension sells news articles and these are traded as virtual products by the
implementation, the implementation is relatively simple.
public function checkAvailability(
Request $request,
Product $cartProduct,
Cart $cart,
$mode = 'update'
): AvailabilityResponse {
return GeneralUtility::makeInstance(
AvailabilityResponse::class
);
}
The \Extcode\Cart\Domain\Model\Dto\AvailabilityResponse
class says by default
that a product is available. It could also be used to check the availability
of a product and return a message in addition to the status. A corresponding
example can be found in EXT:cart_products.
The second method getProductFromRequest
gets the request and based on the
form arguments the product for the shopping cart must be created.
In the implementation in EXT:cart_news, the data record is first loaded from
the database using the transferred message ID.
With this record and the other information from the request, the method
getCartProductFromNews
is then called.
This method returns a virtual product of type \Extcode\Cart\Domain\Model\Cart\Product
.
Since EXT:cart_news does not need any stock management, nothing needs to be considered at this point when customers place an order.