diff --git a/Model/Config/Backend/BusinessImage.php b/Model/Config/Backend/BusinessImage.php
new file mode 100644
index 0000000..34426e1
--- /dev/null
+++ b/Model/Config/Backend/BusinessImage.php
@@ -0,0 +1,68 @@
+_mediaDirectory->getAbsolutePath($this->_appendScopeInfo(self::UPLOAD_DIR));
+ }
+
+ /**
+ * Makes a decision about whether to add info about the scope.
+ *
+ * @return boolean
+ */
+ protected function _addWhetherScopeInfo()
+ {
+ return true;
+ }
+
+ /**
+ * Getter for allowed extensions of uploaded files.
+ *
+ * @return string[]
+ */
+ protected function _getAllowedExtensions()
+ {
+ return ['jpg', 'jpeg', 'png', 'svg'];
+ }
+}
diff --git a/Model/Config/Source/BusinessType.php b/Model/Config/Source/BusinessType.php
new file mode 100644
index 0000000..72be110
--- /dev/null
+++ b/Model/Config/Source/BusinessType.php
@@ -0,0 +1,72 @@
+ __('Store'), 'value' => 'Store'],
+ ['label' => __('Local Business'), 'value' => 'LocalBusiness'],
+ ['label' => __('Auto Parts Store'), 'value' => 'AutoPartsStore'],
+ ['label' => __('Bike Store'), 'value' => 'BikeStore'],
+ ['label' => __('Book Store'), 'value' => 'BookStore'],
+ ['label' => __('Clothing Store'), 'value' => 'ClothingStore'],
+ ['label' => __('Computer Store'), 'value' => 'ComputerStore'],
+ ['label' => __('Convenience Store'), 'value' => 'ConvenienceStore'],
+ ['label' => __('Department Store'), 'value' => 'DepartmentStore'],
+ ['label' => __('Electronics Store'), 'value' => 'ElectronicsStore'],
+ ['label' => __('Florist Store'), 'value' => 'Florist'],
+ ['label' => __('Furniture Store'), 'value' => 'FurnitureStore'],
+ ['label' => __('Garden Store'), 'value' => 'GardenStore'],
+ ['label' => __('Grocery Store'), 'value' => 'GroceryStore'],
+ ['label' => __('Hardware Store'), 'value' => 'HardwareStore'],
+ ['label' => __('Hobby Shop'), 'value' => 'HobbyShop'],
+ ['label' => __('Home Goods Store'), 'value' => 'HomeGoodsStore'],
+ ['label' => __('Jewelry Store'), 'value' => 'JewelryStore'],
+ ['label' => __('Liquor Store'), 'value' => 'LiquorStore'],
+ ['label' => __('Mens Clothing Store'), 'value' => 'MensClothingStore'],
+ ['label' => __('Mobile Phone Store'), 'value' => 'MobilePhoneStore'],
+ ['label' => __('Movie Rental Store'), 'value' => 'MovieRentalStore'],
+ ['label' => __('Music Store'), 'value' => 'MusicStore'],
+ ['label' => __('Office Equipment Store'), 'value' => 'OfficeEquipmentStore'],
+ ['label' => __('Outlet Store'), 'value' => 'OutletStore'],
+ ['label' => __('Pawn Shop'), 'value' => 'PawnShop'],
+ ['label' => __('Pet Store'), 'value' => 'PetStore'],
+ ['label' => __('Shoe Store'), 'value' => 'ShoeStore'],
+ ['label' => __('Sporting Goods Store'), 'value' => 'SportingGoodsStore'],
+ ['label' => __('Tire Shop'), 'value' => 'TireShop'],
+ ['label' => __('Toy Store'), 'value' => 'ToyStore'],
+ ['label' => __('Wholesale Store'), 'value' => 'WholesaleStore'],
+ ];
+ }
+}
diff --git a/Plugin/SeoRender.php b/Plugin/SeoRender.php
index d865797..4bb7341 100755
--- a/Plugin/SeoRender.php
+++ b/Plugin/SeoRender.php
@@ -294,9 +294,10 @@ public function getFullActionName()
/**
* @param Renderer $subject
- * @param string $result
+ * @param $result
*
- * @return string
+ * @return mixed|string
+ * @throws NoSuchEntityException
*/
public function afterRenderHeadContent(Renderer $subject, $result)
{
@@ -310,7 +311,8 @@ public function afterRenderHeadContent(Renderer $subject, $result)
break;
case 'cms_index_index':
if ($this->helperData->getInfoConfig('enable')) {
- $result .= $this->showBusinessStructuredData();
+ $result .= $this->showLogoStructureData();
+ $result .= $this->showLocalBussinessStructureData();
}
if ($this->helperData->getRichsnippetsConfig('enable_site_link')) {
$result .= $this->showSiteLinksStructuredData();
@@ -365,7 +367,7 @@ public function showProductStructuredData()
'@context' => 'http://schema.org/',
'@type' => 'Product',
'name' => $currentProduct->getName(),
- 'description' => trim(strip_tags($currentProduct->getDescription())),
+ 'description' => $currentProduct->getDescription() ? trim(strip_tags($currentProduct->getDescription())) : '',
'sku' => $currentProduct->getSku(),
'url' => $currentProduct->getProductUrl(),
'image' => $this->getUrl('pub/media/catalog') . 'product' . $currentProduct->getImage(),
@@ -555,12 +557,12 @@ public function addProductStructuredDataByType($productType, $currentProduct, $p
}
/**
- * add Grouped Product Structured Data
+ * Add Grouped Product Structured Data
*
* @param Product $currentProduct
* @param array $productStructuredData
*
- * @return mixed
+ * @return array
* @throws NoSuchEntityException
*/
public function getGroupedProductStructuredData($currentProduct, $productStructuredData)
@@ -577,11 +579,11 @@ public function getGroupedProductStructuredData($currentProduct, $productStructu
$offerData[] = [
'@type' => 'Offer',
'name' => $child->getName(),
- 'price' => $this->_priceHelper->currency($child->getPrice(), false),
+ 'price' => $this->_priceHelper->currency($child->getFinalPrice(), false),
'sku' => $child->getSku(),
'image' => $imageUrl
];
- $childrenPrice[] = $this->_priceHelper->currency($child->getPrice(), false);
+ $childrenPrice[] = $this->_priceHelper->currency($child->getFinalPrice(), false);
}
$productStructuredData['offers']['highPrice'] = array_sum($childrenPrice);
@@ -597,21 +599,21 @@ public function getGroupedProductStructuredData($currentProduct, $productStructu
}
/**
- * add Bundle Product Structured Data
+ * Add Bundle Product Structured Data
*
* @param Product $currentProduct
* @param array $productStructuredData
*
- * @return mixed
+ * @return array
* @throws NoSuchEntityException
*/
public function getBundleProductStructuredData($currentProduct, $productStructuredData)
{
$productStructuredData['offers']['@type'] = 'AggregateOffer';
try {
- $productStructuredData['offers']['highPrice'] = $currentProduct->getPriceInfo()->getPrice('regular_price')
+ $productStructuredData['offers']['highPrice'] = $currentProduct->getPriceInfo()->getPrice('final_price')
->getMaximalPrice()->getValue();
- $productStructuredData['offers']['lowPrice'] = $currentProduct->getPriceInfo()->getPrice('regular_price')
+ $productStructuredData['offers']['lowPrice'] = $currentProduct->getPriceInfo()->getPrice('final_price')
->getMinimalPrice()->getValue();
} catch (Exception $exception) {
$productStructuredData['offers']['highPrice'] = 0;
@@ -645,12 +647,12 @@ public function getBundleProductStructuredData($currentProduct, $productStructur
}
/**
- * add Downloadable Product Structured Data
+ * Add Downloadable Product Structured Data
*
* @param Product $currentProduct
* @param array $productStructuredData
*
- * @return mixed
+ * @return array
*/
public function getDownloadableProductStructuredData($currentProduct, $productStructuredData)
{
@@ -771,13 +773,13 @@ public function getRatingSummary()
}
/**
- * get Business Structured Data
+ * Get Logo Structured Data
*
* @return string
*/
- public function showBusinessStructuredData()
+ public function showLogoStructureData()
{
- $businessStructuredData = [
+ $logoStructureData = [
'@context' => 'http://schema.org/',
'@type' => 'Organization',
'url' => $this->getUrl(),
@@ -786,7 +788,7 @@ public function showBusinessStructuredData()
'contactPoint' => []
];
if (!empty($this->getSocialProfiles())) {
- $businessStructuredData['sameAs'] = $this->getSocialProfiles();
+ $logoStructureData['sameAs'] = $this->getSocialProfiles();
}
// get customer service info
@@ -794,7 +796,7 @@ public function showBusinessStructuredData()
|| $this->helperData->getInfoConfig('customer_service_contact_option')
|| $this->helperData->getInfoConfig('customer_service_area_serve')
) {
- $businessStructuredData['contactPoint'][] = [
+ $logoStructureData['contactPoint'][] = [
'@type' => 'ContactPoint',
'telephone' => $this->helperData->getInfoConfig('customer_service_phone'),
'contactType' => 'customer service',
@@ -807,7 +809,7 @@ public function showBusinessStructuredData()
|| $this->helperData->getInfoConfig('technical_support_contact_option')
|| $this->helperData->getInfoConfig('technical_support_area_serve')
) {
- $businessStructuredData['contactPoint'][] = [
+ $logoStructureData['contactPoint'][] = [
'@type' => 'ContactPoint',
'telephone' => $this->helperData->getInfoConfig('technical_support_phone'),
'contactType' => 'technical support',
@@ -820,7 +822,7 @@ public function showBusinessStructuredData()
|| $this->helperData->getInfoConfig('sales_contact_option')
|| $this->helperData->getInfoConfig('sales_area_serve')
) {
- $businessStructuredData['contactPoint'][] = [
+ $logoStructureData['contactPoint'][] = [
'@type' => 'ContactPoint',
'telephone' => $this->helperData->getInfoConfig('sales_phone'),
'contactType' => 'sales',
@@ -830,11 +832,66 @@ public function showBusinessStructuredData()
}
return $this->helperData->createStructuredData(
- $businessStructuredData,
- ''
+ $logoStructureData,
+ ''
);
}
+ /**
+ * Get Local Bussiness Structure data.
+ *
+ * @return string
+ * @throws NoSuchEntityException
+ */
+ public function showLocalBussinessStructureData()
+ {
+ $localBussinessStructureData = [
+ '@context' => 'http://schema.org/',
+ '@type' => $this->helperData->getInfoConfig('business_type'),
+ 'name' => $this->helperData->getInfoConfig('business_name'),
+ 'address' => [
+ '@type' => 'PostalAddress',
+ 'streetAddress' => $this->helperData->getInfoConfig('street_address'),
+ 'addressLocality' => $this->helperData->getInfoConfig('city'),
+ 'addressRegion' => $this->helperData->getInfoConfig('state_province'),
+ 'addressCountry' => $this->helperData->getConfigValue('general/country/default'),
+ 'postalCode' => $this->helperData->getInfoConfig('zip_code'),
+ 'email' => $this->helperData->getInfoConfig('email'),
+ 'faxNumber' => $this->helperData->getInfoConfig('fax')
+ ],
+ 'telephone' => $this->helperData->getInfoConfig('customer_service_phone'),
+ 'priceRange' => $this->helperData->getInfoConfig('price_range'),
+ 'description' => $this->helperData->getInfoConfig('description')
+ ];
+
+ $bussinessImages = $this->getBussinessImageUrlConfig();
+ if ($this->helperData->getInfoConfig('image')) {
+ $image = $this->_storeManager->getStore()->getBaseUrl(UrlInterface::URL_TYPE_MEDIA)
+ . 'mageplaza/seo/' . $this->helperData->getInfoConfig('image');
+ $bussinessImages[] = $image;
+ }
+ $localBussinessStructureData['image'] = $bussinessImages;
+
+ return $this->helperData->createStructuredData(
+ $localBussinessStructureData,
+ ''
+ );
+ }
+
+ /**
+ * @return array
+ */
+ protected function getBussinessImageUrlConfig()
+ {
+ if ($this->helperData->getInfoConfig('image_url')) {
+ return array_map('trim', explode(
+ "\n",
+ $this->helperData->getInfoConfig('image_url')
+ ));
+ }
+ return [];
+ }
+
/**
* get Social Profiles config
*
diff --git a/composer.json b/composer.json
index 6aabfd4..4cafd2c 100644
--- a/composer.json
+++ b/composer.json
@@ -2,10 +2,10 @@
"name": "mageplaza/magento-2-seo-extension",
"description": "Magento 2 SEO extension",
"require": {
- "mageplaza/module-core": "^1.4.5"
+ "mageplaza/module-core": "^1.4.12"
},
"type": "magento2-module",
- "version": "4.1.5",
+ "version": "4.2.0",
"license": "proprietary",
"keywords": [
"magento 2",
diff --git a/etc/adminhtml/system.xml b/etc/adminhtml/system.xml
index 0bbb320..1ba4ff9 100755
--- a/etc/adminhtml/system.xml
+++ b/etc/adminhtml/system.xml
@@ -1,260 +1,335 @@
-
-
-
-
-
- separator-top
-
- mageplaza
- Mageplaza_Seo::configuration
-
-
-
- Mageplaza\Core\Block\Adminhtml\System\Config\Head
-
- User Guide
- Boost up to ↑198% site traffic, ↑32% site ranking with Learn more
- Helpdesk
- Request features
- Increase 25% conversion rate with Layered Navigation
- Magento stores see upwards of 30% revenue 💰 with AVADA. Learn more
-
- ]]>
-
-
-
- Magento\Config\Model\Config\Source\Yesno
-
-
-
-
-
-
- Magento\Config\Model\Config\Source\Yesno
- Avoid duplicate content.
-
-
-
- Magento\Config\Model\Config\Source\Yesno
- Avoid duplicate content.
-
-
-
-
-
-
- Magento\Config\Model\Config\Source\Yesno
- Learn more ]]>
-
-
-
- Mageplaza\Seo\Model\Config\Source\Attribute
-
- 1
-
- required-entry
-
-
-
-
- 1
-
- Mageplaza\Seo\Model\Config\Source\PriceValidUntil
-
-
-
-
- 1
- custom
-
- Mageplaza\Seo\Block\Adminhtml\System\Config\Date
- required-entry
-
-
-
-
- 1
-
- Mageplaza\Seo\Model\Config\Source\ModelField
- here ]]>
-
-
-
-
- 1
-
- Mageplaza\Seo\Model\Config\Source\Attribute
- required-entry
- Recommend field: sku, barcode
-
-
-
- Magento\Config\Model\Config\Source\Yesno
- here ]]>
-
-
-
-
-
-
- Magento\Config\Model\Config\Source\Yesno
- here ]]>
-
-
-
-
- 1
-
-
-
-
-
- 1
-
-
-
-
-
- 1
-
-
-
-
-
- 1
-
-
-
-
-
- 1
-
-
-
-
-
- 1
-
-
-
-
-
- 1
-
-
-
-
-
- 1
-
-
-
-
-
- 1
-
-
-
-
-
- 1
-
-
-
-
-
-
-
-
- validate-url
- Learn more]]>
-
-
-
-
- validate-url
- Learn more]]>
-
-
-
- validate-url
- Learn more]]>
-
-
-
- validate-url
- Learn more]]>
-
-
-
- validate-url
- Learn more]]>
-
-
-
- validate-url
- Learn more]]>
-
-
-
- validate-url
- Learn more]]>
-
-
-
- validate-url
- Learn more]]>
-
-
-
- validate-url
- Learn more]]>
-
-
-
-
-
-
- tag]]>
-
-
-
- tag]]>
-
-
-
- tag]]>
-
-
-
- tag]]>
-
-
-
-
-
+
+
+
+
+
+ separator-top
+
+ mageplaza
+ Mageplaza_Seo::configuration
+
+
+
+ Mageplaza\Core\Block\Adminhtml\System\Config\Head
+
+ User Guide
+ Boost up to ↑198% site traffic, ↑32% site ranking with Learn more
+ Helpdesk
+ Request features
+ Increase 25% conversion rate with Layered Navigation
+ Magento stores see upwards of 30% revenue 💰 with AVADA. Learn more
+
+ ]]>
+
+
+
+ Magento\Config\Model\Config\Source\Yesno
+
+
+
+
+
+
+ Magento\Config\Model\Config\Source\Yesno
+ Avoid duplicate content.
+
+
+
+ Magento\Config\Model\Config\Source\Yesno
+ Avoid duplicate content.
+
+
+
+
+
+
+ Magento\Config\Model\Config\Source\Yesno
+ Learn more ]]>
+
+
+
+ Mageplaza\Seo\Model\Config\Source\Attribute
+
+ 1
+
+ required-entry
+
+
+
+
+ 1
+
+ Mageplaza\Seo\Model\Config\Source\PriceValidUntil
+
+
+
+
+ 1
+ custom
+
+ Mageplaza\Seo\Block\Adminhtml\System\Config\Date
+ required-entry
+
+
+
+
+ 1
+
+ Mageplaza\Seo\Model\Config\Source\ModelField
+ here ]]>
+
+
+
+
+ 1
+
+ Mageplaza\Seo\Model\Config\Source\Attribute
+ required-entry
+ Recommend field: sku, barcode
+
+
+
+ Magento\Config\Model\Config\Source\Yesno
+ here ]]>
+
+
+
+
+
+
+ Magento\Config\Model\Config\Source\Yesno
+ here ]]>
+
+
+
+
+ 1
+
+
+
+
+ Mageplaza\Seo\Model\Config\Source\BusinessType
+
+ 1
+
+
+
+
+ validate-phone-number
+
+ 1
+
+
+
+
+
+ 1
+
+
+
+
+
+ 1
+
+
+
+
+ validate-phone-number
+
+ 1
+
+
+
+
+
+ 1
+
+
+
+
+
+ 1
+
+
+
+
+ validate-phone-number
+
+ 1
+
+
+
+
+
+ 1
+
+
+
+
+
+ 1
+
+
+
+
+ Mageplaza\Seo\Model\Config\Backend\BusinessImage
+ mageplaza/seo
+
+ 1
+
+
+
+
+
+ 1
+
+
+
+
+
+ 1
+
+
+
+
+
+ 1
+
+
+
+
+
+ 1
+
+
+
+
+
+ 1
+
+
+
+
+ validate-email
+
+ 1
+
+
+
+
+ validate-fax
+
+ 1
+
+
+
+
+
+
+ 1
+
+
+
+
+
+ 1
+
+
+
+
+
+
+
+
+ validate-url
+ Learn more]]>
+
+
+
+
+ validate-url
+ Learn more]]>
+
+
+
+ validate-url
+ Learn more]]>
+
+
+
+ validate-url
+ Learn more]]>
+
+
+
+ validate-url
+ Learn more]]>
+
+
+
+ validate-url
+ Learn more]]>
+
+
+
+ validate-url
+ Learn more]]>
+
+
+
+ validate-url
+ Learn more]]>
+
+
+
+ validate-url
+ Learn more]]>
+
+
+
+
+
+
+ tag]]>
+
+
+
+ tag]]>
+
+
+
+ tag]]>
+
+
+
+ tag]]>
+
+
+
+
+
diff --git a/etc/config.xml b/etc/config.xml
index 2447041..594f562 100755
--- a/etc/config.xml
+++ b/etc/config.xml
@@ -1,48 +1,52 @@
-
-
-
-
-
-
- 1
- seo-m2
-
-
- 1
-
- 0
- manufacturer
- 7days
- mpn
- sku
-
-
-
-
-
- 1
- 1
-
-
-
-
+
+
+
+
+
+
+ 1
+ seo-m2
+
+
+ 1
+
+
+ 0
+ manufacturer
+ 7days
+ mpn
+ sku
+
+
+ 0
+ Store
+
+
+
+
+ 1
+ 1
+
+
+
+
diff --git a/view/adminhtml/requirejs-config.js b/view/adminhtml/requirejs-config.js
new file mode 100644
index 0000000..3b632a9
--- /dev/null
+++ b/view/adminhtml/requirejs-config.js
@@ -0,0 +1,29 @@
+/**
+ * Mageplaza
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Mageplaza.com license that is
+ * available through the world-wide-web at this URL:
+ * https://www.mageplaza.com/LICENSE.txt
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade this extension to newer
+ * version in the future.
+ *
+ * @category Mageplaza
+ * @package Mageplaza_Seo
+ * @copyright Copyright (c) Mageplaza (https://www.mageplaza.com/)
+ * @license https://www.mageplaza.com/LICENSE.txt
+ */
+
+var config = {
+ config: {
+ mixins: {
+ 'mage/validation': {
+ 'Mageplaza_Seo/js/admin-config/validator-rules-mixin': true
+ }
+ }
+ }
+};
diff --git a/view/adminhtml/web/js/admin-config/validator-rules-mixin.js b/view/adminhtml/web/js/admin-config/validator-rules-mixin.js
new file mode 100644
index 0000000..c15ba2d
--- /dev/null
+++ b/view/adminhtml/web/js/admin-config/validator-rules-mixin.js
@@ -0,0 +1,40 @@
+/**
+ * Mageplaza
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Mageplaza.com license that is
+ * available through the world-wide-web at this URL:
+ * https://www.mageplaza.com/LICENSE.txt
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade this extension to newer
+ * version in the future.
+ *
+ * @category Mageplaza
+ * @package Mageplaza_Seo
+ * @copyright Copyright (c) Mageplaza (https://www.mageplaza.com/)
+ * @license https://www.mageplaza.com/LICENSE.txt
+ */
+
+define([
+ 'jquery'
+], function ($) {
+ 'use strict';
+ return function (target) {
+ $.validator.addMethod(
+ 'validate-phone-number',
+ function (value) {
+ var regex = new RegExp(/^((\+\d{1,3}(-| )?\(?\d\)?(-| )?\d{1,5})|(\(?\d{2,6}\)?))(-| )?(\d{3,4})(-| )?(\d{4})(( x| ext)\d{1,5}){0,1}$/);
+ if (value.length) {
+ return regex.match(value);
+ } else {
+ return true;
+ }
+ },
+ $.mage.__('Please enter a valid phone number')
+ );
+ return target;
+ };
+});