protected function useApplicableCubeRegions(CubeQueryRequest $request, CubeMetaData $cube)
 {
     $metamodel = data_controller_get_metamodel();
     if (!isset($cube->regions)) {
         return;
     }
     // FIXME add support for measures in query list. Selected region needs to suport not only returning measures but also querying onces
     $isExactMatchRequired = FALSE;
     if (isset($request->measures)) {
         foreach ($request->measures as $requestMeasure) {
             $measureName = $requestMeasure->measureName;
             $cubeMeasure = $cube->findMeasure($measureName);
             if (isset($cubeMeasure) && isset($cubeMeasure->aggregationType)) {
                 switch ($cubeMeasure->aggregationType) {
                     case MeasureTypes::ADDITIVE:
                         break;
                     case MeasureTypes::SEMI_ADDITIVE:
                     case MeasureTypes::NON_ADDITIVE:
                         $isExactMatchRequired = TRUE;
                         break;
                     default:
                         throw new UnsupportedOperationException(t('Unsupported measure aggregation type: @measureAggregationType', array('@measureAggregationType' => $cubeMeasure->aggregationType)));
                 }
             }
         }
     }
     // collecting possible eligible regions
     $eligibleRegionNames = NULL;
     foreach ($cube->regions as $regionName => $region) {
         // checking if the region supports all requested measures
         if (isset($request->measures)) {
             foreach ($request->measures as $requestMeasure) {
                 if (!isset($region->measures[$requestMeasure->measureName])) {
                     continue 2;
                 }
             }
         }
         $eligibleRegionNames[] = $regionName;
     }
     if (!isset($eligibleRegionNames)) {
         return;
     }
     // filtering eligible regions based on requested or queried dimensions
     if (isset($request->dimensions)) {
         $this->excludeIneligibleRegions($cube, $eligibleRegionNames, $request->dimensions, $isExactMatchRequired);
     }
     if (isset($request->queries)) {
         $this->excludeIneligibleRegions($cube, $eligibleRegionNames, $request->queries, $isExactMatchRequired);
     }
     // do we still have any regions which could be used for the request
     if (count($eligibleRegionNames) === 0) {
         return;
     }
     // we select first region suitable for the request
     $selectedRegionName = reset($eligibleRegionNames);
     $selectedRegion = $cube->regions->{$selectedRegionName};
     // preparing new cube configuration
     $regionCube = new CubeMetaData();
     $regionCube->name = "{$cube->name}_using_{$selectedRegionName}_region";
     // source dataset
     $regionCube->sourceDatasetName = $selectedRegion->datasetName;
     // dimensions
     if (isset($cube->dimensions)) {
         foreach ($cube->dimensions as $dimension) {
             $dimensionName = $dimension->name;
             if (!isset($selectedRegion->dimensions->{$dimensionName})) {
                 continue;
             }
             $regionCubeDimension = $regionCube->registerDimension($dimensionName);
             $selectedRegionDimension = $selectedRegion->dimensions->{$dimensionName};
             if (isset($selectedRegionDimension->levels)) {
                 // we need to prepare new dimension which contains levels which are supported by this region
                 $sourceLevel = NULL;
                 $isSelectedLevelFound = FALSE;
                 foreach ($dimension->levels as $level) {
                     $levelName = $level->name;
                     if (!$isSelectedLevelFound && isset($level->sourceColumnName)) {
                         $sourceLevel = $level;
                     }
                     $isLevelPresent = isset($selectedRegionDimension->levels->{$levelName});
                     if ($isLevelPresent) {
                         if ($isSelectedLevelFound) {
                             throw new UnsupportedOperationException(t("Only one level is supported yet for each dimension in '@selectedRegionName' region of '@cubeName' cube", array('@selectedRegionName' => $selectedRegionName, '@cubeName' => $cube->publicName)));
                         }
                         $isSelectedLevelFound = TRUE;
                     }
                     if ($isSelectedLevelFound) {
                         $regionLevel = $regionCubeDimension->registerLevel($levelName);
                         $regionLevel->initializeFrom($level);
                         if ($isLevelPresent) {
                             $regionLevel->sourceColumnName = $sourceLevel->sourceColumnName;
                         } elseif (isset($regionLevel->sourceColumnName)) {
                             // we cannot support source key on consecutive levels. It is only supported for 'virtual' cubes
                             unset($regionLevel->sourceColumnName);
                         }
                     }
                 }
             } else {
                 $regionCubeDimension->initializeFrom($dimension);
             }
         }
     }
     // measures
     if (isset($request->measures)) {
         foreach ($request->measures as $requestMeasure) {
             $measureName = $requestMeasure->measureName;
             $cubeMeasure = $cube->getMeasure($measureName);
             $regionMeasure = $regionCube->registerMeasure($measureName);
             $regionMeasure->initializeFrom($cubeMeasure);
         }
     }
     // FIXME the following code will throw an exception if we try to reuse the same region during execution of a PHP script
     // registering the cube in meta model
     $regionCube->temporary = TRUE;
     // FIXME when loading meta model automatically create cubes for all regions
     $metamodel->registerCube($regionCube);
     // updating the request to use new cube
     LogHelper::log_notice(t("Using '@selectedRegionName' region of '@cubeName' cube", array('@selectedRegionName' => $selectedRegionName, '@cubeName' => $cube->name)));
     LogHelper::log_info(t('Creating temporary cube to satisfy this request: @regionCubeName', array('@regionCubeName' => $regionCube->name)));
     // FIXME create new request and delete the following method in request class
     $request->setCubeName($regionCube->name);
 }
    protected function prepareAttributeDistinctCountMeasure(__CubeUIMetaDataGenerator_CallContext $callcontext, AbstractRootElementUIMetaData $attributeUIMetaData, $referencePath, CubeMetaData $cube, ColumnMetaData $column, $attributeName) {
        $measureName = StarSchemaNamingConvention::getAttributeRelatedMeasureName(
            $attributeName, StarSchemaNamingConvention::$MEASURE_NAME_SUFFIX__DISTINCT_COUNT);
        // the measure has been used already
        if (!isset($callcontext->usedMeasureNames[$measureName]) || $callcontext->usedMeasureNames[$measureName]) {
            return;
        }

        $measure = $cube->findMeasure($measureName);
        if (!isset($measure)) {
            return;
        }

        $measureUIMetaData = new AttributeMeasureUIMetaData();
        $measureUIMetaData->name = self::prepareMeasureUIMetaDataName($referencePath, $cube, $measureName);
        $measureUIMetaData->publicName = $column->publicName;
        $measureUIMetaData->description = $measure->description;
        $measureUIMetaData->type = clone $measure->type;

        $attributeUIMetaData->registerElement($measureUIMetaData);

        // marking that the measure is used by this attribute
        $callcontext->usedMeasureNames[$measureName] = TRUE;
    }
 protected static function unregisterFactMeasure(CubeMetaData $cube, $columnName, $functionName)
 {
     $measureName = StarSchemaNamingConvention::getFactRelatedMeasureName($columnName, $functionName);
     $measure = $cube->findMeasure($measureName);
     if (isset($measure)) {
         $cube->unregisterMeasure($measureName);
     }
 }