_processObservation(); } /** * Adds additional editor fields to the Contentserv interface * * @param CSGuiEditor $editor * @param CSMonitorObserver $observer */ public function prepareEditor(CSGuiEditor $editor, CSMonitorObserver $observer) { $this->_observer = $observer; $editor->addField("InspectProcesses", CS::translate('CSALIVE_MONITOR_INSPECT_PROCESSES', 'csalive'), $this->getInspectProcesses(), 'execCheckout', FALSE, array( 'PaneTitle' => CS::translate('REST_GUI_EDIT_SETTINGS'), 'noEmptyOption' => true, 'multiple' => true )); $editor->addField("RecordType", CS::translate('CSALIVE_MONITOR_RECORD_TYPE', 'csalive'), $this->getRecordTypes(), 'Pdmarticle', FALSE, array( 'PaneTitle' => CS::translate('REST_GUI_EDIT_SETTINGS'), 'noEmptyOption' => true, 'onlyFolder' => true )); $editor->addField("SampleFolderID", CS::translate('CSALIVE_MONITOR_SAMPLE_FOLDER_ID', 'csalive'), $this->getSelectedRecord(), '', FALSE, array( 'PaneTitle' => CS::translate('REST_GUI_EDIT_SETTINGS'), )); $editor->addField("SampleObjectID", CS::translate('CSALIVE_MONITOR_SAMPLE_OBJECT_ID', 'csalive'), $this->getSelectedRecord(), '', FALSE, array( 'PaneTitle' => CS::translate('REST_GUI_EDIT_SETTINGS'), )); $editor->addField("SampleObjectAttributeID", CS::translate('CSALIVE_MONITOR_SAMPLE_OBJECT_ATTRIBUTE_ID', 'csalive'), $this->getSelectedRecord()->getConfiguration(), '', FALSE, array( 'PaneTitle' => CS::translate('REST_GUI_EDIT_SETTINGS'), 'multiple' => true, 'attributes' => 'bottomFrame="core|extensions|item|dialogs|itemConfigurationRecordInputBottomFrame.php"' )); $editor->addField("SearchValue", CS::translate('CSALIVE_MONITOR_SEARCH_VALUE', 'csalive'), '', '', FALSE, array( 'PaneTitle' => CS::translate('REST_GUI_EDIT_SETTINGS'), )); $editor->addField("SearchObject", CS::translate('CSALIVE_MONITOR_SEARCH_OBJECT', 'csalive'), $this->getSelectedRecord(), '', FALSE, array( 'PaneTitle' => CS::translate('REST_GUI_EDIT_SETTINGS'), )); $editor->addField("SearchField", CS::translate('CSALIVE_MONITOR_SEARCH_FIELD', 'csalive'), $this->getSelectedRecord()->getConfiguration(), '', FALSE, array( 'PaneTitle' => CS::translate('REST_GUI_EDIT_SETTINGS'), 'multiple' => true, 'attributes' => 'bottomFrame="core|extensions|item|dialogs|itemConfigurationRecordInputBottomFrame.php"', )); } ///// PROTECTED METHODS ////////////////////////////////////////////////////// /** * Measures the time needed for a specific process and stores it in the database */ protected function _processObservation() { try { $objObject = $this->getSelectedRecord($this->_observer->getValue('SampleObjectID')); $arrChosenProcesses = explode(',', $this->_observer->getValue('InspectProcesses')); foreach ((array) $arrChosenProcesses as $value) { $intStartTime = $this->microtimeFloat(); $strFunctionName = $value; if (!method_exists($this, $strFunctionName)) { continue; } $this->strService = $this->getServiceName($strFunctionName); if ($strFunctionName === 'execUnfoldTree' || $strFunctionName === 'execObjectList') { $objFolder = $this->getSelectedRecord($this->_observer->getValue('SampleFolderID')); $mixedReturnValue = $this->$strFunctionName($objFolder); } else { $mixedReturnValue = $this->$strFunctionName($objObject); } $this->saveMeasuredValue($this->getDuration($intStartTime), 's', $this->strService); if ($mixedReturnValue !== NULL) { if ($mixedReturnValue === 99999) { $this->saveMeasuredValue($mixedReturnValue, 'Error', $this->strService . 'Value'); } else { $this->saveMeasuredValue($mixedReturnValue, 'Count', $this->strService . 'Value'); } } } } catch (Exception $e) { } } ///// PRIVATE METHODS ////////////////////////////////////////////////////// private function getServiceName($strFunctionName) { return $this->_observer->getValue('RecordType') . '.' . substr($strFunctionName, 4); } /** * Accesses the editor to receive the selected record type * * @param int $intID * * @return object Record */ private function getSelectedRecord($intID = 0) { $strRecordType = $this->_observer->getValue('RecordType'); if (!$strRecordType) { $strRecordType = 'Pdmarticle'; } return CS::getRecord($strRecordType, (int)$intID); } /** * Returns an array of Strings of all processes the plugin can monitor * * @return array all processes possible to be inspect */ private function getInspectProcesses() { $arrClassMethods = get_class_methods($this); $strSearchWord = 'exec'; $arrMatches = array_filter((array) $arrClassMethods, function($var) use ($strSearchWord) { return preg_match("/$strSearchWord/i", $var); }); foreach ((array) $arrMatches as $value) { $arrTranslatedMatches[$value] = CS::translate($value, 'csalive'); } return (array) $arrTranslatedMatches; } /** * Returns an array of Strings of all available filetypes * * @return array Possible datatypes that can be chosen to be monitored */ private function getRecordTypes() { return (array) array( 'Pdmarticle' => CS::translate('Pdmarticle'), 'Mamfile' => CS::translate('Mamfile'), 'Pdmarticlestructure' => CS::translate('Pdmarticlestructure'), 'User' => CS::translate('User') ); } /** * Returns a the current time as float. * * Helper function to measure script durations * * @return float Returns current microtime */ private function microtimeFloat() { list($usec, $sec) = explode(" ", microtime()); return ((float) $usec + (float) $sec); } /** * Returns the time difference between current time and given time in seconds. * * Helper function to measure script durations * * @return float returns current microtime */ private function getDuration($intStartTime) { return number_format((self::microtimeFloat() - $intStartTime), 4); } /** * Saves the measured values in the database * * @param mixed $mixedMeasuredValue * @param String $strUnit * @param String $strService */ private function saveMeasuredValue($mixedMeasuredValue, $strUnit, $strService) { $observation = CSMonitor::createObservation($this->_observer->getID(), $strService); $observation->setMeasuredValue($mixedMeasuredValue); $observation->setTimestamp(CS::getDate()); $observation->setUnit($strUnit); $state = CSMonitor::MONITOR_GUI_NOTIFICATION_NONE_ID; $observation->setState($state); $observation->setWarningValue(1); $observation->setCriticalValue(2); $observation->store(); } /** * Gets the attribute table name of the given record * * @param string $strRecordName Name of the record * @return string Returns the record name with 'configuration' added */ private function getAttributeTableName($strRecordName) { if ($strRecordName == 'Pdmarticlestructure') $strRecordName = 'Pdmarticle'; return $strRecordName . 'configuration'; } /** * Checks the product out, saves it once and checks it in again * * @param object $objObject */ private function execCheckout($objObject) { if (!empty($objObject) && !empty($objObject->getID())) { $objObject->checkout(); $objObject->store(); $objObject->checkin(); } else { return 99999; } } /** * Simulates opening a product for testing * * @param object $objObject */ private function execObjectEdit($objObject) { if (!empty($objObject->getID())) { $strUrl = $objObject->getEditorUrl() . CSUser::getPIN(); Curl::GET($strUrl); } else { return 99999; } } /** * Simulates opening the list of objects inside a folder * * @param object $objObject */ private function execObjectList($objObject) { if (!empty($objObject->getID())) { $strUrl = $objObject->getListUrl() . CSUser::getPIN(); Curl::GET($strUrl); } else { return 99999; } } /** * Opens a subbranch of a tree for benchmarking * * @param object $objObject */ private function execUnfoldTree($objObject) { if (!empty($objObject->getID())) { $strUrl = '../admin/forward.php?forward=modules|' . $objObject->getModuleName() . '|gui|tree.php&REQUESTED_NODE=' . $objObject->getID() . '&USE_AJAX=true&IS_AJAX_REQUEST=true' . CSUser::getPIN(); Curl::GET($strUrl); } else { return 99999; } } /** * Requests the attributes of a sample product for benchmarking * * @param object $objObject */ private function execRequestValues($objObject) { if (!empty($objObject->getID())) { $strAttributes = $this->_observer->getValue('SampleObjectAttributeID') . ',"Label"'; $arrAttributes = explode(',', $strAttributes); $objObject->getApi()->getValues($arrAttributes, true, true, true, array($objObject->getID()), null, CSITEM_VALUES_ARRAY); } else { return 99999; } } /** * Counts the number of objects in the specific table of the database * * @return int quantity of of all products */ private function execObjectCount() { /* Query AttributeValuesCount */ $strSQLCommand = 'SELECT COUNT(*) FROM ' . CS::getTablePrefix() . $this->_observer->getValue('RecordType') . 'attribute'; $intObjectCount = Database::queryValue($strSQLCommand); $this->saveMeasuredValue($intObjectCount, 'Count', $this->getServiceName('execObjectattributeCount') . 'Value'); /* Query AttributeCount */ $strSQLCommand = 'SELECT COUNT(*) FROM ' . CS::getTablePrefix() . $this->getAttributeTableName($this->_observer->getValue('RecordType')) . ' WHERE IsLink = 0'; $intObjectCount = Database::queryValue($strSQLCommand); $this->saveMeasuredValue($intObjectCount, 'Count', $this->getServiceName('execAttributeCount') . 'Value'); /* Query AVG AttributeCount with values of a object */ $strSQLCommand = 'SELECT AVG (record.grouped_count) FROM (SELECT COUNT( ' . $this->getAttributeTableName($this->_observer->getValue('RecordType')) . 'ID ) as grouped_count FROM ' . CS::getTablePrefix() . $this->_observer->getValue('RecordType') . 'attribute GROUP BY ' . $this->_observer->getValue('RecordType') . 'ID) record'; $intObjectCount = Database::queryValue($strSQLCommand); $this->saveMeasuredValue($intObjectCount, 'Count', $this->getServiceName('execObjectmeanattributeCount') . 'Value'); $strSQLCommand = 'SELECT COUNT(*) FROM ' . CS::getTablePrefix() . $this->_observer->getValue('RecordType'); $intObjectCount = Database::queryValue($strSQLCommand); return $intObjectCount; } /** * Searches the given list of attributes for the entered value * * @return int quantity of all found matches */ private function execObjectSearch() { if (!$this->_observer->getValue('SearchField') || !$this->_observer->getValue('SearchObject') || !$this->_observer->getValue('SearchValue')) throw new Exception("Ignore Plugin!", 404); $objItem = $this->getSelectedRecord($this->_observer->getValue('SearchObject')); $strSearchValue = $this->_observer->getValue('SearchValue'); $arrSearchField = explode(',', $this->_observer->getValue('SearchField')); $objSearchFilter = new CSItemSearchFilter(CS_SEARCH_WITH_OR); foreach ($arrSearchField as $value) { $objSearchFilter->addFilter($strSearchValue, 'like', $value); } $arrFindProd = $objItem->getApi()->searchContent($objSearchFilter, array($objItem->getID()), true, true, array(), ''); return count($arrFindProd); } }