Самый простой способ - использовать один массив с правильной вложенностью:
Persons::find()
->select([Persons::tableName() . ".[[first_name]]"])
->where([
'or',
['<', 'age', 21],
[
'and',
['>', 'age', 21],
[Persons::tableName() . ".[[first_name]]" => 'John'],
],
]);
andwhere()
и orWhere()
всегда добавляют новое условие к существующим условиям, поэтому вы получите что-то вроде:
(((<first condition>) AND <second condition>) OR <third condition>)