Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
2 changes: 1 addition & 1 deletion src/Boot/Scheduler.php
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,7 @@ private static function load( ContainerInterface $container ): void {
*/
private static function report_a_step_that_threw( string $step, string $consequence, Throwable $thrown ): void {
self::report_error(
self::class,
self::class . '::report_a_step_that_threw',
sprintf( 'The %s threw, so %s: %s', $step, $consequence, $thrown->getMessage() )
);
}
Expand Down
2 changes: 1 addition & 1 deletion src/Conflict/Resolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ public function resolve_all(): void {
// failure a host is likeliest to hear about as "the site is broken", and on a
// production site the developer channel says nothing at all.
self::report_error(
self::class,
self::class . '::resolve_all',
sprintf(
'The conflict for "%s" threw while being resolved, so it was abandoned: %s',
$sub_plugin->get_slug(),
Expand Down
6 changes: 3 additions & 3 deletions src/Loader.php
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ public function load_all(): void {
$this->load( $sub_plugin );
} catch ( Throwable $thrown ) {
self::report_error(
self::class,
self::class . '::load_all',
sprintf(
'The sub-plugin "%s" threw while loading, so it was abandoned: %s',
$sub_plugin->get_slug(),
Expand Down Expand Up @@ -168,7 +168,7 @@ private function load( Sub_Plugin $sub_plugin ): void {
// what anything watching `skipped` is counting. A host listening to both sees this one
// twice, and that is said plainly in the docs rather than solved by picking one.
self::report_error(
self::class,
self::class . '::load',
sprintf(
'The bundled plugin file for "%s" is missing or unreadable: %s',
$sub_plugin->get_slug(),
Expand Down Expand Up @@ -263,7 +263,7 @@ private function announce( string $hook, array $arguments, Sub_Plugin $sub_plugi
do_action_ref_array( $hook, $arguments );
} catch ( Throwable $thrown ) {
self::report_error(
self::class,
self::class . '::announce',
sprintf(
'A listener on %s threw, and was abandoned: %s',
$hook,
Expand Down
2 changes: 1 addition & 1 deletion src/Registry/Reader.php
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ protected function flush(): void {
// listener is being told which object was thrown away, and the one already in the
// registrar is readable from every other path there is.
self::report_error(
self::class,
self::class . '::flush',
sprintf(
'%1$s The registration already held was kept; %2$s was discarded.',
$exception->getMessage(),
Expand Down
2 changes: 1 addition & 1 deletion src/Traits/Guards_Hook_Prefix.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ private static function has_hook_prefix(): bool {
try {
Config::get_hook_prefix();
} catch ( Config_Exception $exception ) {
self::report_error( self::class, $exception->getMessage() );
self::report_error( self::class . '::has_hook_prefix', $exception->getMessage() );

return false;
}
Expand Down
14 changes: 12 additions & 2 deletions src/Traits/Reports_Errors.php
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,19 @@ trait Reports_Errors {
* `catch` around it would turn every assertion about a report this library makes into a silent
* pass.
*
* `$function` is always `Class::method`, never a bare class name. WordPress prints it as
* "Function %s was called incorrectly", so it is the only part of a report that says where in this
* library the sentence came from — and a class alone cannot separate two of them, which is exactly
* what the facade needs, where `render_notices()` and `filter_activation_error_markup()` are both
* static trampolines reporting under the same name. Normally that is `self::class` joined to the
* method the report is made from; where the mistake is in a call the host made, it names that call
* instead, as the too-late boot names `Absorber::boot`. `self::class` rather than `__METHOD__`,
* because two traits report through here and `__METHOD__` inside a trait names the trait rather
* than the class using it.
*
* @since 1.0.0
*
* @param string $function Member the mistake is reported against, as
* @param string $function Member the mistake is reported against, `Class::method`, as
* `_doing_it_wrong()` takes it.
* @param string $message What went wrong, in the words the developer needs.
* @param Sub_Plugin|null $sub_plugin Sub-plugin the failure belongs to, where it belongs to one.
Expand Down Expand Up @@ -80,7 +90,7 @@ private static function report_error( string $function, string $message, ?Sub_Pl
// out -- from inside `plugins_loaded`, on every request. The developer channel is the one
// that cannot be broken by whatever is on the hook.
_doing_it_wrong(
self::class,
self::class . '::report_error',
sprintf(
'A listener on %s threw, and was abandoned: %s',
$hook,
Expand Down
10 changes: 10 additions & 0 deletions tests/_support/Traits/WithIncorrectUsage.php
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,16 @@ protected function assert_the_library_reported_incorrect_usage(): void {
$report,
'The report has to name this library, or the host goes looking in WordPress.'
);

// The member, not just the class. Which method reported is the only thing separating two
// reports from the same class -- the facade makes two, from separate trampolines -- and
// pinning the shape rather than the name is what keeps this assertion loose enough to
// survive a rename while still refusing a bare class name.
$this->assertStringContainsString(
'::',
$report,
'The report has to name the member it was made from, not just the class.'
);
}
}

Expand Down
Loading