Exemplo n.º 1
0
/**
 * Fills the given XML node with te details of the specified object
 */
function AddNodeDetails(&$oNode, $oObj)
{
    $aZlist = MetaModel::GetZListItems(get_class($oObj), 'list');
    $aLabels = array();
    $index = 0;
    foreach ($aZlist as $sAttCode) {
        $oAttDef = MetaModel::GetAttributeDef(get_class($oObj), $sAttCode);
        $aLabels[] = $oAttDef->GetLabel();
        if (!$oAttDef->IsLinkSet()) {
            $oNode->SetAttribute('att_' . $index, $oObj->GetAsHTML($sAttCode));
        }
        $index++;
    }
    $oNode->SetAttribute('zlist', implode(',', $aLabels));
}
 protected function SuggestField($sClass, $sAttCode)
 {
     switch ($sAttCode) {
         case 'id':
             // replace 'id' by 'friendlyname'
             $sAttCode = 'friendlyname';
             break;
         default:
             $oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode);
             if ($oAttDef instanceof AttributeExternalKey) {
                 $sAttCode .= '_friendlyname';
             }
     }
     return parent::SuggestField($sClass, $sAttCode);
 }
Exemplo n.º 3
0
/**
 * Adds the context parameters to the audit query
 */
function FilterByContext(DBSearch &$oFilter, ApplicationContext $oAppContext)
{
    $sObjClass = $oFilter->GetClass();
    $aContextParams = $oAppContext->GetNames();
    $aCallSpec = array($sObjClass, 'MapContextParam');
    if (is_callable($aCallSpec)) {
        foreach ($aContextParams as $sParamName) {
            $sValue = $oAppContext->GetCurrentValue($sParamName, null);
            if ($sValue != null) {
                $sAttCode = call_user_func($aCallSpec, $sParamName);
                // Returns null when there is no mapping for this parameter
                if ($sAttCode != null && MetaModel::IsValidAttCode($sObjClass, $sAttCode)) {
                    // Check if the condition points to a hierarchical key
                    if ($sAttCode == 'id') {
                        // Filtering on the objects themselves
                        $sHierarchicalKeyCode = MetaModel::IsHierarchicalClass($sObjClass);
                        if ($sHierarchicalKeyCode !== false) {
                            $oRootFilter = new DBObjectSearch($sObjClass);
                            $oRootFilter->AddCondition($sAttCode, $sValue);
                            $oFilter->AddCondition_PointingTo($oRootFilter, $sHierarchicalKeyCode, TREE_OPERATOR_BELOW);
                            // Use the 'below' operator by default
                            $bConditionAdded = true;
                        }
                    } else {
                        $oAttDef = MetaModel::GetAttributeDef($sObjClass, $sAttCode);
                        $bConditionAdded = false;
                        if ($oAttDef->IsExternalKey()) {
                            $sHierarchicalKeyCode = MetaModel::IsHierarchicalClass($oAttDef->GetTargetClass());
                            if ($sHierarchicalKeyCode !== false) {
                                $oRootFilter = new DBObjectSearch($oAttDef->GetTargetClass());
                                $oRootFilter->AddCondition('id', $sValue);
                                $oHKFilter = new DBObjectSearch($oAttDef->GetTargetClass());
                                $oHKFilter->AddCondition_PointingTo($oRootFilter, $sHierarchicalKeyCode, TREE_OPERATOR_BELOW);
                                // Use the 'below' operator by default
                                $oFilter->AddCondition_PointingTo($oHKFilter, $sAttCode);
                                $bConditionAdded = true;
                            }
                        }
                    }
                    if (!$bConditionAdded) {
                        $oFilter->AddCondition($sAttCode, $sValue);
                    }
                }
            }
        }
    }
}
Exemplo n.º 4
0
 /**
  * Helper to make an output value for a given attribute
  * 	 
  * @param DBObject $oObject The object being reported
  * @param string $sAttCode The attribute code (must be valid)
  * @param boolean $bExtendedOutput Output all of the link set attributes ?
  * @return string A scalar representation of the value
  */
 protected function MakeResultValue(DBObject $oObject, $sAttCode, $bExtendedOutput = false)
 {
     if ($sAttCode == 'id') {
         $value = $oObject->GetKey();
     } else {
         $sClass = get_class($oObject);
         $oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode);
         if ($oAttDef instanceof AttributeLinkedSet) {
             // Iterate on the set and build an array of array of attcode=>value
             $oSet = $oObject->Get($sAttCode);
             $value = array();
             while ($oLnk = $oSet->Fetch()) {
                 $sLnkRefClass = $bExtendedOutput ? get_class($oLnk) : $oAttDef->GetLinkedClass();
                 $aLnkValues = array();
                 foreach (MetaModel::ListAttributeDefs($sLnkRefClass) as $sLnkAttCode => $oLnkAttDef) {
                     // Skip attributes pointing to the current object (redundant data)
                     if ($sLnkAttCode == $oAttDef->GetExtKeyToMe()) {
                         continue;
                     }
                     // Skip any attribute of the link that points to the current object
                     $oLnkAttDef = MetaModel::GetAttributeDef($sLnkRefClass, $sLnkAttCode);
                     if (method_exists($oLnkAttDef, 'GetKeyAttCode')) {
                         if ($oLnkAttDef->GetKeyAttCode() == $oAttDef->GetExtKeyToMe()) {
                             continue;
                         }
                     }
                     $aLnkValues[$sLnkAttCode] = $this->MakeResultValue($oLnk, $sLnkAttCode, $bExtendedOutput);
                 }
                 $value[] = $aLnkValues;
             }
         } else {
             $value = $oAttDef->GetForJSON($oObject->Get($sAttCode));
         }
     }
     return $value;
 }
Exemplo n.º 5
0
 function DisplayBareProperties(WebPage $oPage, $bEditMode = false, $sPrefix = '', $aExtraParams = array())
 {
     $aFieldsMap = parent::DisplayBareProperties($oPage, $bEditMode, $sPrefix, $aExtraParams);
     if (!$bEditMode) {
         $sFields = trim($this->Get('fields'));
         $bExportV1Recommended = $sFields == '';
         if ($bExportV1Recommended) {
             $oFieldAttDef = MetaModel::GetAttributeDef('QueryOQL', 'fields');
             $oPage->add('<div class="message message_error" style="padding-left: 30px;"><div style="padding: 10px;">' . Dict::Format('UI:Query:UrlV1', $oFieldAttDef->GetLabel()) . '</div></div>');
             $sUrl = utils::GetAbsoluteUrlAppRoot() . 'webservices/export.php?format=spreadsheet&login_mode=basic&query=' . $this->GetKey();
         } else {
             $sUrl = utils::GetAbsoluteUrlAppRoot() . 'webservices/export-v2.php?format=spreadsheet&login_mode=basic&query=' . $this->GetKey();
         }
         $sOql = $this->Get('oql');
         $sMessage = null;
         try {
             $oSearch = DBObjectSearch::FromOQL($sOql);
             $aParameters = $oSearch->GetQueryParams();
             foreach ($aParameters as $sParam => $val) {
                 $sUrl .= '&arg_' . $sParam . '=["' . $sParam . '"]';
             }
             $oPage->p(Dict::S('UI:Query:UrlForExcel') . ':<br/><textarea cols="80" rows="3" READONLY>' . $sUrl . '</textarea>');
             if (count($aParameters) == 0) {
                 $oBlock = new DisplayBlock($oSearch, 'list');
                 $aExtraParams = array('table_id' => 'query_preview_' . $this->getKey());
                 $sBlockId = 'block_query_preview_' . $this->GetKey();
                 // make a unique id (edition occuring in the same DOM)
                 $oBlock->Display($oPage, $sBlockId, $aExtraParams);
             }
         } catch (OQLException $e) {
             $sMessage = '<div class="message message_error" style="padding-left: 30px;"><div style="padding: 10px;">' . Dict::Format('UI:RunQuery:Error', $e->getHtmlDesc()) . '</div></div>';
             $oPage->p($sMessage);
         }
     }
     return $aFieldsMap;
 }
 public function GetTooltip($aContextDefs)
 {
     $sHtml = '';
     $oCurrObj = $this->GetProperty('object');
     $sSubClass = get_class($oCurrObj);
     $sHtml .= $oCurrObj->GetHyperlink() . "<hr/>";
     $aContextRootCauses = $this->GetProperty('context_root_causes');
     if (!is_null($aContextRootCauses)) {
         foreach ($aContextRootCauses as $key => $aObjects) {
             $aContext = $aContextDefs[$key];
             $aRootCauses = array();
             foreach ($aObjects as $oRootCause) {
                 $aRootCauses[] = $oRootCause->GetHyperlink();
             }
             $sHtml .= '<p><img style="max-height: 24px; vertical-align:bottom;" src="' . utils::GetAbsoluteUrlModulesRoot() . $aContext['icon'] . '" title="' . htmlentities(Dict::S($aContext['dict'])) . '">&nbsp;' . implode(', ', $aRootCauses) . '</p>';
         }
         $sHtml .= '<hr/>';
     }
     $sHtml .= '<table><tbody>';
     foreach (MetaModel::GetZListItems($sSubClass, 'list') as $sAttCode) {
         $oAttDef = MetaModel::GetAttributeDef($sSubClass, $sAttCode);
         $sHtml .= '<tr><td>' . $oAttDef->GetLabel() . ':&nbsp;</td><td>' . $oCurrObj->GetAsHtml($sAttCode) . '</td></tr>';
     }
     $sHtml .= '</tbody></table>';
     return $sHtml;
 }
Exemplo n.º 7
0
 public function unserialize($sData)
 {
     $aData = unserialize($sData);
     $this->iDefaultPageSize = $aData['iDefaultPageSize'];
     $this->aColumns = $aData['aColumns'];
     foreach ($this->aClassAliases as $sAlias => $sClass) {
         foreach ($this->aColumns[$sAlias] as $sAttCode => $aData) {
             $aFieldData = false;
             if ($sAttCode == '_key_') {
                 $aFieldData = $this->GetFieldData($sAlias, $sAttCode, null, true, $aData['sort']);
             } else {
                 if (MetaModel::isValidAttCode($sClass, $sAttCode)) {
                     $oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode);
                     $aFieldData = $this->GetFieldData($sAlias, $sAttCode, $oAttDef, true, $aData['sort']);
                 }
             }
             if ($aFieldData) {
                 $this->aColumns[$sAlias][$sAttCode] = $aFieldData;
             } else {
                 unset($this->aColumns[$sAlias][$sAttCode]);
             }
         }
     }
     $this->FixVisibleColumns();
 }
Exemplo n.º 8
0
 /**
  * Common to the recording of link set changes (add/remove/modify)	
  */
 private function PrepareChangeOpLinkSet($iLinkSetOwnerId, $oLinkSet, $sChangeOpClass, $aOriginalValues = null)
 {
     if ($iLinkSetOwnerId <= 0) {
         return null;
     }
     if (!is_subclass_of($oLinkSet->GetHostClass(), 'CMDBObject')) {
         // The link set owner class does not keep track of its history
         return null;
     }
     // Determine the linked item class and id
     //
     if ($oLinkSet->IsIndirect()) {
         // The "item" is on the other end (N-N links)
         $sExtKeyToRemote = $oLinkSet->GetExtKeyToRemote();
         $oExtKeyToRemote = MetaModel::GetAttributeDef(get_class($this), $sExtKeyToRemote);
         $sItemClass = $oExtKeyToRemote->GetTargetClass();
         if ($aOriginalValues) {
             // Get the value from the original values
             $iItemId = $aOriginalValues[$sExtKeyToRemote];
         } else {
             $iItemId = $this->Get($sExtKeyToRemote);
         }
     } else {
         // I am the "item" (1-N links)
         $sItemClass = get_class($this);
         $iItemId = $this->GetKey();
     }
     // Get the remote object, to determine its exact class
     // Possible optimization: implement a tool in MetaModel, to get the final class of an object (not always querying + query reduced to a select on the root table!
     $oOwner = MetaModel::GetObject($oLinkSet->GetHostClass(), $iLinkSetOwnerId, false);
     if ($oOwner) {
         $sLinkSetOwnerClass = get_class($oOwner);
         $oMyChangeOp = MetaModel::NewObject($sChangeOpClass);
         $oMyChangeOp->Set("objclass", $sLinkSetOwnerClass);
         $oMyChangeOp->Set("objkey", $iLinkSetOwnerId);
         $oMyChangeOp->Set("attcode", $oLinkSet->GetCode());
         $oMyChangeOp->Set("item_class", $sItemClass);
         $oMyChangeOp->Set("item_id", $iItemId);
         return $oMyChangeOp;
     } else {
         // Depending on the deletion order, it may happen that the id is already invalid... ignore
         return null;
     }
 }
Exemplo n.º 9
0
 static function ParseJsonSet($oMe, $sLinkClass, $sExtKeyToMe, $sJsonSet)
 {
     $aSet = json_decode($sJsonSet, true);
     // true means hash array instead of object
     $oSet = CMDBObjectSet::FromScratch($sLinkClass);
     foreach ($aSet as $aLinkObj) {
         $oLink = MetaModel::NewObject($sLinkClass);
         foreach ($aLinkObj as $sAttCode => $value) {
             $oAttDef = MetaModel::GetAttributeDef($sLinkClass, $sAttCode);
             if ($oAttDef->IsExternalKey() && $value != '' && $value > 0) {
                 // For external keys: load the target object so that external fields
                 // get filled too
                 $oTargetObj = MetaModel::GetObject($oAttDef->GetTargetClass(), $value);
                 $oLink->Set($sAttCode, $oTargetObj);
             }
             $oLink->Set($sAttCode, $value);
         }
         $oLink->Set($sExtKeyToMe, $oMe->GetKey());
         $oSet->AddObject($oLink);
     }
     return $oSet;
 }
 protected function DisplaySearchField($sClass, $sAttSpec, $aExtraParams, $sPrefix, $sFieldName = null, $aFilterParams = array())
 {
     if (is_null($sFieldName)) {
         $sFieldName = str_replace('->', PARAM_ARROW_SEP, $sAttSpec);
     }
     $iPos = strpos($sAttSpec, '->');
     if ($iPos !== false) {
         $sAttCode = substr($sAttSpec, 0, $iPos);
         $sSubSpec = substr($sAttSpec, $iPos + 2);
         if (!MetaModel::IsValidAttCode($sClass, $sAttCode)) {
             throw new Exception("Invalid attribute code '{$sClass}/{$sAttCode}' in search specification '{$sAttSpec}'");
         }
         $oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode);
         if ($oAttDef->IsLinkSet()) {
             $sTargetClass = $oAttDef->GetLinkedClass();
         } elseif ($oAttDef->IsExternalKey(EXTKEY_ABSOLUTE)) {
             $sTargetClass = $oAttDef->GetTargetClass(EXTKEY_ABSOLUTE);
         } else {
             throw new Exception("Attribute specification '{$sAttSpec}', '{$sAttCode}' should be either a link set or an external key");
         }
         $this->DisplaySearchField($sTargetClass, $sSubSpec, $aExtraParams, $sPrefix, $sFieldName, $aFilterParams);
     } else {
         // $sAttSpec is an attribute code
         //
         $this->add('<span style="white-space: nowrap;padding:5px;display:inline-block;">');
         $sFilterValue = '';
         $sFilterValue = utils::ReadParam($sPrefix . $sFieldName, '', false, 'raw_data');
         $sFilterOpCode = null;
         // Use the default 'loose' OpCode
         $oAttDef = MetaModel::GetAttributeDef($sClass, $sAttSpec);
         if ($oAttDef->IsExternalKey()) {
             $sTargetClass = $oAttDef->GetTargetClass();
             $sFilterDefName = 'PORTAL_TICKETS_SEARCH_FILTER_' . $sAttSpec;
             if (defined($sFilterDefName)) {
                 try {
                     $oFitlerWithParams = DBObjectSearch::FromOQL(constant($sFilterDefName));
                     $sFilterOQL = $oFitlerWithParams->ToOQL(true, $aFilterParams);
                     $oAllowedValues = new DBObjectSet(DBObjectSearch::FromOQL($sFilterOQL), array(), $aFilterParams);
                 } catch (OQLException $e) {
                     throw new Exception("Incorrect filter '{$sFilterDefName}' for attribute '{$sAttcode}': " . $e->getMessage());
                 }
             } else {
                 $oAllowedValues = new DBObjectSet(new DBObjectSearch($sTargetClass));
             }
             $iFieldSize = $oAttDef->GetMaxSize();
             $iMaxComboLength = $oAttDef->GetMaximumComboLength();
             $this->add("<label>" . MetaModel::GetFilterLabel($sClass, $sAttSpec) . ":</label>&nbsp;");
             //$oWidget = UIExtKeyWidget::DIsplayFromAttCode($sAttSpec, $sClass, $oAttDef->GetLabel(), $oAllowedValues, $sFilterValue, $sPrefix.$sFieldName, false, '', $sPrefix, '');
             //$this->add($oWidget->Display($this, $aExtraParams, true /* bSearchMode */));
             $aExtKeyParams = $aExtraParams;
             $aExtKeyParams['iFieldSize'] = $oAttDef->GetMaxSize();
             $aExtKeyParams['iMinChars'] = $oAttDef->GetMinAutoCompleteChars();
             //	                      DisplayFromAttCode($this, $sAttCode, $sClass, $sTitle,              $oAllowedValues, $value,        $iInputId,            $bMandatory, $sFieldName = '', $sFormPrefix = '', $aArgs, $bSearchMode = false)
             $sHtml = UIExtKeyWidget::DisplayFromAttCode($this, $sAttSpec, $sClass, $oAttDef->GetLabel(), $oAllowedValues, $sFilterValue, $sPrefix . $sFieldName, false, $sPrefix . $sFieldName, $sPrefix, $aExtKeyParams, true);
             $this->add($sHtml);
         } else {
             $aAllowedValues = MetaModel::GetAllowedValues_flt($sClass, $sAttSpec, $aExtraParams);
             if (is_null($aAllowedValues)) {
                 // Any value is possible, display an input box
                 $sSanitizedValue = htmlentities($sFilterValue, ENT_QUOTES, 'UTF-8');
                 $this->add("<label>" . MetaModel::GetFilterLabel($sClass, $sAttSpec) . ":</label>&nbsp;<input class=\"textSearch\" name=\"{$sPrefix}{$sFieldName}\" value=\"{$sSanitizedValue}\"/>\n");
             } else {
                 //Enum field or external key, display a combo
                 $sValue = "<select name=\"{$sPrefix}{$sFieldName}\">\n";
                 $sValue .= "<option value=\"\">" . Dict::S('UI:SearchValue:Any') . "</option>\n";
                 foreach ($aAllowedValues as $key => $value) {
                     if ($sFilterValue == $key) {
                         $sSelected = ' selected';
                     } else {
                         $sSelected = '';
                     }
                     $sValue .= "<option value=\"{$key}\"{$sSelected}>{$value}</option>\n";
                 }
                 $sValue .= "</select>\n";
                 $this->add("<label>" . MetaModel::GetFilterLabel($sClass, $sAttSpec) . ":</label>&nbsp;{$sValue}\n");
             }
         }
         unset($aExtraParams[$sFieldName]);
         $this->add('</span> ');
         $sTip = $oAttDef->GetHelpOnSmartSearch();
         if (strlen($sTip) > 0) {
             $sTip = addslashes($sTip);
             $sTip = str_replace(array("\n", "\r"), " ", $sTip);
             // :input does represent in form visible input (INPUT, SELECT, TEXTAREA)
             $this->add_ready_script("\$(':input[name={$sPrefix}{$sFieldName}]').qtip( { content: '{$sTip}', show: 'mouseover', hide: 'mouseout', style: { name: 'dark', tip: 'leftTop' }, position: { corner: { target: 'rightMiddle', tooltip: 'leftTop' }} } );");
         }
     }
 }
Exemplo n.º 11
0
 /**
  * Helper to link objects
  *
  * @param string sLinkAttCode
  * @param string sLinkedClass
  * @param array $aLinkList
  * @param DBObject oTargetObj
  * @param WebServiceResult oRes
  *
  * @return array List of objects that could not be found
  */
 protected function AddLinkedObjects($sLinkAttCode, $sParamName, $sLinkedClass, $aLinkList, &$oTargetObj, &$oRes)
 {
     $oLinkAtt = MetaModel::GetAttributeDef(get_class($oTargetObj), $sLinkAttCode);
     $sLinkClass = $oLinkAtt->GetLinkedClass();
     $sExtKeyToItem = $oLinkAtt->GetExtKeyToRemote();
     $aItemsFound = array();
     $aItemsNotFound = array();
     if (is_null($aLinkList)) {
         return $aItemsNotFound;
     }
     foreach ($aLinkList as $aItemData) {
         if (!array_key_exists('class', $aItemData)) {
             $oRes->LogWarning("Parameter {$sParamName}: missing 'class' specification");
             continue;
             // skip
         }
         $sTargetClass = $aItemData['class'];
         if (!MetaModel::IsValidClass($sTargetClass)) {
             $oRes->LogError("Parameter {$sParamName}: invalid class '{$sTargetClass}'");
             continue;
             // skip
         }
         if (!MetaModel::IsParentClass($sLinkedClass, $sTargetClass)) {
             $oRes->LogError("Parameter {$sParamName}: '{$sTargetClass}' is not a child class of '{$sLinkedClass}'");
             continue;
             // skip
         }
         $oReconFilter = new CMDBSearchFilter($sTargetClass);
         $aCIStringDesc = array();
         foreach ($aItemData['search'] as $sAttCode => $value) {
             if (!MetaModel::IsValidFilterCode($sTargetClass, $sAttCode)) {
                 $aCodes = array_keys(MetaModel::GetClassFilterDefs($sTargetClass));
                 $oRes->LogError("Parameter {$sParamName}: '{$sAttCode}' is not a valid filter code for class '{$sTargetClass}', expecting a value in {" . implode(', ', $aCodes) . "}");
                 continue 2;
                 // skip the entire item
             }
             $aCIStringDesc[] = "{$sAttCode}: {$value}";
             // The attribute is one of our reconciliation key
             $oReconFilter->AddCondition($sAttCode, $value, '=');
         }
         if (count($aCIStringDesc) == 1) {
             // take the last and unique value to describe the object
             $sItemDesc = $value;
         } else {
             // describe the object by the given keys
             $sItemDesc = $sTargetClass . '(' . implode('/', $aCIStringDesc) . ')';
         }
         $oExtObjects = new CMDBObjectSet($oReconFilter);
         switch ($oExtObjects->Count()) {
             case 0:
                 $oRes->LogWarning("Parameter {$sParamName}: object to link {$sLinkedClass} / {$sItemDesc} could not be found (searched: '" . $oReconFilter->ToOQL(true) . "')");
                 $aItemsNotFound[] = $sItemDesc;
                 break;
             case 1:
                 $aItemsFound[] = array('object' => $oExtObjects->Fetch(), 'link_values' => @$aItemData['link_values'], 'desc' => $sItemDesc);
                 break;
             default:
                 $oRes->LogWarning("Parameter {$sParamName}: Found " . $oExtObjects->Count() . " matches for item '{$sItemDesc}' (searched: '" . $oReconFilter->ToOQL(true) . "')");
                 $aItemsNotFound[] = $sItemDesc;
         }
     }
     if (count($aItemsFound) > 0) {
         $aLinks = array();
         foreach ($aItemsFound as $aItemData) {
             $oLink = MetaModel::NewObject($sLinkClass);
             $oLink->Set($sExtKeyToItem, $aItemData['object']->GetKey());
             foreach ($aItemData['link_values'] as $sKey => $value) {
                 if (!MetaModel::IsValidAttCode($sLinkClass, $sKey)) {
                     $oRes->LogWarning("Parameter {$sParamName}: Attaching item '" . $aItemData['desc'] . "', the attribute code '{$sKey}' is not valid ; check the class '{$sLinkClass}'");
                 } else {
                     $oLink->Set($sKey, $value);
                 }
             }
             $aLinks[] = $oLink;
         }
         $oImpactedInfraSet = DBObjectSet::FromArray($sLinkClass, $aLinks);
         $oTargetObj->Set($sLinkAttCode, $oImpactedInfraSet);
     }
     return $aItemsNotFound;
 }
Exemplo n.º 12
0
         if ($oObj->IsNew()) {
             $iFlags = $oObj->GetInitialStateAttributeFlags($sAttCode);
         } else {
             $iFlags = $oObj->GetAttributeFlags($sAttCode);
         }
         if ($iFlags & OPT_ATT_READONLY) {
             $sHTMLValue = "<span id=\"field_{$sId}\">" . $oObj->GetAsHTML($sAttCode);
             $sHTMLValue .= '<input type="hidden" id="' . $sId . '" name="attr_' . $sFormPrefix . $sAttCode . '" value="' . htmlentities($oObj->Get($sAttCode), ENT_QUOTES, 'UTF-8') . '"/></span>';
             $oWizardHelper->SetAllowedValuesHtml($sAttCode, $sHTMLValue);
         } else {
             // It may happen that the field we'd like to update does not
             // exist in the form. For example, if the field should be hidden/read-only
             // in the current state of the object
             $value = $oObj->Get($sAttCode);
             $displayValue = $oObj->GetEditValue($sAttCode);
             $oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode);
             if (!$oAttDef->IsWritable()) {
                 // Even non-writable fields (like AttributeExternal) can be refreshed
                 $sHTMLValue = $oObj->GetAsHTML($sAttCode);
             } else {
                 $iFlags = MetaModel::GetAttributeFlags($sClass, $oObj->GetState(), $sAttCode);
                 $sHTMLValue = cmdbAbstractObject::GetFormElementForField($oPage, $sClass, $sAttCode, $oAttDef, $value, $displayValue, $sId, '', $iFlags, array('this' => $oObj, 'formPrefix' => $sFormPrefix));
                 // Make sure that we immediately validate the field when we reload it
                 $oPage->add_ready_script("\$('#{$sId}').trigger('validate');");
             }
             $oWizardHelper->SetAllowedValuesHtml($sAttCode, $sHTMLValue);
         }
     }
 }
 $oPage->add_script("oWizardHelper{$sFormPrefix}.m_oData=" . $oWizardHelper->ToJSON() . ";\noWizardHelper{$sFormPrefix}.UpdateFields();\n");
 break;
 function DisplayBareRelations(WebPage $oPage, $bEditMode = false)
 {
     parent::DisplayBareRelations($oPage, $bEditMode);
     $sTicketListAttCode = 'tickets_list';
     if (MetaModel::IsValidAttCode(get_class($this), $sTicketListAttCode)) {
         // Display one list per leaf class (the only way to display the status as of now)
         $oAttDef = MetaModel::GetAttributeDef(get_class($this), $sTicketListAttCode);
         $sLnkClass = $oAttDef->GetLinkedClass();
         $sExtKeyToMe = $oAttDef->GetExtKeyToMe();
         $sExtKeyToRemote = $oAttDef->GetExtKeyToRemote();
         $iTotal = 0;
         $aSearches = array();
         foreach (MetaModel::EnumChildClasses('Ticket') as $sSubClass) {
             if (!MetaModel::HasChildrenClasses($sSubClass)) {
                 $sStateAttCode = MetaModel::GetStateAttributeCode($sSubClass);
                 if ($sStateAttCode != '') {
                     $oSearch = DBSearch::FromOQL("SELECT {$sSubClass} AS t JOIN {$sLnkClass} AS lnk ON lnk.{$sExtKeyToRemote} = t.id WHERE {$sExtKeyToMe} = :myself AND {$sStateAttCode} NOT IN ('rejected', 'resolved', 'closed')", array('myself' => $this->GetKey()));
                     $aSearches[$sSubClass] = $oSearch;
                     $oSet = new DBObjectSet($oSearch);
                     $iTotal += $oSet->Count();
                 }
             }
         }
         $sCount = $iTotal > 0 ? ' (' . $iTotal . ')' : '';
         $oPage->SetCurrentTab(Dict::S('Class:FunctionalCI/Tab:OpenedTickets') . $sCount);
         foreach ($aSearches as $sSubClass => $oSearch) {
             $sBlockId = __CLASS__ . '_opened_' . $sSubClass;
             $oPage->add('<fieldset>');
             $oPage->add('<legend>' . MetaModel::GetName($sSubClass) . '</legend>');
             $oBlock = new DisplayBlock($oSearch, 'list', false);
             $oBlock->Display($oPage, $sBlockId, array('menu' => false));
             $oPage->add('</fieldset>');
         }
     }
 }
 public function GetDescription($sDefault = null)
 {
     $sLabel = parent::GetDescription('');
     if (strlen($sLabel) == 0) {
         $sKeyAttCode = $this->Get("extkey_attcode");
         if ($sKeyAttCode == 'id') {
             return Dict::S('Core:FriendlyName-Description');
         } else {
             $oExtKeyAttDef = MetaModel::GetAttributeDef($this->GetHostClass(), $sKeyAttCode);
             $sLabel = $oExtKeyAttDef->GetDescription('');
         }
     }
     return $sLabel;
 }
 public function CheckProjectionSpec($oProjectionSpec, $sProjectedClass)
 {
     $sExpression = $oProjectionSpec->Get('value');
     $sAttribute = $oProjectionSpec->Get('attribute');
     // Shortcut: "any value" or "no value" means no projection
     if (empty($sExpression)) {
         return;
     }
     if ($sExpression == '<any>') {
         return;
     }
     // 1st - compute the data type for the dimension
     //
     $sType = $this->Get('type');
     if (MetaModel::IsValidClass($sType)) {
         $sExpectedType = $sType;
     } else {
         $sExpectedType = '_scalar_';
     }
     // 2nd - compute the data type for the projection
     //
     $sTargetClass = '';
     if ($sExpression == '<this>' || $sExpression == '<user>') {
         $sTargetClass = $sProjectedClass;
     } elseif ($sExpression == '<any>') {
         $sTargetClass = '';
     } else {
         // Evaluate wether it is a constant or not
         try {
             $oObjectSearch = DBObjectSearch::FromOQL_AllData($sExpression);
             $sTargetClass = $oObjectSearch->GetClass();
         } catch (OqlException $e) {
         }
     }
     if (empty($sTargetClass)) {
         $sFoundType = '_void_';
     } else {
         if (empty($sAttribute)) {
             $sFoundType = $sTargetClass;
         } else {
             if (!MetaModel::IsValidAttCode($sTargetClass, $sAttribute)) {
                 throw new CoreException('Unkown attribute code in projection specification', array('found' => $sAttribute, 'expecting' => MetaModel::GetAttributesList($sTargetClass), 'class' => $sTargetClass, 'projection' => $oProjectionSpec));
             }
             $oAttDef = MetaModel::GetAttributeDef($sTargetClass, $sAttribute);
             if ($oAttDef->IsExternalKey()) {
                 $sFoundType = $oAttDef->GetTargetClass();
             } else {
                 $sFoundType = '_scalar_';
             }
         }
     }
     // Compare the dimension type and projection type
     if ($sFoundType != '_void_' && $sFoundType != $sExpectedType) {
         throw new CoreException('Wrong type in projection specification', array('found' => $sFoundType, 'expecting' => $sExpectedType, 'expression' => $sExpression, 'attribute' => $sAttribute, 'projection' => $oProjectionSpec));
     }
 }
Exemplo n.º 16
0
/**
 * Create form to apply a stimulus
 * @param WebPage $oP The current web page
 * @param Object $oObj The target object
 * @param String $sStimulusCode Stimulus that will be applied
 * @param Array $aEditAtt List of attributes to edit
 * @return void
 */
function MakeStimulusForm(WebPage $oP, $oObj, $sStimulusCode, $aEditAtt)
{
    static $bHasStimulusForm = false;
    $sDialogId = $sStimulusCode . "_dialog";
    $sFormId = $sStimulusCode . "_form";
    $sCancelButtonLabel = Dict::S('UI:Button:Cancel');
    $oP->add('<div id="' . $sDialogId . '" style="display: none;">');
    $sClass = get_class($oObj);
    $oP->add('<form id="' . $sFormId . '" method="post">');
    $sTransactionId = utils::GetNewTransactionId();
    $oP->add("<input type=\"hidden\" id=\"transaction_id\" name=\"transaction_id\" value=\"{$sTransactionId}\">\n");
    $oP->add("<input type=\"hidden\" name=\"class\" value=\"{$sClass}\">");
    $oP->add("<input type=\"hidden\" name=\"id\" value=\"" . $oObj->GetKey() . "\">");
    $oP->add("<input type=\"hidden\" name=\"operation\" value=\"update_request\">");
    $oP->add("<input type=\"hidden\" id=\"stimulus_to_apply\" name=\"apply_stimulus\" value=\"{$sStimulusCode}\">\n");
    foreach ($aEditAtt as $sAttCode) {
        $sValue = $oObj->Get($sAttCode);
        $sDisplayValue = $oObj->GetEditValue($sAttCode);
        $aArgs = array('this' => $oObj, 'formPrefix' => '');
        $oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode);
        $sInputId = 'input_' . $sAttCode;
        $sHTMLValue = "<span id=\"field_{$sStimulusCode}_{$sInputId}\">" . cmdbAbstractObject::GetFormElementForField($oP, $sClass, $sAttCode, $oAttDef, $sValue, $sDisplayValue, $sInputId, '', 0, $aArgs) . '</span>';
        $oP->add('<h1>' . MetaModel::GetLabel($sClass, $sAttCode) . '</h1>');
        $oP->add($sHTMLValue);
    }
    $oP->add('</form>');
    $oP->add('</div>');
    if (!$bHasStimulusForm) {
        $bHasStimulusForm = true;
        $oP->add_script(<<<EOF

function RunStimulusDialog(sStimulusCode, sTitle, sOkButtonLabel)
{
\tvar sWidth = 'auto';
\tif (sStimulusCode == 'ev_reopen')
\t{
\t\t// Avoid having a dialog spanning the complete width of the window
\t\t// just because it contains a CaseLog entry
\t\tsWidth = '80%';
\t}
\t\t\t\t
\t\$('#'+sStimulusCode+'_dialog').dialog({
\t\theight: 'auto',
\t\twidth: sWidth,
\t\tmodal: true,
\t\ttitle: sTitle,
\t\tbuttons: [
\t\t{ text: sOkButtonLabel, click: function() {
\t\t\t\$(this).find('#'+sStimulusCode+'_form').submit();
\t\t} },
\t\t{ text: "{$sCancelButtonLabel}", click: function() {
\t\t\t\$(this).dialog( "close" );
\t\t} }
\t\t]
\t});
\t// Start the validation
\tCheckFields(sStimulusCode+'_form', false);
\t\$('#'+sStimulusCode+'_form').submit( function() {
\t\treturn OnSubmit(sStimulusCode+'_form');
\t});
}
EOF
);
    }
}
 /**
  * Interpret the Rest/Json value and get a valid attribute value
  * 	 
  * @param string $sClass Name of the class
  * @param string $sAttCode Attribute code
  * @param mixed $value Depending on the type of attribute (a scalar, or search criteria, or list of related objects...)
  * @return mixed The value that can be used with DBObject::Set()
  * @throws Exception If the specification of the value is not valid.
  * @api
  */
 public static function MakeValue($sClass, $sAttCode, $value)
 {
     try {
         if (!MetaModel::IsValidAttCode($sClass, $sAttCode)) {
             throw new Exception("Unknown attribute");
         }
         $oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode);
         if ($oAttDef instanceof AttributeExternalKey) {
             $oExtKeyObject = static::FindObjectFromKey($oAttDef->GetTargetClass(), $value, true);
             $value = $oExtKeyObject != null ? $oExtKeyObject->GetKey() : 0;
         } elseif ($oAttDef instanceof AttributeLinkedSet) {
             if (!is_array($value)) {
                 throw new Exception("A link set must be defined by an array of objects");
             }
             $sLnkClass = $oAttDef->GetLinkedClass();
             $aLinks = array();
             foreach ($value as $oValues) {
                 $oLnk = static::MakeObjectFromFields($sLnkClass, $oValues);
                 $aLinks[] = $oLnk;
             }
             $value = DBObjectSet::FromArray($sLnkClass, $aLinks);
         } else {
             $value = $oAttDef->FromJSONToValue($value);
         }
     } catch (Exception $e) {
         throw new Exception("{$sAttCode}: " . $e->getMessage(), $e->getCode());
     }
     return $value;
 }
Exemplo n.º 18
0
 public static function FromLinkSet($oObject, $sLinkSetAttCode, $sExtKeyToRemote)
 {
     $oLinkAttCode = MetaModel::GetAttributeDef(get_class($oObject), $sLinkSetAttCode);
     $oExtKeyAttDef = MetaModel::GetAttributeDef($oLinkAttCode->GetLinkedClass(), $sExtKeyToRemote);
     $sTargetClass = $oExtKeyAttDef->GetTargetClass();
     $oLinkSet = $oObject->Get($sLinkSetAttCode);
     $aTargets = array();
     while ($oLink = $oLinkSet->Fetch()) {
         $aTargets[] = MetaModel::GetObject($sTargetClass, $oLink->Get($sExtKeyToRemote));
     }
     return self::FromArray($sTargetClass, $aTargets);
 }
Exemplo n.º 19
0
 protected function MakeSQLObjectQuerySingleTable(&$oBuild, $aAttToLoad, $sTableClass, $aExtKeys, $aValues)
 {
     // $aExtKeys is an array of sTableClass => array of (sAttCode (keys) => array of sAttCode (fields))
     //echo "MakeSQLObjectQuery($sTableClass)-liste des clefs externes($sTableClass): <pre>".print_r($aExtKeys, true)."</pre><br/>\n";
     // Prepare the query for a single table (compound objects)
     // Ignores the items (attributes/filters) that are not on the target table
     // Perform an (inner or left) join for every external key (and specify the expected fields)
     //
     // Returns an SQLQuery
     //
     $sTargetClass = $this->GetFirstJoinedClass();
     $sTargetAlias = $this->GetFirstJoinedClassAlias();
     $sTable = MetaModel::DBGetTable($sTableClass);
     $sTableAlias = $oBuild->GenerateTableAlias($sTargetAlias . '_' . $sTable, $sTable);
     $aTranslation = array();
     $aExpectedAtts = array();
     $oBuild->m_oQBExpressions->GetUnresolvedFields($sTargetAlias, $aExpectedAtts);
     $bIsOnQueriedClass = array_key_exists($sTargetAlias, $oBuild->GetRootFilter()->GetSelectedClasses());
     self::DbgTrace("Entering: tableclass={$sTableClass}, filter=" . $this->ToOQL() . ", " . ($bIsOnQueriedClass ? "MAIN" : "SECONDARY"));
     // 1 - SELECT and UPDATE
     //
     // Note: no need for any values nor fields for foreign Classes (ie not the queried Class)
     //
     $aUpdateValues = array();
     // 1/a - Get the key and friendly name
     //
     // We need one pkey to be the key, let's take the first one available
     $oSelectedIdField = null;
     $oIdField = new FieldExpressionResolved(MetaModel::DBGetKey($sTableClass), $sTableAlias);
     $aTranslation[$sTargetAlias]['id'] = $oIdField;
     if ($bIsOnQueriedClass) {
         // Add this field to the list of queried fields (required for the COUNT to work fine)
         $oSelectedIdField = $oIdField;
     }
     // 1/b - Get the other attributes
     //
     foreach (MetaModel::ListAttributeDefs($sTableClass) as $sAttCode => $oAttDef) {
         // Skip this attribute if not defined in this table
         if (MetaModel::GetAttributeOrigin($sTargetClass, $sAttCode) != $sTableClass) {
             continue;
         }
         // Skip this attribute if not made of SQL columns
         if (count($oAttDef->GetSQLExpressions()) == 0) {
             continue;
         }
         // Update...
         //
         if ($bIsOnQueriedClass && array_key_exists($sAttCode, $aValues)) {
             assert($oAttDef->IsDirectField());
             foreach ($oAttDef->GetSQLValues($aValues[$sAttCode]) as $sColumn => $sValue) {
                 $aUpdateValues[$sColumn] = $sValue;
             }
         }
     }
     // 2 - The SQL query, for this table only
     //
     $oSelectBase = new SQLObjectQuery($sTable, $sTableAlias, array(), $bIsOnQueriedClass, $aUpdateValues, $oSelectedIdField);
     // 3 - Resolve expected expressions (translation table: alias.attcode => table.column)
     //
     foreach (MetaModel::ListAttributeDefs($sTableClass) as $sAttCode => $oAttDef) {
         // Skip this attribute if not defined in this table
         if (MetaModel::GetAttributeOrigin($sTargetClass, $sAttCode) != $sTableClass) {
             continue;
         }
         // Select...
         //
         if ($oAttDef->IsExternalField()) {
             // skip, this will be handled in the joined tables (done hereabove)
         } else {
             //echo "<p>MakeSQLObjectQuerySingleTable: Field $sAttCode is part of the table $sTable (named: $sTableAlias)</p>";
             // standard field, or external key
             // add it to the output
             foreach ($oAttDef->GetSQLExpressions() as $sColId => $sSQLExpr) {
                 if (array_key_exists($sAttCode . $sColId, $aExpectedAtts)) {
                     $oFieldSQLExp = new FieldExpressionResolved($sSQLExpr, $sTableAlias);
                     foreach (MetaModel::EnumPlugins('iQueryModifier') as $sPluginClass => $oQueryModifier) {
                         $oFieldSQLExp = $oQueryModifier->GetFieldExpression($oBuild, $sTargetClass, $sAttCode, $sColId, $oFieldSQLExp, $oSelectBase);
                     }
                     $aTranslation[$sTargetAlias][$sAttCode . $sColId] = $oFieldSQLExp;
                 }
             }
         }
     }
     //echo "MakeSQLObjectQuery- Classe $sTableClass<br/>\n";
     // 4 - The external keys -> joins...
     //
     $aAllPointingTo = $this->GetCriteria_PointingTo();
     if (array_key_exists($sTableClass, $aExtKeys)) {
         foreach ($aExtKeys[$sTableClass] as $sKeyAttCode => $aExtFields) {
             $oKeyAttDef = MetaModel::GetAttributeDef($sTableClass, $sKeyAttCode);
             $aPointingTo = $this->GetCriteria_PointingTo($sKeyAttCode);
             //echo "MakeSQLObjectQuery-Cle '$sKeyAttCode'<br/>\n";
             if (!array_key_exists(TREE_OPERATOR_EQUALS, $aPointingTo)) {
                 //echo "MakeSQLObjectQuery-Ajoutons l'operateur TREE_OPERATOR_EQUALS pour $sKeyAttCode<br/>\n";
                 // The join was not explicitely defined in the filter,
                 // we need to do it now
                 $sKeyClass = $oKeyAttDef->GetTargetClass();
                 $sKeyClassAlias = $oBuild->GenerateClassAlias($sKeyClass . '_' . $sKeyAttCode, $sKeyClass);
                 $oExtFilter = new DBObjectSearch($sKeyClass, $sKeyClassAlias);
                 $aAllPointingTo[$sKeyAttCode][TREE_OPERATOR_EQUALS][$sKeyClassAlias] = $oExtFilter;
             }
         }
     }
     //echo "MakeSQLObjectQuery-liste des clefs de jointure: <pre>".print_r(array_keys($aAllPointingTo), true)."</pre><br/>\n";
     foreach ($aAllPointingTo as $sKeyAttCode => $aPointingTo) {
         foreach ($aPointingTo as $iOperatorCode => $aFilter) {
             foreach ($aFilter as $oExtFilter) {
                 if (!MetaModel::IsValidAttCode($sTableClass, $sKeyAttCode)) {
                     continue;
                 }
                 // Not defined in the class, skip it
                 // The aliases should not conflict because normalization occured while building the filter
                 $oKeyAttDef = MetaModel::GetAttributeDef($sTableClass, $sKeyAttCode);
                 $sKeyClass = $oExtFilter->GetFirstJoinedClass();
                 $sKeyClassAlias = $oExtFilter->GetFirstJoinedClassAlias();
                 //echo "MakeSQLObjectQuery-$sTableClass::$sKeyAttCode Foreach PointingTo($iOperatorCode) <span style=\"color:red\">$sKeyClass (alias:$sKeyClassAlias)</span><br/>\n";
                 // Note: there is no search condition in $oExtFilter, because normalization did merge the condition onto the top of the filter tree
                 //echo "MakeSQLObjectQuery-array_key_exists($sTableClass, \$aExtKeys)<br/>\n";
                 if ($iOperatorCode == TREE_OPERATOR_EQUALS) {
                     if (array_key_exists($sTableClass, $aExtKeys) && array_key_exists($sKeyAttCode, $aExtKeys[$sTableClass])) {
                         // Specify expected attributes for the target class query
                         // ... and use the current alias !
                         $aTranslateNow = array();
                         // Translation for external fields - must be performed before the join is done (recursion...)
                         foreach ($aExtKeys[$sTableClass][$sKeyAttCode] as $sAttCode => $oAtt) {
                             //echo "MakeSQLObjectQuery aExtKeys[$sTableClass][$sKeyAttCode] => $sAttCode-oAtt: <pre>".print_r($oAtt, true)."</pre><br/>\n";
                             if ($oAtt instanceof AttributeFriendlyName) {
                                 // Note: for a given ext key, there is one single attribute "friendly name"
                                 $aTranslateNow[$sTargetAlias][$sAttCode] = new FieldExpression('friendlyname', $sKeyClassAlias);
                                 //echo "<p><b>aTranslateNow[$sTargetAlias][$sAttCode] = new FieldExpression('friendlyname', $sKeyClassAlias);</b></p>\n";
                             } else {
                                 $sExtAttCode = $oAtt->GetExtAttCode();
                                 // Translate mainclass.extfield => remoteclassalias.remotefieldcode
                                 $oRemoteAttDef = MetaModel::GetAttributeDef($sKeyClass, $sExtAttCode);
                                 foreach ($oRemoteAttDef->GetSQLExpressions() as $sColId => $sRemoteAttExpr) {
                                     $aTranslateNow[$sTargetAlias][$sAttCode . $sColId] = new FieldExpression($sExtAttCode, $sKeyClassAlias);
                                     //echo "<p><b>aTranslateNow[$sTargetAlias][$sAttCode.$sColId] = new FieldExpression($sExtAttCode, $sKeyClassAlias);</b></p>\n";
                                 }
                                 //echo "<p><b>ExtAttr2: $sTargetAlias.$sAttCode to $sKeyClassAlias.$sRemoteAttExpr (class: $sKeyClass)</b></p>\n";
                             }
                         }
                         if ($oKeyAttDef instanceof AttributeObjectKey) {
                             // Add the condition: `$sTargetAlias`.$sClassAttCode IN (subclasses of $sKeyClass')
                             $sClassAttCode = $oKeyAttDef->Get('class_attcode');
                             $oClassAttDef = MetaModel::GetAttributeDef($sTargetClass, $sClassAttCode);
                             foreach ($oClassAttDef->GetSQLExpressions() as $sColId => $sSQLExpr) {
                                 $aTranslateNow[$sTargetAlias][$sClassAttCode . $sColId] = new FieldExpressionResolved($sSQLExpr, $sTableAlias);
                             }
                             $oClassListExpr = ListExpression::FromScalars(MetaModel::EnumChildClasses($sKeyClass, ENUM_CHILD_CLASSES_ALL));
                             $oClassExpr = new FieldExpression($sClassAttCode, $sTargetAlias);
                             $oClassRestriction = new BinaryExpression($oClassExpr, 'IN', $oClassListExpr);
                             $oBuild->m_oQBExpressions->AddCondition($oClassRestriction);
                         }
                         // Translate prior to recursing
                         //
                         //echo "<p>oQBExpr ".__LINE__.": <pre>\n".print_r($oBuild->m_oQBExpressions, true)."\n".print_r($aTranslateNow, true)."</pre></p>\n";
                         $oBuild->m_oQBExpressions->Translate($aTranslateNow, false);
                         //echo "<p>oQBExpr ".__LINE__.": <pre>\n".print_r($oBuild->m_oQBExpressions, true)."</pre></p>\n";
                         //echo "<p>External key $sKeyAttCode (class: $sKeyClass), call MakeSQLObjectQuery()/p>\n";
                         self::DbgTrace("External key {$sKeyAttCode} (class: {$sKeyClass}), call MakeSQLObjectQuery()");
                         $oBuild->m_oQBExpressions->PushJoinField(new FieldExpression('id', $sKeyClassAlias));
                         //echo "<p>Recursive MakeSQLObjectQuery ".__LINE__.": <pre>\n".print_r($oBuild->GetRootFilter()->GetSelectedClasses(), true)."</pre></p>\n";
                         $oSelectExtKey = $oExtFilter->MakeSQLObjectQuery($oBuild, $aAttToLoad);
                         $oJoinExpr = $oBuild->m_oQBExpressions->PopJoinField();
                         $sExternalKeyTable = $oJoinExpr->GetParent();
                         $sExternalKeyField = $oJoinExpr->GetName();
                         $aCols = $oKeyAttDef->GetSQLExpressions();
                         // Workaround a PHP bug: sometimes issuing a Notice if invoking current(somefunc())
                         $sLocalKeyField = current($aCols);
                         // get the first column for an external key
                         self::DbgTrace("External key {$sKeyAttCode}, Join on {$sLocalKeyField} = {$sExternalKeyField}");
                         if ($oKeyAttDef->IsNullAllowed()) {
                             $oSelectBase->AddLeftJoin($oSelectExtKey, $sLocalKeyField, $sExternalKeyField, $sExternalKeyTable);
                         } else {
                             $oSelectBase->AddInnerJoin($oSelectExtKey, $sLocalKeyField, $sExternalKeyField, $sExternalKeyTable);
                         }
                     }
                 } elseif (MetaModel::GetAttributeOrigin($sKeyClass, $sKeyAttCode) == $sTableClass) {
                     $oBuild->m_oQBExpressions->PushJoinField(new FieldExpression($sKeyAttCode, $sKeyClassAlias));
                     $oSelectExtKey = $oExtFilter->MakeSQLObjectQuery($oBuild, $aAttToLoad);
                     $oJoinExpr = $oBuild->m_oQBExpressions->PopJoinField();
                     $sExternalKeyTable = $oJoinExpr->GetParent();
                     $sExternalKeyField = $oJoinExpr->GetName();
                     $sLeftIndex = $sExternalKeyField . '_left';
                     // TODO use GetSQLLeft()
                     $sRightIndex = $sExternalKeyField . '_right';
                     // TODO use GetSQLRight()
                     $LocalKeyLeft = $oKeyAttDef->GetSQLLeft();
                     $LocalKeyRight = $oKeyAttDef->GetSQLRight();
                     $oSelectBase->AddInnerJoinTree($oSelectExtKey, $LocalKeyLeft, $LocalKeyRight, $sLeftIndex, $sRightIndex, $sExternalKeyTable, $iOperatorCode);
                 }
             }
         }
     }
     // Translate the selected columns
     //
     //echo "<p>oQBExpr ".__LINE__.": <pre>\n".print_r($oBuild->m_oQBExpressions, true)."</pre></p>\n";
     $oBuild->m_oQBExpressions->Translate($aTranslation, false);
     //echo "<p>oQBExpr ".__LINE__.": <pre>\n".print_r($oBuild->m_oQBExpressions, true)."</pre></p>\n";
     //MyHelpers::var_dump_html($oSelectBase->RenderSelect());
     return $oSelectBase;
 }
Exemplo n.º 20
0
 /**
  * Renders the "Actions" popup menu for the given set of objects
  * 
  * Note that the menu links containing (or ending) with a hash (#) will have their fragment
  * part (whatever is after the hash) dynamically replaced (by javascript) when the menu is
  * displayed, to correspond to the current hash/fragment in the page. This allows modifying
  * an object in with the same tab active by default as the tab that was active when selecting
  * the "Modify..." action.
  */
 public function GetRenderContent(WebPage $oPage, $aExtraParams = array(), $sId)
 {
     if ($this->m_sStyle == 'popup') {
         $this->m_sStyle = 'list';
     }
     $sHtml = '';
     $oAppContext = new ApplicationContext();
     $sContext = $oAppContext->GetForLink();
     if (!empty($sContext)) {
         $sContext = '&' . $sContext;
     }
     $sClass = $this->m_oFilter->GetClass();
     $oReflectionClass = new ReflectionClass($sClass);
     $oSet = new CMDBObjectSet($this->m_oFilter);
     $sFilter = $this->m_oFilter->serialize();
     $sFilterDesc = $this->m_oFilter->ToOql(true);
     $aActions = array();
     $sUIPage = cmdbAbstractObject::ComputeStandardUIPage($sClass);
     $sRootUrl = utils::GetAbsoluteUrlAppRoot();
     // 1:n links, populate the target object as a default value when creating a new linked object
     if (isset($aExtraParams['target_attr'])) {
         $aExtraParams['default'][$aExtraParams['target_attr']] = $aExtraParams['object_id'];
     }
     $sDefault = '';
     if (!empty($aExtraParams['default'])) {
         foreach ($aExtraParams['default'] as $sKey => $sValue) {
             $sDefault .= "&default[{$sKey}]={$sValue}";
         }
     }
     $bIsCreationAllowed = UserRights::IsActionAllowed($sClass, UR_ACTION_CREATE) == UR_ALLOWED_YES && $oReflectionClass->IsSubclassOf('cmdbAbstractObject');
     switch ($oSet->Count()) {
         case 0:
             // No object in the set, the only possible action is "new"
             if ($bIsCreationAllowed) {
                 $aActions['UI:Menu:New'] = array('label' => Dict::S('UI:Menu:New'), 'url' => "{$sRootUrl}pages/{$sUIPage}?operation=new&class={$sClass}{$sContext}{$sDefault}");
             }
             break;
         case 1:
             $oObj = $oSet->Fetch();
             $id = $oObj->GetKey();
             $bLocked = false;
             if (MetaModel::GetConfig()->Get('concurrent_lock_enabled')) {
                 $aLockInfo = iTopOwnershipLock::IsLocked(get_class($oObj), $id);
                 if ($aLockInfo['locked']) {
                     $bLocked = true;
                     //$this->AddMenuSeparator($aActions);
                     //$aActions['concurrent_lock_unlock'] = array ('label' => Dict::S('UI:Menu:ReleaseConcurrentLock'), 'url' => "{$sRootUrl}pages/$sUIPage?operation=kill_lock&class=$sClass&id=$id{$sContext}");
                 }
             }
             $bRawModifiedAllowed = UserRights::IsActionAllowed($sClass, UR_ACTION_MODIFY, $oSet) == UR_ALLOWED_YES && $oReflectionClass->IsSubclassOf('cmdbAbstractObject');
             $bIsModifyAllowed = !$bLocked && $bRawModifiedAllowed;
             $bIsDeleteAllowed = !$bLocked && UserRights::IsActionAllowed($sClass, UR_ACTION_DELETE, $oSet);
             // Just one object in the set, possible actions are "new / clone / modify and delete"
             if (!isset($aExtraParams['link_attr'])) {
                 if ($bIsModifyAllowed) {
                     $aActions['UI:Menu:Modify'] = array('label' => Dict::S('UI:Menu:Modify'), 'url' => "{$sRootUrl}pages/{$sUIPage}?operation=modify&class={$sClass}&id={$id}{$sContext}#");
                 }
                 if ($bIsCreationAllowed) {
                     $aActions['UI:Menu:New'] = array('label' => Dict::S('UI:Menu:New'), 'url' => "{$sRootUrl}pages/{$sUIPage}?operation=new&class={$sClass}{$sContext}{$sDefault}");
                 }
                 if ($bIsDeleteAllowed) {
                     $aActions['UI:Menu:Delete'] = array('label' => Dict::S('UI:Menu:Delete'), 'url' => "{$sRootUrl}pages/{$sUIPage}?operation=delete&class={$sClass}&id={$id}{$sContext}");
                 }
                 // Transitions / Stimuli
                 if (!$bLocked) {
                     $aTransitions = $oObj->EnumTransitions();
                     if (count($aTransitions)) {
                         $this->AddMenuSeparator($aActions);
                         $aStimuli = Metamodel::EnumStimuli(get_class($oObj));
                         foreach ($aTransitions as $sStimulusCode => $aTransitionDef) {
                             $iActionAllowed = get_class($aStimuli[$sStimulusCode]) == 'StimulusUserAction' ? UserRights::IsStimulusAllowed($sClass, $sStimulusCode, $oSet) : UR_ALLOWED_NO;
                             switch ($iActionAllowed) {
                                 case UR_ALLOWED_YES:
                                     $aActions[$sStimulusCode] = array('label' => $aStimuli[$sStimulusCode]->GetLabel(), 'url' => "{$sRootUrl}pages/UI.php?operation=stimulus&stimulus={$sStimulusCode}&class={$sClass}&id={$id}{$sContext}");
                                     break;
                                 default:
                                     // Do nothing
                             }
                         }
                     }
                 }
                 // Relations...
                 $aRelations = MetaModel::EnumRelationsEx($sClass);
                 if (count($aRelations)) {
                     $this->AddMenuSeparator($aActions);
                     foreach ($aRelations as $sRelationCode => $aRelationInfo) {
                         if (array_key_exists('down', $aRelationInfo)) {
                             $aActions[$sRelationCode . '_down'] = array('label' => $aRelationInfo['down'], 'url' => "{$sRootUrl}pages/{$sUIPage}?operation=swf_navigator&relation={$sRelationCode}&direction=down&class={$sClass}&id={$id}{$sContext}");
                         }
                         if (array_key_exists('up', $aRelationInfo)) {
                             $aActions[$sRelationCode . '_up'] = array('label' => $aRelationInfo['up'], 'url' => "{$sRootUrl}pages/{$sUIPage}?operation=swf_navigator&relation={$sRelationCode}&direction=up&class={$sClass}&id={$id}{$sContext}");
                         }
                     }
                 }
                 if ($bLocked && $bRawModifiedAllowed) {
                     // Add a special menu to kill the lock, but only to allowed users who can also modify this object
                     $aAllowedProfiles = MetaModel::GetConfig()->Get('concurrent_lock_override_profiles');
                     $bCanKill = false;
                     $oUser = UserRights::GetUserObject();
                     $aUserProfiles = array();
                     if (!is_null($oUser)) {
                         $oProfileSet = $oUser->Get('profile_list');
                         while ($oProfile = $oProfileSet->Fetch()) {
                             $aUserProfiles[$oProfile->Get('profile')] = true;
                         }
                     }
                     foreach ($aAllowedProfiles as $sProfile) {
                         if (array_key_exists($sProfile, $aUserProfiles)) {
                             $bCanKill = true;
                             break;
                         }
                     }
                     if ($bCanKill) {
                         $this->AddMenuSeparator($aActions);
                         $aActions['concurrent_lock_unlock'] = array('label' => Dict::S('UI:Menu:KillConcurrentLock'), 'url' => "{$sRootUrl}pages/{$sUIPage}?operation=kill_lock&class={$sClass}&id={$id}{$sContext}");
                     }
                 }
                 /*
                 $this->AddMenuSeparator($aActions);
                 // Static menus: Email this page & CSV Export
                 $sUrl = ApplicationContext::MakeObjectUrl($sClass, $id);
                 $aActions['UI:Menu:EMail'] = array ('label' => Dict::S('UI:Menu:EMail'), 'url' => "mailto:?subject=".urlencode($oObj->GetRawName())."&body=".urlencode($sUrl));
                 $aActions['UI:Menu:CSVExport'] = array ('label' => Dict::S('UI:Menu:CSVExport'), 'url' => "{$sRootUrl}pages/$sUIPage?operation=search&filter=".urlencode($sFilter)."&format=csv{$sContext}");
                 // The style tells us whether the menu is displayed on a list of one object, or on the details of the given object 
                 if ($this->m_sStyle == 'list')
                 {
                 	// Actions specific to the list
                 	$sOQL = addslashes($sFilterDesc);
                 	$aActions['UI:Menu:AddToDashboard'] = array ('label' => Dict::S('UI:Menu:AddToDashboard'), 'url' => "#", 'onclick' => "return DashletCreationDlg('$sOQL')");
                 }
                 */
             }
             $this->AddMenuSeparator($aActions);
             foreach (MetaModel::EnumPlugins('iApplicationUIExtension') as $oExtensionInstance) {
                 $oSet->Rewind();
                 foreach ($oExtensionInstance->EnumAllowedActions($oSet) as $sLabel => $sUrl) {
                     $aActions[$sLabel] = array('label' => $sLabel, 'url' => $sUrl);
                 }
             }
             break;
         default:
             // Check rights
             // New / Modify
             $bIsModifyAllowed = UserRights::IsActionAllowed($sClass, UR_ACTION_MODIFY, $oSet) && $oReflectionClass->IsSubclassOf('cmdbAbstractObject');
             $bIsBulkModifyAllowed = !MetaModel::IsAbstract($sClass) && UserRights::IsActionAllowed($sClass, UR_ACTION_BULK_MODIFY, $oSet) && $oReflectionClass->IsSubclassOf('cmdbAbstractObject');
             $bIsBulkDeleteAllowed = UserRights::IsActionAllowed($sClass, UR_ACTION_BULK_DELETE, $oSet);
             if (isset($aExtraParams['link_attr'])) {
                 $id = $aExtraParams['object_id'];
                 $sTargetAttr = $aExtraParams['target_attr'];
                 $oAttDef = MetaModel::GetAttributeDef($sClass, $sTargetAttr);
                 $sTargetClass = $oAttDef->GetTargetClass();
                 $bIsDeleteAllowed = UserRights::IsActionAllowed($sClass, UR_ACTION_DELETE, $oSet);
                 if ($bIsModifyAllowed) {
                     $aActions['UI:Menu:Add'] = array('label' => Dict::S('UI:Menu:Add'), 'url' => "{$sRootUrl}pages/{$sUIPage}?operation=modify_links&class={$sClass}&link_attr=" . $aExtraParams['link_attr'] . "&target_class={$sTargetClass}&id={$id}&addObjects=true{$sContext}");
                 }
                 if ($bIsBulkModifyAllowed) {
                     $aActions['UI:Menu:Manage'] = array('label' => Dict::S('UI:Menu:Manage'), 'url' => "{$sRootUrl}pages/{$sUIPage}?operation=modify_links&class={$sClass}&link_attr=" . $aExtraParams['link_attr'] . "&target_class={$sTargetClass}&id={$id}{$sContext}");
                 }
                 //if ($bIsBulkDeleteAllowed) { $aActions[] = array ('label' => 'Remove All...', 'url' => "#"); }
             } else {
                 // many objects in the set, possible actions are: new / modify all / delete all
                 if ($bIsCreationAllowed) {
                     $aActions['UI:Menu:New'] = array('label' => Dict::S('UI:Menu:New'), 'url' => "{$sRootUrl}pages/{$sUIPage}?operation=new&class={$sClass}{$sContext}{$sDefault}");
                 }
                 if ($bIsBulkModifyAllowed) {
                     $aActions['UI:Menu:ModifyAll'] = array('label' => Dict::S('UI:Menu:ModifyAll'), 'url' => "{$sRootUrl}pages/{$sUIPage}?operation=select_for_modify_all&class={$sClass}&filter=" . urlencode($sFilter) . "{$sContext}");
                 }
                 if ($bIsBulkDeleteAllowed) {
                     $aActions['UI:Menu:BulkDelete'] = array('label' => Dict::S('UI:Menu:BulkDelete'), 'url' => "{$sRootUrl}pages/{$sUIPage}?operation=select_for_deletion&filter=" . urlencode($sFilter) . "{$sContext}");
                 }
                 // Stimuli
                 $aStates = MetaModel::EnumStates($sClass);
                 // Do not perform time consuming computations if there are too may objects in the list
                 $iLimit = MetaModel::GetConfig()->Get('complex_actions_limit');
                 if (count($aStates) > 0 && ($iLimit == 0 || $oSet->Count() < $iLimit)) {
                     // Life cycle actions may be available... if all objects are in the same state
                     //
                     // Group by <state>
                     $oGroupByExp = new FieldExpression(MetaModel::GetStateAttributeCode($sClass), $this->m_oFilter->GetClassAlias());
                     $aGroupBy = array('__state__' => $oGroupByExp);
                     $aQueryParams = array();
                     if (isset($aExtraParams['query_params'])) {
                         $aQueryParams = $aExtraParams['query_params'];
                     }
                     $sSql = $this->m_oFilter->MakeGroupByQuery($aQueryParams, $aGroupBy);
                     $aRes = CMDBSource::QueryToArray($sSql);
                     if (count($aRes) == 1) {
                         // All objects are in the same state...
                         $sState = $aRes[0]['__state__'];
                         $aTransitions = Metamodel::EnumTransitions($sClass, $sState);
                         if (count($aTransitions)) {
                             $this->AddMenuSeparator($aActions);
                             $aStimuli = Metamodel::EnumStimuli($sClass);
                             foreach ($aTransitions as $sStimulusCode => $aTransitionDef) {
                                 $oSet->Rewind();
                                 // As soon as the user rights implementation will browse the object set,
                                 // then we might consider using OptimizeColumnLoad() here
                                 $iActionAllowed = UserRights::IsStimulusAllowed($sClass, $sStimulusCode, $oSet);
                                 $iActionAllowed = get_class($aStimuli[$sStimulusCode]) == 'StimulusUserAction' ? $iActionAllowed : UR_ALLOWED_NO;
                                 switch ($iActionAllowed) {
                                     case UR_ALLOWED_YES:
                                     case UR_ALLOWED_DEPENDS:
                                         $aActions[$sStimulusCode] = array('label' => $aStimuli[$sStimulusCode]->GetLabel(), 'url' => "{$sRootUrl}pages/UI.php?operation=select_bulk_stimulus&stimulus={$sStimulusCode}&state={$sState}&class={$sClass}&filter=" . urlencode($sFilter) . "{$sContext}");
                                         break;
                                     default:
                                         // Do nothing
                                 }
                             }
                         }
                     }
                 }
                 /*
                 $this->AddMenuSeparator($aActions);
                 $sUrl = utils::GetAbsoluteUrlAppRoot();
                 $aActions['UI:Menu:EMail'] = array ('label' => Dict::S('UI:Menu:EMail'), 'url' => "mailto:?subject=$sFilterDesc&body=".urlencode("{$sUrl}pages/$sUIPage?operation=search&filter=".urlencode($sFilter)."{$sContext}"));
                 $aActions['UI:Menu:CSVExport'] = array ('label' => Dict::S('UI:Menu:CSVExport'), 'url' => "{$sRootUrl}pages/$sUIPage?operation=search&filter=".urlencode($sFilter)."&format=csv{$sContext}");
                 $sOQL = addslashes($sFilterDesc);
                 $aActions['UI:Menu:AddToDashboard'] = array ('label' => Dict::S('UI:Menu:AddToDashboard'), 'url' => "#", 'onclick' => "return DashletCreationDlg('$sOQL')");
                 */
             }
     }
     $this->AddMenuSeparator($aActions);
     foreach (MetaModel::EnumPlugins('iApplicationUIExtension') as $oExtensionInstance) {
         $oSet->Rewind();
         foreach ($oExtensionInstance->EnumAllowedActions($oSet) as $sLabel => $data) {
             if (is_array($data)) {
                 // New plugins can provide javascript handlers via the 'onclick' property
                 //TODO: enable extension of different menus by checking the 'target' property ??
                 $aActions[$sLabel] = array('label' => $sLabel, 'url' => isset($data['url']) ? $data['url'] : '#', 'onclick' => isset($data['onclick']) ? $data['onclick'] : '');
             } else {
                 // Backward compatibility with old plugins
                 $aActions[$sLabel] = array('label' => $sLabel, 'url' => $data);
             }
         }
     }
     // New extensions based on iPopupMenuItem interface
     switch ($this->m_sStyle) {
         case 'list':
             $oSet->Rewind();
             $param = $oSet;
             $iMenuId = iPopupMenuExtension::MENU_OBJLIST_ACTIONS;
             break;
         case 'details':
             $oSet->Rewind();
             $param = $oSet->Fetch();
             $iMenuId = iPopupMenuExtension::MENU_OBJDETAILS_ACTIONS;
             break;
     }
     utils::GetPopupMenuItems($oPage, $iMenuId, $param, $aActions);
     $aFavoriteActions = array();
     $aCallSpec = array($sClass, 'GetShortcutActions');
     if (is_callable($aCallSpec)) {
         $aShortcutActions = call_user_func($aCallSpec, $sClass);
         foreach ($aActions as $key => $aAction) {
             if (in_array($key, $aShortcutActions)) {
                 $aFavoriteActions[] = $aAction;
                 unset($aActions[$key]);
             }
         }
     } else {
         $aShortcutActions = array();
     }
     if (count($aFavoriteActions) > 0) {
         $sHtml .= "<div class=\"itop_popup actions_menu\"><ul>\n<li>" . Dict::S('UI:Menu:OtherActions') . "\n<ul>\n";
     } else {
         $sHtml .= "<div class=\"itop_popup actions_menu\"><ul>\n<li>" . Dict::S('UI:Menu:Actions') . "\n<ul>\n";
     }
     $sHtml .= $oPage->RenderPopupMenuItems($aActions, $aFavoriteActions);
     static $bPopupScript = false;
     if (!$bPopupScript) {
         // Output this once per page...
         $oPage->add_ready_script("\$(\"div.itop_popup>ul\").popupmenu();\n");
         $bPopupScript = true;
     }
     return $sHtml;
 }
 /**
  * Describe (as a text string) the modifications corresponding to this change
  */
 public function GetDescription()
 {
     $sResult = '';
     $oTargetObjectClass = $this->Get('objclass');
     $oTargetObjectKey = $this->Get('objkey');
     $oTargetSearch = new DBObjectSearch($oTargetObjectClass);
     $oTargetSearch->AddCondition('id', $oTargetObjectKey, '=');
     $oMonoObjectSet = new DBObjectSet($oTargetSearch);
     if (UserRights::IsActionAllowedOnAttribute($this->Get('objclass'), $this->Get('attcode'), UR_ACTION_READ, $oMonoObjectSet) == UR_ALLOWED_YES) {
         if (!MetaModel::IsValidAttCode($this->Get('objclass'), $this->Get('attcode'))) {
             return '';
         }
         // Protects against renamed attributes...
         $oAttDef = MetaModel::GetAttributeDef($this->Get('objclass'), $this->Get('attcode'));
         $sAttName = $oAttDef->GetLabel();
         $sLinkClass = $oAttDef->GetLinkedClass();
         $aLinkClasses = MetaModel::EnumChildClasses($sLinkClass, ENUM_CHILD_CLASSES_ALL);
         // Search for changes on the corresponding link
         //
         $oSearch = new DBObjectSearch('CMDBChangeOpSetAttribute');
         $oSearch->AddCondition('change', $this->Get('change'), '=');
         $oSearch->AddCondition('objkey', $this->Get('link_id'), '=');
         if (count($aLinkClasses) == 1) {
             // Faster than the whole building of the expression below for just one value ??
             $oSearch->AddCondition('objclass', $sLinkClass, '=');
         } else {
             $oField = new FieldExpression('objclass', $oSearch->GetClassAlias());
             $sListExpr = '(' . implode(', ', CMDBSource::Quote($aLinkClasses)) . ')';
             $sOQLCondition = $oField->Render() . " IN {$sListExpr}";
             $oNewCondition = Expression::FromOQL($sOQLCondition);
             $oSearch->AddConditionExpression($oNewCondition);
         }
         $oSet = new DBObjectSet($oSearch);
         $aChanges = array();
         while ($oChangeOp = $oSet->Fetch()) {
             $aChanges[] = $oChangeOp->GetDescription();
         }
         if (count($aChanges) == 0) {
             return '';
         }
         $sItemDesc = MetaModel::GetHyperLink($this->Get('item_class'), $this->Get('item_id'));
         $sResult = $sAttName . ' - ';
         $sResult .= Dict::Format('Change:LinkSet:Modified', $sItemDesc);
         $sResult .= ' : ' . implode(', ', $aChanges);
     }
     return $sResult;
 }
 /**
  * Prepare structures in memory, to speedup the processing of a given replica
  */
 public function PrepareProcessing($bFirstPass = true)
 {
     if ($this->m_oDataSource->Get('status') == 'obsolete') {
         throw new SynchroExceptionNotStarted(Dict::S('Core:SyncDataSourceObsolete'));
     }
     if (!UserRights::IsAdministrator() && $this->m_oDataSource->Get('user_id') != UserRights::GetUserId()) {
         throw new SynchroExceptionNotStarted(Dict::S('Core:SyncDataSourceAccessRestriction'));
     }
     // Get the list of SQL columns
     $sClass = $this->m_oDataSource->GetTargetClass();
     $aAttCodesExpected = array();
     $aAttCodesToReconcile = array();
     $aAttCodesToUpdate = array();
     $sSelectAtt = "SELECT SynchroAttribute WHERE sync_source_id = :source_id AND (update = 1 OR reconcile = 1)";
     $oSetAtt = new DBObjectSet(DBObjectSearch::FromOQL($sSelectAtt), array(), array('source_id' => $this->m_oDataSource->GetKey()));
     while ($oSyncAtt = $oSetAtt->Fetch()) {
         if ($oSyncAtt->Get('update')) {
             $aAttCodesToUpdate[$oSyncAtt->Get('attcode')] = $oSyncAtt;
         }
         if ($oSyncAtt->Get('reconcile')) {
             $aAttCodesToReconcile[$oSyncAtt->Get('attcode')] = $oSyncAtt;
         }
         $aAttCodesExpected[$oSyncAtt->Get('attcode')] = $oSyncAtt;
     }
     $aColumns = $this->m_oDataSource->GetSQLColumns(array_keys($aAttCodesExpected));
     $aExtDataFields = array_keys($aColumns);
     $aExtDataFields[] = 'primary_key';
     $this->m_aExtDataSpec = array('table' => $this->m_oDataSource->GetDataTable(), 'join_key' => 'id', 'fields' => $aExtDataFields);
     // Get the list of attributes, determine reconciliation keys and update targets
     //
     if ($this->m_oDataSource->Get('reconciliation_policy') == 'use_attributes') {
         $this->m_aReconciliationKeys = $aAttCodesToReconcile;
     } elseif ($this->m_oDataSource->Get('reconciliation_policy') == 'use_primary_key') {
         // Override the settings made at the attribute level !
         $this->m_aReconciliationKeys = array("primary_key" => null);
     }
     if ($bFirstPass) {
         $this->m_oStatLog->AddTrace("Update of: {" . implode(', ', array_keys($aAttCodesToUpdate)) . "}");
         $this->m_oStatLog->AddTrace("Reconciliation on: {" . implode(', ', array_keys($this->m_aReconciliationKeys)) . "}");
     }
     if (count($aAttCodesToUpdate) == 0) {
         $this->m_oStatLog->AddTrace("No attribute to update");
         throw new SynchroExceptionNotStarted('There is no attribute to update');
     }
     if (count($this->m_aReconciliationKeys) == 0) {
         $this->m_oStatLog->AddTrace("No attribute for reconciliation");
         throw new SynchroExceptionNotStarted('No attribute for reconciliation');
     }
     $this->m_aAttributes = array();
     foreach ($aAttCodesToUpdate as $sAttCode => $oSyncAtt) {
         $oAttDef = MetaModel::GetAttributeDef($this->m_oDataSource->GetTargetClass(), $sAttCode);
         if ($oAttDef->IsWritable()) {
             $this->m_aAttributes[$sAttCode] = $oSyncAtt;
         }
     }
     // Compute and keep track of the limit date taken into account for obsoleting replicas
     //
     if ($this->m_oLastFullLoadStartDate == null) {
         // No previous import known, use the full_load_periodicity value... and the current date
         $this->m_oLastFullLoadStartDate = new DateTime();
         // Now
         $iLoadPeriodicity = $this->m_oDataSource->Get('full_load_periodicity');
         // Duration in seconds
         if ($iLoadPeriodicity > 0) {
             $sInterval = "-{$iLoadPeriodicity} seconds";
             $this->m_oLastFullLoadStartDate->Modify($sInterval);
         } else {
             $this->m_oLastFullLoadStartDate = new DateTime('1970-01-01');
         }
     }
     if ($bFirstPass) {
         $this->m_oStatLog->AddTrace("Limit Date: " . $this->m_oLastFullLoadStartDate->Format('Y-m-d H:i:s'));
     }
 }
 public function GetAttributeProperty($sClass, $sAttCode, $sPropName, $default = null)
 {
     $ret = $default;
     $oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode);
     $aParams = $oAttDef->GetParams();
     if (array_key_exists($sPropName, $aParams)) {
         $ret = $aParams[$sPropName];
     }
     if ($oAttDef instanceof AttributeHierarchicalKey) {
         if ($sPropName == 'targetclass') {
             $ret = $sClass;
         }
     }
     return $ret;
 }
Exemplo n.º 24
0
 /**
  * Compute the order of the fields & pages in the wizard
  * @param $oPage iTopWebPage The current page (used to display error messages) 
  * @param $sClass string Name of the class
  * @param $sStateCode string Code of the target state of the object
  * @return hash Two dimensional array: each element represents the list of fields for a given page   
  */
 protected function ComputeWizardStructure()
 {
     $aWizardSteps = array('mandatory' => array(), 'optional' => array());
     $aFieldsDone = array();
     // Store all the fields that are already covered by a previous step of the wizard
     $aStates = MetaModel::EnumStates($this->m_sClass);
     $sStateAttCode = MetaModel::GetStateAttributeCode($this->m_sClass);
     $aMandatoryAttributes = array();
     // Some attributes are always mandatory independently of the state machine (if any)
     foreach (MetaModel::GetAttributesList($this->m_sClass) as $sAttCode) {
         $oAttDef = MetaModel::GetAttributeDef($this->m_sClass, $sAttCode);
         if (!$oAttDef->IsExternalField() && !$oAttDef->IsNullAllowed() && $oAttDef->IsWritable() && $sAttCode != $sStateAttCode) {
             $aMandatoryAttributes[$sAttCode] = OPT_ATT_MANDATORY;
         }
     }
     // Now check the attributes that are mandatory in the specified state
     if (!empty($this->m_sTargetState) && count($aStates[$this->m_sTargetState]['attribute_list']) > 0) {
         // Check all the fields that *must* be included in the wizard for this
         // particular target state
         $aFields = array();
         foreach ($aStates[$this->m_sTargetState]['attribute_list'] as $sAttCode => $iOptions) {
             if (isset($aMandatoryAttributes[$sAttCode]) && $aMandatoryAttributes[$sAttCode] & (OPT_ATT_MANDATORY | OPT_ATT_MUSTCHANGE | OPT_ATT_MUSTPROMPT)) {
                 $aMandatoryAttributes[$sAttCode] |= $iOptions;
             } else {
                 $aMandatoryAttributes[$sAttCode] = $iOptions;
             }
         }
     }
     // Check all the fields that *must* be included in the wizard
     // i.e. all mandatory, must-change or must-prompt fields that are
     // not also read-only or hidden.
     // Some fields may be required (null not allowed) from the database
     // perspective, but hidden or read-only from the user interface perspective
     $aFields = array();
     foreach ($aMandatoryAttributes as $sAttCode => $iOptions) {
         if ($iOptions & (OPT_ATT_MANDATORY | OPT_ATT_MUSTCHANGE | OPT_ATT_MUSTPROMPT) && !($iOptions & (OPT_ATT_READONLY | OPT_ATT_HIDDEN))) {
             $oAttDef = MetaModel::GetAttributeDef($this->m_sClass, $sAttCode);
             $aPrerequisites = $oAttDef->GetPrerequisiteAttributes();
             $aFields[$sAttCode] = array();
             foreach ($aPrerequisites as $sCode) {
                 $aFields[$sAttCode][$sCode] = '';
             }
         }
     }
     // Now use the dependencies between the fields to order them
     // Start from the order of the 'details'
     $aList = MetaModel::FlattenZlist(MetaModel::GetZListItems($this->m_sClass, 'details'));
     $index = 0;
     $aOrder = array();
     foreach ($aFields as $sAttCode => $void) {
         $aOrder[$sAttCode] = 999;
         // At the end of the list...
     }
     foreach ($aList as $sAttCode) {
         if (array_key_exists($sAttCode, $aFields)) {
             $aOrder[$sAttCode] = $index;
         }
         $index++;
     }
     foreach ($aFields as $sAttCode => $aDependencies) {
         // All fields with no remaining dependencies can be entered at this
         // step of the wizard
         if (count($aDependencies) > 0) {
             $iMaxPos = 0;
             // Remove this field from the dependencies of the other fields
             foreach ($aDependencies as $sDependentAttCode => $void) {
                 // position the current field after the ones it depends on
                 $iMaxPos = max($iMaxPos, 1 + $aOrder[$sDependentAttCode]);
             }
         }
     }
     asort($aOrder);
     $aCurrentStep = array();
     foreach ($aOrder as $sAttCode => $rank) {
         $aCurrentStep[] = $sAttCode;
         $aFieldsDone[$sAttCode] = '';
     }
     $aWizardSteps['mandatory'][] = $aCurrentStep;
     // Now computes the steps to fill the optional fields
     $aFields = array();
     // reset
     foreach (MetaModel::ListAttributeDefs($this->m_sClass) as $sAttCode => $oAttDef) {
         $iOptions = isset($aStates[$this->m_sTargetState]['attribute_list'][$sAttCode]) ? $aStates[$this->m_sTargetState]['attribute_list'][$sAttCode] : 0;
         if ($sStateAttCode != $sAttCode && !$oAttDef->IsExternalField() && ($iOptions & (OPT_ATT_HIDDEN | OPT_ATT_READONLY)) == 0 && !isset($aFieldsDone[$sAttCode])) {
             // 'State', external fields, read-only and hidden fields
             // and fields that are already listed in the wizard
             // are removed from the 'optional' part of the wizard
             $oAttDef = MetaModel::GetAttributeDef($this->m_sClass, $sAttCode);
             $aPrerequisites = $oAttDef->GetPrerequisiteAttributes();
             $aFields[$sAttCode] = array();
             foreach ($aPrerequisites as $sCode) {
                 if (!isset($aFieldsDone[$sCode])) {
                     // retain only the dependencies that were not covered
                     // in the 'mandatory' part of the wizard
                     $aFields[$sAttCode][$sCode] = '';
                 }
             }
         }
     }
     // Now use the dependencies between the fields to order them
     while (count($aFields) > 0) {
         $aCurrentStep = array();
         foreach ($aFields as $sAttCode => $aDependencies) {
             // All fields with no remaining dependencies can be entered at this
             // step of the wizard
             if (count($aDependencies) == 0) {
                 $aCurrentStep[] = $sAttCode;
                 $aFieldsDone[$sAttCode] = '';
                 unset($aFields[$sAttCode]);
                 // Remove this field from the dependencies of the other fields
                 foreach ($aFields as $sUpdatedCode => $aDummy) {
                     // remove the dependency
                     unset($aFields[$sUpdatedCode][$sAttCode]);
                 }
             }
         }
         if (count($aCurrentStep) == 0) {
             // This step of the wizard would contain NO field !
             $this->m_oPage->add(Dict::S('UI:Error:WizardCircularReferenceInDependencies'));
             print_r($aFields);
             break;
         }
         $aWizardSteps['optional'][] = $aCurrentStep;
     }
     return $aWizardSteps;
 }
 /**
  * Find redundancy settings that can be viewed and modified in a tab
  * Settings are distributed to the corresponding link set attribute so as to be shown in the relevant tab	 
  */
 protected function FindVisibleRedundancySettings()
 {
     $aRet = array();
     foreach (MetaModel::ListAttributeDefs(get_class($this)) as $sAttCode => $oAttDef) {
         if ($oAttDef instanceof AttributeRedundancySettings) {
             if ($oAttDef->IsVisible()) {
                 $aQueryInfo = $oAttDef->GetRelationQueryData();
                 if (isset($aQueryInfo['sAttribute'])) {
                     $oUpperAttDef = MetaModel::GetAttributeDef($aQueryInfo['sFromClass'], $aQueryInfo['sAttribute']);
                     $oHostAttDef = $oUpperAttDef->GetMirrorLinkAttribute();
                     if ($oHostAttDef) {
                         $sHostAttCode = $oHostAttDef->GetCode();
                         $aRet[$sHostAttCode][] = $oAttDef;
                     }
                 }
             }
         }
     }
     return $aRet;
 }
Exemplo n.º 26
0
 /**
  * Get the form to create a new object of the 'target' class
  */
 public function GetObjectCreationForm(WebPage $oPage, $oCurrObject)
 {
     // Set all the default values in an object and clone this "default" object
     $oNewObj = MetaModel::NewObject($this->sTargetClass);
     // 1st - set context values
     $oAppContext = new ApplicationContext();
     $oAppContext->InitObjectFromContext($oNewObj);
     // 2nd set the default values from the constraint on the external key... if any
     if ($oCurrObject != null && $this->sAttCode != '') {
         $oAttDef = MetaModel::GetAttributeDef(get_class($oCurrObject), $this->sAttCode);
         $aParams = array('this' => $oCurrObject);
         $oSet = $oAttDef->GetAllowedValuesAsObjectSet($aParams);
         $aConsts = $oSet->ListConstantFields();
         $sClassAlias = $oSet->GetFilter()->GetClassAlias();
         if (isset($aConsts[$sClassAlias])) {
             foreach ($aConsts[$sClassAlias] as $sAttCode => $value) {
                 $oNewObj->Set($sAttCode, $value);
             }
         }
     }
     // 3rd - set values from the page argument 'default'
     $oNewObj->UpdateObjectFromArg('default');
     $sDialogTitle = '';
     $oPage->add('<div id="ac_create_' . $this->iId . '"><div class="wizContainer" style="vertical-align:top;"><div id="dcr_' . $this->iId . '">');
     $oPage->add("<h1>" . MetaModel::GetClassIcon($this->sTargetClass) . "&nbsp;" . Dict::Format('UI:CreationTitle_Class', MetaModel::GetName($this->sTargetClass)) . "</h1>\n");
     cmdbAbstractObject::DisplayCreationForm($oPage, $this->sTargetClass, $oNewObj, array(), array('formPrefix' => $this->iId, 'noRelations' => true));
     $oPage->add('</div></div></div>');
     //		$oPage->add_ready_script("\$('#ac_create_$this->iId').dialog({ width: $(window).width()*0.8, height: 'auto', autoOpen: false, modal: true, title: '$sDialogTitle'});\n");
     $oPage->add_ready_script("\$('#ac_create_{$this->iId}').dialog({ width: 'auto', height: 'auto', maxHeight: \$(window).height() - 50, autoOpen: false, modal: true, title: '{$sDialogTitle}'});\n");
     $oPage->add_ready_script("\$('#dcr_{$this->iId} form').removeAttr('onsubmit');");
     $oPage->add_ready_script("\$('#dcr_{$this->iId} form').bind('submit.uilinksWizard', oACWidget_{$this->iId}.DoCreateObject);");
 }
 /**
  * Helper to modify an enum value	
  * The change is made in the datamodel definition, but the value has to be changed in the DB as well	 	 
  * Must be called BEFORE DB update, i.e within an implementation of BeforeDatabaseCreation()
  * This helper does change ONE value at a time	 
  * 	 
  * @param string $sClass A valid class name
  * @param string $sAttCode The enum attribute code
  * @param string $sFrom Original value (already INVALID in the current datamodel)	 	
  * @param string $sTo New value (valid in the current datamodel)
  * @return void	 	 	
  */
 public static function RenameEnumValueInDB($sClass, $sAttCode, $sFrom, $sTo)
 {
     try {
         $sOriginClass = MetaModel::GetAttributeOrigin($sClass, $sAttCode);
         $sTableName = MetaModel::DBGetTable($sOriginClass);
         $oAttDef = MetaModel::GetAttributeDef($sOriginClass, $sAttCode);
         if ($oAttDef instanceof AttributeEnum) {
             $oValDef = $oAttDef->GetValuesDef();
             if ($oValDef) {
                 $aNewValues = array_keys($oValDef->GetValues(array(), ""));
                 if (in_array($sTo, $aNewValues)) {
                     $sEnumCol = $oAttDef->Get("sql");
                     $aFields = CMDBSource::QueryToArray("SHOW COLUMNS FROM `{$sTableName}` WHERE Field = '{$sEnumCol}'");
                     if (isset($aFields[0]['Type'])) {
                         $sColType = $aFields[0]['Type'];
                         // Note: the parsing should rely on str_getcsv (requires PHP 5.3) to cope with escaped string
                         if (preg_match("/^enum\\(\\'(.*)\\'\\)\$/", $sColType, $aMatches)) {
                             $aCurrentValues = explode("','", $aMatches[1]);
                         }
                     }
                     if (!in_array($sFrom, $aNewValues)) {
                         if (!in_array($sTo, $aCurrentValues)) {
                             $sNullSpec = $oAttDef->IsNullAllowed() ? 'NULL' : 'NOT NULL';
                             if (strtolower($sTo) == strtolower($sFrom)) {
                                 SetupPage::log_info("Changing enum in DB - {$sClass}::{$sAttCode} from '{$sFrom}' to '{$sTo}' (just a change in the case)");
                                 $aTargetValues = array();
                                 foreach ($aCurrentValues as $sValue) {
                                     if ($sValue == $sFrom) {
                                         $sValue = $sTo;
                                     }
                                     $aTargetValues[] = $sValue;
                                 }
                                 $sColumnDefinition = "ENUM(" . implode(",", CMDBSource::Quote($aTargetValues)) . ") {$sNullSpec}";
                                 $sRepair = "ALTER TABLE `{$sTableName}` MODIFY `{$sEnumCol}` {$sColumnDefinition}";
                                 CMDBSource::Query($sRepair);
                             } else {
                                 // 1st - Allow both values in the column definition
                                 //
                                 SetupPage::log_info("Changing enum in DB - {$sClass}::{$sAttCode} from '{$sFrom}' to '{$sTo}'");
                                 $aAllValues = $aCurrentValues;
                                 $aAllValues[] = $sTo;
                                 $sColumnDefinition = "ENUM(" . implode(",", CMDBSource::Quote($aAllValues)) . ") {$sNullSpec}";
                                 $sRepair = "ALTER TABLE `{$sTableName}` MODIFY `{$sEnumCol}` {$sColumnDefinition}";
                                 CMDBSource::Query($sRepair);
                                 // 2nd - Change the old value into the new value
                                 //
                                 $sRepair = "UPDATE `{$sTableName}` SET `{$sEnumCol}` = '{$sTo}' WHERE `{$sEnumCol}` = BINARY '{$sFrom}'";
                                 CMDBSource::Query($sRepair);
                                 $iAffectedRows = CMDBSource::AffectedRows();
                                 SetupPage::log_info("Changing enum in DB - {$iAffectedRows} rows updated");
                                 // 3rd - Remove the useless value from the column definition
                                 //
                                 $aTargetValues = array();
                                 foreach ($aCurrentValues as $sValue) {
                                     if ($sValue == $sFrom) {
                                         $sValue = $sTo;
                                     }
                                     $aTargetValues[] = $sValue;
                                 }
                                 $sColumnDefinition = "ENUM(" . implode(",", CMDBSource::Quote($aTargetValues)) . ") {$sNullSpec}";
                                 $sRepair = "ALTER TABLE `{$sTableName}` MODIFY `{$sEnumCol}` {$sColumnDefinition}";
                                 CMDBSource::Query($sRepair);
                                 SetupPage::log_info("Changing enum in DB - removed useless value '{$sFrom}'");
                             }
                         }
                     } else {
                         SetupPage::log_warning("Changing enum in DB - {$sClass}::{$sAttCode} - '{$sFrom}' is still a valid value (" . implode(', ', $aNewValues) . ")");
                     }
                 } else {
                     SetupPage::log_warning("Changing enum in DB - {$sClass}::{$sAttCode} - '{$sTo}' is not a known value (" . implode(', ', $aNewValues) . ")");
                 }
             }
         }
     } catch (Exception $e) {
         SetupPage::log_warning("Changing enum in DB - {$sClass}::{$sAttCode} - '{$sTo}' failed. Reason " . $e->getMessage());
     }
 }
Exemplo n.º 28
0
 /**
  * @param hash $aOrderBy Array of '[<classalias>.]attcode' => bAscending
  */
 public function MakeSelectQuery($aOrderBy = array(), $aArgs = array(), $aAttToLoad = null, $aExtendedDataSpec = null, $iLimitCount = 0, $iLimitStart = 0, $bGetCount = false)
 {
     // Check the order by specification, and prefix with the class alias
     // and make sure that the ordering columns are going to be selected
     //
     $sClass = $this->GetClass();
     $sClassAlias = $this->GetClassAlias();
     $aOrderSpec = array();
     foreach ($aOrderBy as $sFieldAlias => $bAscending) {
         if (!is_bool($bAscending)) {
             throw new CoreException("Wrong direction in ORDER BY spec, found '{$bAscending}' and expecting a boolean value");
         }
         $iDotPos = strpos($sFieldAlias, '.');
         if ($iDotPos === false) {
             $sAttClass = $sClass;
             $sAttClassAlias = $sClassAlias;
             $sAttCode = $sFieldAlias;
         } else {
             $sAttClassAlias = substr($sFieldAlias, 0, $iDotPos);
             $sAttClass = $this->GetClassName($sAttClassAlias);
             $sAttCode = substr($sFieldAlias, $iDotPos + 1);
         }
         if ($sAttCode != 'id') {
             MyHelpers::CheckValueInArray('field name in ORDER BY spec', $sAttCode, MetaModel::GetAttributesList($sAttClass));
             $oAttDef = MetaModel::GetAttributeDef($sAttClass, $sAttCode);
             foreach ($oAttDef->GetOrderBySQLExpressions($sAttClassAlias) as $sSQLExpression) {
                 $aOrderSpec[$sSQLExpression] = $bAscending;
             }
         } else {
             $aOrderSpec['`' . $sAttClassAlias . $sAttCode . '`'] = $bAscending;
         }
         // Make sure that the columns used for sorting are present in the loaded columns
         if (!is_null($aAttToLoad) && !isset($aAttToLoad[$sAttClassAlias][$sAttCode])) {
             $aAttToLoad[$sAttClassAlias][$sAttCode] = MetaModel::GetAttributeDef($sAttClass, $sAttCode);
         }
     }
     $oSQLQuery = $this->GetSQLQuery($aOrderBy, $aArgs, $aAttToLoad, $aExtendedDataSpec, $iLimitCount, $iLimitStart, $bGetCount);
     $aScalarArgs = array_merge(MetaModel::PrepareQueryArguments($aArgs), $this->GetInternalParams());
     try {
         $bBeautifulSQL = self::$m_bTraceQueries || self::$m_bDebugQuery || self::$m_bIndentQueries;
         $sRes = $oSQLQuery->RenderSelect($aOrderSpec, $aScalarArgs, $iLimitCount, $iLimitStart, $bGetCount, $bBeautifulSQL);
         if ($sClassAlias == '_itop_') {
             IssueLog::Info('SQL Query (_itop_): ' . $sRes);
         }
     } catch (MissingQueryArgument $e) {
         // Add some information...
         $e->addInfo('OQL', $this->ToOQL());
         throw $e;
     }
     $this->AddQueryTraceSelect($aOrderBy, $aArgs, $aAttToLoad, $aExtendedDataSpec, $iLimitCount, $iLimitStart, $bGetCount, $sRes);
     return $sRes;
 }
Exemplo n.º 29
0
/**
 * Helper function to build the mapping drop-down list for a field
 * Spec: Possible choices are "writable" fields in this class plus external fields that are listed as reconciliation keys
 *       for any class pointed to by an external key in the current class.
 *       If not in advanced mode, all "id" fields (id and external keys) must be mapped to ":none:" (i.e -- ignore this field --)
 *       External fields that do not correspond to a reconciliation key must be mapped to ":none:"
 *       Otherwise, if a field equals either the 'code' or the 'label' (translated) of a field, then it's mapped automatically
 * @param string $sClassName Name of the class used for the mapping
 * @param string $sFieldName Name of the field, as it comes from the data file (header line)
 * @param integer $iFieldIndex Number of the field in the sequence
 * @param bool $bAdvancedMode Whether or not advanced mode was chosen
 * @param string $sDefaultChoice If set, this will be the item selected by default
 * @return string The HTML code corresponding to the drop-down list for this field
 */
function GetMappingForField($sClassName, $sFieldName, $iFieldIndex, $bAdvancedMode, $sDefaultChoice)
{
    $aChoices = array('' => Dict::S('UI:CSVImport:MappingSelectOne'));
    $aChoices[':none:'] = Dict::S('UI:CSVImport:MappingNotApplicable');
    $sFieldCode = '';
    // Code of the attribute, if there is a match
    $aMatches = array();
    if (preg_match('/^(.+)\\*$/', $sFieldName, $aMatches)) {
        // Remove any trailing "star" character.
        // A star character at the end can be used to indicate a mandatory field
        $sFieldName = $aMatches[1];
    } else {
        if (preg_match('/^(.+)\\*->(.+)$/', $sFieldName, $aMatches)) {
            // Remove any trailing "star" character before the arrow (->)
            // A star character at the end can be used to indicate a mandatory field
            $sFieldName = $aMatches[1] . '->' . $aMatches[2];
        }
    }
    if ($sFieldName == 'id') {
        $sFieldCode = 'id';
    }
    if ($bAdvancedMode) {
        $aChoices['id'] = Dict::S('UI:CSVImport:idField');
    }
    foreach (MetaModel::ListAttributeDefs($sClassName) as $sAttCode => $oAttDef) {
        $sStar = '';
        if ($oAttDef->IsExternalKey()) {
            if ($sFieldName == $oAttDef->GetLabel() || $sFieldName == $sAttCode) {
                $sFieldCode = $sAttCode;
            }
            if ($bAdvancedMode) {
                $aChoices[$sAttCode] = $oAttDef->GetLabel();
            }
            $oExtKeyAttDef = MetaModel::GetAttributeDef($sClassName, $oAttDef->GetKeyAttCode());
            if (!$oExtKeyAttDef->IsNullAllowed()) {
                $sStar = '*';
            }
            // Get fields of the external class that are considered as reconciliation keys
            $sTargetClass = $oAttDef->GetTargetClass();
            foreach (MetaModel::ListAttributeDefs($sTargetClass) as $sTargetAttCode => $oTargetAttDef) {
                if (MetaModel::IsReconcKey($sTargetClass, $sTargetAttCode)) {
                    $bExtKey = $oTargetAttDef->IsExternalKey();
                    $sSuffix = '';
                    if ($bExtKey) {
                        $sSuffix = '->id';
                    }
                    if ($bAdvancedMode || !$bExtKey) {
                        // When not in advanced mode do not allow to use reconciliation keys (on external keys) if they are themselves external keys !
                        $aChoices[$sAttCode . '->' . $sTargetAttCode] = MetaModel::GetLabel($sClassName, $sAttCode . '->' . $sTargetAttCode, true);
                        if (strcasecmp($sFieldName, $oAttDef->GetLabel() . '->' . $oTargetAttDef->GetLabel() . $sSuffix) == 0 || strcasecmp($sFieldName, $sAttCode . '->' . $sTargetAttCode . $sSuffix) == 0) {
                            $sFieldCode = $sAttCode . '->' . $sTargetAttCode;
                        }
                    }
                }
            }
        } else {
            if ($oAttDef->IsWritable() && (!$oAttDef->IsLinkset() || $bAdvancedMode && $oAttDef->IsIndirect())) {
                $aChoices[$sAttCode] = MetaModel::GetLabel($sClassName, $sAttCode, true);
                if ($sFieldName == $oAttDef->GetLabel() || $sFieldName == $sAttCode) {
                    $sFieldCode = $sAttCode;
                }
            }
        }
    }
    asort($aChoices);
    $sHtml = "<select id=\"mapping_{$iFieldIndex}\" name=\"field[{$iFieldIndex}]\">\n";
    $bIsIdField = IsIdField($sClassName, $sFieldCode);
    foreach ($aChoices as $sAttCode => $sLabel) {
        $sSelected = '';
        if ($bIsIdField && !$bAdvancedMode) {
            if ($sAttCode == ':none:') {
                $sSelected = ' selected';
            }
        } else {
            if (empty($sFieldCode) && strpos($sFieldName, '->') !== false) {
                if ($sAttCode == ':none:') {
                    $sSelected = ' selected';
                }
            } else {
                if (is_null($sDefaultChoice) && $sFieldCode == $sAttCode) {
                    $sSelected = ' selected';
                } else {
                    if (!is_null($sDefaultChoice) && $sDefaultChoice == $sAttCode) {
                        $sSelected = ' selected';
                    }
                }
            }
        }
        $sHtml .= "<option value=\"{$sAttCode}\"{$sSelected}>{$sLabel}</option>\n";
    }
    $sHtml .= "</select>\n";
    return $sHtml;
}
Exemplo n.º 30
0
 public function GetHeader()
 {
     $sData = '';
     $oSet = new DBObjectSet($this->oSearch);
     $this->aStatusInfo['status'] = 'running';
     $this->aStatusInfo['position'] = 0;
     $this->aStatusInfo['total'] = $oSet->Count();
     $aSelectedClasses = $this->oSearch->GetSelectedClasses();
     foreach ($aSelectedClasses as $sAlias => $sClassName) {
         if (UserRights::IsActionAllowed($sClassName, UR_ACTION_BULK_READ, $oSet) && (UR_ALLOWED_YES || UR_ALLOWED_DEPENDS)) {
             $aAuthorizedClasses[$sAlias] = $sClassName;
         }
     }
     $aAliases = array_keys($aAuthorizedClasses);
     $aData = array();
     foreach ($this->aStatusInfo['fields'] as $sExtendedAttCode) {
         if (preg_match('/^([^\\.]+)\\.(.+)$/', $sExtendedAttCode, $aMatches)) {
             $sAlias = $aMatches[1];
             $sAttCode = $aMatches[2];
         } else {
             $sAlias = reset($aAliases);
             $sAttCode = $sExtendedAttCode;
         }
         if (!in_array($sAlias, $aAliases)) {
             throw new Exception("Invalid alias '{$sAlias}' for the column '{$sExtendedAttCode}'. Availables aliases: '" . implode("', '", $aAliases) . "'");
         }
         $sClass = $aSelectedClasses[$sAlias];
         switch ($sAttCode) {
             case 'id':
                 if (count($aSelectedClasses) > 1) {
                     $aData[] = $sAlias . '.id';
                     //@@@
                 } else {
                     $aData[] = 'id';
                     //@@@
                 }
                 break;
             default:
                 $oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode);
                 if (count($aSelectedClasses) > 1) {
                     $aData[] = $sAlias . '.' . $oAttDef->GetLabel();
                 } else {
                     $aData[] = $oAttDef->GetLabel();
                 }
         }
     }
     $sData .= "<table class=\"listResults\">\n";
     $sData .= "<thead>\n";
     $sData .= "<tr>\n";
     foreach ($aData as $sLabel) {
         $sData .= "<th>" . $sLabel . "</th>\n";
     }
     $sData .= "</tr>\n";
     $sData .= "</thead>\n";
     $sData .= "<tbody>\n";
     return $sData;
 }