diff --git a/docs/bin/generate-parsed-md.php b/docs/bin/generate-parsed-md.php
index 3731dd38..ea4f3d26 100644
--- a/docs/bin/generate-parsed-md.php
+++ b/docs/bin/generate-parsed-md.php
@@ -141,15 +141,16 @@ public function generate() {
->in( dirname( dirname( __DIR__ ) ) . '/includes' )
->exclude( 'vendor' );
+ // First pass: Process all files and collect documentation
foreach ( $finder as $file ) {
$this->process_file( $file );
}
- // Generate META.md with undocumented elements
- $this->generate_meta_file();
-
- // After processing all files, generate index files
+ // Second pass: Generate all index files
$this->generate_index_files();
+
+ // Finally: Generate META.md with undocumented elements
+ $this->generate_meta_file();
}
/**
@@ -202,9 +203,35 @@ private function extract_docs( array $ast, $file_path ) {
$this->track_undocumented( $file_path, 'function', $node->name->toString() );
}
}
- // Handle classes
+
+ // Handle namespace nodes
+ if ( $node instanceof Node\Stmt\Namespace_ ) {
+ // Process nodes inside the namespace
+ foreach ( $node->stmts as $stmt ) {
+ if ( $stmt instanceof Node\Stmt\Class_ ) {
+ $class_docs = $this->extract_class_docs( $stmt, $file_path );
+ if ( ! empty( $class_docs ) ) {
+ $docs['class'] = $class_docs;
+ }
+ }
+ // Check for hooks inside namespace
+ $hooks = $this->extract_hooks( $stmt, $file_path );
+ if ( ! empty( $hooks ) ) {
+ if ( ! isset( $docs['hooks'] ) ) {
+ $docs['hooks'] = array();
+ }
+ $docs['hooks'] = array_merge( $docs['hooks'], $hooks );
+ }
+ }
+ continue;
+ }
+
+ // Handle non-namespaced code
if ( $node instanceof Node\Stmt\Class_ ) {
- $docs['class'] = $this->extract_class_docs( $node, $file_path );
+ $class_docs = $this->extract_class_docs( $node, $file_path );
+ if ( ! empty( $class_docs ) ) {
+ $docs['class'] = $class_docs;
+ }
}
// Handle hooks
$hooks = $this->extract_hooks( $node, $file_path );
@@ -228,6 +255,7 @@ private function extract_docs( array $ast, $file_path ) {
*/
private function extract_class_docs( Node\Stmt\Class_ $node, $file_path ) {
$doc = $node->getDocComment();
+
if ( ! $doc ) {
$this->track_undocumented( $file_path, 'class', $node->name->toString() );
}
@@ -400,89 +428,40 @@ private function track_undocumented( $file, $type, $name ) {
* Generate index files for each directory of documentation.
*/
private function generate_index_files() {
- foreach ( $this->files_by_directory as $dir => $files ) {
- // Sort files for consistent order
- sort( $files );
-
- // Handle root directory differently
- if ( '' === $dir || '.' === $dir ) {
- $index_path = $this->output_dir . '/index.md';
- } else {
- // For subdirectories, just use index.md
- $index_path = $this->output_dir . '/' . $dir . '/index.md';
+ foreach ( $this->files_by_directory as $directory => $files ) {
+ if ( empty( $files ) ) {
+ continue;
}
- // Special handling for root code reference index
- if ( '' === $dir ) {
- $index_content = '# Code Reference' . "\n\n";
- } else {
- // Format directory name for title
- $dir_title = $this->format_directory_title( $dir );
- $index_content = '# ' . $dir_title . "\n\n";
- }
+ sort( $files ); // Sort files for consistent order
+ $index_path = $this->output_dir . '/' . $directory . '/index.md';
+ $index_dir = dirname( $index_path );
- $index_content .= '## Files' . "\n\n";
+ if ( ! is_dir( $index_dir ) ) {
+ mkdir( $index_dir, 0755, true );
+ }
- foreach ( $files as $file ) {
- $basename = basename( $file, '.md' );
- $title = $this->format_file_title( $basename );
- $index_content .= '- [' . $title . '](' . $basename . ')' . "\n";
+ // Generate title from directory name
+ if ( '' === $directory || '.' === $directory ) {
+ $index_path = $this->output_dir . '/index.md';
}
+ $title = $this->format_directory_title( $directory );
- // Ensure file ends with single newline and no trailing spaces
- $index_content = rtrim( rtrim( $index_content ), "\n" ) . "\n";
+ $markdown = "# {$title}\n\n";
- // Create directory if it doesn't exist
- $dir_path = dirname( $index_path );
- if ( ! is_dir( $dir_path ) ) {
- mkdir( $dir_path, 0755, true );
+ foreach ( $files as $file ) {
+ if ( 'index.md' === $file ) {
+ continue;
+ }
+ $name = basename( $file, self::MD_EXT );
+ $name = $this->format_title( $name );
+ // Remove the '# ' prefix from the title for the link text
+ $name = preg_replace( '/^# /', '', $name );
+ $markdown .= "* [{$name}]({$file})\n";
}
- file_put_contents( $index_path, $index_content );
- }
- }
-
- /**
- * Format directory title with special cases.
- *
- * @param string $dir Directory name.
- * @return string Formatted title.
- */
- private function format_directory_title( $dir ) {
- if ( 'rest-api' === $dir ) {
- return 'REST API';
+ file_put_contents( $index_path, rtrim( $markdown ) . "\n" );
}
- return '.' === $dir ? 'Code Reference' : ucwords( str_replace( '/', ' ', $dir ) );
- }
-
- /**
- * Format file title with special cases.
- *
- * @param string $basename File basename.
- * @return string Formatted title.
- */
- private function format_file_title( $basename ) {
- // Replace common patterns
- $title = str_replace(
- array(
- 'rest-api',
- 'acf-rest-api',
- 'class-acf-rest',
- '-file',
- ),
- array(
- 'REST API',
- 'ACF REST API',
- 'Class ACF REST',
- '',
- ),
- $basename
- );
-
- // Convert to title case and handle special words
- $title = ucwords( str_replace( '-', ' ', $title ) );
-
- return $title;
}
/**
@@ -592,51 +571,90 @@ private function save_markdown( $file, $docs ) {
// Save each hook type to its own file
foreach ( $grouped_hooks as $type => $hooks ) {
- $hook_markdown = '# ' . ucfirst( str_replace( '_', ' ', $type ) ) . "\n\n";
- foreach ( $hooks as $hook ) {
- $hook_markdown .= "## `{$hook['name']}`\n\n";
- if ( ! empty( $hook['doc'] ) ) {
- $hook_markdown .= "{$hook['doc']}\n\n";
- }
- // Add file reference
- $hook_markdown .= '_Defined in: ' . str_replace( dirname( dirname( __DIR__ ) ) . '/includes/', '', $file->getRealPath() ) . "_\n\n";
- }
-
$hook_file = $hooks_dir . '/' . $type . '.md';
- // Load existing content
- $existing_content = file_exists( $hook_file ) ? file_get_contents( $hook_file ) . "\n" : '';
-
- $hook_markdown = $existing_content . $hook_markdown;
-
- // Track hook files for index generation
+ // Track hooks directory for index generation
if ( ! isset( $this->files_by_directory['hooks'] ) ) {
$this->files_by_directory['hooks'] = array();
}
if ( ! in_array( basename( $hook_file ), $this->files_by_directory['hooks'], true ) ) {
$this->files_by_directory['hooks'][] = basename( $hook_file );
}
- }
- // After processing all hooks, sort each file
- foreach ( $this->files_by_directory['hooks'] as $hook_file ) {
- $file_path = $hooks_dir . '/' . $hook_file;
- if ( file_exists( $file_path ) ) {
- // Read the file
- $content = file_get_contents( $file_path );
+ // Get existing content and parse existing hooks with their sources
+ $hook_markdown = '';
+ $existing_hooks = array();
+
+ if ( file_exists( $hook_file ) ) {
+ $existing_content = file_get_contents( $hook_file );
+ // Parse existing hooks and their sources from the content
+ preg_match_all( '/^## `([^`]+)`\n\n(.*?)(?=\n## |$)/ms', $existing_content, $matches, PREG_SET_ORDER );
+ foreach ( $matches as $match ) {
+ $hook_name = $match[1];
+ $content = trim( $match[2] );
+ $existing_hooks[ $hook_name ] = $content;
+ }
+ $hook_markdown = $existing_content;
+ } else {
+ // Only add title for new files
+ $hook_markdown = '# ' . ucfirst( str_replace( '_', ' ', $type ) ) . "\n\n";
+ }
- // Split into sections (each hook documentation)
- $sections = preg_split( '/(?=^## )/m', $content );
+ $updated_hooks = array();
+ foreach ( $hooks as $hook ) {
+ $source = str_replace( dirname( dirname( __DIR__ ) ) . '/includes/', '', $file->getRealPath() );
+ $hook_content = '';
- // Keep the title section (first section starting with # )
- $title = array_shift( $sections );
+ if ( ! empty( $hook['doc'] ) ) {
+ $hook_content .= "{$hook['doc']}\n\n";
+ }
+ $hook_content .= "### Source Files\n\n";
+ $hook_content .= '* ' . $source . "\n\n";
+
+ if ( isset( $existing_hooks[ $hook['name'] ] ) ) {
+ // If hook exists, append the new source file if not already present
+ if ( strpos( $existing_hooks[ $hook['name'] ], $source ) === false ) {
+ $existing_hooks[ $hook['name'] ] = preg_replace(
+ '/(### Source Files\n\n.*?)(\n\n|$)/s',
+ "$1* $source\n\n",
+ $existing_hooks[ $hook['name'] ]
+ );
+ }
+ $updated_hooks[ $hook['name'] ] = true;
+ continue;
+ }
+
+ $hook_markdown .= "## `{$hook['name']}`\n\n" . $hook_content;
+ $updated_hooks[ $hook['name'] ] = true;
+ }
- // Sort the remaining sections
- sort( $sections, SORT_STRING | SORT_FLAG_CASE );
+ // Keep only hooks that were updated or added
+ $final_markdown = '';
+ if ( file_exists( $hook_file ) ) {
+ $lines = explode( "\n", $hook_markdown );
+ $current_hook = null;
+ $buffer = '';
+
+ foreach ( $lines as $line ) {
+ if ( preg_match( '/^## `([^`]+)`$/', $line, $matches ) ) {
+ if ( $current_hook && isset( $updated_hooks[ $current_hook ] ) ) {
+ $final_markdown .= $buffer;
+ }
+ $current_hook = $matches[1];
+ $buffer = $line . "\n";
+ } else {
+ $buffer .= $line . "\n";
+ }
+ }
+ // Handle the last hook
+ if ( $current_hook && isset( $updated_hooks[ $current_hook ] ) ) {
+ $final_markdown .= $buffer;
+ }
- // Combine and write back
- file_put_contents( $file_path, $title . implode( '', $sections ) );
+ $hook_markdown = $final_markdown ? $final_markdown : $hook_markdown;
}
+
+ file_put_contents( $hook_file, $hook_markdown );
}
// Remove hooks from docs array so they're not included in the main file
@@ -645,6 +663,7 @@ private function save_markdown( $file, $docs ) {
// Handle regular documentation
if ( ! empty( $docs ) ) {
+ // Keep the original path structure
$relative_path = str_replace(
dirname( dirname( __DIR__ ) ) . '/includes/',
'',
@@ -702,7 +721,7 @@ private function generate_markdown( $docs, $source_path ) {
$markdown .= "---\n\n";
}
- // Handle class documentation (unchanged)
+ // Handle class documentation
if ( isset( $docs['class'] ) ) {
$markdown .= $this->format_title( $docs['class']['name'] ) . "\n\n";
$markdown .= trim( $docs['class']['doc'] ) . "\n\n";
@@ -737,10 +756,54 @@ private function generate_markdown( $docs, $source_path ) {
* @return string Formatted title.
*/
private function format_title( $title ) {
+ // Special case handling for common terms
+ $title = str_replace(
+ array(
+ 'rest-api',
+ 'acf-rest-api',
+ 'class-acf-rest',
+ '-file',
+ ),
+ array(
+ 'REST API',
+ 'ACF REST API',
+ 'Class ACF REST',
+ '',
+ ),
+ $title
+ );
+
+ // Convert to title case and handle special words
+ $title = ucwords( str_replace( '-', ' ', $title ) );
+
// Convert "Api" or "api" to "API"
$title = preg_replace( '/\b[Aa]pi\b/', 'API', $title );
+
return '# ' . $title;
}
+
+ /**
+ * Format directory title with special cases.
+ *
+ * @param string $directory Directory name.
+ * @return string Formatted title.
+ */
+ private function format_directory_title( $directory ) {
+ if ( '' === $directory || '.' === $directory ) {
+ return 'Code Reference';
+ }
+
+ if ( 'rest-api' === $directory ) {
+ return 'REST API';
+ }
+
+ $title = basename( $directory );
+ $title = str_replace( '-', ' ', $title );
+ $title = ucwords( $title );
+ $title = preg_replace( '/\b[Aa]pi\b/', 'API', $title );
+
+ return $title;
+ }
}
// Parse command line arguments
diff --git a/docs/bin/manifest.json b/docs/bin/manifest.json
index c3cab2ea..f475f7f6 100644
--- a/docs/bin/manifest.json
+++ b/docs/bin/manifest.json
@@ -29,6 +29,11 @@
"parent": null,
"markdown_source": "https://github.com/wordpress/secure-custom-fields/blob/trunk/docs/welcome/index.md"
},
+ "code-reference/Blocks": {
+ "slug": "Blocks",
+ "parent": "code-reference",
+ "markdown_source": "https://github.com/wordpress/secure-custom-fields/blob/trunk/docs/code-reference/Blocks/index.md"
+ },
"code-reference/acf-bidirectional-functions-file": {
"slug": "acf-bidirectional-functions-file",
"parent": "code-reference",
@@ -164,6 +169,11 @@
"parent": "code-reference",
"markdown_source": "https://github.com/wordpress/secure-custom-fields/blob/trunk/docs/code-reference/l10n-file.md"
},
+ "code-reference/legacy": {
+ "slug": "legacy",
+ "parent": "code-reference",
+ "markdown_source": "https://github.com/wordpress/secure-custom-fields/blob/trunk/docs/code-reference/legacy/index.md"
+ },
"code-reference/local-fields-file": {
"slug": "local-fields-file",
"parent": "code-reference",
@@ -259,6 +269,11 @@
"parent": "welcome",
"markdown_source": "https://github.com/wordpress/secure-custom-fields/blob/trunk/docs/welcome/quick-start.md"
},
+ "code-reference/Blocks/Bindings-file": {
+ "slug": "Bindings-file",
+ "parent": "Blocks",
+ "markdown_source": "https://github.com/wordpress/secure-custom-fields/blob/trunk/docs/code-reference/Blocks/Bindings-file.md"
+ },
"code-reference/admin/admin-notices-file": {
"slug": "admin-notices-file",
"parent": "admin",
@@ -294,6 +309,21 @@
"parent": "forms",
"markdown_source": "https://github.com/wordpress/secure-custom-fields/blob/trunk/docs/code-reference/forms/form-front-file.md"
},
+ "code-reference/hooks/action": {
+ "slug": "action",
+ "parent": "hooks",
+ "markdown_source": "https://github.com/wordpress/secure-custom-fields/blob/trunk/docs/code-reference/hooks/action.md"
+ },
+ "code-reference/hooks/filter": {
+ "slug": "filter",
+ "parent": "hooks",
+ "markdown_source": "https://github.com/wordpress/secure-custom-fields/blob/trunk/docs/code-reference/hooks/filter.md"
+ },
+ "code-reference/legacy/class-hooks-file": {
+ "slug": "class-hooks-file",
+ "parent": "legacy",
+ "markdown_source": "https://github.com/wordpress/secure-custom-fields/blob/trunk/docs/code-reference/legacy/class-hooks-file.md"
+ },
"code-reference/rest-api/acf-rest-api-functions-file": {
"slug": "acf-rest-api-functions-file",
"parent": "rest-api",
@@ -399,6 +429,11 @@
"parent": "field",
"markdown_source": "https://github.com/wordpress/secure-custom-fields/blob/trunk/docs/features/field/message/index.md"
},
+ "features/field/nav_menu": {
+ "slug": "nav_menu",
+ "parent": "field",
+ "markdown_source": "https://github.com/wordpress/secure-custom-fields/blob/trunk/docs/features/field/nav_menu/index.md"
+ },
"features/field/number": {
"slug": "number",
"parent": "field",
@@ -579,6 +614,11 @@
"parent": "message",
"markdown_source": "https://github.com/wordpress/secure-custom-fields/blob/trunk/docs/features/field/message/tutorial.md"
},
+ "features/field/nav_menu/tutorial": {
+ "slug": "nav_menu-tutorial",
+ "parent": "nav_menu",
+ "markdown_source": "https://github.com/wordpress/secure-custom-fields/blob/trunk/docs/features/field/nav_menu/tutorial.md"
+ },
"features/field/number/tutorial": {
"slug": "number-tutorial",
"parent": "number",
diff --git a/docs/code-reference/Blocks/Bindings-file.md b/docs/code-reference/Blocks/Bindings-file.md
new file mode 100644
index 00000000..4adcfef6
--- /dev/null
+++ b/docs/code-reference/Blocks/Bindings-file.md
@@ -0,0 +1,23 @@
+# Bindings
+
+The core SCF Blocks binding class.
+
+## Methods
+
+### `__construct`
+
+Block Bindings constructor.
+
+### `register_binding_sources`
+
+Hooked to scf_init, register our binding sources.
+
+### `get_value`
+
+Handle returning the block binding value for an ACF meta value.
+
+* @since ACF 6.2.8
+* @param array $source_attrs An array of the source attributes requested.
+* @param \WP_Block $block_instance The block instance.
+* @param string $attribute_name The block's bound attribute name.
+* @return string|null The block binding value or an empty string on failure.
diff --git a/docs/code-reference/Blocks/index.md b/docs/code-reference/Blocks/index.md
new file mode 100644
index 00000000..84901c87
--- /dev/null
+++ b/docs/code-reference/Blocks/index.md
@@ -0,0 +1,3 @@
+# Blocks
+
+* [Bindings](Bindings-file)
diff --git a/docs/code-reference/META.md b/docs/code-reference/META.md
index b9d58454..6fab498a 100644
--- a/docs/code-reference/META.md
+++ b/docs/code-reference/META.md
@@ -6,9 +6,9 @@ This file tracks code elements that need documentation.
### Hooks
-- `acf/bindings/field_not_allowed_message`
-- `acf/bindings/field_not_supported_message`
-- `acf/blocks/binding_value`
+- `scf_bindings_field_not_allowed_message`
+- `scf_bindings_field_not_supported_message`
+- `scf_blocks_binding_value`
## acf-bidirectional-functions.php
@@ -414,6 +414,12 @@ This file tracks code elements that need documentation.
- `acf/fields/icon_picker/dashicons`
- `acf/fields/icon_picker/tabs`
+## fields/class-acf-field-nav-menu.php
+
+### Hooks
+
+- `wp_nav_menu_container_allowed_tags`
+
## fields/class-acf-field-page_link.php
### Hooks
@@ -503,6 +509,12 @@ This file tracks code elements that need documentation.
- `plugin_locale`
- `pre_determine_locale`
+## legacy/class-hooks.php
+
+### Hooks
+
+- `scf_enable_legacy_hooks`
+
## local-json.php
### Hooks
diff --git a/docs/code-reference/acf-bidirectional-functions-file.md b/docs/code-reference/acf-bidirectional-functions-file.md
index 099e5d5c..d98bba00 100644
--- a/docs/code-reference/acf-bidirectional-functions-file.md
+++ b/docs/code-reference/acf-bidirectional-functions-file.md
@@ -9,6 +9,7 @@ Process updating bidirectional fields.
* @param integer|string $post_id The ACF encoded origin post, user or term ID.
* @param array $field The field being updated on the origin post, user or term ID.
* @param string|false $target_prefix The ACF prefix for a post, user or term ID required for the update_field call for this field type.
+* @return void
## `acf_get_valid_bidirectional_target_types()`
@@ -41,6 +42,7 @@ Renders the field settings required for bidirectional fields
* @since ACF 6.2
* @param array $field The field object passed into field setting functions.
+* @return void
## `acf_get_bidirectional_field_settings_instruction_text()`
diff --git a/docs/code-reference/acf-helper-functions-file.md b/docs/code-reference/acf-helper-functions-file.md
index 560e1a8d..67d90013 100644
--- a/docs/code-reference/acf-helper-functions-file.md
+++ b/docs/code-reference/acf-helper-functions-file.md
@@ -114,7 +114,7 @@ acf_set_filters
* @date 14/7/16
* @since ACF 5.4.0
* @param array $filters An Array of modifiers.
-* @return array
+* @return void
## `acf_disable_filters()`
diff --git a/docs/code-reference/acf-user-functions-file.md b/docs/code-reference/acf-user-functions-file.md
index 0bb27221..93747965 100644
--- a/docs/code-reference/acf-user-functions-file.md
+++ b/docs/code-reference/acf-user-functions-file.md
@@ -32,11 +32,9 @@ acf_get_user_role_labels
## `acf_allow_unfiltered_html()`
-acf_allow_unfiltered_html
+Returns true if the current user is allowed to save unfiltered HTML.
-* Returns true if the current user is allowed to save unfiltered HTML.
-* @date 9/1/19
-* @since ACF 5.7.10
+* @since ACF 5.7.10
* @return boolean
---
diff --git a/docs/code-reference/admin/index.md b/docs/code-reference/admin/index.md
index 1580eb7e..38913d27 100644
--- a/docs/code-reference/admin/index.md
+++ b/docs/code-reference/admin/index.md
@@ -1,6 +1,4 @@
# Admin
-## Files
-
-- [Admin Notices](admin-notices-file)
-- [Admin Tools](admin-tools-file)
+* [Admin Notices](admin-notices-file)
+* [Admin Tools](admin-tools-file)
diff --git a/docs/code-reference/admin/views/global/index.md b/docs/code-reference/admin/views/global/index.md
index 16ed2b8d..2d7ba8f3 100644
--- a/docs/code-reference/admin/views/global/index.md
+++ b/docs/code-reference/admin/views/global/index.md
@@ -1,5 +1,3 @@
-# Admin Views Global
+# Global
-## Files
-
-- [Navigation](navigation-file)
+* [Navigation](navigation-file.md)
diff --git a/docs/code-reference/api/index.md b/docs/code-reference/api/index.md
index f2094832..b555ae2f 100644
--- a/docs/code-reference/api/index.md
+++ b/docs/code-reference/api/index.md
@@ -1,7 +1,5 @@
-# Api
+# API
-## Files
-
-- [Api Helpers](api-helpers-file)
-- [Api Template](api-template-file)
-- [Api Term](api-term-file)
+* [API Helpers](api-helpers-file)
+* [API Template](api-template-file)
+* [API Term](api-term-file)
diff --git a/docs/code-reference/fields/index.md b/docs/code-reference/fields/index.md
index c04a1729..cd3b1b9d 100644
--- a/docs/code-reference/fields/index.md
+++ b/docs/code-reference/fields/index.md
@@ -1,5 +1,3 @@
# Fields
-## Files
-
-- [Class Acf Repeater Table](class-acf-repeater-table-file)
+* [Class Acf Repeater Table](class-acf-repeater-table-file)
diff --git a/docs/code-reference/forms/index.md b/docs/code-reference/forms/index.md
index f4f96e65..c47b68c5 100644
--- a/docs/code-reference/forms/index.md
+++ b/docs/code-reference/forms/index.md
@@ -1,5 +1,3 @@
# Forms
-## Files
-
-- [Form Front](form-front-file)
+* [Form Front](form-front-file)
diff --git a/docs/code-reference/hooks/action.md b/docs/code-reference/hooks/action.md
new file mode 100644
index 00000000..d128639a
--- /dev/null
+++ b/docs/code-reference/hooks/action.md
@@ -0,0 +1,121 @@
+## `acf/register_scripts`
+
+Fires after core scripts and styles have been registered.
+
+* @since ACF 5.6.9
+* @param string $version The ACF version.
+* @param string $suffix The potential ".min" filename suffix.
+
+### Source Files
+
+* assets.php
+
+## `acf/enqueue_uploader`
+
+Fires when enqueuing the uploader.
+
+* @since ACF 5.6.9
+
+### Source Files
+
+* assets.php
+
+## `acf/input/admin_enqueue_scripts`
+
+Fires during "admin_enqueue_scripts" when ACF scripts are enqueued.
+
+* @since ACF 5.6.9
+
+### Source Files
+
+* assets.php
+
+## `acf/admin_enqueue_scripts`
+
+Fires during "admin_enqueue_scripts" when ACF scripts are enqueued.
+
+* @since ACF 5.6.9
+
+### Source Files
+
+* assets.php
+
+## `acf/enqueue_scripts`
+
+### Source Files
+
+* assets.php
+
+## `acf/input/admin_head`
+
+Fires during "admin_head" when ACF scripts are enqueued.
+
+* @since ACF 5.6.9
+
+### Source Files
+
+* assets.php
+
+## `acf/input/admin_print_scripts`
+
+### Source Files
+
+* assets.php
+
+## `acf/admin_head`
+
+Fires during "admin_head" when ACF scripts are enqueued.
+
+* @since ACF 5.6.9
+
+### Source Files
+
+* assets.php
+
+## `acf/admin_print_scripts`
+
+### Source Files
+
+* assets.php
+
+## `acf/input/admin_footer`
+
+Fires during "admin_footer" when ACF scripts are enqueued.
+
+* @since ACF 5.6.9
+
+### Source Files
+
+* assets.php
+
+## `acf/input/admin_print_footer_scripts`
+
+### Source Files
+
+* assets.php
+
+## `acf/admin_footer`
+
+Fires during "admin_footer" when ACF scripts are enqueued.
+
+* @since ACF 5.6.9
+
+### Source Files
+
+* assets.php
+
+## `acf/admin_print_footer_scripts`
+
+### Source Files
+
+* assets.php
+
+## `acf/admin_print_uploader_scripts`
+
+Fires when printing uploader scripts.
+
+* @since ACF 5.6.9
+
+### Source Files
+
+* assets.php
diff --git a/docs/code-reference/hooks/filter.md b/docs/code-reference/hooks/filter.md
new file mode 100644
index 00000000..30513676
--- /dev/null
+++ b/docs/code-reference/hooks/filter.md
@@ -0,0 +1,5 @@
+## `acf/input/admin_l10n`
+
+### Source Files
+
+* assets.php
diff --git a/docs/code-reference/hooks/index.md b/docs/code-reference/hooks/index.md
index fc6cd0ff..da418b5a 100644
--- a/docs/code-reference/hooks/index.md
+++ b/docs/code-reference/hooks/index.md
@@ -1,6 +1,4 @@
# Hooks
-## Files
-
-- [Action](action)
-- [Filter](filter)
+* [Action](action)
+* [Filter](filter)
diff --git a/docs/code-reference/index.md b/docs/code-reference/index.md
index c3241e22..597c3c89 100644
--- a/docs/code-reference/index.md
+++ b/docs/code-reference/index.md
@@ -1,35 +1,33 @@
# Code Reference
-## Files
-
-- [Acf Bidirectional Functions](acf-bidirectional-functions-file)
-- [Acf Field Functions](acf-field-functions-file)
-- [Acf Field Group Functions](acf-field-group-functions-file)
-- [Acf Form Functions](acf-form-functions-file)
-- [Acf Helper Functions](acf-helper-functions-file)
-- [Acf Hook Functions](acf-hook-functions-file)
-- [Acf Input Functions](acf-input-functions-file)
-- [Acf Internal Post Type Functions](acf-internal-post-type-functions-file)
-- [Acf Meta Functions](acf-meta-functions-file)
-- [Acf Post Functions](acf-post-functions-file)
-- [Acf Post Type Functions](acf-post-type-functions-file)
-- [Acf Taxonomy Functions](acf-taxonomy-functions-file)
-- [Acf User Functions](acf-user-functions-file)
-- [Acf Utility Functions](acf-utility-functions-file)
-- [Acf Value Functions](acf-value-functions-file)
-- [Acf Wp Functions](acf-wp-functions-file)
-- [Assets](assets-file)
-- [Blocks](blocks-file)
-- [Compatibility](compatibility-file)
-- [Deprecated](deprecated-file)
-- [Fields](fields-file)
-- [L10n](l10n-file)
-- [Local Fields](local-fields-file)
-- [Local Json](local-json-file)
-- [Local Meta](local-meta-file)
-- [Locations](locations-file)
-- [Loop](loop-file)
-- [Revisions](revisions-file)
-- [Scf Ui Options Page Functions](scf-ui-options-page-functions-file)
-- [Upgrades](upgrades-file)
-- [Validation](validation-file)
+* [Acf Bidirectional Functions](acf-bidirectional-functions-file)
+* [Acf Field Functions](acf-field-functions-file)
+* [Acf Field Group Functions](acf-field-group-functions-file)
+* [Acf Form Functions](acf-form-functions-file)
+* [Acf Helper Functions](acf-helper-functions-file)
+* [Acf Hook Functions](acf-hook-functions-file)
+* [Acf Input Functions](acf-input-functions-file)
+* [Acf Internal Post Type Functions](acf-internal-post-type-functions-file)
+* [Acf Meta Functions](acf-meta-functions-file)
+* [Acf Post Functions](acf-post-functions-file)
+* [Acf Post Type Functions](acf-post-type-functions-file)
+* [Acf Taxonomy Functions](acf-taxonomy-functions-file)
+* [Acf User Functions](acf-user-functions-file)
+* [Acf Utility Functions](acf-utility-functions-file)
+* [Acf Value Functions](acf-value-functions-file)
+* [Acf Wp Functions](acf-wp-functions-file)
+* [Assets](assets-file)
+* [Blocks](blocks-file)
+* [Compatibility](compatibility-file)
+* [Deprecated](deprecated-file)
+* [Fields](fields-file)
+* [L10n](l10n-file)
+* [Local Fields](local-fields-file)
+* [Local Json](local-json-file)
+* [Local Meta](local-meta-file)
+* [Locations](locations-file)
+* [Loop](loop-file)
+* [Revisions](revisions-file)
+* [Scf Ui Options Page Functions](scf-ui-options-page-functions-file)
+* [Upgrades](upgrades-file)
+* [Validation](validation-file)
diff --git a/docs/code-reference/legacy/class-hooks-file.md b/docs/code-reference/legacy/class-hooks-file.md
new file mode 100644
index 00000000..969cf6db
--- /dev/null
+++ b/docs/code-reference/legacy/class-hooks-file.md
@@ -0,0 +1,53 @@
+# Hooks
+
+Class to handle legacy hook mappings.
+
+* @since 6.5.0
+
+## Properties
+
+### `$hook_mappings`
+
+Hook mappings from new to legacy format.
+
+* @since 6.5.0
+* @var array
+
+## Methods
+
+### `__construct`
+
+Constructor.
+
+* @since 6.5.0
+
+### `is_legacy_hooks_enabled`
+
+Check if legacy hooks should be enabled.
+
+* @since 6.5.0
+* @return bool
+
+### `setup_legacy_hooks`
+
+Setup all legacy hook mappings.
+
+* @since 6.5.0
+
+### `setup_legacy_filter`
+
+Setup a legacy filter mapping.
+
+* @since 6.5.0
+* @param string $new_hook New hook name.
+* @param string $legacy_hook Legacy hook name.
+* @param int $accepted_args Number of arguments the filter accepts.
+
+### `setup_legacy_action`
+
+Setup a legacy action mapping.
+
+* @since 6.5.0
+* @param string $new_hook New hook name.
+* @param string $legacy_hook Legacy hook name.
+* @param int $accepted_args Number of arguments the action accepts.
diff --git a/docs/code-reference/legacy/index.md b/docs/code-reference/legacy/index.md
new file mode 100644
index 00000000..73268f03
--- /dev/null
+++ b/docs/code-reference/legacy/index.md
@@ -0,0 +1,3 @@
+# Legacy
+
+* [Class Hooks](class-hooks-file)
diff --git a/docs/code-reference/locations-file.md b/docs/code-reference/locations-file.md
index fe73d4e4..0ca18caa 100644
--- a/docs/code-reference/locations-file.md
+++ b/docs/code-reference/locations-file.md
@@ -69,7 +69,7 @@ Returns true if the provided rule matches the screen args.
* @since ACF 5.6.0
* @param array $rule The location rule.
* @param array $screen The screen args.
-* @param array $field The field group array.
+* @param array $field_group The field group array.
* @return boolean
## `acf_get_location_screen()`
@@ -79,7 +79,7 @@ Returns ann array of screen args to be used against matching rules.
* @date 8/4/20
* @since ACF 5.9.0
* @param array $screen The screen args.
-* @param array $deprecated The field group array.
+* @param array $deprecated Deprecated.
* @return array
## `acf_register_location_rule()`
diff --git a/docs/code-reference/rest-api/index.md b/docs/code-reference/rest-api/index.md
index c33abf0c..00b24f9b 100644
--- a/docs/code-reference/rest-api/index.md
+++ b/docs/code-reference/rest-api/index.md
@@ -1,8 +1,6 @@
# REST API
-## Files
-
-- [Acf REST API Functions](acf-rest-api-functions-file)
-- [Class Acf REST API](class-acf-rest-api-file)
-- [Class ACF REST Embed Links](class-acf-rest-embed-links-file)
-- [Class ACF REST Request](class-acf-rest-request-file)
+* [Acf REST API Functions](acf-rest-api-functions-file)
+* [Class Acf REST API](class-acf-rest-api-file)
+* [Class ACF REST Embed Links](class-acf-rest-embed-links-file)
+* [Class ACF REST Request](class-acf-rest-request-file)
diff --git a/docs/contributing/index.md b/docs/contributing/index.md
index 8d9f8653..f250bc31 100644
--- a/docs/contributing/index.md
+++ b/docs/contributing/index.md
@@ -26,7 +26,7 @@ Guide for contributing to Secure Custom Fields development.
1. Fork the repository
2. Set up local environment
- - The local environment runs with WP env, for setup, see: https://developer.wordpress.org/block-editor/reference-guides/packages/packages-env/ along with prerequisites.
+ - The local environment runs with WP env, for setup, see:
+
See what\'s new', 'secure-custom-fields' ), esc_url( admin_url( 'edit.php?post_type=acf-field-group' ) ) ) ); ?>
diff --git a/includes/blocks.php b/includes/blocks.php index e8546a08..09687783 100644 --- a/includes/blocks.php +++ b/includes/blocks.php @@ -826,7 +826,7 @@ function ( $block ) { $blocks_js_path = acf_get_url( "assets/build/js/pro/acf-pro-blocks{$min}.js" ); - wp_enqueue_script( 'acf-blocks', $blocks_js_path, array( 'acf-input', 'wp-blocks' ), ACF_VERSION, true ); + wp_enqueue_script( 'acf-blocks', $blocks_js_path, array( 'acf-input', 'wp-blocks' ), SCF_VERSION, true ); // Enqueue block assets. array_map( 'acf_enqueue_block_type_assets', $block_types ); @@ -858,12 +858,12 @@ function acf_enqueue_block_type_assets( $block_type ) { // Enqueue style. if ( $block_type['enqueue_style'] ) { - wp_enqueue_style( $handle, $block_type['enqueue_style'], array(), ACF_VERSION, 'all' ); + wp_enqueue_style( $handle, $block_type['enqueue_style'], array(), SCF_VERSION, 'all' ); } // Enqueue script. if ( $block_type['enqueue_script'] ) { - wp_enqueue_script( $handle, $block_type['enqueue_script'], array(), ACF_VERSION, true ); + wp_enqueue_script( $handle, $block_type['enqueue_script'], array(), SCF_VERSION, true ); } // Enqueue assets callback. diff --git a/includes/class-acf-site-health.php b/includes/class-acf-site-health.php index fa7b6066..b56205b1 100644 --- a/includes/class-acf-site-health.php +++ b/includes/class-acf-site-health.php @@ -258,7 +258,7 @@ public function get_site_health_values(): array { $fields['version'] = array( 'label' => __( 'Plugin Version', 'secure-custom-fields' ), - 'value' => defined( 'ACF_VERSION' ) ? ACF_VERSION : '', + 'value' => defined( 'SCF_VERSION' ) ? SCF_VERSION : '', ); $fields['wp_version'] = array( diff --git a/includes/compatibility.php b/includes/compatibility.php index 681e2311..55596f04 100644 --- a/includes/compatibility.php +++ b/includes/compatibility.php @@ -43,7 +43,7 @@ function __construct() { add_filter( 'acf/location/validate_rule/type=post_category', array( $this, 'validate_post_taxonomy_location_rule' ), 20, 1 ); // Update settings - add_action( 'acf/init', array( $this, 'init' ) ); + add_action( 'scf_init', array( $this, 'init' ) ); } /** diff --git a/includes/legacy/class-hooks.php b/includes/legacy/class-hooks.php new file mode 100644 index 00000000..f01c2551 --- /dev/null +++ b/includes/legacy/class-hooks.php @@ -0,0 +1,159 @@ + array( + 'scf_blocks_binding_value' => array( + 'hook' => 'acf/blocks/binding_value', + 'args' => 4, + ), + 'scf_bindings_field_not_supported_message' => array( + 'hook' => 'acf/bindings/field_not_supported_message', + 'args' => 1, + ), + 'scf_bindings_field_not_allowed_message' => array( + 'hook' => 'acf/bindings/field_not_allowed_message', + 'args' => 1, + ), + ), + 'actions' => array( + 'scf_init' => array( + 'hook' => 'acf/init', + 'args' => 1, + ), + 'scf_include_field_types' => 'acf/include_field_types', + 'scf_include_location_rules' => 'acf/include_location_rules', + 'scf_include_fields' => 'acf/include_fields', + 'scf_include_post_types' => 'acf/include_post_types', + 'scf_include_taxonomies' => 'acf/include_taxonomies', + 'scf_include_options_pages' => 'acf/include_options_pages', + 'scf_first_activated' => 'acf/first_activated', + 'scf_init_internal_post_types' => 'acf/init_internal_post_types', + ), + ); + + /** + * Constructor. + * + * @since 6.5.0 + */ + public function __construct() { + if ( ! $this->is_legacy_hooks_enabled() ) { + return; + } + + $this->setup_legacy_hooks(); + } + + /** + * Check if legacy hooks should be enabled. + * + * @since 6.5.0 + * + * @return bool + */ + private function is_legacy_hooks_enabled() { + /** + * Filter whether legacy hooks should be enabled. + * + * @since 6.5.0 + * + * @param bool $enabled Whether legacy hooks are enabled. + */ + return apply_filters( 'scf_enable_legacy_hooks', true ); + } + + /** + * Setup all legacy hook mappings. + * + * @since 6.5.0 + */ + private function setup_legacy_hooks() { + foreach ( $this->hook_mappings['filters'] as $new_hook => $config ) { + $this->setup_legacy_filter( $new_hook, $config['hook'], $config['args'] ); + } + + foreach ( $this->hook_mappings['actions'] as $new_hook => $config ) { + if ( is_array( $config ) ) { + $this->setup_legacy_action( $new_hook, $config['hook'], $config['args'] ); + } else { + // Handle string format for actions without args. + $this->setup_legacy_action( $new_hook, $config, 1 ); + } + } + } + + /** + * Setup a legacy filter mapping. + * + * @since 6.5.0 + * + * @param string $new_hook New hook name. + * @param string $legacy_hook Legacy hook name. + * @param int $accepted_args Number of arguments the filter accepts. + */ + private function setup_legacy_filter( $new_hook, $legacy_hook, $accepted_args ) { + add_filter( + $new_hook, + function () use ( $new_hook, $legacy_hook ) { + $args = func_get_args(); + $value = $args[0]; + + // Run the legacy filter if it has any callbacks + if ( has_filter( $legacy_hook ) ) { + $value = apply_filters( $legacy_hook, $value, ...array_slice( $args, 1 ) ); + } + + return $value; + }, + 1, + $accepted_args + ); + } + + /** + * Setup a legacy action mapping. + * + * @since 6.5.0 + * + * @param string $new_hook New hook name. + * @param string $legacy_hook Legacy hook name. + * @param int $accepted_args Number of arguments the action accepts. + */ + private function setup_legacy_action( $new_hook, $legacy_hook, $accepted_args ) { + add_action( + $new_hook, + function () use ( $new_hook, $legacy_hook ) { + $args = func_get_args(); + + // Run the legacy action if it has any callbacks + if ( has_action( $legacy_hook ) ) { + do_action( $legacy_hook, ...$args ); + } + }, + 1, + $accepted_args + ); + } +} + +new Hooks(); diff --git a/includes/post-types/class-acf-post-type.php b/includes/post-types/class-acf-post-type.php index 3a4eb8a1..4f669e9a 100644 --- a/includes/post-types/class-acf-post-type.php +++ b/includes/post-types/class-acf-post-type.php @@ -73,7 +73,7 @@ public function __construct() { parent::__construct(); - add_action( 'acf/init', array( $this, 'register_post_types' ), 6 ); + add_action( 'scf_init', array( $this, 'register_post_types' ), 6 ); add_filter( 'enter_title_here', array( $this, 'enter_title_here' ), 10, 2 ); } diff --git a/includes/post-types/class-acf-taxonomy.php b/includes/post-types/class-acf-taxonomy.php index 985b19b7..592767ee 100644 --- a/includes/post-types/class-acf-taxonomy.php +++ b/includes/post-types/class-acf-taxonomy.php @@ -72,7 +72,7 @@ public function __construct() { parent::__construct(); - add_action( 'acf/init', array( $this, 'register_taxonomies' ), 6 ); + add_action( 'scf_init', array( $this, 'register_taxonomies' ), 6 ); } /** diff --git a/includes/post-types/class-acf-ui-options-page.php b/includes/post-types/class-acf-ui-options-page.php index 18c5a468..fa34be69 100644 --- a/includes/post-types/class-acf-ui-options-page.php +++ b/includes/post-types/class-acf-ui-options-page.php @@ -81,7 +81,7 @@ public function __construct() { parent::__construct(); - add_action( 'acf/init', array( $this, 'register_ui_options_pages' ), 6 ); + add_action( 'scf_init', array( $this, 'register_ui_options_pages' ), 6 ); add_action( 'acf/include_options_pages', array( $this, 'include_json_options_pages' ) ); } diff --git a/includes/third-party.php b/includes/third-party.php index c17ba927..52908d22 100644 --- a/includes/third-party.php +++ b/includes/third-party.php @@ -144,7 +144,7 @@ public function pts_allowed_pages( $pages ) { */ public function doing_dark_mode() { $min = defined( 'SCF_DEVELOPMENT_MODE' ) && SCF_DEVELOPMENT_MODE ? '' : '.min'; - wp_enqueue_style( 'acf-dark', acf_get_url( 'assets/css/acf-dark' . $min . '.css' ), array(), ACF_VERSION ); + wp_enqueue_style( 'acf-dark', acf_get_url( 'assets/css/acf-dark' . $min . '.css' ), array(), SCF_VERSION ); } } diff --git a/includes/upgrades.php b/includes/upgrades.php index ee7ff0b8..e4dfbd4a 100644 --- a/includes/upgrades.php +++ b/includes/upgrades.php @@ -13,12 +13,12 @@ function acf_has_upgrade() { $db_version = acf_get_db_version(); - if ( $db_version && acf_version_compare( $db_version, '<', ACF_UPGRADE_VERSION ) ) { + if ( $db_version && acf_version_compare( $db_version, '<', SCF_UPGRADE_VERSION ) ) { return true; } - if ( $db_version !== ACF_VERSION ) { - acf_update_db_version( ACF_VERSION ); + if ( SCF_VERSION !== $db_version ) { + acf_update_db_version( SCF_VERSION ); } return false; @@ -56,16 +56,16 @@ function acf_upgrade_all() { } /** - * When adding new upgrade routines here, increment the ACF_UPGRADE_VERSION + * When adding new upgrade routines here, increment the SCF_UPGRADE_VERSION * constant in `acf.php` to the new highest upgrade version. */ // upgrade DB version once all updates are complete - acf_update_db_version( ACF_VERSION ); + acf_update_db_version( SCF_VERSION ); if ( is_multisite() ) { // Clears the network upgrade notification banner after site upgrades. - delete_site_transient( 'acf_network_upgrade_needed_' . ACF_UPGRADE_VERSION ); + delete_site_transient( 'acf_network_upgrade_needed_' . SCF_UPGRADE_VERSION ); } // log diff --git a/secure-custom-fields.php b/secure-custom-fields.php index dc494ade..c2b00303 100644 --- a/secure-custom-fields.php +++ b/secure-custom-fields.php @@ -82,7 +82,16 @@ public function initialize() { defined( 'ACF_MAJOR_VERSION' ) || define( 'ACF_MAJOR_VERSION', 6 ); defined( 'ACF_FIELD_API_VERSION' ) || define( 'ACF_FIELD_API_VERSION', 5 ); defined( 'ACF_UPGRADE_VERSION' ) || define( 'ACF_UPGRADE_VERSION', '5.5.0' ); // Highest version with an upgrade routine. See upgrades.php. - defined( 'ACF_PRO' ) || define( 'ACF_PRO', true ); + defined( 'ACF_PRO' ) || define( 'ACF_PRO', true ); // Legacy. Always true in SCF. + + // Temporary: define SCF constants based on ACF values. @todo Add ACF constants to the legacy class. + defined( 'SCF' ) || define( 'SCF', true ); + defined( 'SCF_PATH' ) || define( 'SCF_PATH', ACF_PATH ); + defined( 'SCF_BASENAME' ) || define( 'SCF_BASENAME', ACF_BASENAME ); + defined( 'SCF_VERSION' ) || define( 'SCF_VERSION', ACF_VERSION ); + defined( 'SCF_MAJOR_VERSION' ) || define( 'SCF_MAJOR_VERSION', ACF_MAJOR_VERSION ); + defined( 'SCF_FIELD_API_VERSION' ) || define( 'SCF_FIELD_API_VERSION', ACF_FIELD_API_VERSION ); + defined( 'SCF_UPGRADE_VERSION' ) || define( 'SCF_UPGRADE_VERSION', ACF_UPGRADE_VERSION ); // Register activation hook. register_activation_hook( __FILE__, array( $this, 'acf_plugin_activated' ) ); @@ -90,10 +99,10 @@ public function initialize() { // Define settings. $this->settings = array( 'name' => 'Secure Custom Fields', // Will be updated in the init hook to i18n string. - 'slug' => dirname( ACF_BASENAME ), - 'version' => ACF_VERSION, - 'basename' => ACF_BASENAME, - 'path' => ACF_PATH, + 'slug' => dirname( SCF_BASENAME ), + 'version' => SCF_VERSION, + 'basename' => SCF_BASENAME, + 'path' => SCF_PATH, 'file' => __FILE__, 'url' => plugin_dir_url( __FILE__ ), 'show_admin' => true, @@ -132,7 +141,8 @@ public function initialize() { ); // Include utility functions. - include_once ACF_PATH . 'includes/acf-utility-functions.php'; + include_once SCF_PATH . 'includes/acf-utility-functions.php'; + include_once SCF_PATH . 'includes/legacy/class-hooks.php'; // Include previous API functions. acf_include( 'includes/api/api-helpers.php' ); @@ -288,7 +298,7 @@ public function init() { acf_include( 'includes/post-types/class-acf-ui-options-page.php' ); } // Add other ACF internal post types. - do_action( 'acf/init_internal_post_types' ); + do_action( 'scf_init_internal_post_types' ); // Include fields. acf_include( 'includes/fields/class-acf-field-text.php' ); @@ -333,11 +343,11 @@ public function init() { /** * Fires after field types have been included. * - * @since ACF 5.0.0 + * @since 6.5.0 * * @param int $version The field API version. */ - do_action( 'acf/include_field_types', ACF_FIELD_API_VERSION ); + do_action( 'scf_include_field_types', SCF_FIELD_API_VERSION ); // Include locations. acf_include( 'includes/locations/class-acf-location-post-type.php' ); @@ -367,47 +377,49 @@ public function init() { /** * Fires after location types have been included. * - * @since ACF 5.0.0 + * @since 6.5.0 * * @param int $version The field API version. */ - do_action( 'acf/include_location_rules', ACF_FIELD_API_VERSION ); + do_action( 'scf_include_location_rules', SCF_FIELD_API_VERSION ); /** * Fires during initialization. Used to add local fields. * - * @since ACF 5.0.0 + * @since 6.5.0 * * @param int $version The field API version. */ - do_action( 'acf/include_fields', ACF_FIELD_API_VERSION ); + do_action( 'scf_include_fields', SCF_FIELD_API_VERSION ); /** * Fires during initialization. Used to add local post types. * - * @since ACF 6.1 + * @since 6.5.0 * * @param int $version The major version of ACF. */ - do_action( 'acf/include_post_types', ACF_MAJOR_VERSION ); + do_action( 'scf_include_post_types', SCF_MAJOR_VERSION ); /** * Fires during initialization. Used to add local taxonomies. * - * @since ACF 6.1 + * @since 6.5.0 * * @param int $version The major version of ACF. */ - do_action( 'acf/include_taxonomies', ACF_MAJOR_VERSION ); + do_action( 'scf_include_taxonomies', SCF_MAJOR_VERSION ); /** * Fires during initialization. Used to add local option pages. * - * @param int $version The major version of ACF. + * @since 6.5.0 + * + * @param int $version The major version of ACF. */ - do_action( 'acf/include_options_pages', ACF_MAJOR_VERSION ); + do_action( 'scf_include_options_pages', SCF_MAJOR_VERSION ); - // If we're on WP 6.5 or newer, load block bindings. This will move to an autoloader in SCF 6.3. + // If we're on WP 6.5 or newer, load block bindings. This will move to an autoloader later. if ( version_compare( get_bloginfo( 'version' ), '6.5-beta1', '>=' ) ) { acf_include( 'includes/Blocks/Bindings.php' ); new ACF\Blocks\Bindings(); @@ -416,11 +428,11 @@ public function init() { /** * Fires after ACF is completely "initialized". * - * @since ACF 5.0.0 + * @since 6.5.0 * * @param int $version The major version of ACF. */ - do_action( 'acf/init', ACF_MAJOR_VERSION ); + do_action( 'scf_init', SCF_MAJOR_VERSION ); } /** @@ -734,9 +746,9 @@ public function acf_plugin_activated() { if ( null === get_option( 'acf_first_activated_version', null ) ) { // If acf_version is set, this isn't the first activated version, so leave it unset so it's legacy. if ( null === get_option( 'acf_version', null ) ) { - update_option( 'acf_first_activated_version', ACF_VERSION, true ); + update_option( 'acf_first_activated_version', SCF_VERSION, true ); - do_action( 'acf/first_activated' ); + do_action( 'scf_first_activated' ); } } } diff --git a/tests/php/legacy/test-hooks.php b/tests/php/legacy/test-hooks.php new file mode 100644 index 00000000..2f92a3a5 --- /dev/null +++ b/tests/php/legacy/test-hooks.php @@ -0,0 +1,121 @@ +assertEquals( $test_value . '_' . $modified, $result ); + } + + /** + * Test that legacy actions are called when new actions are triggered + */ + public function test_legacy_action_called() { + $action_called = false; + + add_action( + 'acf/init', + function () use ( &$action_called ) { + $action_called = true; + } + ); + + do_action( 'scf_init' ); + $this->assertTrue( $action_called ); + } + + /** + * Test that filter arguments are passed correctly + */ + public function test_filter_arguments_passed() { + $test_value = 'test'; + $source_attrs = array( 'foo' => 'bar' ); + $block_instance = array( 'name' => 'test-block' ); + $attribute_name = 'test-attr'; + + add_filter( + 'acf/blocks/binding_value', + function ( $value, $attrs, $block, $attr ) use ( $source_attrs, $block_instance, $attribute_name ) { + $this->assertEquals( $source_attrs, $attrs ); + $this->assertEquals( $block_instance, $block ); + $this->assertEquals( $attribute_name, $attr ); + return $value; + }, + 10, + 4 + ); + + apply_filters( 'scf_blocks_binding_value', $test_value, $source_attrs, $block_instance, $attribute_name ); + } + + /** + * Test that action arguments are passed correctly + */ + public function test_action_arguments_passed() { + $version = \SCF_MAJOR_VERSION; + + add_action( + 'acf/init', + function ( $major_version ) use ( $version ) { + $this->assertEquals( $version, $major_version ); + }, + 10, + 1 + ); + + do_action( 'scf_init', $version ); + } + + /** + * Test that legacy hooks can be disabled + */ + public function test_legacy_hooks_can_be_disabled() { + add_filter( 'scf_enable_legacy_hooks', '__return_false' ); + + $this->legacy_hooks = new Hooks(); // Reinitialize with filter active + + $action_called = false; + add_action( + 'acf/bindings/test_action', + function () use ( &$action_called ) { + $action_called = true; + } + ); + + do_action( 'scf_bindings_test_action' ); + $this->assertFalse( $action_called ); + } +}