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]]> - - - - 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]]> + + + + 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; + }; +});