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: along with prerequisites. 3. Install dependencies - run `composer install` - build the plugin files (JS/CSS) via `npm run build` diff --git a/docs/features/field/nav_menu/index.md b/docs/features/field/nav_menu/index.md index b1ac75b6..12b07cd7 100644 --- a/docs/features/field/nav_menu/index.md +++ b/docs/features/field/nav_menu/index.md @@ -6,12 +6,10 @@ The Nav Menu Field field provides a way to select nav menus and output them. - Different Return Value (Object, HTML, ID) - Different Menu Container (nav, div) -- Ability to select no value +- Ability to select no value ## Settings - Return Value - Menu Container - Allow Null? - - diff --git a/docs/features/field/nav_menu/tutorial.md b/docs/features/field/nav_menu/tutorial.md index bc21954d..d1d911d9 100644 --- a/docs/features/field/nav_menu/tutorial.md +++ b/docs/features/field/nav_menu/tutorial.md @@ -63,6 +63,7 @@ if ($menu_id) { Use the `wp_nav_menu_container_allowed_tags` hook to add additional allowed container tags for the Nav Menu field. This will enable more flexibility in the menu's wrapper tag. Example: + ```php function my_custom_menu_container_tags($tags) { $tags[] = 'section'; // Adds 'section' as an allowed container tag diff --git a/includes/Blocks/Bindings.php b/includes/Blocks/Bindings.php index 4c043eba..32fff700 100644 --- a/includes/Blocks/Bindings.php +++ b/includes/Blocks/Bindings.php @@ -21,11 +21,11 @@ public function __construct() { return; } - add_action( 'acf/init', array( $this, 'register_binding_sources' ) ); + add_action( 'scf_init', array( $this, 'register_binding_sources' ) ); } /** - * Hooked to acf/init, register our binding sources. + * Hooked to scf_init, register our binding sources. */ public function register_binding_sources() { if ( acf_get_setting( 'enable_block_bindings' ) ) { @@ -61,7 +61,7 @@ public function get_value( array $source_attrs, \WP_Block $block_instance, strin if ( ! acf_field_type_supports( $field['type'], 'bindings', true ) ) { if ( is_preview() ) { - return apply_filters( 'acf/bindings/field_not_supported_message', '[' . esc_html__( 'The requested SCF field type does not support output in Block Bindings or the SCF shortcode.', 'secure-custom-fields' ) . ']' ); + return apply_filters( 'scf_bindings_field_not_supported_message', '[' . esc_html__( 'The requested SCF field type does not support output in Block Bindings or the SCF shortcode.', 'secure-custom-fields' ) . ']' ); } else { return ''; } @@ -69,7 +69,7 @@ public function get_value( array $source_attrs, \WP_Block $block_instance, strin if ( isset( $field['allow_in_bindings'] ) && ! $field['allow_in_bindings'] ) { if ( is_preview() ) { - return apply_filters( 'acf/bindings/field_not_allowed_message', '[' . esc_html__( 'The requested SCF field is not allowed to be output in bindings or the SCF Shortcode.', 'secure-custom-fields' ) . ']' ); + return apply_filters( 'scf_bindings_field_not_allowed_message', '[' . esc_html__( 'The requested SCF field is not allowed to be output in bindings or the SCF Shortcode.', 'secure-custom-fields' ) . ']' ); } else { return ''; } @@ -87,6 +87,6 @@ public function get_value( array $source_attrs, \WP_Block $block_instance, strin } } - return apply_filters( 'acf/blocks/binding_value', $value, $source_attrs, $block_instance, $attribute_name ); + return apply_filters( 'scf_blocks_binding_value', $value, $source_attrs, $block_instance, $attribute_name ); } } diff --git a/includes/acf-helper-functions.php b/includes/acf-helper-functions.php index e0110821..71ad3871 100644 --- a/includes/acf-helper-functions.php +++ b/includes/acf-helper-functions.php @@ -618,7 +618,7 @@ function acf_maybe_unserialize( $data ) { * @return boolean True if the current install version contains a dash, indicating a alpha, beta or RC release. */ function acf_is_beta() { - return defined( 'ACF_VERSION' ) && strpos( ACF_VERSION, '-' ) !== false; + return defined( 'SCF_VERSION' ) && strpos( SCF_VERSION, '-' ) !== false; } /** @@ -633,7 +633,7 @@ function acf_is_beta() { function acf_get_version_when_first_activated() { // Check if ACF is network-activated on a multisite. if ( is_multisite() ) { - $acf_dir_and_filename = basename( ACF_PATH ) . '/acf.php'; + $acf_dir_and_filename = basename( SCF_PATH ) . '/acf.php'; $plugins = get_site_option( 'active_sitewide_plugins' ); if ( isset( $plugins[ $acf_dir_and_filename ] ) ) { diff --git a/includes/acf-utility-functions.php b/includes/acf-utility-functions.php index 323b2041..c86f1935 100644 --- a/includes/acf-utility-functions.php +++ b/includes/acf-utility-functions.php @@ -115,7 +115,7 @@ function acf_switch_stores( $site_id, $prev_site_id ) { * @return string */ function acf_get_path( $filename = '' ) { - return ACF_PATH . ltrim( $filename, '/' ); + return SCF_PATH . ltrim( $filename, '/' ); } /** diff --git a/includes/admin/admin-internal-post-type-list.php b/includes/admin/admin-internal-post-type-list.php index ecfa52f2..0dc7e960 100644 --- a/includes/admin/admin-internal-post-type-list.php +++ b/includes/admin/admin-internal-post-type-list.php @@ -307,7 +307,7 @@ public function get_not_found_html() { $view = $this->post_type . '/list-empty'; if ( $this->is_pro_feature ) { - $view = ACF_PATH . 'pro/admin/views/' . $view . '.php'; + $view = SCF_PATH . 'pro/admin/views/' . $view . '.php'; } acf_get_view( $view ); diff --git a/includes/admin/admin-upgrade.php b/includes/admin/admin-upgrade.php index 672b433a..6a257677 100644 --- a/includes/admin/admin-upgrade.php +++ b/includes/admin/admin-upgrade.php @@ -39,7 +39,7 @@ class ACF_Admin_Upgrade { */ public function __construct() { - $this->network_upgrade_needed_transient = 'acf_network_upgrade_needed_' . ACF_UPGRADE_VERSION; + $this->network_upgrade_needed_transient = 'acf_network_upgrade_needed_' . SCF_UPGRADE_VERSION; add_action( 'admin_menu', array( $this, 'admin_menu' ), 20 ); if ( is_multisite() ) { @@ -112,10 +112,10 @@ public function network_admin_menu() { * multisite network. * * Stores the result in `$this->network_upgrade_needed_transient`, - * which is version-linked to ACF_UPGRADE_VERSION: the highest ACF + * which is version-linked to SCF_UPGRADE_VERSION: the highest SCF * version that requires an upgrade function to run. Bumping - * ACF_UPGRADE_VERSION will trigger new upgrade checks but incrementing - * ACF_VERSION alone will not. + * SCF_UPGRADE_VERSION will trigger new upgrade checks but incrementing + * SCF_VERSION alone will not. * * @since ACF 6.0.0 * @return string 'yes' if any site in the network requires an upgrade, diff --git a/includes/admin/tools/class-acf-admin-tool-export.php b/includes/admin/tools/class-acf-admin-tool-export.php index dbffedd0..64a16802 100644 --- a/includes/admin/tools/class-acf-admin-tool-export.php +++ b/includes/admin/tools/class-acf-admin-tool-export.php @@ -399,7 +399,7 @@ public function html_generate() { } elseif ( 'acf-post-type' === $post_type || 'acf-taxonomy' === $post_type ) { echo "add_action( 'init', function() {\r\n"; } elseif ( 'acf-ui-options-page' === $post_type ) { - echo "add_action( 'acf/init', function() {\r\n"; + echo "add_action( 'scf_init', function() {\r\n"; } $count = 0; diff --git a/includes/admin/views/upgrade/network.php b/includes/admin/views/upgrade/network.php index c6e1d277..a0bbe074 100644 --- a/includes/admin/views/upgrade/network.php +++ b/includes/admin/views/upgrade/network.php @@ -74,7 +74,7 @@ class="alternate"> - + @@ -145,7 +145,7 @@ class="alternate"> // show loading - $row.find('.response').html(' '); + $row.find('.response').html(' '); // send ajax request to upgrade DB $.ajax({ diff --git a/includes/admin/views/upgrade/upgrade.php b/includes/admin/views/upgrade/upgrade.php index 5053a43e..bff1c335 100644 --- a/includes/admin/views/upgrade/upgrade.php +++ b/includes/admin/views/upgrade/upgrade.php @@ -26,7 +26,7 @@

-

+

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 ); + } +}