generator = $generator; } /** * Hooks into the field group screen of ACF and SCF. */ public function register(): void { add_action( 'acf/field_group/admin_head', array( $this, 'add_meta_box' ) ); add_action( 'acf/field_group/admin_enqueue_scripts', array( $this, 'enqueue' ) ); } /** * Whether the current user may see the box: the capability that administers ACF or SCF. * * @return bool */ public static function user_can(): bool { $capability = function_exists( 'acf_get_setting' ) ? acf_get_setting( 'capability' ) : ''; return is_string( $capability ) && '' !== $capability && current_user_can( $capability ); } /** * Adds the box after the Fields and Settings boxes (acf/field_group/admin_head). */ public function add_meta_box(): void { if ( ! self::user_can() ) { return; } add_meta_box( 'awfc-field-code', __( 'Field Code', 'antwork-field-code' ), array( $this, 'render' ), self::POST_TYPE, 'normal', 'high' ); } /** * Scripts and styles (acf/field_group/admin_enqueue_scripts). */ public function enqueue(): void { if ( ! self::user_can() ) { return; } // WordPress's own code editor, read only; false when the user turned syntax highlighting off. $editor = wp_enqueue_code_editor( array( 'type' => 'application/x-httpd-php', 'codemirror' => array( 'readOnly' => true, 'lineNumbers' => true, 'lineWrapping' => true, 'viewportMargin' => 100000, 'indentWithTabs' => true, 'tabSize' => 4, 'styleActiveLine' => false, ), ) ); wp_enqueue_style( self::HANDLE, plugins_url( 'assets/css/field-code.css', PLUGIN_FILE ), array(), VERSION ); wp_enqueue_script( self::HANDLE, plugins_url( 'assets/js/field-code.js', PLUGIN_FILE ), array( 'wp-i18n', 'wp-a11y' ), VERSION, true ); wp_set_script_translations( self::HANDLE, 'antwork-field-code' ); $config = array( 'editor' => $editor ? $editor : false, 'supportUrl' => self::SUPPORT_URL, 'reviewUrl' => self::REVIEW_URL, 'systemInfo' => current_user_can( 'view_site_health_checks' ) ? self::system_info() : '', ); wp_add_inline_script( self::HANDLE, 'window.awfcFieldCode = ' . self::json( $config ) . ';', 'before' ); } /** * Renders the box. * * @param \WP_Post $post Field group post. */ public function render( $post ): void { echo '
' . esc_html__( 'Save the field group to see the code of its fields.', 'antwork-field-code' ) . '
' . esc_html( $line ) . '
'; return; } echo '' . esc_html__( 'Paste in a template of your theme, inside the Loop. Shows the saved field group.', 'antwork-field-code' ) . '
'; echo ''; echo '' . esc_html( $line ) . '
'; } // One reminder per box: under the location line when Antwork Field Code Pro covers the location, otherwise // under the line of each field whose type it covers (one field shows at a time). $location_reminder = self::pro_covers_location( $result['uncovered_rules'] ); if ( $location_reminder ) { self::render_pro_reminder(); } // Without JavaScript: the list of links and the fields one under the other. The script turns them // into a list of fields on the left and the code of the chosen field on the right. echo '%3$s%4$s',
esc_attr( $heading ),
esc_html( self::title( $field ) ),
esc_html( $field['name'] ),
esc_html( self::type_label( $field['type'] ) )
);
if ( null !== $field['code'] ) {
printf(
'',
esc_attr( $heading ),
esc_attr( self::title( $field ) ),
esc_html__( 'Copy', 'antwork-field-code' )
);
}
echo '' . esc_html__( 'This field type is not covered yet.', 'antwork-field-code' ) . '
'; if ( $reminder && self::pro_covers_type( $field['type'] ) ) { self::render_pro_reminder(); } } else { printf( '%2$s',
esc_attr(
sprintf(
/* translators: %s: field label. */
__( 'Code of %s', 'antwork-field-code' ),
self::title( $field )
)
),
esc_html( $field['code'] )
);
}
echo '%1$s
', wp_kses( /* translators: %s: "Antwork Field Code Pro", a link to its page. */ sprintf( esc_html__( 'Covered by %s.', 'antwork-field-code' ), $link ), array( 'a' => array( 'href' => true, 'target' => true, 'rel' => true, ), 'span' => array( 'class' => true ), ) ), esc_html__( 'Dismiss', 'antwork-field-code' ) ); } /** * Label of a field, or its name when it has none. * * @param array $field Field with its code. * @return string */ private static function title( array $field ): string { $label = trim( wp_strip_all_tags( $field['label'] ) ); return '' !== $label ? $label : $field['name']; } /** * Name of a field type, as ACF or SCF shows it; for a type they do not register (Gallery in ACF free, * a type of a plugin that is turned off), its name in words. * * @param string $type Field type. * @return string */ private static function type_label( string $type ): string { if ( function_exists( 'acf_get_field_type' ) ) { $object = acf_get_field_type( $type ); if ( is_object( $object ) && isset( $object->label ) && is_string( $object->label ) && '' !== $object->label ) { return $object->label; } } return ucwords( str_replace( array( '_', '-' ), ' ', $type ) ); } /** * Versions to paste in a support request. Built here, copied by the browser: nothing is sent. * * @return string */ public static function system_info(): string { $lines = array( 'WordPress: ' . get_bloginfo( 'version' ), 'PHP: ' . PHP_VERSION, ); if ( defined( 'ACF_VERSION' ) ) { $name = function_exists( 'acf_get_setting' ) ? (string) acf_get_setting( 'name' ) : ''; $name = '' !== $name ? $name : 'Advanced Custom Fields'; $name .= defined( 'ACF_PRO' ) && ACF_PRO ? ' PRO' : ''; $lines[] = $name . ': ' . ACF_VERSION; } $lines[] = 'Antwork Field Code: ' . VERSION; return implode( "\n", $lines ); } /** * JSON that is safe inside a