Hi guys,
I’m trying to create a base View Composer like described in this post, but somehow it’s not working for me. This is my base view composer:
namespace App\View\Composers;
use Roots\Acorn\View\Composer;
class ProductCardBase extends Composer {
protected static $dataMethods = [
'title',
'description',
'image',
'product_link'
];
public function with() {
$id = $this->data['product'];
$product = wc_get_product($id);
// Uncommenting this block does work?
// return [
// 'title' => $this->title($id, $product),
// 'description' => $this->description($id, $product),
// 'image' => $this->image($id, $product),
// 'page_link' => $this->page_link($id, $product),
// 'product_link' => $this->product_link($id, $product)
// ];
return array_map(function($method) use ($id, $product) {
if (method_exists($this, $method)) {
return [$method => $this->{$method}($id, $product)];
}
return [$method => false];
}, $this::$dataMethods);
}
/**
* Returns the product title.
*
* @return string
*/
public function title($id, $product) {
return $product->get_name();
}
/**
* Returns the product short description.
*
* @return string
*/
public function description($id, $product) {
return $product->get_short_description();
}
/**
* Returns the product image.
*
* @return string
*/
public function image($id, $product) {
return $product->get_image('medium');
}
/**
* Returns the product url.
*
* @return string
*/
public function product_link($id, $product) {
return $product->get_permalink();
}
}
I extend it in a ProductBlock composer:
namespace App\View\Composers;
class ProductBlock extends ProductCardBase {
/**
* List of views served by this composer.
*
* @var array
*/
protected static $views = [
'blocks.product-block'
];
}
In a loop, I include the partial and pass the product id:
@foreach ($products as $product)
<div class="swiper-slide">
@include('blocks.product-block', [
'product' => $product
])
</div>
@endforeach
And my blocks.product-block partial:
@isset($product)
<article class="b-product">
<header class="b-product__header">
<h3 class="b-product__title">{!! $title !!}</h3>
<div class="b-product__desc">{!! $description !!}</div>
</header>
@if ($image)
<figure class="b-product__image">{!! $image !!}</figure>
@endif
<footer class="b-product__footer">
@if ($product_link)
<a class="btn btn-outline-primary" href="{{ $product_link }}" role="button">{!! __('Configure', 'mydomain') !!}</a>
@endif
</footer>
</article>
@endisset
Strangely, if I just return the commented array with the function calls directly, it does work?
I thought it had to do with how the class functions are called by string name:
$this->{$method}($id, $product)
so instead I tried:
call_user_func([$this, $method], $id, $product);
with same result, not data available in my view?
What am I missing here? Is this array_map
technique not possible anymore with the latest Composer?
Thanks!