1
votes

I have a has_one in one of my models. But it exceeds the dropdown_field_threshold. But in the getCMSFields method I have changed the query for that dropdown. But since it already exceeds the threshold before this method is called, the dropdown is converted to NumericDropdown or something like that.

Is there a way to alter the query before the threshold gets checked?

By the way, I know I can make a custom dropdown with my own query. But Silverstripe already handles a lot, so it would be better to just alter the query.


Edit: Example code

public function getCMSFields() {
    $fields = parent::getCMSFields();
    $questionnaire = $this->QuestionnaireSection()->Questionnaire();
    $nextQuestionOptions = $questionnaire->Sections();

    /** @var DropdownField $dropdownField */
    $dropdownField = $fields->dataFieldByName("NextQuestionID");
    $dropdownField->setSource($nextQuestionOptions->map()->toArray());

    return $fields;
}
1
Could you please share your code? - scrowler
@RobbieAverill Sorry for the late response, needed it that day, since I was on a holliday the day after. I added the code I'm using. Right now the threshold is exceeded because all "Sections" is too much, but I'm reducing the amount by only getting the sections of the current "Questionnaire". So I know after the reducing it shouldn't exceed the threshold anymore. - Kevin van Mierlo

1 Answers

1
votes

Unfortunately it is not possible to alter this query within the context of the class. An alternative may be to write your own scaffold function instead of calling parent::getCMSFields, but that is not really advised in this case.

If you have some way to obtain the current Questionnaire object globally, you could add an augmentDataQueryCreation function like below to QuestionnaireSection to add a where clause to the query that is being executed. Be aware however that this function is called in every case that QuestionnaireSection::get() is executed.

public function augmentDataQueryCreation(SQLSelect $query, DataQuery $dataQuery){
    $baseTable = $this->baseTable();
    $filter = 1; //Your global param here
    $dataQuery->where("\"$baseTable\".\"QuestionnaireID\" = $filter");
}

An alternative to prevent the DropdownField from being replaced by a NumericField is to change the threshold of this switch by adding the following code to your mysite.yml. This does not solve your problem entirely, but is a good workaround.

SilverStripe\ORM\FieldType\DBForeignKey:
    dropdown_field_threshold: 100000