 Good morning or late good evening or wherever you are in the world to everybody joining us here today. It is lovely to see you all. Super excited for today's session we are joined by the ever amazing and I hope I pronounce this correct now it's Milana it's up if I'm not mistaken is that the correct pronunciation yes. I made the point of when I met Milana not not the most recent time but the time before that to ask her how to pronounce her surname so that I could get a right for future events but Milana is joining us today welcome Milana how are you today. Good, good, thank you for having me. I always like talk about WPC live. Maybe we won't have enough time for one hour but maybe there's another sequel. Absolutely. Absolutely. So, so while everybody's joining what I like to do is just give everybody an opportunity to let us know where in the world they're joining us from. So if you'd like to either in the chat or just by a voice. Just let us know where you're joining us from today. Hey everybody. I am Catholic I'm joining from India. Awesome. Awesome. Anybody else want to want to introduce themselves. I'm from India. Awesome. Welcome. Hi guys, I'm Sagar. I'm also from India and Milana knows me. Hi Milana. How are you. Good. Good. I'm all pumped up for WPC live. Yeah, I'm looking forward to it. I'm joining from Estonia. Awesome. Welcome Andre. Anyone else? Anatoly from Ukraine. Hey Anatoly. You were in my workshop last week, right? Yeah. I was in your workshop at Jonathan. Yes, that's right. I'm recognizing some names. That's awesome. Anybody else want to introduce themselves. Let us know where they're from. Everybody else is either quiet or working or still waking up. All right. So yeah, so today we have Milana today talking to us about WPC live for PHP developers. Milana is probably besides maybe Elaine who is the current maintainer of WPC live Milana is probably the one person who knows the most about it. So I'm super excited to have us with us here today. So I will hand it over to you and let you take over and I will I will, I will shut up from now. Okay, so I have a little bonus for you from the beginning. I've been reading what people answered there what they are looking for to to learn. And there was one thing that was very interested to me how to how to use WPC live to export stuff from production to local or something like that. So I have a little treat for you. This is something that's going to happen in one liner. And I'm going to use WPC live alias because it's very easy for my local to connect it to all the remote servers. So when you want to check what you have you type WPC live alias. I'm sorry if you hear my keyboard it's an alias list. And this is what I have. Also, if this is small, tell me to just zoom in. But if you can see that school. So I'm going to use this one. My imaginary clients. So this is a remote server. And this one is my local one. So let me show you. If I use WPC, it was imaginary client. And I can say like option get home. It will give me the URL. So you see it's a remote one. And this is how it looks like. This is the website that I usually harass when I do workshops and talks about WPC live. And if we do the same for. What was the other WPC live. You see these URL. It's local one and it just freshly installed this morning. But I'm going to do, I'm going to take database from this one from remote to my local one. Now, if you don't know how to set alias, there is a documentation about that for remote one, you first need to set SSH connection between your local computer and the remote server. It's done by making SSH key pairs. You can put your public key to, to remote server and then when you try to connect with SSH, it creates handshake and then you can connect to your terminal from local to your remote server. We are not going to cover that because we don't have enough time. So that's important to know to be able to create alias with remote server, you first need to have SSH connection. So now I have these two connections with the WPC live aliases and what I can do is I can say that I am. So this is my remote one and I'm going to say database export. Now, if I run this like this, it will export database to a file on remote server. I don't want that. I'm going to type minus or whatever it's called and that's, that will escape creating a file and just put the output into standard output. That means we can do with it whatever we want. And what we want, we want to make it input for our next command. So I'm going to use pipe. And my next command will be WP. Now I'm doing the local one CLI database import. And again, I want to do it not from file, but from standard input. So I'm doing minus now. We all know when we just import database. That's wrong URL and you have to fix it. So I'm going to change this when this is done, I'm going to send it to the end. And then I'm going to run search replace on local ones and WP. WP CLI search replace. And now we have all URL and then new URL. So let me just close this. This is the old URL. And this is new URL. So let me just close this. What means all the new. First is search then replace. So I'm searching in database this one and replacing it with this one. And that's all in one line. What we are doing. We are not making any files, not leaving any tracks. And we are exporting from a remote server. Importing to local and running search replace on CLI. Everything in one command. And then we are going to run it. Oh, my God, it's done. And we have no files, nothing just one line. And if you notice here, this is my home folder. This is not in any WordPress install. Because this is local. I could actually just go to WP. I could run the whole command without this alias. But with alias, I can run it from wherever I want on this computer. Now let's just check this. If all of it, oh, it's not done. Not all of it is done. So let me, you have to always check. Let's do it like this. I don't know everything. I don't know if you see all the places where this shows up and in what what form. So I'm going to do this made another seven replacements. So now it says this one, but you see, I don't know if you see. The problem is it's doing the. Https and my local is Https. So I'm going to run another thing and just say Https. And then so this was supposed to be in one line. It's not, and it really depends on what you have already in database. So right now I'm just replacing Https with Http, but only on the main name made three replacements. Now let's see. And now it's working. Okay. So we needed a little bit of adjustment, but the database was exported imported and such a place done in one command that was your bonus on the main name. Now let's start to it. With our workshop today. Yeah, could I just interrupt before we do that. And it's only was asking, do you maybe have some resources or some commanders with what you were talking about. Do you know offhand, which is the documentation for setting up the the aliases and the SSH connection. I found one that says running commands remotely. Is it that one? Yeah. Yeah, I think. Yeah. Okay. I'm going to share it in the chat with folks. So this is the running commands remotely setting up the SSH connection that Milano was talking about earlier. So definitely go give that a read. So if you go to. If you go to here, it's amazing documentation. And here you have everything about installing and then here running commands remotely. And you can see all setting up aliases. And it doesn't cover SSH connection because that's something that's not unique to WPCI. It's actually just Linux administration. But you can find it on a lot of places. I do recommend just go to this place and read it. It's amazing. Or maybe I'm just excited about the current page. Okay. So any more questions or can I move on? No, there were no more questions. Okay. So I was just saying Rita had like a starring face and a head exploding emoji. Andres said, thank you, Lana. And Andre was the one who asked about the feature and the one liner. And then, and then I totally was saying, you're amazing. You deliberately made mistakes to show us how even, even seniors can make mistakes. And I just said the beauty of it is that even senior developers have hiccups. They just know how to tweak things to get it all working. Oh, I made mistakes. And I did it on production and all, you don't want to know. But maybe you want to know. Yeah. You'll make mistakes a lot of times. So. What I have here is now new. You see all these posts, but basically it's just a fresh WordPress. Or maybe not. Let's see. WP. For Virgin. Oh, it's fresh. Okay. What I want to show you today is. How you can use some commands to come, combine dates with the PHP. And if you ever saw me doing WP CLI, you saw probably days that would be evil. And then I said echo. And. And this is what you probably saw. And this, when you run this command in WordPress install, this is what you get. You get logging URL. Now this is useless because. You see it's connected. You can't just click on it because. It doesn't have a new line. So what you can do is. Just add here. Like. New line. And there you go. So you can click on it now and you go to. And that's what you can do with evil. So evil is just executing arbitrary PHP. I used it so many times. So I have a functionality that is. Really big. And maybe. I usually use it. I use it. I have some external API. I need to import only once. I don't need, you know, Chrome jobs. I don't need it to happen. A lot of times just once. And I wrote the functionality and it's working. That's the, that's the local. And I don't want it to be ever executed without my knowledge. So. What I do. I just upload functionality to. Server. And I go to SSH and execute it. And it just imports everything and it's clean. So nobody will ever execute it because nobody knows. Okay. So that's what's useful. There is also another. Command that you can use to just check things. And it's with PHP. So if you are more comfortable with PHP. You can use shell. And. It will open. PHP shell. There we go. Unable to track. Okay. I don't know if my WPC is updated here, but this will open PHP shell. And you can run any PHP. Like. For example, you can run any PHP. You can run any PHP. Like. For example, get users. And you get users. So you can check things. If you don't know. What's happening. On. What, what is the result? What is the output of something? You can run it in. This one. In shell. And. It's very, very helpful. If you start. Using it. If you need to, if you need to, a lot of checking what's happening on the server. And. It's production. You can't really go and print things. All over the place. So that's a very good. And for debugging as well, you know, you can see what's. What's going to happen. What's going to be returned. So that's another thing for PHP developers. But there is another thing that. You can run any PHP. You can run any PHP. You can run it. So you can run it on PHP first, but there is another thing that. You can do. And then. Just. I'll show you, we can execute. This is great. So we are going to create PHP file inside of this is WordPress. So it's not going to be a plugin. And let's say test.php. Now we have here this test PHP file. And I'm gonna open it with code because I want syntax highlighting. I used to create plugins in terminal. It's not fine. It is a bit, but it's easier to do it actually in code editor. So let's open that one. And here we have this one. So let's just say like this is just the best file. That's it, okay. And let me say like it works. So this is very, very basic, but what we can do here, we can say WP evil file test. And it says it works. So again, not very useful here, but for that, we have something magnificent and it's internal API. My internet is a little bad today, but you're gonna get there. Well, while we're getting there, Milana, I actually have a question unrelated to this, but I just noticed that you're, as far as I can tell, you're running Windows. No, I'm running Windows. Oh, okay. Sorry, okay. Sorry, I thought you were in Windows. That's cool. Then my question doesn't exist anymore, do I? Yeah, I know that setting up Windows, WPCLi on Windows is mess and WPCLi doesn't officially support Windows. So that's why I always tell people, if you have Windows and you're running WPCLi successfully on it, please log about it. Create tutorial. Well, that's the reason I'm asking because I want to create a tutorial specifically for that. And I thought you had it writing and I was gonna ask you what you mean. No, no, I don't have. Okay, so here we go. And what about Mac? I mean, does it work on Mac or only works on, I mean, Linux? No, no, no, it's supported on Mac and on Linux. Oh, okay. It works out of box. Unix, yeah, yeah, Unix, yeah. Okay. Windows is a little bit problematic. It can run. I saw people making it run. Some commands behave very strange and it takes a little time to set everything but it doesn't run out of box and maintainers just don't have a time to support it. So it's unexpected for now. So here we have internal API from WPCLi and this is for output. So this is how we want, how we can do things, you know, how we can display stuff. So with log, we can just say, we can create just a message. Okay, right. And this is how it looks like. See? So we can just say this WPCLi and I'm gonna say this one and because we are translating everything, right? I don't know, it can be WPCLi, right? And now when we, oh, it works, it works. Hold on. It should be just once. Here it is. And if we would say like error or maybe success, let's say success instead of log, it works. Awesome. So this is very interesting and you can use it to do stuff but not very useful and we can make it useful. So I don't have anything specifically weird on this WordPress install, it's just a fresh install. So I'm gonna use users and I'm gonna show you that you can, you can do this thing that I wanna do. You can do that with WPCLi right away from terminal because users are standard object in WordPress, standard entities, but if you have something that is not really standard that is custom made, you might find this useful and you might get some ideas how to do more stuff with this, what I'm gonna show you. So what I'm gonna do, I'm gonna export users and but I don't want to export everything. So I show you already with Shell when you say get users, you see you get a lot of data. I don't want to export all of that. I just want to export like for stuff like user login ID and maybe email, I don't know, maybe password because I want to import it somewhere else. So maybe just for stuff I want to export, I don't want all of this and you can do that with WPCLi. You can say WPC user list and you can use like, let's see how we can say which fields, see here, we can say which fields we want to export. So we want to show user login, no, this my name ID, user login, user email and user pass. So all of it has user except for ID. Okay, let's say fields and reset ID and then user login, user email and user pass. Now, if I do it like this, it will just display it here. But if I do, you know what? I'm going to generate some more users, let's have them 100, why not? Because it's more interesting, loading. You can also create with internal API this loading progress bar, it's lovely. So now I can list users and it's beautiful and you see I have only these four columns, these four fields I wanted. So if I do it again and do this, so this is just showing where to put that output and I say, for example, user see as we and now when I, you see, I have user CSV and when I want to open it, let's open it. Let's open here with this one. You see, it's the actual users, it's actual CSV files. So you can do that very easily with anything, any entity. And what you have here is those four fields. So it's like a table title. Maybe you want it without the title and we are going to do it right now. So what we can do here is, let's just move this. We wanna say users and it's gonna be get users. So let's see what the documentation say. This is usually what I do. So this is not just to show you where to find stuff. I usually go to documentation to check what's there because sometimes I know things by heart, but sometimes I just don't want to face the error and then go just, go and check it. So this is what we want, we want. No, it is practically impossible to learn all these syntax by heart. Yeah, yeah, so yeah. Some things you can know because you do it a lot of times, but I don't know if it's a plural or singular and what parameter is first, so I always go there. So get users is actually taking an array of arguments. So we're gonna say here, and then we wanted fields. And fields is also an array, or it can be string. Okay, we are gonna do that. Array, or it can be string. Okay, we are gonna do the array. So we want, and you notice this is very convenient. User pass, user email, so everything is the same. So WPCI use everything the same, so it's very convenient. So the fields, again, it's an array and the fields are gonna be OD and then user, what was that? Logging, right? Logging, and then there was user email and user pass. Now coding standards say you have to have comma after the last item in an array of get users not exactly. Okay, so when we do this and let's say print this one, I'm gonna run on this side. So now you will file and this is what we get. This is our print for, we have objects of users now. So now with that, we can export that in CSV file and with PHP, we are going to use a function that is pure PHP, right? C and C, PHP, it's called output file with CSV. Right, or format line as CSV. Okay, so I didn't understand the name correctly that I remembered it as file put. Okay, so here we have example. To make this work, we need three PHP functions. It's not just F put, it's also F open and F closed. So we need to open file, put in there and then close the file. So we have our array and we're gonna just copy this and paste it here. Now I'm gonna call this file users, but let's say PHP, like coming from PHP. Now this WV means, let me go here, F open. It means write, but it's, oh, here, it will point, the pointer will be at the beginning of the file. So everything you already had in a file, it will be rewritten. So it will behave like it's just a new file. If you want to add to it, you're gonna use A as a pen. But right now we're gonna use just B and then we need to change this. So this is gonna be users as user. And here is so coding standard, web spaces. So what we do, we open this file users PHP, we write to it for each users as user and we put it into file and then we close file. Now I'm not gonna waste your time now on error that we will get here. And why we are going to get error because it says here we have the stream, first parameter is stream, that's the stream here, the file. Then we have fields and here it says an array of string. What we have here, users is returning array of objects. So it's gonna make an error and we don't want to waste time now. You can play with it, you can run it and see what's gonna happen. But what we need to do, we need to convert these objects into arrays. And there are easier doing like doing this. And if you're in a hurry, but I like to show you what exactly happened. So I'm gonna save user array equals array. And here I'm gonna use these to make it quicker. And actually let me copy this. So let's be a little bit productive. And this is gonna be this. Okay, this is just a little bit past copy, but this is how we convert. And now instead of object, we are gonna put array. So this is gonna be for every row. So for each users, we will have each user will be another row. And we can do... So if we run this like this, what's gonna happen, we expect this file to show up and let's see. So now if you list it, this file showed up, but we didn't see what's happened there. So we can open it and check it's there. As you can see, it doesn't have any headings for columns. That's what we wanted, I guess. But to have like output, to have feedback what's happening, we can say right thing and maybe stay, or it can be creative as well, but let's do it like this. And now you see the feedback, what's happened. Feedback, what's happened. Now, when this is done, or maybe you want to have a table, I don't know, maybe to show it. You know, you can do that with internal APIs. So what you are going to use is this format items. So this is how you use it. Let me copy paste. Copy paste is a best thing for developers. So let's see what's happening here. It's format table, you can use table JSON, SCV, CSV, YAML, so whatever items is an item. Array of items. So we need every user array to be in another array. So let's create this array here because this is array of objects and it's not gonna work. So let's say here output equals array. Let's just declare this empty array. Now, we're gonna add to this array each of these users and items is actually now this outputs, right? And that second parameter, the third parameter is named fields for each item data. If you take a look at this example here, key value, this is key value. So these are just titles for the table and what we can do here, not to repeat ourselves, we can take these fields. So this array and you can say fields equals this array. And then this one will be fields and now we can use those fields here as an array of this, oh, sorry. And this should give us the table and yay. So we have table, but we also have this success, right. So this is for exporting and now we have this file that we can export and then we can import somewhere else and we have enough time to import them as well. So we're gonna make another file and let me just rename this file. So it's not gonna be called. So if you want to rename something in terminal, it's actually what you're doing is moving. So move test PHP and we are gonna say export users PHP. So it thinks it moved file to the same location but with different name. And now when you see there is no test but there is export users PHP. Okay. So now we are going to create import users PHP. That's import users PHP and let's open it with the code. So here you can just write the command how would you run this file? Evo file import users PHP. So you don't have to think about it. You can just copy paste. Okay. And again, we're going to use PHP for this and what we need is get CSV. Right. Now we are gonna get the file. It's again stream. And again, you have file open and then length separator and close and escape. And here we have the example. So let's see row one. We don't really need rows. Our loop is gonna be much simpler than this. So let's see what we have here. We have candle. So we are opening file and we are checking if it exists in the same. So what we are going to check for, hold on. No, no, no, we are checking for this file. Users copy paste. Okay. F open R. I assume it's read. Open for reading only. Okay. Nice. Then while we have, and now the data is getting is getting from this file from handle. This is stream and now this is number. So let's see. Length must be greater than the longest line. So if you wanna be sure. So this is very like arbitrary. Okay. I don't know how many I have. So you just put like, you can use some PHP constants there for maximum number or whatever. Then, so you want to make sure that you will get all of them or maybe you just want first 10 or whatever. So you can define it there. Then the separator and the separator because we are using scv CSV file, then it's gonna be the comma and then. So if we have data, now count data, we don't wanna count. Maybe we do, but I will leave that to you to play afterwards. And this we don't need. Let me just delete all of that. And after we are gonna close the file. So let's just print out this data to see what's gonna happen. So now we run this file. And this is what we have. We have, oh, this is interesting that we don't really need this, right? It's confusing. This is what I'm used to have. Okay. So we have array of all these users. Now, these are the users we already have in this install and I don't wanna create another install. We don't have enough time for that. So what I'm gonna do, I'm gonna delete all the users that we have in this, we have in this install. And then I'm gonna import the users from here. So how you do that from the file? Now this is gonna be the inception. We are gonna run WPCLI command to run PHP file in which we are gonna run WPCLI command. This is crazy. So execution, this, you wanna run WPCLI command. You have some options here, but we really don't need any of those. We don't even need this. So you see, it doesn't have this first WP in command. So what I'm gonna say here, WP, it doesn't have, I just said it. User delete, right. So we need to delete all the users, but for deleting all the users, we need to run through the loop and that's gonna be, I don't know if that's possible here. So let me show you, I'm gonna comment this out. So when we wanna delete users, WP user delete. You see user is mandatory. All of these in these brackets are mandatory. All parameters in square brackets are optional. So we need this. And this is user login, user email or user ID. Now to do it, we are not gonna do it one by one. It's just insane. That's why we use terminal and not to do things like that, not to repeat. So we're gonna make a loop and we make loop with another command. Now that's what's done with, in terminal, that's very easy. If you wanna run another command in command, you just type dollar sign and brackets. I don't know what's the exact name in English. So inside these brackets, you can run another command. So I'm gonna look through this like with WP user list. Now when we list users, you remember we had the table and that's not gonna work. For this, we need either ID or email or username. So what we can do, we can just return a field that will be field, will be ID. I don't know if that's, let me check WP user rules. If we run one ID, one field, yeah, we can do it like that. Okay. So field is gonna be ID and I think that's it. User list, field ID. Let's see. Reassign. Yeah, of course. So now we deleted all the users. Great. WP user list, nothing. So let me see if I can just use it here. Let's generate some users. WP user general route. And let's say count 10, we don't want more. Okay, so let me see user list. Okay, we have 10 and I'm gonna run now this file just to see if it's gonna work. That I delete all of them. Yeah, cool. So you can do it like this and now we have no users but we have them all exported to this file. And we saw that this is array of, so each user is array, I believe. Let's run it again because I forgot what we saw here. So very quickly, Milona, there's another question which we can get back to much later but Sega had a question about when you run that use the delete, does it delete the related data too? And my understanding is that's what that reassign question was about because in the, yeah. So if you have to reassign the articles to some other users that we are deleting all of the users. So I don't know, let's check here. This is our, so all the posts are here by no one. So the posts exist, you can assign them to some other users and we'll check. This is a good question and good moment to ask. So we are gonna check when we import all the users, we're gonna check to see what will happen if they're gonna be back to their posts. So right now, we have this array of, user data and now let's use just WordPress command to create user command function because now we are doing the PHP. Let's create user, let's see. So what we have, username is the user name data, data one, then password is data three and email is, I believe data two, right? It's data two. Do we have anything else? No, that's it, okay. So let's see what's gonna happen. We can also add, what's the problem here? Unexpected, oh, sorry. Okay, and we can add here like a little feedback, right? Where is the expert users? So user name, yay. And this should be it, let's see what's gonna happen, right? Oh my God, right, let the user list and they're all there. So now I can do this and every time I want to import, I can just delete all of them and then import and that's about it for today, I think. Cool, there was another question earlier, which if you wouldn't mind, when you were doing WP shell and it totally asked about can you run sort of WordPress functionality using WP shell? And his example was for example, getting a post or getting some custom fields. Maybe if you want to show what stuff, like a simple example would just be run get posts inside WP shell, let's just show folks what that does. Let's just check this one that we said, oh, it's not reassigned. That's probably because ID is different because we didn't insert the ID. Okay, that's another thing to learn. So that would be shell. We wanted to, yeah, let's see, let me log in here, password, username. Okay, I don't need to log in. Let me just take those with, so we were at the post 35, this is the ID 233. Now let's go back to shell and let's say get post meta for 233 post, it's empty. What function do we have any example there? I mean, you could just run get posts, for example, and just show what that does as it is. Yeah, you just say get posts and just show. We did it with users, so here you have this. You can run anything that you can run in a file on WordPress, you can run it here in shell. And you can run all the other functions to get data from, let's see, what is the function to get PHP info? It's PHP info, right? Yes, just PHP info, yes. Without the underscore, it's just one word, yeah. Right, so you see, you get that. You can run any function, PHP or WordPress, so you can get all the data you want. And you can do the dry run, so you can just see what's gonna happen if you would run it, but not actually run it. There are a lot of possibilities to do. So whatever is more comfortable to you, is it PHP, is it WPCLi, or you can combine it, whatever is quicker, you can use it. Perfect, and then just one last question, Karthik asks if you wouldn't mind pasting your PHP code that you were writing up today, the test code that you were working on, would you mind sharing that either somewhere online or in the chat or something like that? Yeah, I will put it in GitHub repository. Okay, perfect. And then what we can do is we can link it in the meetup comments. Yes, yes. Cool. Awesome. Well, that was fun. I learned so much about what WPCLi could do. I didn't know that you could run commands within commands. That was very cool. That actually, that is what makes the terminal so powerful when you start combining it with other tools that's blowing mine, you know, I was deleting 20,000 posts and I was like, oh my God, this is great. Just watching it delete, you know, you don't do anything. So that's where the full power is. Absolutely. Awesome. Awesome. Well, I think those are all the questions we've dealt with. So thank you, Milana, for sharing with us today. I love the fact that when you write your code, it works perfectly first time. That was brilliant. No errors here. Thanks, folks, for joining. If you do have any other questions, you're welcome to post them in the meetup chat and we'll follow up with those. We'll also get this recording up to WordPress TV within a few days so that you can check this out. If you're watching this online and you have questions, feel free to post these in the meetup. Again, thank you, Milana, for hosting. It was lovely. Thank you everybody for joining and we'll see you around. Thank you, Milana and Jonathan. Thank you very much. Thank you. Thank you, Milana. Awesome, awesome. Thank you. Bye.