| 1 |
<?php |
| 2 |
|
| 3 |
namespace YayMail\SocialIcons; |
| 4 |
|
| 5 |
/** |
| 6 |
* On-disk render cache for tinted social icon PNGs. |
| 7 |
* |
| 8 |
* Keyed by a caller-supplied hash (icon+color+size+mask-mtime), so a given |
| 9 |
* combination is generated by GD at most once per server; every later |
| 10 |
* request for the same combination is served straight off disk. |
| 11 |
*/ |
| 12 |
class SocialIconImageCache { |
| 13 |
|
| 14 |
private const DIR_NAME = 'yaymail-social-icons'; |
| 15 |
|
| 16 |
/** |
| 17 |
* Resolve (and lazily create) the on-disk cache path for a cache key. |
| 18 |
* Returns null when the uploads dir is unavailable/unwritable, in which |
| 19 |
* case the caller just falls back to generating on every request. |
| 20 |
* |
| 21 |
* @param string $cache_key Hash of icon+color+size+mask-mtime. |
| 22 |
*/ |
| 23 |
public static function get_path( $cache_key ) { |
| 24 |
$upload_dir = wp_upload_dir(); |
| 25 |
if ( ! empty( $upload_dir['error'] ) ) { |
| 26 |
return null; |
| 27 |
} |
| 28 |
|
| 29 |
$dir = trailingslashit( $upload_dir['basedir'] ) . self::DIR_NAME . '/'; |
| 30 |
if ( ! wp_mkdir_p( $dir ) ) { |
| 31 |
return null; |
| 32 |
} |
| 33 |
|
| 34 |
return $dir . $cache_key . '.png'; |
| 35 |
} |
| 36 |
|
| 37 |
/** |
| 38 |
* Write PNG bytes to the cache atomically (temp file + rename) so a |
| 39 |
* concurrent request never reads a half-written file. |
| 40 |
* |
| 41 |
* @param string $cache_path Destination path from get_path(). |
| 42 |
* @param string $png_data Raw PNG bytes. |
| 43 |
*/ |
| 44 |
public static function write( $cache_path, $png_data ) { |
| 45 |
$tmp_path = $cache_path . '.' . uniqid( '', true ) . '.tmp'; |
| 46 |
if ( false === file_put_contents( $tmp_path, $png_data ) ) { // phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_put_contents |
| 47 |
return; |
| 48 |
} |
| 49 |
|
| 50 |
if ( ! rename( $tmp_path, $cache_path ) ) { |
| 51 |
wp_delete_file( $tmp_path ); |
| 52 |
} |
| 53 |
} |
| 54 |
} |
| 55 |
|