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

Add service for entity registrant detection #6682

Conversation

dhaval-parekh
Copy link
Collaborator

@dhaval-parekh dhaval-parekh commented Nov 3, 2021

Summary

Fixes #6516

This PR adds new services "EntityRegistrantDetection", which detect the function which registers new entities such as post type, taxonomy, shortcode or block. And provide that info via REST endpoint.

Sample REST response.

{
	"post_types":{
		"product":{
			"name":"Products",
			"slug":"product",
			"description":"This is where you can browse products in this store.",
			"hierarchical":false,
			"source":{
				"type":"plugin",
				"name":"woocommerce",
				"file":"includes\/class-wc-post-types.php",
				"line":286,
				"function":"WC_Post_Types::register_post_types",
				"hook":"init",
				"priority":5
			}
		},
	},
	"taxonomies":{
		"product_type":{
			"name":"Product type",
			"slug":"product_type",
			"description":"",
			"hierarchical":false,
			"source":{
				"type":"plugin",
				"name":"woocommerce",
				"file":"includes\/class-wc-post-types.php",
				"line":37,
				"function":"WC_Post_Types::register_taxonomies",
				"hook":"init",
				"priority":5
			}
		},
	},
	"blocks":{
		"woocommerce\/product-summary":{
			"name":"woocommerce\/product-summary",
			"title":"woocommerce\/product-summary",
			"description":"",
			"category":null,
			"attributes":[
				
			],
			"is_dynamic":true,
			"source":{
				"type":"plugin",
				"name":"woocommerce",
				"file":"packages\/woocommerce-blocks\/src\/BlockTypesController.php",
				"line":57,
				"function":"Automattic\\WooCommerce\\Blocks\\BlockTypesController::register_blocks",
				"hook":"init",
				"priority":10
			}
		},
	},
	"shortcodes":{
		"product":{
			"tag":"product",
			"source":{
				"type":"plugin",
				"name":"woocommerce",
				"file":"includes\/class-wc-shortcodes.php",
				"line":19,
				"function":"WC_Shortcodes::init",
				"hook":"init",
				"priority":10
			}
		},
	}
}

Checklist

  • My code is tested and passes existing tests.
  • My code follows the Engineering Guidelines (updates are often made to the guidelines, check it out periodically).

@dhaval-parekh dhaval-parekh marked this pull request as ready for review November 10, 2021 14:27
@github-actions
Copy link
Contributor

github-actions bot commented Nov 10, 2021

Plugin builds for b9aea83 are ready 🛎️!

@westonruter westonruter added this to the v2.2 milestone Nov 12, 2021
src/EntityRegistrantDetection/RestController.php Outdated Show resolved Hide resolved
src/EntityRegistrantDetection/CallbackWrapper.php Outdated Show resolved Hide resolved
* @type array $shortcode List of default shortcode.
* ]
*/
const DEFAULT_ENTITIES = [
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of storing this here, I think it would be better to have a $initial_entities variable which is null to begin with, then when the callback wrapper is invoked it can check if $this->initial_entities === null, and of so, populate the initial array with what is registered.

Nevertheless, I wonder if it is necessary? If we capture all of the registered entities at prepare and then diff them with what is registered at finalize, why do we need to also need the default entities?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of storing this here, I think it would be better to have a $initial_entities variable which is null to begin with, then when the callback wrapper is invoked it can check if $this->initial_entities === null, and of so, populate the initial array with what is registered.

Currently, We are doing the same but with $registered_entities. In prepare(), we collect all registered entities and in finalize() we update the same property with a difference of registered entities.

Nevertheless, I wonder if it is necessary? If we capture all of the registered entities at prepare and then diff them with what is registered at finalize(), why do we need to also need the default entities?

Since We are checking all the callbacks from all hooks. It will also track the WordPress default functions which registers default entities. which I think is unnecessary to track. (Since the idea to detect if any theme/plugin is registering entities or not) and will increase the REST API payload.
So to exclude WordPress default entities in finalize() this const is being used.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry I haven't been able to respond to this yet. I'll have to dig more deeply into the PR and its changes in order to be able to reply. That'll have to come next week.

src/EntityRegistrantDetection/CallbackWrapper.php Outdated Show resolved Hide resolved
src/EntityRegistrantDetection/CallbackWrapper.php Outdated Show resolved Hide resolved
src/EntityRegistrantDetection/RestController.php Outdated Show resolved Hide resolved
@milindmore22
Copy link
Collaborator

PHP Warning: hash_equals(): Expected known_string to be a string, null given in /srv/www/amp-local/public_html/wp-content/plugins/amp/src/EntityRegistrantDetection/EntityRegistrantDetectionManager.php on line 109

@dhaval-parekh dhaval-parekh force-pushed the enhancement/6516-rest-endpoint-for-registered-entities branch from 9ba9773 to 0e5aa72 Compare November 16, 2021 18:28
@dhaval-parekh
Copy link
Collaborator Author

PHP Warning: hash_equals(): Expected known_string to be a string, null given in /srv/www/amp-local/public_html/wp-content/plugins/amp/src/EntityRegistrantDetection/EntityRegistrantDetectionManager.php on line 109

I have addressed this in 0e5aa72 commit.

@dhaval-parekh dhaval-parekh force-pushed the enhancement/6516-rest-endpoint-for-registered-entities branch from 0e5aa72 to 20f4291 Compare November 23, 2021 09:18
Comment on lines 207 to 210
$result = call_user_func_array(
$this->get_callback_function(),
array_slice( $args, 0, (int) $this->callback['accepted_args'] )
);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason why the outdated and slow call_user_func_array() is used here?
This could be rewritten to use a faster variadic arguments call:

Suggested change
$result = call_user_func_array(
$this->get_callback_function(),
array_slice( $args, 0, (int) $this->callback['accepted_args'] )
);
$callback = $this->get_callback_function();
$result = $callback( ... array_slice( $args, 0, (int) $this->callback['accepted_args'] ));

Note that it cannot be done as a one-liner because of PHP 5.6 parsing.

*/
protected function wrapped_callback( $callback ) {

return $this->injector->make( CallbackWrapper::class, compact( 'callback' ) );
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Injecting the injector should always be avoided whenever possible. There are two viable options for doing so here:

If CallbackWrapper is considered a service or similar:

Instead of injecting the injector (and hence, giving control to the object of the entire rest of the application), it would be preferable to inject a CallbackWrapperFactory instead which is specialized on directly instantiating instances of type CallbackWrapper.

Using a factory is always a valid way of decoupling a new call, as the injector can override the factory implementation if needed.

If CallbackWrapper is considered a Value Object:

If we consider CallbackWrapper to be a value object conceptually (which is a bit far-fetched but not entirely wrong), then it would mean we can freely new that value object directly, instead of having it be instantiated via the injector.

@westonruter westonruter removed this from the v2.2 milestone Nov 30, 2021
@westonruter westonruter added this to the v2.3 milestone Nov 30, 2021
@westonruter westonruter removed this from the v2.3 milestone Apr 14, 2022
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

Successfully merging this pull request may close these issues.

Add endpoint that lists out the entities registered by each theme/plugin
4 participants