/** * Spreadsheet output: designed for end users doing some reporting * Then the ids are excluded and replaced by the corresponding friendlyname */ static function GetSetAsHTMLSpreadsheet(DBObjectSet $oSet, $aParams = array()) { $aFields = null; if (isset($aParams['fields']) && strlen($aParams['fields']) > 0) { $aFields = explode(',', $aParams['fields']); } $bFieldsAdvanced = false; if (isset($aParams['fields_advanced'])) { $bFieldsAdvanced = (bool) $aParams['fields_advanced']; } $bLocalize = true; if (isset($aParams['localize_values'])) { $bLocalize = (bool) $aParams['localize_values']; } $aList = array(); $oAppContext = new ApplicationContext(); $aClasses = $oSet->GetFilter()->GetSelectedClasses(); $aAuthorizedClasses = array(); foreach ($aClasses as $sAlias => $sClassName) { if (UserRights::IsActionAllowed($sClassName, UR_ACTION_READ, $oSet) && (UR_ALLOWED_YES || UR_ALLOWED_DEPENDS)) { $aAuthorizedClasses[$sAlias] = $sClassName; } } $aAttribs = array(); $aHeader = array(); foreach ($aAuthorizedClasses as $sAlias => $sClassName) { $aList[$sAlias] = array(); foreach (MetaModel::ListAttributeDefs($sClassName) as $sAttCode => $oAttDef) { if (is_null($aFields) || count($aFields) == 0) { // Standard list of attributes (no link sets) if ($oAttDef->IsScalar() && ($oAttDef->IsWritable() || $oAttDef->IsExternalField())) { $sAttCodeEx = $oAttDef->IsExternalField() ? $oAttDef->GetKeyAttCode() . '->' . $oAttDef->GetExtAttCode() : $sAttCode; $aList[$sAlias][$sAttCodeEx] = $oAttDef; if ($bFieldsAdvanced && $oAttDef->IsExternalKey(EXTKEY_RELATIVE)) { $sRemoteClass = $oAttDef->GetTargetClass(); foreach (MetaModel::GetReconcKeys($sRemoteClass) as $sRemoteAttCode) { $aList[$sAlias][$sAttCode . '->' . $sRemoteAttCode] = MetaModel::GetAttributeDef($sRemoteClass, $sRemoteAttCode); } } } } else { // User defined list of attributes if (in_array($sAttCode, $aFields) || in_array($sAlias . '.' . $sAttCode, $aFields)) { $aList[$sAlias][$sAttCode] = $oAttDef; } } } // Replace external key by the corresponding friendly name (if not already in the list) foreach ($aList[$sAlias] as $sAttCode => $oAttDef) { if ($oAttDef->IsExternalKey()) { unset($aList[$sAlias][$sAttCode]); $sFriendlyNameAttCode = $sAttCode . '_friendlyname'; if (!array_key_exists($sFriendlyNameAttCode, $aList[$sAlias]) && MetaModel::IsValidAttCode($sClassName, $sFriendlyNameAttCode)) { $oFriendlyNameAtt = MetaModel::GetAttributeDef($sClassName, $sFriendlyNameAttCode); $aList[$sAlias][$sFriendlyNameAttCode] = $oFriendlyNameAtt; } } } foreach ($aList[$sAlias] as $sAttCodeEx => $oAttDef) { $sColLabel = $bLocalize ? MetaModel::GetLabel($sClassName, $sAttCodeEx) : $sAttCodeEx; $oFinalAttDef = $oAttDef->GetFinalAttDef(); if (get_class($oFinalAttDef) == 'AttributeDateTime') { $aHeader[] = $sColLabel . ' (' . Dict::S('UI:SplitDateTime-Date') . ')'; $aHeader[] = $sColLabel . ' (' . Dict::S('UI:SplitDateTime-Time') . ')'; } else { $aHeader[] = $sColLabel; } } } $sHtml = "<table border=\"1\">\n"; $sHtml .= "<tr>\n"; $sHtml .= "<td>" . implode("</td><td>", $aHeader) . "</td>\n"; $sHtml .= "</tr>\n"; $oSet->Seek(0); while ($aObjects = $oSet->FetchAssoc()) { $aRow = array(); foreach ($aAuthorizedClasses as $sAlias => $sClassName) { $oObj = $aObjects[$sAlias]; foreach ($aList[$sAlias] as $sAttCodeEx => $oAttDef) { if (is_null($oObj)) { $aRow[] = '<td></td>'; } else { $oFinalAttDef = $oAttDef->GetFinalAttDef(); if (get_class($oFinalAttDef) == 'AttributeDateTime') { $sDate = $oObj->Get($sAttCodeEx); if ($sDate === null) { $aRow[] = '<td></td>'; $aRow[] = '<td></td>'; } else { $iDate = AttributeDateTime::GetAsUnixSeconds($sDate); $aRow[] = '<td>' . date('Y-m-d', $iDate) . '</td>'; $aRow[] = '<td>' . date('H:i:s', $iDate) . '</td>'; } } else { if ($oAttDef instanceof AttributeCaseLog) { $rawValue = $oObj->Get($sAttCodeEx); $outputValue = str_replace("\n", "<br/>", htmlentities($rawValue->__toString(), ENT_QUOTES, 'UTF-8')); // Trick for Excel: treat the content as text even if it begins with an equal sign $aRow[] = '<td x:str>' . $outputValue . '</td>'; } else { $rawValue = $oObj->Get($sAttCodeEx); // Due to custom formatting rules, empty friendlynames may be rendered as non-empty strings // let's fix this and make sure we render an empty string if the key == 0 if ($oAttDef instanceof AttributeFriendlyName) { $sKeyAttCode = $oAttDef->GetKeyAttCode(); if ($sKeyAttCode != 'id') { if ($oObj->Get($sKeyAttCode) == 0) { $rawValue = ''; } } } if ($bLocalize) { $outputValue = htmlentities($oFinalAttDef->GetEditValue($rawValue), ENT_QUOTES, 'UTF-8'); } else { $outputValue = htmlentities($rawValue, ENT_QUOTES, 'UTF-8'); } $aRow[] = '<td>' . $outputValue . '</td>'; } } } } } $sHtml .= implode("\n", $aRow); $sHtml .= "</tr>\n"; } $sHtml .= "</table>\n"; return $sHtml; }
} $oPage->add('<tr>'); $oPage->add("<th>{$sField}</th>"); $oPage->add('<td>' . GetMappingForField($sClassName, $sField, $index, $bAdvanced, $sDefaultChoice) . '</td>'); $oPage->add('<td> </td>'); $oPage->add('<td><input id="search_' . $index . '" type="checkbox" name="search_field[' . $index . ']" value="1" /></td>'); $oPage->add('<td>' . (isset($aData[$iStartLine][$index - 1]) ? htmlentities($aData[$iStartLine][$index - 1], ENT_QUOTES, 'UTF-8') : ' ') . '</td>'); $oPage->add('<td>' . (isset($aData[$iStartLine + 1][$index - 1]) ? htmlentities($aData[$iStartLine + 1][$index - 1], ENT_QUOTES, 'UTF-8') : ' ') . '</td>'); $oPage->add('</tr>'); $index++; } $oPage->add("</table>\n"); if (empty($sInitSearchField)) { // Propose a reconciliation scheme // $aReconciliationKeys = MetaModel::GetReconcKeys($sClassName); $aMoreReconciliationKeys = array(); // Store: key => void to automatically remove duplicates foreach ($aReconciliationKeys as $sAttCode) { if (!MetaModel::IsValidAttCode($sClassName, $sAttCode)) { continue; } $oAttDef = MetaModel::GetAttributeDef($sClassName, $sAttCode); if ($oAttDef->IsExternalKey()) { // An external key is specified as a reconciliation key: this means that all the reconciliation // keys of this class are proposed to identify the target object $aMoreReconciliationKeys = array_merge($aMoreReconciliationKeys, GetMappingsForExtKey($sAttCode, $oAttDef, $bAdvanced)); } elseif ($oAttDef->IsExternalField()) { // An external field is specified as a reconciliation key, translate the field into a field on the target class // since external fields are not writable, and thus never appears in the mapping form $sKeyAttCode = $oAttDef->GetKeyAttCode();
protected function GetSubAttributes($sClass, $sAttCode, $oAttDef) { $aResult = array(); switch (get_class($oAttDef)) { case 'AttributeExternalKey': case 'AttributeHierarchicalKey': $bAddFriendlyName = true; $oKeyAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode); $sRemoteClass = $oKeyAttDef->GetTargetClass(); $sFriendlyNameAttCode = MetaModel::GetFriendlyNameAttributeCode($sRemoteClass); if (!is_null($sFriendlyNameAttCode)) { // The friendly name is made of a single attribute, check if that attribute is present as an external field foreach (MetaModel::ListAttributeDefs($sClass) as $sSubAttCode => $oSubAttDef) { if ($oSubAttDef instanceof AttributeExternalField) { if ($oSubAttDef->GetKeyAttCode() == $sAttCode && $oSubAttDef->GetExtAttCode() == $sFriendlyNameAttCode) { $bAddFriendlyName = false; } } } } $aResult[$sAttCode] = array('code' => $sAttCode, 'unique_label' => $oAttDef->GetLabel(), 'label' => Dict::S('UI:CSVImport:idField'), 'attdef' => $oAttDef); if ($bAddFriendlyName) { if ($this->IsExportableField($sClass, $sAttCode . '->friendlyname')) { $aResult[$sAttCode . '->friendlyname'] = array('code' => $sAttCode . '->friendlyname', 'unique_label' => $oAttDef->GetLabel() . '->' . Dict::S('Core:FriendlyName-Label'), 'label' => Dict::S('Core:FriendlyName-Label'), 'attdef' => MetaModel::GetAttributeDef($sClass, $sAttCode . '_friendlyname')); } } foreach (MetaModel::ListAttributeDefs($sClass) as $sSubAttCode => $oSubAttDef) { if ($oSubAttDef instanceof AttributeExternalField) { if ($this->IsExportableField($sClass, $sSubAttCode, $oSubAttDef)) { if ($oSubAttDef->GetKeyAttCode() == $sAttCode) { $sAttCodeEx = $sAttCode . '->' . $oSubAttDef->GetExtAttCode(); $aResult[$sAttCodeEx] = array('code' => $sAttCodeEx, 'unique_label' => $oAttDef->GetLabel() . '->' . $oSubAttDef->GetExtAttDef()->GetLabel(), 'label' => MetaModel::GetLabel($sRemoteClass, $oSubAttDef->GetExtAttCode()), 'attdef' => $oSubAttDef); } } } } // Add the reconciliation keys foreach (MetaModel::GetReconcKeys($sRemoteClass) as $sRemoteAttCode) { $sAttCodeEx = $sAttCode . '->' . $sRemoteAttCode; if (!array_key_exists($sAttCodeEx, $aResult)) { $oRemoteAttDef = MetaModel::GetAttributeDef($sRemoteClass, $sRemoteAttCode); if ($this->IsExportableField($sRemoteClass, $sRemoteAttCode, $oRemoteAttDef)) { $aResult[$sAttCodeEx] = array('code' => $sAttCodeEx, 'unique_label' => $oAttDef->GetLabel() . '->' . $oRemoteAttDef->GetLabel(), 'label' => MetaModel::GetLabel($sRemoteClass, $sRemoteAttCode), 'attdef' => $oRemoteAttDef); } } } break; case 'AttributeStopWatch': foreach (MetaModel::ListAttributeDefs($sClass) as $sSubAttCode => $oSubAttDef) { if ($oSubAttDef instanceof AttributeSubItem) { if ($oSubAttDef->GetParentAttCode() == $sAttCode) { if ($this->IsExportableField($sClass, $sSubAttCode, $oSubAttDef)) { $aResult[$sSubAttCode] = array('code' => $sSubAttCode, 'unique_label' => $oSubAttDef->GetLabel(), 'label' => $oSubAttDef->GetLabel(), 'attdef' => $oSubAttDef); } } } } break; } return $aResult; }
/** * Store an object in the database and remember the mapping * between its original ID and the newly created ID in the database */ protected function StoreObject($sClass, $oTargetObj, $iSrcId, $bSearch = false, $bUpdateKeyCacheOnly = false) { $iObjId = 0; try { if ($bSearch) { // Check if the object does not already exist, based on its usual reconciliation keys... $aReconciliationKeys = MetaModel::GetReconcKeys($sClass); if (count($aReconciliationKeys) > 0) { // Some reconciliation keys have been defined, use them to search for the object $oSearch = new DBObjectSearch($sClass); $iConditionsCount = 0; foreach ($aReconciliationKeys as $sAttCode) { if ($oTargetObj->Get($sAttCode) != '') { $oSearch->AddCondition($sAttCode, $oTargetObj->Get($sAttCode), '='); $iConditionsCount++; } } if ($iConditionsCount > 0) { $oSet = new DBObjectSet($oSearch); if ($oSet->count() == 1) { // The object already exists, reuse it $oExistingObject = $oSet->Fetch(); $iObjId = $oExistingObject->GetKey(); } } } } if ($iObjId == 0) { if ($oTargetObj->IsNew()) { if (!$bUpdateKeyCacheOnly) { $iObjId = $oTargetObj->DBInsertNoReload(); $this->m_iCountCreated++; } } else { $iObjId = $oTargetObj->GetKey(); if (!$bUpdateKeyCacheOnly) { $oTargetObj->DBUpdate(); } } } } catch (Exception $e) { SetupPage::log_error("An object could not be recorded - {$sClass}/{$iSrcId} - " . $e->getMessage()); $this->m_aErrors[] = "An object could not be recorded - {$sClass}/{$iSrcId} - " . $e->getMessage(); } $aParentClasses = MetaModel::EnumParentClasses($sClass); $aParentClasses[] = $sClass; foreach ($aParentClasses as $sObjClass) { $this->m_aKeys[$sObjClass][$iSrcId] = $iObjId; } $this->m_aObjectsCache[$sClass][$iObjId] = $oTargetObj; }
// if (empty($sReconcKeys)) { $aReconcSpec = array(); // Base reconciliation scheme on the default one // The reconciliation attributes not present in the data will be ignored foreach (MetaModel::GetReconcKeys($sClass) as $sReconcKeyAttCode) { if (in_array($sReconcKeyAttCode, $aFieldList)) { if ($bLocalize) { $aReconcSpec[] = MetaModel::GetLabel($sClass, $sReconcKeyAttCode); } else { $aReconcSpec[] = $sReconcKeyAttCode; } } } if (count($aReconcSpec) == 0) { throw new BulkLoadException("No reconciliation scheme could be defined, please add a column corresponding to one defined reconciliation key (class: '{$sClass}', reconciliation:" . implode(',', MetaModel::GetReconcKeys($sClass)) . ")"); } $sReconcKeys = implode(',', $aReconcSpec); } // Interpret the list of reconciliation keys // $aFinalReconcilKeys = array(); $aReconcilKeysReport = array(); foreach (explode(',', $sReconcKeys) as $sReconcKey) { $sReconcKey = trim($sReconcKey); if (empty($sReconcKey)) { continue; } // skip empty spec if (array_key_exists(strtolower($sReconcKey), $aKnownColumnNames)) { // Translate from a translated name to codes
protected function GetFieldsList($oSet, $bFieldsAdvanced = false, $bLocalize = true, $aFields = null) { $this->aFieldsList = array(); $oAppContext = new ApplicationContext(); $aClasses = $oSet->GetFilter()->GetSelectedClasses(); $this->aAuthorizedClasses = array(); foreach ($aClasses as $sAlias => $sClassName) { if (UserRights::IsActionAllowed($sClassName, UR_ACTION_READ, $oSet) && (UR_ALLOWED_YES || UR_ALLOWED_DEPENDS)) { $this->aAuthorizedClasses[$sAlias] = $sClassName; } } $aAttribs = array(); $this->aTableHeaders = array(); foreach ($this->aAuthorizedClasses as $sAlias => $sClassName) { $aList[$sAlias] = array(); foreach (MetaModel::ListAttributeDefs($sClassName) as $sAttCode => $oAttDef) { if (is_null($aFields) || count($aFields) == 0) { // Standard list of attributes (no link sets) if ($oAttDef->IsScalar() && ($oAttDef->IsWritable() || $oAttDef->IsExternalField())) { $sAttCodeEx = $oAttDef->IsExternalField() ? $oAttDef->GetKeyAttCode() . '->' . $oAttDef->GetExtAttCode() : $sAttCode; if ($oAttDef->IsExternalKey(EXTKEY_ABSOLUTE)) { if ($bFieldsAdvanced) { $aList[$sAlias][$sAttCodeEx] = $oAttDef; if ($oAttDef->IsExternalKey(EXTKEY_RELATIVE)) { $sRemoteClass = $oAttDef->GetTargetClass(); foreach (MetaModel::GetReconcKeys($sRemoteClass) as $sRemoteAttCode) { $this->aFieldsList[$sAlias][$sAttCode . '->' . $sRemoteAttCode] = MetaModel::GetAttributeDef($sRemoteClass, $sRemoteAttCode); } } } } else { // Any other attribute $this->aFieldsList[$sAlias][$sAttCodeEx] = $oAttDef; } } } else { // User defined list of attributes if (in_array($sAttCode, $aFields) || in_array($sAlias . '.' . $sAttCode, $aFields)) { $this->aFieldsList[$sAlias][$sAttCode] = $oAttDef; } } } if ($bFieldsAdvanced) { $this->aTableHeaders['id'] = '0'; } foreach ($this->aFieldsList[$sAlias] as $sAttCodeEx => $oAttDef) { $sLabel = $bLocalize ? MetaModel::GetLabel($sClassName, $sAttCodeEx, isset($aParams['showMandatoryFields'])) : $sAttCodeEx; if ($oAttDef instanceof AttributeDateTime) { $this->aTableHeaders[$sLabel] = 'datetime'; } else { $this->aTableHeaders[$sLabel] = 'string'; } } } }