Got distracted testing my own bug, got too into a silly (possible) bug in WordPress

in wordpress •  7 years ago  (edited)

For background, WordPress, which I love, but bless its heart, for some reason still supports PHP 5.2, which hasn't had security support forever. I'm pretty passionate that if WordPress wants to be the serious application platform we all want to claim its become because REST API, than dropping support for PHP5 in core, is an important signal to the developer community that developer experience is going to be prioritized.

Also, I pride myself on really tweaky bug reports and patches. My favorite is the patch I wrote to reduce the loops that run when metadata is saved from 4 to 2. That or some inline documentation updates in \WP_Query.

Also, I'm experimenting with acceptance testing using Ghost Inspector, which is a really cool name for a SaaS. They give you a really simple looking way to record and run acceptance tests and I think using this tool will be easier to set up and maintain then learning/deploying/using Selenium, which I'm sure they are using.

But, this isn't about acceptance testing with Ghost Inspector. I'll report back on that once I figure that out, either here or on Torque. Anyway, this post is about how I registered a widget, inside an an anonymous function, using an anonymous class extending \WP_Widget class included in WordPress core. #ApexClosure

If you're not familiar with older versions of PHP, PHP 5.4 was probably the first version where object-oriented programming made sense, because you could actually use $this in object-context inside of a closure, and also late static bindings -- closures being new to PHP in 5.3 is the key point here.

You can see a simplified version of what I did here: https://gist.github.com/Shelob9/fbc12169c965d77ed37b43256cac7071#file-wp-af-closure-php

And if you're wondering, who does that, I do, I want to have a way to record current Caldera Forms version and WordPress version in the video, so I made a quick widget:
Screenshot from 2017-10-06 19-51-37.png

Yah, that's my Hello Dolly right now. I know anyone reading this from inside the WordPress bubble might be screaming right now that I'm using the wp-admin code editor. While I don't want to encourage this behavior in the spirit of WordPress 4.9, which is making this easier to do, let me just make it clear, I do this shit all the time.

Anyway, off topic - Widget should work, but in the admin area we're getting a warning from this widget:
Screenshot from 2017-10-06 19-48-25.png

Message is Warning: preg_match(): Null byte in regex in /srv/bindings/84ff30a58b1643d3bd9d52e40799fee1/code/wp-admin/includes/widgets.php on line 147

So, problem one with using an anonymous class for a WordPress widget is it creates that warning.

Also, when adding this widget, we get a fun console error - Uncaught Error: Syntax error, unrecognized expression: #widget-17_class@anonymous�

Diamond in a question mark is browser for "I can't decode this shit." This led me to belive -- I later confirmed it by reading source -- that WordPress must be identifying widgets in the DOM by the name of the class that calls them, and then using this identifier as part of the ID attribute of the UI element for adding a new instance of this widget to a sidebar.

So, problem two with using an anonymous class for a WordPress widget is that the unique identifier used will no longer be safe to use as an HTML attribute, which it is. BTW Someone should check the escaping there.
Screenshot from 2017-10-06 20-18-25.png

Finally, problem three with using an anonymous class for a WordPress widget is it doesn't work.

So, what's next? Obviously code review first, make sure I'm not totally full of shit here. If this still feels valid tomorrow, I'll open a new trac ticket. Yes, WordPress uses trac, not Github issues...

And BTW, if you're thinking, hey that's supposed to be a string you're passing to register_widget -- the function that registers widgets, at first glance you'd think you have a strong case. The docs clearly indicate that function argument should be The name of a class that extends WP_Widget IE a string.

Screenshot from 2017-10-06 20-31-07.png

But that function probably -- but who knows because that's assuming the value of a global variable, which is how 26% of the internet works -- is a wrapper for \WP_Widget_Factory::register() which has totally different inline docs that make it clear that, and I quote Either the name of a WP_Widget subclass or an instance of a WP_Widget subclass.

Therefore, unless I'm missing something, I think this is a clear bug as the documentation and the way the program is actually written should allow for any instance of any \WP_Widget subclass, including an anonymous class extending \WP_Widget should work. But the hash_object method of that class is probably broken in this context.

But first, figuring out why my acceptance tests are passing but when I do the clicks myself, I can reproduce the bug in my own software, which actually will get fixed if I can figure this one thing out, which requires me modifying my Hello Dolly plugin to just use a named class #sigh.

I hope someone enjoys my story.

Authors get paid when people like you upvote their post.
If you enjoyed what you read here, create your account today and start earning FREE STEEM!
Sort Order:  

Congratulations @shelob9! You have completed some achievement on Steemit and have been rewarded with new badge(s) :

You published your First Post
You made your First Comment
You got a First Vote
Award for the number of upvotes
You got a First Reply

Click on any badge to view your own Board of Honor on SteemitBoard.
For more information about SteemitBoard, click here

If you no longer want to receive notifications, reply to this comment with the word STOP

By upvoting this notification, you can help all Steemit users. Learn how here!

Thanks bot!