websocket

This commit is contained in:
afornerot 2020-11-23 13:08:01 +01:00
parent 81edd7b208
commit c174987967
26 changed files with 1096 additions and 62 deletions

View File

@ -16,7 +16,7 @@
<!-- template -->
<file filelist='ninesurvey' name='/etc/apache2/sites-available/ninesurvey' source='ninesurvey-apache.conf' />
<file filelist='ninesurvey' name='/var/www/html/ninesurvey/.env.local' source='ninesurvey-env.local' rm='True'/>
<file filelist='ninegate' name='/etc/cron.d/ninesurvey' source='ninesurvey.cron' rm='True'/>
<file filelist='ninesurvey' name='/etc/cron.d/ninesurvey' source='ninesurvey.cron' rm='True'/>
</container>
</containers>

View File

@ -5,6 +5,7 @@
"php": "^7.1.3",
"ext-ctype": "*",
"ext-iconv": "*",
"cboden/ratchet": "^0.4.3",
"craue/formflow-bundle": "^3.3",
"doctrine/annotations": "^1.8",
"friendsofsymfony/ckeditor-bundle": "^2.2",

View File

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically"
],
"content-hash": "061d29f07b7ffdac985f06a830f7ce71",
"content-hash": "e2590c5a41dce3868f00073d0a1c9a7c",
"packages": [
{
"name": "brick/math",
@ -52,6 +52,63 @@
],
"time": "2020-08-18T23:57:15+00:00"
},
{
"name": "cboden/ratchet",
"version": "v0.4.3",
"source": {
"type": "git",
"url": "https://github.com/ratchetphp/Ratchet.git",
"reference": "466a0ecc83209c75b76645eb823401b5c52e5f21"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/ratchetphp/Ratchet/zipball/466a0ecc83209c75b76645eb823401b5c52e5f21",
"reference": "466a0ecc83209c75b76645eb823401b5c52e5f21",
"shasum": ""
},
"require": {
"guzzlehttp/psr7": "^1.0",
"php": ">=5.4.2",
"ratchet/rfc6455": "^0.3",
"react/socket": "^1.0 || ^0.8 || ^0.7 || ^0.6 || ^0.5",
"symfony/http-foundation": "^2.6|^3.0|^4.0|^5.0",
"symfony/routing": "^2.6|^3.0|^4.0|^5.0"
},
"require-dev": {
"phpunit/phpunit": "~4.8"
},
"type": "library",
"autoload": {
"psr-4": {
"Ratchet\\": "src/Ratchet"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Chris Boden",
"email": "cboden@gmail.com",
"role": "Developer"
},
{
"name": "Matt Bonneau",
"role": "Developer"
}
],
"description": "PHP WebSocket library",
"homepage": "http://socketo.me",
"keywords": [
"Ratchet",
"WebSockets",
"server",
"sockets",
"websocket"
],
"time": "2020-07-07T15:50:14+00:00"
},
{
"name": "composer/package-versions-deprecated",
"version": "1.11.99",
@ -1338,6 +1395,7 @@
"reflection",
"static"
],
"abandoned": "roave/better-reflection",
"time": "2020-10-27T21:46:55+00:00"
},
{
@ -1451,6 +1509,49 @@
],
"time": "2020-09-26T15:48:38+00:00"
},
{
"name": "evenement/evenement",
"version": "v3.0.1",
"source": {
"type": "git",
"url": "https://github.com/igorw/evenement.git",
"reference": "531bfb9d15f8aa57454f5f0285b18bec903b8fb7"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/igorw/evenement/zipball/531bfb9d15f8aa57454f5f0285b18bec903b8fb7",
"reference": "531bfb9d15f8aa57454f5f0285b18bec903b8fb7",
"shasum": ""
},
"require": {
"php": ">=7.0"
},
"require-dev": {
"phpunit/phpunit": "^6.0"
},
"type": "library",
"autoload": {
"psr-0": {
"Evenement": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Igor Wiedler",
"email": "igor@wiedler.ch"
}
],
"description": "Événement is a very simple event dispatching library for PHP",
"keywords": [
"event-dispatcher",
"event-emitter"
],
"time": "2017-07-23T21:35:13+00:00"
},
{
"name": "exsyst/swagger",
"version": "v0.4.1",
@ -1669,6 +1770,77 @@
],
"time": "2020-09-10T06:52:17+00:00"
},
{
"name": "guzzlehttp/psr7",
"version": "1.7.0",
"source": {
"type": "git",
"url": "https://github.com/guzzle/psr7.git",
"reference": "53330f47520498c0ae1f61f7e2c90f55690c06a3"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/guzzle/psr7/zipball/53330f47520498c0ae1f61f7e2c90f55690c06a3",
"reference": "53330f47520498c0ae1f61f7e2c90f55690c06a3",
"shasum": ""
},
"require": {
"php": ">=5.4.0",
"psr/http-message": "~1.0",
"ralouphie/getallheaders": "^2.0.5 || ^3.0.0"
},
"provide": {
"psr/http-message-implementation": "1.0"
},
"require-dev": {
"ext-zlib": "*",
"phpunit/phpunit": "~4.8.36 || ^5.7.27 || ^6.5.14 || ^7.5.20 || ^8.5.8 || ^9.3.10"
},
"suggest": {
"laminas/laminas-httphandlerrunner": "Emit PSR-7 responses"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.7-dev"
}
},
"autoload": {
"psr-4": {
"GuzzleHttp\\Psr7\\": "src/"
},
"files": [
"src/functions_include.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Michael Dowling",
"email": "mtdowling@gmail.com",
"homepage": "https://github.com/mtdowling"
},
{
"name": "Tobias Schultze",
"homepage": "https://github.com/Tobion"
}
],
"description": "PSR-7 message implementation that also provides common utility methods",
"keywords": [
"http",
"message",
"psr-7",
"request",
"response",
"stream",
"uri",
"url"
],
"time": "2020-09-30T07:37:11+00:00"
},
{
"name": "jasig/phpcas",
"version": "1.3.8",
@ -2620,6 +2792,56 @@
],
"time": "2019-01-08T18:20:26+00:00"
},
{
"name": "psr/http-message",
"version": "1.0.1",
"source": {
"type": "git",
"url": "https://github.com/php-fig/http-message.git",
"reference": "f6561bf28d520154e4b0ec72be95418abe6d9363"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363",
"reference": "f6561bf28d520154e4b0ec72be95418abe6d9363",
"shasum": ""
},
"require": {
"php": ">=5.3.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0.x-dev"
}
},
"autoload": {
"psr-4": {
"Psr\\Http\\Message\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "PHP-FIG",
"homepage": "http://www.php-fig.org/"
}
],
"description": "Common interface for HTTP messages",
"homepage": "https://github.com/php-fig/http-message",
"keywords": [
"http",
"http-message",
"psr",
"psr-7",
"request",
"response"
],
"time": "2016-08-06T14:39:51+00:00"
},
{
"name": "psr/link",
"version": "1.0.0",
@ -2716,6 +2938,46 @@
],
"time": "2020-03-23T09:12:05+00:00"
},
{
"name": "ralouphie/getallheaders",
"version": "3.0.3",
"source": {
"type": "git",
"url": "https://github.com/ralouphie/getallheaders.git",
"reference": "120b605dfeb996808c31b6477290a714d356e822"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/120b605dfeb996808c31b6477290a714d356e822",
"reference": "120b605dfeb996808c31b6477290a714d356e822",
"shasum": ""
},
"require": {
"php": ">=5.6"
},
"require-dev": {
"php-coveralls/php-coveralls": "^2.1",
"phpunit/phpunit": "^5 || ^6.5"
},
"type": "library",
"autoload": {
"files": [
"src/getallheaders.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Ralph Khattar",
"email": "ralph.khattar@gmail.com"
}
],
"description": "A polyfill for getallheaders.",
"time": "2019-03-08T08:55:37+00:00"
},
{
"name": "ramsey/collection",
"version": "1.1.1",
@ -2860,6 +3122,443 @@
],
"time": "2020-08-18T17:17:46+00:00"
},
{
"name": "ratchet/rfc6455",
"version": "v0.3",
"source": {
"type": "git",
"url": "https://github.com/ratchetphp/RFC6455.git",
"reference": "c8651c7938651c2d55f5d8c2422ac5e57a183341"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/ratchetphp/RFC6455/zipball/c8651c7938651c2d55f5d8c2422ac5e57a183341",
"reference": "c8651c7938651c2d55f5d8c2422ac5e57a183341",
"shasum": ""
},
"require": {
"guzzlehttp/psr7": "^1.0",
"php": ">=5.4.2"
},
"require-dev": {
"phpunit/phpunit": "5.7.*",
"react/socket": "^1.3"
},
"type": "library",
"autoload": {
"psr-4": {
"Ratchet\\RFC6455\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Chris Boden",
"email": "cboden@gmail.com",
"role": "Developer"
},
{
"name": "Matt Bonneau",
"role": "Developer"
}
],
"description": "RFC6455 WebSocket protocol handler",
"homepage": "http://socketo.me",
"keywords": [
"WebSockets",
"rfc6455",
"websocket"
],
"time": "2020-05-15T18:31:24+00:00"
},
{
"name": "react/cache",
"version": "v1.1.0",
"source": {
"type": "git",
"url": "https://github.com/reactphp/cache.git",
"reference": "44a568925556b0bd8cacc7b49fb0f1cf0d706a0c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/reactphp/cache/zipball/44a568925556b0bd8cacc7b49fb0f1cf0d706a0c",
"reference": "44a568925556b0bd8cacc7b49fb0f1cf0d706a0c",
"shasum": ""
},
"require": {
"php": ">=5.3.0",
"react/promise": "^3.0 || ^2.0 || ^1.1"
},
"require-dev": {
"phpunit/phpunit": "^9.3 || ^5.7 || ^4.8.35"
},
"type": "library",
"autoload": {
"psr-4": {
"React\\Cache\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Christian Lück",
"email": "christian@clue.engineering",
"homepage": "https://clue.engineering/"
},
{
"name": "Cees-Jan Kiewiet",
"email": "reactphp@ceesjankiewiet.nl",
"homepage": "https://wyrihaximus.net/"
},
{
"name": "Jan Sorgalla",
"email": "jsorgalla@gmail.com",
"homepage": "https://sorgalla.com/"
},
{
"name": "Chris Boden",
"email": "cboden@gmail.com",
"homepage": "https://cboden.dev/"
}
],
"description": "Async, Promise-based cache interface for ReactPHP",
"keywords": [
"cache",
"caching",
"promise",
"reactphp"
],
"time": "2020-09-18T12:12:35+00:00"
},
{
"name": "react/dns",
"version": "v1.4.0",
"source": {
"type": "git",
"url": "https://github.com/reactphp/dns.git",
"reference": "665260757171e2ab17485b44e7ffffa7acb6ca1f"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/reactphp/dns/zipball/665260757171e2ab17485b44e7ffffa7acb6ca1f",
"reference": "665260757171e2ab17485b44e7ffffa7acb6ca1f",
"shasum": ""
},
"require": {
"php": ">=5.3.0",
"react/cache": "^1.0 || ^0.6 || ^0.5",
"react/event-loop": "^1.0 || ^0.5",
"react/promise": "^3.0 || ^2.7 || ^1.2.1",
"react/promise-timer": "^1.2"
},
"require-dev": {
"clue/block-react": "^1.2",
"phpunit/phpunit": "^9.3 || ^4.8.35"
},
"type": "library",
"autoload": {
"psr-4": {
"React\\Dns\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Christian Lück",
"email": "christian@clue.engineering",
"homepage": "https://clue.engineering/"
},
{
"name": "Cees-Jan Kiewiet",
"email": "reactphp@ceesjankiewiet.nl",
"homepage": "https://wyrihaximus.net/"
},
{
"name": "Jan Sorgalla",
"email": "jsorgalla@gmail.com",
"homepage": "https://sorgalla.com/"
},
{
"name": "Chris Boden",
"email": "cboden@gmail.com",
"homepage": "https://cboden.dev/"
}
],
"description": "Async DNS resolver for ReactPHP",
"keywords": [
"async",
"dns",
"dns-resolver",
"reactphp"
],
"time": "2020-09-18T12:12:55+00:00"
},
{
"name": "react/event-loop",
"version": "v1.1.1",
"source": {
"type": "git",
"url": "https://github.com/reactphp/event-loop.git",
"reference": "6d24de090cd59cfc830263cfba965be77b563c13"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/reactphp/event-loop/zipball/6d24de090cd59cfc830263cfba965be77b563c13",
"reference": "6d24de090cd59cfc830263cfba965be77b563c13",
"shasum": ""
},
"require": {
"php": ">=5.3.0"
},
"require-dev": {
"phpunit/phpunit": "^7.0 || ^6.4 || ^5.7 || ^4.8.35"
},
"suggest": {
"ext-event": "~1.0 for ExtEventLoop",
"ext-pcntl": "For signal handling support when using the StreamSelectLoop",
"ext-uv": "* for ExtUvLoop"
},
"type": "library",
"autoload": {
"psr-4": {
"React\\EventLoop\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"description": "ReactPHP's core reactor event loop that libraries can use for evented I/O.",
"keywords": [
"asynchronous",
"event-loop"
],
"time": "2020-01-01T18:39:52+00:00"
},
{
"name": "react/promise",
"version": "v2.8.0",
"source": {
"type": "git",
"url": "https://github.com/reactphp/promise.git",
"reference": "f3cff96a19736714524ca0dd1d4130de73dbbbc4"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/reactphp/promise/zipball/f3cff96a19736714524ca0dd1d4130de73dbbbc4",
"reference": "f3cff96a19736714524ca0dd1d4130de73dbbbc4",
"shasum": ""
},
"require": {
"php": ">=5.4.0"
},
"require-dev": {
"phpunit/phpunit": "^7.0 || ^6.5 || ^5.7 || ^4.8.36"
},
"type": "library",
"autoload": {
"psr-4": {
"React\\Promise\\": "src/"
},
"files": [
"src/functions_include.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Jan Sorgalla",
"email": "jsorgalla@gmail.com"
}
],
"description": "A lightweight implementation of CommonJS Promises/A for PHP",
"keywords": [
"promise",
"promises"
],
"time": "2020-05-12T15:16:56+00:00"
},
{
"name": "react/promise-timer",
"version": "v1.6.0",
"source": {
"type": "git",
"url": "https://github.com/reactphp/promise-timer.git",
"reference": "daee9baf6ef30c43ea4c86399f828bb5f558f6e6"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/reactphp/promise-timer/zipball/daee9baf6ef30c43ea4c86399f828bb5f558f6e6",
"reference": "daee9baf6ef30c43ea4c86399f828bb5f558f6e6",
"shasum": ""
},
"require": {
"php": ">=5.3",
"react/event-loop": "^1.0 || ^0.5 || ^0.4 || ^0.3.5",
"react/promise": "^3.0 || ^2.7.0 || ^1.2.1"
},
"require-dev": {
"phpunit/phpunit": "^9.0 || ^5.7 || ^4.8.35"
},
"type": "library",
"autoload": {
"psr-4": {
"React\\Promise\\Timer\\": "src/"
},
"files": [
"src/functions_include.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Christian Lück",
"email": "christian@lueck.tv"
}
],
"description": "A trivial implementation of timeouts for Promises, built on top of ReactPHP.",
"homepage": "https://github.com/reactphp/promise-timer",
"keywords": [
"async",
"event-loop",
"promise",
"reactphp",
"timeout",
"timer"
],
"time": "2020-07-10T12:18:06+00:00"
},
{
"name": "react/socket",
"version": "v1.6.0",
"source": {
"type": "git",
"url": "https://github.com/reactphp/socket.git",
"reference": "e2b96b23a13ca9b41ab343268dbce3f8ef4d524a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/reactphp/socket/zipball/e2b96b23a13ca9b41ab343268dbce3f8ef4d524a",
"reference": "e2b96b23a13ca9b41ab343268dbce3f8ef4d524a",
"shasum": ""
},
"require": {
"evenement/evenement": "^3.0 || ^2.0 || ^1.0",
"php": ">=5.3.0",
"react/dns": "^1.1",
"react/event-loop": "^1.0 || ^0.5",
"react/promise": "^2.6.0 || ^1.2.1",
"react/promise-timer": "^1.4.0",
"react/stream": "^1.1"
},
"require-dev": {
"clue/block-react": "^1.2",
"phpunit/phpunit": "^9.3 || ^5.7 || ^4.8.35",
"react/promise-stream": "^1.2"
},
"type": "library",
"autoload": {
"psr-4": {
"React\\Socket\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Christian Lück",
"email": "christian@clue.engineering",
"homepage": "https://clue.engineering/"
},
{
"name": "Cees-Jan Kiewiet",
"email": "reactphp@ceesjankiewiet.nl",
"homepage": "https://wyrihaximus.net/"
},
{
"name": "Jan Sorgalla",
"email": "jsorgalla@gmail.com",
"homepage": "https://sorgalla.com/"
},
{
"name": "Chris Boden",
"email": "cboden@gmail.com",
"homepage": "https://cboden.dev/"
}
],
"description": "Async, streaming plaintext TCP/IP and secure TLS socket server and client connections for ReactPHP",
"keywords": [
"Connection",
"Socket",
"async",
"reactphp",
"stream"
],
"time": "2020-08-28T12:49:05+00:00"
},
{
"name": "react/stream",
"version": "v1.1.1",
"source": {
"type": "git",
"url": "https://github.com/reactphp/stream.git",
"reference": "7c02b510ee3f582c810aeccd3a197b9c2f52ff1a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/reactphp/stream/zipball/7c02b510ee3f582c810aeccd3a197b9c2f52ff1a",
"reference": "7c02b510ee3f582c810aeccd3a197b9c2f52ff1a",
"shasum": ""
},
"require": {
"evenement/evenement": "^3.0 || ^2.0 || ^1.0",
"php": ">=5.3.8",
"react/event-loop": "^1.0 || ^0.5 || ^0.4 || ^0.3.5"
},
"require-dev": {
"clue/stream-filter": "~1.2",
"phpunit/phpunit": "^7.0 || ^6.4 || ^5.7 || ^4.8.35"
},
"type": "library",
"autoload": {
"psr-4": {
"React\\Stream\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"description": "Event-driven readable and writable streams for non-blocking I/O in ReactPHP",
"keywords": [
"event-driven",
"io",
"non-blocking",
"pipe",
"reactphp",
"readable",
"stream",
"writable"
],
"time": "2020-05-04T10:17:57+00:00"
},
{
"name": "sensio/framework-extra-bundle",
"version": "v5.6.1",

View File

@ -13,6 +13,8 @@ twig:
appName: '%appName%'
appCron: '%appCron%'
appMasteridentity: '%appMasteridentity%'
wssuse: '%wssuse%'
wssurl: '%wssurl%'
sondeUse: '%sondeUse%'
sondeUrl: '%sondeUrl%'

View File

@ -62,6 +62,11 @@ app_theme_select:
path: /admin/theme/select/{name}
defaults: { _controller: App\Controller\ThemeController:select, name: "" }
#== Wss ==================================================================================================================
app_wss_sample:
path: /user/wss/sampble
defaults: { _controller: App\Controller\WebsocketController:sample }
#== Sonde ================================================================================================================
app_sonde:
path: /sonde
@ -134,10 +139,6 @@ app_user_profil:
path: /user/profil
defaults: { _controller: App\Controller\UserController:profil }
app_user_survey:
path: /user/surveys
defaults: { _controller: App\Controller\UserController:survey }
#== Group ========================================================================================================
app_group:
path: /admin/group
@ -164,6 +165,10 @@ app_group_info:
defaults: { _controller: App\Controller\GroupController:info }
#== Survey ========================================================================================================
app_survey:
path: /user/survey
defaults: { _controller: App\Controller\SurveyController:list }
app_survey_submit:
path: /user/survey/submit
defaults: { _controller: App\Controller\SurveyController:submit }

View File

@ -47,6 +47,10 @@ parameters:
casLastname: '%env(resolve:CAS_LASTNAME)%'
casFirstname: '%env(resolve:CAS_FIRSTNAME)%'
wssuse: '%env(resolve:WSS_USE)%'
wssport: '%env(resolve:WSS_PORT)%'
wssurl: 'wss://%env(resolve:APP_WEBURL)%/wss%env(resolve:APP_ALIAS)%'
proxyUse: '%env(resolve:PROXY_USE)%'
proxyHost: '%env(resolve:PROXY_HOST)%'
proxyPort: '%env(resolve:PROXY_PORT)%'

View File

@ -12,6 +12,11 @@ h1{
}
.page-maxed {
max-width:1200px;
margin:auto !important;
}
/* Sidebar Styles */
.contentsidebar {
margin-left:250px;

View File

@ -52,6 +52,11 @@ CAS_LASTNAME=lastname
CAS_FIRSTNAME=firstname
# WEBSOCKET
WSS_USE=0
WSS_PORT=5576
# Proxy
PROXY_USE=0
PROXY_HOST=

View File

@ -6,12 +6,15 @@ cd ${DIR}
cd ..
DIR=$(pwd)
# Mise en place du fichier d'environnement model
yes 2>/dev/null | cp $DIR/scripts/.env.model $DIR/.env
# Import des env
. $DIR/.env
. $DIR/.env.local
# Déclaration d'un proxy
if [[ "$PROXY_USE"=="1" ]]
if [[ "$PROXY_USE" == "1" ]]
then
export HTTP_PROXY="$PROXY_HOST:$PROXY_PORT"
export HTTPS_PROXY="$PROXY_HOST:$PROXY_PORT"
@ -23,9 +26,6 @@ then
find $DIR/var/log -mindepth 1 -mtime +7 -delete
fi
# Mise en place du fichier d'environnement model
yes 2>/dev/null | cp $DIR/scripts/.env.model $DIR/.env
# Installation des dépendances composer
echo COMPOSER = Install
composer install --quiet
@ -34,6 +34,12 @@ php bin/console app:AppInit --env=prod
php bin/console app:CronInit --env=prod
php bin/console app:Script --env=prod
# Websocket
if [[ "$WSS_USE" == "1" ]]
then
$DIR/scripts/websocket.sh restart
fi
# Permissions
echo PERMISSIONS
./scripts/perm.sh www-data

View File

@ -0,0 +1,37 @@
#!/bin/bash
# Se positionner sur la racine du projet
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
cd ${DIR}
cd ..
DIR=$(pwd)
# Import des env
. $DIR/.env
. $DIR/.env.local
# Déclaration d'un proxy
if [[ "$WSS_USE" == "1" ]]
then
# Server Websocket
if [[ "$1" != "restartifdown" ]]; then
echo WEBSOCKET = STOP
pid="$(pgrep -a -f app:Websocket| grep $APP_ALIAS)"
if [ -n "${pid}" ]; then
IFS=' ' read -r -a array <<< "$pid"
kill -9 ${array[0]};
fi
fi
# Port LISTEN ?
pid="$(pgrep -a -f app:Websocket| grep $APP_ALIAS)"
restart="yes"
if [ "$1" == "restartifdown" ] && [ -n "${pid}" ] ; then
restart="no"
fi
if [ "$restart" == "yes" ] && [ "$1" != "stop" ] ; then
echo WEBSOCKET = START
bin/console app:Websocket --name $APP_ALIAS & disown
fi
fi

View File

@ -9,6 +9,7 @@ use Symfony\Component\DependencyInjection\ContainerInterface;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\Console\Input\ArrayInput;
use Ramsey\Uuid\Uuid;
use Doctrine\ORM\Mapping\ClassMetadata;
use Doctrine\ORM\Id\AssignedGenerator;
@ -354,6 +355,8 @@ class AppInitCommand extends Command
if(!$entity) {
$this->writelnred('Création du compte admin par défaut avec password admin - Veuillez modifier votre password admin après connexion');
$entity = new User;
$key = Uuid::uuid4();
$entity->setId(0);
$entity->setUsername("admin");
$entity->setPassword("admin");
@ -362,6 +365,7 @@ class AppInitCommand extends Command
$entity->setEmail($this->appmailnoreply);
$entity->setRoles(["ROLE_ADMIN"]);
$entity->setAvatar("admin.jpg");
$entity->setApiKey($key);
$this->em->persist($entity);
}

View File

@ -3,15 +3,11 @@
namespace App\Command;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\Console\Input\ArrayInput;
use Doctrine\ORM\Mapping\ClassMetadata;
use Doctrine\ORM\Id\AssignedGenerator;
use Ramsey\Uuid\Uuid;
use App\Entity\Script;
@ -49,7 +45,7 @@ class ScriptCommand extends Command
$output->writeln('APP = Scripts');
//$this->callscript("test");
$this->callscript("addapikey");
$output->writeln('');
@ -61,7 +57,7 @@ class ScriptCommand extends Command
private function callscript($name) {
$script=$this->em->getRepository("App:Script")->findOneBy(["name"=>$name]);
if(!$script) {
$this->writelnred("== SCRIPT = ".$name);
//$this->writelnred("== SCRIPT = ".$name);
$this->$name();
$script=new Script();
@ -72,8 +68,14 @@ class ScriptCommand extends Command
}
}
private function test() {
$this->writeln("TEST");
private function addapikey() {
$users=$this->em->getRepository("App:User")->findBy(["apikey"=>null]);
foreach($users as $user) {
$key = Uuid::uuid4();
$user->setApikey($key);
$this->em->persist($user);
$this->em->flush();
}
}

View File

@ -10,6 +10,7 @@ use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\Security\Core\Encoder\EncoderFactory;
use Symfony\Component\Security\Core\Encoder\MessageDigestPasswordEncoder;
use Ramsey\Uuid\Uuid;
use App\Entity\Group;
use App\Entity\User;
@ -517,9 +518,11 @@ class SynchroUsersCommand extends Command
if(!$simulate) {
if(!$user) {
$user = new User();
$key = Uuid::uuid4();
$user->setUsername($apiuser->username);
$user->setPassword("NOPASSWORD");
$user->setApiKey($key);
}
$user->setLastname($apiuser->lastname);
@ -678,13 +681,15 @@ class SynchroUsersCommand extends Command
protected function addUser($username,$firstname,$lastname,$email,$usersadmin) {
$user = new User();
$key = Uuid::uuid4();
$user->setUsername($username);
$user->setPassword("NOPASSWORD");
$user->setLastname($lastname);
$user->setFirstname($firstname);
$user->setEmail($email);
$user->setApiKey($key);
// Definition du role
if(in_array($username,$usersadmin))
$role="ROLE_ADMIN";

View File

@ -0,0 +1,53 @@
<?php
namespace App\Command;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Doctrine\ORM\EntityManagerInterface;
use Ratchet\Http\HttpServer;
use Ratchet\Server\IoServer;
use Ratchet\WebSocket\WsServer;
use App\Websocket\MessageHandler;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Input\InputOption;
class WebsocketServerCommand extends Command
{
private $container;
private $em;
public function __construct(ContainerInterface $container,EntityManagerInterface $em)
{
parent::__construct();
$this->container = $container;
$this->em = $em;
}
protected function configure()
{
$this
->setName('app:Websocket')
->setDescription('Lauch Websocket server')
->setHelp('Lauch Websocket server')
->addOption('name',null,InputOption::VALUE_REQUIRED,'Websocket server name',null)
;
}
protected function execute(InputInterface $input, OutputInterface $output)
{
$port = $this->container->getParameter('wssport');
$output->writeln("Starting server on port " . $port);
$server = IoServer::factory(
new HttpServer(
new WsServer(
new MessageHandler($this->container,$this->em)
)
),
$port
);
$server->run();
return 0;
}
}

View File

@ -11,7 +11,7 @@ class HomeController extends AbstractController
{
public function home()
{
return $this->redirectToRoute('app_user_survey');
return $this->redirectToRoute('app_survey');
}
public function admin()

View File

@ -12,6 +12,7 @@ use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
use Symfony\Component\EventDispatcher\EventDispatcher;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Ramsey\Uuid\Uuid;
class SecurityController extends AbstractController
{
@ -84,11 +85,13 @@ class SecurityController extends AbstractController
if (!$exists) {
$user = new User();
$key = Uuid::uuid4();
$user->setUsername($username);
$user->setLastname($lastname);
$user->setFirstname($firstname);
$user->setEmail($email);
$user->setApiKey($key);
$user->setPassword("CASPWD-".$username);
$user->setSalt("CASPWD-".$username);

View File

@ -20,6 +20,17 @@ use App\Form\SurveystatusType as SurveystatusType;
class SurveyController extends AbstractController
{
public function list()
{
$guests=$this->getUser()->getGuests();
return $this->render('Survey/survey.html.twig', [
'useheader' => true,
'usesidebar' => false,
'guests' => $guests,
]);
}
public function submit(CreateSurveyFlow $flow)
{
$em = $this->getDoctrine()->getManager();

View File

@ -5,7 +5,7 @@ namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Form\FormError;
use Ramsey\Uuid\Uuid;
use App\Entity\User as Entity;
use App\Form\UserType as Form;
@ -37,7 +37,9 @@ class UserController extends AbstractController
// Initialisation de l'enregistrement
$em = $this->getDoctrine()->getManager();
$data = new Entity();
$key = Uuid::uuid4();
$data->setAvatar("noavatar.png");
$data->setApiKey($key);
// Création du formulaire
$form = $this->createForm(Form::class,$data,array("mode"=>"submit","appAuth"=>$this->getParameter("appAuth"),"appMasteridentity"=>$this->getParameter("appMasteridentity")));
@ -206,7 +208,7 @@ class UserController extends AbstractController
$response->headers->set('Content-Type', 'application/json');
return $response;
}
public function info(Request $request)
{
// S'assurer que c'est un appel ajax
@ -228,22 +230,6 @@ class UserController extends AbstractController
$response->headers->set('Content-Type', 'application/json');
return $response;
}
/**
* Affiche la page d'accueil d'un utilisateur
* - La liste de ses sondages
* - La liste des sondages auxquels il participe
*/
public function survey()
{
$guests=$this->getUser()->getGuests();
return $this->render($this->render.'survey.html.twig', [
'useheader' => true,
'usesidebar' => false,
'guests' => $guests,
]);
}
protected function getErrorForm($id,$form,$request,$data,$mode) {
if ($form->get('submit')->isClicked()&&$mode=="delete") {
@ -260,5 +246,5 @@ class UserController extends AbstractController
$request->getSession()->getFlashBag()->add("error", $error->getMessage());
}
}
}
}
}

View File

@ -103,7 +103,8 @@ class UserType extends AbstractType
$builder->add('apikey',
TextType::class, [
"label" =>"Clé Accès",
"required" => false
"required" => true,
"disabled" => true,
]
);

View File

@ -0,0 +1,141 @@
<?php
namespace App\Websocket;
use Exception;
use Ratchet\ConnectionInterface;
use Ratchet\MessageComponentInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Doctrine\ORM\EntityManagerInterface;
use SplObjectStorage;
use App\Entity\Scrum;
use App\Entity\Scrumcolumn;
use App\Entity\Scrumwidget;
class MessageHandler implements MessageComponentInterface
{
protected $container;
protected $em;
protected $clients;
private $channels;
private $channeltypes;
private $channelkeys;
private $userconns;
private $userkeys;
public function __construct(ContainerInterface $container, EntityManagerInterface $em)
{
$this->container = $container;
$this->em = $em;
$this->clients = new SplObjectStorage;
$this->channels = [];
$this->channeltypes = [];
$this->channelkeys = [];
$this->userconns = [];
$this->userkeys = [];
}
public function onOpen(ConnectionInterface $conn)
{
$this->clients->attach($conn);
$this->userconns[$conn->resourceId] = $conn;
}
public function onClose(ConnectionInterface $conn)
{
$data= new \stdClass;
$data->command = "adead";
// Envoyer le message de deconnection
if (isset($this->channels[$conn->resourceId])) {
$this->sendMessage($conn,$data,"other");
}
// Détacher
$this->clients->detach($conn);
unset($this->userconns[$conn->resourceId]);
unset($this->userkeys[$conn->resourceId]);
unset($this->channels[$conn->resourceId]);
}
public function onError(ConnectionInterface $conn, Exception $e)
{
$conn->close();
}
public function onMessage(ConnectionInterface $conn, $msg)
{
$data = json_decode($msg);
switch ($data->command) {
case "subscribe":
$this->channels[$conn->resourceId] = $data->channel;
$this->channeltypes[$conn->resourceId] = $data->channeltype;
$this->channelkeys[$conn->resourceId] = $data->channelkey;
$this->userkeys[$conn->resourceId] = $data->userkey;
break;
case "meto":
if (isset($this->channels[$conn->resourceId])) {
$this->sendMessage($conn,$data,"other");
}
break;
case "alive":
if (isset($this->channels[$conn->resourceId])) {
$this->sendMessage($conn,$data);
}
break;
default:
if (isset($this->channels[$conn->resourceId])) {
switch ($this->channeltypes[$conn->resourceId]) {
//case "type": $this->onMessageYype($conn,$data); break;
default: $this->sendMessage($conn,$data);
}
}
break;
}
}
private function sendMessage(ConnectionInterface $conn, $data, $dest="all") {
$target = $this->channels[$conn->resourceId];
foreach ($this->channels as $id=>$channel) {
if ($channel == $target) {
// dest = all - tout le monde meme l'expediteur
// dest = other - tout le monde sauf l'expedituer
// dest = me - seumlement l'expediteur
if($dest=="all"||($dest=="other"&&$id!=$conn->resourceId)||($dest=="me"&&$id==$conn->resourceId)) {
// From
$key= $this->userkeys[$conn->resourceId];
$from=$this->em->getRepository("App:User")->findOneBy(["apikey"=>$key]);
// To
$key= $this->userkeys[$id];
$to=$this->em->getRepository("App:User")->findOneBy(["apikey"=>$key]);
// Send
if($from && $to) {
$data->from= new \stdClass;
$data->from->id = $from->getId();
$data->from->username = $from->getUsername();
$data->from->displayname = $from->getDisplayname();
$data->from->avatar = $this->getAvatar($from->getAvatar());
$data->log="== GET MSG from ".$data->from->username." to ".$to->getUsername()." = ".$data->command;
$this->userconns[$id]->send(json_encode($data));
}
}
}
}
}
private function getAvatar($avatar) {
if(stripos($avatar,"http")===0)
return $avatar;
else
return "/".$this->container->getParameter("appAlias")."/uploads/avatar/".$avatar;
}
}

View File

@ -2,6 +2,9 @@
"brick/math": {
"version": "0.9.1"
},
"cboden/ratchet": {
"version": "v0.4.3"
},
"craue/formflow-bundle": {
"version": "3.3.2"
},
@ -87,6 +90,9 @@
"egulias/email-validator": {
"version": "2.1.17"
},
"evenement/evenement": {
"version": "v3.0.1"
},
"exsyst/swagger": {
"version": "v0.4.1"
},
@ -114,6 +120,9 @@
"config/packages/fos_rest.yaml"
]
},
"guzzlehttp/psr7": {
"version": "1.7.0"
},
"jasig/phpcas": {
"version": "1.3.8"
},
@ -200,18 +209,48 @@
"psr/event-dispatcher": {
"version": "1.0.0"
},
"psr/http-message": {
"version": "1.0.1"
},
"psr/link": {
"version": "1.0.0"
},
"psr/log": {
"version": "1.1.2"
},
"ralouphie/getallheaders": {
"version": "3.0.3"
},
"ramsey/collection": {
"version": "1.1.1"
},
"ramsey/uuid": {
"version": "4.1.1"
},
"ratchet/rfc6455": {
"version": "v0.3"
},
"react/cache": {
"version": "v1.1.0"
},
"react/dns": {
"version": "v1.4.0"
},
"react/event-loop": {
"version": "v1.1.1"
},
"react/promise": {
"version": "v2.8.0"
},
"react/promise-timer": {
"version": "v1.6.0"
},
"react/socket": {
"version": "v1.6.0"
},
"react/stream": {
"version": "v1.1.1"
},
"sensio/framework-extra-bundle": {
"version": "5.2",
"recipe": {

View File

@ -1,7 +1,9 @@
{% extends "base.html.twig" %}
{% block body %}
{% if wssuse and app.user %}
{{ render(path("app_wss_sample")) }}
{% endif %}
{% endblock %}

View File

@ -1,4 +1,12 @@
$(document).ready(function() {
$(".pick-a-color").spectrum(
{
type: "text",
showAlpha: false
}
);
var doit = true;
$("a[data-method]").on('click',function(){
@ -21,3 +29,23 @@ function ModalLoad(idmodal,title,path) {
$("#"+idmodal+" iframe").attr("src",path);
$("#"+idmodal).modal("show");
}
{% if wssuse %}
function subscribe(channeltype,channelkey,userkey) {
console.log("== SUBSCRIBE "+channeltype+"-"+channelkey+" with userkey "+userkey);
conn.send(JSON.stringify({
command: "subscribe",
log: "",
channel: channeltype+"-"+channelkey,
channeltype: channeltype,
channelkey: channelkey,
userkey: userkey
}));
}
function sendMessage(msg) {
json=JSON.stringify(msg);
console.log("== SEND MSG = "+json);
conn.send(json);
}
{% endif %}

View File

@ -13,7 +13,7 @@
{% block encorelinktags %}
{% endblock encorelinktags %}
<link type="text/css" rel="stylesheet" href="{{ asset('bundles/craueformflow/css/buttons.css') }}" />
<link rel="shortcut icon" href="/{{ appAlias }}/uploads/logo/{{app.session.get("logolight")}}" />
</head>
@ -34,6 +34,15 @@
{% endblock %}
</style>
{{ encore_entry_script_tags('app') }}
{% block encorescripttags %}
{% endblock %}
<script>
{{ include('Include/javascript.js.twig') }}
</script>
{% set class="" %}
{% if usemonocolor is defined and usemonocolor %}
@ -93,7 +102,7 @@
</nav>
{% endif %}
<main id="main" class="container-fluid">
<main id="main" class="container-fluid {% if maxwidth is defined and maxwidth %} page-maxed {% endif %}">
{% set contentsidebar="" %}
{% if usesidebar is defined and usesidebar %}
{% set contentsidebar="contentsidebar" %}
@ -111,19 +120,20 @@
<div class="modal-dialog modal-lg" role="document">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">Modification Evènement</h5>
<h4 class="modal-title"></h4>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<iframe id="framemodal" frameborder=0 width="100%" height="600px"></iframe>
<iframe frameborder=0 width="100%" height="600px"></iframe>
</div>
</div>
</div>
</div>
<div id="mymodallarge" class="modal fade" tabindex="-1" role="dialog">
<div class="modal-dialog modal-xl">
<div class="modal-content">
@ -138,28 +148,12 @@
</div>
</div>
{{ encore_entry_script_tags('app') }}
{% block encorescripttags %}
{% endblock %}
{% block localexternalscript %}
{% endblock %}
<script>
{{ include('Include/javascript.js.twig') }}
</script>
<script>
$(".pick-a-color").spectrum(
{
type: "text",
showAlpha: false
}
);
{% block localjavascript %}
{% endblock %}

View File

@ -1 +1,2 @@
* * * * * root /var/www/html/ninesurvey/scripts/cron.sh &>/dev/null
* * * * * root /var/www/html/ninesurvey/scripts/websocket.sh restartifdown &>/dev/null