Open putzwasser opened 1 week ago
Attention: Patch coverage is 0%
with 10 lines
in your changes missing coverage. Please review.
Project coverage is 62.17%. Comparing base (
fadcf26
) to head (c5343b4
). Report is 5 commits behind head on 5.x.:exclamation: Current head c5343b4 differs from pull request most recent head 2df00f6
Please upload reports for the commit 2df00f6 to get more accurate results.
I would love to and tried.
I could figure out what to change for #13851 and this PR, but the remaining code is (still) too complex for me to figure out how to write a proper test.
I'd appreciate assistance here :)
The best way would be to make a functional test where you'd create a contact and a segment with the filters that causes this bug and run the command to build the segment and then assert that the contact was added to that contact correctly. Can this be tested anyhow on Mautic itself? For example by updating the lead_email_read_count
segment filter?
ForeignFuncFilterQueryBuilder and ForeignValueFilterQueryBuilder are pretty similar. The latter has a test already.
I guess, a proper test should be similar to the one for ForeignValueFilterQueryBuilder. I just fail to replicate and adapt it.
Can this be tested anyhow on Mautic itself? For example by updating the lead_email_read_count segment filter?
It all depends on the filter conditions. You don't need the additional DB table as "it just creates the SQL". This can be teted. (If you know how :sweat_smile: )
I'm wondering whether if you change this line:
https://github.com/mautic/mautic/blob/58c1903e8e2d76b8938948e826bdea015e2e3a28/app/bundles/LeadBundle/Services/ContactSegmentFilterDictionary.php#L83
to use contact_id
, would that segment work? This way you can simplify the testing steps and write functional test for it as well. Does it make sense?
That's not the issue. My problem is that the ContactSegmentFilterDictionary isn't populated correctly.
The class uses
private function fetchFiltersFromSubscribers(): void
{
if ($this->dispatcher->hasListeners(LeadEvents::SEGMENT_DICTIONARY_ON_GENERATE)) {
$event = new SegmentDictionaryGenerationEvent($this->filters);
$this->dispatcher->dispatch($event, LeadEvents::SEGMENT_DICTIONARY_ON_GENERATE);
$this->filters = $event->getTranslations();
}
}
to get/create the filter.
I pushed my WIP test. I tried to mock/recreate subscribing to LeadEvents::SEGMENT_DICTIONARY_ON_GENERATE
but I'm doing something wrong. The dictionary is still empty:
.^ Mautic\LeadBundle\Segment\ContactSegmentFilter^ {#874
+contactSegmentFilterCrate: Mautic\LeadBundle\Segment\ContactSegmentFilterCrate^ {#291
-glue: "and"
-field: "contact_id"
-object: "lead"
-type: "number"
-filter: "2"
-operator: "gt"
-sourceArray: array:8 [
"glue" => "and"
"field" => "contact_id"
"object" => "lead"
"type" => "number"
"operator" => "gt"
"properties" => array:1 [
"filter" => "2"
]
"filter" => "0"
"display" => null
]
-nullValue: null
-mergedProperty: []
}
-filterDecorator: Mautic\LeadBundle\Segment\Decorator\CustomMappedDecorator^ {#834
#contactSegmentFilterOperator: Mautic\LeadBundle\Segment\ContactSegmentFilterOperator^ {#796
-filterOperatorProvider: Mautic\LeadBundle\Provider\FilterOperatorProvider^ {#828
-cachedOperators: []
-dispatcher: Mock_EventDispatcherInterface_bb01641d^ {#655 β¦3}
-translator: Mock_TranslatorInterface_69a4af1a^ {#803 β¦3}
}
}
=====βββββ=====
#dictionary: Mautic\LeadBundle\Services\ContactSegmentFilterDictionary^ {#830
-filters: []
-dispatcher: Mock_EventDispatcherInterface_bb01641d^ {#655 β¦3}
}
}
=====βββββ=====
-schemaCache: Mock_TableSchemaColumnsCache_84d8166a^ {#872 β¦5}
-filterQueryBuilder: Mautic\LeadBundle\Segment\Query\Filter\ForeignFuncFilterQueryBuilder^ {#606
-parameterNameGenerator: Mautic\LeadBundle\Segment\RandomParameterName^ {#402
#lastUsedParameterId: 0
}
-dispatcher: Mock_EventDispatcherInterface_bb01641d^ {#655 β¦3}
}
-batchLimiters: []
}
This dump comes from:
class ForeignFuncFilterQueryBuilder extends BaseFilterQueryBuilder
{
public function applyQuery(QueryBuilder $queryBuilder, ContactSegmentFilter $filter): QueryBuilder
{
dump($filter);
It should be
#dictionary: Mautic\LeadBundle\Services\ContactSegmentFilterDictionary {#1800
-filters: array:44 [
...
"type" => "mautic.lead.query.builder.foreign.func"
"foreign_table" => "test_table"
"foreign_table_field" => "contact_id"
"table" => "leads"
"table_field" => "id"
"func" => "count"
"field" => "id"
"where" => "some_bool = 1"
]
]
43 filter items are Mautic's default filters and the last one the custom filter.
I pushed my WIP test
I don't see it
I noticed, I just committed (to the wrong branch) and didn't push 5 min ago :facepalm:
Came here to check it is published now. But you already caught me :sweat_smile:
I don't see anything obvious. Try to go line by line with Xdebug to understand what's going on.
Description
This PR adds the possibility to use ForeignFuncFilterQueryBuilder with a custom
WHERE
clause.This makes it possible to create more sophisticated segment filters more easily. The SegmentFilterSubscriber in the PointBundle is an example for this (but it uses
ForeignFuncFilterQueryBuilder
).This is already possible in ForeignValueFilterQueryBuilder (L44), but not in ForeignFuncFilterQueryBuilder. This PR makes both filter "behave" similarly.
Under the hood: CustomMappedDecorator::getForeignContactColumn() looks for the
ContactSegmentFilterCrate
fieldforeign_table_field
.NOTE: This PR builds on #13851 (this PR's branch is based on that PR).
π Steps to test this PR:
Open this PR on Gitpod or pull down for testing locally (see docs on testing PRs here)
Add a custom table to your database for a custom segment filter. Use this SQL (it creates the table
test_table
and adds 4 rows of data to it):Create a test segment filter subscriber. Create the file
app/bundles/CoreBundle/EventListener/TestSegmentFilterSubscriber.php
in your CoreBundle's event listener directory.This creates a new custom filter. This filter counts how many times a lead is referenced in the new
test_table
IF the columnsome_bool
istrue
(Note: WHERE can be any filter condition, though).Clear the cache.
Create a new segment and use the new filter:
Run
php bin/console mautic:segments:rebuild
Contact with ID 1 gets added to your new segment.