PluginProbe
ActivityPub / 8.0.0
ActivityPub v8.0.0
9.3.1 9.3.0 9.2.2 9.2.1 9.2.0 9.1.0 9.0.2 9.0.1 9.0.0 8.3.0 8.2.1 8.2.0 8.1.1 1.0.5 1.0.6 1.0.7 1.0.8 1.0.9 1.1.0 1.2.0 1.3.0 2.0.0 2.0.1 2.1.0 2.1.1 All 160 releases
activitypub / includes / cli / class-cache-command.php

class-cache-command.php in ActivityPub 8.0.0, at includes/cli/class-cache-command.php

275 lines 6.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Cache CLI Command.
4 *
5 * @package Activitypub
6 */
7
8 namespace Activitypub\Cli;
9
10 use Activitypub\Cache\Avatar;
11 use Activitypub\Cache\Emoji;
12 use Activitypub\Cache\File;
13 use Activitypub\Cache\Media;
14
15 /**
16 * Manage ActivityPub remote media cache.
17 *
18 * @package Activitypub
19 */
20 class Cache_Command extends \WP_CLI_Command {
21
22 /**
23 * Clear the remote media cache.
24 *
25 * Removes cached files from the uploads directory. By default clears all
26 * cache types, or specify --type to clear only a specific cache.
27 *
28 * ## OPTIONS
29 *
30 * [--type=<type>]
31 * : The cache type to clear. If omitted, clears all caches.
32 * ---
33 * options:
34 * - avatar
35 * - media
36 * - emoji
37 * - all
38 * default: all
39 * ---
40 *
41 * [--yes]
42 * : Skip confirmation prompt.
43 *
44 * ## EXAMPLES
45 *
46 * # Clear all caches
47 * $ wp activitypub cache clear
48 *
49 * # Clear only avatar cache
50 * $ wp activitypub cache clear --type=avatar
51 *
52 * # Clear emoji cache without confirmation
53 * $ wp activitypub cache clear --type=emoji --yes
54 *
55 * @subcommand clear
56 *
57 * @param array $args The positional arguments.
58 * @param array $assoc_args The associative arguments.
59 */
60 public function clear( $args, $assoc_args ) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable
61 $type = $assoc_args['type'] ?? 'all';
62
63 $types_to_clear = array();
64 if ( 'all' === $type ) {
65 $types_to_clear = array( 'avatar', 'media', 'emoji' );
66 } else {
67 $types_to_clear = array( $type );
68 }
69
70 $type_label = 'all' === $type ? 'all cache types' : "{$type} cache";
71 \WP_CLI::confirm( "Are you sure you want to clear {$type_label}?", $assoc_args );
72
73 $total_cleared = 0;
74
75 foreach ( $types_to_clear as $cache_type ) {
76 $cleared = $this->clear_cache_type( $cache_type );
77 $total_cleared += $cleared;
78 \WP_CLI::log( \sprintf( 'Cleared %d %s cache directories.', $cleared, $cache_type ) );
79 }
80
81 \WP_CLI::success( \sprintf( 'Cache cleared. Total directories removed: %d', $total_cleared ) );
82 }
83
84 /**
85 * Show cache status and statistics.
86 *
87 * Displays information about cached files including count and total size
88 * for each cache type.
89 *
90 * ## OPTIONS
91 *
92 * [--format=<format>]
93 * : Output format.
94 * ---
95 * default: table
96 * options:
97 * - table
98 * - json
99 * - csv
100 * - yaml
101 * ---
102 *
103 * ## EXAMPLES
104 *
105 * # Show cache status
106 * $ wp activitypub cache status
107 *
108 * # Show status as JSON
109 * $ wp activitypub cache status --format=json
110 *
111 * @subcommand status
112 *
113 * @param array $args The positional arguments.
114 * @param array $assoc_args The associative arguments.
115 */
116 public function status( $args, $assoc_args ) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable
117 $upload_dir = \wp_upload_dir();
118
119 $cache_types = array(
120 'avatar' => array(
121 'label' => 'Avatars',
122 'path' => Avatar::get_base_dir(),
123 ),
124 'media' => array(
125 'label' => 'Post Media',
126 'path' => Media::get_base_dir(),
127 ),
128 'emoji' => array(
129 'label' => 'Emoji',
130 'path' => Emoji::get_base_dir(),
131 ),
132 );
133
134 $data = array();
135 $total_files = 0;
136 $total_size = 0;
137
138 foreach ( $cache_types as $type => $info ) {
139 $dir = $upload_dir['basedir'] . $info['path'];
140 $stats = $this->get_directory_stats( $dir );
141
142 $data[] = array(
143 'type' => $info['label'],
144 'enabled' => $this->is_cache_enabled( $type ) ? 'Yes' : 'No',
145 'files' => $stats['files'],
146 'size' => \size_format( $stats['size'] ),
147 'path' => $info['path'],
148 );
149
150 $total_files += $stats['files'];
151 $total_size += $stats['size'];
152 }
153
154 // Add totals row for table format.
155 if ( 'table' === ( $assoc_args['format'] ?? 'table' ) ) {
156 $data[] = array(
157 'type' => '---',
158 'enabled' => '---',
159 'files' => '---',
160 'size' => '---',
161 'path' => '---',
162 );
163 $data[] = array(
164 'type' => 'TOTAL',
165 'enabled' => '',
166 'files' => $total_files,
167 'size' => \size_format( $total_size ),
168 'path' => '/activitypub/',
169 );
170 }
171
172 $format = $assoc_args['format'] ?? 'table';
173 \WP_CLI\Utils\format_items( $format, $data, array( 'type', 'enabled', 'files', 'size', 'path' ) );
174 }
175
176 /**
177 * Clear a specific cache type.
178 *
179 * @param string $type The cache type (avatar, media, emoji).
180 *
181 * @return int Number of directories cleared.
182 */
183 private function clear_cache_type( $type ) {
184 $upload_dir = \wp_upload_dir();
185
186 switch ( $type ) {
187 case 'avatar':
188 $base_dir = $upload_dir['basedir'] . Avatar::get_base_dir();
189 break;
190 case 'media':
191 $base_dir = $upload_dir['basedir'] . Media::get_base_dir();
192 break;
193 case 'emoji':
194 $base_dir = $upload_dir['basedir'] . Emoji::get_base_dir();
195 break;
196 default:
197 return 0;
198 }
199
200 if ( ! \is_dir( $base_dir ) ) {
201 return 0;
202 }
203
204 // Count subdirectories before clearing.
205 $subdirs = \glob( $base_dir . '/*', GLOB_ONLYDIR );
206 $count = $subdirs ? \count( $subdirs ) : 0;
207
208 // Remove all subdirectories using the cache's native delete_directory helper.
209 foreach ( $subdirs as $subdir ) {
210 File::delete_directory( $subdir );
211 }
212
213 // Also clear avatar URL meta for avatar cache.
214 if ( 'avatar' === $type ) {
215 \delete_metadata( 'post', 0, '_activitypub_avatar_url', '', true );
216 }
217
218 return $count;
219 }
220
221 /**
222 * Get statistics for a cache directory.
223 *
224 * @param string $dir The directory path.
225 *
226 * @return array {
227 * Directory statistics.
228 *
229 * @type int $files Total number of files.
230 * @type int $size Total size in bytes.
231 * }
232 */
233 private function get_directory_stats( $dir ) {
234 $stats = array(
235 'files' => 0,
236 'size' => 0,
237 );
238
239 if ( ! \is_dir( $dir ) ) {
240 return $stats;
241 }
242
243 $iterator = new \RecursiveIteratorIterator(
244 new \RecursiveDirectoryIterator( $dir, \RecursiveDirectoryIterator::SKIP_DOTS ),
245 \RecursiveIteratorIterator::LEAVES_ONLY
246 );
247
248 foreach ( $iterator as $file ) {
249 if ( $file->isFile() ) {
250 ++$stats['files'];
251 $stats['size'] += $file->getSize();
252 }
253 }
254
255 return $stats;
256 }
257
258 /**
259 * Check if a cache type is enabled.
260 *
261 * @param string $type The cache type.
262 *
263 * @return bool True if enabled.
264 */
265 private function is_cache_enabled( $type ) {
266 // Check global cache enablement (includes constant and activitypub_remote_cache_enabled filter).
267 if ( ! \Activitypub\Cache::is_enabled() ) {
268 return false;
269 }
270
271 // Check type-specific filter.
272 return (bool) \apply_filters( "activitypub_cache_{$type}_enabled", true );
273 }
274 }
275