@@ -19,8 +19,14 @@ class BlueprintParser {
1919 */
2020 private $ configuration ;
2121
22+ /**
23+ * @var BundleValidator
24+ */
25+ private $ bundle_validator ;
26+
2227 public function __construct ( RunnerConfiguration $ configuration ) {
2328 $ this ->configuration = $ configuration ;
29+ $ this ->bundle_validator = new BundleValidator ( $ configuration );
2430 }
2531
2632 public function parse ( string $ blueprint_string ): Blueprint {
@@ -397,7 +403,7 @@ private function buildThemeStep( $theme ): array {
397403 throw new InvalidArgumentException ( 'Invalid theme reference format in "themes" array. ' );
398404 }
399405
400- $ error = $ this ->validateDataSource ( $ step ['args ' ]['source ' ], ' wp-content/themes/* ' );
406+ $ error = $ this ->bundle_validator -> validate_theme_source ( $ step ['args ' ]['source ' ] );
401407 $ step ['errors ' ] = $ error ? [$ error ] : [];
402408 return $ step ;
403409 }
@@ -417,7 +423,10 @@ private function buildPluginStep( $plugin ): array {
417423 $ plugin = [ 'source ' => $ plugin ];
418424 }
419425
420- $ error = $ this ->validateDataSource ( $ plugin ['source ' ], 'wp-content/plugins/* ' );
426+ $ error = null ;
427+ if ( isset ( $ plugin ['source ' ] ) ) {
428+ $ error = $ this ->bundle_validator ->validate_plugin_source ( $ plugin ['source ' ] );
429+ }
421430 return [
422431 'key ' => 'plugins ' ,
423432 'name ' => 'installPlugin ' ,
@@ -430,7 +439,7 @@ private function buildMediaStep( $media ): array {
430439 $ errors = [];
431440 foreach ( $ media as $ media_def ) {
432441 $ source = is_array ( $ media_def ) ? $ media_def ['source ' ] : $ media_def ;
433- $ error = $ this ->validateDataSource ( $ source, ' wp-content/uploads/* ' );
442+ $ error = $ this ->bundle_validator -> validate_media_source ( $ source );
434443 if ( $ error ) {
435444 $ errors [] = $ error ;
436445 }
@@ -497,7 +506,7 @@ private function buildContentStep( $content ): array {
497506 }
498507
499508 foreach ( $ sources as $ source ) {
500- $ error = $ this ->validateDataSource ( $ source, ' wp-content/content/posts/* ' );
509+ $ error = $ this ->bundle_validator -> validate_content_source ( $ source );
501510 if ( $ error ) {
502511 $ errors [] = $ error ;
503512 }
@@ -522,38 +531,6 @@ private function buildAdditionalStepsAfterExecution( $step_data ): array {
522531 ];
523532 }
524533
525- private function validateDataSource ( string $ source , string $ allowed_pattern ): ?string {
526- if ( 0 === strlen ( $ source ) ) {
527- return 'Source must be a non-empty string. ' ;
528- }
529-
530- // 1. Absolute URL.
531- if ( str_contains ( $ source , ':// ' ) ) {
532- return null ;
533- }
534-
535- // 2. Bundle-relative path.
536- $ byte_1 = $ source [0 ];
537- $ byte_2 = $ source [1 ] ?? null ;
538- if ( str_contains ( $ source , '/ ' ) ) {
539- if ( '/ ' === $ byte_1 ) {
540- $ source = substr ( $ source , 1 );
541- } elseif ( '. ' === $ byte_1 && '/ ' === $ byte_2 ) {
542- $ source = substr ( $ source , 2 );
543- }
544-
545- if ( ! fnmatch ( $ allowed_pattern , $ source ) ) {
546- return sprintf (
547- 'Invalid path "%s". Expected to match "%s". ' ,
548- $ source ,
549- $ allowed_pattern
550- );
551- }
552- }
553-
554- return null ;
555- }
556-
557534 /**
558535 * Detect on which line a top-level JSON key is defined in the input string.
559536 * This is a simple helper that only supports top-level keys in a top-level
0 commit comments