Merge pull request 'Adding Feature Request for single product highlight' (#7) from feature-single-product into main
All checks were successful
Create Release / build (push) Successful in 3s

Reviewed-on: #7
This commit is contained in:
jknapp 2025-05-18 17:27:06 +00:00
commit 554e2ba93e
3 changed files with 134 additions and 5 deletions

View File

@ -1,12 +1,29 @@
# fourth-wall-embed-wp # fourth-wall-embed-wp
A WordPress Plugin to embed a fourth wall embed. A WordPress Plugin to embed a Fourthwall store or individual products.
### How to use the plugin ### How to use the plugin
* Download the latest release from [releases](https://repo.anhonesthost.net/CyberCoveLLC/fourth-wall-embed-wp/releases) * Download the latest release from [releases](https://repo.anhonesthost.net/CyberCoveLLC/fourth-wall-embed-wp/releases)
* Upload the Plugin to WordPress * Upload the Plugin to WordPress
* In the WordPress Dashboard, Navigate to the Fourthwall settings page, and paste your store url. * In the WordPress Dashboard, Navigate to the Fourthwall settings page, and paste your store URL.
* On the page you want have your store displayed, add the shortcode ```[fourthwall]```
This is an early release of the plugin, and if you can think of things that could be improved or find any bugs, please open an issue on the repository. #### Display your entire store
To display your entire Fourthwall store on a page, use the shortcode:
```[fourthwall]```
#### Display a single product
To display an individual product from your Fourthwall store, use the shortcode with the product URL:
```[fourthwall_single url="https://your-store.fourthwall.com/products/product-name"]```
You can also display the product description by setting the `show_description` attribute to "true":
```[fourthwall_single url="https://your-store.fourthwall.com/products/product-name" show_description="true"]```
### Requirements
* WordPress 6.0 or higher
* PHP 7.4 or higher
* Active Fourthwall store
This plugin allows you to integrate your Fourthwall store directly into your WordPress site, either showing your complete product collection or featuring specific products individually.
If you can think of things that could be improved or find any bugs, please open an issue on the repository.

View File

@ -1,7 +1,7 @@
<?php <?php
/** /**
* Plugin Name: Fourthwall Store Embed * Plugin Name: Fourthwall Store Embed
* Plugin URL: https://cybercove.io/ * Plugin URL: https://darksideofperfection.com/
* Description: Embed Fourthwall Store in WordPress * Description: Embed Fourthwall Store in WordPress
* Version: {auto_update_value_on_deploy} * Version: {auto_update_value_on_deploy}
* Author: Joshua Knapp * Author: Joshua Knapp

View File

@ -99,4 +99,116 @@ function fwembed_shortcode( $atts ) {
$store_render = '<div class="fw-store-parent">' . PHP_EOL . $store_html . PHP_EOL . '</div>'; $store_render = '<div class="fw-store-parent">' . PHP_EOL . $store_html . PHP_EOL . '</div>';
return $store_render; return $store_render;
} }
function fwembed_parse_html_single($url = null, $show_description = false) {
if ($url === null) {
throw new ValueError("Missing URL");
}
$ch = curl_init();
// More complete browser-like headers
$headers = [
'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
'Accept-Language: en-US,en;q=0.5',
'Connection: keep-alive',
'Upgrade-Insecure-Requests: 1',
'Cache-Control: max-age=0'
];
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_ENCODING, "");
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/115.0');
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // Only if necessary for testing
curl_setopt($ch, CURLOPT_COOKIEJAR, '/tmp/cookies.txt'); // Store cookies
curl_setopt($ch, CURLOPT_COOKIEFILE, '/tmp/cookies.txt'); // Use cookies
$html_content = curl_exec($ch);
if (curl_errno($ch)) {
$error = curl_error($ch);
curl_close($ch);
return "Error fetching URL: " . $error;
}
$status_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if ($status_code == 403) {
curl_close($ch);
return "Access forbidden (403). The website may be blocking automated requests.";
}
curl_close($ch);
$html = null;
libxml_use_internal_errors(true);
$dom = new DOMDocument();
@$dom->loadHTML(loadHTML5($html_content), LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
$dom->documentURI = $url;
$xpath = new DOMXPath($dom);
// Extract product information
$productTitle = $xpath->query('//h1[@class="product-info__title"]');
$productPrice = $xpath->query('//span[@class="product-info__price product-info__price--original"]');
$productImage = $xpath->query('//div[@data-gallery="gallery-slide"][1]//img[@class="gallery__image-object"]');
$productDesc = $xpath->query('//div[@class="product-info__description"]//div[@class="html-formatter"]');
if ($productTitle->length > 0 && $productImage->length > 0) {
$title = $productTitle->item(0)->textContent;
$price = $productPrice->length > 0 ? $productPrice->item(0)->textContent : '';
// Get image attributes
$imageNode = $productImage->item(0);
$imageSrc = $imageNode->getAttribute('src');
$imageAlt = $imageNode->getAttribute('alt');
// Build the HTML
$html = '<div class="product-tile">';
$html .= '<a class="product-link" target="_blank" href="' . $url . '">';
$html .= '<img class="tile__item tile__item--1" src="' . $imageSrc . '" alt="' . htmlspecialchars($imageAlt) . '">';
$html .= '<div class="tile__description">';
$html .= '<h3 class="tile__heading">' . htmlspecialchars(trim($title)) . '</h3>';
$html .= '<div class="tile__prices">';
$html .= '<span class="tile__price tile__price--original">' . trim($price) . '</span>';
$html .= '</div>';
$html .= '</div>';
$html .= '</a>';
// Add description if show_description is true
if ($show_description && $productDesc->length > 0) {
$description = $dom->saveHTML($productDesc->item(0));
$html .= '<div class="product-description">' . $description . '</div>';
}
$html .= '</div>';
}
libxml_clear_errors();
return $html;
}
function fwembed_single_shortcode($atts) {
$atts = shortcode_atts(
array(
'url' => '',
'show_description' => 'false',
),
$atts
);
if (empty($atts['url'])) {
return '<p>Error: URL is required for [fourthwall_single] shortcode</p>';
}
// Convert string 'true'/'false' to boolean
$show_description = filter_var($atts['show_description'], FILTER_VALIDATE_BOOLEAN);
$product_html = fwembed_parse_html_single($atts['url'], $show_description);
return '<div class="fw-single-product">' . PHP_EOL . $product_html . PHP_EOL . '</div>';
}
add_shortcode('fourthwall_single', 'fwembed_single_shortcode');
add_shortcode( 'fourthwall', 'fwembed_shortcode' ); add_shortcode( 'fourthwall', 'fwembed_shortcode' );