/** * Akce pro vytvoření nového atributu * @SWG\Post( * tags={"Attributes"}, * path="/attributes", * summary="Create new attribute using defined preprocessing", * consumes={"application/json","application/xml"}, * produces={"application/json","application/xml"}, * security={{"apiKey":{}},{"apiKeyHeader":{}}}, * @SWG\Parameter( * description="New attribute", * name="body", * required=true, * @SWG\Schema(ref="#/definitions/NewAttributeInput"), * in="body" * ), * @SWG\Response( * response=201, * description="Attribute created", * @SWG\Schema( * ref="#/definitions/AttributeResponse" * ) * ), * @SWG\Response( * response=400, * description="Invalid API key supplied", * @SWG\Schema(ref="#/definitions/StatusResponse") * ) * ) * @throws \InvalidArgumentException */ public function actionCreate() { /** @var array $inputData */ $inputData = $this->input->getData(); $miner = $this->findMinerWithCheckAccess(@$inputData['miner']); $this->minersFacade->checkMinerMetasource($miner); $currentUser = $this->getCurrentUser(); //aktualizace informace o datových sloupcích $this->datasourcesFacade->updateDatasourceColumns($miner->datasource, $currentUser); try { if (!empty($inputData['column'])) { $datasourceColumn = $this->datasourcesFacade->findDatasourceColumn($miner->datasource, @$inputData['column']); } else { $datasourceColumn = $this->datasourcesFacade->findDatasourceColumnByName($miner->datasource, @$inputData['columnName']); } } catch (\Exception $e) { throw new InvalidArgumentException("Datasource columns was not found: " . @$inputData['columnName']); } //inicializace formátu $format = $datasourceColumn->format; if (!$format) { //TODO implementovat podporu automatického mapování $format = $this->metaAttributesFacade->simpleCreateMetaAttributeWithFormatFromDatasourceColumn($datasourceColumn, $currentUser); $datasourceColumn->format = $format; $this->datasourcesFacade->saveDatasourceColumn($datasourceColumn); } //vytvoření nového atributu $attribute = new Attribute(); $attribute->metasource = $miner->metasource; $attribute->datasourceColumn = $datasourceColumn; $attribute->name = $this->minersFacade->prepareNewAttributeName($miner, $inputData['name']); $attribute->type = $attribute->datasourceColumn->type; if (@$inputData['specialPreprocessing'] == Preprocessing::SPECIALTYPE_EACHONE) { $preprocessing = $this->metaAttributesFacade->findPreprocessingEachOne($datasourceColumn->format); $attribute->preprocessing = $preprocessing; } else { throw new \BadMethodCallException('Selected preprocessing type is not supported.'); //FIXME je nutné nalézt příslušný preprocessing... } $attribute->active = false; $this->metasourcesFacade->saveAttribute($attribute); //inicializace preprocessingu $metasourceTask = $this->metasourcesFacade->startAttributesPreprocessing($miner->metasource, [$attribute]); while ($metasourceTask && $metasourceTask->state != MetasourceTask::STATE_DONE) { $metasourceTask = $this->metasourcesFacade->preprocessAttributes($metasourceTask); } //smazání předzpracovávací úlohy $this->metasourcesFacade->deleteMetasourceTask($metasourceTask); $this->setXmlMapperElements('attribute'); $this->resource = $attribute->getDataArr(); $this->sendResource(); }
/** * Akce pro ověření přihlášeného uživatele * @param string $dbType * @SWG\Get( * tags={"Databases"}, * path="/databases/{dbType}", * summary="Get user access credentials for MySQL and other databases", * produces={"application/json","application/xml"}, * security={{"apiKey":{}},{"apiKeyHeader":{}}}, * @SWG\Parameter( * name="dbType", * description="Type of database", * required=true, * type="string", * in="path", * enum={"limited","unlimited","mysql"} * ), * @SWG\Response( * response=200, * description="Connection params", * @SWG\Schema( * required={"server","username","password","database"}, * @SWG\Property(property="server",type="string",description="DB Server (IP or URL)"), * @SWG\Property(property="port",type="integer",description="DB server port (empty if default)"), * @SWG\Property(property="username",type="string",description="Database username"), * @SWG\Property(property="password",type="string",description="Database password"), * @SWG\Property(property="database",type="string",description="Database name"), * ) * ), * @SWG\Response( * response=400, * description="Invalid API key supplied", * @SWG\Schema(ref="#/definitions/StatusResponse") * ) * ) */ public function actionRead($dbType) { $this->setXmlMapperElements('database'); $dbType = strtolower($dbType); //kontrola toho, kdy byl naposled kontrolován přístup k DB if ($this->currentUser->getLastDbCheck($dbType) < time() - DatabaseFactory::DB_AVAILABILITY_CHECK_INTERVAL) { $this->currentUser->setLastDbCheck($dbType, time()); $this->usersFacade->saveUser($this->currentUser); //TODO tahle kontrola by ještě měla být optimalizovaná $dbAvailabilityCheck = true; } else { $dbAvailabilityCheck = false; } //připravení informací o datovém zdroji pro konkrétního uživatele... $datasource = $this->datasourcesFacade->prepareNewDatasourceForUser($dbType, $this->currentUser, !$dbAvailabilityCheck); $dbConnection = $datasource->getDbConnection(); #region sestavení data arr $result = []; if (!empty($dbConnection->dbServer)) { $result['server'] = $dbConnection->dbServer; } if (!empty($dbConnection->dbApi)) { $result['api'] = $dbConnection->dbApi; } if (!empty($dbConnection->dbPort)) { $result['port'] = $dbConnection->dbPort; } #endregion sestavení data arr $arr =& $result; if (!empty($datasource->dbUsername)) { $arr['username'] = $datasource->dbUsername; } $dbPassword = $datasource->getDbPassword(); if (!empty($dbPassword)) { $arr['password'] = $dbPassword; } if (!empty($datasource->dbName)) { $arr['database'] = $datasource->dbName; } $this->resource = $arr; $this->sendResource(); }
/** * Signál vracející přejmenovávací dialog * @param int $datasource * @param int $column */ public function handleGetDatasourceColumnRenameDialog($datasource, $column) { $this->template->showDatasourceColumnRenameDialog = true; $datasourceColumn = $this->datasourcesFacade->findDatasourceColumn($datasource, $column); /** @var Form $form */ $form = $this->getComponent('datasourceColumnRenameDialog'); $form->setDefaults(array('name' => $datasourceColumn->name, 'datasource' => $datasource, 'column' => $column)); if ($this->presenter->isAjax()) { $this->redrawControl('datasourceColumnRenameDialog'); } }
/** * Formulář pro vytvoření nového formátu * @return Form */ protected function createComponentNewFormatForm() { $form = new Form(); $form->addHidden('datasource'); $form->addHidden('column'); $metaAttribute = $form->addHidden('metaAttribute'); $form->addText('metaAttributeName', 'Meta-attribute:')->setAttribute('readonly', 'readonly')->setAttribute('class', 'normalWidth'); $formatName = $form->addText('formatName', 'Format name:')->setRequired()->setAttribute('class', 'normalWidth'); $formatName->addRule(Form::MIN_LENGTH, 'Min length of format name is %s characters!', 3); $formatName->addRule(function (TextInput $control) use($metaAttribute) { try { $format = $this->metaAttributesFacade->findFormatByName($metaAttribute->value, $control->value); ///XXX if ($format instanceof Format) { return false; } } catch (\Exception $e) { /*chybu ignorujeme (nenalezený metaatribut je OK)*/ } return true; }, 'Format with this name already exists!'); $form->addCheckbox('formatShared', 'Create shared (standard) format'); $form->addSelect('formatType', 'Values range:', array('interval' => 'Continuous values (interval)', 'values' => 'Distinct values (enumeration)'))->setAttribute('class', 'normalWidth')->setDefaultValue('values'); $submit = $form->addSubmit('create', 'Create format'); $submit->setValidationScope(array($formatName)); $submit->onClick[] = function (SubmitButton $button) { $values = $button->form->values; try { $datasourceColumn = $this->datasourcesFacade->findDatasourceColumn($values->datasource, $values->column); $metaAttribute = $this->metaAttributesFacade->findMetaAttribute($values->metaAttribute); $datasource = $this->datasourcesFacade->findDatasource($values->datasource); $this->databasesFacade->openDatabase($datasource->getDbConnection()); $datasourceColumnValuesStatistic = $this->databasesFacade->getColumnValuesStatistic($datasource->dbTable, $datasourceColumn->name); $format = $this->metaAttributesFacade->createFormatFromDatasourceColumn($metaAttribute, $values->formatName, $datasourceColumn, $datasourceColumnValuesStatistic, @$values->formatType, @$values->formatShared); $datasourceColumn->format = $format; $this->datasourcesFacade->saveDatasourceColumn($datasourceColumn); } catch (\Exception $e) { $this->flashMessage($this->translator->translate('Format creation failed.')); } $this->redirect('Close'); }; $storno = $form->addSubmit('storno', 'Storno'); $storno->setValidationScope(array()); $storno->onClick[] = function (SubmitButton $button) { $values = $button->form->values; $this->redirect('SelectFormat', array('datasource' => $values->datasource, 'column' => $values->column, 'metaAttribute' => $values->metaAttribute)); }; $form->onError[] = function (Form $form) { $values = $form->values; $this->handleNewFormat($values->datasource, $values->column, $values->metaAttribute); }; return $form; }
/** * Funkce pro nalezení datového zdroje s kontrolou oprávnění přístupu * @param int $datasourceId * @throws BadRequestException * @return Datasource */ private function findDatasourceWithCheckAccess($datasourceId) { try { $datasource = $this->datasourcesFacade->findDatasource($datasourceId); if (!$this->datasourcesFacade->checkDatasourceAccess($datasource, $this->getCurrentUser())) { throw new BadRequestException("You are not authorized to use the selected datasource!"); } } catch (\Exception $e) { throw new BadRequestException("Requested datasource was not found or is not accessible!"); } return $datasource; }
/** * Akce vracející data description a konfiguraci pro EasyMiner UI * @param int $id_dm * @param int $miner * @throws ForbiddenRequestException */ public function actionGetData($id_dm, $miner) { if (empty($miner)) { $miner = $id_dm; } //------------------------------------------------------------------------------------------------------------------ $miner = $this->findMinerWithCheckAccess($miner); $minerType = $miner->type; $FLPathElement = 'FLPath_' . Strings::upper($minerType); //------------------------------------------------------------------------------------------------------------------ #region připravení informací pro UI - s odděleným připravením DataDictionary $dataDescriptionPMML = null; $dataParser = new DataParser($dataDescriptionPMML, $this->config->{$FLPathElement}, $this->config->FGCPath, null, null, $this->translator->getLang()); $dataParser->loadData(); $responseContent = $dataParser->parseData(); $user = $this->getCurrentUser(); $responseContent['DD'] = ['dataDictionary' => $this->datasourcesFacade->exportDataDictionaryArr($miner->datasource, $user, $rowsCount), 'transformationDictionary' => $this->metasourcesFacade->exportTransformationDictionaryArr($miner->metasource, $user), 'recordCount' => $rowsCount]; #endregion připravení informací pro UI - s odděleným připravením DataDictionary uksort($responseContent['DD']['transformationDictionary'], function ($a, $b) { return strnatcasecmp($a, $b); }); uksort($responseContent['DD']['dataDictionary'], function ($a, $b) { return strnatcasecmp($a, $b); //return strnatcasecmp(mb_strtolower($a,'utf-8'),mb_strtolower($b,'utf-8')); }); $responseContent['status'] = 'ok'; $responseContent['miner_type'] = $miner->type; $responseContent['miner_name'] = $miner->name; if ($miner->ruleSet) { $ruleSet = $miner->ruleSet; } else { $ruleSet = $this->ruleSetsFacade->saveNewRuleSetForUser($miner->name, $this->getCurrentUser()); $miner->ruleSet = $ruleSet; $this->minersFacade->saveMiner($miner); } $responseContent['miner_ruleset'] = ['id' => $ruleSet->ruleSetId, 'name' => $ruleSet->name]; $responseContent['miner_config'] = $miner->getExternalConfig(); $this->sendJsonResponse($responseContent); }
/** * Funkce vracející formulář pro vytvoření atributu na základě vybraného sloupce a preprocessingu * @return Form */ protected function createComponentNewAttributeForm() { $form = new Form(); $presenter = $this; $form->setTranslator($this->translator); $form->addHidden('miner'); $form->addHidden('column'); $form->addHidden('preprocessing'); $form->addText('attributeName', 'Attribute name:')->setRequired('Input attribute name!')->addRule(Form::PATTERN, 'Attribute name can contain only letters, numbers and _ and has start with a letter.', '[a-zA-Z]{1}\\w*')->addRule(function (TextInput $input) { //kontrola, jestli již existuje atribtu se zadaným názvem $values = $input->getForm(true)->getValues(); $miner = $this->findMinerWithCheckAccess($values->miner); $attributes = $miner->metasource->attributes; if (!empty($attributes)) { foreach ($attributes as $attribute) { if ($attribute->name == $input->value) { return false; } } } return true; }, 'Attribute with this name already exists!'); $form->addSubmit('submit', 'Create attribute')->onClick[] = function (SubmitButton $button) { $values = $button->form->values; $miner = $this->findMinerWithCheckAccess($values->miner); $this->minersFacade->checkMinerMetasource($miner); $attribute = new Attribute(); $attribute->metasource = $miner->metasource; $attribute->datasourceColumn = $this->datasourcesFacade->findDatasourceColumn($miner->datasource, $values->column); $attribute->name = $values->attributeName; $attribute->type = $attribute->datasourceColumn->type; $attribute->preprocessing = $this->metaAttributesFacade->findPreprocessing($values->preprocessing); $attribute->active = false; $this->metasourcesFacade->saveAttribute($attribute); $metasourceTask = $this->metasourcesFacade->startAttributesPreprocessing($miner->metasource, [$attribute]); $this->redirect('preprocessingTask', ['id' => $metasourceTask->metasourceTaskId]); }; $storno = $form->addSubmit('storno', 'storno'); $storno->setValidationScope(array()); $storno->onClick[] = function (SubmitButton $button) use($presenter) { //přesměrování na výběr preprocessingu $values = $button->form->getValues(); $presenter->redirect('addAttribute', array('column' => $values->column, 'miner' => $values->miner)); }; return $form; }
/** * Akce pro vyhodnocení klasifikace * @SWG\Get( * tags={"Evaluation"}, * path="/evaluation/classification", * summary="Evaluate classification model", * produces={"application/json","application/xml"}, * security={{"apiKey":{}},{"apiKeyHeader":{}}}, * @SWG\Parameter( * name="scorer", * description="Scorer type", * required=true, * type="string", * in="query", * enum={"easyMinerScorer","modelTester"} * ), * @SWG\Parameter( * name="task", * description="Task ID", * required=false, * type="integer", * in="query" * ), * @SWG\Parameter( * name="ruleSet", * description="Rule set ID", * required=false, * type="integer", * in="query" * ), * @SWG\Parameter( * name="datasource", * description="Datasource ID (if not specified, task datasource will be used)", * required=false, * type="integer", * in="query" * ), * @SWG\Response( * response=200, * description="Evaluation result", * @SWG\Schema( * ref="#/definitions/ScoringResultResponse" * ) * ), * @SWG\Response( * response=400, * description="Invalid API key supplied", * @SWG\Schema(ref="#/definitions/StatusResponse") * ) * ) * * @throws BadRequestException * @throws NotImplementedException */ public function actionClassification() { $this->setXmlMapperElements('classification'); $inputData = $this->getInput()->getData(); /** @var IScorerDriver $scorerDriver */ if (empty($inputData['scorer'])) { $scorerDriver = $this->scorerDriverFactory->getDefaultScorerInstance(); } else { $scorerDriver = $this->scorerDriverFactory->getScorerInstance($inputData['scorer']); } if (!empty($inputData['datasource'])) { try { $datasource = $this->datasourcesFacade->findDatasource(@$inputData['datasource']); if (!$this->datasourcesFacade->checkDatasourceAccess($datasource, $this->getCurrentUser())) { throw new \Exception(); } } catch (\Exception $e) { throw new BadRequestException("Requested data source was not found!"); } } elseif (!empty($inputData['task'])) { $task = $this->findTaskWithCheckAccess($inputData['task']); $datasource = $task->miner->datasource; } else { throw new BadRequestException("Data source was not specified!"); } if (!empty($inputData['task'])) { if (empty($task)) { $task = $this->findTaskWithCheckAccess($inputData['task']); } $result = $scorerDriver->evaluateTask($task, $datasource)->getCorrectIncorrectDataArr(); $result['task'] = $task->getDataArr(false); } elseif (!empty($inputData['ruleSet'])) { $ruleSet = $this->ruleSetsFacade->findRuleSet($inputData['ruleSet']); //TODO kontrola oprávnění k rule setu $result = $scorerDriver->evaluateRuleSet($ruleSet, $datasource)->getDataArr(); $result['ruleSet'] = $ruleSet->getDataArr(); } else { throw new BadRequestException("No task or rule set found!"); } $this->resource = $result; $this->sendResource(); }
/** * @return Form */ public function createComponentUploadForm() { $form = new Form(); $form->setTranslator($this->translator); $form->addUpload('file', 'Upload file:')->setRequired('Je nutné vybrat soubor pro import!'); $dbTypes = $this->datasourcesFacade->getDbTypes(true); if (count($dbTypes) == 1) { reset($dbTypes); $form->addHidden('dbType', key($dbTypes)); } else { $form->addSelect('dbType', 'Database type:', $dbTypes)->setDefaultValue($this->datasourcesFacade->getPreferredDbType()); } //přidání submit tlačítek $form->addSubmit('submit', 'Configure upload...')->onClick[] = function () { //nepodporujeme upload bez javascriptové konfigurace $this->flashMessage('For file upload using UI, you have to enable the javascript code!', 'error'); $this->redirect('newMiner'); }; return $form; }
/** * Funkce pro kontrolu vstupů pro vytvoření nového mineru */ public function validateCreate() { $currentUser = $this->getCurrentUser(); /** @noinspection PhpMethodParametersCountMismatchInspection */ $this->input->field('name')->addRule(IValidator::REQUIRED, 'Name is required!'); /** @noinspection PhpMethodParametersCountMismatchInspection */ $this->input->field('type')->addRule(IValidator::REQUIRED, 'Miner type is required!'); /** @noinspection PhpMethodParametersCountMismatchInspection */ $this->input->field('datasourceId')->addRule(IValidator::REQUIRED, 'Datasource ID is required!')->addRule(IValidator::CALLBACK, 'Requested datasource was not found, or is not accessible!', function ($value) use($currentUser) { try { $this->datasource = $this->datasourcesFacade->findDatasource($value); if ($this->datasourcesFacade->checkDatasourceAccess($this->datasource, $currentUser)) { //kontrola dostupnosti kompatibilního mineru s vybraným datasource $availableMinerTypes = $this->minersFacade->getAvailableMinerTypes($this->datasource->type); return !empty($availableMinerTypes[$this->getInput()->getData()['type']]); } else { return false; } } catch (\Exception $e) { return false; } }); /** @noinspection PhpMethodParametersCountMismatchInspection */ $this->input->field('ruleSetId')->addRule(IValidator::CALLBACK, 'Requested rule set was not found, or is not accessible!', function ($value) use($currentUser) { if (empty($value)) { return true; } try { $this->ruleSet = $this->ruleSetsFacade->findRuleSet($value); $this->ruleSetsFacade->checkRuleSetAccess($this->ruleSet, $currentUser); return true; } catch (\Exception $e) { return false; } }); }
/** * Funkce pro aktualizaci info o atributech v DB * @param Metasource &$metasource * @param User $user */ public function updateMetasourceAttributes(Metasource &$metasource, User $user) { /** @var IPreprocessing $preprocessing */ $preprocessing = $this->preprocessingFactory->getPreprocessingInstance($metasource->getPpConnection(), $user); $ppDataset = $preprocessing->getPpDataset($metasource->ppDatasetId ? $metasource->ppDatasetId : $metasource->name); $datasource = $metasource->datasource; $metasource->size = $ppDataset->size; $ppAttributes = $preprocessing->getPpAttributes($ppDataset); #region připravení seznamu aktuálně existujících datasourceColumns /** @var Attribute[] $existingAttributesByPpDatasetAttributeId */ $existingAttributesByPpDatasetAttributeId = []; /** @var Attribute[] $existingAttributesByName */ $existingAttributesByName = []; /** @var Attribute[] $attributes */ $attributes = $metasource->attributes; if (!empty($attributes)) { foreach ($attributes as &$attribute) { if (!empty($attribute->ppDatasetAttributeId)) { $existingAttributesByPpDatasetAttributeId[$attribute->ppDatasetAttributeId] = $attribute; } else { $existingAttributesByName[$attribute->name] = $attribute; } } } #endregion #region aktualizace seznamu sloupců získaných z DB if (!empty($ppAttributes)) { foreach ($ppAttributes as $ppAttribute) { if (!empty($ppAttribute->id) && is_int($ppAttribute->id) && isset($existingAttributesByPpDatasetAttributeId[$ppAttribute->id])) { //sloupec s daným ID již je v databázi $attribute = $existingAttributesByPpDatasetAttributeId[$ppAttribute->id]; $modified = false; if ($attribute->name != $ppAttribute->name) { $attribute->name = $ppAttribute->name; $modified = true; } if (!$attribute->active) { $modified = true; $attribute->active = true; } if ($modified) { $this->saveAttribute($attribute); } unset($existingAttributesByPpDatasetAttributeId[$ppAttribute->id]); } elseif (!empty($ppAttribute->name) && isset($existingAttributesByName[$ppAttribute->name])) { //sloupec najdeme podle jména $attribute = $existingAttributesByName[$ppAttribute->name]; if (!empty($ppAttribute->id) && $attribute->ppDatasetAttributeId != $ppAttribute->id) { $attribute->ppDatasetAttributeId = $ppAttribute->id; $attribute->active = true; $this->saveAttribute($attribute); } elseif (!$attribute->active) { $attribute->active = true; $this->saveAttribute($attribute); } unset($existingAttributesByName[$ppAttribute->name]); } elseif (!empty($ppAttribute->field)) { //máme tu nový datový sloupec (který má svoji vazbu na datasource) $attribute = new Attribute(); $attribute->metasource = $metasource; try { $datasourceColumn = $this->datasourcesFacade->findDatasourceColumnByDbDatasourceColumnId($datasource, $ppAttribute->field); } catch (\Exception $e) { $datasourceColumn = null; } $attribute->datasourceColumn = $datasourceColumn; $attribute->name = $ppAttribute->name; if (is_int($ppAttribute->id)) { $attribute->ppDatasetAttributeId = $ppAttribute->id; } $attribute->active = true; $attribute->type = $ppAttribute->type; $this->saveAttribute($attribute); } } } #endregion #region deaktivace již neexistujících sloupců //TODO kontrola, jestli je není možné kompletně smazat (pokud ještě nebyly dovytvořeny v rámci preprocessingu) if (!empty($existingAttributesByPpDatasetAttributeId)) { foreach ($existingAttributesByPpDatasetAttributeId as &$attribute) { if ($attribute->active) { $attribute->active = false; $this->saveAttribute($attribute); } } } if (!empty($existingAttributesByName)) { foreach ($existingAttributesByName as &$attribute) { if ($attribute->active) { $attribute->active = false; $this->saveAttribute($attribute); } } } #endregion //aktualizace datového zdroje z DB $metasource = $this->findMetasource($metasource->metasourceId); #region vyčištění preprocessing úloh if (!empty($metasource->metasourceTasks)) { $attributesArr = $metasource->getAttributesArr(); if (!empty($attributesArr)) { foreach ($metasource->metasourceTasks as $metasourceTask) { if ($metasourceTask->type == MetasourceTask::TYPE_PREPROCESSING) { if (!empty($metasourceTask->attributes)) { $finished = true; foreach ($metasourceTask->attributes as $taskAttribute) { if (!$taskAttribute->active) { $finished = false; } } if ($finished) { $this->metasourceTasksRepository->delete($metasourceTask); } } } } } } #endregion }