public static function link(RedBean_OODBBean $bean1, RedBean_OODBBean $bean2, $name = null) { if (!$bean2->id) { ZurmoRedBean::store($bean2); } $fieldName = self::getLinkField($bean2->getMeta("type"), $name); $bean1->{$fieldName} = $bean2->id; return true; }
public function testPDOTypesToShowTheDodginessOfNotBeingAbleToGetNumbersOut() { $wukka = ZurmoRedBean::dispense('wukka'); $wukka->integer = 69; ZurmoRedBean::store($wukka); $id = $wukka->id; unset($wukka); $pdo = new PDO(Yii::app()->db->connectionString, Yii::app()->db->username, Yii::app()->db->password); // Not Coding Standard $statement = $pdo->prepare('select version() as version;'); $statement->execute(); $rows = $statement->fetchAll(); $mysqlVersion = substr($rows[0]['version'], 0, 3); $phpVersion = substr(phpversion(), 0, 5); // These is what we are interested in. They seem to be ignored in // php 5.3 with mysql 5.1, but works in php 5.3.6 & mysql 5.5. // Both are needed to be set false. // Whether it is the newer php version or the newer mysql version // or both together, and at exactly which versions it works is // unknown. That is for some future investigation. $pdo->setAttribute(PDO::ATTR_STRINGIFY_FETCHES, false); $pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); $wukka = ZurmoRedBean::load('wukka', $id); $statement = $pdo->prepare('select * from wukka;'); $statement->execute(); $rows = $statement->fetchAll(); if (($phpVersion == '5.3.6' || $phpVersion == '5.3.5' || $phpVersion == '5.5.2') && $mysqlVersion == '5.5') { $this->assertEquals('integer', gettype($rows[0]['integer'])); // Good! This is what we want!!! $this->assertEquals('string', gettype($wukka->integer)); // Dodgy!!! } else { $this->assertEquals('string', gettype($rows[0]['integer'])); // Dodgy!!! $this->assertEquals('string', gettype($wukka->integer)); // Dodgy!!! } }
public function testSellPriceFormulaSanitizationWithBothInvalidAndValidData() { $mappingData = array(); $data = array(); $this->processSantizerCSVAndGetData($mappingData, $data); $counter = 1; foreach ($data as $rowBean) { //@see ImportDataAnalyze::analyzePage $sanitizer = ImportSanitizerUtilFactory::make('SellPriceFormulaType', 'ProductTemplate', 'sellPriceFormula__type', 'column_2', $mappingData['column_2']); if ($counter == 1) { $sanitizer->analyzeByRow($rowBean); $this->assertEquals(1, count($sanitizer->getAnalysisMessages())); $this->assertTrue((bool) $sanitizer->getShouldSkipRow()); try { $sanitizer->sanitizeValue($rowBean->column_2); } catch (InvalidValueToSanitizeException $e) { $this->assertEquals(Zurmo::t('ProductTemplatesModule', 'Sell Price Formula type specified is invalid.'), $e->getMessage()); } } elseif ($counter == 2) { $sanitizer->analyzeByRow($rowBean); $this->assertEquals(0, count($sanitizer->getAnalysisMessages())); $value = $sanitizer->sanitizeValue($rowBean->column_2); $this->assertEquals(2, $value); } elseif ($counter == 3) { $value = $sanitizer->sanitizeValue($rowBean->column_2); $this->assertEquals(2, $value); ZurmoRedBean::store($rowBean); $sanitizer->analyzeByRow($rowBean); $this->assertEquals(0, count($sanitizer->getAnalysisMessages())); } elseif ($counter == 4) { $value = $sanitizer->sanitizeValue($rowBean->column_2); $this->assertEquals(3, $value); ZurmoRedBean::store($rowBean); $sanitizer->analyzeByRow($rowBean); $this->assertEquals(0, count($sanitizer->getAnalysisMessages())); } $counter++; } }
/** * Sets a configuration entry. * @param $user id * @param $moduleName A non-empty string identifying the module to which * the configuration entry belongs. * @param $key A non-empty string identifying the configuration entry. * @param $value The value to store, of whatever desired type. */ public static function set($userId, $moduleName, $key, $value) { assert('$userId != null && is_int($userId)'); assert('is_string($moduleName)'); assert('is_string($key)'); assert('$moduleName != ""'); assert('$key != ""'); try { $bean = UserConfiguration::getBean($userId, $moduleName, $key); } catch (NotFoundException $e) { $bean = ZurmoRedBean::dispense(UserConfiguration::getTableName()); $bean->userId = $userId; $bean->moduleName = $moduleName; $bean->key = $key; } $bean->value = $value; ZurmoRedBean::store($bean); }
public function save($runValidation = true) { if (!parent::save($runValidation)) { return false; } foreach ($this->deferredRelateBeans as $bean) { if ($this->linkType == RedBeanModel::LINK_TYPE_POLYMORPHIC) { if ($this->bean->id == null) { ZurmoRedBean::store($this->bean); } $polyIdFieldName = strtolower($this->linkName) . '_id'; $polyTypeFieldName = strtolower($this->linkName) . '_type'; $bean->{$polyTypeFieldName} = $this->bean->getMeta('type'); $bean->{$polyIdFieldName} = $this->bean->id; } else { ZurmoRedBeanLinkManager::link($bean, $this->bean, $this->resolveLinkNameForCasing()); } ZurmoRedBean::store($bean); } $this->deferredRelateBeans = array(); $relatedModelClassName = $this->relatedModelClassName; $tableName = $relatedModelClassName::getTableName(); foreach ($this->deferredUnrelateBeans as $bean) { if (!$this->owns) { if ($this->linkType == RedBeanModel::LINK_TYPE_POLYMORPHIC) { throw new NotSupportedException("Polymorphic relations can not be NOT_OWNED"); } ZurmoRedBeanLinkManager::breakLink($bean, $tableName, $this->resolveLinkNameForCasing()); ZurmoRedBean::store($bean); } else { ZurmoRedBean::trash($bean); } } $this->deferredUnrelatedBeans = array(); foreach ($this->deferredUnrelatedModels as $model) { $event = new CModelEvent($model); $model->onRedBeanOneToManyRelatedModelsChange($event); } $this->deferredUnrelatedModels = array(); return true; }
public function actionCreateDemoImportForAnalysis($firstRowIsHeaderRow = true) { if (!Group::isUserASuperAdministrator(Yii::app()->user->userModel)) { throw new NotSupportedException(); } $import = new Import(); $serializedData['importRulesType'] = 'Accounts'; $mappingData = array('column_0' => array('attributeIndexOrDerivedType' => 'name', 'type' => 'importColumn', 'mappingRulesData' => array('DefaultValueModelAttributeMappingRuleForm' => array('defaultValue' => null))), 'column_1' => array('attributeIndexOrDerivedType' => 'officePhone', 'type' => 'importColumn', 'mappingRulesData' => array('DefaultValueModelAttributeMappingRuleForm' => array('defaultValue' => null))), 'column_2' => array('attributeIndexOrDerivedType' => 'officeFax', 'type' => 'importColumn', 'mappingRulesData' => array('DefaultValueModelAttributeMappingRuleForm' => array('defaultValue' => null))), 'column_3' => array('attributeIndexOrDerivedType' => 'employees', 'type' => 'importColumn', 'mappingRulesData' => array('DefaultValueModelAttributeMappingRuleForm' => array('defaultValue' => null))), 'column_4' => array('attributeIndexOrDerivedType' => 'annualRevenue', 'type' => 'importColumn', 'mappingRulesData' => array('DefaultValueModelAttributeMappingRuleForm' => array('defaultValue' => null))), 'column_5' => array('attributeIndexOrDerivedType' => 'description', 'type' => 'importColumn', 'mappingRulesData' => array('DefaultValueModelAttributeMappingRuleForm' => array('defaultValue' => null))), 'column_6' => array('attributeIndexOrDerivedType' => 'website', 'type' => 'importColumn', 'mappingRulesData' => array('DefaultValueModelAttributeMappingRuleForm' => array('defaultValue' => null))), 'column_7' => array('attributeIndexOrDerivedType' => null, 'type' => 'importColumn', 'mappingRulesData' => array())); $serializedData['mappingData'] = $mappingData; $serializedData['rowColumnDelimiter'] = ','; // Not Coding Standard $serializedData['rowColumnEnclosure'] = '"'; $serializedData['firstRowIsHeaderRow'] = $firstRowIsHeaderRow; $import->serializedData = serialize($serializedData); $saved = $import->save(); if (!$saved) { throw new FailedToSaveModelException(); } $this->createImportTempTable(8, $import->getTempTableName()); //Make header row if ($firstRowIsHeaderRow) { $newBean = ZurmoRedBean::dispense($import->getTempTableName()); $newBean->column_0 = 'Header #1'; $newBean->column_1 = 'Header #2'; $newBean->column_2 = 'Header #3'; $newBean->column_3 = 'Header #4'; $newBean->column_4 = 'Header #5'; $newBean->column_5 = 'Header #6'; $newBean->column_6 = 'Header #7'; $newBean->column_7 = 'Header #8'; ZurmoRedBean::store($newBean); } //Make data rows that are clean for ($i = 0; $i < 3; $i++) { $newBean = ZurmoRedBean::dispense($import->getTempTableName()); $newBean->column_0 = 'aa1' . $i; $newBean->column_1 = 'aa2' . $i; $newBean->column_2 = 'aa3' . $i; $newBean->column_3 = 'aa4' . $i; $newBean->column_4 = 'aa5' . $i; $newBean->column_5 = 'aa6' . $i; $newBean->column_6 = 'aa7' . $i; $newBean->column_7 = 'aa8' . $i; $newBean->analysisStatus = ImportDataAnalyzer::STATUS_CLEAN; $analysisData = array(); $analysisData['column_0'] = array(); $analysisData['column_0'][] = 'a test message 1'; $analysisData['column_0'][] = 'a test message 2'; $analysisData['column_2'] = array(); $analysisData['column_2'][] = 'a test message 1'; $analysisData['column_2'][] = 'a test message 2'; $newBean->serializedAnalysisMessages = serialize($analysisData); ZurmoRedBean::store($newBean); } //Make data rows that have a warning for ($i = 0; $i < 3; $i++) { $newBean = ZurmoRedBean::dispense($import->getTempTableName()); $newBean->column_0 = 'ba1' . $i; $newBean->column_1 = 'ba2' . $i; $newBean->column_2 = 'ba3' . $i; $newBean->column_3 = 'ba4' . $i; $newBean->column_4 = 'ba5' . $i; $newBean->column_5 = 'ba6' . $i; $newBean->column_6 = 'ba7' . $i; $newBean->column_7 = 'ba8' . $i; $newBean->analysisStatus = ImportDataAnalyzer::STATUS_WARN; $analysisData = array(); $analysisData['column_0'] = array(); $analysisData['column_0'][] = 'a test message 1'; $analysisData['column_0'][] = 'a test message 2'; $analysisData['column_2'] = array(); $analysisData['column_2'][] = 'a test message 1'; $analysisData['column_2'][] = 'a test message 2'; $newBean->serializedAnalysisMessages = serialize($analysisData); ZurmoRedBean::store($newBean); } //Make data rows that are skipped for ($i = 0; $i < 10; $i++) { $newBean = ZurmoRedBean::dispense($import->getTempTableName()); $newBean->column_0 = 'ca1' . $i; $newBean->column_1 = 'ca2' . $i; $newBean->column_2 = 'ca3' . $i; $newBean->column_3 = 'ca4' . $i; $newBean->column_4 = 'ca5' . $i; $newBean->column_5 = 'ca6' . $i; $newBean->column_6 = 'ca7' . $i; $newBean->column_7 = 'ca8' . $i; $newBean->analysisStatus = ImportDataAnalyzer::STATUS_SKIP; $analysisData = array(); $analysisData['column_0'] = array(); $analysisData['column_0'][] = 'a test message 1'; $analysisData['column_0'][] = 'a test message 2'; $analysisData['column_2'] = array(); $analysisData['column_2'][] = 'a test message 1'; $analysisData['column_2'][] = 'a test message 2'; $newBean->serializedAnalysisMessages = serialize($analysisData); ZurmoRedBean::store($newBean); } ZurmoRedBean::store($newBean); echo 'the import id is: ' . $import->id; }
/** * Update the row value in the table with a new value * @param string $tableName * @param integer $id * @param string $attribute * @param string|null $newValue * @throws NotFoundException * @throws FailedToSaveModelException */ public static function updateRowValue($tableName, $id, $attribute, $newValue) { assert('is_string($tableName)'); assert('is_int($id)'); assert('is_string($attribute)'); assert('is_string($newValue) || $newValue == null'); extract(static::geColumnData($tableName, $attribute)); $newDbType = null; $newDbLength = null; RedBeanModelMemberRulesToColumnAdapter::resolveStringTypeAndLengthByMaxLength($newDbType, $newDbLength, strlen($newValue)); $update = false; if ($newDbType == 'string') { if ($columnType == 'varchar' && $newDbLength > $columnLength) { $update = true; } } elseif ($newDbType != $columnType) { if ($newDbType == 'longtext') { $update = true; } elseif ($newDbType == 'text' && $columnType == 'varchar') { $update = true; } } if ($update) { $column = RedBeanModelMemberToColumnUtil::resolveColumnMetadataByHintType($attribute, $newDbType, $newDbLength); $schema = CreateOrUpdateExistingTableFromSchemaDefinitionArrayUtil::getTableSchema($tableName, array($column)); $messageLogger = new ImportMessageLogger(); CreateOrUpdateExistingTableFromSchemaDefinitionArrayUtil::generateOrUpdateTableBySchemaDefinition($schema, $messageLogger, false); } $bean = ZurmoRedBean::findOne($tableName, "id = :id", array('id' => $id)); if ($bean == null) { throw new NotFoundException(); } $bean->{$attribute} = $newValue; $storedId = ZurmoRedBean::store($bean); if ($storedId != $id) { throw new FailedToSaveModelException("Id of updated record does not match the id used in finding it."); } }
/** * Saves the model to the database. Models are only saved if they have been * modified and related models are saved before this model. If a related model * is modified and needs saving the deems the model to be modified and need * saving, which ensures that keys are updated. * Cyclic relationships are prevented from causing problems by the * save only proceeding to non-saved models. */ public function save($runValidation = true, array $attributeNames = null) { if ($attributeNames !== null) { throw new NotSupportedException(); } if ($this->isSaving) { return true; } $this->isSaving = true; try { if (!$runValidation || $this->validate()) { if ($this->beforeSave()) { $beans = array_values($this->modelClassNameToBean); $this->linkBeans(); // The breakLink/link is deferred until the save to avoid // disconnecting or creating an empty row if the model was // never actually saved. foreach ($this->unlinkedRelationNames as $key => $relationName) { $bean = $this->attributeNameToBeanAndClassName[$relationName][0]; $relationAndOwns = static::getRelationNameToRelationTypeModelClassNameAndOwnsForModel(); $relatedModelClassName = $relationAndOwns[$relationName][1]; $tempRelatedModelClassName = $relatedModelClassName; self::resolveModelClassNameForClassesWithoutBeans($tempRelatedModelClassName); $relatedTableName = $tempRelatedModelClassName::getTableName(); $linkName = strtolower($relationName); if (static::getRelationType($relationName) == self::HAS_ONE && static::getRelationLinkType($relationName) == self::LINK_TYPE_SPECIFIC) { $linkName = strtolower(static::getRelationLinkName($relationName)); } elseif ($linkName == strtolower($relatedModelClassName)) { $linkName = null; } ZurmoRedBeanLinkManager::breakLink($bean, $relatedTableName, $linkName); //Check the $this->{$relationName} second in the if clause to avoid accidentially getting //a relation to now save. //todo: this needs to be properly handled. if (isset($this->unlinkedOwnedRelatedModelsToRemove[$relationName]) && $this->{$relationName} !== null) { //Remove hasOne owned related models that are no longer needed because they have //been replaced with another hasOne owned model. if ($this->unlinkedOwnedRelatedModelsToRemove[$relationName]->id > 0) { $this->unlinkedOwnedRelatedModelsToRemove[$relationName]->unrestrictedDelete(); } unset($this->unlinkedOwnedRelatedModelsToRemove[$relationName]); } unset($this->unlinkedRelationNames[$key]); } assert('count($this->unlinkedRelationNames) == 0'); foreach ($this->relationNameToRelatedModel as $relationName => $relatedModel) { $relationAndOwns = static::getRelationNameToRelationTypeModelClassNameAndOwnsForModel(); $relationType = $relationAndOwns[$relationName][0]; if (!in_array($relationType, array(self::HAS_ONE_BELONGS_TO, self::HAS_MANY_BELONGS_TO))) { if ($this->isRelatedModelReallyModified($relatedModel, $relationAndOwns[$relationName][0], $relationAndOwns[$relationName][2]) || $this->isAttributeRequired($relationName)) { //If the attribute is required, but already exists and has not been modified we do //not have to worry about saving it. if ($this->isSavableFromRelation && !($this->isAttributeRequired($relationName) && !$relatedModel->isModified() && $relatedModel->id > 0)) { if (!$relatedModel->save(false)) { $this->isSaving = false; return false; } } elseif ($relatedModel->isModified()) { throw new NotSuportedException(); } } } if ($relatedModel instanceof RedBeanModel) { $bean = $this->attributeNameToBeanAndClassName[$relationName][0]; $relationAndOwns = static::getRelationNameToRelationTypeModelClassNameAndOwnsForModel(); $relatedModelClassName = $relationAndOwns[$relationName][1]; $linkName = strtolower($relationName); if ($relationType == self::HAS_ONE && static::getRelationLinkType($relationName) == self::LINK_TYPE_SPECIFIC) { $linkName = strtolower(static::getRelationLinkName($relationName)); } elseif (strtolower($linkName) == strtolower($relatedModelClassName) || static::getRelationLinkType($relationName) == self::LINK_TYPE_ASSUMPTIVE) { $linkName = null; } elseif ($relationType == static::HAS_MANY_BELONGS_TO || $relationType == static::HAS_ONE_BELONGS_TO) { throw new NotSupportedException(Zurmo::t('Core', 'Relations of type HAS_MANY_BELONGS_TO OR HAS_ONE_BELONGS_TO must have the relation name ' . 'the same as the related model class name. Relation: {relationName} ' . 'Relation model class name: {relationModelClassName}', array('{relationName}' => $linkName, '{relationModelClassName}' => $relatedModelClassName))); } //Needed to exclude HAS_ONE_BELONGS_TO because an additional column was being created //on the wrong side. if ($relationType != static::HAS_ONE_BELONGS_TO && ($this->isRelatedModelReallyModified($relatedModel, $relationAndOwns[$relationName][0], $relationAndOwns[$relationName][2]) || $relatedModel->id > 0 || $this->isAttributeRequired($relationName))) { $relatedModel = $this->relationNameToRelatedModel[$relationName]; $relatedBean = $relatedModel->getClassBean($relatedModelClassName); //Exclude HAS_MANY_BELONGS_TO because if the existing relation is unlinked, then //this link should not be reactivated, because it will improperly create the bean //in the database. if (!($relationType == static::HAS_MANY_BELONGS_TO && $this->{$relationName}->id < 0)) { ZurmoRedBeanLinkManager::link($bean, $relatedBean, $linkName); } } } } $baseModelClassName = null; foreach ($this->modelClassNameToBean as $modelClassName => $bean) { ZurmoRedBean::store($bean); assert('$bean->id > 0'); } $this->modified = false; $this->afterSave(); $calledModelClassName = get_called_class(); if ($calledModelClassName::isCacheable()) { RedBeanModelsCache::cacheModel($this); } $this->isSaving = false; return true; } } $this->isSaving = false; return false; } catch (Exception $e) { $this->isSaving = false; throw $e; } }
public function analyzePage() { $data = $this->dataProvider->getData(true); foreach ($data as $rowBean) { assert('$rowBean->id != null'); $columnMessages = array(); $shouldSkipRow = false; foreach ($this->sanitizableColumnNames as $columnName) { $attributeIndexOrDerivedType = $this->mappingData[$columnName]['attributeIndexOrDerivedType']; $penultimateModelClassName = ImportUtil::getPenultimateModelClassNameByImportRules($this->importRules); $attributeImportRules = AttributeImportRulesFactory::makeByImportRulesTypeAndAttributeIndexOrDerivedType($this->importRules->getType(), $attributeIndexOrDerivedType, $penultimateModelClassName); $modelClassName = $attributeImportRules->getModelClassName(); $attributeName = static::resolveAttributeNameByRules($attributeImportRules); if (null != ($attributeValueSanitizerUtilTypes = $attributeImportRules->getSanitizerUtilTypesInProcessingOrder())) { assert('is_array($attributeValueSanitizerUtilTypes)'); foreach ($attributeValueSanitizerUtilTypes as $attributeValueSanitizerUtilType) { $sanitizer = ImportSanitizerUtilFactory::make($attributeValueSanitizerUtilType, $modelClassName, $attributeName, $columnName, $this->mappingData[$columnName], null, $penultimateModelClassName, $attributeIndexOrDerivedType); $sanitizer->analyzeByRow($rowBean); if ($sanitizer->getShouldSkipRow()) { $shouldSkipRow = true; } foreach ($sanitizer->getAnalysisMessages() as $message) { $columnMessages[$columnName][] = $message; } $classToEvaluate = new ReflectionClass($sanitizer); if ($classToEvaluate->implementsInterface('ImportSanitizerHasCustomFieldValuesInterface')) { $missingCustomFieldValues = $sanitizer->getMissingCustomFieldValues(); $this->getCustomFieldsInstructionData()->addMissingValuesByColumnName($missingCustomFieldValues, $columnName); } } } } if (!empty($columnMessages)) { $rowBean->serializedAnalysisMessages = serialize($columnMessages); if ($shouldSkipRow) { $rowBean->analysisStatus = static::STATUS_SKIP; } else { $rowBean->analysisStatus = static::STATUS_WARN; } } else { $rowBean->serializedAnalysisMessages = null; $rowBean->analysisStatus = static::STATUS_CLEAN; } ZurmoRedBean::store($rowBean); } }
public function testDateTimeHinting() { $bean = ZurmoRedBean::dispense("wukka"); // Not Coding Standard $bean->setMeta("hint", array("prop" => "datetime")); // Not Coding Standard $bean->prop = "2010-01-01 10:00:00"; // Not Coding Standard ZurmoRedBean::store($bean); // Not Coding Standard $rows = ZurmoRedBean::getAll('desc wukka'); $this->assertEquals('prop', $rows[3]['Field']); $this->assertEquals('datetime', $rows[3]['Type']); }