Skip to main content
5 of 5
Fixed mistake

I haven't tested it but it should give you a pretty good idea on how to set this up.

public function actionTest() {
    $entryQuery = Entry::find()->section('mySection');

    // All the element relations. For example tags and categories.
    // These have to be Element objects. For example craft\elements\Tag.
    $myArrayWithTags = [/* ... */];
    $myArrayWithCategories = [/* ... */];
    $allRelations = array_merge($myArrayWithTags, $myArrayWithCategories);

    // Filter by relations
    $this->_applyRelationFilter($entryQuery, $allRelations);

    // Filter by custom fields
    $this->_applyFieldFilter($entryQuery, 'myRadioField', 'value2');
    $this->_applyFieldFilter($entryQuery, 'myNumberField', 3);
    $this->_applyFieldFilter($entryQuery, 'myCheckboxField', ['option1', 'option2']);

    // Build response string
    $content = "Entries:<br>";
    $content .= "<pre>" . json_encode($entryQuery->all()) . "</pre>";

    // Respond
    $response = Craft::$app->getResponse();
    $response->content = $content;
    return $response;
}

private function _applyRelationFilter(ElementQuery $query, array $elements) : array {
    $relatedTo = [];

    // Build the list of relations in the correct format
    foreach($elements as $element) {
        array_push($relatedTo, [
            "targetElement" => $element
        ]);
    }

    // Create an array with and as the first value so 
    // the result only contains elements that have all the set relations
    $relatedTo = array_merge(['and'], $relatedTo);

    // Set query relatedTo
    return $query->relatedTo($relatedTo);
}

private function _applyFieldFilter(ElementQuery $query, string $handle, $value) {
    $query->andWhere([
        ('content.field_' . $handle) => $value
    ]);
}

You need to have the following imports:

use Craft;
use craft\elements\Entry;
use craft\elements\db\ElementQuery;

Info about querying by custom field: https://craftcms.stackexchange.com/a/22995/9754