true, 'targetClass' => StoredAdmissionCampaignReferenceType::class, 'targetAttribute' => ['campaign_ref_id' => 'id'], 'except' => [static::$SCENARIO_WITHOUT_EXISTS_CHECK] ], [ ['competitive_group_ref_id'], 'exist', 'skipOnError' => true, 'targetClass' => StoredCompetitiveGroupReferenceType::class, 'targetAttribute' => ['competitive_group_ref_id' => 'id'], 'except' => [static::$SCENARIO_WITHOUT_EXISTS_CHECK] ], [ ['curriculum_ref_id'], 'exist', 'skipOnError' => true, 'targetClass' => StoredCurriculumReferenceType::class, 'targetAttribute' => ['curriculum_ref_id' => 'id'], 'except' => [static::$SCENARIO_WITHOUT_EXISTS_CHECK] ], ]; } public function attributeLabels() { return [ 'id' => 'ID', 'campaign_ref_id' => 'Campaign Ref ID', 'curriculum_ref_id' => 'Curriculum Ref ID', 'competitive_group_ref_id' => 'Competitive Group Ref ID', 'updated_at' => 'Updated At', 'created_at' => 'Created At', ]; } public function getCampaignRef() { return $this->hasOne(StoredAdmissionCampaignReferenceType::class, ['id' => 'campaign_ref_id']); } public function getCgetEntranceTestSets() { return $this->hasMany(CgetEntranceTestSet::class, ['dictionary_competitive_group_entrance_test_id' => 'id']); } public function getCompetitiveGroupRef() { return $this->hasOne(StoredCompetitiveGroupReferenceType::class, ['id' => 'competitive_group_ref_id']); } public function getCurriculumRef() { return $this->hasOne(StoredCurriculumReferenceType::class, ['id' => 'curriculum_ref_id']); } private static function findBySpeciality( Speciality $speciality, ?StoredAdmissionCampaignReferenceType $campaignRef = null, array $educationTypeRefUids = [], array $profileRefUids = [], array $privilegeUids = [], array $specialMarkListUids = [] ): array { $curriculumRef = $speciality->curriculumRef; $competitiveGroupRef = $speciality->competitiveGroupRef; if (empty($curriculumRef) || empty($competitiveGroupRef)) { return []; } $tnCompetitiveGroupEntranceTest = DictionaryCompetitiveGroupEntranceTest::tableName(); $sets = CgetEntranceTestSet::find() ->joinWith('dictionaryCompetitiveGroupEntranceTest') ->andWhere(["{$tnCompetitiveGroupEntranceTest}.archive" => false]); $filterDatas = [ [ 'tableName' => StoredAdmissionCampaignReferenceType::tableName(), 'joinWith' => 'campaignRef', 'refData' => $campaignRef, ], [ 'tableName' => StoredCurriculumReferenceType::tableName(), 'joinWith' => 'curriculumRef', 'refData' => $curriculumRef, ], [ 'tableName' => StoredCompetitiveGroupReferenceType::tableName(), 'joinWith' => 'competitiveGroupRef', 'refData' => $competitiveGroupRef, ], ]; foreach ($filterDatas as $filterData) { [ 'tableName' => $tableName, 'joinWith' => $joinWith, 'refData' => $refData, ] = $filterData; $sets = DictionaryCompetitiveGroupEntranceTest::additionalFilter( $sets, $refData, $joinWith, $tableName ); } $filterDatas = [ 'privilege_id' => $privilegeUids, 'special_mark_id' => $specialMarkListUids, 'profile_reference_type_id' => $profileRefUids, 'dictionary_education_type_id' => $educationTypeRefUids, ]; foreach ($filterDatas as $filterRow => $filterData) { $sets = DictionaryCompetitiveGroupEntranceTest::additionalFilterByConditions( $sets, $filterRow, $filterData ); } return $sets->all(); } private static function additionalFilter( ActiveQuery $sets, ?ActiveRecord $refData, string $joinWith, string $tableName ): ActiveQuery { return $sets->joinWith("dictionaryCompetitiveGroupEntranceTest.{$joinWith}") ->andWhere([ "{$tableName}.archive" => false, "{$tableName}.reference_uid" => $refData->reference_uid ]); } private static function additionalFilterByConditions( ActiveQuery $sets, string $filterRow, array $filterData ): ActiveQuery { $tnEntranceTestSet = CgetEntranceTestSet::tableName(); if (!($buildAttributesForFiltering = CgetConditionType::buildAttributesForFiltering($filterRow))) { return $sets; } [ 'filterJoin' => $filterJoin, 'filterTableName' => $filterTableName, 'referenceUidField' => $referenceUidField, ] = $buildAttributesForFiltering; $sets = $sets->joinWith("cgetConditionTypes.$filterJoin") ->andOnCondition(["{$tnEntranceTestSet}.archive" => false]); if (!$filterData) { return $sets->andWhere(["{$filterTableName}.id" => null]); } return $sets->andWhere([ 'OR', ["{$filterTableName}.id" => null], [ 'AND', ["{$filterTableName}.archive" => false], ['IN', "{$filterTableName}.{$referenceUidField}", $filterData], ] ]); } public static function getDataProviderByApplication(BachelorApplication $application): ArrayDataProvider { $cache = []; $data = []; $sortedData = []; $campaignRef = $application->type->rawCampaign->referenceType; $tnSpecialMark = SpecialMark::tableName(); $specialMarkListUids = $application->getPreferences() ->select("{$tnSpecialMark}.ref_key") ->joinWith('specialMark') ->andWhere(["{$tnSpecialMark}.archive" => false]) ->column(); $specialitiesList = $application->specialities; $bachelorSpecialityService = Yii::createObject(BachelorSpecialityService::class); $hierarchicalSpecialities = $bachelorSpecialityService->makeSpecialitiesListHierarchical($specialitiesList); $specialitiesList = $bachelorSpecialityService->flattenSpecialities($hierarchicalSpecialities); foreach ($specialitiesList as $specialities) { $educationTypeRefUids = $specialities->getEducationsRefAttributeUidByPath('educationType'); $profileRefUids = $specialities->getEducationsRefAttributeUidByPath('profileRef'); $privilegeUids = []; $privilegeUid = ArrayHelper::getValue($specialities, 'preference.privilege.ref_key'); if ($privilegeUid) { $privilegeUids = [$privilegeUid]; } $key = $specialities->id; $data["{$key}_"] = []; $speciality = $specialities->speciality; $priorityList = []; $rowspan = 1; $data["{$key}_"]['priority'] = ''; $data["{$key}_"]['minScore'] = ''; $data["{$key}_"]['exam_form'] = ''; $data["{$key}_"]['allowMulti'] = ''; $data["{$key}_"]['discipline'] = ''; $data["{$key}_"]['parentDiscipline'] = ''; $direction_name = $speciality->directionRef->reference_name ?? ''; $group_name = $speciality->competitiveGroupRef->reference_name ?? ''; $data["{$key}_"]['subject'] = ['value' => "{$direction_name} {$group_name}"]; $data["{$key}_"]['bachelorSpecialityModel'] = $specialities; if ($specialities->isWithoutEntranceTests) { $data["{$key}_"]['priority'] = [ 'value' => Yii::$app->configurationManager->getText('text_for_set_when_speciality-bvi'), 'rowspan' => 0, 'colspan' => 4, ]; $data["{$key}_"]['subject']['rowspan'] = $rowspan; $sortedData["{$key}_"] = $data["{$key}_"]; continue; } $needEmptyMessage = false; $sets = DictionaryCompetitiveGroupEntranceTest::findBySpeciality( $speciality, $campaignRef, $educationTypeRefUids, $profileRefUids, $privilegeUids, $specialMarkListUids ); if (!empty($sets)) { foreach ($sets as $set) { $tests = $set->cgetEntranceTests; foreach ($tests as $test) { $parentSubjectRef = 0; $subjectList = $test->cgetChildSubjects; if (!$subjectList) { $subjectList = [$test]; } else { $parentSubjectRef = self::loadFromCache( $test, 'subjectRef.id', $test->subject_ref_id, $cache ); } foreach ($subjectList as $subject) { $rowspan = DictionaryCompetitiveGroupEntranceTest::subjectAssembly( $data, $subject, $test, $set, $specialities, $priorityList, $key, $rowspan, $parentSubjectRef, $cache ); } } } } else { $needEmptyMessage = true; } if ($needEmptyMessage) { $message = Yii::$app->configurationManager->getText('text_for_an_empty_line_when_it_was_not_possible_to_collect_a_set_of_entrance_tests'); $data["{$key}_"]['priority'] = [ 'value' => $message, 'rowspan' => 0, 'colspan' => 4, ]; $data["{$key}_"]['subject']['rowspan'] = $rowspan; $sortedData["{$key}_"] = $data["{$key}_"]; } $data["{$key}_"]['subject']['rowspan'] = $rowspan; $sortedData["{$key}_"] = $data["{$key}_"]; ksort($priorityList); foreach ($priorityList as $priority => $value) { foreach (array_keys($value['discipline']) as $indexPart) { $index = "{$indexPart}_{$priority}"; $sortedData[$index] = $data[$index]; } } } return new ArrayDataProvider([ 'allModels' => $sortedData, 'sort' => false, 'pagination' => ['pageSize' => 1000], ]); } private static function loadFromCache( ActiveRecord $abstraction, string $path, int $refValue, array &$cache ) { $key = "{$path}_{$refValue}"; if (key_exists($key, $cache)) { return $cache[$key]; } $cache[$key] = ArrayHelper::getValue($abstraction, $path); return $cache[$key]; } private static function subjectAssembly( array &$data, object $subject, object $test, object $set, object $specialities, array &$priorityList, string $key, int $rowspan, int $parentSubjectRef, array &$cache ): int { $subjectRefId = $subject instanceof CgetEntranceTest ? 'subject_ref_id' : 'child_subject_ref_id'; $subjectRef = self::loadFromCache( $subject, 'subjectRef', $subject->{$subjectRefId}, $cache ); $entranceTestResultSourceRef = self::loadFromCache( $test, 'entranceTestResultSourceRef', $test->entrance_test_result_source_ref_id, $cache ); $I = "{$key}_{$subjectRef->id}_{$test->priority}"; if (!array_key_exists($I, $data)) { $rowspan++; $data[$I]['subject'] = ''; } if (!isset($data[$I]['priority'])) { $data[$I]['priority'] = [ 'value' => $test->priority, 'rowspan' => 0, ]; } $data[$I]['allowMulti'] = self::loadFromCache( $set, 'allowMultiplyAlternativeSubjects', $set->dictionary_competitive_group_entrance_test_id, $cache ); if ($parentSubjectRef) { $data[$I]['parentDiscipline'] = empty($parentSubjectRef) ? '' : $parentSubjectRef; } if (!in_array($test->priority, array_keys($priorityList))) { $priorityList[$test->priority]['count'] = 1; $priorityList[$test->priority]['discipline'] = ["{$key}_{$subjectRef->id}" => $subjectRef->id]; $data[$I]['priority'] = [ 'value' => $test->priority, 'rowspan' => &$priorityList[$test->priority]['count'], ]; } if (!in_array($subjectRef->id, $priorityList[$test->priority]['discipline'])) { $priorityList[$test->priority]['discipline']["{$key}_{$subjectRef->id}"] = $subjectRef->id; } $priorityList[$test->priority]['count'] = count($priorityList[$test->priority]['discipline']); $data[$I]['min_score'] = $test->min_score; $data[$I]['discipline'] = $subjectRef->reference_name; $data[$I]['bachelorSpecialityModel'] = $specialities; if (isset($data[$I]['exam_form'])) { $data[$I]['exam_form'][$entranceTestResultSourceRef->id] = [ 'minScore' => $test->min_score, 'name' => $entranceTestResultSourceRef->reference_name, ]; } else { $data[$I]['exam_form'] = [$entranceTestResultSourceRef->id => [ 'minScore' => $test->min_score, 'name' => $entranceTestResultSourceRef->reference_name, ]]; } return $rowspan; } }