| @@ -62,8 +62,38 @@ | ||
| 62 | 62 | return $value; |
| 63 | 63 | } |
| 64 | 64 | |
| 65 | 65 | /** |
| 66 | + * Undo escape_cell() on a value read back from a CSV. | |
| 67 | + * | |
| 68 | + * The inverse of the guard above, so an export -> import round trip returns | |
| 69 | + * the value the donor actually wrote. Without it a comment that began with | |
| 70 | + * a formula character comes back one apostrophe longer every trip, and that | |
| 71 | + * text is published on the campaign page. | |
| 72 | + * | |
| 73 | + * Only strips a leading apostrophe when the character after it is one this | |
| 74 | + * class would have escaped — so a value the donor genuinely began with an | |
| 75 | + * apostrophe ("'til next year") is left alone. | |
| 76 | + * | |
| 77 | + * @param string $value Raw cell value from the CSV. | |
| 78 | + * @return string Value without the injected guard. | |
| 79 | + * @since 1.6.0 | |
| 80 | + */ | |
| 81 | + public static function unescape_cell( $value ) { | |
| 82 | + if ( ! is_string( $value ) || 2 > strlen( $value ) || "'" !== $value[0] ) { | |
| 83 | + return is_string( $value ) ? $value : ''; | |
| 84 | + } | |
| 85 | + | |
| 86 | + $stripped = ltrim( substr( $value, 1 ) ); | |
| 87 | + | |
| 88 | + if ( '' !== $stripped && in_array( $stripped[0], self::FORMULA_PREFIXES, true ) ) { | |
| 89 | + return substr( $value, 1 ); | |
| 90 | + } | |
| 91 | + | |
| 92 | + return $value; | |
| 93 | + } | |
| 94 | + | |
| 95 | + /** | |
| 66 | 96 | * Build a CSV string from an array of rows. |
| 67 | 97 | * |
| 68 | 98 | * Every cell is passed through escape_cell() so callers cannot forget the |
| 69 | 99 | * injection guard. The first row is typically the header labels (escaping |