ACF\Blocks\AutoInlineEditing
apply_inline_editing_attributes_to_html_string() │ ACF 1.0
Applies inline editing attributes to dom elements if they contain field values.
No Hooks.
Returns
String.
Usage
apply_inline_editing_attributes_to_html_string( $html_string, $block ): string;
- $html_string(string) (required)
- The HTML string being processed.
- $block(array) (required)
- The block data.
apply_inline_editing_attributes_to_html_string() apply inline editing attributes to html string code ACF 6.8.8
function apply_inline_editing_attributes_to_html_string( $html_string, $block ): string {
global $acf_fields_used_in_block_render_template;
// Don't apply autoInlineEditing if the current PHP doesn't include DOMDocument or DOMXPath.
if ( ! class_exists( 'DOMDocument' ) || ! class_exists( 'DOMXPath' ) ) {
return $html_string;
}
$allowed_contenteditable_field_types = get_allowed_contenteditable_fields();
$non_auto_inline_editing_fields = get_non_auto_inline_editing_fields();
$html = '<!DOCTYPE html><html><head><meta charset="UTF-8"></head>' . $html_string;
// Load the HTML into DOMDocument
$dom = new \DOMDocument();
libxml_use_internal_errors( true ); // Suppress warnings for invalid HTML
$dom->loadHTML( $html, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD );
libxml_clear_errors();
// Get all elements
$xpath = new \DOMXPath( $dom );
$elements = $xpath->query( '//*' );
// Iterate over elements and modify based on text content
foreach ( $elements as $element ) {
$field_names_for_popover = array();
$top_level_text = '';
// phpcs:ignore WordPress.NamingConventions.ValidVariableName
if ( empty( $element->childNodes ) ) {
continue;
}
// Loop through the child nodes of the current element
// phpcs:ignore WordPress.NamingConventions.ValidVariableName
foreach ( $element->childNodes as $child ) {
// Check if the child node is a text node
// phpcs:ignore WordPress.NamingConventions.ValidVariableName
if ( $child->nodeType === XML_TEXT_NODE ) {
// phpcs:ignore WordPress.NamingConventions.ValidVariableName
$top_level_text .= $child->nodeValue;
}
}
$top_level_text = trim( $top_level_text );
if ( ! empty( $top_level_text ) ) {
$acf_field_found = false;
// Loop through each field used in this render template.
foreach ( $acf_fields_used_in_block_render_template as $key => $field_data ) {
if ( ! $field_data['name'] ) {
continue;
}
// If the value for this field matches the text in the dom, apply the inline editing attributes.
if ( $field_data['value'] === $top_level_text ) {
$acf_field_found = true;
$field_slug = $field_data['name'];
$field_value = $field_data['value'];
$field_type = $field_data['type'];
$field_placeholder_text = ! empty( $field_data['placeholder'] ) ? $field_data['placeholder'] : __( 'Type to edit...', 'acf' );
if ( ! in_array( $field_type, $non_auto_inline_editing_fields, true ) ) {
if ( in_array( $field_type, $allowed_contenteditable_field_types, true ) ) {
// Add the contenteditable things.
if ( ! $element->getAttribute( 'data-acf-inline-contenteditable' ) ) {
$element->setAttribute( 'role', 'button' );
$element->setAttribute( 'data-acf-inline-contenteditable', true );
$element->setAttribute( 'data-acf-inline-contenteditable-field-slug', str_replace( 'acf_auto_inline_editing_field_name_', '', $field_slug ) );
$element->setAttribute( 'data-acf-placeholder', $field_placeholder_text );
}
// phpcs:ignore WordPress.NamingConventions.ValidVariableName
if ( $field_value !== 'acf_auto_inline_editing_field_name_' . $field_slug ) {
// phpcs:ignore WordPress.NamingConventions.ValidVariableName
$element->nodeValue = $field_value;
} else {
// phpcs:ignore WordPress.NamingConventions.ValidVariableName
$element->nodeValue = '';
}
} else {
// Make the field popover instead of contenteditable.
$field_names_for_popover[] = str_replace( 'acf_auto_inline_editing_field_name_', '', $field_slug );
}
}
// We found a matching field so we can stop looping.
break;
}
}
if ( ! $acf_field_found ) {
foreach ( $acf_fields_used_in_block_render_template as $key => $field_data ) {
// Remove the acf_auto_inline_editing_field_name_ placeholder from the text node.
if ( strpos( $top_level_text, 'acf_auto_inline_editing_field_name_' . $field_data['name'] ) !== false ) {
// phpcs:ignore WordPress.NamingConventions.ValidVariableName
$element->nodeValue = str_replace( 'acf_auto_inline_editing_field_name_' . $field_data['name'], '', $top_level_text );
}
}
}
}
// If the value for this field matches the field slug, remove it.
// phpcs:ignore WordPress.NamingConventions.ValidVariableName
if ( strpos( $top_level_text, 'acf_auto_inline_editing_field_name_' ) === 0 ) {
// phpcs:ignore WordPress.NamingConventions.ValidVariableName
$element->textContent = '';
}
// Loop over each attribute. If an attribute comes from acf, make it popup when parent is selected.
foreach ( $element->attributes as $attribute ) {
if ( $attribute->name === 'data-acf-inline-contenteditable-field-slug' ) {
continue;
}
$attribute_value = trim( $attribute->value );
foreach ( $acf_fields_used_in_block_render_template as $field_data ) {
if ( empty( $field_data['name'] ) ) {
continue;
}
$field_slug = $field_data['name'];
$field_value = $field_data['value'];
if ( ! is_array( $field_value ) && $attribute_value === $field_value ) {
$field_names_for_popover[] = str_replace( 'acf_auto_inline_editing_field_name_', '', $field_slug );
}
if ( strpos( $attribute_value, 'acf_auto_inline_editing_field_name_' ) !== false ) {
$attribute_value = str_replace( 'acf_auto_inline_editing_field_name_' . $field_slug, '', $attribute_value );
$element->setAttribute( $attribute->name, $attribute_value );
}
}
}
$field_names_for_popover = array_unique( $field_names_for_popover );
// Don't add popover fields to the top level element unless it has text content (as opposed to html/non-text content, which is what most top level elements contain).
// phpcs:ignore WordPress.NamingConventions.ValidVariableName
$is_top_level = isset( $element->parentNode->tagName ) && $element->parentNode->tagName === 'body';
if ( ! $is_top_level && ! empty( $field_names_for_popover ) ) {
$preexisting_inline_fields_uid = $element->getAttribute( 'data-acf-inline-fields-uid' );
if ( ! $preexisting_inline_fields_uid ) {
$element->setAttribute( 'data-acf-inline-fields-uid', implode( '__', $field_names_for_popover ) . '__' . $block['id'] );
$element->setAttribute(
'data-acf-inline-fields',
wp_json_encode( $field_names_for_popover ),
);
}
}
}
// phpcs:ignore WordPress.NamingConventions.ValidVariableName
$dom->preserveWhiteSpace = true;
// phpcs:ignore WordPress.NamingConventions.ValidVariableName
$dom->formatOutput = false;
return str_replace( '<meta charset="UTF-8">', '', $dom->saveHTML() );
}