 Right, yes, so my name is Juliette, and just in case anyone's confused, that's not Gijmen. Gijmen is in the auditorium, and he's also got an awesome talk, so if you're in any way confused in thinking this might be too technical, Gijmen's got an awesome talk as well. You now is your chance to leave if you still want to. So, who here is a developer? Oh, the majority. That is nice. It always happens to me when I give a talk like this. Who here normally doesn't work with code? Okay. Oh, you're making my life so easy. Normally I have to do a whole caveat about if you're a plug-in installer and selector, then this can still be useful for you, but I don't have to do it now if you're all working with code. So let's dive in. WordPress CS. Basically, there are coding standards for WordPress. That's in the handbook. It's a written set of rules, and some of that might be arbitrary. Some of it makes actually really good sense. But before anyone gets confused, WordPress CS does not mean code style. It includes code style, but it's far more than that. It's coding standards. It's best practices. It's quality assurance. It's more than just code style. When you look at code, you need to look at so many different things when you review code. When you get a feature request or when you get a pull request with a change, a bug fix. There's so many things you need to pay attention to. So many different things to take into account. Is this something we want in our codebase? Is it architected in the right way? Is it belong in this codebase or in another codebase which is related? There's so many things you need to look at. It's really, really, really easy to overlook something. So think of the codified WordPress coding standards, which is a package you can use in your daily life, as a little robot which looks over your shoulder and hopefully finds a lot of those things you might otherwise overlook. Does that make sense? How many of you already use the coding standards? I'm in my home crowd now. Let's see how well you've actually paid attention to the coding standards, because if you get a code snippet like this and you review it, what's wrong with it? Where? There's nothing translatable there. Your world's not escaped, ding, ding, ding. What else? DING, DING, DING. We have the URL, which is not escaped, and we have a training comma, which is PHP 7.3 plus. If your code needs to be cross-version compatible, this is going to be a parse error, and it's so incredibly easy to overlook this. Should we do another one? Right. A bit more complex. Dat is niet verpreidelijk. De code briefphrase, dat is niet een error, het kan niet be verpreid. Oké, dus de postphrase may not exist. Er is no validation being done. No check with is said whether that actually exists. Very well done. Non-sverification? Er is no non-sverification being done. Also very well done. If you don't do non-sverification, you do not know whether the post or you get comes from your form, and that opens you up to cross-site request for juries, which is security risk. It's not sanitised, butch bit. The one at the bottom is not sanitised before it's not output escaped, before it's printed again. At the top it's not sanitised before we're actually checking the value. Correct. I did say there was more wrong with this one. Should we go through all of it? Oké, so first we don't know where the post exists. That was already mentioned. Next. Oké, wordpress slashes everything it receives from post and requests and gets. If you compare string, the postphrase, it's a brand new day without unslashing it, this is never ever ever ever going to match. So this code is absolute nonsense if you don't sanitise and unslash the postphrase. On top of that we're doing a loose comparison against false, but string position might return integer zero. So this loose comparison again is absolute crap, because if the phrase is it's a brand new day, it's literally that phrase or it starts with that, this is going to give you the wrong answer. So as I said, there's a lot wrong with this code. What's more, yes we're escaping the congratulations and wrong answer phrases, but we're not translating them. We just ask HTML just escaped, it doesn't translate, we need to ask HTML with underscores to translate it as well. But we're passing the domain, so we're actually saying we want to translate it, except we're not doing it. Then again the output escaping for the phrase there, so yes, it's really easy to overlook something when you review code. Should we continue and do another one? All right, I'll keep going. Screen icon is deprecated, and I heard something here at the front. Sorry? Text domain has to be a string. Text domain has to be a string, definitely. The shorthand pfp opening is not always supported from all voting environments. No, but a good point, but not completely correct, but there is something wrong there, I'll come back to that. Sorry, I'm getting two answers at the same time, what were you saying? There's no closing, this is the header, so the closing might be in a footer function, so that may not be wrong. But it is something to check when you review, absolutely. But it's something to check manually. And you were saying? It's not sanitised? Sorry? Come again? My admin page is not translated. I'm still missing one of the most important ones. It's not an H1. It's not an H1. That is arbitrary, maybe there is an H1 in another function above it, and then the H2 is correct. That's something I cannot determine just by looking at the code. That needs a manual reviewer. But there is still one thing which is really wrong with this. It's not documented, completely correct, except that's not what I'm looking for. Come again? Sorry? Shall I just go through the things which are wrong? Okay, first thing. Now if I highlight what's wrong, can anyone tell me what's wrong here? It should have been namespaced. It should have been either namespaced or prefixed. So anything you do in the global namespace should be namespaced or prefixed. Why? Very simple. With thousands and thousands of plugins and teams out there, it's so bloody easy for people to use the same name twice. So if you in a plugin use admin page header and someone in a team uses admin page header, you have a fatal error because the function is being defined twice. And that means the end user has a white screen of that. Do we want to give the end user a white screen of that? In that case prefix everything. And for functions for classes, if you namespace your code, you're fine. But not for variables. Namespacing has no effect on variables. Namespacing has no effect on text domains. Namespacing has no effect on filters. So for anything, when you define your own filter, which is going to be, you know, do action or apply filter, when you define variables, make sure you prefix those if they're in the global namespace. Ja? Okay. The first thing which was mentioned, this was mentioned already at the back, screen icon is deprecated so you shouldn't use it anymore. We have admin page which is not translated. This is by the way something which we cannot detect automatically. Because some hard coded text strings are not being output to the screen. So we cannot determine whether something needs to be translated or not. The fact that you actually found this and saw this is a good thing because yes manual review is still necessary. This is only a robot which can help you. It cannot replace you. What else? Okay. We have the short echo tag. You already mentioned that. The thing with the short echo tag is unless you're using PHP 5.3 or lower, there is no risk using it. I want to get rid of the rule forbidding it because it's absolute total nonsense. Prior to PHP 5.4, there was an initiating which would determine whether a short open echo tag would work or not. The short open echo tag is now no longer subject to that initiating. It's not a risk anymore. So you don't need to have the risk of code exposure that way. But there is still a problem here because the underscore E function on the one hand is not escaping, which it should do. It is translating but it's also echoing. And the short open echo tag also echoes. So now you get the content echoed out plus an extra one. Because the result of that echo out function being echoed out again is true. And that echoes out as one. So now you have a stray one and you need to debug where the hell that one came from. Does that make sense? This is why automated checks can really help you. Right. Text domain, we also already mentioned that. That really should be a hard coded string. There was a reason for that. There's a lot of different generators for the translation files which can be used to make a plugin internationalized. If you submit to wordpress.org, that's all handled by Rosetta. But not everyone does that for commercial plugins of plugins which are proprietary. You still want the text strings to be translated. And the tooling for that can often not handle it if you don't use a hard coded text string. It cannot distinguish which bits it needs to extract from your code to say that belongs with this plugin to translate. So always make sure that's a hard coded string. Yes, I know it's annoying because you don't want to look at hard coded strings but it is what it is. One more? One more. Ok, let's see. It's not a prepared statement. It's not a prepared statement. Ding, ding, ding. Sorry. It doesn't mean that the Globes are already initialized. The WPB and the WID. Actually, if you import them with Globes, if I remember correctly, they will always be available. It is correct what you're saying that WPBDB might not be the object. Then you have to be sure that it's initialized after the WBB is already there. Ok, so basically what you're saying is the Globes team imports the variables maar those variables may not have been initialized by WordPress yet so we need to check that they are actually available with the right content before we start using them. Good point. In most cases if you use the normal WordPress flow these will be available. So these are low risk but it is a very good thing to always check that when you hook into WordPress you hook in at the right place because if you hook into early then you have that risk. Search doesn't have a fullback. It doesn't exist. Ok, what would that mean for the code? If search doesn't exist? It doesn't exist return. Basically you wouldn't have a result and we're going into the for each without checking that the result is actually an array. That is iterable. Searching for the string search is not the value given to the function. Searching for the string search is not the value given to the variable you're saying. Actually it's a double quoted string so that's not true. This will be interpolated. But it is subject to SQL injection. That's when we come back to the first person who mentioned prepared statements. In the for each ID is being overwritten Ding ding ding. En dan hebben we het. Er is nog een, maar we zijn bijna daar. Dit is niet een voorbereid statement. Waarom zijn voorbereid statements belangrijk? Do you all know that cartoon Bobby Tables? Ok, if you don't know it look up XKCD on the internet Bobby Tables. You are going to laugh. Basically any time you query the database you use a variable as input you don't know what the content of that variable is. That variable might contain a string which is crafted in such a way that it damages your database. That's the Bobby Tables cartoon where basically someone puts their child up for school and made a sure name. The semicolon delete tables. Ah, and suddenly the school administration was gone. So any time you use any arbitrary data in a query in a database query you need to prepare it you need to make it safe for use in that query. That's not being done here and that should be done. So the search there is really dangerous but there's more wrong with that search because we're doing a like with the search except where a like says ok, I want it to be like something and something can be either in front of it or behind it or on both sides of it except now we're using the hard coded search string. We're not actually telling the database that there can be something before it or after it so we should have just used a straight comparison here. This like is absolutely useless. What else? For each we already mentioned that we're not checking if we actually got a result back if we got something iterable back before we go into the false each so we may be for each thing on false which is likely at some point in the future to return a PHP error and we're overriding ID and we're overriding ID is really really dangerous because it's a global variable defined by WordPress Core. That means that WordPress Core might break At any point after you've done this code after you've run this code now WordPress code cannot rely on that variable it defined itself. Now any other plugin or team can no longer rely on that variable. Basically you are breaking WordPress if you overwrite any of the WordPress globals. Having seen these code samples is anyone still unconvinced that coding standards and quality insurance in such a way has a value. Well not everything I showed you can be caught by automated tooling but a lot of it can be and to do that we have codified that handbook decoding standards into an automated tool we call it WordPress CS and there's a new version version 3 just come out and it does so much more than just checking code style it has security checks WordPress plugin and core interoperability checks it checks if you're using deprecated functions from WordPress if you add PHP compatibility WordPress to it it can even check for PHP compatibility issues so there's lots of different things that can check and help you with there may be some rules you don't like it's configurable you can change things so that's okay so how do you get WordPress CS considering most of you already use it I think I can skip over this largely just very quickly as of WordPress CS 3 the only way to install WordPress CS the automated the codified version is via composer we no longer accept or support peer install cloned installs you can still do it it's still perfectly workable install which is a clone on my local machine but we do not offer support for it anymore because WordPress CS has grown it's become more complex and the amount of support the amount of time it costs us to support non-composer installs is just not really worth our time at some point we make it as easy as possible just install it with composing again I mentioned optionally the PHP compatibility WordPress standard which is basically the PHP compatibility standard with some caveats for known polyfills which are in WordPress as you can also see here and oh okay the little dot doesn't work on the screen you can see composer global that's optional generally the recommended way of doing this is install it as a requirement in your project but if you don't work with code for the 1, 2, 3 people maybe here people will for instance select plugins then it might be better to install it globally so you can use it whenever you're infalluating plugin and you don't have to add it to each plugin because that's not yours to do yeah if you do install it as a global package for with composer make sure that the composer vendor bin the global composer vendor bin is in your windows or your linux bot that way you can just use phpcs wherever you are on your computer doesn't matter okay normally I would do a little demo now showing how it works but should I still do that yes okay let's have a look okay so hang on going to okay ha this is going to be fun that's not right I need a much bigger command line because this is unreadable for all you all hang on settings this is impossible for me to do sorry normally I use a separate profile on my laptop for presenting and everything like this has been set up but that doesn't work nicely with the command line so I saw that cheat and used my normal profile I shouldn't have done that right let's set this to 20 hahaha 64 hahaha why did it not take anyway ah it's just not big enough yeah let's not okay so can you all see the command line now yeah okay so if I do phpcs dash i it should say all list of standards normally when you do this you will see maybe one third of this list of standard but as I develop this kind of shit yeah I have a little bit more so this way you can see all the different standards which are available and yes I'm using php3 already now to run it normally would you send a bin phpcs I'm using phpcs global I'm going to say I want to see progress I want to see error code I want to run it on the complete project project I want a report which shows me the full report and a summary and the source report and I want to run against the word press standard let's see what happens okay I made a typo let's do a comma here instead of a dot there we go ah now something is happening oh yes nobody saw which project this was did you we did it okay this is a project which is old which hasn't been updated that much recently so maybe it needs a bit of love please forgive that project and if you feel inclined contribute to it because it's on github nowadays recently but yeah you can see in everything I just showed you let me just scroll up if I can do that yes you can see all the errors here if there's a little cross here that's something which is auto fixable that means you can run a second command php cbf code beautifier and it will actually fix those things for you if you want to anything without that cross cannot be auto fixed and needs manual attention this is the full report where it gives you everything on each line for every file then we have a summary it gives you how many hours are in each file and then you get the source report why is the source report interesting it gives you the error code and the error codes can be used to configure WordPress cs you can say at some point okay it says something needs to be output escaped but hang on I actually did that a couple of lines above it and I verified this this is correct the sniff is just not intelligent enough yet to understand that put an ignore annotation in place to tell phpcs it can ignore that to do that it's best to use those error codes so phpcs will only and just and only ignore that bit which should be ignored and not anything else so those error codes are important they can also be used to configure what you want to check and I'll come back to that in a minute right let's make it a little bit easier on myself again I can see what I'm doing now previously WordPress cs 3 which I presume most of you are still using how many of you have upgraded to 3 yet 1 person, how did you like upgrading to 3 it didn't work with 2.6 it did as long as you silenced deprecation notices why do we like this ok, so it wasn't too hard to upgrade no for those people who haven't upgraded yet when you had WordPress cs 3 which you all know you would get php code sniffer you would get the WordPress coding standard and with code sniffer came a couple of standards and with WordPress a couple more standards and then you had to wire that together yourself you had to add a plugin for instance for a composer to make sure that php coach never knew where WordPress was installed or you had to tell it in another way where WordPress was installed you also could optionally have the php compatibility rulesets there with php compatibility WordPress but yeah, you had to do more yourself now, it took a long time for us to release WordPress cs 3 any of you have questions about that did any of you read the make post about the release ok, a few people did I'll quickly reiterate why it took so long we started with the refactor because things like you saw me mention php compatibility a couple of times already php compatibility and WordPress cs were using a lot of utility functions which were basically doing the same thing which were not in php code sniffer but they had to be maintained in multiple places now so we thought we could make that smarter so we were refactoring the code to organize all those utility functions which make writing sniffs easier in a central place so that refactor was going on additionally in March 2020 we published a post with a proposal for rules for modern php because php had a shitload of syntaxes over the years and while some of it can't be used yet by WordPress some of it could be used and there were no rules in place how to format that so code was becoming quite inconsistent regarding that and at the same time even if things can't be used by WordPress yet when you write a proprietary plugin on php8 can use that syntax and you might still want some formatting rules to make sure your code stays consistent so we basically were marching in front of the band trying to put those rules in place and finding all the rules and sometimes writing new sniffs to create those rules takes a while, takes time and while we were doing that PHP 7.4 came out which added error functions which in case you don't know actually is really really complicated for PHP code sniffer to understand and then PHP 8.0 hit which added something like 15 new syntaxes and all of them had to be accounted for first in PHP code sniffer then in that centralized utility repository we were creating and then in all the sniffs and while we were doing that PHP 8.0 hit so the amount of syntaxes PHP is added since PHP 7.4 7.4, 8.0, 8.1, 8.2 those four versions have basically added more syntaxes than every single PHP version from 5.0 up to 7.3 together and we had to account for all of it because if we didn't you'd get false positives and false negatives because if we were looking for a global function you check like is there no object operator before it but hang on PHP 8.0 introduced a nullsafe object operator so every single place where we were checking is this a global function or not we would have to change that code to take the nullsafe object operator into account and that's just one example what about match what about enums so every single syntax caused new problems and we had to review every sniff in detail to be able to make sure that there's no false positives and false negatives and I'm not guaranteeing there won't be any I mean my imagination only reaches up to a certain point people can write really, really creative code please if you find something reported and we'll try to work around it but we've really made the best effort to figure out as much as we could to prevent false positives and false negatives so what do you get in WordPress cf3 you don't have to worry about installing WordPress with PHP code sniff anymore that will be done automatically with the Composer plugin you get that utility layer that extra layer of utility functions which we created for writing sniffs you get a second package next to WordPress which is called PHP cs extra which has a lot of what I tend to call the forgotten sniffs the sniffs you didn't know you needed but you do and we're using a lot of those sniffs now in WordPress cs for WordPress cs3 we, oh well I wrote I think 35 new sniffs so that's pretty extensive a lot of them again with fixers in extra everything is documented in WordPress a lot of it is documented so you can actually get command line documentation as well I would highly recommend using PHP compatibility WordPress as well that hasn't got the next version yet we're still working on PHP compatibility 10 which has the same problem except that code space is still about four times as large as WordPress cs so it's a lot of work and I'm trying please be patient it's coming if you upgrade or when you upgrade I really really highly recommend read the upgrade guide and read the change log the upgrade guide just follow it step by step it's extremely detailed you probably only need to make 3-4 small changes but it will make sure that you check everything which you could possibly need to change just go through it step by step those guides are available I see a smirk here you know what I'm going to do you're going to upgrade and see what breaks yes I know what you're going to do that's not the way you host so when you do that when you just upgrade and everything breaks because it will then you know where to look for the answers please do not open an issue until you've checked the change log and the upgrade guide because I will bloody close it straight away I'm not joking don't waste our time you see how much work has gone into this and how much work it's been to upgrade everything so the pressure and amount of stress that's caused us has been a lot that means that if people don't even bother to read yes we will close issues quickly no offence meant but the information is there I didn't read okay now when you start using WordPress.js I think all of you already have this because nearly all of you are already using WordPress.js you have a custom rule set generally that's the recommended way of using it you have a few basic settings saying okay we want to scan this part of the codebase we want to scan PHP we want to use the WordPress standards but there are a couple of things you should really configure and this is something you really need to pay attention to if you're already using it and you're not using these settings I'm going to tell you please add them as soon as you get back to the office because they're really really important so if you use PHP compatibility WordPress tell it the minimum PHP version you are using and then a dash after it because otherwise PHP compatibility will not be able to give you the right results because it doesn't know what versions of PHP your code needs to be compatible with along the same lines tell WordPress.js what minimum WordPress version you want to be compatible with otherwise we will not be able to warn you correctly about deprecated functions or whether a new feature like the percentage i in prepared statements can be used so add those options the minimum WordPress version configuration setting is used by multiple sniffs that's why we use it as a config setting and it changed names in 3.0 so if you do have it you need to make sure that you change the name to the new 3.0 name which is more consistent all around yes then we continue you want to translate your text strings so you need to tell WordPress.js what text domain your text strings should comply with because otherwise we cannot verify that the text domain is actually correct if we don't know what to look for we can check it similarly you need to prefix everything in the global namespace I already explained to you why that's so important when you prefix everything tell WordPress.js what prefix you're using and that can be easily especially with all the code bases which are still migrating to be consistent it can be multiple prefixes so you can tell it okay we have a few which were used originally and now we're all migrating to one new name new prefix for consistency while you're doing that you can have multiple preferably you only use one prefix but you need to tell WordPress.js what prefix you're using otherwise it doesn't know what to do en met dat you can just run it so there's a last few pro tips before we finish the explain command basically if you run phpcs with dash e e for explain it will give you a list of all the sniffs included and that can sometimes give you some information of oh hang on but that's something I don't want that whole thing about long arrays lets use short arrays now your conditions make my code really unreadable you can do that you can quickly find out the name of the sniff to exclude by checking which sniffs are included so dash e can be used to explain see all the sniffs which are included in the standard and there's a lot of them in WordPress at the moment now the next one is I already mentioned documentation you can actually generate documentation on the command line for all the sniffs included in the standard or just for one sniff if you just want to see it for one sniff and that documentation has a little explanation of what rule is being checked and code samples with this is valid code this is invalid code so it gives you more information of what is expected of you and how to fix something and it can help you educate yourself to improve your code writing next one quite often you might have a really big code base in which you're working with 500 files, 2000 files and you've just been working in 3 files when you want to check the code style of your changes do you scan your whole code base start using filter get modified or filter get staged and it will only check those files which are either modified and unstaged of modified and staged it will make your scan so much quicker you can also combine this with PHP code beautifier so with cbf command and it will just fix those files yes right now you've heard me say how much work this has been open source software is not free there is a huge huge cost and the cost is not with you the cost is with the maintainers the cost is in mental health the cost is in work life balance the thing is you are just not paying the price the maintainers are and one thing we've noticed the work has grown exponentially with how fast PHP is going this is unsustainable the way it is for us to fund this project and I'm not asking you as individuals to do this I'm asking you to go to your employer and make the case that they help fund open source projects not just WordPress.js but there's a whole chain of dependence issues hopefully you're using PHP unit you're using composer you're using PHP if any of those projects would go away your work life would become really really difficult so make the case to your employer that as part of good business practice they should sponsor open source projects including WordPress.js for WordPress.js we have an open collective keep an eye on the URL I'll post the slides online in a minute if you want to look it up later and I want to thank you for your attention