diff --git a/README.md b/README.md index eacfd48..599d8a0 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,29 @@ # 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 * Download the latest release from [releases](https://repo.anhonesthost.net/CyberCoveLLC/fourth-wall-embed-wp/releases) * Upload the Plugin to WordPress -* 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]``` +* In the WordPress Dashboard, Navigate to the Fourthwall settings page, and paste your store URL. -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. \ No newline at end of file +#### 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. \ No newline at end of file diff --git a/fw-store-embed.php b/fw-store-embed.php index 599fbc2..d6dbf6b 100644 --- a/fw-store-embed.php +++ b/fw-store-embed.php @@ -1,7 +1,7 @@ ' . PHP_EOL . $store_html . PHP_EOL . ''; 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 = '
'; + $html .= ''; + $html .= '' . htmlspecialchars($imageAlt) . ''; + + $html .= '
'; + $html .= '

' . htmlspecialchars(trim($title)) . '

'; + $html .= '
'; + $html .= '' . trim($price) . ''; + $html .= '
'; + $html .= '
'; + $html .= '
'; + + // Add description if show_description is true + if ($show_description && $productDesc->length > 0) { + $description = $dom->saveHTML($productDesc->item(0)); + $html .= '
' . $description . '
'; + } + + $html .= '
'; + } + + libxml_clear_errors(); + return $html; +} + +function fwembed_single_shortcode($atts) { + $atts = shortcode_atts( + array( + 'url' => '', + 'show_description' => 'false', + ), + $atts + ); + + if (empty($atts['url'])) { + return '

Error: URL is required for [fourthwall_single] shortcode

'; + } + + // 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 '
' . PHP_EOL . $product_html . PHP_EOL . '
'; +} +add_shortcode('fourthwall_single', 'fwembed_single_shortcode'); add_shortcode( 'fourthwall', 'fwembed_shortcode' );