<?php
function curl_fetch($url) {
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_USERAGENT => "Mozilla/5.0 (Windows NT 10.0; Win64; x64)",
CURLOPT_TIMEOUT => 10,
]);
return false;
}
if ($statusCode !== 200) {
echo "Failed to fetch: $url (HTTP $statusCode)\n";
return false;
}
return $html;
}
function find_first_product_url($homepageHtml, $baseUrl) {
$dom = new DOMDocument();
@$dom->loadHTML($homepageHtml);
$xpath = new DOMXPath($dom);
$links = $xpath->query("//a[contains(@href, '/products/')]");
foreach ($links as $link) {
$href = $link->getAttribute("href");
if (strpos($href, '/products/') !== false) { // Normalize URL
if (strpos($href, 'http') !== 0) { $href = rtrim($baseUrl, '/') . '/' . ltrim($href, '/'); }
return $href;
}
}
return null;
}
function extract_clean_review_text($html) {
$dom = new DOMDocument();
@$dom->loadHTML($html);
$xpath = new DOMXPath($dom);
$reviews = [];
// Known Shopify review selectors
$selectors = [
"//*[contains(@class, 'loox-review-content')]",
"//*[contains(@class, 'jdgm-rev__body')]",
"//*[contains(@class, 'yotpo-review-content')]",
"//*[contains(@class, 'spr-review-content')]",
"//*[contains(@class, 'review')]",
"//*[contains(@class, 'customer-review')]"
];
foreach ($selectors as $selector) {
$nodes = $xpath->query($selector);
foreach ($nodes as $node) {
$text = trim($node->textContent); $reviews[] = $text;
}
}
break;
}
}
return $reviews;
}
// ---------------- MAIN SCRIPT ----------------
$shopifyStore = "https://w...content-available-to-author-only...o.uk";
echo "Fetching homepage: $shopifyStore\n";
$homeHtml = curl_fetch($shopifyStore);
$productUrl = find_first_product_url($homeHtml, $shopifyStore);
if (!$productUrl) {
die("No product URLs found on the homepage.\n"); }
echo "Found product URL: $productUrl\n";
$productHtml = curl_fetch($productUrl);
$reviews = extract_clean_review_text($productHtml);
echo "No reviews found on the product page.\n";
} else {
echo "Found " . count($reviews) . " reviews:\n\n"; foreach ($reviews as $i => $review) {
echo ($i + 1) . ". " . $review . "\n\n";
}
}
PD9waHAKCmZ1bmN0aW9uIGN1cmxfZmV0Y2goJHVybCkgewogICAgJGNoID0gY3VybF9pbml0KCR1cmwpOwogICAgY3VybF9zZXRvcHRfYXJyYXkoJGNoLCBbCiAgICAgICAgQ1VSTE9QVF9SRVRVUk5UUkFOU0ZFUiA9PiB0cnVlLAogICAgICAgIENVUkxPUFRfRk9MTE9XTE9DQVRJT04gPT4gdHJ1ZSwKICAgICAgICBDVVJMT1BUX1NTTF9WRVJJRllQRUVSID0+IGZhbHNlLAogICAgICAgIENVUkxPUFRfVVNFUkFHRU5UID0+ICJNb3ppbGxhLzUuMCAoV2luZG93cyBOVCAxMC4wOyBXaW42NDsgeDY0KSIsCiAgICAgICAgQ1VSTE9QVF9USU1FT1VUID0+IDEwLAogICAgXSk7CgogICAgJGh0bWwgPSBjdXJsX2V4ZWMoJGNoKTsKCiAgICBpZiAoY3VybF9lcnJubygkY2gpKSB7CiAgICAgICAgZWNobyAiY1VSTCBlcnJvcjogIiAuIGN1cmxfZXJyb3IoJGNoKSAuICJcbiI7CiAgICAgICAgY3VybF9jbG9zZSgkY2gpOwogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgICAkc3RhdHVzQ29kZSA9IGN1cmxfZ2V0aW5mbygkY2gsIENVUkxJTkZPX0hUVFBfQ09ERSk7CiAgICBjdXJsX2Nsb3NlKCRjaCk7CgogICAgaWYgKCRzdGF0dXNDb2RlICE9PSAyMDApIHsKICAgICAgICBlY2hvICJGYWlsZWQgdG8gZmV0Y2g6ICR1cmwgKEhUVFAgJHN0YXR1c0NvZGUpXG4iOwogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgICByZXR1cm4gJGh0bWw7Cn0KCmZ1bmN0aW9uIGZpbmRfZmlyc3RfcHJvZHVjdF91cmwoJGhvbWVwYWdlSHRtbCwgJGJhc2VVcmwpIHsKICAgICRkb20gPSBuZXcgRE9NRG9jdW1lbnQoKTsKICAgIEAkZG9tLT5sb2FkSFRNTCgkaG9tZXBhZ2VIdG1sKTsKICAgICR4cGF0aCA9IG5ldyBET01YUGF0aCgkZG9tKTsKCiAgICAkbGlua3MgPSAkeHBhdGgtPnF1ZXJ5KCIvL2FbY29udGFpbnMoQGhyZWYsICcvcHJvZHVjdHMvJyldIik7CiAgICBmb3JlYWNoICgkbGlua3MgYXMgJGxpbmspIHsKICAgICAgICAkaHJlZiA9ICRsaW5rLT5nZXRBdHRyaWJ1dGUoImhyZWYiKTsKICAgICAgICBpZiAoc3RycG9zKCRocmVmLCAnL3Byb2R1Y3RzLycpICE9PSBmYWxzZSkgewogICAgICAgICAgICAvLyBOb3JtYWxpemUgVVJMCiAgICAgICAgICAgIGlmIChzdHJwb3MoJGhyZWYsICdodHRwJykgIT09IDApIHsKICAgICAgICAgICAgICAgICRocmVmID0gcnRyaW0oJGJhc2VVcmwsICcvJykgLiAnLycgLiBsdHJpbSgkaHJlZiwgJy8nKTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gJGhyZWY7CiAgICAgICAgfQogICAgfQoKICAgIHJldHVybiBudWxsOwp9CgpmdW5jdGlvbiBleHRyYWN0X2NsZWFuX3Jldmlld190ZXh0KCRodG1sKSB7CiAgICAkZG9tID0gbmV3IERPTURvY3VtZW50KCk7CiAgICBsaWJ4bWxfdXNlX2ludGVybmFsX2Vycm9ycyh0cnVlKTsKICAgIEAkZG9tLT5sb2FkSFRNTCgkaHRtbCk7CiAgICBsaWJ4bWxfY2xlYXJfZXJyb3JzKCk7CgogICAgJHhwYXRoID0gbmV3IERPTVhQYXRoKCRkb20pOwogICAgJHJldmlld3MgPSBbXTsKCiAgICAvLyBLbm93biBTaG9waWZ5IHJldmlldyBzZWxlY3RvcnMKICAgICRzZWxlY3RvcnMgPSBbCiAgICAgICAgIi8vKltjb250YWlucyhAY2xhc3MsICdsb294LXJldmlldy1jb250ZW50JyldIiwKICAgICAgICAiLy8qW2NvbnRhaW5zKEBjbGFzcywgJ2pkZ20tcmV2X19ib2R5JyldIiwKICAgICAgICAiLy8qW2NvbnRhaW5zKEBjbGFzcywgJ3lvdHBvLXJldmlldy1jb250ZW50JyldIiwKICAgICAgICAiLy8qW2NvbnRhaW5zKEBjbGFzcywgJ3Nwci1yZXZpZXctY29udGVudCcpXSIsCiAgICAgICAgIi8vKltjb250YWlucyhAY2xhc3MsICdyZXZpZXcnKV0iLAogICAgICAgICIvLypbY29udGFpbnMoQGNsYXNzLCAnY3VzdG9tZXItcmV2aWV3JyldIgogICAgXTsKCiAgICBmb3JlYWNoICgkc2VsZWN0b3JzIGFzICRzZWxlY3RvcikgewogICAgICAgICRub2RlcyA9ICR4cGF0aC0+cXVlcnkoJHNlbGVjdG9yKTsKICAgICAgICBmb3JlYWNoICgkbm9kZXMgYXMgJG5vZGUpIHsKICAgICAgICAgICAgJHRleHQgPSB0cmltKCRub2RlLT50ZXh0Q29udGVudCk7CiAgICAgICAgICAgIGlmICghZW1wdHkoJHRleHQpKSB7CiAgICAgICAgICAgICAgICAkcmV2aWV3c1tdID0gJHRleHQ7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmICghZW1wdHkoJHJldmlld3MpKSB7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgIH0KCiAgICByZXR1cm4gJHJldmlld3M7Cn0KCi8vIC0tLS0tLS0tLS0tLS0tLS0gTUFJTiBTQ1JJUFQgLS0tLS0tLS0tLS0tLS0tLQokc2hvcGlmeVN0b3JlID0gImh0dHBzOi8vdy4uLmNvbnRlbnQtYXZhaWxhYmxlLXRvLWF1dGhvci1vbmx5Li4uby51ayI7CgplY2hvICJGZXRjaGluZyBob21lcGFnZTogJHNob3BpZnlTdG9yZVxuIjsKJGhvbWVIdG1sID0gY3VybF9mZXRjaCgkc2hvcGlmeVN0b3JlKTsKaWYgKCEkaG9tZUh0bWwpIGV4aXQ7CgokcHJvZHVjdFVybCA9IGZpbmRfZmlyc3RfcHJvZHVjdF91cmwoJGhvbWVIdG1sLCAkc2hvcGlmeVN0b3JlKTsKaWYgKCEkcHJvZHVjdFVybCkgewogICAgZGllKCJObyBwcm9kdWN0IFVSTHMgZm91bmQgb24gdGhlIGhvbWVwYWdlLlxuIik7Cn0KCmVjaG8gIkZvdW5kIHByb2R1Y3QgVVJMOiAkcHJvZHVjdFVybFxuIjsKJHByb2R1Y3RIdG1sID0gY3VybF9mZXRjaCgkcHJvZHVjdFVybCk7CmlmICghJHByb2R1Y3RIdG1sKSBleGl0OwoKJHJldmlld3MgPSBleHRyYWN0X2NsZWFuX3Jldmlld190ZXh0KCRwcm9kdWN0SHRtbCk7CgppZiAoZW1wdHkoJHJldmlld3MpKSB7CiAgICBlY2hvICJObyByZXZpZXdzIGZvdW5kIG9uIHRoZSBwcm9kdWN0IHBhZ2UuXG4iOwp9IGVsc2UgewogICAgZWNobyAiRm91bmQgIiAuIGNvdW50KCRyZXZpZXdzKSAuICIgcmV2aWV3czpcblxuIjsKICAgIGZvcmVhY2ggKCRyZXZpZXdzIGFzICRpID0+ICRyZXZpZXcpIHsKICAgICAgICBlY2hvICgkaSArIDEpIC4gIi4gIiAuICRyZXZpZXcgLiAiXG5cbiI7CiAgICB9Cn0K