From 2e1263dcefbd0d2decf40336e3bc73968e305982 Mon Sep 17 00:00:00 2001 From: iazaran Date: Fri, 25 Feb 2022 13:06:00 +0400 Subject: [PATCH 1/9] Nginx configurations updated --- docker/nginx_http1/default.conf | 2 +- docker/nginx_http2/default.conf | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docker/nginx_http1/default.conf b/docker/nginx_http1/default.conf index 3ee78e8..47b3f27 100644 --- a/docker/nginx_http1/default.conf +++ b/docker/nginx_http1/default.conf @@ -17,7 +17,7 @@ server { fastcgi_pass php-mvc-app:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; - fastcgi_param PHP_VALUE "error_log=/var/log/nginx/application_php_errors.log"; + fastcgi_param PHP_VALUE "error_log=/var/log/nginx/app_php_errors.log"; fastcgi_param PATH_INFO $fastcgi_path_info; } } diff --git a/docker/nginx_http2/default.conf b/docker/nginx_http2/default.conf index e4e964d..495bc4b 100644 --- a/docker/nginx_http2/default.conf +++ b/docker/nginx_http2/default.conf @@ -17,7 +17,7 @@ server { fastcgi_pass php-mvc-app:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; - fastcgi_param PHP_VALUE "error_log=/var/log/nginx/application_php_errors.log"; + fastcgi_param PHP_VALUE "error_log=/var/log/nginx/grpc_php_errors.log"; fastcgi_param PATH_INFO $fastcgi_path_info; } } From a2c25496bb00a7c2ccdabe550c096e95404372a1 Mon Sep 17 00:00:00 2001 From: iazaran Date: Fri, 25 Feb 2022 13:06:21 +0400 Subject: [PATCH 2/9] Nginx configurations websocket added --- docker/nginx_websocket/default.conf | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 docker/nginx_websocket/default.conf diff --git a/docker/nginx_websocket/default.conf b/docker/nginx_websocket/default.conf new file mode 100644 index 0000000..484cfff --- /dev/null +++ b/docker/nginx_websocket/default.conf @@ -0,0 +1,23 @@ +map $http_upgrade $connection_upgrade { + default upgrade; + '' close; +} + +upstream websocket { + server php-mvc-websocket:9090; +} + +server { + listen 80; + client_max_body_size 108M; + access_log /var/log/nginx/websocket.access.log; + error_log /var/log/nginx/websocket.error.log; + + location / { + proxy_pass http://websocket; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection $connection_upgrade; + proxy_set_header Host $host; + } +} From 2f67f3ec16ba45fb67aacac370e3d2888de68a61 Mon Sep 17 00:00:00 2001 From: iazaran Date: Fri, 25 Feb 2022 13:06:45 +0400 Subject: [PATCH 3/9] sockets extension added to Dockerfile --- docker/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker/Dockerfile b/docker/Dockerfile index c8bf38f..6c9cc7e 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -11,7 +11,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ && rm -rf /var/lib/apt/lists/* RUN docker-php-ext-configure gd --with-freetype=/usr/include/ --with-jpeg=/usr/include/ -RUN docker-php-ext-install mysqli pdo pdo_mysql gd +RUN docker-php-ext-install mysqli pdo pdo_mysql gd sockets RUN pecl install -o -f memcached \ && docker-php-ext-enable memcached RUN pecl install grpc \ From f62dde269565d74a2eeef251cd0fa065f9689b0a Mon Sep 17 00:00:00 2001 From: iazaran Date: Fri, 25 Feb 2022 13:07:01 +0400 Subject: [PATCH 4/9] sockets extension added to composer --- composer.json | 1 + composer.lock | 7 ++++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/composer.json b/composer.json index 338af1b..e16ba19 100644 --- a/composer.json +++ b/composer.json @@ -32,6 +32,7 @@ "ext-iconv": "*", "ext-memcached": "*", "ext-grpc": "*", + "ext-sockets": "*", "phpmailer/phpmailer": "6.5.4", "grpc/grpc": "1.42.0", "google/protobuf": "3.19.4" diff --git a/composer.lock b/composer.lock index 11886fc..ecc88d0 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "916025bd31dcd4fc79f3d5448c8b8f3d", + "content-hash": "a0bd4ffdfebb23b93bfa85d30cc6351b", "packages": [ { "name": "google/protobuf", @@ -187,11 +187,12 @@ "ext-gd": "*", "ext-iconv": "*", "ext-memcached": "*", - "ext-grpc": "*" + "ext-grpc": "*", + "ext-sockets": "*" }, "platform-dev": [], "platform-overrides": { "php": "8.1" }, - "plugin-api-version": "2.2.0" + "plugin-api-version": "2.0.0" } From 184968e41e15ed56c653632ad84772ca19312ddf Mon Sep 17 00:00:00 2001 From: iazaran Date: Fri, 25 Feb 2022 13:07:32 +0400 Subject: [PATCH 5/9] New services added to docker-compose.yml because of WebSocket --- docker-compose.yml | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/docker-compose.yml b/docker-compose.yml index d469432..0f4e7ff 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -23,6 +23,17 @@ services: networks: - php-mvc-network + php-mvc-websocket-server: + image: nginx:alpine + container_name: php-mvc-websocket-server + volumes: + - ./:/var/www + - ./docker/nginx_websocket:/etc/nginx/conf.d/ + ports: + - '9090:80' + networks: + - php-mvc-network + php-mvc-app: build: context: . @@ -50,6 +61,19 @@ services: networks: - php-mvc-network + php-mvc-websocket: + build: + context: . + dockerfile: docker/Dockerfile + container_name: php-mvc-websocket + user: www + command: php /var/www/websocket/index.php + volumes: + - ./:/var/www + - ./docker/php/local.ini:/usr/local/etc/php/conf.d/local.in + networks: + - php-mvc-network + php-mvc-db: image: mysql container_name: php-mvc-db From 38c5cde042b30d15551c3ed31a84f03e1230dcf0 Mon Sep 17 00:00:00 2001 From: iazaran Date: Fri, 25 Feb 2022 13:08:16 +0400 Subject: [PATCH 6/9] WebSocket PHP class and JS codes added --- public/js/main.js | 50 ++++++++++- public/js/main.min.js | 2 +- src/App/WebSocket.php | 201 ++++++++++++++++++++++++++++++++++++++++++ websocket/index.php | 16 ++++ 4 files changed, 265 insertions(+), 4 deletions(-) create mode 100644 src/App/WebSocket.php create mode 100644 websocket/index.php diff --git a/public/js/main.js b/public/js/main.js index ef7ce8b..e1b9198 100644 --- a/public/js/main.js +++ b/public/js/main.js @@ -44,7 +44,7 @@ $(document).ready(function () { * for form and blog-create-submit for it"s button. Form"s buttons * need to have constant form-button class. */ - body.on("click", ".form-button", function(event) { + body.on("click", ".form-button", function (event) { let elementId = $(this).attr("id"); elementId = elementId.replace("-submit", ""); @@ -139,6 +139,10 @@ $(document).ready(function () { } }); }); + + if (window.location.pathname === "/websocket") { + handleChat(); + } }); /** @@ -151,7 +155,7 @@ $(document).ready(function () { function setCookie(name, value, expiresDay) { const d = new Date(); d.setTime(d.getTime() + (expiresDay * 24 * 60 * 60 * 1000)); - let expires = "expires="+d.toUTCString(); + let expires = "expires=" + d.toUTCString(); document.cookie = name + "=" + value + ";" + expires + ";path=/"; } @@ -165,7 +169,7 @@ function setCookie(name, value, expiresDay) { function getCookie(name) { let cookieName = name + "="; let ca = document.cookie.split(";"); - for(let i = 0; i < ca.length; i++) { + for (let i = 0; i < ca.length; i++) { let c = ca[i]; while (c.charAt(0) === " ") { c = c.substring(1); @@ -177,3 +181,43 @@ function getCookie(name) { return ""; } + +/** + * Add message to existing ones on chat + * + * @param messageHTML + */ +function showMessage(messageHTML) { + $("#output").append(messageHTML); +} + +function handleChat() { + let webSocket = new WebSocket("ws://localhost:9090"); + + webSocket.onopen = function (event) { + showMessage("Successfully entered the room..."); + }; + + webSocket.onmessage = function (event) { + let data = JSON.parse(event.data); + showMessage("

" + data.message + "

"); + $("#message").val(""); + }; + + webSocket.onerror = function (event) { + showMessage("Problem due to some Error!

"); + }; + + webSocket.onclose = function (event) { + showMessage("Connection Closed"); + }; + + $("#chat-submit").on("click", function (event) { + event.preventDefault(); + let messageJSON = { + name: $("#client-name").val(), + message: $("#message").val() + }; + webSocket.send(JSON.stringify(messageJSON)); + }); +} diff --git a/public/js/main.min.js b/public/js/main.min.js index dda611f..4cb57c1 100644 --- a/public/js/main.min.js +++ b/public/js/main.min.js @@ -1 +1 @@ -$(document).ready(function(){const summernoteBody=$("#body");if(summernoteBody.length){summernoteBody.summernote({tabsize:4,height:100})}const toastElement=$(".toast");toastElement.toast({delay:4000});const message=getCookie("message");if(message!==""){toastElement.toast("show");$(".toast-body").text(decodeURI(message))}$(function(){$("[data-toggle='tooltip']").tooltip()});const body=$("body");body.on("click",".form-button",function(event){let elementId=$(this).attr("id");elementId=elementId.replace("-submit","");let formData=new FormData($("form").get(0));$.ajax({url:apiAddress+"/"+elementId.replace("-","/"),data:formData,type:"POST",dataType:"JSON",cache:false,processData:false,contentType:false,beforeSend(){$(".progress").css("top","56px")},complete(){$(".progress").css("top","51px")},success(result){if(result.status==="OK"){window.location.replace("/")}else{toastElement.toast("show");$(".toast-body").text(result.message)}},error(xhr,status,error){toastElement.toast("show");let message="Unknown Error!";if(typeof result==="undefined"){message="DB connection error! Please try again."}else{message=result.message}$(".toast-body").text(message)}})});body.on("keypress","form",function(event){if(event.key==="Enter")$(".form-button").click()});body.on("click",".form-delete-button",function(event){let elementId=$(this).attr("id");$.ajax({url:apiAddress+"/blog/delete/"+elementId,type:"DELETE",dataType:"JSON",beforeSend(){$(".progress").css("top","56px")},complete(){$(".progress").css("top","51px")},success(result){if(result.status==="OK"){window.location.replace("/")}else{toastElement.toast("show");$(".toast-body").text(result.message)}},error(xhr,status,error){toastElement.toast("show");let message="Unknown Error!";if(typeof result==="undefined"){message="DB connection error! Please try again."}else{message=result.message}$(".toast-body").text(message)}})})});function setCookie(name,value,expiresDay){const d=new Date();d.setTime(d.getTime()+(expiresDay*24*60*60*1000));let expires="expires="+d.toUTCString();document.cookie=name+"="+value+";"+expires+";path=/"}function getCookie(name){let cookieName=name+"=";let ca=document.cookie.split(";");for(let i=0;iSuccessfully entered the room...
")};webSocket.onmessage=function(event){let data=JSON.parse(event.data);showMessage("

"+data.message+"

");$("#message").val("")};webSocket.onerror=function(event){showMessage("Problem due to some Error!

")};webSocket.onclose=function(event){showMessage("Connection Closed")};$("#chat-submit").on("click",function(event){event.preventDefault();let messageJSON={name:$("#client-name").val(),message:$("#message").val()};webSocket.send(JSON.stringify(messageJSON))})} \ No newline at end of file diff --git a/src/App/WebSocket.php b/src/App/WebSocket.php new file mode 100644 index 0000000..5cda343 --- /dev/null +++ b/src/App/WebSocket.php @@ -0,0 +1,201 @@ +server = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); + $this->address = $address; + $this->port = $port; + + socket_set_option($this->server, SOL_SOCKET, SO_REUSEADDR, 1); + socket_bind($this->server, 0, $port); + socket_listen($this->server); + } + + /** + * Send messages to all clients, previously encoded in json first. + * + * @param $message + * @return bool + */ + function send($message): bool + { + $raw = $this->seal(json_encode([ + 'message' => $message + ])); + + foreach ($this->clients as $client) { + @socket_write($client, $raw, strlen($raw)); + } + + return true; + } + + /** + * Since the receive socket is still raw, we have to unseal it first. + * + * @param $socketData + * @return string + */ + public function unseal($socketData): string + { + $length = ord($socketData[1]) & 127; + + if ($length == 126) { + $masks = substr($socketData, 4, 4); + $data = substr($socketData, 8); + } elseif ($length == 127) { + $masks = substr($socketData, 10, 4); + $data = substr($socketData, 14); + } else { + $masks = substr($socketData, 2, 4); + $data = substr($socketData, 6); + } + + $socketData = ''; + + for ($i = 0; $i < strlen($data); ++$i) { + $socketData .= $data[$i] ^ $masks[$i % 4]; + } + + return $socketData; + } + + /** + * Send seal data. + * + * @param $socketData + * @return string + */ + function seal($socketData): string + { + $b1 = 0x80 | (0x1 & 0x0f); + $length = strlen($socketData); + + if ($length <= 125) + $header = pack('CC', $b1, $length); + elseif ($length < 65536) + $header = pack('CCn', $b1, 126, $length); + else + $header = pack('CCNN', $b1, 127, $length); + + return $header . $socketData; + } + + /** + * Sends handshake headers to connected clients. + * + * @param $header + * @param $socket + * @param $address + * @param $port + * @return void + */ + function handshake($header, $socket, $address, $port): void + { + $headers = array(); + $lines = preg_split("/\r\n/", $header); + foreach ($lines as $line) { + $line = chop($line); + if (preg_match("/\A(\S+): (.*)\z/", $line, $matches)) { + $headers[$matches[1]] = $matches[2]; + } + } + + $secKey = $headers['Sec-WebSocket-Key']; + $secAccept = base64_encode(pack('H*', sha1($secKey . '258EAFA5-E914-47DA-95CA-C5AB0DC85B11'))); + + $buffer = "HTTP/1.1 101 Web Socket Protocol Handshake\r\n"; + $buffer .= "Upgrade: websocket\r\n"; + $buffer .= "Connection: Upgrade\r\n"; + $buffer .= "WebSocket-Origin: $address\r\n"; + $buffer .= "WebSocket-Location: ws://$address:$port/Server.php\r\n"; + $buffer .= "Sec-WebSocket-Accept:$secAccept\r\n\r\n"; + + socket_write($socket, $buffer, strlen($buffer)); + } + + /** + * Running websocket server. + * + * @return void + */ + public function run() + { + $this->clients = [ + $this->server + ]; + + $address = $this->address; + $port = $this->port; + + echo "Listening incoming request on port {$this->port} ..\n"; + + while (true) { + $newClients = $this->clients; + + socket_select($newClients, $null, $null, 0, 10); + + if (in_array($this->server, $newClients)) { + $newSocket = socket_accept($this->server); + $this->clients[] = $newSocket; + $header = socket_read($newSocket, 1024); + $this->handshake($header, $newSocket, $address, $port); + + socket_getpeername($newSocket, $ip); + $this->send("Clients with IP: {$ip} just joined"); + echo "Clients with IP: {$ip} just joined \n"; + + $index = array_search($this->server, $newClients); + unset($newClients[$index]); + } + + foreach ($newClients as $newClientsResource) { + while (socket_recv($newClientsResource, $socketData, 1024, 0) >= 1) { + if ($socketData) { + $socketMessage = $this->unseal($socketData); + $messageObj = json_decode($socketMessage); + + if (isset($messageObj->name) && isset($messageObj->message)) { + $this->send("{$messageObj->name} : {$messageObj->message}"); + } + + break 2; + } + } + + $socketData = @socket_read($newClientsResource, 1024, PHP_NORMAL_READ); + + if ($socketData === false) { + socket_getpeername($newClientsResource, $ip); + $this->send("Clients with IP: {$ip} just came out"); + echo "Clients with IP: {$ip} just came out \n"; + + $index = array_search($newClientsResource, $this->clients); + unset($this->clients[$index]); + } + } + } + + socket_close($this->server); + } +} diff --git a/websocket/index.php b/websocket/index.php new file mode 100644 index 0000000..a8578a6 --- /dev/null +++ b/websocket/index.php @@ -0,0 +1,16 @@ +#!/usr/bin/php + +run(); From 69585c2c73a11430953de43a707647d4e970a5ea Mon Sep 17 00:00:00 2001 From: iazaran Date: Fri, 25 Feb 2022 13:08:39 +0400 Subject: [PATCH 7/9] Sample route/controller added to test WebSocket --- src/Controllers/WebSocketController.php | 28 ++++++++++++++++++++ src/Views/WebSocket/chat.php | 34 +++++++++++++++++++++++++ src/routes.php | 1 + 3 files changed, 63 insertions(+) create mode 100644 src/Controllers/WebSocketController.php create mode 100644 src/Views/WebSocket/chat.php diff --git a/src/Controllers/WebSocketController.php b/src/Controllers/WebSocketController.php new file mode 100644 index 0000000..1c04ad5 --- /dev/null +++ b/src/Controllers/WebSocketController.php @@ -0,0 +1,28 @@ + 'Chat', + 'page_subtitle' => 'Basic WebSocket Sample', + ] + ); + } +} diff --git a/src/Views/WebSocket/chat.php b/src/Views/WebSocket/chat.php new file mode 100644 index 0000000..675d61c --- /dev/null +++ b/src/Views/WebSocket/chat.php @@ -0,0 +1,34 @@ + + +
+
+ Chat based on WebSocket +
+
+
+
+
+
+
+ +
+
+ +
+ +
+
+
+ +
+ +
+
+
+
+ Send +
+
+
+ + diff --git a/src/routes.php b/src/routes.php index 865a571..a6fa617 100644 --- a/src/routes.php +++ b/src/routes.php @@ -6,6 +6,7 @@ * Web routes */ Router::get('/', 'HomeController@index'); +Router::get('/websocket', 'WebSocketController@chat'); Router::get('/blog', 'BlogController@index'); Router::get('/blog/(:any)', 'BlogController@show'); Router::get('/blog/create', 'BlogController@create'); From efb61e56deb4ba5a8bb3b76feddc7b86f8bb422f Mon Sep 17 00:00:00 2001 From: iazaran Date: Fri, 25 Feb 2022 13:08:52 +0400 Subject: [PATCH 8/9] README.md updated --- README.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 37c957b..c7c3ab3 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ > This project tries to cover some PHP features in a simple MVC structure with minimum installed composer packages. Then developers can use packages for specific requirements. Please add your ideas in Discussions, ask features or report bugs in issues. -💡 TODO: SEO & WebSocket +💡 TODO: SPL #### Features: **List of features related with structure** @@ -16,6 +16,10 @@ Assets can contain your media files like images, audios & videos. Contains the styles & scripts _(After changes on these files, you can use minifier script to update minified versions, just run `docker-compose exec php-mvc-app php minifier.php`)_ - **public/feed** There is a RSS generator in here and runs after creation or updating a post. +- **grpc** +A simple router for distribute the requests to different services. It is not working yet and I created an issue for it ⚠ and if you have an idea or a solution, only by PHP for both server and client sides, please add your solution in there. +- **websocket** +A WebSocket sample. You can open /websocket route in 2 tabs and test the websocket connection. - **src** Contains migrations for a DB and routes. - **src/App** From 1ad3019b69a5852d0cebccaf760ee68a0456c3a9 Mon Sep 17 00:00:00 2001 From: iazaran Date: Fri, 25 Feb 2022 13:19:38 +0400 Subject: [PATCH 9/9] JS updated --- public/js/main.js | 154 +++++++++++++++++++++--------------------- public/js/main.min.js | 2 +- 2 files changed, 78 insertions(+), 78 deletions(-) diff --git a/public/js/main.js b/public/js/main.js index e1b9198..957e6a5 100644 --- a/public/js/main.js +++ b/public/js/main.js @@ -1,3 +1,80 @@ +/** + * Set cookie + * + * @param name + * @param value + * @param expiresDay + */ +function setCookie(name, value, expiresDay) { + const d = new Date(); + d.setTime(d.getTime() + (expiresDay * 24 * 60 * 60 * 1000)); + let expires = "expires=" + d.toUTCString(); + + document.cookie = name + "=" + value + ";" + expires + ";path=/"; +} + +/** + * Get cookie + * + * @param name + * @returns {string} + */ +function getCookie(name) { + let cookieName = name + "="; + let ca = document.cookie.split(";"); + for (let i = 0; i < ca.length; i++) { + let c = ca[i]; + while (c.charAt(0) === " ") { + c = c.substring(1); + } + if (c.indexOf(cookieName) === 0) { + return c.substring(cookieName.length, c.length); + } + } + + return ""; +} + +/** + * Add message to existing ones on chat + * + * @param messageHTML + */ +function showMessage(messageHTML) { + $("#output").append(messageHTML); +} + +function handleChat() { + let webSocket = new WebSocket("ws://localhost:9090"); + + webSocket.onopen = function (event) { + showMessage("Successfully entered the room..."); + }; + + webSocket.onmessage = function (event) { + let data = JSON.parse(event.data); + showMessage("

" + data.message + "

"); + $("#message").val(""); + }; + + webSocket.onerror = function (event) { + showMessage("Problem due to some Error!

"); + }; + + webSocket.onclose = function (event) { + showMessage("Connection Closed"); + }; + + $("#chat-submit").on("click", function (event) { + event.preventDefault(); + let messageJSON = { + name: $("#client-name").val(), + message: $("#message").val() + }; + webSocket.send(JSON.stringify(messageJSON)); + }); +} + $(document).ready(function () { /** * Start summernote if needed @@ -144,80 +221,3 @@ $(document).ready(function () { handleChat(); } }); - -/** - * Set cookie - * - * @param name - * @param value - * @param expiresDay - */ -function setCookie(name, value, expiresDay) { - const d = new Date(); - d.setTime(d.getTime() + (expiresDay * 24 * 60 * 60 * 1000)); - let expires = "expires=" + d.toUTCString(); - - document.cookie = name + "=" + value + ";" + expires + ";path=/"; -} - -/** - * Get cookie - * - * @param name - * @returns {string} - */ -function getCookie(name) { - let cookieName = name + "="; - let ca = document.cookie.split(";"); - for (let i = 0; i < ca.length; i++) { - let c = ca[i]; - while (c.charAt(0) === " ") { - c = c.substring(1); - } - if (c.indexOf(cookieName) === 0) { - return c.substring(cookieName.length, c.length); - } - } - - return ""; -} - -/** - * Add message to existing ones on chat - * - * @param messageHTML - */ -function showMessage(messageHTML) { - $("#output").append(messageHTML); -} - -function handleChat() { - let webSocket = new WebSocket("ws://localhost:9090"); - - webSocket.onopen = function (event) { - showMessage("Successfully entered the room..."); - }; - - webSocket.onmessage = function (event) { - let data = JSON.parse(event.data); - showMessage("

" + data.message + "

"); - $("#message").val(""); - }; - - webSocket.onerror = function (event) { - showMessage("Problem due to some Error!

"); - }; - - webSocket.onclose = function (event) { - showMessage("Connection Closed"); - }; - - $("#chat-submit").on("click", function (event) { - event.preventDefault(); - let messageJSON = { - name: $("#client-name").val(), - message: $("#message").val() - }; - webSocket.send(JSON.stringify(messageJSON)); - }); -} diff --git a/public/js/main.min.js b/public/js/main.min.js index 4cb57c1..b8fc4b4 100644 --- a/public/js/main.min.js +++ b/public/js/main.min.js @@ -1 +1 @@ -$(document).ready(function(){const summernoteBody=$("#body");if(summernoteBody.length){summernoteBody.summernote({tabsize:4,height:100})}const toastElement=$(".toast");toastElement.toast({delay:4000});const message=getCookie("message");if(message!==""){toastElement.toast("show");$(".toast-body").text(decodeURI(message))}$(function(){$("[data-toggle='tooltip']").tooltip()});const body=$("body");body.on("click",".form-button",function(event){let elementId=$(this).attr("id");elementId=elementId.replace("-submit","");let formData=new FormData($("form").get(0));$.ajax({url:apiAddress+"/"+elementId.replace("-","/"),data:formData,type:"POST",dataType:"JSON",cache:false,processData:false,contentType:false,beforeSend(){$(".progress").css("top","56px")},complete(){$(".progress").css("top","51px")},success(result){if(result.status==="OK"){window.location.replace("/")}else{toastElement.toast("show");$(".toast-body").text(result.message)}},error(xhr,status,error){toastElement.toast("show");let message="Unknown Error!";if(typeof result==="undefined"){message="DB connection error! Please try again."}else{message=result.message}$(".toast-body").text(message)}})});body.on("keypress","form",function(event){if(event.key==="Enter")$(".form-button").click()});body.on("click",".form-delete-button",function(event){let elementId=$(this).attr("id");$.ajax({url:apiAddress+"/blog/delete/"+elementId,type:"DELETE",dataType:"JSON",beforeSend(){$(".progress").css("top","56px")},complete(){$(".progress").css("top","51px")},success(result){if(result.status==="OK"){window.location.replace("/")}else{toastElement.toast("show");$(".toast-body").text(result.message)}},error(xhr,status,error){toastElement.toast("show");let message="Unknown Error!";if(typeof result==="undefined"){message="DB connection error! Please try again."}else{message=result.message}$(".toast-body").text(message)}})});if(window.location.pathname==="/websocket"){handleChat()}});function setCookie(name,value,expiresDay){const d=new Date();d.setTime(d.getTime()+(expiresDay*24*60*60*1000));let expires="expires="+d.toUTCString();document.cookie=name+"="+value+";"+expires+";path=/"}function getCookie(name){let cookieName=name+"=";let ca=document.cookie.split(";");for(let i=0;iSuccessfully entered the room...
")};webSocket.onmessage=function(event){let data=JSON.parse(event.data);showMessage("

"+data.message+"

");$("#message").val("")};webSocket.onerror=function(event){showMessage("Problem due to some Error!

")};webSocket.onclose=function(event){showMessage("Connection Closed")};$("#chat-submit").on("click",function(event){event.preventDefault();let messageJSON={name:$("#client-name").val(),message:$("#message").val()};webSocket.send(JSON.stringify(messageJSON))})} \ No newline at end of file +function setCookie(name,value,expiresDay){const d=new Date();d.setTime(d.getTime()+(expiresDay*24*60*60*1000));let expires="expires="+d.toUTCString();document.cookie=name+"="+value+";"+expires+";path=/"}function getCookie(name){let cookieName=name+"=";let ca=document.cookie.split(";");for(let i=0;iSuccessfully entered the room...
")};webSocket.onmessage=function(event){let data=JSON.parse(event.data);showMessage("

"+data.message+"

");$("#message").val("")};webSocket.onerror=function(event){showMessage("Problem due to some Error!

")};webSocket.onclose=function(event){showMessage("Connection Closed")};$("#chat-submit").on("click",function(event){event.preventDefault();let messageJSON={name:$("#client-name").val(),message:$("#message").val()};webSocket.send(JSON.stringify(messageJSON))})}$(document).ready(function(){const summernoteBody=$("#body");if(summernoteBody.length){summernoteBody.summernote({tabsize:4,height:100})}const toastElement=$(".toast");toastElement.toast({delay:4000});const message=getCookie("message");if(message!==""){toastElement.toast("show");$(".toast-body").text(decodeURI(message))}$(function(){$("[data-toggle='tooltip']").tooltip()});const body=$("body");body.on("click",".form-button",function(event){let elementId=$(this).attr("id");elementId=elementId.replace("-submit","");let formData=new FormData($("form").get(0));$.ajax({url:apiAddress+"/"+elementId.replace("-","/"),data:formData,type:"POST",dataType:"JSON",cache:false,processData:false,contentType:false,beforeSend(){$(".progress").css("top","56px")},complete(){$(".progress").css("top","51px")},success(result){if(result.status==="OK"){window.location.replace("/")}else{toastElement.toast("show");$(".toast-body").text(result.message)}},error(xhr,status,error){toastElement.toast("show");let message="Unknown Error!";if(typeof result==="undefined"){message="DB connection error! Please try again."}else{message=result.message}$(".toast-body").text(message)}})});body.on("keypress","form",function(event){if(event.key==="Enter")$(".form-button").click()});body.on("click",".form-delete-button",function(event){let elementId=$(this).attr("id");$.ajax({url:apiAddress+"/blog/delete/"+elementId,type:"DELETE",dataType:"JSON",beforeSend(){$(".progress").css("top","56px")},complete(){$(".progress").css("top","51px")},success(result){if(result.status==="OK"){window.location.replace("/")}else{toastElement.toast("show");$(".toast-body").text(result.message)}},error(xhr,status,error){toastElement.toast("show");let message="Unknown Error!";if(typeof result==="undefined"){message="DB connection error! Please try again."}else{message=result.message}$(".toast-body").text(message)}})});if(window.location.pathname==="/websocket"){handleChat()}}); \ No newline at end of file