How to retreave New Arrivals in another view?
Forum rules
Always add your Laravel, Aimeos and PHP version as well as your environment (Linux/Mac/Win)
Spam and unrelated posts will be removed immediately!
Always add your Laravel, Aimeos and PHP version as well as your environment (Linux/Mac/Win)
Spam and unrelated posts will be removed immediately!
How to retreave New Arrivals in another view?
PHP: 8.1.2-1ubuntu2.14
Laravel Framework: 10.43.0
System: Ubuntu Gnu Linux 22.04
We installed another theme and trying to customize it to work with the platform. My task is to get the New Arrivals list in main page (PHP file) and show in a view specified by the theme.
How should I approach this problem correctly?
1. Do I have to know where is the logic lies of this "query" or the place where this logic is going? If Yes, where is the logic of the New Arrivals are placed (if exist)?
2. Or there is another more simple approach to do it using an abstract layer, created by Aimeos for such type tasks?
3. Or I have to use a mixed way using a custom manager or a controller, for example?
Laravel Framework: 10.43.0
System: Ubuntu Gnu Linux 22.04
We installed another theme and trying to customize it to work with the platform. My task is to get the New Arrivals list in main page (PHP file) and show in a view specified by the theme.
How should I approach this problem correctly?
1. Do I have to know where is the logic lies of this "query" or the place where this logic is going? If Yes, where is the logic of the New Arrivals are placed (if exist)?
2. Or there is another more simple approach to do it using an abstract layer, created by Aimeos for such type tasks?
3. Or I have to use a mixed way using a custom manager or a controller, for example?
Re: How to retreave New Arrivals in another view?
There's currently not specialized component to display the latest products but you can use the catalog/list component and pass f_sort=-ctime as Parameter.
If the list should be manageable via the CMS module, you need to implement a block in JS for GrapesJS like here:
- https://github.com/aimeos/ai-cms-grapes ... #L347-L356
- https://github.com/aimeos/ai-cms-grapes ... #L570-L663
If the list should be manageable via the CMS module, you need to implement a block in JS for GrapesJS like here:
- https://github.com/aimeos/ai-cms-grapes ... #L347-L356
- https://github.com/aimeos/ai-cms-grapes ... #L570-L663
Professional support and custom implementation are available at Aimeos.com
If you like Aimeos, give us a star
If you like Aimeos, give us a star
Re: How to retreave New Arrivals in another view?
Thank you for response.
No, I don't need a manageable list via CMS module. My goal is very simple right now. I just need to get a product list by a "controller" or from context to make a filter on it (for example by date). And this list will be something, that we can call a "New Arrivals".
But while You answer, I created a new controller (in app/Http/Controllers/MainPageController.php) for main page, which is actually a back end, that uses another class (in app/Http/Controllers/Frontend/NewArrivalsCustom.php) where the search is going on. And a Service (in app/Services/ProductService.php) which calls a product Item's methods to get some data. And I get some basic data, like label for instance. But I don't get media data now, like images. And I think this data I have to get from additional tables, 'mshop_media' or something like that.
I'm not sure this is good way to get products data in the main page. But I'm working on it.
This is the Controller code snippet:
This is the helper class:
This is a ProductService class code snippet:
I'm not an expert in Front-end and I try do it by standard Laravel way (as I think). If you have any advice, I'll be very grateful.
No, I don't need a manageable list via CMS module. My goal is very simple right now. I just need to get a product list by a "controller" or from context to make a filter on it (for example by date). And this list will be something, that we can call a "New Arrivals".
But while You answer, I created a new controller (in app/Http/Controllers/MainPageController.php) for main page, which is actually a back end, that uses another class (in app/Http/Controllers/Frontend/NewArrivalsCustom.php) where the search is going on. And a Service (in app/Services/ProductService.php) which calls a product Item's methods to get some data. And I get some basic data, like label for instance. But I don't get media data now, like images. And I think this data I have to get from additional tables, 'mshop_media' or something like that.
I'm not sure this is good way to get products data in the main page. But I'm working on it.
This is the Controller code snippet:
Code: Select all
class MainPageController extends Controller
{
protected ProductService $productService;
public function __construct(ProductService $productService)
{
$this->productService = $productService;
}
public function showMainPage()
{
$context = app('aimeos.context')->get(false);
$newArrivalsController = new NewArrivalsCustom($context);
$newArrivals = $newArrivalsController->getNewArrivals();
foreach($newArrivals as $product) {
$product->label = $this->productService->getLabel($product);
// other data
}
// Passing variables to the view
return view('myext::catalog.home', [
'newArrivals' => $newArrivals,
// other variables
]);
}
}
Code: Select all
class NewArrivalsCustom extends Standard
{
public function __construct(\Aimeos\MShop\ContextIface $context)
{
parent::__construct($context);
$this->context = $context;
}
public function getNewArrivals(): \Aimeos\Map
{
$indexManager = \Aimeos\MShop::create($this->context, 'index');
$search = $indexManager->filter();
// Set the conditions for "new" products
// $search->setConditions($search->compare('>=', 'product.ctime', date('Y-m-d H:i:s', strtotime('-30 days'))));
$search->setConditions($search->compare('>', 'product.id', 0));
$search->setSortations([$search->sort('-', 'product.ctime')]);
$search->slice(0, 10);
return $indexManager->search($search);
}
}
Code: Select all
class ProductService
{
protected $context;
public function __construct(\Aimeos\MShop\ContextIface $context)
{
$this->context = $context;
}
public function getLabel($productItem)
{
return $productItem->getLabel();
}
public function getName($productItem)
{
return $productItem->getName();
}
}
Re: How to retreave New Arrivals in another view?
All your code should go into the MainPageController.php to make it simple.
You can get related items to products like images, prices and texts by using:
You can get related items to products like images, prices and texts by using:
Code: Select all
$indexManager = \Aimeos\MShop::create($this->context, 'index');
$search = $indexManager->filter( true )
->add('product.ctime', '>=', date('Y-m-d H:i:s', time() - 86400 * 30))
->order('-product.ctime')
->slice(0, 10);
return $indexManager->search($search, ['media', 'price', 'text']);
Professional support and custom implementation are available at Aimeos.com
If you like Aimeos, give us a star
If you like Aimeos, give us a star
Re: How to retreave New Arrivals in another view?
I solved my issue and I want to share how I did it.
The main problem was that the main page has been written in PHP (I mean it is not blade file) and has a complex slider. But the part of code where I iterate the newArrivals was included into blade file. And I couldn't make these two files work together. Because to make my blade file see the data I created my own controller. And that controller was called from my custom Route in the /routes/web.php. I spent a lot of time in trying merge them together. So. This is the part of slider file where "this" is the Aimeos\Base\View\Standard class:
I solved this problem by creating Laravel View Composer. I created app/Http/ViewComposers/NewArrivalsComposer.php file, where I get the newArrivals:
Where app/Services/NewArrivalsFilter.php is:
And app/Services/ProductService.php is:
Then I register the View Composer in boot() method of the package Service Provider:
And our blade file packages/our-package/views/catalog/parts/content.blade.php shows the newArrivals:
Maybe I created extra files. But architecturally it looks normal.
The main problem was that the main page has been written in PHP (I mean it is not blade file) and has a complex slider. But the part of code where I iterate the newArrivals was included into blade file. And I couldn't make these two files work together. Because to make my blade file see the data I created my own controller. And that controller was called from my custom Route in the /routes/web.php. I spent a lot of time in trying merge them together. So. This is the part of slider file where "this" is the Aimeos\Base\View\Standard class:
Code: Select all
<?php if( isset( $this->homeTree ) && !(
$this->homeTree->getRefItems( 'media', 'stage', 'default' )->isEmpty()
&& $this->homeTree->getChildren()->getRefItems( 'media', 'stage', 'default' )->collapse( 1 )->isEmpty()
) ) : ?>
...
Code: Select all
use Aimeos\MShop\Exception;
use App\Services\NewArrivalsFilter;
use App\Services\ProductService;
use Illuminate\View\View;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
class NewArrivalsComposer
{
public function __construct(private readonly ProductService $productService) { }
public function compose(View $view): void
{
$context = app('aimeos.context')->get(false);
$newArrivalsController = new NewArrivalsFilter($context);
$newArrivals = $newArrivalsController->getNewArrivals();
foreach($newArrivals as $product) {
$product->label = $this->productService->getLabel($product);
$product->price = $this->productService->getPrice($product);
}
$view->with('newArrivals', $newArrivals);
}
}
Code: Select all
use Aimeos\Controller\Frontend\Catalog\Standard;
use Aimeos\MShop;
use Aimeos\MShop\ContextIface;
use Aimeos\MShop\Exception;
class NewArrivalsFilter extends Standard
{
public function __construct(private readonly ContextIface $context)
{
parent::__construct($context);
}
public function getNewArrivals(): \Aimeos\Map
{
$indexManager = MShop::create($this->context, 'index');
$search = $indexManager->filter();
// Sort descending by the creation time.
$search->setSortations([$search->sort('-','product.ctime' )]);
// Show only the first 10 new arrivals from the last search result.
$search->slice(0, 10);
$productIds = $indexManager->search($search)->keys()->toArray();
$productManager = MShop::create($this->context, 'product');
$products = $productManager->search($productManager->filter(true), ['media', 'price', 'text']);
return $products->filter(function ($item) use ($productIds) {
return in_array($item->getId(), $productIds);
});
}
}
Code: Select all
class ProductService
{
public function getLabel(mixed $productItem)
{
return $productItem->getLabel();
}
public function getName(mixed $productItem)
{
return $productItem->getName();
}
public function getPrice(mixed $productItem): ?string
{
$price = $productItem->getRefItems('price', 'default', 'default')->first();
if ($price) {
return sprintf('%s %s', $price->getValue(), $price->getCurrencyId());
}
return null;
}
}
Code: Select all
View::composer(
'our-package::catalog.parts.content',
NewArrivalsComposer::class
);
Code: Select all
<div class="tab-content jump">
<div class="tab-pane active" id="home1">
<div class="custom-row">
@foreach ($newArrivals as $product)
<div class="custom-col-5 mb-30">
<div class="devita-product-2 mrg-inherit devita-product-red">
<div class="product-img">
<div class="product-img-slider">
@php
$mediaItem = $product->getRefItems('media', 'default', 'default')->first();
@endphp
@if ($mediaItem)
<a href="#">
<img src="{{ asset($mediaItem->getPreview()) }}" alt="{{ $mediaItem->getProperties('title')->first() }}">
<span>{{ $product->price }}</span>
</a>
@else
...
@endif
</div>
@if($product->getLabel())
<span>{{ $product->label }}</span>
@endif
</div>
</div>
</div>
@endforeach
</div>
</div>