@@ -314,25 +314,72 @@ function rewrite_wp_config_to_define_constants( $content, $constants = array() )
314314
315315 // Add any constants that weren't found in the file
316316 if ( count( $constants ) ) {
317- $prepend = array(
318- "<?php \n",
319- );
320- foreach ( $constants as $name => $value ) {
321- $prepend = array_merge(
322- $prepend,
323- array(
324- 'define(',
325- var_export( $name, true ),
326- ',',
327- var_export( $value, true ),
328- ");\n",
329- )
330- );
317+ // First try to find the "That's all, stop editing!" comment.
318+ $anchor = find_first_token_index( $output, T_COMMENT, "That's all, stop editing!" );
319+
320+ // If not found, try the "Absolute path to the WordPress directory." doc comment.
321+ if ( null === $anchor ) {
322+ $anchor = find_first_token_index( $output, T_DOC_COMMENT, "Absolute path to the WordPress directory." );
323+ }
324+
325+ // If not found, try the "Sets up WordPress vars and included files." doc comment.
326+ if ( null === $anchor ) {
327+ $anchor = find_first_token_index( $output, T_DOC_COMMENT, "Sets up WordPress vars and included files." );
328+ }
329+
330+ // If not found, try "require_once ABSPATH . 'wp-settings.php';".
331+ if ( null === $anchor ) {
332+ $require_anchor = find_first_token_index( $output, T_REQUIRE_ONCE );
333+ if ( null !== $require_anchor ) {
334+ $abspath = $output[$require_anchor + 2] ?? null;
335+ $path = $output[$require_anchor + 6] ?? null;
336+ if (
337+ ( is_array( $abspath ) && $abspath[1] === 'ABSPATH' )
338+ && ( is_array( $path ) && $path[1] === "'wp-settings.php'" )
339+ ) {
340+ $anchor = $require_anchor;
341+ }
342+ }
343+ }
344+
345+ // If not found, fall back to the PHP opening tag.
346+ if ( null === $anchor ) {
347+ $open_tag_anchor = find_first_token_index( $output, T_OPEN_TAG );
348+ if ( null !== $open_tag_anchor ) {
349+ $anchor = $open_tag_anchor + 1;
350+ }
351+ }
352+
353+ // If we still don't have an anchor, the file is not a valid PHP file.
354+ if ( null === $anchor ) {
355+ error_log( "Blueprint Error: wp-config.php file is not a valid PHP file." );
356+ exit( 1 );
331357 }
332- $prepend[] = '?>';
333- $output = array_merge(
334- $prepend,
335- $output
358+
359+ // Ensure surrounding newlines when not already present.
360+ $prev = $output[ $anchor - 1 ] ?? null;
361+ $prev = is_array( $prev ) ? $prev[1] : $prev;
362+ $next = $output[ $anchor ] ?? null;
363+ $next = is_array( $next ) ? $next[1] : $next;
364+
365+ $no_prefix = $prev && "\n\n" === substr( $prev, -2 );
366+ $no_suffix = $next && "\n\n" === substr( $next, 0, 2 );
367+
368+ // Add the new constants.
369+ $new_constants = array( "\n" );
370+ foreach ( $constants as $name => $path ) {
371+ $new_constants[] = 'define( ';
372+ $new_constants[] = var_export( $name, true );
373+ $new_constants[] = ', ';
374+ $new_constants[] = var_export( $path, true );
375+ $new_constants[] = " );\n";
376+ }
377+ $new_constants[] = "\n";
378+
379+ $output = array_merge(
380+ array_slice( $output, 0, $anchor ),
381+ $new_constants,
382+ array_slice( $output, $anchor )
336383 );
337384 }
338385
@@ -365,6 +412,23 @@ function skip_whitespace( $tokens ) {
365412 return $output;
366413}
367414
415+ function find_first_token_index( $tokens, $type, $search = null ) {
416+ foreach ( $tokens as $i => $token ) {
417+ if ( ! is_array( $token ) ) {
418+ continue;
419+ }
420+
421+ if ( $type !== $token[0] ) {
422+ continue;
423+ }
424+
425+ if ( null === $search || false !== strpos( $token[1], $search ) ) {
426+ return $i;
427+ }
428+ }
429+ return null;
430+ }
431+
368432$wp_config_path = getenv( "DOCROOT" ) . "/wp-config.php";
369433
370434if ( ! file_exists( $wp_config_path ) ) {
0 commit comments