/** * @see resolveAttributeIndexesByComponents * @param ComponentForReportForm $componentForm * @return array */ protected static function resolveAttributeIndexesByComponent(ComponentForReportForm $componentForm) { $attributeIndexes = array(); $modelClassName = $componentForm->getModelClassName(); $moduleClassName = $componentForm->getModuleClassName(); if (!$componentForm->hasRelatedData()) { static::resolveAttributeIndexes($modelClassName, $attributeIndexes); } else { $attributeIndexPrefix = null; foreach ($componentForm->attributeAndRelationData as $relationOrAttribute) { static::resolveAttributeIndexes($modelClassName, $attributeIndexes, $attributeIndexPrefix); $modelToReportAdapter = ModelRelationsAndAttributesToReportAdapter::make($moduleClassName, $modelClassName, $componentForm->getReportType()); if ($modelToReportAdapter->isReportedOnAsARelation($relationOrAttribute)) { $modelClassName = $modelToReportAdapter->getRelationModelClassName($relationOrAttribute); $moduleClassName = $modelToReportAdapter->getRelationModuleClassName($relationOrAttribute); $attributeIndexPrefix = $attributeIndexPrefix . $relationOrAttribute . FormModelUtil::RELATION_DELIMITER; } } } return $attributeIndexes; }
/** * @return ModelRelationsAndAttributesToReportAdapter */ protected function makeModelRelationsAndAttributesToReportAdapter() { return ModelRelationsAndAttributesToReportAdapter::make($this->filter->getResolvedAttributeModuleClassName(), $this->filter->getResolvedAttributeModelClassName(), $this->filter->getReportType()); }
/** * @return string * @throws NotSupportedException */ protected function resolveComponentAttributeStringContentForNestedAttribute() { $attributeAndRelationData = $this->componentForm->getAttributeAndRelationData(); $count = 0; $moduleClassName = $this->componentForm->getModuleClassName(); $modelClassName = $this->componentForm->getModelClassName(); $onTableAliasName = null; $startingModelClassName = null; foreach ($attributeAndRelationData as $key => $relationOrAttribute) { $modelToReportAdapter = ModelRelationsAndAttributesToReportAdapter::make($moduleClassName, $modelClassName, $this->componentForm->getReportType()); $modelAttributeToDataProviderAdapter = $this->makeModelAttributeToDataProviderAdapter($modelToReportAdapter, $relationOrAttribute); if ($this->shouldPrematurelyStopBuildingJoinsForAttribute($modelToReportAdapter, $modelAttributeToDataProviderAdapter)) { $attribute = 'id'; $modelAttributeToDataProviderAdapter = $this->makeModelAttributeToDataProviderAdapter($modelToReportAdapter, $attribute); break; } elseif ($modelToReportAdapter->isReportedOnAsARelation($relationOrAttribute)) { $modelClassName = $modelToReportAdapter->getRelationModelClassName($relationOrAttribute); $moduleClassName = $modelToReportAdapter->getRelationModuleClassName($relationOrAttribute); if ($modelToReportAdapter->isInferredRelation($relationOrAttribute) || $modelToReportAdapter->isDerivedRelationsViaCastedUpModelRelation($relationOrAttribute)) { static::resolveCastingHintForAttribute($modelToReportAdapter, $modelAttributeToDataProviderAdapter, $modelClassName, $modelToReportAdapter->resolveRealAttributeName($attributeAndRelationData[$key + 1])); } $modelAttributeToDataProviderAdapter->setCastingHintStartingModelClassName($startingModelClassName); $builder = new ModelJoinBuilder($modelAttributeToDataProviderAdapter, $this->joinTablesAdapter); $onTableAliasName = $builder->resolveJoins($onTableAliasName, ModelDataProviderUtil::resolveCanUseFromJoins($onTableAliasName)); $startingModelClassName = $modelAttributeToDataProviderAdapter->getCastingHintModelClassNameForAttribute(); } else { if ($count + 1 != count($attributeAndRelationData)) { throw new NotSupportedException('The final element in array must be an attribute, not a relation'); } } $count++; } $modelAttributeToDataProviderAdapter->setCastingHintStartingModelClassName($startingModelClassName); return $this->resolveFinalContent($modelAttributeToDataProviderAdapter, $onTableAliasName); }
/** * @param array $attributeAndRelationData * @param $modelClassName * @return string $lastModelClassName */ protected function resolvePenultimateModelClassNameFromData(array $attributeAndRelationData, $modelClassName) { assert(count($attributeAndRelationData) > 0); // Not Coding Standard array_pop($attributeAndRelationData); foreach ($attributeAndRelationData as $relationOrAttribute) { $lastModelClassName = $modelClassName; $modelToReportAdapter = ModelRelationsAndAttributesToReportAdapter::make($modelClassName::getModuleClassName(), $modelClassName, $this->reportType); if ($modelToReportAdapter->isReportedOnAsARelation($relationOrAttribute)) { $modelClassName = $modelToReportAdapter->getRelationModelClassName($relationOrAttribute); } } return $lastModelClassName; }
public function actionGetAvailableSeriesAndRangesForChart($type, $id = null, $isBeingCopied = false) { $postData = PostUtil::getData(); $savedReport = null; $report = null; $this->resolveSavedReportAndReportByPostData($postData, $savedReport, $report, $type, $id, (bool) $isBeingCopied); $moduleClassName = $report->getModuleClassName(); $modelClassName = $moduleClassName::getPrimaryModelName(); $modelToReportAdapter = ModelRelationsAndAttributesToReportAdapter::make($moduleClassName, $modelClassName, $report->getType()); if (!$modelToReportAdapter instanceof ModelRelationsAndAttributesToSummationReportAdapter) { throw new NotSupportedException(); } $seriesAttributesData = $modelToReportAdapter->getAttributesForChartSeries($report->getGroupBys(), $report->getDisplayAttributes()); $rangeAttributesData = $modelToReportAdapter->getAttributesForChartRange($report->getDisplayAttributes()); $dataAndLabels = array(); $dataAndLabels['firstSeriesDataAndLabels'] = array('' => Zurmo::t('Core', '(None)')); $dataAndLabels['firstSeriesDataAndLabels'] = array_merge($dataAndLabels['firstSeriesDataAndLabels'], ReportUtil::makeDataAndLabelsForSeriesOrRange($seriesAttributesData)); $dataAndLabels['firstRangeDataAndLabels'] = array('' => Zurmo::t('Core', '(None)')); $dataAndLabels['firstRangeDataAndLabels'] = array_merge($dataAndLabels['firstRangeDataAndLabels'], ReportUtil::makeDataAndLabelsForSeriesOrRange($rangeAttributesData)); $dataAndLabels['secondSeriesDataAndLabels'] = array('' => Zurmo::t('Core', '(None)')); $dataAndLabels['secondSeriesDataAndLabels'] = array_merge($dataAndLabels['secondSeriesDataAndLabels'], ReportUtil::makeDataAndLabelsForSeriesOrRange($seriesAttributesData)); $dataAndLabels['secondRangeDataAndLabels'] = array('' => Zurmo::t('Core', '(None)')); $dataAndLabels['secondRangeDataAndLabels'] = array_merge($dataAndLabels['secondRangeDataAndLabels'], ReportUtil::makeDataAndLabelsForSeriesOrRange($rangeAttributesData)); echo CJSON::encode($dataAndLabels); }
public function testGetFilterRulesByAttribute() { $model = new ReportModelTestItem(); $rules = new ReportsTestReportRules(); $adapter = new ModelRelationsAndAttributesToReportAdapter($model, $rules, Report::TYPE_ROWS_AND_COLUMNS); $exptected = ModelAttributeRulesToDefaultValueMappingRuleUtil::getApplicableRulesByModelClassNameAndAttributeName(get_class($model), 'string', 'value', false, true, false); $this->assertEquals($exptected, $adapter->getFilterRulesByAttribute('string', 'value')); $exptected = ModelAttributeRulesToDefaultValueMappingRuleUtil::getApplicableRulesByModelClassNameAndAttributeName(get_class($model), 'boolean', 'value', false, true, false); $this->assertEquals($exptected, $adapter->getFilterRulesByAttribute('boolean', 'value')); $exptected = array(array('value', 'type', 'type' => 'float')); $this->assertEquals($exptected, $adapter->getFilterRulesByAttribute('currencyValue', 'value')); $exptected = ModelAttributeRulesToDefaultValueMappingRuleUtil::getApplicableRulesByModelClassNameAndAttributeName(get_class($model), 'date', 'value', false, true, false); $this->assertEquals($exptected, $adapter->getFilterRulesByAttribute('date', 'value')); $exptected = ModelAttributeRulesToDefaultValueMappingRuleUtil::getApplicableRulesByModelClassNameAndAttributeName(get_class($model), 'dateTime', 'value', false, true, false); $this->assertEquals($exptected, $adapter->getFilterRulesByAttribute('dateTime', 'value')); $exptected = ModelAttributeRulesToDefaultValueMappingRuleUtil::getApplicableRulesByModelClassNameAndAttributeName(get_class($model), 'dropDown', 'value', false, true, false); $this->assertEquals($exptected, $adapter->getFilterRulesByAttribute('dropDown', 'value')); $exptected = ModelAttributeRulesToDefaultValueMappingRuleUtil::getApplicableRulesByModelClassNameAndAttributeName(get_class($model), 'float', 'value', false, true, false); $this->assertEquals($exptected, $adapter->getFilterRulesByAttribute('float', 'value')); $exptected = ModelAttributeRulesToDefaultValueMappingRuleUtil::getApplicableRulesByModelClassNameAndAttributeName(get_class($model), 'integer', 'value', false, true, false); $this->assertEquals($exptected, $adapter->getFilterRulesByAttribute('integer', 'value')); $exptected = ModelAttributeRulesToDefaultValueMappingRuleUtil::getApplicableRulesByModelClassNameAndAttributeName(get_class($model), 'multiDropDown', 'value', false, true, false); $this->assertEquals($exptected, $adapter->getFilterRulesByAttribute('multiDropDown', 'value')); $exptected = ModelAttributeRulesToDefaultValueMappingRuleUtil::getApplicableRulesByModelClassNameAndAttributeName(get_class($model), 'owner', 'value', false, true, false); $this->assertEquals($exptected, $adapter->getFilterRulesByAttribute('owner', 'value')); $exptected = ModelAttributeRulesToDefaultValueMappingRuleUtil::getApplicableRulesByModelClassNameAndAttributeName(get_class($model), 'phone', 'value', false, true, false); $this->assertEquals($exptected, $adapter->getFilterRulesByAttribute('phone', 'value')); $exptected = ModelAttributeRulesToDefaultValueMappingRuleUtil::getApplicableRulesByModelClassNameAndAttributeName(get_class($model), 'radioDropDown', 'value', false, true, false); $this->assertEquals($exptected, $adapter->getFilterRulesByAttribute('radioDropDown', 'value')); $exptected = ModelAttributeRulesToDefaultValueMappingRuleUtil::getApplicableRulesByModelClassNameAndAttributeName(get_class($model), 'tagCloud', 'value', false, true, false); $this->assertEquals($exptected, $adapter->getFilterRulesByAttribute('tagCloud', 'value')); $exptected = ModelAttributeRulesToDefaultValueMappingRuleUtil::getApplicableRulesByModelClassNameAndAttributeName(get_class($model), 'textArea', 'value', false, true, false); $this->assertEquals($exptected, $adapter->getFilterRulesByAttribute('textArea', 'value')); $exptected = ModelAttributeRulesToDefaultValueMappingRuleUtil::getApplicableRulesByModelClassNameAndAttributeName(get_class($model), 'url', 'value', false, true, false); $this->assertEquals($exptected, $adapter->getFilterRulesByAttribute('url', 'value')); $exptected = ModelAttributeRulesToDefaultValueMappingRuleUtil::getApplicableRulesByModelClassNameAndAttributeName(get_class($model), 'likeContactState', 'value', false, true, false); $this->assertEquals($exptected, $adapter->getFilterRulesByAttribute('likeContactState', 'value')); $model = new ReportModelTestItem12(); $rules = new ReportsTestReportRules(); $adapter = new ModelRelationsAndAttributesToReportAdapter($model, $rules, Report::TYPE_ROWS_AND_COLUMNS); $exptected = array(array('value', 'type', 'type' => 'string')); $this->assertEquals($exptected, $adapter->getFilterRulesByAttribute('emailAddress', 'value')); }
/** * Sally cannot access notes, tasks, or contacts. User is always accessible regardless of right to access */ public function testGetAllReportableRelationsAsANonElevatedUser() { Yii::app()->user->userModel = User::getByUsername('sally'); $model = new Account(); $rules = new AccountsReportRules(); $report = new Report(); $report->setType(Report::TYPE_ROWS_AND_COLUMNS); $report->setModuleClassName('AccountsModule'); $adapter = new ModelRelationsAndAttributesToReportAdapter($model, $rules, $report->getType()); $relations = $adapter->getSelectableRelationsData(); $relations = $adapter->getSelectableRelationsDataResolvedForUserAccess(Yii::app()->user->userModel, $relations); $this->assertEquals(9, count($relations)); $compareData = array('label' => 'Billing Address'); $this->assertEquals($compareData, $relations['billingAddress']); $compareData = array('label' => 'Created By User'); $this->assertEquals($compareData, $relations['createdByUser']); $compareData = array('label' => 'Meetings'); $this->assertEquals($compareData, $relations['meetings']); $compareData = array('label' => 'Modified By User'); $this->assertEquals($compareData, $relations['modifiedByUser']); $compareData = array('label' => 'Opportunities'); $this->assertEquals($compareData, $relations['opportunities']); $compareData = array('label' => 'Owner'); $this->assertEquals($compareData, $relations['owner']); $compareData = array('label' => 'Primary Email'); $this->assertEquals($compareData, $relations['primaryEmail']); $compareData = array('label' => 'Shipping Address'); $this->assertEquals($compareData, $relations['shippingAddress']); $compareData = array('label' => 'Secondary Email'); $this->assertEquals($compareData, $relations['secondaryEmail']); }
/** * @param ComponentForReportForm $componentForm * @return ModelRelationsAndAttributesToReportAdapter */ protected static function makeModelToReportAdapterByComponentForm(ComponentForReportForm $componentForm) { return ModelRelationsAndAttributesToReportAdapter::make($componentForm->getResolvedAttributeModuleClassName(), $componentForm->getResolvedAttributeModelClassName(), $componentForm->getReportType()); }
/** * @depends testGetFilterValueElementType */ public function testGetAvailableOperatorsType() { $model = new ReportModelTestItem(); $rules = new ReportsTestReportRules(); $adapter = new ModelRelationsAndAttributesToReportAdapter($model, $rules, Report::TYPE_ROWS_AND_COLUMNS); $this->assertEquals(ModelAttributeToReportOperatorTypeUtil::AVAILABLE_OPERATORS_TYPE_STRING, $adapter->getAvailableOperatorsType('string')); $model = new ReportModelTestItem(); $rules = new ReportsTestReportRules(); $adapter = new ModelRelationsAndAttributesToReportAdapter($model, $rules, Report::TYPE_ROWS_AND_COLUMNS); $this->assertEquals(ModelAttributeToReportOperatorTypeUtil::AVAILABLE_OPERATORS_TYPE_BOOLEAN, $adapter->getAvailableOperatorsType('boolean')); $this->assertEquals(ModelAttributeToReportOperatorTypeUtil::AVAILABLE_OPERATORS_TYPE_NUMBER, $adapter->getAvailableOperatorsType('currencyValue')); $this->assertNull($adapter->getAvailableOperatorsType('date')); $this->assertNull($adapter->getAvailableOperatorsType('dateTime')); $this->assertEquals(ModelAttributeToReportOperatorTypeUtil::AVAILABLE_OPERATORS_TYPE_DROPDOWN, $adapter->getAvailableOperatorsType('dropDown')); $this->assertEquals(ModelAttributeToReportOperatorTypeUtil::AVAILABLE_OPERATORS_TYPE_NUMBER, $adapter->getAvailableOperatorsType('float')); $this->assertEquals(ModelAttributeToReportOperatorTypeUtil::AVAILABLE_OPERATORS_TYPE_NUMBER, $adapter->getAvailableOperatorsType('integer')); $this->assertEquals(ModelAttributeToReportOperatorTypeUtil::AVAILABLE_OPERATORS_TYPE_DROPDOWN, $adapter->getAvailableOperatorsType('multiDropDown')); $this->assertEquals(ModelAttributeToReportOperatorTypeUtil::AVAILABLE_OPERATORS_TYPE_HAS_ONE, $adapter->getAvailableOperatorsType('owner__User')); $this->assertEquals(ModelAttributeToReportOperatorTypeUtil::AVAILABLE_OPERATORS_TYPE_STRING, $adapter->getAvailableOperatorsType('phone')); $this->assertEquals(ModelAttributeToReportOperatorTypeUtil::AVAILABLE_OPERATORS_TYPE_DROPDOWN, $adapter->getAvailableOperatorsType('radioDropDown')); $this->assertEquals(ModelAttributeToReportOperatorTypeUtil::AVAILABLE_OPERATORS_TYPE_STRING, $adapter->getAvailableOperatorsType('string')); $this->assertEquals(ModelAttributeToReportOperatorTypeUtil::AVAILABLE_OPERATORS_TYPE_DROPDOWN, $adapter->getAvailableOperatorsType('tagCloud')); $this->assertEquals(ModelAttributeToReportOperatorTypeUtil::AVAILABLE_OPERATORS_TYPE_STRING, $adapter->getAvailableOperatorsType('textArea')); $this->assertEquals(ModelAttributeToReportOperatorTypeUtil::AVAILABLE_OPERATORS_TYPE_STRING, $adapter->getAvailableOperatorsType('url')); $this->assertEquals(ModelAttributeToReportOperatorTypeUtil::AVAILABLE_OPERATORS_TYPE_DROPDOWN, $adapter->getAvailableOperatorsType('likeContactState')); $model = new ReportModelTestItem(); $rules = new ReportsAlternateStateTestReportRules(); $adapter = new ModelRelationsAndAttributesToReportAdapter($model, $rules, Report::TYPE_ROWS_AND_COLUMNS); $this->assertEquals(ModelAttributeToReportOperatorTypeUtil::AVAILABLE_OPERATORS_TYPE_DROPDOWN, $adapter->getAvailableOperatorsType('likeContactState')); }
/** * @param string $nodeId * @param ModelRelationsAndAttributesToReportAdapter $modelToReportAdapter * @param RedBeanModel $precedingModel * @param string $precedingRelation */ protected function resolvePrecedingModelRelationAndAdapterByNodeId($nodeId, &$modelToReportAdapter, &$precedingModel, &$precedingRelation) { assert('$modelToReportAdapter instanceof ModelRelationsAndAttributesToReportAdapter'); if ($nodeId == 'source') { return; } $relations = explode(FormModelUtil::RELATION_DELIMITER, $nodeId); $lastRelation = end($relations); foreach ($relations as $relation) { $relationModelClassName = $modelToReportAdapter->getRelationModelClassName($relation); $precedingRelation = $relation; if ($relation != $lastRelation) { $precedingModel = new $relationModelClassName(false); } elseif (count($relations) == 1) { $precedingModel = $modelToReportAdapter->getModel(); } $modelToReportAdapter = $this->makeModelRelationsAndAttributesToReportAdapter($relationModelClassName::getModuleClassName(), $relationModelClassName); } }
/** * Resolves for a given component whether the user has necessary rights to access the component information. * An example is if a component is account's opportunities and the current user cannot access the opportunities * module. * @param ComponentForReportForm $componentForm * @return bool */ protected static function canCurrentUserAccessComponent(ComponentForReportForm $componentForm) { $modelClassName = $componentForm->getModelClassName(); $moduleClassName = $componentForm->getModuleClassName(); if (!$componentForm->hasRelatedData()) { return self::canCurrentUserCanAccessModule($moduleClassName); } else { foreach ($componentForm->attributeAndRelationData as $relationOrAttribute) { if (!self::canCurrentUserCanAccessModule($moduleClassName)) { return false; } $modelToReportAdapter = ModelRelationsAndAttributesToReportAdapter::make($moduleClassName, $modelClassName, $componentForm->getReportType()); if ($modelToReportAdapter->isReportedOnAsARelation($relationOrAttribute)) { $modelClassName = $modelToReportAdapter->getRelationModelClassName($relationOrAttribute); $moduleClassName = $modelToReportAdapter->getRelationModuleClassName($relationOrAttribute); } } return true; } }
/** * @param string $attribute * @return string * @throws NotSupportedException if the attribute is an invalid display calculation */ public function getDisplayElementType($attribute) { assert('is_string($attribute)'); if ($this->isAttributeIndexOrDerivedTypeADisplayCalculation($attribute)) { if ($attribute == self::DISPLAY_CALCULATION_COUNT) { return 'Integer'; } list($realAttribute, $notUsed) = explode(FormModelUtil::DELIMITER, $attribute); $attributeType = ModelAttributeToMixedTypeUtil::getType($this->model, $realAttribute); if ($attributeType == 'Decimal' || $attributeType == 'Integer') { return 'Decimal'; } elseif ($attributeType == 'Date') { return 'Date'; } elseif ($attributeType == 'DateTime') { return 'DateTime'; } elseif ($this->model->isRelation($realAttribute) && $this->model->getRelationModelClassName($realAttribute) == 'CurrencyValue') { return 'CalculatedCurrencyValue'; } else { throw new NotSupportedException(); } } elseif ($this->isAttributeACalculatedGroupByModifier($attribute) && $this->getGroupByCalculationTypeByAttribute($attribute) == self::GROUP_BY_CALCULATION_MONTH) { return 'GroupByModifierMonth'; } elseif ($this->isAttributeACalculatedGroupByModifier($attribute)) { return 'Text'; } return parent::getDisplayElementType($attribute); }
public static function forgetAll() { self::$derivedAttributesData = null; self::$attributesNotIncludingDerivedAttributesData = null; self::$inferredRelationsData = null; self::$dynamicallyDerivedAttributesData = null; }