تماشای این درس نیاز به اشتراک حرفه‌ای دارد.

Ordering constants first0:00

Now that we have all the pieces of our Model class, we can start to order them. At the highest level, that order is going to be constants, followed by properties, followed by the methods. For the constants, we can simply order those by name, and the same for the properties. But the methods will have a special ordering. So let's start with the easy ones. First constants, we'll loop over those as instances, constants, constant. Let's start accumulating a new definitions string, where we'll store the ordered definitions. So for each one, I'm going to want to extract that definition, and to do so I can pass that in the constant, and I'll need the class file as a set of lines.

So for each one, I'm going to want to extract that definition, and to do so I can pass that in the constant, and I'll need the class file as a set of lines. To get that, instead of using file_get_contents, we can use file. This returns an array with each line as an element, still including the line breaks. We'll change this variable to lines, but our parse doesn't take an array, it takes a string, so we'll need to implode those back together again. Remember, lines contains all of the original line breaks, so there's no reason to implode it with a new line. Alright, let's go back to working on this extractDefinition. This is going to return a string, and it takes an array, which will be the definition, and

Extracting definition lines1:27

Alright, let's go back to working on this extract definition. This is going to return a string, and it takes an array, which will be the definition, and the lines are an array. In the simplest form, we would return the implode of the array_slice for that definition's line segment. So we can take lines, we can take the startingLine, and then the definitionLineEnd minus the start. Now, I've created a temporary variable for start, and that's because we can't simply use the start line of that definition. If we go back to our license file and take a look at something like guarded, we'll see

use the start line of that definition. If we go back to our license file and take a look at something like guarded, we'll see that it's start line is 20, but really it's start line is 17 because it has a comment. So start is going to depend on if the definition has a comment. If so, I would want to use the definition's comment start line. Otherwise, I can use the definition's start line. Uh oh, that shouldn't be two question marks, that should be a colon. Okay, we should be free of any syntax errors. Let's go back up, and before moving on to properties, let's simply echo out the definitions. I'll remove this print_r, and instead let's default this to an empty string.

Debugging extraction errors2:57

Let's go back up, and before moving on to properties, let's simply echo out the definitions. I'll remove this print_r, and instead let's default this to an empty string. Jumping back to the command line, if we run php artisan shift, run, order, model, uh oh, we have an issue. Undefined array key constants. Let's take a look at our class definition finder. Okay, in process we have constants, so that's correct. The issue here is that we're looping over multiple instances, but really we're only ever going to have one class in a file. So I think it makes sense to get rid of this foreach loop and simply return the very first.

ever going to have one class in a file. So I think it makes sense to get rid of this for each loop and simply return the very first instance. So let's change these to instances, zero. Alright and it looks like I missed a little curly here, let's clean that up. Run it again. Undefined array key comment. Okay, we're getting a little farther. Comment. Let's go down and take a look at constants.

Comment. Let's go down and take a look at constants. Ah, I called it comments. I'm not sure why I pluralized it. I guess maybe because it could be multiple lines, but since I just wrote this as comment, let's go ahead and take the opportunity to clean up our code. Anytime I'm confused about a name of something and find myself naming it something different later, it makes more sense for me to just go ahead and change it, because clearly that name is more natural to me. Alright, let's clear out all this noise and try one more time.

name is more natural to me. Alright, let's clear out all this noise and try one more time. Okay, we don't have a failure, but I'm also not seeing that class constant. Remember, license has this max activations. So I should be seeing that. Let's take a look. Our issue here is the classic zero based array versus the line count. Line count starts at one, but our array of lines is going to start at zero. So start is really start minus one. Another got you is the length.

So start is really start minus one. Another got you is the length. Think about when the start and end line is the same. Our length is going to end up being zero. So I've learned that we should pretty much always add one to the length. Alright, let's run this one more time. And there we go. There's our constant. Good. I think we're on the right track.

Ordering and sorting properties5:09

Good. I think we're on the right track. Oh, looks like I have a little typo here. Let's go ahead and fix that while we're at it. Definition. Alright, cool. We're using this up here for constants. We can do the same thing for our properties. So let's change constants to properties. And let's change this temporary variable as well to property.

So let's change constants to properties. And let's change this temporary variable as well to property. And if we run this again, we are getting our properties. We need a little breathing room between this. So since we're accumulating these lines and we're only taking the exact definition, it's safe to go ahead and add line breaks between them. So at least give us the breathing room and then, like before, we can trust our formatter to clean up anything else. Alright, that's looking a lot better. Now our issue is we're not actually sorting them.

Alright, that's looking a lot better. Now our issue is we're not actually sorting them. These should at least be sorted by name. We only have one constant, so there's nothing to change there. But cache should be before guarded when we're talking about the properties. So let's update these definitions to be ordered. We'll say orderBy name. And we'll pass in the set of definitions. Let's clear out this comment and go ahead and generate this method. Alright, this is a generic method, so we'll just call it items and it's going to return

Let's clear out this comment and go ahead and generate this method. Alright, this is a generic method, so we'll just call it items and it's going to return an array. And in this case, we can use a simple uksort. That's going to be on the items and it needs to take a comparator function, which accepts two items and compares them together. We can just do a simple natural string comparison on those two items, so a and b. What this method does is return negative 1 when a is less than b, 0 when they're equal, and greater than 1 when b is greater than a. Since this works on a reference to items, we'll need to return the now sorted items.

and greater than 1 when $b is greater than $a. Since this works on a reference to items, we'll need to return the now sorted items. Alright, let's clear out the old stuff, run this again. And there we go. Casts is first and guarded is second and look at that, our Comment is also associated with guarded correctly. Alright, we're getting closer. Let's move on to the hard stuff. We need to also do the same thing for methods. So let's copy this orderBy name for methods, change things to methods, we'll call it method.

Defining method order rules7:27

We need to also do the same thing for methods. So let's copy this orderBy name for methods, change things to methods, we'll call it method. Let's just run this to see how things are looking. Great, it is getting the methods, but they're not sorted in that special way that we want. I think this is a good opportunity to go back to Tlint and take a look at how they order their models. So right away we can see their order here in their own class constant. So I'm going to copy this and adjust it for ours. Let's go back up to the top, drop in our own constant. I don't think there's a need to key this array, so let's go ahead and just clean that.

Let's go back up to the top, drop in our own constant. I don't think there's a need to key this array, so let's go ahead and just clean that up real fast. Okay, good, and let's start adjusting it. I want the constructor to explicitly be at the top, so let's add a new one for constructor. Then we have these lifecycle methods for models. Those are pretty straightforward. I'm actually going to move custom static down. I don't mind those being their own little section at the bottom of the class. Again, I really want Laravel's stuff at the top, so I think relationship methods are next.

I don't mind those being their own little section at the bottom of the class. Again, I really want Laravel's stuff at the top, so I think relationship methods are next. I'm going to move scopes a bit lower, and I'm actually not going to differentiate between accessors and mutators. In Laravel 9, there's a new attribute method, and I think that's becoming more popular to use, so let's just call this attribute. Okay, I feel pretty good about this order for my classes. Again, this is something you can adjust for your own projects, but let's get this working. If we go back down to our methods, we're going to want to order by type. Now type isn't something that we have on our methods yet.

Assigning method types9:08

If we go back down to our methods, we're going to want to order by type. Now type isn't something that we have on our methods yet. Let's go ahead and create this method, and for now, I'm just going to return methods. Go ahead and give this a type hint while we're down here. Jumping back up to our loop, before we can do anything with these methods, we actually need to assign their type. That's not something we were able to pull from the finder. We're going to need to do that ourselves, so let's create a temporary variable for methods and make a new helper method called addMethodType, and we'll want to pass it in the methods and instead in our loop, use this new array.

and make a new helper method called addMethodType, and we'll want to pass it in the methods and instead in our loop, use this new array. All right, let's generate our new method. It's going to also return an array, it's going to take the methods, and essentially what we're going to do here is map in a new element on our methods array. For now, let's just make a function placeholder that takes the method and loop over methods, and we can go ahead and return this. Everything's going to happen in this callback. To keep this callback from getting crazy, we can just say methodType is equal to this methodType and pass it in the method, and ultimately return method with this added type.

To keep this callback from getting crazy, we can just say methodType is equal to this methodType and pass it in the method, and ultimately return method with this added type. Now methodType is where the magic's going to happen. It takes an array, which is the methodDefinition, and it's going to return a string. So let's start working through what we know. We know that if the methodName is equal to construct, then by the rules of PHP, we would know that that would be the constructor. That's pretty straightforward. Similarly, we would know that if the methodName were in the set of names for the different booting methods, so booting, boot, and booted, then we could just return the methodName.

Similarly, we would know that if the method name were in the set of names for the different booting methods, so booting, boot, and booted, then we could just return the method name. Now while the name matches, Laravel has some more requirements on these methods. They have to be public, and they have to be static. So let's add in that additional logic. If method visibility is equal to public, and method is static, and its name is booting, boot, or booted, then we know we could return that specific type. Alright, we also need the attribute method, scope methods, static methods, and ultimately custom methods. These all have similar logic to what we've already written, so with the power of video

custom methods. These all have similar logic to what we've already written, so with the power of video editing, let me bring them to life. The one that's not very straightforward are relationship methods. So let's write that one together.

دوست دارید گاهی خبرهای Laracasts را ایمیل کنیم؟