PluginProbe
ThinkRank AI SEO – AI SEO Plugin for WordPress: Schema, XML Sitemaps, Meta Tags, Search Console & Local SEO / 2.9.0
ThinkRank AI SEO – AI SEO Plugin for WordPress: Schema, XML Sitemaps, Meta Tags, Search Console & Local SEO v2.9.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 1.27.0 1.26.0 1.25.0 trunk 1.0.0 1.0.1 All 51 releases
← All changes | includes/admin/importers/class-import-detector.php +73 -0 2.1.0 → 2.9.0 View file →
@@ -30,8 +30,13 @@
30 30 */
31 31 private const CACHE_KEY = 'thinkrank_import_detection';
32 32
33 33 /**
34 + * Transient key for caching the native (ThinkRank's own data) counts
35 + */
36 + private const NATIVE_CACHE_KEY = 'thinkrank_export_detection';
37 +
38 + /**
34 39 * Cache TTL in seconds (1 hour)
35 40 */
36 41 private const CACHE_TTL = 3600;
37 42
@@ -63,8 +68,16 @@
63 68 'meta_prefix' => '',
64 69 'option_keys' => ['aioseo_options'],
65 70 'plugin_files' => ['all-in-one-seo-pack/all_in_one_seo_pack.php', 'all-in-one-seo-pack-pro/all_in_one_seo_pack.php'],
66 71 ],
72 + 'squirrly' => [
73 + 'name' => 'Squirrly SEO',
74 + // Squirrly keeps SEO in its own `qss` table, not postmeta (#740);
75 + // `_sq_` only covers its few fallback meta keys.
76 + 'meta_prefix' => '_sq_',
77 + 'option_keys' => ['sq_options'],
78 + 'plugin_files' => ['squirrly-seo/squirrly.php'],
79 + ],
67 80 ];
68 81
69 82 /**
70 83 * Detect all source plugins present in the database
@@ -94,8 +107,44 @@
94 107 return $detected;
95 108 }
96 109
97 110 /**
111 + * Detect ThinkRank's own exportable data.
112 + *
113 + * Deliberately NOT part of the PLUGINS registry that detect() walks. That
114 + * registry describes plugins to migrate FROM: every entry is gated on
115 + * is_source_active() (which would reject us), feeds the "import from" cards
116 + * in the UI, and — most importantly — drives cleanup()'s prefix maps, which
117 + * delete the listed plugin's live data. Keeping the native source on its
118 + * own path avoids all three problems instead of special-casing each.
119 + *
120 + * @param bool $use_cache Whether to use cached results
121 + * @return array|null Detection result, or null when there is nothing to export
122 + */
123 + public function detect_native(bool $use_cache = true): ?array {
124 + if ($use_cache) {
125 + $cached = get_transient(self::NATIVE_CACHE_KEY);
126 + if ($cached !== false) {
127 + return is_array($cached) ? $cached : null;
128 + }
129 + }
130 +
131 + $exporter = new Thinkrank_Exporter();
132 + $counts = $exporter->get_available_types();
133 +
134 + $result = [
135 + 'plugin' => $exporter->get_plugin_slug(),
136 + 'plugin_name' => $exporter->get_plugin_name(),
137 + 'counts' => $counts,
138 + 'total' => array_sum($counts),
139 + ];
140 +
141 + set_transient(self::NATIVE_CACHE_KEY, $result, self::CACHE_TTL);
142 +
143 + return $result;
144 + }
145 +
146 + /**
98 147 * Clear the detection cache
99 148 *
100 149 * @return void
101 150 */
@@ -100,8 +149,9 @@
100 149 * @return void
101 150 */
102 151 public function clear_cache(): void {
103 152 delete_transient(self::CACHE_KEY);
153 + delete_transient(self::NATIVE_CACHE_KEY);
104 154 }
105 155
106 156 /**
107 157 * Detect a single plugin's data presence
@@ -126,8 +176,11 @@
126 176
127 177 if ($slug === 'aioseo') {
128 178 // AIOSEO uses a custom table
129 179 $counts = $this->detect_aioseo();
180 + } elseif ($slug === 'squirrly') {
181 + // Squirrly uses a custom table too; the exporter classifies rows.
182 + $counts = $this->detect_squirrly();
130 183 } else {
131 184 // Standard postmeta-based plugins
132 185 $prefix = $config['meta_prefix'];
133 186
@@ -261,8 +314,28 @@
261 314 if ($redirects > 0) {
262 315 $counts['redirections'] = $redirects;
263 316 }
264 317 }
318 + // Squirrly's Advanced Pack redirects are counted by the exporter in
319 + // detect_squirrly(), since only its `url` actions are redirects.
320 +
321 + return $counts;
322 + }
323 +
324 + /**
325 + * Detect Squirrly SEO data (custom `qss` table + Advanced Pack redirects).
326 + *
327 + * Delegated to the exporter: the table mixes posts, terms, author
328 + * profiles and the homepage, and only the exporter knows how to tell
329 + * them apart from the serialized `post` column.
330 + *
331 + * @return array Counts array
332 + */
333 + private function detect_squirrly(): array {
334 + $exporter = new Squirrly_Exporter();
335 + $counts = $exporter->get_available_types();
336 + // Settings are added by the caller from option_keys.
337 + unset($counts['settings']);
265 338
266 339 return $counts;
267 340 }
268 341