/** * Spreadsheet output: designed for end users doing some reporting * Then the ids are excluded and replaced by the corresponding friendlyname */ static function GetSetAsHTMLSpreadsheet(DBObjectSet $oSet, $aParams = array()) { $aFields = null; if (isset($aParams['fields']) && strlen($aParams['fields']) > 0) { $aFields = explode(',', $aParams['fields']); } $bFieldsAdvanced = false; if (isset($aParams['fields_advanced'])) { $bFieldsAdvanced = (bool) $aParams['fields_advanced']; } $bLocalize = true; if (isset($aParams['localize_values'])) { $bLocalize = (bool) $aParams['localize_values']; } $aList = array(); $oAppContext = new ApplicationContext(); $aClasses = $oSet->GetFilter()->GetSelectedClasses(); $aAuthorizedClasses = array(); foreach ($aClasses as $sAlias => $sClassName) { if (UserRights::IsActionAllowed($sClassName, UR_ACTION_READ, $oSet) && (UR_ALLOWED_YES || UR_ALLOWED_DEPENDS)) { $aAuthorizedClasses[$sAlias] = $sClassName; } } $aAttribs = array(); $aHeader = array(); foreach ($aAuthorizedClasses as $sAlias => $sClassName) { $aList[$sAlias] = array(); foreach (MetaModel::ListAttributeDefs($sClassName) as $sAttCode => $oAttDef) { if (is_null($aFields) || count($aFields) == 0) { // Standard list of attributes (no link sets) if ($oAttDef->IsScalar() && ($oAttDef->IsWritable() || $oAttDef->IsExternalField())) { $sAttCodeEx = $oAttDef->IsExternalField() ? $oAttDef->GetKeyAttCode() . '->' . $oAttDef->GetExtAttCode() : $sAttCode; $aList[$sAlias][$sAttCodeEx] = $oAttDef; if ($bFieldsAdvanced && $oAttDef->IsExternalKey(EXTKEY_RELATIVE)) { $sRemoteClass = $oAttDef->GetTargetClass(); foreach (MetaModel::GetReconcKeys($sRemoteClass) as $sRemoteAttCode) { $aList[$sAlias][$sAttCode . '->' . $sRemoteAttCode] = MetaModel::GetAttributeDef($sRemoteClass, $sRemoteAttCode); } } } } else { // User defined list of attributes if (in_array($sAttCode, $aFields) || in_array($sAlias . '.' . $sAttCode, $aFields)) { $aList[$sAlias][$sAttCode] = $oAttDef; } } } // Replace external key by the corresponding friendly name (if not already in the list) foreach ($aList[$sAlias] as $sAttCode => $oAttDef) { if ($oAttDef->IsExternalKey()) { unset($aList[$sAlias][$sAttCode]); $sFriendlyNameAttCode = $sAttCode . '_friendlyname'; if (!array_key_exists($sFriendlyNameAttCode, $aList[$sAlias]) && MetaModel::IsValidAttCode($sClassName, $sFriendlyNameAttCode)) { $oFriendlyNameAtt = MetaModel::GetAttributeDef($sClassName, $sFriendlyNameAttCode); $aList[$sAlias][$sFriendlyNameAttCode] = $oFriendlyNameAtt; } } } foreach ($aList[$sAlias] as $sAttCodeEx => $oAttDef) { $sColLabel = $bLocalize ? MetaModel::GetLabel($sClassName, $sAttCodeEx) : $sAttCodeEx; $oFinalAttDef = $oAttDef->GetFinalAttDef(); if (get_class($oFinalAttDef) == 'AttributeDateTime') { $aHeader[] = $sColLabel . ' (' . Dict::S('UI:SplitDateTime-Date') . ')'; $aHeader[] = $sColLabel . ' (' . Dict::S('UI:SplitDateTime-Time') . ')'; } else { $aHeader[] = $sColLabel; } } } $sHtml = "<table border=\"1\">\n"; $sHtml .= "<tr>\n"; $sHtml .= "<td>" . implode("</td><td>", $aHeader) . "</td>\n"; $sHtml .= "</tr>\n"; $oSet->Seek(0); while ($aObjects = $oSet->FetchAssoc()) { $aRow = array(); foreach ($aAuthorizedClasses as $sAlias => $sClassName) { $oObj = $aObjects[$sAlias]; foreach ($aList[$sAlias] as $sAttCodeEx => $oAttDef) { if (is_null($oObj)) { $aRow[] = '<td></td>'; } else { $oFinalAttDef = $oAttDef->GetFinalAttDef(); if (get_class($oFinalAttDef) == 'AttributeDateTime') { $sDate = $oObj->Get($sAttCodeEx); if ($sDate === null) { $aRow[] = '<td></td>'; $aRow[] = '<td></td>'; } else { $iDate = AttributeDateTime::GetAsUnixSeconds($sDate); $aRow[] = '<td>' . date('Y-m-d', $iDate) . '</td>'; $aRow[] = '<td>' . date('H:i:s', $iDate) . '</td>'; } } else { if ($oAttDef instanceof AttributeCaseLog) { $rawValue = $oObj->Get($sAttCodeEx); $outputValue = str_replace("\n", "<br/>", htmlentities($rawValue->__toString(), ENT_QUOTES, 'UTF-8')); // Trick for Excel: treat the content as text even if it begins with an equal sign $aRow[] = '<td x:str>' . $outputValue . '</td>'; } else { $rawValue = $oObj->Get($sAttCodeEx); // Due to custom formatting rules, empty friendlynames may be rendered as non-empty strings // let's fix this and make sure we render an empty string if the key == 0 if ($oAttDef instanceof AttributeFriendlyName) { $sKeyAttCode = $oAttDef->GetKeyAttCode(); if ($sKeyAttCode != 'id') { if ($oObj->Get($sKeyAttCode) == 0) { $rawValue = ''; } } } if ($bLocalize) { $outputValue = htmlentities($oFinalAttDef->GetEditValue($rawValue), ENT_QUOTES, 'UTF-8'); } else { $outputValue = htmlentities($rawValue, ENT_QUOTES, 'UTF-8'); } $aRow[] = '<td>' . $outputValue . '</td>'; } } } } } $sHtml .= implode("\n", $aRow); $sHtml .= "</tr>\n"; } $sHtml .= "</table>\n"; return $sHtml; }
public static function FormatDeadline($value) { $sResult = ''; if ($value !== null) { $iValue = AttributeDateTime::GetAsUnixSeconds($value); $sDate = $value; $difference = $iValue - time(); if ($difference >= 0) { $sDifference = self::FormatDuration($difference); } else { $sDifference = Dict::Format('UI:DeadlineMissedBy_duration', self::FormatDuration(-$difference)); } $sFormat = MetaModel::GetConfig()->Get('deadline_format', '$difference$'); $sResult = str_replace(array('$date$', '$difference$'), array($sDate, $sDifference), $sFormat); } return $sResult; }
public function GetNextChunk(&$aStatus) { $sRetCode = 'run'; $iPercentage = 0; $oSet = new DBObjectSet($this->oSearch); $oSet->SetLimit($this->iChunkSize, $this->aStatusInfo['position']); $this->OptimizeColumnLoad($oSet); $iCount = 0; $sData = ''; $iPreviousTimeLimit = ini_get('max_execution_time'); $iLoopTimeLimit = MetaModel::GetConfig()->Get('max_execution_time_per_loop'); while ($aRow = $oSet->FetchAssoc()) { set_time_limit($iLoopTimeLimit); $sData .= "<tr>"; foreach ($this->aStatusInfo['fields'] as $iCol => $aFieldSpec) { $sAlias = $aFieldSpec['sAlias']; $sAttCode = $aFieldSpec['sAttCode']; $sField = ''; $oObj = $aRow[$sAlias]; if ($oObj == null) { $sData .= "<td x:str></td>"; continue; } switch ($sAttCode) { case 'id': $sField = $oObj->GetKey(); $sData .= "<td>{$sField}</td>"; break; default: $oAttDef = MetaModel::GetAttributeDef(get_class($oObj), $sAttCode); $oFinalAttDef = $oAttDef->GetFinalAttDef(); if (get_class($oFinalAttDef) == 'AttributeDateTime') { $iDate = AttributeDateTime::GetAsUnixSeconds($oObj->Get($sAttCode)); $sData .= '<td>' . date('Y-m-d', $iDate) . '</td>'; // Add the first column directly $sField = date('H:i:s', $iDate); // Will add the second column below $sData .= "<td>{$sField}</td>"; } else { if ($oAttDef instanceof AttributeCaseLog) { $rawValue = $oObj->Get($sAttCode); $sField = str_replace("\n", "<br/>", htmlentities($rawValue->__toString(), ENT_QUOTES, 'UTF-8')); // Trick for Excel: treat the content as text even if it begins with an equal sign $sData .= "<td x:str>{$sField}</td>"; } else { if ($oAttDef instanceof AttributeString) { $sField = $oObj->GetAsHTML($sAttCode, $this->bLocalizeOutput); $sData .= "<td x:str>{$sField}</td>"; } else { $rawValue = $oObj->Get($sAttCode); if ($this->bLocalizeOutput) { $sField = htmlentities($oFinalAttDef->GetEditValue($rawValue), ENT_QUOTES, 'UTF-8'); } else { $sField = htmlentities($rawValue, ENT_QUOTES, 'UTF-8'); } $sData .= "<td>{$sField}</td>"; } } } } } $sData .= "</tr>"; $iCount++; } set_time_limit($iPreviousTimeLimit); $this->aStatusInfo['position'] += $this->iChunkSize; if ($this->aStatusInfo['total'] == 0) { $iPercentage = 100; } else { $iPercentage = floor(min(100.0, 100.0 * $this->aStatusInfo['position'] / $this->aStatusInfo['total'])); } if ($iCount < $this->iChunkSize) { $sRetCode = 'done'; } $aStatus = array('code' => $sRetCode, 'message' => Dict::S('Core:BulkExport:RetrievingData'), 'percentage' => $iPercentage); return $sData; }
public function SetResolveDate($sStimulusCode) { $this->Set('resolution_date', time()); $iTimeSpent = time() - AttributeDateTime::GetAsUnixSeconds($this->Get('start_date')); $this->Set('time_spent', $iTimeSpent); return true; }
public function GetNextChunk(&$aStatus) { $sRetCode = 'run'; $iPercentage = 0; $oSet = new DBObjectSet($this->oSearch); $aSelectedClasses = $this->oSearch->GetSelectedClasses(); $oSet->SetLimit($this->iChunkSize, $this->aStatusInfo['position']); $aAliasByField = array(); $aColumnsToLoad = array(); // Prepare the list of aliases / columns to load foreach ($this->aStatusInfo['fields'] as $sExtendedAttCode) { if (preg_match('/^([^\\.]+)\\.(.+)$/', $sExtendedAttCode, $aMatches)) { $sAlias = $aMatches[1]; $sAttCode = $aMatches[2]; } else { $sAlias = reset($aSelectedClasses); $sAttCode = $sExtendedAttCode; } if (!array_key_exists($sAlias, $aSelectedClasses)) { throw new Exception("Invalid alias '{$sAlias}' for the column '{$sExtendedAttCode}'. Availables aliases: '" . implode("', '", array_keys($aSelectedClasses)) . "'"); } if (!array_key_exists($sAlias, $aColumnsToLoad)) { $aColumnsToLoad[$sAlias] = array(); } if ($sAttCode != 'id') { // id is not a real attribute code and, moreover, is always loaded $aColumnsToLoad[$sAlias][] = $sAttCode; } $aAliasByField[$sExtendedAttCode] = array('alias' => $sAlias, 'attcode' => $sAttCode); } $iCount = 0; $sData = ''; $oSet->OptimizeColumnLoad($aColumnsToLoad); $iPreviousTimeLimit = ini_get('max_execution_time'); $iLoopTimeLimit = MetaModel::GetConfig()->Get('max_execution_time_per_loop'); while ($aRow = $oSet->FetchAssoc()) { set_time_limit($iLoopTimeLimit); $sData .= "<tr>"; foreach ($aAliasByField as $aAttCode) { $sField = ''; $oObj = $aRow[$aAttCode['alias']]; if ($oObj == null) { $sData .= "<td x:str>{$sField}</td>"; continue; } switch ($aAttCode['attcode']) { case 'id': $sField = $oObj->GetName(); $sData .= "<td>{$sField}</td>"; break; default: $oAttDef = MetaModel::GetAttributeDef(get_class($oObj), $aAttCode['attcode']); $oFinalAttDef = $oAttDef->GetFinalAttDef(); if (get_class($oFinalAttDef) == 'AttributeDateTime') { $iDate = AttributeDateTime::GetAsUnixSeconds($oObj->Get($aAttCode['attcode'])); $sData .= '<td>' . date('Y-m-d', $iDate) . '</td>'; // Add the first column directly $sField = date('H:i:s', $iDate); // Will add the second column below $sData .= "<td>{$sField}</td>"; } else { if ($oAttDef instanceof AttributeCaseLog) { $rawValue = $oObj->Get($aAttCode['attcode']); $sField = str_replace("\n", "<br/>", htmlentities($rawValue->__toString(), ENT_QUOTES, 'UTF-8')); // Trick for Excel: treat the content as text even if it begins with an equal sign $sData .= "<td x:str>{$sField}</td>"; } else { $rawValue = $oObj->Get($aAttCode['attcode']); // Due to custom formatting rules, empty friendlynames may be rendered as non-empty strings // let's fix this and make sure we render an empty string if the key == 0 if ($oAttDef instanceof AttributeFriendlyName) { $sKeyAttCode = $oAttDef->GetKeyAttCode(); if ($sKeyAttCode != 'id') { if ($oObj->Get($sKeyAttCode) == 0) { $sValue = ''; } } } if ($this->aStatusInfo['localize']) { $sField = htmlentities($oFinalAttDef->GetEditValue($rawValue), ENT_QUOTES, 'UTF-8'); } else { $sField = htmlentities($rawValue, ENT_QUOTES, 'UTF-8'); } $sData .= "<td>{$sField}</td>"; } } } } $sData .= "</tr>"; $iCount++; } set_time_limit($iPreviousTimeLimit); $this->aStatusInfo['position'] += $this->iChunkSize; if ($this->aStatusInfo['total'] == 0) { $iPercentage = 100; } else { $iPercentage = floor(min(100.0, 100.0 * $this->aStatusInfo['position'] / $this->aStatusInfo['total'])); } if ($iCount < $this->iChunkSize) { $sRetCode = 'done'; } $aStatus = array('code' => $sRetCode, 'message' => Dict::S('Core:BulkExport:RetrievingData'), 'percentage' => $iPercentage); return $sData; }
/** * Lifecycle action: Set the time elapsed since a reference point */ public function SetElapsedTime($sAttCode, $sRefAttCode, $sWorkingTimeComputer = null) { if (is_null($sWorkingTimeComputer)) { $sWorkingTimeComputer = class_exists('SLAComputation') ? 'SLAComputation' : 'DefaultWorkingTimeComputer'; } $oComputer = new $sWorkingTimeComputer(); $aCallSpec = array($oComputer, 'GetOpenDuration'); if (!is_callable($aCallSpec)) { throw new CoreException("Unknown class/verb '{$sWorkingTimeComputer}/GetOpenDuration'"); } $iStartTime = AttributeDateTime::GetAsUnixSeconds($this->Get($sRefAttCode)); $oStartDate = new DateTime('@' . $iStartTime); // setTimestamp not available in PHP 5.2 $oEndDate = new DateTime(); // now if (class_exists('WorkingTimeRecorder')) { $sClass = get_class($this); WorkingTimeRecorder::Start($this, time(), "DBObject-SetElapsedTime-{$sAttCode}-{$sRefAttCode}", 'Core:ExplainWTC:ElapsedTime', array("Class:{$sClass}/Attribute:{$sAttCode}")); } $iElapsed = call_user_func($aCallSpec, $this, $oStartDate, $oEndDate); if (class_exists('WorkingTimeRecorder')) { WorkingTimeRecorder::End(); } $this->Set($sAttCode, $iElapsed); return true; }