From 28d44d6884b2b80aad6e457b7a003fe15f4b7e2d Mon Sep 17 00:00:00 2001 From: Jonathan Miller Date: Sun, 21 Jun 2026 15:40:01 -0500 Subject: [PATCH] fix: undefined $db in findImage(), pass cached product to buildProduct() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add missing Factory::getDbo() in findImage() category fallback — would cause fatal error on article pages with no images (found in PR review) - Pass cached product to JsonLdBuilder::buildProduct() to avoid duplicate DB query (same pattern as buildArticle with cachedArticle) - Fix orphaned PHPDoc block for getImageDimensions() --- .../src/Extension/MokoOG.php | 19 ++++++------ .../src/Helper/JsonLdBuilder.php | 31 +++++++++++-------- 2 files changed, 27 insertions(+), 23 deletions(-) diff --git a/source/packages/plg_system_mokoog/src/Extension/MokoOG.php b/source/packages/plg_system_mokoog/src/Extension/MokoOG.php index 5418449..312d96a 100644 --- a/source/packages/plg_system_mokoog/src/Extension/MokoOG.php +++ b/source/packages/plg_system_mokoog/src/Extension/MokoOG.php @@ -218,7 +218,7 @@ final class MokoOG extends CMSPlugin implements SubscriberInterface $imageUrl = $image ? $this->resolveImageUrl($image) : ''; if ($option === 'com_mokoshop' && $view === 'product' && $id > 0) { - $schema = JsonLdBuilder::buildProduct($id, $title, $description, $imageUrl); + $schema = JsonLdBuilder::buildProduct($id, $title, $description, $imageUrl, $this->loadShopProduct($id)); } elseif ($option === 'com_content' && $view === 'article' && $id > 0) { $schema = JsonLdBuilder::buildArticle($id, $title, $description, $imageUrl, $this->loadArticle($id)); } else { @@ -464,6 +464,7 @@ final class MokoOG extends CMSPlugin implements SubscriberInterface // Fallback: check the article's category for an image if ($view === 'article') { + $db = Factory::getDbo(); $catQuery = $db->getQuery(true) ->select($db->quoteName('cat.params')) ->from($db->quoteName('#__categories', 'cat')) @@ -622,15 +623,6 @@ final class MokoOG extends CMSPlugin implements SubscriberInterface } } - /** - * Get the actual pixel dimensions of a local image. - * - * Returns [width, height] or null for external URLs or unreadable images. - * - * @param string $image Image path (relative or absolute URL) - * - * @return array{0: int, 1: int}|null - */ /** * Load MokoSuiteShop product data by product ID. * @@ -661,6 +653,13 @@ final class MokoOG extends CMSPlugin implements SubscriberInterface return $cache[$productId]; } + /** + * Get the actual pixel dimensions of a local image. + * + * @param string $image Image path (relative or absolute URL) + * + * @return array{0: int, 1: int}|null + */ private function getImageDimensions(string $image): ?array { // Cannot determine dimensions for external URLs diff --git a/source/packages/plg_system_mokoog/src/Helper/JsonLdBuilder.php b/source/packages/plg_system_mokoog/src/Helper/JsonLdBuilder.php index 9c92d85..9f7f975 100644 --- a/source/packages/plg_system_mokoog/src/Helper/JsonLdBuilder.php +++ b/source/packages/plg_system_mokoog/src/Helper/JsonLdBuilder.php @@ -162,28 +162,33 @@ class JsonLdBuilder /** * Build Product schema for a MokoSuiteShop product. * - * @param int $productId CRM product ID - * @param string $title Product title - * @param string $description Product description - * @param string $image Image URL (absolute) + * @param int $productId CRM product ID + * @param string $title Product title + * @param string $description Product description + * @param string $image Image URL (absolute) + * @param object|null $cachedProduct Pre-loaded product data (avoids duplicate query) * * @return array|null */ - public static function buildProduct(int $productId, string $title, string $description, string $image): ?array + public static function buildProduct(int $productId, string $title, string $description, string $image, ?object $cachedProduct = null): ?array { if ($productId <= 0) { return null; } - $db = Factory::getDbo(); - $query = $db->getQuery(true) - ->select('p.sku, p.price, p.currency, p.stock_qty') - ->from($db->quoteName('#__mokosuite_crm_products', 'p')) - ->where($db->quoteName('p.id') . ' = ' . $productId) - ->where($db->quoteName('p.published') . ' = 1'); + $product = $cachedProduct; - $db->setQuery($query); - $product = $db->loadObject(); + if (!$product) { + $db = Factory::getDbo(); + $query = $db->getQuery(true) + ->select('p.sku, p.price, p.currency, p.stock_qty') + ->from($db->quoteName('#__mokosuite_crm_products', 'p')) + ->where($db->quoteName('p.id') . ' = ' . $productId) + ->where($db->quoteName('p.published') . ' = 1'); + + $db->setQuery($query); + $product = $db->loadObject(); + } if (!$product) { return null;