@@ -43,6 +43,100 @@ add_filter('c3_invalidation_items', function($items, $post) {
4343}, 10, 2);
4444```
4545
46+ ### ` c3_invalidation_post_batch_home_path `
47+
48+ Customize the home path when invalidating a single post.
49+
50+ ** Hook Type:** Filter
51+ ** Since:** 7.2.0
52+ ** Parameters:**
53+ - ` $home_path ` (string): The home URL/path to be invalidated
54+ - ` $post ` (WP_Post|null): The post object that triggered the invalidation
55+
56+ ** Return:** ` string ` - Modified home path
57+
58+ ** Examples:**
59+
60+ ``` php
61+ // Use different home path for specific post types
62+ add_filter('c3_invalidation_post_batch_home_path', function($home_path, $post) {
63+ if ($post && $post->post_type === 'product') {
64+ return '/shop/'; // Invalidate shop page instead of home
65+ }
66+ return $home_path;
67+ }, 10, 2);
68+
69+ // Skip home invalidation for draft posts
70+ add_filter('c3_invalidation_post_batch_home_path', function($home_path, $post) {
71+ if ($post && $post->post_status === 'draft') {
72+ return null; // Skip home invalidation
73+ }
74+ return $home_path;
75+ }, 10, 2);
76+ ```
77+
78+ ### ` c3_invalidation_posts_batch_home_path `
79+
80+ Customize the home path when invalidating multiple posts.
81+
82+ ** Hook Type:** Filter
83+ ** Since:** 7.2.0
84+ ** Parameters:**
85+ - ` $home_path ` (string): The home URL/path to be invalidated
86+ - ` $posts ` (array): Array of WP_Post objects being invalidated
87+
88+ ** Return:** ` string ` - Modified home path
89+
90+ ** Examples:**
91+
92+ ``` php
93+ // Use different home path for bulk operations
94+ add_filter('c3_invalidation_posts_batch_home_path', function($home_path, $posts) {
95+ if (count($posts) > 5) {
96+ return '/'; // Use root path for large bulk operations
97+ }
98+ return $home_path;
99+ }, 10, 2);
100+
101+ // Custom path based on post types in batch
102+ add_filter('c3_invalidation_posts_batch_home_path', function($home_path, $posts) {
103+ $post_types = array_unique(array_column($posts, 'post_type'));
104+ if (in_array('product', $post_types)) {
105+ return '/shop/';
106+ }
107+ return $home_path;
108+ }, 10, 2);
109+ ```
110+
111+ ### ` c3_invalidation_manual_batch_all_path `
112+
113+ Customize the path for manual "clear all cache" operations.
114+
115+ ** Hook Type:** Filter
116+ ** Since:** 7.2.0
117+ ** Parameters:**
118+ - ` $all_path ` (string): The path pattern for clearing all cache (default: '/* ')
119+
120+ ** Return:** ` string ` - Modified path pattern
121+
122+ ** Examples:**
123+
124+ ``` php
125+ // Use more specific path for manual clear all
126+ add_filter('c3_invalidation_manual_batch_all_path', function($all_path) {
127+ // Only clear content directories instead of everything
128+ return '/content/*';
129+ });
130+
131+ // Environment-specific clear all behavior
132+ add_filter('c3_invalidation_manual_batch_all_path', function($all_path) {
133+ if (wp_get_environment_type() === 'staging') {
134+ return '/staging/*';
135+ }
136+ return $all_path;
137+ });
138+ ```
139+
46140### ` c3_credential `
47141
48142Override AWS credentials programmatically.
@@ -272,6 +366,117 @@ add_action('c3_invalidation_failed', function($paths, $error, $post_id) {
272366}, 10, 3);
273367```
274368
369+ ## WordPress Subdirectory Installation Support
370+
371+ The new path adjustment hooks (` c3_invalidation_post_batch_home_path ` , ` c3_invalidation_posts_batch_home_path ` , and ` c3_invalidation_manual_batch_all_path ` ) fully support WordPress installations in subdirectories.
372+
373+ ### How Subdirectory Support Works
374+
375+ When WordPress is installed in a subdirectory (e.g., ` https://example.com/blog/ ` ), the plugin automatically handles subdirectory paths through WordPress's standard ` home_url() ` function:
376+
377+ ** Normal Installation:**
378+ ```
379+ WordPress URL: https://example.com/
380+ home_url('/') → https://example.com/
381+ ```
382+
383+ ** Subdirectory Installation:**
384+ ```
385+ WordPress URL: https://example.com/blog/
386+ home_url('/') → https://example.com/blog/
387+ ```
388+
389+ ### Path Generation Logic
390+
391+ The plugin uses ` parse_url() ` to extract path components from URLs, which automatically includes subdirectory paths:
392+
393+ ``` php
394+ // In Invalidation_Batch.php
395+ public function make_invalidate_path( $url ) {
396+ $parse_url = parse_url( $url );
397+ return isset( $parse_url['path'] )
398+ ? $parse_url['path'] // Includes subdirectory
399+ : preg_replace( array( '#^https?://[^/]*#', '#\?.*$#' ), '', $url );
400+ }
401+ ```
402+
403+ ### Subdirectory Examples
404+
405+ #### Example 1: Custom Home Path for Subdirectory Installation
406+
407+ ``` php
408+ // WordPress installed at https://example.com/blog/
409+ add_filter('c3_invalidation_post_batch_home_path', function($home_path, $post) {
410+ // $home_path automatically contains "/blog/"
411+
412+ if ($post && $post->post_type === 'product') {
413+ return '/blog/shop/'; // Subdirectory + custom path
414+ }
415+ return $home_path; // Default: /blog/
416+ }, 10, 2);
417+ ```
418+
419+ #### Example 2: Manual Clear All with Subdirectory Restriction
420+
421+ ``` php
422+ // Only clear cache within the WordPress subdirectory
423+ add_filter('c3_invalidation_manual_batch_all_path', function($all_path) {
424+ // Restrict clearing to subdirectory only
425+ return '/blog/*'; // Only invalidate /blog/* paths
426+ });
427+ ```
428+
429+ #### Example 3: Environment-Specific Subdirectory Handling
430+
431+ ``` php
432+ add_filter('c3_invalidation_posts_batch_home_path', function($home_path, $posts) {
433+ // Handle different subdirectories per environment
434+ $environment = wp_get_environment_type();
435+
436+ switch ($environment) {
437+ case 'staging':
438+ return '/staging/blog/';
439+ case 'development':
440+ return '/dev/blog/';
441+ default:
442+ return $home_path; // Production subdirectory
443+ }
444+ }, 10, 2);
445+ ```
446+
447+ ### Testing Subdirectory Support
448+
449+ To test subdirectory functionality, you can simulate a subdirectory installation:
450+
451+ ``` php
452+ // Test case for subdirectory support
453+ public function test_subdirectory_installation_support() {
454+ // Mock subdirectory home URL
455+ add_filter('home_url', function($url) {
456+ return 'https://example.com/blog/';
457+ });
458+
459+ add_filter('c3_invalidation_post_batch_home_path', function($home_path, $post) {
460+ // Verify subdirectory path is included
461+ return $home_path; // Should be /blog/
462+ }, 10, 2);
463+
464+ $post = $this->factory->post->create_and_get();
465+ $target = new AWS\Invalidation_Batch_Service();
466+ $result = $target->create_batch_by_post('https://example.com/blog/', 'EXXXX', $post);
467+
468+ // Assert subdirectory path is present
469+ $this->assertContains('/blog/', $result['InvalidationBatch']['Paths']['Items']);
470+ }
471+ ```
472+
473+ ### Key Benefits for Subdirectory Installations
474+
475+ 1 . ** Automatic Path Detection** : No manual configuration needed
476+ 2 . ** Flexible Customization** : Hooks allow fine-tuned control over subdirectory paths
477+ 3 . ** Environment Compatibility** : Works seamlessly across different deployment scenarios
478+ 4 . ** Backward Compatibility** : Existing ` c3_invalidation_items ` filter continues to work
479+
275480## Best Practices
276481
277482### 1. Performance Considerations
@@ -371,4 +576,4 @@ add_action('c3_before_invalidation', function($paths, $post_id) {
371576}, 10, 2);
372577```
373578
374- This comprehensive reference provides all the tools you need to customize C3 CloudFront Cache Controller for your specific use case.
579+ This comprehensive reference provides all the tools you need to customize C3 CloudFront Cache Controller for your specific use case.
0 commit comments