Closed (fixed)
Project:
Search API
Version:
8.x-1.x-dev
Component:
Framework
Priority:
Normal
Category:
Task
Assigned:
Unassigned
Issue tags:
Reporter:
Created:
1 Apr 2014 at 20:16 UTC
Updated:
15 Aug 2016 at 14:14 UTC
Jump to comment: Most recent, Most recent file
Comments
Comment #1
drunken monkeyI spoke with Andrei. His suggestion is to first split out all the fields-related functionality into a service and then review what's left.
One issue there would be that the methods for creating a query (and others) could still not be switched out. So probably we'd then need a second service for those other methods that someone might conceivably want to override.
Comment #2
drunken monkeyComment #3
nick_vhComment #4
drunken monkeyWhile we're at a major overhaul of that class, we should also pick one of
self::orstatic::for inner-class calls and stick with that – currently, it's just arbitrary, and we should at least be arbitrary and consistent. (Probablystaticis better, in case anyone really does extend the class, however improbable. It's also more often used currently (14 vs. 6).)Comment #5
drunken monkeyTo support the (theoretical) use case of #2230907: Split up Utility into one or more services, or similar ones that might come up, making this a service (or a collection of several services) seems to make the most sense.
(In which case the
self/staticquestion becomes moot anyways.)Comment #6
drunken monkeyFor those methods for which overriding them has no real use case, instead of leaving them in
Utilitysplitting them into traits and including those where needed would also be a variant. (Suggestion coming from Nick.)Would have the advantage of separating different functionality more cleanly. Not completely sure it's worth the additional code changes, though.
In any case, we should probably wait with this until less patches are in the queue, since this will most likely break all of them.
Comment #7
drunken monkeyOK, so I've finally tackled this, and the first idea I had was to keep
Utilitywith all its methods for now and just mark them deprecated. Then, in all new code, we can just use the new services and thus we should have a lot less trouble transitioning at some point during Beta (i.e., removing the methods fromUtility).Then, I saw that about 90% of
Utilityis indeed fields-related. I split those into their own service, which I calledFieldsHelper(better naming suggestions welcome). It also contains the three data type-related methods (isTextType(),getFieldTypeMapping(),getDataTypeFallbackMapping()) – if you think, we can also create a separate service for these.The
createQuery()method I moved/copied to theResultsCacheservice – a pretty good fit regarding considering the functionality (and that that method actually retrieved the results cache service), even though the naming is a bit weird now. Usually, people will useIndex::query()anyways, though, so it shouldn't matter much. On the other hand, we can also rename it to something likeSearchHelperorQueryHelper, if we decide that would be better. (Again, better naming suggestions welcome.*Service?*Manager?)The
processIndexTasks()I just moved to theIndexTaskManagerservice (keeping it static, though, by necessity (as far as I'm aware) – still, makes more sense there).This leaves five methods, which I think we can just keep as static
Utilitymethods:createTextToken(),deepCopy(),createCombinedId(),splitCombinedId()andsplitPropertyPath().We could also split them into one or more traits, but I don't really see the advantage of that (some of these are pretty ubiquitous, and having traits with a single method for the others would be also weird). But all is up for discussion.
Comment #9
borisson_I agree, that makes sense.
I don't understand the move into Item, I'd suggest we move this into src/Utility/FieldsHelper.php
I think we should, I suggest DataTypeHelper
The naming is very weird, let's move this into the Query class and rename the method to
::fromResultCache?I agree, that makes sense.
Sure, let's move those to src/Utility/Utility.php?
I also don't understand why you created FieldsHelperInterface, there won't be any alternative implementations of this and not everything needs an interface. So let's just remove that.
Comment #10
drunken monkeyOh, of course, this once again complicates the unit tests. A lot.
(Also, switching the new service and the
TestItemsTraitto camelCase for everything.)Comment #11
borisson_Back to NW for #9
Comment #12
drunken monkeyAh, sorry, cross-posted with you there.
Well, the functionality belong to items and fields, so that namespace/folder seemed natural.
Utilitywould have been an option, too, but I didn't want a namespace with just a single class (or class plus interface). But if we now get more classes there,Utilityis fine.OK.
That would completely defeat the purpose of moving it to a service in the first place – i.e., being able to switch the query class (see #1). So if the naming is too weird, I'd rather suggest renaming the service (and, possibly, the existing methods). Maybe
SearchHelper, staying with the nomenclature in this issue? Optionally, we could also move it toUtility.OK.
If there wouldn't be (the possibility of) alternative implementations, having it as a service would be pointless.
Also, we pass it to some constructors/methods and I dislike type-hinting with class names. When in doubt, I like to err on the side of too many interfaces. It doesn't really do any harm, does it?
Comment #13
drunken monkeyComment #15
borisson_Sure, SearchHelper makes sense - maybe QueryHelper?
I figured ::fromResultCache was a good name to keep in line with the URL object in drupal core. That has ::fromRoute, ::fromUserInput, ... and I figured this would make it follow that very closely. You can still switch the query class and have it extend the original query class, as long as ::fromResultCache returns new static, I don't see any issues with that. If you disagree, my vote goes to QueryHelper.
I don't think a service is pointless even if we don't see alternative implementations, it's easier to get a class like that from the container or have it injected with all it's dependencies.
It doesn't really do any harm, other than making the code a little bit more complex.
I understand the argument about not wanting to typehint on classnames though, so I guess keeping the interface doesn't hurt.
Comment #16
drunken monkeyYou can also just create a new class implementing
QueryInterfaceand use its constructor. Using a different query class in your own code is never a problem – the problem is being able to replace the query class in other people's code (such as the code contained in the Search API itself). It's probably rather a niche use case, but if we can support it without much hassle, I'd still call that a plus.So, I went with
QueryHelperand moved it tosrc/Utilityalong with its interface.Utilitydidn't have any dependencies, and just using the class name and doing a static call is certainly a lot easier than any way of obtaining the service. The main purpose of making it a service is not ease of use, in my opinion, but making as much code as possible overridable (either by other modules, or just for testing purposes).Comment #17
borisson_I think your branch is not rebased with the latest changes, there seem to be unrelated changes in the patch.
Comment #18
drunken monkeyOh, damn, you're right! Thanks a lot for noticing that, that would have been pretty bad!
Comment #19
borisson_These changes are unrelated, but I like them. Let's keep those in.
I like this change, is it possible to do this in other places as well?
Those are the only things I noticed - putting this back to NW for .2.
Comment #20
drunken monkeyAh, needed a (small) re-roll anyways …
I don't really know why I made that change, but sure, we can also do that in the rest of the test.
Comment #21
borisson_Awesome, if the tests agree with this, so do I.
Comment #23
drunken monkeyOK, probably just using
Utility::createField()there is the easier choice.Comment #24
drunken monkeyCommitted.
Thanks a lot for reviewing!