Integrated Contractconfig Hooks in Contractconfig/Save with restore on

error
This commit is contained in:
Frank Schubert
2023-03-21 22:04:57 +01:00
parent a27d7a7418
commit 61e84f085d
14 changed files with 5956 additions and 86 deletions

View File

@@ -1,6 +1,7 @@
<?php
class ContractconfigController extends mfBaseController {
public $hook_errors;
protected function init() {
$this->needlogin=true;
@@ -68,13 +69,24 @@ class ContractconfigController extends mfBaseController {
$error_items = [];
$old_values = [];
foreach($r->itemvalues as $item_id => $itemvalue) {
//var_dump($item_id, $itemvalue); continue;
$item = new ContractconfigItem($item_id);
if(!$item->id) {
$this->log->warn("Tried to save non-existant ContractconfigItem $item_id");
continue;
}
$item->setContractId($contract_id);
/*if(!array_key_exists($item->name, $old_values)) {
$old_values[$item->name] = [];
}*/
$old_values[$item->name] = $item->getValue();
if(!$item->value->set($itemvalue)) {
$error_items[$item->id] = $item->name;
continue;
@@ -85,6 +97,7 @@ class ContractconfigController extends mfBaseController {
return $this->editAction();
}
}
//exit;
if(count($error_items)) {
$this->layout()->set("error_items", array_keys($error_items));
@@ -94,12 +107,74 @@ class ContractconfigController extends mfBaseController {
}
// run custom productgroup hooks
if(!$this->runAfterSaveHooks($contract)) {
$errors = [];
foreach($this->hook_errors as $item_name => $item_errors) {
if(is_array($item_errors) && count($item_errors)) {
foreach($item_errors as $error_string) {
$errors[] = "[$item_name] $error_string";
}
//var_dump($old_values[$item_name]);
// on error restore old values
if(array_key_exists($item_name, $old_values)) {
$old_item = ContractconfigItemModel::getFirst(["name" => $item_name]);
$old_item->setContractId($contract_id);
$old_item->value->set($old_values[$item_name]);
$old_item->value->save();
//var_dump($old_item->value->json);exit;
}
}
}
//var_dump($errors);exit;
$this->layout()->setFlash(implode("<br />", $errors), "error");
$this->redirect("Contract", "view", ['id' => $contract_id]);
}
$this->layout()->setFlash("Konfiguration gespeichert", "success");
$this->redirect("Contract", "view", ['id' => $contract_id]);
}
private function runAfterSaveHooks(Contract $contract) {
if(!$contract || !$contract->id) {
return false;
}
$folderpath = APPDIR."/Contractconfig/hooks/";
$dir = opendir($folderpath);
while($filename = readdir($dir)) {
if(substr($filename, 0, 1) == ".") {
continue;
}
if($filename == "Contractconfig_Hook.php") continue;
if(substr($filename, -4) != ".php") continue;
$hook_type = basename($filename, ".php");
$classname = "Contractconfig_Hook_$hook_type";
$hook_class_filename = $folderpath.$filename;
require_once $hook_class_filename;
if(!class_exists($classname)) {
continue;
}
$hook = new $classname($contract);
if($hook->isResponsible()) {
$this->log->debug("Running {$classname}->afterSave() for Contract id ".$contract->id);
$hook->afterSave();
if($hook->errors) {
$this->hook_errors = $hook->errors;
return false;
}
}
}
return true;
}
}

View File

@@ -1,6 +1,8 @@
<?php
abstract class Contractconfig_Hook {
protected $log;
protected $required_product_attributes = [];
protected $contract;
protected $items;
@@ -22,6 +24,8 @@ abstract class Contractconfig_Hook {
public function __construct(Contract $contract) {
$this->log = mfLoghandler::singleton();
$this->contract = $contract;
if($contract->product) {

View File

@@ -1,10 +1,12 @@
<?php
require_once __DIR__."/Contractconfig_Hook.php";
class Contractconfig_Hook_Voicenumberblock extends Contractconfig_Hook {
protected $required_product_attributes = ["needs_number"];
private $voip_routing;
private $create_numbers = [];
/*
* Checks to determine if class needs to work on contract.
*/
@@ -24,6 +26,9 @@ class Contractconfig_Hook_Voicenumberblock extends Contractconfig_Hook {
}
public function init() {
$this->errors["voicenumberblock_voicenumber"] = [];
// get voip routing for number
if(is_array($this->contract->configvalues)) {
// look in contract config
@@ -39,78 +44,117 @@ class Contractconfig_Hook_Voicenumberblock extends Contractconfig_Hook {
}
public function beforeSave() {
return $this->checkNewNumbers();
}
public function afterSave() {
// check if number was saved
if(!array_key_exists("voicenumber", $this->configitems)) {
echo "configitem voicenumber does not exists\n";
return true;
}
echo "configitem voicenumber exists\n";
$item = $this->configitems['voicenumber'];
$number = $item->value->string;
if(!$number) {
echo "Keine nummer gespeichert\n";
return true;
}
echo "Nummer: $number\n";
$this->checkNewNumbers();
// check if Voicenumber exists
$voicenumberblock = Voicenumberblock::findBlock($number);
if(!$voicenumberblock) {
$this->errors[] = "Ungültige Rufnummer: Kein aktiver Rufnummernblock gefunden";
echo "Voicenumberblock für $number nicht gefunden\n";
}
if(!$voicenumberblock->isNumberInBlock($number)) {
$this->errors[] = "Ungültige Rufnummer: Bitte Rufnummernlänge kontrollieren! Block erlaubt ".$voicenumberblock->first ." bis ".$voicenumberblock->last;
echo "Voicenumber $number not in Block ".$voicenumberblock->prefix."\n";
if(count($this->errors["voicenumberblock_voicenumber"])) {
return false;
}
$voicenumber = VoicenumberModel::getFirst(['number' => $number]);
if($voicenumber) {
// check if number belongs to another contract
if($voicenumber->contract_id) {
if($voicenumber->contract_id == $this->contract->id) {
// belongs to our contract already => no changes needed
return true;
foreach($this->create_numbers as $voicenumberblock_id => $numbers) {
foreach($numbers as $number){
$voicenumber = VoicenumberModel::getFirst(['number' => $number]);
if(!$voicenumber) {
$this->log->debug("creating voicenumber $number in block ".$voicenumberblock->prefix);
$voicenumber = VoicenumberModel::create([
'voicenumberblock_id' => $voicenumberblock_id,
"contract_id" => $this->contract->id,
'active' => 1,
'activated_date' => date('U'),
'routing' => $this->voip_routing,
'number' => $number,
'disabled' => 0
]);
if(!$voicenumber->save()) {
$this->errors["voicenumberblock_voicenumber"][] = "Error saving new number $number";
}
}
$this->errors[] = "Ungültige Rufnummer: Rufnummer gehört zu bestehendem contract ".$voicenumber->contract_id;
return false;
}
// check if number is locked
if($voicenumber->disabled) {
$this->errors[] = "Ungültige Rufnummer: Rufnummer ist gesperrt ".$voicenumber->contract_id;
return false;
}
// check if number was ported out
if($voicenumber->ported_out) {
$this->errors[] = "Ungültige Rufnummer: Rufnummer wurde rausportiert ".$voicenumber->contract_id;
return false;
}
} else {
echo "creating voicenumber $number in block ".$voicenumberblock->prefix."\n";
$voicenumber = VoicenumberModel::create([
'voicenumberblock_id' => $voicenumberblock->id,
"contract_id" => $this->contract->id,
'active' => 1,
'activated_date' => date('U'),
'routing' => $this->voip_routing,
'number' => $number,
'disabled' => 0
]);
if(!$voicenumber->save()) {
echo "Error saving new number\n";
}
}
if(count($this->errors["voicenumberblock_voicenumber"])) {
return false;
}
return true;
}
/*
* TODO: Check if contract was canceled, then set lock and lock_reason to reserved
*/
public function checkNewNumbers() {
$this->log->debug(":: In Contractconfig_Hook_Voicenumberblock->afterSave()");
// check if number was saved
if(!array_key_exists("voicenumber", $this->configitems)) {
$this->log->debug("configitem voicenumber does not exists");
return true;
}
$item = $this->configitems['voicenumber'];
//var_dump($item);exit;
if($item->value->json) {
$numbers = json_decode($item->value->json);
}
if(!is_array($numbers) || !count($numbers)) {
return true;
}
foreach($numbers as $number) {
if(!$number) {
$this->log->debug("Keine nummer gespeichert");
continue;
}
$this->log->debug("Nummer: $number");
// check if Voicenumber exists
$voicenumberblock = Voicenumberblock::findBlock($number);
if(!$voicenumberblock) {
$this->errors["voicenumberblock_voicenumber"][] = "Ungültige Rufnummer $number: Kein aktiver Rufnummernblock gefunden";
continue;
}
if(!$voicenumberblock->isNumberInBlock($number)) {
$this->errors["voicenumberblock_voicenumber"][] = "Ungültige Rufnummer $number: Bitte Rufnummernlänge kontrollieren! Block erlaubt ".$voicenumberblock->first ." bis ".$voicenumberblock->last;
continue;
}
$voicenumber = VoicenumberModel::getFirst(['number' => $number]);
if($voicenumber) {
// check if number belongs to another contract
if($voicenumber->contract_id) {
if($voicenumber->contract_id == $this->contract->id) {
// belongs to our contract already => no changes needed
continue;
}
$this->errors["voicenumberblock_voicenumber"][] = "Ungültige Rufnummer $number: Rufnummer gehört zu bestehendem contract ".$voicenumber->contract_id;
continue;
}
// check if number is locked
if($voicenumber->disabled) {
$this->errors["voicenumberblock_voicenumber"][] = "Ungültige Rufnummer $number: Rufnummer ist gesperrt ".$voicenumber->contract_id;
continue;
}
// check if number was ported out
if($voicenumber->ported_out) {
$this->errors["voicenumberblock_voicenumber"][] = "Ungültige Rufnummer $number: Rufnummer wurde rausportiert ".$voicenumber->contract_id;
continue;
}
} else {
if(!array_key_exists($voicenumberblock->id, $this->create_numbers)) {
$this->create_numbers[$voicenumberblock->id] = [];
}
$this->create_numbers[$voicenumberblock->id][] = $number;
}
}
if(count($this->errors["voicenumberblock_voicenumber"])) {
return false;
}
return true;
}