 Right, we're going to be talking about leveraging the coding standards to review plugins and teams. But before we do that, I need to get a little feeling of who's in the room, so I know who I'm talking with. So this is me, but who are you? Are you owners of a WordPress block? Are you installers of WordPress? Configurators, team authors, plugin authors, agencies, hardcore developers, anyone who feels left out? Is there anything I haven't mentioned where you're like, oh, but what about me? Just build a website. Yeah? Yeah? Absolutely, absolutely. Right, so once in a while you need to choose a new plugin or need to replace an old plugin or you want a different team and you're like, okay, so this looks good and it seems to do what it's supposed to do, but can I actually trust this code? Is this code where I can reasonably say to my customer, this is safe to use on your website or will their site be hacked because of it? Anyone ever had that idea? Right, I'm going to try and show you some tools how to make your life easier and to automate those kind of queries to just get an impression of how good the code quality of a plugin or a team is. Right, so coding standards, we're going to use coding standards for that. Anyone know what coding standards are? Yeah? Go for it. Describe best practices, what to do and what not to do, what else do you need? There's more, but yeah, that's a very good beginning, absolutely. Coding standards describe how to code, how not to code, best practices, often also code style and do you also know that WordPress has coding standards? You've all seen them. If not, please go and you've got your first homework, go to makewordpress.org slash core and visit the handbook and you can read about the PHP coding standards. You can read about JavaScript coding standards, CSS coding standards, HTML coding standards and the ones I'm talking about today is PHP. Anyone here who's never heard of PHP? I've had, seriously, don't laugh, I've had this. So PHP is a programming language, the programming language in which WordPress has been written and in which all teams and plugins are written as well and they also might use JavaScript and CSS, they generally will output HTML, but PHP is the actual programming language. Now coding standards can do more than just best practices and most of the time they don't actually do best practices, most of the time the main thing they do is code style. Do you have to have wide space on the inside of brackets or not? Do you have an enter in front of brackets or not? That's not so interesting if you're talking about code quality because as long as someone has a consistent code style, that's enough. Whether that code style is PSR2 or the WordPress code style, I'm not interested in as long as they use something consistently. Whether code is documented says something about the professionalism of the developer, but doesn't necessarily say if the code is good or not. So we're going to move those two out and then we're still left with some things. Code smells, things like our errors being silenced, just, you know, okay, I know there's an error there, but I'm just going to ignore it just because I can. That is something which is bad practice. Something like code metrics is code so complex that you cannot test it anymore. If code cannot be automated, the tests for it cannot be automated, then you might get really awkward bugs and not be able to fix them because you can't guarantee that what you have before will still work if you change something. So untestable code is something which is definitely to do with how complex the code is. Best practices, as I said, most of the time, yes, there are industry best practices, there's WordPress best practices, but most of the time they can't be tested automatically. However, the WordPress coding standard has actually got a lot of automated tests for that and they're one of the few leading the fields in automated tests for best practices. Code compatibility. We all know what the minimum supported version for WordPress is for PHP, 5.24. Do you all know what the current version of PHP is? 722, I think, yes, so WordPress is lagging a little behind. So what you get with code compatibility is, okay, I'm now with a web host where my website is running perfectly on PHP 5.4, but everyone is telling me WordPress would run so much faster on PHP 7, so I want to upgrade my site and move it to server where they run PHP 7. But can I do so safely? Will the plugins and the team I have still work on PHP 7? So code compatibility, whether code is compatible with various versions of PHP and various versions of WordPress is also something which is important for code quality and something which can be tested automatically most of the time. You can't test everything automatically, but there are a lot of things we can test. So what I've done is I've created a little project called QA WordPress Projects and I've taken some automated tooling, PHP code snaper as the basis, that's an industry standard for checking code, and built on top of that you have the WordPress coding standard automated tooling and the PHP compatibility automated tooling. They all work with PHP code snaper and I've put them all together and then you have QA WordPress Projects. This is on GitHub, so you can get it from GitHub, you can get it from packages and if those names don't mean anything to you, do not worry, I'll come back to that. Is there anyone here who already says those names didn't mean anything to me? Packages to GitHub? We'll come back to that. So before we start, say you want to select a plugin or a team. How do you go about it? What do you look for? What do you mean by that? Professional organization? Okay, so to replay this for the camera. Basically that there's an organization which demands that the developers work according to certain quality standards. But that's presuming that every plugin or team is written by an organization. Not always, not always. I mean, I'm not an organization, I'm just me. I write plugins too. Okay, so you would look for plugins or teams which are written by an organization because you have more confidence if it's an organization and not just one person. Right, to continue, what other things do we look for? I mean, so how many people have active users does the plugin have? I'm going to repeat it again. Whether the plugin is supported as in it's actually maintained but also if there are support tickets that the actual author responds to them. And whether there are a lot of tickets or not that many tickets doesn't really matter that much because it's more important that you get a response when there are tickets and you look at reviews too, which is good. All of it is good. Thank you. Is it compatible to the current WordPress version and doesn't do what I wanted to do? Thank you. You've basically made my point which I want to make with this slide. Slide which I just added by the way. So basically you do continue doing those things. When you're looking for a plugin to say at a Twitter box, look at the plugins out there. Do the normal review with like is it supported? Is it actively maintained? Is it a plugin which does what I wanted to do? Try two, three, four plugins. And at some point you'll end up with maybe two plugins like these are the short list. I have to now choose between these two. They both do what I want them to do. They both are actively maintained, having an organization behind them or the author response to support tickets. So now what? Yes. Last time updated, actively maintained. That's what I mean by actively maintained. And at the same time some plugins don't need active maintenance. I have some plugins which I never needed to change in four years time. I'll come back to that after the talk or at the end of the talk if there's time. But let's continue for now. But yeah, just testing it on the right version, changing the test it up to that. That's enough. Right, now you've done all that. You've tested the two plugins you end up with like either one of those is going to be. But now I need to look at code quality. See if one of those two stands out as being significantly better than the other. So first you download the plugin and you unzip it, make sure you have it locally somewhere. And it doesn't have to be in a WordPress install. You can just install, download your whole site and scan the whole site, that's fine. But you can also just scan one particular directory in your file system. Then we need to check for the minimum supported WordPress version. This is important because automated scanning needs some information to make a judgment call. If we say, well, yeah, but the minimum supported WordPress version shouldn't go too far back. So anything, any function, WordPress function which was deprecated before WordPress 4.6, that should be, yeah, told off, the developers should be told off for that. But if that plugin still supports WordPress 3.4, it wouldn't be fair to the developer to tell them off for it. So you need to make sure you scan on the right information. So we need to know the minimum supported WordPress version. And you can find that obviously on the WordPress. So you all know this little block of information, obviously. Also take note of the required PHP version if it's there. There's a lot of sites which, a lot of plugins which don't actually mention this yet. It's a new feature to be able to actually post what's the minimum supported PHP version. If it's there, take a note of it. What's even better is knowing where you're going to be deploying your plugins or your website. Knowing the PHP version which is run on your hosting company. How many of you know the PHP version where your sites are running? Nearly all of you, awesome. Okay, I don't have to tell you why it's important. Just make sure you know that version and see that as the minimum. Check what the text domain is, what is used by a plugin. And that's quite easy to check. You do have to open a file, just to read me. And at the top of the read me, every single plugin or team should have, and in the team it might be in the style.css, should have text domain with the name of their text domain. If they do not, the default text domain is the slug of the plugin or the team. So if a plugin is called WordPress importer, the default text domain will be WordPress importer. Make sense? Make a note of that again. Then guess the team or plugin prefixes, and prefixes is complex. Basically if you have a lot of different codes all running in one environment, so you have WordPress and you have 10 plugins and a team, and maybe those plugins have dependencies and pull in some more plugins again. If they use the same names, that can get awkward, because if a plugin calls a variable message, is it my message or is it the message from that other plugin? It's like, okay, how many people are called Jan Janssen in the Netherlands? Or how many people are called Jan Janssen at this very conference? That makes it smaller. So if you have either a class or a namespace or some technical way of making sure that things are local instead of global, instead of accessible to everyone, that's better, except not all developers do that. The best thing you can do when you write a plugin or team is make sure everything is prefix. So everything has your specific name before the actual function name or before the variable name. So you know you only will change your own information and you will only get your own information. Make sense? Everyone understands prefixes? Okay, to find out a prefix, quite often you need to have a quick look at the main plugin file to just get a feel for it. And it will look like this, you see here, the class name starts with WPorg and then a setting starts with WPorg. When you see that kind of prefix at the beginning of various names, then you can presume that's the prefix they've chosen. So often you might need to guess, but often you can sort of tell by just opening one file in the plugin. Without actually needing to read the code, you just need to look at prefix names. So take a note of that. You've got all that, and you're ready to start scanning. So we're going to review with PHP code, Sniffer. Now to do that, we need to install some things. How many of you all have a local test environment with PHP installed? Nearly everyone. Okay, if you don't, have you got one server or some server or one of those installed locally? Then you already have PHP as well. Yes. If you don't, you can still download it. And there's exit files, there's zip files, so it's easy to install. If you run on Mac or Linux, quite often it comes by default with your operating system depending on the version you have on your system. So it shouldn't be that hard to get PHP in your system. Once you have PHP, you need to get Composer. If you have one or some, or already have local test environment, most people might actually accidentally already have Composer. And Composer is a dependency management system for PHP. So if I tell Composer to install a certain project, it will automatically install all the other projects that project depends on. So it makes your life easier. So instead of me telling you, now you need to install five tools, I just tell you to install one tool, and then Composer will do the rest for you. So that's why I say do it with Composer. And then once you have Composer installed, make sure it's in your path, and run Composer require with the name of the project I just mentioned, QAWP projects. And then you have the tooling available to you to actually do automated scanning. All of it will be installed and ready for you to use. And what I'm gonna show you in a minute does depend on one pull request to be merged. So I'm hoping it's gonna be merged still this weekend. If not, I'll just make a little tweak to make sure that you still can run it. But at this moment, you need that pull request to be merged, the change to PHP coaching for itself. Okay, once you've installed this, you have two standards to choose from. You have the WordPress QA basic standard or the strict standard. The basic standard just gives you a global idea. Strict is a lot more strict. All of the things which are being checked are opinionated checks. It's my opinion that those are indicators for quote quality. So if you don't agree with it, open an issue and we'll talk about it. But yeah, basic does 95 checks, strict does more checks and makes some strict checks which are in basic, just warnings makes them errors. So it really is stricter. But they both would give you some idea of quote quality. Wanna see what it looks like? Yeah, okay. This is the command we're gonna run. And remember all those things we looked up at the beginning? We're gonna use them. We've unzipped the project, the plugin, and we know the parts to where we've unzipped it. We need that to tell the tool what to scan. We're gonna set a test version. That's the PHP version, the minimum PHP version with a dash. So from that version upwards, the code should work on those PHP versions. We're gonna set the minimum supported WordPress version which we looked up in the read me. We're gonna set the prefixes. Most of the time will be one prefix, sometimes it'll be several prefixes, but we're gonna set those. So we don't penalize code for not being prefixed when they actually use a prefix. And we're gonna, if we use strict, we're gonna set the text domain which we looked up to make sure that they actually consistently use that text domain. Because otherwise we'll end up with a plugin which says that it's fully translated and it isn't. And then your Dutch customers might not be able to display things from the plugin in Dutch. Right, let's see this in action, right. Okay, now I did some of the typing for this before rounds. So PHP CS, the part where I'm in is already the part where WordPress importer plugin has been installed. I'm gonna run it against the strict standards. I tell it PHP 5.2 and up. I tell it that the prefix is wp underscore import. I tell it that the minimum supported WordPress version is 3.6 as per the read me. And I tell that the text domain is WordPress underscore importer. It's gonna take about 20 seconds to run. And you can see it running, you can see like it's showing whether there's warnings or errors and that it scans a file. Ooh, here we go, we have outputs. Now I'm gonna scroll up a little to the start of the report and it starts with a little disclaimer. This is advice, this is not a hard judgment, this is not like, the target is not to have zero errors because sometimes something is not fully analyzable by a code analyzer. So zero errors is, yeah, utopia, but not always necessary for something to be good code. But let's have a look at the top of it. How many files have we analyzed? We have analyzed eight files. Four were plugin files, four were test files. Together they had 2300 lines of code, less tests than plugins. So the plugin is probably not fully tested. And the comments to code ratio of about 20% which is on the low side. For comments, I think about 30 to 40% is a good amount of comments as a general rule of thumb. To say code will be well documented. And the reason why documentation is important is quite simple. If I have to look at code, I wrote three years ago, I have no clue where to start unless there's documentation telling me. So for code to be maintainable in the future, for other people to be able to contribute to code, good documentation in the code base is important. So that's just a general, to get a general feeling. 30% is a nice number, 15% is a bit on the low side here. On the good side, they do actually have tests. Then again, most of the time, tests shouldn't be shipped to production as in the distributed plugin shouldn't actually have the tests in them. But you can then check whether they're on GitHub, whether they have tests in the GitHub repository. If you wanna make sure that the code is actually tested by the developers as well. But yeah, if they do have tests, I do make a difference. So if we look at the report per category, again, scans per plugins and per test files. So they're separated because for tests, we don't have to be as strict as for the plugin files. And we can see some things there. We see some untestable code. We see some incompatible codes. We see some potentially conflicting codes. And again, zero is not the target. What you need to look at is sort of the relativity. If you have a code base which is really, really large and they have 500 errors or 500 warnings, I wouldn't be too worried. If it's a small plugin with only a thousand lines of code and they have 500 errors or warnings, I would start worrying. So that's why I've added the percentages, the amount of errors and warnings set off against the number of lines of code. Actual code, not comments, just code. So you have some feeling of, okay, if this is between one and 5%, it should probably be okay. If it's above 20, do not touch that plugin, kind of saying. You have to develop a little feeling for it. But yeah, it just gives you an indication and gives you some idea. 12% here is a bit on the high side with warnings, but I do know they're actually working on improving this plugin at this moment. And I know who's doing it. So I fully trust this will go down really soon in the next release. So does this give you some idea? Does this look useful? Absolutely. Let me just scroll up to the beginning where I actually have that little disclaimer which says it is advisable to let an experienced developer actually assess whether something is serious or not. But you have some idea whether it's worth it to spend money on a developer having a look at the code. If there's over 20% issues of lines of code which with issues reported, you might just not wanna bother with that plugin in the first place. You know what I mean? So to make a judgment call, you need a developer to actually look at the code. To get an idea of quote quality, to get an impression, to get some advice when you're not a developer yourself, this can help you. But it's not hard judgment because a static analyzer is not the same as a human brain looking at code. Right, let's get back to it because what does it all mean? Let's interpret these results. First of all, the top line was hard errors. That means if code has parse errors. Basically that means the code cannot run. If you get that, just don't bother. That's where it stops. Even if you have one parse error, do not bother with the plugin. Then we have, oh, sorry, I didn't realize I had a slide for that, hard errors. Okay, then we have dangerous code. What's dangerous code, code which does arbitrary code execution on arbitrary variables which you don't know about. So we're talking about code which is being default, code which does string replacements with arbitrary variables, shell execution as in literally running commands on your system where your server is. Code which does that can generally be classed as dangerous no matter what. There's very, very few exceptions which would make that code not dangerous. Very, very few. Untestable codes. That's what I talked about earlier. How complex a code can be if the code is really complex it becomes untestable. If it's untestable, when a bug fix is made you don't know whether you're changing existing behavior in the right way or changing something which shouldn't have been changed. So that's not very good for code stability. And that's defined by metrics, high code complexity and deep code nesting. And I can give you a whole technical story about what that means but basically take it from me. It just, the short of it is it's very complex code. Outdated code. Anyone? PHP style, a four style code. We all said already that PHP 524 which is still the minimum WordPress version is really, really, really, really old. PHP 4 is even older. If people write code in the style of PHP 4, I couldn't say something a bit arbitrary or a bit judgmental here but that probably means they've copy pasted a lot of it from Stack Overflow. And they don't actually know what things, more than just what the code means which they've copied and pasted because that has been explained to them but they don't actually know that much of PHP itself. Another typical outdated code style is using global functions. Global functions mean that a function you write in your plugin, I can call it from my plugin. And maybe not the most desirable situation because that also means I might confuse your function with the function from someone else. So those outdated practices, this says something about the skill level, the knowledge that the developer has. Messy code. Messy code, typical things are used of abstract, extract that is like, oh, you know, I have some array with lots of information, let's just make it all available to everyone. And then you don't know where things come from again, you don't have a strict management of information which makes things difficult. Duplicate classes, duplicate function arguments, assignment in condition, making things difficult to debug, jump on the increment, these are just things which make things messy, it makes it more difficult to debug things and again, it says something about the skill level of a developer if you come across these things. Now we get to more important and more weighty things and that's code incompatibility with PHP. Warnings generally with incompatible PHP code will mean that something is using deprecated functionality. Errors means you're using stuff which is either not available in versions before a certain PHP version or after a certain version. So using the evil string replace with regular expression in PHP 7 will be an error because seriously that is just not gonna work anymore. However, if you use unset cast in PHP 5, that'll be fine. In 7, that'll be a warning because it's gonna be removed. So it's an indication of whether the code is written in a way which is cross version compatible which makes it safe for you to go to a hosting company which runs a more up-to-date PHP version or if the hosting company upgrades the PHP version whether your site will still work. Yeah? With incompatible code for WordPress, similar things can be said except most of the time WordPress will not remove things, they will just deprecate it. It's still not good to have a lot of deprecated functions in use but most of the time WordPress will still allow the code to work. So a bit more leniency there but still not something which is future proof. Okay, next, conflicting code. Well, we talked about prefixes. Do you all remember what I said about prefixes? If you have a variable called message, I have a variable called message, what's the actual message text in there? Because I will write to that variable, you will write to the variable by the time I actually use it to display it on the screen I will be displaying your message. This is serious. This is something which is fine if you only run one plugin on your site but it's not fine if you have 20 plugins running on your site. This is a serious warning indicator. At the same time, you have to make sure you actually give the prefixes to the scanning tool properly because otherwise it will not be able to make that judgment call properly. Right, potentially insecure code. We all know the mantra or have heard of the mantra for developers. Validate all inputs, escape all output. We don't want sites to be hacked. And one of the most common things I see with WordPress sites is strings are being made translatable and then they just output the translation to the screen without escaping the translated string. But that means that you trust one, all the translators are translators which are trustworthy. And 99.9% are, but there's always some which aren't. And second of all, you trust that the actual translation files on your server will never get hacked. And neither of those situations are true. So those are the most common problems with escaping output or output not being escaped in WordPress plugins and teams. But there's more, not using prepared queries to the database, that means that information which is sent to the database which determines what will be displayed on your site might be compromised. That might mean that your whole database can be wiped or that someone else can get access as an admin to your website. You don't want that. So anything which is in the potentially insecure category you should have someone look at. But it's a lot of plugins and teams will have zero issues in that category. But when they do have someone look at it. Make sense still? Have I lost someone yet? No, okay. Internationalization issue, well we already mentioned you want your Dutch customer to be able to display their site in Dutch. And if your plugin or team which you wanna install displays something on the front end that should be in the language of the site. If that isn't translatable or isn't translatable in a proper way, it doesn't allow translators to correctly translate it because it doesn't give the right information to the translators, you have a problem. So that's internationalization issues. Potentially buggy code. Code which can be made better. Not necessarily an error, not necessarily a bug but it could become a bug. And just by changing that code slightly that code would prevent it to ever become buggy. And it's often to do with strict comparisons. Let me see, yeah. Also the WordPress SQL best practices are mentioned preparing the queries but there's more things you can do in best practices to do with how you prepare the query, how you pass information to the database. So again, those things are being checked when you use the strict standards. Sloppy code, empty statement. A condition which doesn't actually test anything. Code which basically should be removed or should never have gotten into the code place in the first place. Again, says more something about the scale level of the developer than anything else. Discouraged code, last category. Code which most of the time in this case, WordPress will say, we have a better alternative. And the reason you should use those WordPress alternatives for PHP functions, for instance, is because the WordPress function will take differences between PHP versions into account if the function has changed across versions. So the result will be more stable across different PHP versions. So the discouraged code, discouraged functions, not a hard problem but something to be wary of if it's a lot. All right, then we get to the balancing act. Because as I said, zero is not the target. You don't have to have zero errors. Not even say like less than 1%, it's a balancing act. You need to make a judgment call and I cannot make that judgment for you. I can just give you the information to base your judgment on. And just make sure the amount of problems don't outweigh the non-problem code. If it's more than 20%, get very worried. If it's somewhere between one and 5%, it's your judgment whether you trust the plugin or not. But at least you have some information to base that judgment on. Right, now what if you have a plug in your team and you do not find any issues whatsoever? At all, I'm gonna make it easy for you. Run the scan again but at ignore annotations. There are annotations developers can use to tell this scanning tool and that's not just my scanning tool but the underlying tooling I use to ignore certain code. If you still have zero errors when you run the tool again with ignore annotations, check whether there's actually any code in there. But this is a way to check whether developers are cheating basically. It's fine to ignore a few things because sometimes a developer has looked at it and said, oh no, but this is used correctly. Thanks scanning tool for telling me to have a look at this but it's fine and then it's fine to whitelist it. So if there's a difference and the difference is small between running the scan without ignore annotations and with ignore annotations, that's fine. If the difference is big, get worried. Right, now what about Tite? Has everyone heard of Tite? Tite is a project which was very ambitious and said we're gonna ask code quality indications to the whole plug-in directory and the whole team directory at WordPress.org. For now it's been managed back to just show PHP compatibility information that's gonna be happening soon but they do still intend to show more information about code quality of plugins and teams at WordPress.org. You can basically expect Tite to go in this direction and not with the tooling I'm using and the command line interface, they will make it look pretty but the underlying tooling is the same. They use the same tools as I just showed you. Right, so what's this useful? Yeah? Anyone who's now itching to get started on Monday and scan some of the plugins they're using? Nice, nice. Let me know if you run into any problems with it. Ping me on Twitter or open ish on GitHub. All my contact details are there. I will put up the slides on speaker deck later today and I will tweet the link but if you just go to speaker deck slash jrf you should find them. Yeah, thank you for your attention.