/** * Akce vracející pravidla pro vykreslení v easymineru * @param int $id * @param int $miner * @param string $task * @param string $rule * @throws BadRequestException * @throws ForbiddenRequestException */ public function renderRuleDetails($id = null, $miner, $rule) { $rule = $this->rulesFacade->findRule($rule); //kontrola přístupů $task = $rule->task; $minerId = $miner; $miner = $task->miner; if ($miner->minerId != $minerId || $task->taskId != $id) { throw new ForbiddenRequestException($this->translator->translate('You are not authorized to access selected data!')); } $this->checkMinerAccess($miner); $this->template->rule = $rule; }
/** * Akce pro odebrání celého obsahu rule clipboard z konkrétního rulesetu * @param int $id * @param int $miner * @param int $ruleset * @param string $returnRules ='' - IDčka oddělená čárkami, případně jedno ID * @throws ForbiddenRequestException * @throws BadRequestException */ public function actionRemoveRulesFromRuleSet($id = null, $miner, $ruleset, $returnRules = '') { //načtení dané úlohy a zkontrolování přístupu k mineru $task = $this->tasksFacade->findTask($id); $this->checkMinerAccess($task->miner); $ruleIdsArr = explode(',', str_replace(';', ',', $returnRules)); //najití RuleSetu a kontroly $ruleSet = $this->ruleSetsFacade->findRuleSet($ruleset); $this->ruleSetsFacade->checkRuleSetAccess($ruleSet, $this->user->id); //přidání pravidel $this->ruleSetsFacade->removeAllRuleClipboardRulesFromRuleSet($task, $ruleSet); $result = array(); if (count($ruleIdsArr) > 0) { foreach ($ruleIdsArr as $ruleId) { try { $rule = $this->rulesFacade->findRule($ruleId); //TODO optimalizovat kontroly... $ruleTask = $rule->task; if ($ruleTask->taskId != $task->taskId) { throw new InvalidArgumentException(); } if ($ruleTask->miner->minerId != $miner) { throw new InvalidArgumentException(); } $result[$rule->ruleId] = $rule->getBasicDataArr(); } catch (\Exception $e) { continue; } } } $this->sendJsonResponse(array('rules' => $result)); }
/** * Funkce připravující pole s informacemi o vybraných pravidlech pro vrácení v rámci JSON odpovědi * @param int[] $ruleIdsArr * @param RuleSet|int $ruleSet * @return array */ private function prepareRulesResult($ruleIdsArr, $ruleSet = null) { $result = []; if (!empty($ruleIdsArr)) { foreach ($ruleIdsArr as $ruleId) { if (!$ruleId) { continue; } try { $rule = $this->rulesFacade->findRule($ruleId); $result[$rule->ruleId] = $rule->getBasicDataArr(); if (!empty($ruleSet)) { $relation = $rule->getRuleSetRelation($ruleSet); if (!empty($relation)) { $result[$rule->ruleId]['ruleSetRelation'] = $relation->relation; } else { $result[$rule->ruleId]['ruleSetRelation'] = ''; } } } catch (\Exception $e) { continue; } } } return $result; }
/** * Funkce pro kontrolu, jestli je zvolená úloha obsažená v Rule Clipboard * @param Task $task */ public function checkTaskInRuleClipoard(Task &$task) { $rulesCount = $this->rulesFacade->getRulesCountByTask($task, true); if ($rulesCount != $task->rulesInRuleClipboardCount) { $task->rulesInRuleClipboardCount = $rulesCount; $this->saveTask($task); } }
/** * Funkce pro nalezení pravidla dle zadaného ID a kontrolu oprávnění aktuálního uživatele pracovat s daným pravidlem * @param int $ruleId * @return RuleSet * @throws \Nette\Application\BadRequestException */ private function findRuleWithCheckAccess($ruleId) { try { /** @var Rule $rule */ $rule = $this->rulesFacade->findRule($ruleId); } catch (EntityNotFoundException $e) { $this->error('Requested rule was not found.'); return null; } //TODO kontrola oprávnění return $rule; }
/** * Funkce pro odebrání všech pravidel z RuleClipboard konkrétní úlohy z RuleSetu * @param $task * @param $ruleSet */ public function removeAllRuleClipboardRulesFromRuleSet($task, $ruleSet) { if (!$ruleSet instanceof RuleSet) { $ruleSet = $this->findRuleSet($ruleSet); } $rules = $this->rulesFacade->findRulesByTask($task, null, null, null, true); if (!empty($rules)) { foreach ($rules as $rule) { $this->removeRuleFromRuleSet($rule, $ruleSet); } } $this->updateRuleSetRulesCount($ruleSet); }
/** * Akce vracející pravidla pro vykreslení v easymineru * @param int $id * @param $offset * @param $limit * @param $order * @throws BadRequestException * @throws ForbiddenRequestException */ public function actionGetRules($id, $offset = 0, $limit = 25, $order = 'rule_id') { if ($order == '') { $order = 'rule_id'; } //nalezení daného mineru a kontrola oprávnění uživatele pro přístup k němu $task = $this->tasksFacade->findTask($id); $miner = $task->miner; $this->checkMinerAccess($miner); $rules = $this->rulesFacade->findRulesByTask($task, $order, $offset, $limit); $rulesArr = array(); if (!empty($rules)) { foreach ($rules as $rule) { $rulesArr[$rule->ruleId] = $rule->getBasicDataArr(); } } $this->sendJsonResponse(array('task' => array('name' => $task->name, 'rulesCount' => $task->rulesCount, 'IMs' => $task->getInterestMeasures(), 'state' => $task->state, 'importState' => $task->importState), 'rules' => $rulesArr)); }
/** * Akce pro odebrání pravidel z rulesetu * @param int $id * @param int|string $rules * @throws \Nette\Application\BadRequestException * @SWG\Delete( * tags={"RuleSets"}, * path="/rule-sets/{id}/rules", * summary="Remove rules from the selected rule set", * security={{"apiKey":{}},{"apiKeyHeader":{}}}, * produces={"application/json","application/xml"}, * @SWG\Parameter( * name="id", * description="RuleSet ID", * required=true, * type="integer", * in="path" * ), * @SWG\Parameter( * name="rules", * description="IDs of rules (optinally multiple - separated with , or ;)", * required=true, * type="array", * @SWG\items( * type="integer" * ), * collectionFormat="csv", * in="query" * ), * @SWG\Response( * response=200, * description="Rules have been removed from the rule set.", * @SWG\Schema(ref="#/definitions/StatusResponse"),examples={"code":200,"status":"OK"} * ), * @SWG\Response(response=404, description="Requested rule set was not found.") * ) */ public function actionDeleteRules($id, $rules) { /** @var RuleSet $ruleSet */ $ruleSet = $this->findRuleSetWithCheckAccess($id); /** @var int[] $ruleIdsArr */ $ruleIdsArr = explode(',', str_replace(';', ',', $rules)); if (!empty($ruleIdsArr)) { foreach ($ruleIdsArr as $ruleId) { if (!$ruleId) { continue; } try { $rule = $this->rulesFacade->findRule($ruleId); $this->ruleSetsFacade->removeRuleFromRuleSet($rule, $ruleSet); } catch (\Exception $e) { continue; } } } $this->ruleSetsFacade->updateRuleSetRulesCount($ruleSet); $this->resource = ['code' => 200, 'status' => 'ok']; $this->sendResource(); }
/** * Funkce pro načtení PMML * @param string $pmml * @return bool */ public function parseRulesPMML($pmml) { $xml = simplexml_load_string($pmml); $xml->registerXPathNamespace('guha', 'http://keg.vse.cz/ns/GUHA0.1rev1'); $guhaAssociationModel = $xml->xpath('//guha:AssociationModel'); $guhaAssociationModel = $guhaAssociationModel[0]; /** @var \SimpleXMLElement $associationRulesXml */ $associationRulesXml = $guhaAssociationModel->AssociationRules; if (count($associationRulesXml->AssociationRule) == 0) { return true; } //pokud nejsou vrácena žádná pravidla, nemá smysl zpracovávat cedenty... #region zpracování cedentů jen s jedním subcedentem $dbaItems = $associationRulesXml->xpath('./DBA[count(./BARef)=1]'); $alternativeCedentIdsArr = array(); if (!empty($dbaItems)) { foreach ($dbaItems as $dbaItem) { $idStr = (string) $dbaItem['id']; $BARefStr = (string) $dbaItem->BARef; $alternativeCedentIdsArr[$idStr] = isset($alternativeCedentIdsArr[$BARefStr]) ? $alternativeCedentIdsArr[$BARefStr] : $BARefStr; } } if (!empty($alternativeCedentIdsArr)) { $repeat = true; while ($repeat) { $repeat = false; foreach ($alternativeCedentIdsArr as $id => $referencedId) { if (isset($alternativeCedentIdsArr[$referencedId])) { $alternativeCedentIdsArr[$id] = $alternativeCedentIdsArr[$referencedId]; $repeat = true; } } } } #endregion /** @var Cedent[] $cedentsArr */ $cedentsArr = array(); /** @var RuleAttribute[] $ruleAttributesArr */ $ruleAttributesArr = array(); $unprocessedIdsArr = array(); #region zpracování rule attributes $bbaItems = $associationRulesXml->xpath('//BBA'); if (!empty($bbaItems)) { foreach ($bbaItems as $bbaItem) { $ruleAttribute = new RuleAttribute(); //FIXME IMPORTANT změna ukládání ruleAttributes //FIXME IMPORTANT podpora většího množství hodnot v rule attribute $idStr = (string) $bbaItem['id']; $ruleAttribute->field = (string) $bbaItem->FieldRef; $ruleAttribute->value = (string) $bbaItem->CatRef; $ruleAttributesArr[$idStr] = $ruleAttribute; $this->rulesFacade->saveRuleAttribute($ruleAttribute); } } //pročištění pole s alternativními IDčky if (!empty($alternativeCedentIdsArr)) { foreach ($alternativeCedentIdsArr as $id => $alternativeId) { if (isset($ruleAttributesArr[$alternativeId])) { unset($alternativeCedentIdsArr[$id]); } } } #endregion #region zpracování cedentů s více subcedenty/hodnotami $dbaItems = $associationRulesXml->xpath('./DBA[count(./BARef)>0]'); if (!empty($dbaItems)) { do { foreach ($dbaItems as $dbaItem) { $idStr = (string) $dbaItem['id']; if (isset($cedentsArr[$idStr])) { continue; } if (isset($alternativeCedentIdsArr[$idStr])) { continue; } if (isset($ruleAttributesArr[$idStr])) { continue; } $process = true; foreach ($dbaItem->BARef as $BARef) { $BARefStr = (string) $BARef; if (isset($alternativeCedentIdsArr[$BARefStr])) { $BARefStr = $alternativeCedentIdsArr[$BARefStr]; } if (!isset($cedentsArr[$BARefStr]) && !isset($ruleAttributesArr[$BARefStr])) { $unprocessedIdsArr[$BARefStr] = $BARefStr; $process = false; } } if ($process) { unset($unprocessedIdsArr[$idStr]); //vytvoření konkrétního cedentu... $cedent = new Cedent(); if (isset($dbaItem['connective'])) { $cedent->connective = Strings::lower((string) $dbaItem['connective']); } else { $cedent->connective = 'conjunction'; } $this->rulesFacade->saveCedent($cedent); $cedentsArr[$idStr] = $cedent; foreach ($dbaItem->BARef as $BARef) { $BARefStr = (string) $BARef; if (isset($alternativeCedentIdsArr[$BARefStr])) { $BARefStr = $alternativeCedentIdsArr[$BARefStr]; } if (isset($cedentsArr[$BARefStr])) { $cedent->addToCedents($cedentsArr[$BARefStr]); } elseif (isset($ruleAttributesArr[$BARefStr])) { $cedent->addToRuleAttributes($ruleAttributesArr[$BARefStr]); } } $this->rulesFacade->saveCedent($cedent); } else { $unprocessedIdsArr[$idStr] = $idStr; } } } while (!empty($unprocessedIdsArr)); } #endregion foreach ($associationRulesXml->AssociationRule as $associationRule) { $rule = new Rule(); $rule->task = $this->task; if (isset($associationRule['antecedent'])) { //jde o pravidlo s antecedentem $antecedentId = (string) $associationRule['antecedent']; if (isset($alternativeCedentIdsArr[$antecedentId])) { $antecedentId = $alternativeCedentIdsArr[$antecedentId]; } $rule->antecedent = $cedentsArr[$antecedentId]; } else { //jde o pravidlo bez antecedentu $rule->antecedent = null; } $consequentId = (string) $associationRule['consequent']; if (isset($alternativeCedentIdsArr[$consequentId])) { $consequentId = $alternativeCedentIdsArr[$consequentId]; } $rule->consequent = $cedentsArr[$consequentId]; $rule->text = (string) $associationRule->Text; $fourFtTable = $associationRule->FourFtTable; $rule->a = (string) $fourFtTable['a']; $rule->b = (string) $fourFtTable['b']; $rule->c = (string) $fourFtTable['c']; $rule->d = (string) $fourFtTable['d']; $this->rulesFacade->saveRule($rule); } $this->rulesFacade->calculateMissingInterestMeasures(); return true; }
/** * Funkce pro načtení PMML * @param string|\SimpleXMLElement $pmml * @param int &$rulesCount = null - informace o počtu importovaných pravidel * @param bool $updateImportedRulesHeads=false * @return bool * @throws \Exception */ public function fullParseRulesPMML($pmml, &$rulesCount = null, $updateImportedRulesHeads = false) { Debugger::log('fullParseRulesPMML start ' . time(), ILogger::DEBUG); if ($pmml instanceof \SimpleXMLElement) { $xml = $pmml; } else { $xml = simplexml_load_string($pmml); } $xml->registerXPathNamespace('guha', 'http://keg.vse.cz/ns/GUHA0.1rev1'); $guhaAssociationModel = $xml->xpath('//guha:AssociationModel'); $guhaAssociationModel = $guhaAssociationModel[0]; $rulesCount = (string) $guhaAssociationModel['numberOfRules']; /** @var \SimpleXMLElement $associationRulesXml */ $associationRulesXml = $guhaAssociationModel->AssociationRules; if (count($associationRulesXml->AssociationRule) == 0) { return true; } //pokud nejsou vrácena žádná pravidla, nemá smysl zpracovávat cedenty... #region zpracování cedentů jen s jedním subcedentem $dbaItems = $associationRulesXml->xpath('./DBA[count(./BARef)=1]'); $alternativeCedentIdsArr = array(); if (!empty($dbaItems)) { foreach ($dbaItems as $dbaItem) { $idStr = (string) $dbaItem['id']; $BARefStr = (string) $dbaItem->BARef; $alternativeCedentIdsArr[$idStr] = isset($alternativeCedentIdsArr[$BARefStr]) ? $alternativeCedentIdsArr[$BARefStr] : $BARefStr; } } if (!empty($alternativeCedentIdsArr)) { do { $repeat = false; foreach ($alternativeCedentIdsArr as $id => $referencedId) { if (isset($alternativeCedentIdsArr[$referencedId])) { $alternativeCedentIdsArr[$id] = $alternativeCedentIdsArr[$referencedId]; $repeat = true; } } } while ($repeat); } #endregion /** @var Cedent[] $cedentsArr */ $cedentsArr = []; /** @var RuleAttribute[] $ruleAttributesArr */ $ruleAttributesArr = []; /** @var string[] $unprocessedIdsArr */ $unprocessedIdsArr = []; /** @var ValuesBin[]|Value[] $valuesBinsArr */ $valuesBinsArr = []; /** @var Attribute[] $attributesArr - pole indexované pomocí názvů atributů použitých v PMML */ $attributesArr = $this->miner->metasource->getAttributesByNamesArr(); #region zpracování rule attributes $bbaItems = $associationRulesXml->xpath('//BBA'); if (!empty($bbaItems)) { foreach ($bbaItems as $bbaItem) { $ruleAttribute = new RuleAttribute(); $idStr = (string) $bbaItem['id']; //uložení vazby na Attribute $attributeName = (string) $bbaItem->FieldRef; $valueName = (string) $bbaItem->CatRef; $attribute = $attributesArr[$attributeName]; $ruleAttribute->attribute = $attribute; $valueItem = $attribute->preprocessing->findValue($valueName); if ($valueItem instanceof Value) { $ruleAttribute->value = $valueItem; } elseif ($valueItem instanceof ValuesBin) { $ruleAttribute->valuesBin = $valueItem; } elseif ($attribute->preprocessing->specialType == Preprocessing::SPECIALTYPE_EACHONE) { //pokud jde o preprocessing each-one a nebyla nalezena příslušná hodnota v DB, tak ji uložíme $value = new Value(); $value->format = $attribute->preprocessing->format; $value->value = $valueName; $this->metaAttributesFacade->saveValue($value); $ruleAttribute->value = $value; } $this->rulesFacade->saveRuleAttribute($ruleAttribute); $ruleAttributesArr[$idStr] = $ruleAttribute; } } //pročištění pole s alternativními IDčky if (!empty($alternativeCedentIdsArr)) { foreach ($alternativeCedentIdsArr as $id => $alternativeId) { if (isset($ruleAttributesArr[$alternativeId])) { unset($alternativeCedentIdsArr[$id]); } } } #endregion #region zpracování cedentů s více subcedenty/hodnotami $dbaItems = $associationRulesXml->xpath('./DBA[count(./BARef)>0]'); if (!empty($dbaItems)) { do { foreach ($dbaItems as $dbaItem) { $idStr = (string) $dbaItem['id']; if (isset($cedentsArr[$idStr])) { continue; } if (isset($alternativeCedentIdsArr[$idStr])) { continue; } if (isset($ruleAttributesArr[$idStr])) { continue; } $process = true; foreach ($dbaItem->BARef as $BARef) { $BARefStr = (string) $BARef; if (isset($alternativeCedentIdsArr[$BARefStr])) { $BARefStr = $alternativeCedentIdsArr[$BARefStr]; } if (!isset($cedentsArr[$BARefStr]) && !isset($ruleAttributesArr[$BARefStr])) { $unprocessedIdsArr[$BARefStr] = $BARefStr; $process = false; } } if ($process) { unset($unprocessedIdsArr[$idStr]); //vytvoření konkrétního cedentu... $cedent = new Cedent(); if (isset($dbaItem['connective'])) { $cedent->connective = Strings::lower((string) $dbaItem['connective']); } else { $cedent->connective = 'conjunction'; } $this->rulesFacade->saveCedent($cedent); $cedentsArr[$idStr] = $cedent; foreach ($dbaItem->BARef as $BARef) { $BARefStr = (string) $BARef; if (isset($alternativeCedentIdsArr[$BARefStr])) { $BARefStr = $alternativeCedentIdsArr[$BARefStr]; } if (isset($cedentsArr[$BARefStr])) { $cedent->addToCedents($cedentsArr[$BARefStr]); } elseif (isset($ruleAttributesArr[$BARefStr])) { $cedent->addToRuleAttributes($ruleAttributesArr[$BARefStr]); } } $this->rulesFacade->saveCedent($cedent); } else { $unprocessedIdsArr[$idStr] = $idStr; } } } while (!empty($unprocessedIdsArr)); } #endregion #region association rules /** @var Cedent[] $topCedentsArr - pole s cedenty na vrcholné úrovni (pokud je ruleAttribute přímo na vrcholné úrovni, musí být zabalen v cedentu)*/ $topCedentsArr = array(); foreach ($associationRulesXml->AssociationRule as $associationRule) { $rule = false; if ($updateImportedRulesHeads) { try { $rule = $this->rulesFacade->findRuleByPmmlImportId($this->task->taskId, (string) $associationRule['id']); } catch (\Exception $e) { /*ignore*/ } } if (!$rule) { $rule = new Rule(); } $rule->task = $this->task; #region antecedent if (isset($associationRule['antecedent'])) { //jde o pravidlo s antecedentem $antecedentId = (string) $associationRule['antecedent']; if (isset($alternativeCedentIdsArr[$antecedentId])) { $antecedentId = $alternativeCedentIdsArr[$antecedentId]; } if (isset($cedentsArr[$antecedentId])) { $rule->antecedent = $cedentsArr[$antecedentId]; } else { if (isset($ruleAttributesArr[$antecedentId])) { if (!isset($topCedentsArr[$antecedentId])) { $cedent = new Cedent(); $cedent->connective = 'conjunction'; $this->rulesFacade->saveCedent($cedent); $topCedentsArr[$antecedentId] = $cedent; $cedent->addToRuleAttributes($ruleAttributesArr[$antecedentId]); $this->rulesFacade->saveCedent($cedent); } $rule->antecedent = $topCedentsArr[$antecedentId]; } else { throw new \Exception('Import failed!'); } } } else { //jde o pravidlo bez antecedentu $rule->antecedent = null; } #endregion antecedent #region consequent $consequentId = (string) $associationRule['consequent']; if (isset($alternativeCedentIdsArr[$consequentId])) { $consequentId = $alternativeCedentIdsArr[$consequentId]; } if (isset($cedentsArr[$consequentId])) { $rule->consequent = $cedentsArr[$consequentId]; } else { if (isset($ruleAttributesArr[$consequentId])) { if (!isset($topCedentsArr[$consequentId])) { $cedent = new Cedent(); $cedent->connective = 'conjunction'; $this->rulesFacade->saveCedent($cedent); $topCedentsArr[$consequentId] = $cedent; $cedent->addToRuleAttributes($ruleAttributesArr[$consequentId]); $this->rulesFacade->saveCedent($cedent); } $rule->consequent = $topCedentsArr[$consequentId]; } else { throw new \Exception('Import failed!'); } } #endregion consequent $rule->text = (string) $associationRule->Text; $fourFtTable = $associationRule->FourFtTable; $rule->a = (string) $fourFtTable['a']; $rule->b = (string) $fourFtTable['b']; $rule->c = (string) $fourFtTable['c']; $rule->d = (string) $fourFtTable['d']; $this->rulesFacade->saveRule($rule); } $this->rulesFacade->calculateMissingInterestMeasures($this->task); #endregion association rules Debugger::log('fullParseRulesPMML end ' . time(), ILogger::DEBUG); return true; }