protected function prepareDatasetSequence(ReferenceCallContext $callcontext, MetaModel $metamodel, ReferenceLink $link, $referencePath) { $referenceParts = ReferencePathHelper::splitReference($referencePath); $parentColumnName = array_pop($referenceParts); $parentDatasetName = array_pop($referenceParts); $referencedColumnName = $referencedDatasetName = NULL; $leftReferencePartCount = count($referenceParts); $nestedReferencePath = $referencePath; if ($link->dataset->name == $parentDatasetName) { // dataset is there and it is link's dataset if ($leftReferencePartCount == 0) { return; } // assembling new reference path $nestedReferencePath = ReferencePathHelper::assembleReferenceParts($referenceParts); $referencedColumnName = array_pop($referenceParts); $referencedDatasetName = array_pop($referenceParts); if (!isset($referencedDatasetName)) { throw new UnsupportedOperationException(t( 'Dataset name is not set in the reference path: %referencePath', array('%referencePath' => $referencePath))); } } elseif (isset($parentDatasetName)) { $referencedColumnName = $parentColumnName; $referencedDatasetName = $parentDatasetName; $parentColumnName = $parentDatasetName = NULL; } else { if ($leftReferencePartCount > 0) { throw new UnsupportedOperationException(t( 'Dataset name is not set in the reference path: %referencePath', array('%referencePath' => $referencePath))); } // it means that we just point to column in link's dataset return; } // checking if there any references which could be used to find required dataset $references = $metamodel->findReferencesByDatasetName($link->dataset->name); if (!isset($references)) { return; } // maximum number of columns in direct references $directReferencePointColumnCount = NULL; // checking if there is any reference which directly link to referenced dataset $parentReferencePointIndex4References = $directReferencePointIndex4References = $transitionalReferencePointIndexes4References = NULL; foreach ($references as $reference) { $referencePointColumnCount = $reference->getPointColumnCount(); // checking if the reference can be used to link with other datasets $parentReferencePointIndex4Reference = $directReferencePointIndex4Reference = $transitionalReferencePointIndexes4Reference = NULL; for ($referencePointColumnIndex = 0; $referencePointColumnIndex < $referencePointColumnCount; $referencePointColumnIndex++) { $parentReferencePointIndex = $directReferencePointIndex = $transitionalReferencePointIndexes = NULL; foreach ($reference->points as $referencePointIndex => $referencePoint) { $datasetName = $referencePoint->columns[$referencePointColumnIndex]->datasetName; if (($link->dataset->name == $datasetName) && (!isset($parentColumnName) || ($parentColumnName == $referencePoint->columns[$referencePointColumnIndex]->columnName))) { if (isset($parentReferencePointIndex)) { // Found several possible ways to start a join from the referring dataset. // That happens because we do not have parent column name and possible join is ambiguous // We cannot use this way to proceed continue 3; } else { $parentReferencePointIndex = $referencePointIndex; } } elseif ($datasetName == $referencedDatasetName) { if (isset($directReferencePointIndex)) { // found several possible ways to join with the referenced dataset continue 3; } else { $directReferencePointIndex[$referencePointIndex] = TRUE; } } else { $transitionalReferencePointIndexes[$referencePointIndex] = FALSE; } } // this reference cannot be used because none of the reference points linked with parent dataset if (!isset($parentReferencePointIndex)) { continue 2; } if (isset($directReferencePointIndex)) { // if we have direct reference we do not care about indirect ones $transitionalReferencePointIndexes = NULL; } else { // there is no direct or indirect ways. This reference is useless :) if (!isset($transitionalReferencePointIndexes)) { continue 2; } } $parentReferencePointIndex4Reference[$referencePointColumnIndex] = $parentReferencePointIndex; if (isset($directReferencePointIndex)) { $directReferencePointIndex4Reference[$referencePointColumnIndex] = $directReferencePointIndex; } if (isset($transitionalReferencePointIndexes)) { $transitionalReferencePointIndexes4Reference[$referencePointColumnIndex] = $transitionalReferencePointIndexes; } } // we support only direct references between datasets // in this case we have direct reference based on some columns only. Rest columns are connected indirectly if (isset($directReferencePointIndex4Reference) && isset($transitionalReferencePointIndexes4Reference)) { continue; } $parentReferencePointIndex4References[$reference->name] = $parentReferencePointIndex4Reference; if (isset($directReferencePointIndex4Reference)) { $directReferencePointIndex4References[$reference->name] = $directReferencePointIndex4Reference; $directReferencePointColumnCount = MathHelper::max($directReferencePointColumnCount, $referencePointColumnCount); } if (isset($transitionalReferencePointIndexes4Reference)) { $transitionalReferencePointIndexes4References[$reference->name] = $transitionalReferencePointIndexes4Reference; } } // we could use none of the selected references if (!isset($parentReferencePointIndex4References)) { return; } // removing all useless direct and indirect references if there is a direct way if (isset($directReferencePointColumnCount)) { foreach ($parentReferencePointIndex4References as $referenceName => $parentReferencePointIndex4Reference) { $referencePointColumnCount = count($parentReferencePointIndex4Reference); if (isset($directReferencePointIndex4References[$referenceName])) { // we preserve only direct ways with maximum number of columns if ($referencePointColumnCount == $directReferencePointColumnCount) { continue; } } else { // we preserve only indirect ways with more columns than in direct way if ($referencePointColumnCount > $directReferencePointColumnCount) { continue; } } unset($parentReferencePointIndex4References[$referenceName]); unset($directReferencePointIndex4References[$referenceName]); unset($transitionalReferencePointIndexes4References[$referenceName]); } } foreach ($parentReferencePointIndex4References as $referenceName => $parentReferencePointIndex4Reference) { $reference = $references[ArrayHelper::search($references, 'name', $referenceName)]; $referencePointColumnCount = $reference->getPointColumnCount(); $referencePointIndexes4Reference = isset($directReferencePointIndex4References[$referenceName]) ? $directReferencePointIndex4References[$referenceName] : NULL; $isDirectReference = isset($referencePointIndexes4Reference); if (!$isDirectReference) { // 01/09/2014 reference can be reused only for direct references if (isset($callcontext->referenceNameStack[$referenceName])) { continue; } $referencePointIndexes4Reference = isset($transitionalReferencePointIndexes4References[$referenceName]) ? $transitionalReferencePointIndexes4References[$referenceName] : NULL; } // registering the reference in a stack to avoid excessive calls // registration was moved here because we could have date[->month->quarter->year] and year columns in one dataset // if references related to date and year are registered before we start to process individual references // we will end up with nested links for date->month->quarter->year which do not contain a reference to year // which leads to GOVDB-1313 issue $callcontext->referenceNameStack[$reference->name] = TRUE; // preparing dataset names for each reference point $referencePointDatasetNames = NULL; for ($referencePointColumnIndex = 0; $referencePointColumnIndex < $referencePointColumnCount; $referencePointColumnIndex++) { foreach ($referencePointIndexes4Reference[$referencePointColumnIndex] as $referencePointIndex => $directReferencePointFlag) { $referencePointColumn = $reference->points[$referencePointIndex]->columns[$referencePointColumnIndex]; $datasetName = $referencePointColumn->datasetName; // it is expected that dataset name is the same for all columns in a reference point if (isset($referencePointDatasetNames[$referencePointIndex])) { if ($referencePointDatasetNames[$referencePointIndex] != $datasetName) { // Dataset name is not the same for all columns for the reference point $referencePointDatasetNames[$referencePointIndex] = FALSE; } } else { $referencePointDatasetNames[$referencePointIndex] = $datasetName; } } } // removing all reference points which we cannot support now foreach ($referencePointDatasetNames as $referencePointIndex => $datasetName) { if ($datasetName === FALSE) { unset($referencePointDatasetNames[$referencePointIndex]); } } // if nothing left there is not need to proceed if (count($referencePointDatasetNames) == 0) { continue; } // preparing list of parent column names $parentColumnNames = NULL; for ($referencePointColumnIndex = 0; $referencePointColumnIndex < $referencePointColumnCount; $referencePointColumnIndex++) { $parentReferencePointIndex = $parentReferencePointIndex4Reference[$referencePointColumnIndex]; $parentReferencePointColumnName = $reference->points[$parentReferencePointIndex]->columns[$referencePointColumnIndex]->columnName; $parentColumnNames[$referencePointColumnIndex] = $parentReferencePointColumnName; } $referenceCallContext = $isDirectReference ? $callcontext : (clone $callcontext); // adding all indirect datasets in stack to prevent recursive calls if (!$isDirectReference) { foreach ($referencePointDatasetNames as $referencePointIndex => $datasetName) { if (isset($referenceCallContext->datasetNameStack[$datasetName])) { unset($referencePointDatasetNames[$referencePointIndex]); } else { $referenceCallContext->datasetNameStack[$datasetName] = TRUE; } } } foreach ($referencePointDatasetNames as $referencePointIndex => $datasetName) { // looking for existing link $referencedLink = $link->findNestedLinkByDatasetNameAndParentColumnNames($datasetName, $parentColumnNames); if (!isset($referencedLink)) { $dataset = $metamodel->getDataset($datasetName); $referencedLink = new ReferenceLink($dataset); foreach ($parentColumnNames as $referencePointColumnIndex => $parentReferencePointColumnName) { $referencePointColumn = $reference->points[$referencePointIndex]->columns[$referencePointColumnIndex]; $referencedLink->linkColumnWithParent($referencePointColumnIndex, $parentReferencePointColumnName, $referencePointColumn->columnName); } $link->registerNestedLink($referencedLink); } ArrayHelper::addUniqueValue($referencedLink->referenceNames, $referenceName); // marking the link as required for the branch so it will not be deleted by the optimizer later if ($isDirectReference) { $referencedLink->required = TRUE; } // because this reference path is not processed completely we need to continue scanning this branch if (isset($nestedReferencePath)) { LogHelper::log_debug(t( 'Checking sub-path[linkId: @linkId; stackSize: @stackSize]: @referencePath', array('@linkId' => $referencedLink->linkId, '@stackSize' => count($callcontext->referenceNameStack), '@referencePath' => $referencePath))); $referencePointCallContext = clone $referenceCallContext; $this->prepareDatasetSequence($referencePointCallContext, $metamodel, $referencedLink, $nestedReferencePath); } } } }
public function registerAjaxCssFile($sPath) { if (ArrayHelper::search($sPath, $this->aAjaxCssFiles) === false) { array_push($this->aAjaxCssFiles, $sPath); return true; } return false; }