DEV Community

Cover image for My plugin passed every check. It still didn't work.
Eugeniya Ivanova
Eugeniya Ivanova

Posted on

My plugin passed every check. It still didn't work.

We built a WordPress plugin. The idea was simple: you publish a post on your blog, and a couple of minutes later an announcement goes out to your social networks automatically. Headline, image, link. About two thousand lines of code. A small project, I thought.

I should probably mention that I don't write the code myself. Claude does. My contribution is asking questions, testing things and occasionally refusing to accept an answer because something about it bothers me. This turned out to be one of those occasions.

Before submitting, we went through all the checks. phpcs against the WordPress coding standards: zero errors, zero warnings. The official Plugin Check: clean. WordPress directory review: approved. The plugin was published, and I was quite pleased with us.

Then I installed it on an actual WordPress site. It didn't work.

The green checkmarks were checking the wrong thing

Here's the embarrassing part: before submitting, we'd never actually run the plugin in WordPress. We'd tried, but our local environment wouldn't start. WP-CLI kept crashing with the latest PHP version, and instead of sorting that out, we carried on with static checks.

The WordPress directory review checks whether a plugin follows the rules and meets security requirements. It doesn't mean somebody has tested whether your particular publishing workflow works. I understood this perfectly well in theory. In practice, I saw all those green checkmarks and decided we were finished.

Eventually, we got the plugin running in WordPress Playground, which runs WordPress through WebAssembly without needing a traditional local server. It took one command to start. On the first proper test, we found two bugs.

Bug one: the Connect button led nowhere

You click Connect, expecting to reach the Publora sign-in page, and WordPress sends you straight back to the admin dashboard. No error, no warning. You're just back where you started.

The problem was wp_safe_redirect(). We'd used it because, well, it has safe in the name. Unfortunately, it also restricts redirects to approved hosts. Our sign-in page lives on another domain, so WordPress replaced the destination with the admin URL.

The function was doing exactly what it was supposed to do. We were the ones asking it to do the wrong thing.

The fix was to allow the Publora authentication host for that particular redirect:

add_filter('allowed_redirect_hosts', [$this, 'allow_auth_host']);
wp_safe_redirect($url, 302, 'Publora');
Enter fullscreen mode Exit fullscreen mode

Nothing here looked suspicious to the static analyzer. The code was valid, the redirect was safe, and the Connect button was completely useless.

Bug two: the editor kept losing the image

The second problem was harder to spot. When publishing from Gutenberg, the social announcement sometimes went out without the featured image. It also ignored the post settings: whether to share the post at all, which networks to use, and so on.

We'd attached publishing to the transition_post_status hook. When a post changes to publish, send the announcement. That seemed reasonable.

Except Gutenberg doesn't necessarily save everything in one request. The post status can change before the featured image and some settings have finished saving. The old metabox can send its data separately too. Our hook fired, we read whatever was available at that moment, and sent it off to social. Which, often enough, was nothing.

The plugin wasn't losing the image. We were asking for it before it had arrived.

We moved the publishing logic to wp_after_insert_post, where we could work with the saved post data, and added a check to avoid sending an announcement when an already-published post was updated:

if ($post_before instanceof WP_Post && 'publish' === $post_before->post_status) return;
Enter fullscreen mode Exit fullscreen mode

Neither bug had anything to do with syntax or coding standards. We needed to see how WordPress actually behaved: where it redirected users, when Gutenberg saved its data, and which hooks fired along the way.

And now, how we dug them up in the first place

This is probably my favourite part of the story, although I wasn't enjoying it quite so much at the time.

When we discovered the plugin wasn't working, Claude suggested contacting WordPress directory support. They know the platform, they could help us investigate, and we'd already passed review. A reasonable suggestion.

I didn't want to do that yet.

Partly because I hate waiting for support replies, and partly because we hadn't even managed to run the thing properly ourselves. It seemed a little early to ask somebody else why it was broken.

So I asked Claude to go back through the documentation and help me set up a working test environment. We opened Playground and started trying things. Publish with an image. Publish without one. Disable sharing. Select Mastodon only. Try the classic editor. Watch what happens, check the logs, change something and try again.

By the end of the evening, we'd found both bugs and fixed them. No support tickets, no waiting for somebody to investigate. Just us, WordPress and a rather overdue first proper test.

I still can't read PHP nearly as well as Claude. When it shows me a function, I often need an explanation of what I'm looking at. But I can tell when we're trying to get around a problem instead of understanding it. And sometimes I can be sufficiently stubborn about that to make us investigate.

This was one of those times. Claude did the technical work, and I contributed a firm refusal to send an email. An unexpectedly useful division of labour.

What I took from it

I knew static checks weren't the same as testing a working plugin. I really did. I just apparently needed to publish one before remembering.

The other thing that stayed with me was how close we came to asking support for help with two bugs we hadn't even tried to reproduce properly. There are plenty of problems where support is exactly what you need. This wasn't one of them.

And I'm glad I pushed back on Claude's suggestion. Not because Claude was wrong to offer it, but because I would have learned very little from sending that email and waiting for somebody else to find the problem.

If you're building a WordPress plugin, I'd recommend running it in Playground before submitting it. We spent longer getting our broken local environment to cooperate than it took to find both bugs once WordPress was actually running.

The plugin passed review. The Connect button still sent me back to the dashboard. I think I'll remember that particular combination for a while.


Anyone else had something pass every check and then fail the first time you actually used it?

Top comments (0)