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

fix: prevent fatal errors with DOMHelpers methods by improving typesafety and returning early #257

Merged
merged 7 commits into from
Aug 7, 2024
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/cuddly-yaks-try.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@wpengine/wp-graphql-content-blocks": patch
---

chore: update Composer dev-dependencies and fix resulting issues.
12 changes: 12 additions & 0 deletions .changeset/few-cooks-reflect.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
---
"@wpengine/wp-graphql-content-blocks": minor
---

fix: prevent fatal errors by improving type-safety and returning early when parsing HTML.
The following methods have been deprecated for their stricter-typed counterparts:
- `DOMHelpers::parseAttribute()` => `::parse_attribute()`
- `DOMHelpers::parseFirstNodeAttribute()` => `::parse_first_node_attribute()`
- `DOMHelpers::parseHTML()` => `::parse_html()`
- `DOMHelpers::getElementsFromHTML()` => `::get_elements_from_html()`
- `DOMHelpers::parseText()` => `::parse_text()`
- `DOMHelpers::findNodes()`=> `::find_nodes()`
548 changes: 324 additions & 224 deletions composer.lock

Large diffs are not rendered by default.

67 changes: 34 additions & 33 deletions includes/Blocks/Block.php
Original file line number Diff line number Diff line change
Expand Up @@ -124,11 +124,11 @@ private function register_block_attributes_as_fields(): void {

/**
* Returns the type of the block attribute
*
* @param string $name The block name
* @param object $attribute The block attribute config
* @param string $prefix Current prefix string to use for the get_query_type
*
*
* @param string $name The block name
* @param array<string,mixed> $attribute The block attribute config
* @param string $prefix Current prefix string to use for the get_query_type
*
* @return mixed
*/
private function get_attribute_type( $name, $attribute, $prefix ) {
Expand Down Expand Up @@ -196,9 +196,9 @@ private function get_block_attribute_fields( ?array $block_attributes, string $p
if ( null === $block_attributes ) {
return $fields;
}

foreach ( $block_attributes as $attribute_name => $attribute_config ) {
$graphql_type = self::get_attribute_type( $attribute_name, $attribute_config, $prefix );
$graphql_type = $this->get_attribute_type( $attribute_name, $attribute_config, $prefix );

if ( empty( $graphql_type ) ) {
continue;
Expand All @@ -217,18 +217,18 @@ private function get_block_attribute_fields( ?array $block_attributes, string $p
$attribute_name => $attribute_config,
];
$result = $this->resolve_block_attributes_recursive( $block['attrs'], wp_unslash( render_block( $block ) ), $config );

return $result[ $attribute_name ];
},
];
}//end foreach

return $fields;
}

/**
* Returns the type of the block query attribute
*
*
* @param string $name The block name
* @param array $query The block query config
* @param string $prefix The current prefix string to use for registering the new query attribute type
Expand All @@ -237,7 +237,7 @@ private function get_query_type( string $name, array $query, string $prefix ): s
$type = $prefix . ucfirst( $name );

$fields = $this->create_attributes_fields( $query, $type );

register_graphql_object_type(
$type,
[
Expand All @@ -256,7 +256,7 @@ private function get_query_type( string $name, array $query, string $prefix ): s

/**
* Creates the new attribute fields for query types
*
*
* @param array $attributes The query attributes config
* @param string $prefix The current prefix string to use for registering the new query attribute type
*/
Expand Down Expand Up @@ -289,10 +289,10 @@ private function create_attributes_fields( $attributes, $prefix ): array {

/**
* Normalizes the value of the attribute
*
*
* @param array|string $value The value
* @param string $type The type of the value
*
*
* @return array|string|int|float|bool
*/
private function normalize_attribute_value( $value, $type ) {
Expand Down Expand Up @@ -365,14 +365,17 @@ private function register_type(): void {

/**
* Resolved the value of the block attributes based on the specified config
*
*
* @param array<string,mixed> $attributes The block current attributes value.
* @param string $html The block rendered html.
* @param array<string,mixed> $config The block current attribute configuration, keyed to the attribute name.
*/
private function resolve_block_attributes_recursive( $attributes, string $html, array $config ): array {
$result = [];

// Clean up the html.
$html = trim( $html );

foreach ( $config as $key => $value ) {
// Get default value.
$default = $value['default'] ?? null;
Expand Down Expand Up @@ -424,29 +427,27 @@ private function resolve_block_attributes_recursive( $attributes, string $html,
$result[ $key ] = $attributes[ $key ] ?? $default;
}
}

return $result;
}

/**
* Parses the block content of a source only block type
*
*
* @param string $html The html value
* @param string $source The source type
*
* @return string|null
*/
private function parse_single_source( $html, $source ) {
$value = null;
private function parse_single_source( string $html, $source ): ?string {
if ( empty( $html ) ) {
return $value;
return null;
}

switch ( $source ) {
case 'html':
$value = DOMHelpers::findNodes( $html )->innerHTML();
break;
return DOMHelpers::find_nodes( $html )->innerHTML();
}
return $value;

return null;
}

/**
Expand All @@ -458,15 +459,15 @@ private function parse_single_source( $html, $source ) {
* @param array<string,mixed> $value The value configuration.
*/
private function parse_html_source( string $html, $value ): ?string {
if ( ! isset( $value['selector'] ) ) {
if ( empty( $html ) || ! isset( $value['selector'] ) ) {
return null;
}

$result = DOMHelpers::parseHTML( $html, $value['selector'] );
$result = DOMHelpers::parse_html( $html, $value['selector'] );

// Multiline values are located somewhere else.
if ( isset( $value['multiline'] ) && ! empty( $result ) ) {
$result = DOMHelpers::getElementsFromHTML( $result, $value['multiline'] );
$result = DOMHelpers::get_elements_from_html( $result, $value['multiline'] );
}

return $result;
Expand All @@ -479,11 +480,11 @@ private function parse_html_source( string $html, $value ): ?string {
* @param array<string,mixed> $value The value configuration.
*/
private function parse_attribute_source( string $html, $value ): ?string {
if ( ! isset( $value['selector'] ) || ! isset( $value['attribute'] ) ) {
if ( empty( $html ) || ! isset( $value['selector'] ) || ! isset( $value['attribute'] ) ) {
return null;
}

return DOMHelpers::parseAttribute( $html, $value['selector'], $value['attribute'] );
return DOMHelpers::parse_attribute( $html, $value['selector'], $value['attribute'] );
}

/**
Expand All @@ -497,12 +498,12 @@ private function parse_text_source( string $html, $value ): ?string {
return null;
}

return DOMHelpers::parseText( $html, $value['selector'] );
return DOMHelpers::parse_text( $html, $value['selector'] );
}

/**
* Parses a query source block type.
*
*
* @param string $html The html value.
* @param array<string,mixed> $value The value configuration.
* @param array<string,mixed> $attributes The block attributes.
Expand All @@ -514,7 +515,7 @@ private function parse_query_source( string $html, $value, $attributes ): ?array
return null;
}

$nodes = DOMHelpers::findNodes( $html, $value['selector'] );
$nodes = DOMHelpers::find_nodes( $html, $value['selector'] );

// Coerce nodes to an array if it's not already.
if ( ! is_array( $nodes ) ) {
Expand Down
2 changes: 1 addition & 1 deletion includes/Field/BlockSupports/Anchor.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public static function register(): void {
if ( empty( $rendered_block ) ) {
return null;
}
return DOMHelpers::parseFirstNodeAttribute( $rendered_block, 'id' );
return DOMHelpers::parse_first_node_attribute( $rendered_block, 'id' );
},
],
],
Expand Down
Loading
Loading