| @@ -121,8 +121,57 @@ | ||
| 121 | 121 | return []; |
| 122 | 122 | } |
| 123 | 123 | |
| 124 | 124 | /** |
| 125 | + * Product for blocks that support a query_type attribute — same | |
| 126 | + * resolution ProductInfoBlockEditor::render() uses: 'custom' + | |
| 127 | + * product_id renders the picked product, anything else falls back | |
| 128 | + * to the current product context (single product page, Product | |
| 129 | + * Info wrapper, shop loops). | |
| 130 | + * | |
| 131 | + * @return object|null Product model, or null when nothing resolves | |
| 132 | + */ | |
| 133 | + /** | |
| 134 | + * The block's wrapper around what it rendered — or nothing at all when | |
| 135 | + * it rendered nothing. A review block on a product with reviews turned | |
| 136 | + * off would otherwise leave an empty div with the block's classes | |
| 137 | + * behind, which is a stray gap on the page and a false hook for styles. | |
| 138 | + * | |
| 139 | + * @param string $wrapperAttributes get_block_wrapper_attributes() output | |
| 140 | + * @param string $inner | |
| 141 | + * @return string | |
| 142 | + */ | |
| 143 | + protected static function wrapUnlessEmpty(string $wrapperAttributes, string $inner): string | |
| 144 | + { | |
| 145 | + if (trim($inner) === '') { | |
| 146 | + return ''; | |
| 147 | + } | |
| 148 | + | |
| 149 | + return '<div ' . $wrapperAttributes . '>' . $inner . '</div>'; | |
| 150 | + } | |
| 151 | + | |
| 152 | + protected function resolveProduct(array $attributes) | |
| 153 | + { | |
| 154 | + if (Arr::get($attributes, 'query_type', 'default') === 'custom') { | |
| 155 | + $productId = absint(Arr::get($attributes, 'product_id', 0)); | |
| 156 | + | |
| 157 | + if (!$productId) { | |
| 158 | + return null; | |
| 159 | + } | |
| 160 | + | |
| 161 | + // Published only, so a hand-edited product_id cannot surface a | |
| 162 | + // draft/private product on a public page. No eager loading — | |
| 163 | + // callers only read the ID; a caller that needs relations loads | |
| 164 | + // them itself. | |
| 165 | + return \FluentCart\App\Models\Product::query() | |
| 166 | + ->where('post_status', 'publish') | |
| 167 | + ->find($productId); | |
| 168 | + } | |
| 169 | + | |
| 170 | + return fluent_cart_get_current_product(); | |
| 171 | + } | |
| 172 | + | |
| 173 | + /** | |
| 125 | 174 | * Register just the block type (render callback, attributes, supports) |
| 126 | 175 | * without editor scripts/styles. Used for email-only blocks that handle |
| 127 | 176 | * asset enqueuing through the email editor handler instead of globally. |
| 128 | 177 | */ |