Merge pull request #3088 from jitendra-webkul/1.0

Rich snippet feature added for products and category
This commit is contained in:
Jitendra Singh 2020-05-18 23:08:33 +05:30 committed by GitHub
commit 84aede5cef
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 370 additions and 15 deletions

View File

@ -206,10 +206,68 @@ return [
'channel_based' => true,
],
],
], [
'key' => 'catalog.rich_snippets',
'name' => 'admin::app.admin.system.rich-snippets',
'sort' => 3,
], [
'key' => 'catalog.rich_snippets.products',
'name' => 'admin::app.admin.system.products',
'sort' => 1,
'fields' => [
[
'name' => 'enable',
'title' => 'admin::app.admin.system.enable',
'type' => 'boolean',
], [
'name' => 'show_sku',
'title' => 'admin::app.admin.system.show-sku',
'type' => 'boolean',
], [
'name' => 'show_weight',
'title' => 'admin::app.admin.system.show-weight',
'type' => 'boolean',
], [
'name' => 'show_categories',
'title' => 'admin::app.admin.system.show-categories',
'type' => 'boolean',
], [
'name' => 'show_images',
'title' => 'admin::app.admin.system.show-images',
'type' => 'boolean',
], [
'name' => 'show_reviews',
'title' => 'admin::app.admin.system.show-reviews',
'type' => 'boolean',
], [
'name' => 'show_ratings',
'title' => 'admin::app.admin.system.show-ratings',
'type' => 'boolean',
], [
'name' => 'show_offers',
'title' => 'admin::app.admin.system.show-offers',
'type' => 'boolean',
],
],
], [
'key' => 'catalog.rich_snippets.categories',
'name' => 'admin::app.admin.system.categories',
'sort' => 1,
'fields' => [
[
'name' => 'enable',
'title' => 'admin::app.admin.system.enable',
'type' => 'boolean',
], [
'name' => 'show_search_input_field',
'title' => 'admin::app.admin.system.show-search-input-field',
'type' => 'boolean',
]
]
], [
'key' => 'customer',
'name' => 'admin::app.admin.system.customer',
'sort' => 3,
'sort' => 4,
], [
'key' => 'customer.settings',
'name' => 'admin::app.admin.system.settings',
@ -252,7 +310,7 @@ return [
], [
'key' => 'emails',
'name' => 'admin::app.admin.emails.email',
'sort' => 1,
'sort' => 5,
], [
'key' => 'emails.general',
'name' => 'admin::app.admin.emails.notification_label',

View File

@ -1323,7 +1323,21 @@ return [
'cheapest-first' => 'Cheapest First',
'expensive-first' => 'Expensive First',
'comma-seperated' => 'Comma Seperated',
'favicon' => 'Favicon'
'favicon' => 'Favicon',
'seo' => 'SEO',
'rich-snippets' => 'Rich Snippets',
'products' => 'Products',
'enable' => 'Enable',
'show-weight' => 'Show Weight',
'show-categories' => 'Show Categories',
'show-images' => 'Show Images',
'show-reviews' => 'Show Reviews',
'show-ratings' => 'Show Ratings',
'show-offers' => 'Show Offers',
'show-sku' => 'Show SKU',
'categories' => 'Categories',
'show-sku' => 'Show SKU',
'show-search-input-field' => 'Show Search Input Field'
]
]
];

View File

@ -1331,7 +1331,21 @@ return [
'cheapest-first' => 'Cheapest First',
'expensive-first' => 'Expensive First',
'comma-seperated' => 'Comma Seperated',
'favicon' => 'Favicon'
'favicon' => 'Favicon',
'seo' => 'SEO',
'rich-snippets' => 'Rich Snippets',
'products' => 'Products',
'enable' => 'Enable',
'show-weight' => 'Show Weight',
'show-categories' => 'Show Categories',
'show-images' => 'Show Images',
'show-reviews' => 'Show Reviews',
'show-ratings' => 'Show Ratings',
'show-offers' => 'Show Offers',
'show-sku' => 'Show SKU',
'categories' => 'Categories',
'show-sku' => 'Show SKU',
'show-search-input-field' => 'Show Search Input Field'
]
]
];

View File

@ -1329,7 +1329,21 @@ return [
'cheapest-first' => 'Cheapest First',
'expensive-first' => 'Expensive First',
'comma-seperated' => 'Comma Seperated',
'favicon' => 'Favicon'
'favicon' => 'Favicon',
'seo' => 'SEO',
'rich-snippets' => 'Rich Snippets',
'products' => 'Products',
'enable' => 'Enable',
'show-weight' => 'Show Weight',
'show-categories' => 'Show Categories',
'show-images' => 'Show Images',
'show-reviews' => 'Show Reviews',
'show-ratings' => 'Show Ratings',
'show-offers' => 'Show Offers',
'show-sku' => 'Show SKU',
'categories' => 'Categories',
'show-sku' => 'Show SKU',
'show-search-input-field' => 'Show Search Input Field'
]
]
];

View File

@ -1333,8 +1333,21 @@ return [
'cheapest-first' => 'I più convenienti prima',
'expensive-first' => 'I più cari prima',
'comma-seperated' => 'Separato da virgola',
'favicon' => 'Favicon'
'favicon' => 'Favicon',
'seo' => 'SEO',
'rich-snippets' => 'Rich Snippets',
'products' => 'Products',
'enable' => 'Enable',
'show-weight' => 'Show Weight',
'show-categories' => 'Show Categories',
'show-images' => 'Show Images',
'show-reviews' => 'Show Reviews',
'show-ratings' => 'Show Ratings',
'show-offers' => 'Show Offers',
'show-sku' => 'Show SKU',
'categories' => 'Categories',
'show-sku' => 'Show SKU',
'show-search-input-field' => 'Show Search Input Field'
]
]
];

View File

@ -1328,7 +1328,21 @@ return [
'cheapest-first' => 'Cheapest First',
'expensive-first' => 'Expensive First',
'comma-seperated' => 'Comma Seperated',
'favicon' => 'Favicon'
'favicon' => 'Favicon',
'seo' => 'SEO',
'rich-snippets' => 'Rich Snippets',
'products' => 'Products',
'enable' => 'Enable',
'show-weight' => 'Show Weight',
'show-categories' => 'Show Categories',
'show-images' => 'Show Images',
'show-reviews' => 'Show Reviews',
'show-ratings' => 'Show Ratings',
'show-offers' => 'Show Offers',
'show-sku' => 'Show SKU',
'categories' => 'Categories',
'show-sku' => 'Show SKU',
'show-search-input-field' => 'Show Search Input Field'
]
]
];

View File

@ -1002,7 +1002,7 @@ return [
'specific-coupon' => 'Konkretny kupon',
'auto-generate-coupon' => 'Automatyczniegeneruj kupon',
'no' => 'Nie',
'yes' => 'Tak,
'yes' => 'Tak',
'coupon-code' => 'Kod kuponu',
'uses-per-coupon' => 'Wartość wykorzystania na kupon',
'uses-per-customer' => 'Wartość wykorzystania na klienta',
@ -1318,7 +1318,21 @@ return [
'all-customer-groups' => 'Wszystkie grupy klientów',
'invoice-slip-design' => 'Wzór wydruku faktury',
'logo' => 'Logo',
'favicon' => 'Favicon'
'favicon' => 'Favicon',
'seo' => 'SEO',
'rich-snippets' => 'Rich Snippets',
'products' => 'Products',
'enable' => 'Enable',
'show-weight' => 'Show Weight',
'show-categories' => 'Show Categories',
'show-images' => 'Show Images',
'show-reviews' => 'Show Reviews',
'show-ratings' => 'Show Ratings',
'show-offers' => 'Show Offers',
'show-sku' => 'Show SKU',
'categories' => 'Categories',
'show-sku' => 'Show SKU',
'show-search-input-field' => 'Show Search Input Field'
]
]
];

View File

@ -1332,7 +1332,21 @@ return [
'cheapest-first' => 'Cheapest First',
'expensive-first' => 'Expensive First',
'comma-seperated' => 'Comma Seperated',
'favicon' => 'Favicon'
'favicon' => 'Favicon',
'seo' => 'SEO',
'rich-snippets' => 'Rich Snippets',
'products' => 'Products',
'enable' => 'Enable',
'show-weight' => 'Show Weight',
'show-categories' => 'Show Categories',
'show-images' => 'Show Images',
'show-reviews' => 'Show Reviews',
'show-ratings' => 'Show Ratings',
'show-offers' => 'Show Offers',
'show-sku' => 'Show SKU',
'categories' => 'Categories',
'show-sku' => 'Show SKU',
'show-search-input-field' => 'Show Search Input Field'
]
]
];

View File

@ -103,7 +103,7 @@ class CategoryRepository extends Repository
{
static $categories = [];
if(array_key_exists($id, $categories)) {
if (array_key_exists($id, $categories)) {
return $categories[$id];
}

View File

@ -21,8 +21,9 @@ class ProductImage extends AbstractProduct
$images = [];
foreach ($product->images as $image) {
if (! Storage::has($image->path))
if (! Storage::has($image->path)) {
continue;
}
$images[] = [
'small_image_url' => url('cache/small/' . $image->path),

View File

@ -71,7 +71,7 @@ class Review extends AbstractProduct
return $totalRating[$product->id];
}
return $totalRating[$product->id] = $product->reviews()->where('status','approved')->sum('rating');
return $totalRating[$product->id] = $product->reviews()->where('status', 'approved')->sum('rating');
}
/**
@ -85,7 +85,7 @@ class Review extends AbstractProduct
$reviews = $product->reviews()->where('status', 'approved')
->select('rating', DB::raw('count(*) as total'))
->groupBy('rating')
->orderBy('rating','desc')
->orderBy('rating', 'desc')
->get();
$totalReviews = $this->getTotalReviews($product);

View File

@ -0,0 +1,185 @@
<?php
namespace Webkul\Product\Helpers;
use Illuminate\Support\Facades\Storage;
class SEO
{
/**
* Returns product json ld data for product
*
* @param \Webkul\Product\Contracts\Product|\Webkul\Product\Contracts\ProductFlat $product
* @return array
*/
public function getProductJsonLd($product)
{
$data = [
'@context' => 'https://schema.org/',
'@type' => 'Product',
'name' => $product->name,
'description' => $product->description,
'url' => route('shop.productOrCategory.index', $product->url_key),
];
if (core()->getConfigData('catalog.rich_snippets.products.show_sku')) {
$data['sku'] = $product->sku;
}
if (core()->getConfigData('catalog.rich_snippets.products.show_weight')) {
$data['image'] = $product->weight;
}
if (core()->getConfigData('catalog.rich_snippets.products.show_categories')) {
$data['categories'] = $this->getProductCategories($product);
}
if (core()->getConfigData('catalog.rich_snippets.products.show_images')) {
$data['image'] = $this->getProductImages($product);
}
if (core()->getConfigData('catalog.rich_snippets.products.show_reviews')) {
$data['review'] = $this->getProductReviews($product);
}
if (core()->getConfigData('catalog.rich_snippets.products.show_ratings')) {
$data['aggregateRating'] = $this->getProductAggregateRating($product);
}
if (core()->getConfigData('catalog.rich_snippets.products.show_offers')) {
$data['offers'] = $this->getProductOffers($product);
}
return json_encode($data);
}
/**
* Returns product categories
*
* @param \Webkul\Product\Contracts\Product|\Webkul\Product\Contracts\ProductFlat $product
* @return string
*/
public function getProductCategories($product)
{
if ($product instanceof \Webkul\Product\Models\ProductFlat) {
$categories = $product->product->categories;
} else {
$categories = $product->categories;
}
$names = [];
foreach ($categories as $key => $category) {
$names[] = $category->name;
}
return implode(', ', $names);
}
/**
* Returns product images
*
* @param \Webkul\Product\Contracts\Product|\Webkul\Product\Contracts\ProductFlat $product
* @return array
*/
public function getProductImages($product)
{
$images = [];
foreach ($product->images as $image) {
if (! Storage::has($image->path)) {
continue;
}
$images[] = $image->url;
}
return $images;
}
/**
* Returns product reviews
*
* @param \Webkul\Product\Contracts\Product|\Webkul\Product\Contracts\ProductFlat $product
* @return array
*/
public function getProductReviews($product)
{
$reviews = [];
foreach ($product->reviews()->where('status', 'approved')->get() as $review) {
$reviews[] = [
'@type' => 'Review',
'reviewRating' => [
'@type' => 'Rating',
'ratingValue' => $review->rating,
'bestRating' => '5',
],
'author' => [
'@type' => 'Person',
'name' => $review->name,
],
];
}
return $reviews;
}
/**
* Returns product average ratings
*
* @param \Webkul\Product\Contracts\Product|\Webkul\Product\Contracts\ProductFlat $product
* @return array
*/
public function getProductAggregateRating($product)
{
$reviewHelper = app('Webkul\Product\Helpers\Review');
return [
'@type' => 'AggregateRating',
'ratingValue' => $reviewHelper->getAverageRating($product),
'reviewCount' => $reviewHelper->getTotalReviews($product),
];
}
/**
* Returns product average ratings
*
* @param \Webkul\Product\Contracts\Product|\Webkul\Product\Contracts\ProductFlat $product
* @return array
*/
public function getProductOffers($product)
{
return [
'@type' => 'Offer',
'priceCurrency' => core()->getCurrentCurrencyCode(),
'price' => $product->getTypeInstance()->getMinimalPrice(),
'availability' => 'https://schema.org/InStock',
];
}
/**
* Returns product json ld data for category
*
* @param \Webkul\Category\Contracts\Category $category
* @return array
*/
public function getCategoryJsonLd($category)
{
$data = [
'@type' => 'WebSite',
'@context' => 'http://schema.org',
'url' => config('app.url'),
];
if (core()->getConfigData('catalog.rich_snippets.categories.show_search_input_field')) {
$data['potentialAction'] = [
'@type' => 'SearchAction',
'target' => config('app.url') . '/search/?term={search_term_string}',
'query-input' => 'required name=search_term_string',
];
}
return json_encode($data);
}
}

View File

@ -6,7 +6,14 @@
@section('seo')
<meta name="description" content="{{ trim($category->meta_description) != "" ? $category->meta_description : \Illuminate\Support\Str::limit(strip_tags($category->description), 120, '') }}"/>
<meta name="keywords" content="{{ $category->meta_keywords }}"/>
@if (core()->getConfigData('catalog.rich_snippets.categories.enable'))
<script type="application/ld+json">
{!! app('Webkul\Product\Helpers\SEO')->getCategoryJsonLd($category) !!}
</script>
@endif
@stop
@section('content-wrapper')

View File

@ -6,7 +6,14 @@
@section('seo')
<meta name="description" content="{{ trim($product->meta_description) != "" ? $product->meta_description : \Illuminate\Support\Str::limit(strip_tags($product->description), 120, '') }}"/>
<meta name="keywords" content="{{ $product->meta_keywords }}"/>
@if (core()->getConfigData('catalog.rich_snippets.products.enable'))
<script type="application/ld+json">
{!! app('Webkul\Product\Helpers\SEO')->getProductJsonLd($product) !!}
</script>
@endif
@stop
@section('content-wrapper')