← All changes
|
includes/admin/importers/class-snapshot-store.php
+43
-1
1.28.0
→
2.14.0
View file →
| @@ -32,8 +32,50 @@ | ||
| 32 | 32 | */ |
| 33 | 33 | private const OPTION_PREFIX = 'thinkrank_snapshot_'; |
| 34 | 34 | |
| 35 | 35 | /** |
| 36 | + * Width of `wp_options.option_name`, VARCHAR(191) since WordPress 4.4 cut it | |
| 37 | + * to fit a utf8mb4 index. | |
| 38 | + * | |
| 39 | + * @var int | |
| 40 | + */ | |
| 41 | + private const OPTION_NAME_MAX = 191; | |
| 42 | + | |
| 43 | + /** | |
| 44 | + * Digits held back for the chunk page number in a key. Ten is far past what | |
| 45 | + * any real snapshot pages to; it costs ten characters of type slug. | |
| 46 | + * | |
| 47 | + * @var int | |
| 48 | + */ | |
| 49 | + private const PAGE_DIGITS = 10; | |
| 50 | + | |
| 51 | + /** | |
| 52 | + * Longest type slug whose chunk key still fits `option_name`. | |
| 53 | + * | |
| 54 | + * MySQL's default (non-strict) mode truncates an over-long option name on | |
| 55 | + * write instead of refusing it, and the truncated row is then invisible to | |
| 56 | + * the read, which looks the full key up. In-request option caching hides | |
| 57 | + * that until the next request, when read_chunk() starts returning null for | |
| 58 | + * records the manifest still counts — a snapshot that advertises data it | |
| 59 | + * cannot produce. Callers taking a type slug from an uploaded file must | |
| 60 | + * check it against this before storing anything under it. | |
| 61 | + * | |
| 62 | + * @since 2.12.0 | |
| 63 | + * | |
| 64 | + * @param string $plugin Plugin slug the chunks are filed under. | |
| 65 | + * @return int Maximum type slug length, in characters. | |
| 66 | + */ | |
| 67 | + public static function max_type_length(string $plugin): int { | |
| 68 | + // The key is OPTION_PREFIX . "{$plugin}_{$type}_chunk_{$page}". | |
| 69 | + $overhead = strlen(self::OPTION_PREFIX) | |
| 70 | + + strlen($plugin) | |
| 71 | + + strlen('__chunk_') | |
| 72 | + + self::PAGE_DIGITS; | |
| 73 | + | |
| 74 | + return max(1, self::OPTION_NAME_MAX - $overhead); | |
| 75 | + } | |
| 76 | + | |
| 77 | + /** | |
| 36 | 78 | * Write a chunk of snapshot data |
| 37 | 79 | * |
| 38 | 80 | * @param string $plugin Plugin slug (e.g., 'yoast') |
| 39 | 81 | * @param string $type Data type (e.g., 'postmeta') |
| @@ -105,9 +147,9 @@ | ||
| 105 | 147 | // Extract plugin slug from option name: thinkrank_snapshot_{plugin}_manifest |
| 106 | 148 | $option_name = $row['option_name']; |
| 107 | 149 | $plugin = str_replace([self::OPTION_PREFIX, '_manifest'], '', $option_name); |
| 108 | 150 | |
| 109 | - $manifest = maybe_unserialize($row['option_value']); | |
| 151 | + $manifest = Safe_Unserializer::unserialize($row['option_value']); | |
| 110 | 152 | if (is_array($manifest)) { |
| 111 | 153 | $snapshots[$plugin] = $manifest; |
| 112 | 154 | } |
| 113 | 155 | } |