Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fatal error: Uncaught Error: Unknown format specifier "A" #1503

Open
M4N0JKUM4R opened this issue Nov 22, 2023 · 8 comments
Open

Fatal error: Uncaught Error: Unknown format specifier "A" #1503

M4N0JKUM4R opened this issue Nov 22, 2023 · 8 comments

Comments

@M4N0JKUM4R
Copy link

Hey devs,

I am working on a client's site and when I try to redirect from the Google sign-in page there is a code added to the URL. The site is using PHP 8.0+.

The plugin creates an error and the page does not load. What is a good solution? I guess it is because there is a conflict between the CMB form submission and the Google authentication code.

image

The function that it points to Line 344 is printf( $format_parts[0], esc_attr( $cmb->cmb_id ), esc_attr( $object_id ) );

/**
 * Display a metabox form & save it on submission
 *
 * @since  1.0.0
 * @param  mixed      $meta_box  Metabox config array or Metabox ID.
 * @param  int|string $object_id Object ID (string for options-page).
 * @param  array $args           Optional arguments array.
 */
function cmb2_print_metabox_form( $meta_box, $object_id = 0, $args = array() ) {

    $object_id = $object_id ? $object_id : get_the_ID();
    $cmb = cmb2_get_metabox( $meta_box, $object_id );

    // if passing a metabox ID, and that ID was not found.
    if ( ! $cmb ) {
	    return;
    }

    $args = wp_parse_args( $args, array(
	    'form_format' => '<form class="cmb-form" method="post" id="%1$s" enctype="multipart/form-data" encoding="multipart/form-data"><input type="hidden" name="object_id" value="%2$s">%3$s<input type="submit" name="submit-cmb" value="%4$s" class="button-primary"></form>',
	    'save_button' => esc_html__( 'Save', 'cmb2' ),
	    'object_type' => $cmb->mb_object_type(),
	    'cmb_styles'  => $cmb->prop( 'cmb_styles' ),
	    'enqueue_js'  => $cmb->prop( 'enqueue_js' ),
    ) );

    // Set object type explicitly (rather than trying to guess from context).
    $cmb->object_type( $args['object_type'] );

    // Save the metabox if it's been submitted
    // check permissions
    // @todo more hardening?
    if (
	    $cmb->prop( 'save_fields' )
	    // check nonce.
	    && isset( $_POST['submit-cmb'], $_POST['object_id'], $_POST[ $cmb->nonce() ] )
	    && wp_verify_nonce( $_POST[ $cmb->nonce() ], $cmb->nonce() )
	    && $object_id && $_POST['object_id'] == $object_id
    ) {
	    $cmb->save_fields( $object_id, $cmb->object_type(), $_POST );
    }

    // Enqueue JS/CSS.
    if ( $args['cmb_styles'] ) {
	    CMB2_Hookup::enqueue_cmb_css();
    }

    if ( $args['enqueue_js'] ) {
	    CMB2_Hookup::enqueue_cmb_js();
    }

    $form_format = apply_filters( 'cmb2_get_metabox_form_format', $args['form_format'], $object_id, $cmb );

    $format_parts = explode( '%3$s', $form_format );

    // Show cmb form.
    printf( $format_parts[0], esc_attr( $cmb->cmb_id ), esc_attr( $object_id ) );
    $cmb->show_form();

    if ( isset( $format_parts[1] ) && $format_parts[1] ) {
	    printf( str_ireplace( '%4$s', '%1$s', $format_parts[1] ), esc_attr( $args['save_button'] ) );
    }

}
@tw2113
Copy link
Contributor

tw2113 commented Nov 22, 2023

I wonder what's coming in as parto f the format_parts array that's coming from the $args['form_format'] on line 339.

@M4N0JKUM4R
Copy link
Author

I wonder what's coming in as parto f the format_parts array that's coming from the $args['form_format'] on line 339.

I guess after Google redirects the page URL:

https://website/profile/?code=big_code&scope=email+profile+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email+openid&authuser=1&prompt=consent

The CMB checks for the submission values. Is there a way to skip that? or do I need to disable the plugin? When I comment out the 344 line, there is no error and the page is displayed.

@jtsternberg
Copy link
Member

cmb2_print_metabox_form takes an array of $args as the third param and form_format is one of those args. So first place to check is what's being passed in in the $args array. 2nd place it's getting modified is via the cmb2_get_metabox_form_format filter, so probably check if $form_format is different than $args['form_format'] after that filter to see if something is filtering it and causing the format to break.

@M4N0JKUM4R
Copy link
Author

cmb2_print_metabox_form takes an array of $args as the third param and form_format is one of those args. So first place to check is what's being passed in in the $args array. 2nd place it's getting modified is via the cmb2_get_metabox_form_format filter, so probably check if $form_format is different than $args['form_format'] after that filter to see if something is filtering it and causing the format to break.

Thanks for the answer but I don't want cmb2 form to interfere with the Google-authenticated redirect. I have never worked with cmb2 before, is there a way I can fix that apart from disabling it? Since the client is using a theme dependent on CMB2.

@jtsternberg
Copy link
Member

jtsternberg commented Nov 22, 2023

I don't want cmb2 form to interfere

There's nothing in the CMB2 code causing this. My comment was explaining the ways our code is used and the ways it could be being used incorrectly.
Can you provide us w/ the code that's in wp-content/themes/freeio-child/template-jobs/misc/profile-form.php?

@M4N0JKUM4R
Copy link
Author

M4N0JKUM4R commented Nov 23, 2023

Can you provide us w/ the code that's in wp-content/themes/freeio-child/template-jobs/misc/profile-form.php?

Yeah, sure.

<?php
if ( ! defined( 'ABSPATH' ) ) {
	exit;
}
wp_enqueue_style( 'dashicons' );

?>
<div class="profile-form-wrapper box-dashboard-wrapper">

	<div class="edit-profile-section">
		<h3 class="title"><?php esc_html_e('Edit Profile','freeio') ?></h3>
		<div class="social-login">
			
			<div class="youtube-login-container login-container">
				<?php echo do_shortcode( '[eroyalties-youtube-login]' ); ?>
			</div>
			
			<div class="facebook-login-container login-container">
					<?php echo do_shortcode( '[eroyalties-facebook-login]' ); ?>
			</div>
			
			<div class="tiktok-login-container login-container">
				<?php echo do_shortcode( '[eroyalties-tiktok-login]' ); ?>
			</div>

		</div>
	</div>

	<?php
		if ( WP_Freeio_User::is_freelancer() ) {
			$post_status =  get_post_status($post_id);
			if ( $post_status == 'pending' || $post_status == 'pending_approve' ) {
				?>
				<div class="alert alert-danger"><?php esc_html_e('Your resume has to be confirmed by an administrator before publish.', 'freeio'); ?></div>
				<?php
				do_action('wp-freeio-resume-form-status-pending', $post_status, $post_id);
			} elseif ( $post_status == 'expired' ) {
				?>
				<div class="alert alert-danger"><?php esc_html_e('Your resume has expired.', 'freeio'); ?></div>
				<?php
				do_action('wp-freeio-resume-form-status-expired', $post_status, $post_id);
			}

			do_action('wp-freeio-resume-form-status', $post_status, $post_id);
		}
		if ( ! empty( $_SESSION['messages'] ) ) : ?>
		<div class="inner-list">
			<ul class="messages">
				<?php foreach ( $_SESSION['messages'] as $message ) { ?>
					<?php
					$status = !empty( $message[0] ) ? $message[0] : 'success';
					if ( !empty( $message[1] ) ) {
					?>
					<li class="message_line <?php echo esc_attr( $status ) ?>">
						<?php echo trim( $message[1] ); ?>
					</li>
				<?php
					}
				}
				unset( $_SESSION['messages'] );
				?>
			</ul>
		</div>
	<?php endif; ?>

	<?php
		echo cmb2_get_metabox_form( $metaboxes_form, $post_id, array(
			'form_format' => '<form action="' . esc_url(WP_Freeio_Mixes::get_full_current_url()) . '" class="cmb-form" method="post" id="%1$s" enctype="multipart/form-data" encoding="multipart/form-data"><input type="hidden" name="object_id" value="%2$s">%3$s
			<div class="submit-button-wrapper"><button type="submit" name="submit-cmb-profile" value="%4$s" class="btn btn-theme btn-inverse">%4$s <i class="flaticon-right-up next"></i></button></div></form>',
			'save_button' => esc_html__( 'Save Profile', 'freeio' ),
		) );
	?>
</div>

@jtsternberg
Copy link
Member

jtsternberg commented Nov 23, 2023

Yah, the issue is in the line:

'form_format' => '<form action="' . esc_url(WP_Freeio_Mixes::get_full_current_url()) . '" …

In the default form_format, we do not set the action at all. But here, they are setting it to the current url, and the current url contains some characters which look like PHP format specifiers, but are actually not (e.g. %3A). Your best bet is to contact the theme author to issue a fix for the action url they are using. I don't know why/how they use the action param, but they may be able to simply omit it to fix this.

If that's not an option, you can use this code to "fix" the action url:

add_filter( 'cmb2_get_metabox_form_format', function( $form_format ) {
	if ( ! isset( $_GET['code'] ) ) {
		return $form_format;
	}

	$parts = explode( 'action="', $form_format, 2 );
	$before = $parts[0] . 'action="';
	$parts = explode( '"', $parts[1], 2 );
	// Remove the query args from the action URL.
	$url = explode( '?', $parts[0], 2 )[0];
	$after = '"' . $parts[1];

	return $before . esc_url( $url ) . $after;

	return $form_format;
} );

@M4N0JKUM4R
Copy link
Author

Thanks, @jtsternberg You are a star. Much appreciated!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants