diff --git a/Layout/default/menu.php b/Layout/default/menu.php index c203637f3..f8aba54e9 100644 --- a/Layout/default/menu.php +++ b/Layout/default/menu.php @@ -99,7 +99,8 @@ Telefonie
diff --git a/bin/rimo-websocket-client-daemon.php b/bin/rimo-websocket-client-daemon.php new file mode 100755 index 000000000..e9428c702 --- /dev/null +++ b/bin/rimo-websocket-client-daemon.php @@ -0,0 +1,175 @@ +#!/usr/bin/php + + * @version 2016-08-28 + */ + +if (PHP_SAPI !== 'cli') { + die("This program can only be run on the command line.\n"); +} + +fclose(STDIN); +fclose(STDOUT); +fclose(STDERR); + +$STDIN = fopen('/dev/null', 'r'); +$STDOUT = fopen('/dev/null', 'w'); +$STDERR = fopen('/dev/null', 'w'); + + +define('mfUI',"cli"); +define('FRONKDB_SQLDEBUG',false); + +/* Set default Timezone and error reporting */ +ini_set("date.timezone","Europe/Vienna"); +error_reporting(E_ALL & ~(E_NOTICE | E_STRICT | E_DEPRECATED)); + +define("LOGFILENAME",realpath(dirname(__FILE__)."/../var/log/")."/rimo-websocket-client.log"); + +$configfilepath = realpath(dirname(__FILE__)."/../config/config.php"); +if(file_exists($configfilepath)) { + require($configfilepath); +} else { + die("CANNOT FIND CONFIGFILE!\n\nThis is a serious error. You should not run your mvcfronk application without a configfile. Not proceeding."); +} + +if(defined('MFLOCALE_TIME')) { + setlocale(LC_TIME, MFLOCALE_TIME); +} +if(defined('MFLOCALE_MONETARY')) { + setlocale(LC_MONETARY, MFLOCALE_MONETARY); +} +if(defined('MFLOCALE_NUMERIC')) { + setlocale(LC_NUMERIC, MFLOCALE_NUMERIC); +} + +$request=array(); + +// Put commandline arguments into $request +if(count($argv)) { + $args=$argv; + array_shift($args); // shift scriptname off of args array + foreach($args as $i => $arg) { + if(preg_match('/^--(.+)/',$arg,$m)) { + if(isset($args[$i+1]) && !preg_match('/^-/',$args[$i+1])) { + $request[$m[1]] = $args[$i+1]; + } else { + $request[$m[1]] = true; + } + } elseif(preg_match('/^-([a-zA-Z])(.+)/', $arg, $m)) { + $request[$m[1]] = $m[2]; + } elseif(preg_match('/^-([^-])/', $arg, $m)) { + if(isset($args[$i+1]) && !preg_match('/^-/',$args[$i+1])) { + $request[$m[1]] = $args[$i + 1]; + } else { + $request[$m[1]] = true; + } + } + } +} + +$is_daemon = false; + +if($request['d'] || $request['daemonize']) { + if(pcntl_fork() !== 0) { + exit; + } + $is_daemon = true; +} + +require_once(LIBDIR."/mvcfronk/mfRouter/mfRouter.php"); +$log = mfLoghandler::singleton(); + +cli_set_process_title("thetool-rimo-client"); +pcntl_async_signals(true); +pcntl_signal(SIGTERM, 'signalHandler'); + +if(!defined("RIMO_CLIENT_MAX_FORK")) define("RIMO_CLIENT_MAX_FORK", 2); + +$forkcount = 0; +$continue = true; +$childpid = false; + +while($continue) { + + $log->debug("Starting new child."); + $pid = pcntl_fork(); + + if ($pid === -1) { + $log->debug("error forking"); + } elseif ($pid > 0) { + // in parent + $forkcount++; + $childpid = $pid; + $status = false; + while(!pcntl_waitpid($pid,$status, WNOHANG)) { + sleep(1); + } + $log->debug("child returned"); + if(RIMO_CLIENT_MAX_FORK && $forkcount > RIMO_CLIENT_MAX_FORK) { + // exit daemon, have systemd restart it + exit(1); + } + // wait RIMO_CLIENT_SLEEP_SEC seconds before next run + sleep(RIMO_API_WS_SLEEP_SEC); + } else { + // in child + $mypid = getmypid(); + + try { + // open rimo websocket connection and process events + //$continue = false; // don't fork again after child is done + $ws_timeout = 3600; + $ws = new WebSocket\Client(RIMO_API_WS_URL, ["timeout" => $ws_timeout]); + + $i = 0; + while(1) { + if($i == 0) { + $ws->text("[$mypid] Hello into Websocket!"); + } + $output = $ws->receive(); + + client_log($mypid, "Received from websocktet: $output"); + sleep(1); + $i++; + } + + $ws->close(); + + } catch (\Exception $e) { + // exit child process on error + client_log($mypid, "Caught exception: ".$e->getMessage(), "error"); + //$log->error("Caught exception: ".$e->getMessage()."\n"); + exit; + } + } +} + +function signalHandler($sig) { + global $continue; + global $childpid; + $continue = false; + //echo "in signal handler\n"; + + if($childpid) { + posix_kill($childpid, SIGTERM); + } + exit; +} + +function client_log($pid, $text, $severity = "notice") { + global $log; + global $is_daemon; + + if($is_daemon) { + echo "[".date('Y-m-d H:i:s')."] [$pid] $text\n"; + } + $log->$severity($text); + + return true; +} \ No newline at end of file diff --git a/composer.json b/composer.json index 9af302862..f6270db98 100644 --- a/composer.json +++ b/composer.json @@ -1,6 +1,7 @@ { "require": { "phpoffice/phpspreadsheet": "^1.23", - "robmorgan/phinx": "^0.13.4" + "robmorgan/phinx": "^0.13.4", + "textalk/websocket": "^1.6" } } diff --git a/db/migrations/20231003174028_add_table_ivt_product_match.php b/db/migrations/20231003174028_add_table_ivt_product_match.php index 592b1f7b8..f52a33fa3 100644 --- a/db/migrations/20231003174028_add_table_ivt_product_match.php +++ b/db/migrations/20231003174028_add_table_ivt_product_match.php @@ -29,7 +29,8 @@ final class AddTableIvtProductMatch extends AbstractMigration public function down(): void { if($this->getEnvironment() == "thetool") { - + $table = $this->table("IvtProductMatch"); + $table->drop(); } if($this->getEnvironment() == "addressdb") { diff --git a/db/migrations/20231004141500_add_can_voice_plan_permission.php b/db/migrations/20231004141500_add_can_voice_plan_permission.php new file mode 100644 index 000000000..3788a7e7e --- /dev/null +++ b/db/migrations/20231004141500_add_can_voice_plan_permission.php @@ -0,0 +1,44 @@ +getEnvironment() == "thetool") { + $table = $this->table("WorkerPermission"); + $table->addColumn("canVoiceplan", "enum", ["values" => 'false,true', "default" => "false", "after" => "canVoipnumbering"]); + $table->update(); + + // set canVoiceplan true where canVoipnumbering is true + $builder = $this->getQueryBuilder(); + $q = $builder->select("*")->from("WorkerPermission")->where(["canVoipnumbering" => "true"])->execute(); + + while($perm = $q->fetch('assoc')) { + $id = $perm["id"]; + + $this->query("UPDATE WorkerPermission SET canVoiceplan='true' WHERE id=$id"); + + } + } + + if($this->getEnvironment() == "addressdb") { + + } + } + + public function down(): void + { + if($this->getEnvironment() == "thetool") { + $table = $this->table("WorkerPermission"); + $table->removeColumn("canVoiceplan"); + $table->update(); + } + + if($this->getEnvironment() == "addressdb") { + + } + } +} diff --git a/db/migrations/20231004143109_add_voicenumber_tables.php b/db/migrations/20231004143109_add_voicenumber_tables.php new file mode 100644 index 000000000..fa56f8b6d --- /dev/null +++ b/db/migrations/20231004143109_add_voicenumber_tables.php @@ -0,0 +1,95 @@ +getEnvironment() == "thetool") { + $table = $this->table("Voicenumberblock"); + $table->addColumn("name", "string", ["null" => true, "limit" => 255, "default" => null]); + $table->addColumn("countrycode", "integer", ["null" => false]); + $table->addColumn("areacode", "integer", ["null" => false]); + $table->addColumn("prefix", "string", ["null" => false, "limit" => 64]); + $table->addColumn("first", "string", ["null" => false, "limit" => 64]); + $table->addColumn("last", "string", ["null" => false, "limit" => 64]); + $table->addColumn("comment", "text", ["null" => true, "default" => null]); + $table->addColumn("create_by", "integer", ["null" => false]); + $table->addColumn("edit_by", "integer", ["null" => false]); + $table->addColumn("create", "integer", ["null" => false]); + $table->addColumn("edit", "integer", ["null" => false]); + $table->create(); + + $table = $this->table("Voicenumber"); + $table->addColumn("voicenumberblock_id", "integer", ["null" => true, "default" => null]); + $table->addColumn("orderproduct_id", "integer", ["null" => true, "default" => null]); + $table->addColumn("contract_id", "integer", ["null" => true, "default" => null]); + $table->addColumn("active", "integer", ["null" => false, "default" => 0, "limit" => \Phinx\Db\Adapter\MysqlAdapter::INT_TINY]); + $table->addColumn("activated_date", "integer", ["null" => true, "default" => null]); + $table->addColumn("routing", "enum", ["values" => "sipit,kolmisoft", "null" => false, "default" => "kolmisoft"]); + $table->addColumn("number", "string", ["null" => false, "limit" => 64]); + $table->addColumn("port_in_date", "integer", ["null" => true, "default" => null]); + $table->addColumn("port_out_date", "integer", ["null" => true, "default" => null]); + $table->addColumn("ported_in", "integer", ["null" => true, "default" => null]); + $table->addColumn("ported_out", "integer", ["null" => true, "default" => null]); + $table->addColumn("disabled", "integer", ["null" => false, "default" => 0, "limit" => \Phinx\Db\Adapter\MysqlAdapter::INT_TINY]); + $table->addColumn("disabled_reason", "enum", ["values" => "ported_out,ported_back,reserved,legacy,damaged", "null" => true, "default" => null]); + $table->addColumn("enable_on_date", "integer", ["null" => true, "default" => null]); + $table->addColumn("comment", "text", ["null" => true, "default" => null]); + $table->addColumn("create_by", "integer", ["null" => false]); + $table->addColumn("edit_by", "integer", ["null" => false]); + $table->addColumn("create", "integer", ["null" => false]); + $table->addColumn("edit", "integer", ["null" => false]); + $table->create(); + + $table = $this->table("Voiceplan"); + $table->addColumn("name", "string", ["null" => false, "limit" => 64]); + $table->addColumn("comment", "text", ["null" => true, "default" => null]); + $table->addColumn("source", "string", ["null" => true, "default" => null, "limit" => 255]); + $table->addColumn("source_id", "string", ["null" => true, "default" => null, "limit" => 255]); + $table->addColumn("increment_first", "integer", ["null" => false, "default" => 1]); + $table->addColumn("increment", "integer", ["null" => false, "default" => 1]); + $table->addColumn("create_by", "integer", ["null" => false]); + $table->addColumn("edit_by", "integer", ["null" => false]); + $table->addColumn("create", "integer", ["null" => false]); + $table->addColumn("edit", "integer", ["null" => false]); + $table->create(); + + $table = $this->table("Voiceplandestination"); + $table->addColumn("voiceplan_id", "integer", ["null" => false]); + $table->addColumn("destination", "string", ["null" => false, "limit" => 64]); + $table->addColumn("prefix", "string", ["null" => false, "limit" => 64]); + $table->addColumn("purchase_price", "decimal", ["null" => false, "precision" => 14, "scale" => 4]); + $table->addColumn("price", "decimal", ["null" => false, "precision" => 14, "scale" => 4]); + $table->addColumn("increment_first", "integer", ["null" => false, "default" => 1]); + $table->addColumn("increment", "integer", ["null" => false, "default" => 1]); + $table->addColumn("create_by", "integer", ["null" => false]); + $table->addColumn("edit_by", "integer", ["null" => false]); + $table->addColumn("create", "integer", ["null" => false]); + $table->addColumn("edit", "integer", ["null" => false]); + $table->create(); + + + } + + if($this->getEnvironment() == "addressdb") { + + } + } + + public function down(): void + { + if($this->getEnvironment() == "thetool") { + $this->table("Voiceplandestination")->drop(); + $this->table("Voiceplan")->drop(); + $this->table("Voicenumber")->drop(); + $this->table("Voicenumberblock")->drop(); + } + + if($this->getEnvironment() == "addressdb") { + + } + } +}