Gelişmiş Ürün Seçenekleri Uzantısında Seçeneklere Özel Alan Nasıl Eklenir
Yayınlanan: 2020-09-08Bu makaleden, ürün özel seçenekleri için bir "GTIN" alanının nasıl oluşturulacağını, ürün sayfasında ön uçta nasıl gösterileceğini ve sırayla görüntüleneceğini öğreneceksiniz.
Lafı fazla uzatmadan adım adım yönergelere geçelim.
İçindekiler
- Aşama 1. Yeni Modül Oluştur
- Adım 2. Yeni Alanımızı Veritabanına Ekleyin
- Aşama 3. Arka Uçla Çalışmak için Mantık Ekleyin
- 4. Adım. Alanımızı Ürün Sayfası Ön Uçta Görüntüleyin
- Adım 5. Öznitelik Verilerimizi Veritabanındaki Sipariş Ayrıntılarına Ekleyin
- Adım #6. Yönetici Panelindeki Siparişler Sayfasındaki Verileri Görüntüle
Aşama 1. Yeni Modül Oluştur
Modül oluşturmayı bu yazımızda detaylı olarak anlattık. Bu nedenle, bu kısmı atlayalım ve doğrudan bir eklenti oluşturmak için ihtiyaç duyacağınız koda geçelim:
1.besteci.json
{ "name": "mageworx/module-optiongtin", "description": "N/A", "require": { "magento/framework" : ">=100.1.0 <101", "magento/module-catalog": ">=101.0.0 <104" }, "type": "magento2-module", "version": "1.0.0", "license": [ "OSL-3.0", "AFL-3.0" ], "autoload": { "files": [ "registration.php" ], "psr-4": { "VendorName\\OptionGtin\\": "" } } }
2.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="VendorName_OptionGtin" setup_version="1.0.0"> <sequence> <module name="Magento_Catalog"/> <module name="MageWorx_OptionBase"/> </sequence> </module> </config>
3.registration.php
<?php \Magento\Framework\Component\ComponentRegistrar::register( \Magento\Framework\Component\ComponentRegistrar::MODULE, 'VendorName_OptionGtin', __DIR__ );
Adım 2. Yeni Alanımızı Veritabanına Ekleyin
Boş bir modül oluşturduktan sonra sıra yeni “GTIN” alanını oluşturup ilgili tablodaki veritabanına eklemeye geliyor. Seçenek değerleri için bir alan eklediğimizde “catalog_product_option” tablosuna ihtiyacımız olacak.
Aşağıdaki dosyayı oluşturalım:
app/code/VendorName/OptionGtin/Setup/InstallSchema.php
<?php namespace VendorName\OptionGtin\Setup; use Magento\Framework\Setup\InstallSchemaInterface; use Magento\Framework\Setup\ModuleContextInterface; use Magento\Framework\Setup\SchemaSetupInterface; use Magento\Framework\DB\Ddl\Table; class InstallSchema implements InstallSchemaInterface { public function install(SchemaSetupInterface $setup, ModuleContextInterface $context) { $setup->startSetup(); $setup->getConnection()->addColumn( $setup->getTable('catalog_product_option'), 'gtin', [ 'type' => Table::TYPE_TEXT, 'nullable' => true, 'default' => null, 'comment' => 'Gtin (added by VendorName Option Gtin)', ] ); $setup->endSetup(); } }
Aşama 3. Arka Uçla Çalışmak için Mantık Ekleyin
Yeni alanımızı eklemek için havuz değiştirici mekanizmasını kullanacağız.
Şimdi aşağıdaki dosyayı ekleyin:
app/code/VendorName/OptionGtin/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"> <virtualType name="MageWorx\OptionBase\Ui\DataProvider\Product\Form\Modifier\Pool"> <arguments> <argument name="modifiers" xsi:type="array"> <item name="mageworx-option-gtin" xsi:type="array"> <item name="class" xsi:type="string">VendorName\OptionGtin\Ui\DataProvider\Product\Form\Modifier\OptionGtin</item> <item name="sortOrder" xsi:type="number">72</item> </item> </argument> </arguments> </virtualType> </config>
Burada, değiştiricimizi Gelişmiş Ürün Seçenekleri uzantısının paylaşılan havuzuna ekleyelim―”MageWorx\OptionBase\Ui\DataProvider\Product\Form\Modifier\Pool”. “VendorName\OptionGtin\Ui\DataProvider\Product\Form\Modifier\OptionGtin” sınıf değiştiricimizdir.
app/code/VendorName/OptionGtin/Ui/DataProvider/Product/Form/Modifier/OptionGtin.php
formuna eklemeyi sağlayan kod aşağıda verilmiştir:
<?php namespace VendorName\OptionGtin\Ui\DataProvider\Product\Form\Modifier; use Magento\Catalog\Ui\DataProvider\Product\Form\Modifier\AbstractModifier; use Magento\Catalog\Ui\DataProvider\Product\Form\Modifier\CustomOptions; use Magento\Ui\Component\Form\Element\Input; use Magento\Ui\Component\Form\Element\DataType\Number; use Magento\Ui\Component\Form\Field; use MageWorx\OptionBase\Ui\DataProvider\Product\Form\Modifier\ModifierInterface; class OptionGtin extends AbstractModifier implements ModifierInterface { /** * @var array */ protected $meta = []; /** * {@inheritdoc} */ public function modifyData(array $data) { return $data; } /** * {@inheritdoc} */ public function modifyMeta(array $meta) { $this->meta = $meta; $this->addFields(); return $this->meta; } /** * Adds fields to the meta-data */ protected function addFields() { $groupCustomOptionsName = CustomOptions::GROUP_CUSTOM_OPTIONS_NAME; $optionContainerName = CustomOptions::CONTAINER_OPTION; $commonOptionContainerName = CustomOptions::CONTAINER_COMMON_NAME; // Add fields to the option $optionFeaturesFields = $this->getOptionGtinFieldsConfig(); $this->meta[$groupCustomOptionsName]['children']['options']['children']['record']['children'] [$optionContainerName]['children'][$commonOptionContainerName]['children'] = array_replace_recursive( $this->meta[$groupCustomOptionsName]['children']['options']['children']['record']['children'] [$optionContainerName]['children'][$commonOptionContainerName]['children'], $optionFeaturesFields ); } /** * The custom option fields config * * @return array */ protected function getOptionGtinFieldsConfig() { $fields['gtin'] = $this->getGtinFieldConfig(); return $fields; } /** * Get gtin field config * * @return array */ protected function getGtinFieldConfig() { return [ 'arguments' => [ 'data' => [ 'config' => [ 'label' => __('GTIN'), 'componentType' => Field::NAME, 'formElement' => Input::NAME, 'dataType' => Number::NAME, 'dataScope' => 'gtin', 'sortOrder' => 65 ], ], ], ]; } /** * Check is current modifier for the product only * * @return bool */ public function isProductScopeOnly() { return false; } /** * Get sort order of modifier to load modifiers in the right order * * @return int */ public function getSortOrder() { return 32; } }
Şimdi uzantıyı yüklemeye çalışalım ve her şeyin görüntülenip görüntülenmediğini kontrol edelim:
- php bin/magento modülü:SatıcıAdı_OptionGtin'i etkinleştirin
- php bin/magento kurulumu:yükseltme
- php bin/magento önbelleği:flush
Yeni alanımız başarıyla eklendi:
4. Adım. Alanımızı Ürün Sayfası Ön Uçta Görüntüleyin
Mageworx Gelişmiş Ürün Seçenekleri uzantısı, modülümüzün eklediği özellikleri görüntülemek ve bunlarla çalışmak için zaten her şeye sahiptir. Tek yapmamız gereken, paylaşılan veri kümesine yeni özniteliği eklemek.
MageWorx_OptionBase modülümüz zaten getExtendedOptionsConfig()
yöntemini kullanıyor. Ön uçtaki bir bloktaki tüm özel nitelikleri toplar ve görüntüler. Nasıl uygulandığını görmek için app/code/MageWorx/OptionBase/Block/Product/View/Options.php
sınıfını açın.
Özniteliğimizle bir model oluşturmaya başlayalım:
app/code/VendorName/OptionGtin/Model/Attriburte/Option/Gtin.php
<?php namespace VendorName\OptionGtin\Model\Attribute\Option; use MageWorx\OptionBase\Model\Product\Option\AbstractAttribute; class Gtin extends AbstractAttribute { /** * @return string */ public function getName() { return 'gtin'; } }
Şimdi, "bağımlılık ekleme" mekanizmasını kullanın ve özelliğimizi Gelişmiş Ürün Seçenekleri uzantısının paylaşılan nitelikler veri kümesine ekleyin.
app/code/VendorName/OptionGtin/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"> <!-- Data --> <type name="MageWorx\OptionBase\Model\Product\Option\Attributes"> <arguments> <argument name="data" xsi:type="array"> <item name="gtin" xsi:type="object">VendorName\OptionGtin\Model\Attribute\Option\Gtin</item> </argument> </arguments> </type> </config>
Başka bir deyişle, MageWorx\OptionBase\Model\Product\Option\Attributes
sınıfını açarak, bunun tüm öznitelik nesnelerini paylaşılan veri kümesine topladığını göreceksiniz.
Yeni "GTIN" özelliğimizin verilerini görüntülemek için app/code/MageWorx/OptionFeatures/view/base/web/js/catalog/product/features.js
firstrun()
işlevini kullanmaya karar verdik. Örneğimize en iyi uyan gerekli tüm uygulamaya zaten sahiptir. Tüm dosyanın üzerine yazmaktan kaçınmak için, yalnızca gerekli işlevi değiştirmemize yardımcı olacak “JavaScript mixins” mekanizmasını uygulayacağız.
Aşağıdaki dosyayı oluşturun ve karışımımızı orada tanımlayın: app/code/VendorName/OptionGtin/view/frontend/requirejs-config.js
var config = { config: { mixins: { 'MageWorx_OptionFeatures/js/catalog/product/features': { 'VendorName_OptionGtin/js/catalog/product/features-gtin-mixin' : true } } } };
Burada MageWorx_OptionFeatures/js/catalog/product/features
dosyamızın köküdür, hangi yöntemi yeniden yazmamız gerekiyor. VendorName_OptionGtin/js/catalog/product/features-gtin-mixin
metodu yeniden yazacağımız dosyadır.
Şimdi onu oluşturalım: app/code/VendorName/OptionGtin/view/frontend/web/js/catalog/product/features-gtin-mixin.js
define([ 'jquery', 'jquery/ui', 'mage/utils/wrapper' ], function ($, wrapper) { 'use strict'; return function (widget) { $.widget('mageworx.optionFeatures', widget, { /** * Triggers one time at first run (from base.js) * @param optionConfig * @param productConfig * @param base * @param self */ firstRun: function firstRun(optionConfig, productConfig, base, self) { //shareable link $('#mageworx_shareable_hint_icon').qtip({ content: { text: this.options.shareable_link_hint_text }, style: { classes: 'qtip-light' }, position: { target: false } }); $('#mageworx_shareable_link').on('click', function () { try { self.copyTextToClipboard(self.getShareableLink(base)); $('.mageworx-shareable-link-container').hide(); $('.mageworx-shareable-link-success-container').show(); setTimeout(function () { $('.mageworx-shareable-link-container').show(); $('.mageworx-shareable-link-success-container').hide(); }, 2000); } catch (error) { console.log('Something goes wrong. Unable to copy'); } }); setTimeout(function () { // Qty input $('.mageworx-option-qty').each(function () { $(this).on('change', function () { var optionInput = $("[data-selector='" + $(this).attr('data-parent-selector') + "']"); optionInput.trigger('change'); }); }); }, 500); // Option\Value Description & tooltip var extendedOptionsConfig = typeof base.options.extendedOptionsConfig != 'undefined' ? base.options.extendedOptionsConfig : {}; for (var option_id in optionConfig) { if (!optionConfig.hasOwnProperty(option_id)) { continue; } var description = extendedOptionsConfig[option_id]['description'], gtin = extendedOptionsConfig[option_id]['gtin'], gtinTitle = "Global Trade Item Number: ", $option = base.getOptionHtmlById(option_id); if (1 > $option.length) { console.log('Empty option container for option with id: ' + option_id); continue; } var $label = $option.find('label'); if(gtin != null && gtin.length > 0) { if ($label.length > 0) { $label .first() .after($('<p class="option-gtin-text"><span>' + gtinTitle + '</span>' + gtin + '</p>')); } else { $label = $option.find('span'); $label .first() .parent() .after($('<p class="option-gtin-text"><span>' + gtinTitle + '</span>' + gtin + '</p>')); } } if (this.options.option_description_enabled && !_.isEmpty(extendedOptionsConfig[option_id]['description'])) { if (this.options.option_description_mode == this.options.option_description_modes.tooltip) { var $element = $option.find('label span') .first(); if ($element.length == 0) { $element = $option.find('fieldset legend span') .first(); } $element.css('border-bottom', '1px dotted black'); $element.qtip({ content: { text: description }, style: { classes: 'qtip-light' }, position: { target: false } }); } else if (this.options.option_description_mode == this.options.option_description_modes.text) { if ($label.length > 0) { $label .first() .after($('<p class="option-description-text">' + description + '</p>')); } else { $label = $option.find('span'); $label .first() .parent() .after($('<p class="option-description-text">' + description + '</p>')); } } else { console.log('Unknown option mode'); } } if (this.options.value_description_enabled) { this._addValueDescription($option, optionConfig, extendedOptionsConfig); } } } }); return $.mageworx.optionFeatures; }; });
Genel olarak, şimdi aşağıdaki komutları çalıştırabiliriz:
- php bin/magento önbelleği:flush
- php bin/magento kurulumu:statik içerik:dağıtım (yalnızca üretim modu için)
ve elimizde ne olduğunu görün. Ama önce, yeni özelliğimize bazı stiller ekleyin ve ön uçta güzel görünmesini sağlayın.
Bir düzen oluşturun ve yeni stil dosyamızı orada tanımlayın: app/code/VendorName/OptionGtin/view/frontend/layout/catalog_product_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"> <head> <css src="VendorName_OptionGtin::css/gtin.css"/> </head> </page>
Bir stil dosyası oluşturmanın zamanı geldi: app/code/VendorName/OptionGtin/view/frontend/web/css/gtin.css
.option-gtin-text span { color: #6cc308; font-weight: 700; }
Şimdi daha önce açıklanan komutları çalıştıralım ve sonuçları kontrol edelim:
Adım 5. Öznitelik Verilerimizi Veritabanındaki Sipariş Ayrıntılarına Ekleyin
Bir müşteri bir satın alma yaptığında, bir sipariş oluşturulur. Eklenen öğelerle ilgili ayrıntılar, sales_order_item
tablosuna dahil edilir. Bu tablo, eklenen bir öğenin seçilen parametreleri hakkında bilgi içeren product_options
alanına sahiptir. Yeni özniteliğimizin verilerini buraya eklemeliyiz.
Bir sipariş oluşturulduğunda, sales_quote_address_collect_totals_before
olayı tetiklenir. Verilerimizi ürün seçeneklerine eklemek için kullanacağız.
Olayı şu şekilde tanımlayalım: app/code/VendorName/OptionGtin/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_quote_address_collect_totals_before"> <observer name="mageworx_optiongtin_add_gtin_to_order" instance="VendorName\OptionGtin\Observer\AddGtinToOrder" /> </event> </config>
Ardından, gözlemcimizi oluşturun: app/code/VendorName/OptionGtin/Observer/AddGtinToOrder.php
<?php namespace VendorName\OptionGtin\Observer; use Magento\Framework\Event\Observer; use Magento\Framework\Event\ObserverInterface; use Magento\Catalog\Model\ProductRepository as ProductRepository; use MageWorx\OptionBase\Helper\Data as BaseHelper; class AddGtinToOrder implements ObserverInterface { /** * @var BaseHelper */ protected $baseHelper; protected $productRepository; /** * AddGtinToOrder constructor. * @param BaseHelper $baseHelper * @param ProductRepository $productRepository */ public function __construct( BaseHelper $baseHelper, ProductRepository $productRepository ) { $this->baseHelper = $baseHelper; $this->productRepository = $productRepository; } /** * Add product to quote action * Processing: gtin * * @param Observer $observer * @return $this */ public function execute(Observer $observer) { $quoteItems = $observer->getQuote()->getAllItems(); /** @var \Magento\Quote\Model\Quote\Item $quoteItem */ foreach ($quoteItems as $quoteItem) { $buyRequest = $quoteItem->getBuyRequest(); $optionIds = array_keys($buyRequest->getOptions()); $productOptions = $this->productRepository->getById($buyRequest->getProduct())->getOptions(); $quoteItemOptionGtins = []; $optionGtins = []; foreach ($productOptions as $option) { if ($option->getGtin()) { $quoteItemOptionGtins[$option->getOptionId()] = $option->getGtin(); } } foreach ($optionIds as $optionId) { $optionGtins[$optionId] = $optionId; } $optionGtins = array_intersect_key($quoteItemOptionGtins, $optionGtins); $infoBuyRequest = $quoteItem->getOptionByCode('info_buyRequest'); $buyRequest->setData('gtin', $optionGtins); $infoBuyRequest->setValue($this->baseHelper->encodeBuyRequestValue($buyRequest->getData())); $quoteItem->addOption($infoBuyRequest); } } }
Burada, gözlemcinin yardımıyla, siparişteki tüm öğelerin listesini alıyoruz ve “GTIN” özelliğimizin verilerini $infoBuyRequest
olarak adlandırılana ekliyoruz.
Her şeyin doğru yapılıp yapılmadığını kontrol etmek için, seçeneklerde “GTIN” verisi bulunan ürünle bir sipariş oluşturun. Verilerin eklenip eklenmediğini Database sales_order_item table
-> product_options
alanında kontrol edebilirsiniz:
Adım #6. Yönetici Panelindeki Siparişler Sayfasındaki Verileri Görüntüle
Hazır şablonda gerekli bilgileri göstermenin farklı yolları vardır. Örneğin, “js” kullanmak. Bu yazıda “js” ile çalıştık. Bir değişiklik için şablonların kendileri üzerinde çalışalım ve onları yeniden yazmaya çalışalım!
Eklentiyi buraya ekleyerek önceden oluşturulmuş app/code/VendorName/OptionGtin/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"> <virtualType name="MageWorx\OptionBase\Ui\DataProvider\Product\Form\Modifier\Pool"> <arguments> <argument name="modifiers" xsi:type="array"> <item name="mageworx-option-gtin" xsi:type="array"> <item name="class" xsi:type="string">VendorName\OptionGtin\Ui\DataProvider\Product\Form\Modifier\OptionGtin</item> <item name="sortOrder" xsi:type="number">72</item> </item> </argument> </arguments> </virtualType> <!-- Plugins--> <type name="Magento\Sales\Block\Adminhtml\Items\Column\DefaultColumn"> <plugin name="mageworx-optiongtin-add-default-column" type="VendorName\OptionGtin\Plugin\AddDefaultColumn" sortOrder="5" disabled="false" /> </type> </config>
Eklentinin kendisini oluşturun:
app/code/VendorName/OptionGtin/Plugin/AddDefaultColumn.php
<?php namespace VendorName\OptionGtin\Plugin; class AddDefaultColumn { /** * @param \Magento\Sales\Block\Adminhtml\Items\Column\DefaultColumn $subject * @param $result * @return array */ public function afterGetOrderOptions(\Magento\Sales\Block\Adminhtml\Items\Column\DefaultColumn $subject, $result) { if ($options = $subject->getItem()->getProductOptions()) { if (isset($result)) { foreach ($result as &$option) { if (array_key_exists($option['option_id'], $options['info_buyRequest']['gtin'])) { $option['gtin'] = $options['info_buyRequest']['gtin'][$option['option_id']]; } } } } return $result; } }
Bu eklenti, bu verilerin mevcut olduğu sipariş seçenekleri için yeni özelliğimiz hakkında bilgi ekler.
vendor/magento/module-sales/view/adminhtml/templates/items/column/name.phtml
, yönetici panelindeki sipariş sayfasında ürün seçenekleriyle ilgili bilgilerin görüntülenmesinden sorumludur.
“GTIN” imizi görüntülemek için yeniden yazalım. Bunun için “column_name” bloğunu daha doğrusu şablonunu yeniden yazmamız gerekiyor. Bir düzen ve şablon oluşturun:
app/code/VendorName/OptionGtin/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> <referenceBlock name="column_name"> <action method="setTemplate"> <argument name="template" xsi:type="string">VendorName_OptionGtin::items/column/name.phtml</argument> </action> </referenceBlock> </body> </page>
app/code/VendorName/OptionGtin/view/adminhtml/templates/items/column/name.phtml
<?php /* @var $block \Magento\Sales\Block\Adminhtml\Items\Column\Name */ ?> <?php if ($_item = $block->getItem()) : ?> <div class="product-title"> <?= $block->escapeHtml($_item->getName()) ?> </div> <div class="product-sku-block"> <span><?= $block->escapeHtml(__('SKU'))?>:</span> <?= /* @noEscape */ implode('<br />', $this->helper(\Magento\Catalog\Helper\Data::class)->splitSku($block->escapeHtml($block->getSku()))) ?> </div> <?php if ($block->getOrderOptions()) : ?> <dl class="item-options"> <?php foreach ($block->getOrderOptions() as $_option) : ?> <dt><?= $block->escapeHtml($_option['label']) ?>:</dt> <dd> <?php if (isset($_option['custom_view']) && $_option['custom_view']) : ?> <?= /* @noEscape */ $block->getCustomizedOptionValue($_option) ?> <?php else : ?> <?php $optionValue = $block->getFormattedOption($_option['value']); ?> <?php $dots = 'dots' . uniqid(); ?> <?php $ . uniqid(); ?> <?= $block->escapeHtml($optionValue['value'], ['a', 'br']) ?><?php if (isset($optionValue['remainder']) && $optionValue['remainder']) : ?> <span> ...</span> <span><?= $block->escapeHtml($optionValue['remainder'], ['a']) ?></span> <script> require(['prototype'], function() { $('<?= /* @noEscape */ $id; ?>').hide(); $('<?= /* @noEscape */ $id; ?>').up().observe('mouseover', function(){$('<?= /* @noEscape */ $id; ?>').show();}); $('<?= /* @noEscape */ $id; ?>').up().observe('mouseover', function(){$('<?= /* @noEscape */ $dots; ?>').hide();}); $('<?= /* @noEscape */ $id; ?>').up().observe('mouseout', function(){$('<?= /* @noEscape */ $id; ?>').hide();}); $('<?= /* @noEscape */ $id; ?>').up().observe('mouseout', function(){$('<?= /* @noEscape */ $dots; ?>').show();}); }); </script> <?php endif; ?> <?php endif; ?> </dd> <dt> <?php if (isset($_option['gtin']) && $_option['gtin']) : ?> <span>GTIN:</span> <?php endif; ?> </dt> <dd> <?php if (isset($_option['gtin']) && $_option['gtin']) : ?> <span> <?= $block->escapeHtml($_option['gtin']) ?></span> <?php endif; ?> </dd> <?php endforeach; ?> </dl> <?php endif; ?> <?= $block->escapeHtml($_item->getDescription()) ?> <?php endif; ?>
Her şey doğru yapıldıysa, temizlendiyse ve derlendiyse, aşağıdaki sonucu göreceksiniz:
Bu makaleyi yararlı bulacağınızı umuyoruz. Herhangi bir zorluk veya sorununuz varsa, aşağıdaki yorumlar alanında bize bildirmekten çekinmeyin.