PluginProbe
ThinkRank AI SEO – AI SEO Plugin for WordPress: Schema, XML Sitemaps, Meta Tags, Search Console & Local SEO / 2.14.2
ThinkRank AI SEO – AI SEO Plugin for WordPress: Schema, XML Sitemaps, Meta Tags, Search Console & Local SEO v2.14.2
2.14.2 2.14.1 2.14.0 2.13.0 2.12.0 2.11.0 2.10.0 2.9.0 2.8.0 2.7.0 2.6.0 2.5.0 2.4.0 2.3.0 2.2.0 2.1.1 2.1.0 2.0.2 2.0.1 2.0.0 1.32.0 1.31.0 1.30.0 1.29.0 1.28.0 All 57 releases
← All changes | includes/seo/class-site-identity-manager.php +39 -11 2.14.1 → 2.14.2 View file →
@@ -1636,9 +1636,9 @@
1636 1636 $optimization['suggestions'][] = 'Add a site logo for better branding and professional appearance';
1637 1637 $optimization['score'] -= 20;
1638 1638 } else {
1639 1639 // Validate logo URL and dimensions
1640 - if (!filter_var($logo_url, FILTER_VALIDATE_URL)) {
1640 + if (!\ThinkRank\Core\Url_Validator::is_http_url($logo_url)) {
1641 1641 $optimization['warnings'][] = 'Logo URL format is invalid';
1642 1642 $optimization['score'] -= 15;
1643 1643 }
1644 1644 }
@@ -1657,9 +1657,9 @@
1657 1657 $optimization['score'] -= 10;
1658 1658 }
1659 1659
1660 1660 // Additional logo analysis for local images
1661 - if (!empty($logo_url) && filter_var($logo_url, FILTER_VALIDATE_URL)) {
1661 + if (!empty($logo_url) && \ThinkRank\Core\Url_Validator::is_http_url($logo_url)) {
1662 1662 $attachment_id = Attachment_Lookup::id_from_url($logo_url);
1663 1663 if ($attachment_id) {
1664 1664 $image_meta = wp_get_attachment_metadata($attachment_id);
1665 1665 // The configured file's own size — a logo picked at a generated
@@ -2145,12 +2145,37 @@
2145 2145 $validation['suggestions'][] = 'Consider making site description longer (120-160 characters)';
2146 2146 }
2147 2147 }
2148 2148
2149 - // Validate logo URL
2150 - if (isset($settings['logo_url']) && !empty($settings['logo_url'])) {
2151 - if (!filter_var($settings['logo_url'], FILTER_VALIDATE_URL)) {
2152 - $validation['errors'][] = 'Logo URL must be a valid URL';
2149 + // Image and link URLs. These are written into src and href
2150 + // attributes (the schema logo, the admin previews, the hero section),
2151 + // so only web URLs are accepted. is_valid() takes any scheme, and
2152 + // "javascript://%0Aalert(1)" passed it and was stored as
2153 + // "javascript://alert(1)" once sanitize_text_field() dropped the %0A.
2154 + // The logo and default social image must be absolute: they are
2155 + // published in schema and Open Graph, which require it. The others
2156 + // may also be a path on this site.
2157 + $url_fields = [
2158 + 'logo_url' => ['Logo URL', false],
2159 + 'default_social_image' => ['Default social image URL', false],
2160 + 'favicon_url' => ['Favicon URL', true],
2161 + 'apple_touch_icon_url' => ['Apple touch icon URL', true],
2162 + 'hero_background_image' => ['Hero background image URL', true],
2163 + 'hero_cta_url' => ['Call-to-action URL', true],
2164 + ];
2165 + foreach ($url_fields as $key => [$label, $allow_path]) {
2166 + if (!isset($settings[$key]) || '' === $settings[$key] || null === $settings[$key]) {
2167 + continue;
2168 + }
2169 +
2170 + $ok = $allow_path
2171 + ? \ThinkRank\Core\Url_Validator::is_http_url_or_path($settings[$key])
2172 + : \ThinkRank\Core\Url_Validator::is_http_url($settings[$key]);
2173 +
2174 + if (!$ok) {
2175 + $validation['errors'][] = $allow_path
2176 + ? sprintf('%s must be an http or https URL, or a path starting with /', $label)
2177 + : sprintf('%s must be an http or https URL', $label);
2153 2178 $validation['valid'] = false;
2154 2179 }
2155 2180 }
2156 2181
@@ -2588,9 +2613,9 @@
2588 2613 }
2589 2614
2590 2615 // CTA URL validation
2591 2616 if (!empty($settings['hero_cta_url'])) {
2592 - if (filter_var($settings['hero_cta_url'], FILTER_VALIDATE_URL) || strpos($settings['hero_cta_url'], '/') === 0) {
2617 + if (\ThinkRank\Core\Url_Validator::is_http_url_or_path($settings['hero_cta_url'])) {
2593 2618 $field_details[] = [
2594 2619 'field' => 'hero_cta_url',
2595 2620 'label' => 'Call-to-action URL is properly configured.',
2596 2621 'status' => 'valid',
@@ -2631,9 +2656,9 @@
2631 2656 }
2632 2657
2633 2658 // Site Logo validation (from Site Assets section)
2634 2659 if (!empty($settings['logo_url'])) {
2635 - if (filter_var($settings['logo_url'], FILTER_VALIDATE_URL)) {
2660 + if (\ThinkRank\Core\Url_Validator::is_http_url($settings['logo_url'])) {
2636 2661 $field_details[] = [
2637 2662 'field' => 'logo_url',
2638 2663 'label' => 'Site logo is properly configured.',
2639 2664 'status' => 'valid',
@@ -4102,9 +4127,12 @@
4102 4127 $validation['warnings'][] = "Path '{$value}' should start with '/'";
4103 4128 }
4104 4129 break;
4105 4130 case 'sitemap':
4106 - if (!filter_var($value, FILTER_VALIDATE_URL)) {
4131 + // Url_Validator, not the raw PHP filter: on a site with an
4132 + // internationalised domain the site's own sitemap URL is
4133 + // non-ASCII and the raw filter refused it.
4134 + if (!\ThinkRank\Core\Url_Validator::is_valid($value)) {
4107 4135 $validation['errors'][] = "Invalid sitemap URL: {$value}";
4108 4136 $validation['valid'] = false;
4109 4137 }
4110 4138 break;
@@ -4503,10 +4531,10 @@
4503 4531 return $optimization;
4504 4532 }
4505 4533
4506 4534 // Validate URL
4507 - if (!filter_var($value, FILTER_VALIDATE_URL)) {
4508 - $optimization['validation']['errors'][] = "{$element} must be a valid URL";
4535 + if (!\ThinkRank\Core\Url_Validator::is_http_url($value)) {
4536 + $optimization['validation']['errors'][] = "{$element} must be an http or https URL";
4509 4537 $optimization['validation']['valid'] = false;
4510 4538 return $optimization;
4511 4539 }
4512 4540