diff --git a/.editorconfig b/.editorconfig old mode 100644 new mode 100755 diff --git a/.env b/.env old mode 100644 new mode 100755 index 9ffd25c..e6c326f --- a/.env +++ b/.env @@ -27,12 +27,15 @@ DEFAULT_URI=http://localhost ###< symfony/routing ### ###> doctrine/doctrine-bundle ### -DATABASE_URL=mysql://root:root@172.28.2.1:3306/anyvideo?mariadb-10.4.34 +DATABASE_URL=mysql://root:root@172.28.2.1:3306/video?mariadb-10.4.34 ###< doctrine/doctrine-bundle ### ###> symfony/messenger ### -# Choose one of the transports below -# MESSENGER_TRANSPORT_DSN=amqp://guest:guest@localhost:5672/%2f/messages -# MESSENGER_TRANSPORT_DSN=redis://localhost:6379/messages MESSENGER_TRANSPORT_DSN=doctrine://default?auto_setup=0 ###< symfony/messenger ### + +###> LISTMONK/API ### +LISTMONK_BASE_URL=https://listmonk.powerpme.com +LISTMONK_API_USER= +LISTMONK_TOKEN= +###> LISTMONK/API ### \ No newline at end of file diff --git a/.env.dev b/.env.dev old mode 100644 new mode 100755 diff --git a/.gitignore b/.gitignore old mode 100644 new mode 100755 diff --git a/README.md b/README.md old mode 100644 new mode 100755 diff --git a/composer.json b/composer.json old mode 100644 new mode 100755 index 6b2977b..7cc8f09 --- a/composer.json +++ b/composer.json @@ -17,15 +17,18 @@ "symfony/flex": "^2", "symfony/form": "7.4.*", "symfony/framework-bundle": "7.4.*", + "symfony/http-client": "7.4.*", "symfony/messenger": "7.4.*", "symfony/mime": "7.4.*", + "symfony/monolog-bundle": "^4.0", "symfony/process": "7.4.*", "symfony/runtime": "7.4.*", "symfony/security-bundle": "7.4.*", "symfony/translation": "7.4.*", "symfony/twig-bundle": "7.4.*", "symfony/validator": "7.4.*", - "symfony/yaml": "7.4.*" + "symfony/yaml": "7.4.*", + "zytzagoo/smtp-validate-email": "^1.1" }, "config": { "allow-plugins": { diff --git a/composer.lock b/composer.lock old mode 100644 new mode 100755 index 9d8eab6..054aef0 --- 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": "fa4e9dc1d92013ffdfd4e67f8fc84fde", + "content-hash": "74f141d0409156b15f70c662450fd66a", "packages": [ { "name": "doctrine/collections", @@ -1120,6 +1120,109 @@ }, "time": "2026-02-08T16:21:46+00:00" }, + { + "name": "monolog/monolog", + "version": "3.10.0", + "source": { + "type": "git", + "url": "https://github.com/Seldaek/monolog.git", + "reference": "b321dd6749f0bf7189444158a3ce785cc16d69b0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Seldaek/monolog/zipball/b321dd6749f0bf7189444158a3ce785cc16d69b0", + "reference": "b321dd6749f0bf7189444158a3ce785cc16d69b0", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "psr/log": "^2.0 || ^3.0" + }, + "provide": { + "psr/log-implementation": "3.0.0" + }, + "require-dev": { + "aws/aws-sdk-php": "^3.0", + "doctrine/couchdb": "~1.0@dev", + "elasticsearch/elasticsearch": "^7 || ^8", + "ext-json": "*", + "graylog2/gelf-php": "^1.4.2 || ^2.0", + "guzzlehttp/guzzle": "^7.4.5", + "guzzlehttp/psr7": "^2.2", + "mongodb/mongodb": "^1.8 || ^2.0", + "php-amqplib/php-amqplib": "~2.4 || ^3", + "php-console/php-console": "^3.1.8", + "phpstan/phpstan": "^2", + "phpstan/phpstan-deprecation-rules": "^2", + "phpstan/phpstan-strict-rules": "^2", + "phpunit/phpunit": "^10.5.17 || ^11.0.7", + "predis/predis": "^1.1 || ^2", + "rollbar/rollbar": "^4.0", + "ruflin/elastica": "^7 || ^8", + "symfony/mailer": "^5.4 || ^6", + "symfony/mime": "^5.4 || ^6" + }, + "suggest": { + "aws/aws-sdk-php": "Allow sending log messages to AWS services like DynamoDB", + "doctrine/couchdb": "Allow sending log messages to a CouchDB server", + "elasticsearch/elasticsearch": "Allow sending log messages to an Elasticsearch server via official client", + "ext-amqp": "Allow sending log messages to an AMQP server (1.0+ required)", + "ext-curl": "Required to send log messages using the IFTTTHandler, the LogglyHandler, the SendGridHandler, the SlackWebhookHandler or the TelegramBotHandler", + "ext-mbstring": "Allow to work properly with unicode symbols", + "ext-mongodb": "Allow sending log messages to a MongoDB server (via driver)", + "ext-openssl": "Required to send log messages using SSL", + "ext-sockets": "Allow sending log messages to a Syslog server (via UDP driver)", + "graylog2/gelf-php": "Allow sending log messages to a GrayLog2 server", + "mongodb/mongodb": "Allow sending log messages to a MongoDB server (via library)", + "php-amqplib/php-amqplib": "Allow sending log messages to an AMQP server using php-amqplib", + "rollbar/rollbar": "Allow sending log messages to Rollbar", + "ruflin/elastica": "Allow sending log messages to an Elastic Search server" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Monolog\\": "src/Monolog" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "https://seld.be" + } + ], + "description": "Sends your logs to files, sockets, inboxes, databases and various web services", + "homepage": "https://github.com/Seldaek/monolog", + "keywords": [ + "log", + "logging", + "psr-3" + ], + "support": { + "issues": "https://github.com/Seldaek/monolog/issues", + "source": "https://github.com/Seldaek/monolog/tree/3.10.0" + }, + "funding": [ + { + "url": "https://github.com/Seldaek", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/monolog/monolog", + "type": "tidelift" + } + ], + "time": "2026-01-02T08:56:05+00:00" + }, { "name": "psr/cache", "version": "3.0.0", @@ -3023,6 +3126,189 @@ ], "time": "2026-05-13T12:04:42+00:00" }, + { + "name": "symfony/http-client", + "version": "v7.4.13", + "source": { + "type": "git", + "url": "https://github.com/symfony/http-client.git", + "reference": "e8a112b8415707265a7e614278136a9d92989a6a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/http-client/zipball/e8a112b8415707265a7e614278136a9d92989a6a", + "reference": "e8a112b8415707265a7e614278136a9d92989a6a", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "psr/log": "^1|^2|^3", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/http-client-contracts": "~3.4.4|^3.5.2", + "symfony/polyfill-php83": "^1.29", + "symfony/service-contracts": "^2.5|^3" + }, + "conflict": { + "amphp/amp": "<2.5", + "amphp/socket": "<1.1", + "php-http/discovery": "<1.15", + "symfony/http-foundation": "<6.4" + }, + "provide": { + "php-http/async-client-implementation": "*", + "php-http/client-implementation": "*", + "psr/http-client-implementation": "1.0", + "symfony/http-client-implementation": "3.0" + }, + "require-dev": { + "amphp/http-client": "^4.2.1|^5.0", + "amphp/http-tunnel": "^1.0|^2.0", + "guzzlehttp/promises": "^1.4|^2.0", + "nyholm/psr7": "^1.0", + "php-http/httplug": "^1.0|^2.0", + "psr/http-client": "^1.0", + "symfony/amphp-http-client-meta": "^1.0|^2.0", + "symfony/cache": "^6.4|^7.0|^8.0", + "symfony/dependency-injection": "^6.4|^7.0|^8.0", + "symfony/http-kernel": "^6.4|^7.0|^8.0", + "symfony/messenger": "^6.4|^7.0|^8.0", + "symfony/process": "^6.4|^7.0|^8.0", + "symfony/rate-limiter": "^6.4|^7.0|^8.0", + "symfony/stopwatch": "^6.4|^7.0|^8.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\HttpClient\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides powerful methods to fetch HTTP resources synchronously or asynchronously", + "homepage": "https://symfony.com", + "keywords": [ + "http" + ], + "support": { + "source": "https://github.com/symfony/http-client/tree/v7.4.13" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2026-05-24T09:57:54+00:00" + }, + { + "name": "symfony/http-client-contracts", + "version": "v3.7.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/http-client-contracts.git", + "reference": "4a2d00c37651c0bdc2b9e1c773487a8bf4edb12d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/http-client-contracts/zipball/4a2d00c37651c0bdc2b9e1c773487a8bf4edb12d", + "reference": "4a2d00c37651c0bdc2b9e1c773487a8bf4edb12d", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, + "branch-alias": { + "dev-main": "3.7-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\HttpClient\\": "" + }, + "exclude-from-classmap": [ + "/Test/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to HTTP clients", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/http-client-contracts/tree/v3.7.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2026-03-06T13:17:50+00:00" + }, { "name": "symfony/http-foundation", "version": "v7.4.8", @@ -3407,6 +3693,168 @@ ], "time": "2026-05-23T16:22:37+00:00" }, + { + "name": "symfony/monolog-bridge", + "version": "v7.4.12", + "source": { + "type": "git", + "url": "https://github.com/symfony/monolog-bridge.git", + "reference": "20bb2345ac7a9dd57724b6b7ada92c6d7d67b4b8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/monolog-bridge/zipball/20bb2345ac7a9dd57724b6b7ada92c6d7d67b4b8", + "reference": "20bb2345ac7a9dd57724b6b7ada92c6d7d67b4b8", + "shasum": "" + }, + "require": { + "monolog/monolog": "^3", + "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/http-kernel": "^6.4|^7.0|^8.0", + "symfony/service-contracts": "^2.5|^3" + }, + "conflict": { + "symfony/console": "<6.4", + "symfony/http-foundation": "<6.4", + "symfony/security-core": "<6.4" + }, + "require-dev": { + "symfony/console": "^6.4|^7.0|^8.0", + "symfony/http-client": "^6.4|^7.0|^8.0", + "symfony/mailer": "^6.4|^7.0|^8.0", + "symfony/messenger": "^6.4|^7.0|^8.0", + "symfony/mime": "^6.4|^7.0|^8.0", + "symfony/security-core": "^6.4|^7.0|^8.0", + "symfony/var-dumper": "^6.4|^7.0|^8.0" + }, + "type": "symfony-bridge", + "autoload": { + "psr-4": { + "Symfony\\Bridge\\Monolog\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides integration for Monolog with various Symfony components", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/monolog-bridge/tree/v7.4.12" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2026-05-20T07:20:23+00:00" + }, + { + "name": "symfony/monolog-bundle", + "version": "v4.0.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/monolog-bundle.git", + "reference": "c012c6aba13129eb02aa7dd61e66e720911d8598" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/monolog-bundle/zipball/c012c6aba13129eb02aa7dd61e66e720911d8598", + "reference": "c012c6aba13129eb02aa7dd61e66e720911d8598", + "shasum": "" + }, + "require": { + "composer-runtime-api": "^2.0", + "monolog/monolog": "^3.5", + "php": ">=8.2", + "symfony/config": "^7.3 || ^8.0", + "symfony/dependency-injection": "^7.3 || ^8.0", + "symfony/http-kernel": "^7.3 || ^8.0", + "symfony/monolog-bridge": "^7.3 || ^8.0", + "symfony/polyfill-php84": "^1.30" + }, + "require-dev": { + "phpunit/phpunit": "^11.5.41 || ^12.3", + "symfony/console": "^7.3 || ^8.0", + "symfony/yaml": "^7.3 || ^8.0" + }, + "type": "symfony-bundle", + "autoload": { + "psr-4": { + "Symfony\\Bundle\\MonologBundle\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony MonologBundle", + "homepage": "https://symfony.com", + "keywords": [ + "log", + "logging" + ], + "support": { + "issues": "https://github.com/symfony/monolog-bundle/issues", + "source": "https://github.com/symfony/monolog-bundle/tree/v4.0.2" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2026-04-02T18:27:21+00:00" + }, { "name": "symfony/options-resolver", "version": "v7.4.8", @@ -6135,6 +6583,60 @@ } ], "time": "2026-05-17T07:41:26+00:00" + }, + { + "name": "zytzagoo/smtp-validate-email", + "version": "v1.1.1", + "source": { + "type": "git", + "url": "https://github.com/zytzagoo/smtp-validate-email.git", + "reference": "22fb5fed11608b66c0c64f8f2ed49f206295e90b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/zytzagoo/smtp-validate-email/zipball/22fb5fed11608b66c0c64f8f2ed49f206295e90b", + "reference": "22fb5fed11608b66c0c64f8f2ed49f206295e90b", + "shasum": "" + }, + "require": { + "php": ">=7.2||>=8" + }, + "require-dev": { + "dealerdirect/phpcodesniffer-composer-installer": "^0.7.0", + "phpcompatibility/php-compatibility": "^9.0", + "phpunit/phpunit": "^9.5", + "squizlabs/php_codesniffer": "^3.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "SMTPValidateEmail\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "GPL-3.0-or-later" + ], + "authors": [ + { + "name": "Tomaš Trkulja [zytzagoo]", + "email": "zyt@zytzagoo.net" + } + ], + "description": "Perform email address verification via SMTP", + "homepage": "https://github.com/zytzagoo/smtp-validate-email", + "keywords": [ + "email", + "smtp", + "validator", + "verify" + ], + "support": { + "docs": "https://github.com/zytzagoo/smtp-validate-email", + "issues": "https://github.com/zytzagoo/smtp-validate-email/issues", + "source": "https://github.com/zytzagoo/smtp-validate-email" + }, + "time": "2022-09-12T14:00:41+00:00" } ], "packages-dev": [ diff --git a/config/bundles.php b/config/bundles.php old mode 100644 new mode 100755 index a77783f..65b0945 --- a/config/bundles.php +++ b/config/bundles.php @@ -8,4 +8,5 @@ return [ Doctrine\Bundle\MigrationsBundle\DoctrineMigrationsBundle::class => ['all' => true], Symfony\Bundle\SecurityBundle\SecurityBundle::class => ['all' => true], Symfony\Bundle\WebProfilerBundle\WebProfilerBundle::class => ['dev' => true, 'test' => true], + Symfony\Bundle\MonologBundle\MonologBundle::class => ['all' => true], ]; diff --git a/config/packages/cache.yaml b/config/packages/cache.yaml old mode 100644 new mode 100755 diff --git a/config/packages/csrf.yaml b/config/packages/csrf.yaml old mode 100644 new mode 100755 diff --git a/config/packages/doctrine.yaml b/config/packages/doctrine.yaml old mode 100644 new mode 100755 diff --git a/config/packages/doctrine_migrations.yaml b/config/packages/doctrine_migrations.yaml old mode 100644 new mode 100755 diff --git a/config/packages/framework.yaml b/config/packages/framework.yaml old mode 100644 new mode 100755 diff --git a/config/packages/messenger.yaml b/config/packages/messenger.yaml old mode 100644 new mode 100755 diff --git a/config/packages/monolog.yaml b/config/packages/monolog.yaml new file mode 100644 index 0000000..bb59708 --- /dev/null +++ b/config/packages/monolog.yaml @@ -0,0 +1,55 @@ +monolog: + channels: + - deprecation # Deprecations are logged in the dedicated "deprecation" channel when it exists + +when@dev: + monolog: + handlers: + main: + type: stream + path: "%kernel.logs_dir%/%kernel.environment%.log" + level: debug + channels: ["!event"] + console: + type: console + process_psr_3_messages: false + channels: ["!event", "!doctrine", "!console"] + +when@test: + monolog: + handlers: + main: + type: fingers_crossed + action_level: error + handler: nested + excluded_http_codes: [404, 405] + channels: ["!event"] + nested: + type: stream + path: "%kernel.logs_dir%/%kernel.environment%.log" + level: debug + +when@prod: + monolog: + handlers: + main: + type: fingers_crossed + action_level: error + handler: nested + excluded_http_codes: [404, 405] + channels: ["!deprecation"] + buffer_size: 50 # How many messages should be saved? Prevent memory leaks + nested: + type: stream + path: php://stderr + level: debug + formatter: monolog.formatter.json + console: + type: console + process_psr_3_messages: false + channels: ["!event", "!doctrine"] + deprecation: + type: stream + channels: [deprecation] + path: php://stderr + formatter: monolog.formatter.json diff --git a/config/packages/property_info.yaml b/config/packages/property_info.yaml old mode 100644 new mode 100755 diff --git a/config/packages/routing.yaml b/config/packages/routing.yaml old mode 100644 new mode 100755 diff --git a/config/packages/security.yaml b/config/packages/security.yaml old mode 100644 new mode 100755 diff --git a/config/packages/translation.yaml b/config/packages/translation.yaml old mode 100644 new mode 100755 diff --git a/config/packages/twig.yaml b/config/packages/twig.yaml old mode 100644 new mode 100755 diff --git a/config/packages/validator.yaml b/config/packages/validator.yaml old mode 100644 new mode 100755 diff --git a/config/packages/web_profiler.yaml b/config/packages/web_profiler.yaml old mode 100644 new mode 100755 diff --git a/config/preload.php b/config/preload.php old mode 100644 new mode 100755 diff --git a/config/reference.php b/config/reference.php old mode 100644 new mode 100755 index 994eb0e..a954280 --- a/config/reference.php +++ b/config/reference.php @@ -472,7 +472,7 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param; * }, * disallow_search_engine_index?: bool|Param, // Enabled by default when debug is enabled. // Default: true * http_client?: bool|array{ // HTTP Client configuration - * enabled?: bool|Param, // Default: false + * enabled?: bool|Param, // Default: true * max_host_connections?: int|Param, // The maximum number of connections to a single host. * default_options?: array{ * headers?: array, @@ -1255,6 +1255,149 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param; * intercept_redirects?: bool|Param, // Default: false * excluded_ajax_paths?: scalar|Param|null, // Default: "^/((index|app(_[\\w]+)?)\\.php/)?_wdt" * } + * @psalm-type MonologConfig = array{ + * use_microseconds?: scalar|Param|null, // Default: true + * channels?: list, + * handlers?: array, + * }>, + * accepted_levels?: list, + * min_level?: scalar|Param|null, // Default: "DEBUG" + * max_level?: scalar|Param|null, // Default: "EMERGENCY" + * buffer_size?: scalar|Param|null, // Default: 0 + * flush_on_overflow?: bool|Param, // Default: false + * handler?: scalar|Param|null, + * url?: scalar|Param|null, + * exchange?: scalar|Param|null, + * exchange_name?: scalar|Param|null, // Default: "log" + * channel?: scalar|Param|null, // Default: null + * bot_name?: scalar|Param|null, // Default: "Monolog" + * use_attachment?: scalar|Param|null, // Default: true + * use_short_attachment?: scalar|Param|null, // Default: false + * include_extra?: scalar|Param|null, // Default: false + * icon_emoji?: scalar|Param|null, // Default: null + * webhook_url?: scalar|Param|null, + * exclude_fields?: list, + * token?: scalar|Param|null, + * region?: scalar|Param|null, + * source?: scalar|Param|null, + * use_ssl?: bool|Param, // Default: true + * user?: mixed, + * title?: scalar|Param|null, // Default: null + * host?: scalar|Param|null, // Default: null + * port?: scalar|Param|null, // Default: 514 + * config?: list, + * members?: list, + * connection_string?: scalar|Param|null, + * timeout?: scalar|Param|null, + * time?: scalar|Param|null, // Default: 60 + * deduplication_level?: scalar|Param|null, // Default: 400 + * store?: scalar|Param|null, // Default: null + * connection_timeout?: scalar|Param|null, + * persistent?: bool|Param, + * message_type?: scalar|Param|null, // Default: 0 + * parse_mode?: scalar|Param|null, // Default: null + * disable_webpage_preview?: bool|Param|null, // Default: null + * disable_notification?: bool|Param|null, // Default: null + * split_long_messages?: bool|Param, // Default: false + * delay_between_messages?: bool|Param, // Default: false + * topic?: int|Param, // Default: null + * factor?: int|Param, // Default: 1 + * tags?: string|list, + * console_formatter_options?: mixed, // Default: [] + * formatter?: scalar|Param|null, + * nested?: bool|Param, // Default: false + * publisher?: string|array{ + * id?: scalar|Param|null, + * hostname?: scalar|Param|null, + * port?: scalar|Param|null, // Default: 12201 + * chunk_size?: scalar|Param|null, // Default: 1420 + * encoder?: "json"|"compressed_json"|Param, + * }, + * mongodb?: string|array{ + * id?: scalar|Param|null, // ID of a MongoDB\Client service + * uri?: scalar|Param|null, + * username?: scalar|Param|null, + * password?: scalar|Param|null, + * database?: scalar|Param|null, // Default: "monolog" + * collection?: scalar|Param|null, // Default: "logs" + * }, + * elasticsearch?: string|array{ + * id?: scalar|Param|null, + * hosts?: list, + * host?: scalar|Param|null, + * port?: scalar|Param|null, // Default: 9200 + * transport?: scalar|Param|null, // Default: "Http" + * user?: scalar|Param|null, // Default: null + * password?: scalar|Param|null, // Default: null + * }, + * index?: scalar|Param|null, // Default: "monolog" + * document_type?: scalar|Param|null, // Default: "logs" + * ignore_error?: scalar|Param|null, // Default: false + * redis?: string|array{ + * id?: scalar|Param|null, + * host?: scalar|Param|null, + * password?: scalar|Param|null, // Default: null + * port?: scalar|Param|null, // Default: 6379 + * database?: scalar|Param|null, // Default: 0 + * key_name?: scalar|Param|null, // Default: "monolog_redis" + * }, + * predis?: string|array{ + * id?: scalar|Param|null, + * host?: scalar|Param|null, + * }, + * from_email?: scalar|Param|null, + * to_email?: string|list, + * subject?: scalar|Param|null, + * content_type?: scalar|Param|null, // Default: null + * headers?: list, + * mailer?: scalar|Param|null, // Default: null + * email_prototype?: string|array{ + * id?: scalar|Param|null, + * method?: scalar|Param|null, // Default: null + * }, + * verbosity_levels?: array{ + * VERBOSITY_QUIET?: scalar|Param|null, // Default: "ERROR" + * VERBOSITY_NORMAL?: scalar|Param|null, // Default: "WARNING" + * VERBOSITY_VERBOSE?: scalar|Param|null, // Default: "NOTICE" + * VERBOSITY_VERY_VERBOSE?: scalar|Param|null, // Default: "INFO" + * VERBOSITY_DEBUG?: scalar|Param|null, // Default: "DEBUG" + * }, + * channels?: string|array{ + * type?: scalar|Param|null, + * elements?: list, + * }, + * }>, + * } * @psalm-type ConfigType = array{ * imports?: ImportsConfig, * parameters?: ParametersConfig, @@ -1264,6 +1407,7 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param; * doctrine?: DoctrineConfig, * doctrine_migrations?: DoctrineMigrationsConfig, * security?: SecurityConfig, + * monolog?: MonologConfig, * "when@dev"?: array{ * imports?: ImportsConfig, * parameters?: ParametersConfig, @@ -1275,6 +1419,7 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param; * doctrine_migrations?: DoctrineMigrationsConfig, * security?: SecurityConfig, * web_profiler?: WebProfilerConfig, + * monolog?: MonologConfig, * }, * "when@prod"?: array{ * imports?: ImportsConfig, @@ -1285,6 +1430,7 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param; * doctrine?: DoctrineConfig, * doctrine_migrations?: DoctrineMigrationsConfig, * security?: SecurityConfig, + * monolog?: MonologConfig, * }, * "when@test"?: array{ * imports?: ImportsConfig, @@ -1296,6 +1442,7 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param; * doctrine_migrations?: DoctrineMigrationsConfig, * security?: SecurityConfig, * web_profiler?: WebProfilerConfig, + * monolog?: MonologConfig, * }, * ...projectDir = $params->get('kernel.project_dir'); } @@ -349,6 +351,16 @@ final class HomeController extends AbstractController #[Route('/test', name: 'app_test')] public function test() { + die; + $this->mailer->send( + ['maher.tili@gmail.com'], + 7, + ['name'=> 'Monjie', 'video'=> 'mon happy movie test', 'date'=> '19/06/2026 15:45', 'url'=> 'https://video.powerpme.com/downloder/user/4/'], + 'external', + ['Content-Type' => 'application/json; charset=utf-8'] + ); + + dd($result); die; return $this->render('/frontend/test.html.twig', []); } diff --git a/src/Controller/Frontend/SecurityController.php b/src/Controller/Frontend/SecurityController.php old mode 100644 new mode 100755 diff --git a/src/Entity/.gitignore b/src/Entity/.gitignore old mode 100644 new mode 100755 diff --git a/src/Entity/AnonymeDownloader.php b/src/Entity/AnonymeDownloader.php old mode 100644 new mode 100755 diff --git a/src/Entity/User.php b/src/Entity/User.php old mode 100644 new mode 100755 diff --git a/src/Entity/UserDownloader.php b/src/Entity/UserDownloader.php old mode 100644 new mode 100755 diff --git a/src/EventListener/LocaleSubscriber.php b/src/EventListener/LocaleSubscriber.php old mode 100644 new mode 100755 diff --git a/src/Form/UserInfoCnxType.php b/src/Form/UserInfoCnxType.php old mode 100644 new mode 100755 diff --git a/src/Form/UserRegistrationType.php b/src/Form/UserRegistrationType.php old mode 100644 new mode 100755 diff --git a/src/Kernel.php b/src/Kernel.php old mode 100644 new mode 100755 diff --git a/src/MessageHandler/DownloaderVideoHandler.php b/src/MessageHandler/DownloaderVideoHandler.php old mode 100644 new mode 100755 index c57a38e..b216c65 --- a/src/MessageHandler/DownloaderVideoHandler.php +++ b/src/MessageHandler/DownloaderVideoHandler.php @@ -9,6 +9,8 @@ use Symfony\Component\Process\Exception\ProcessFailedException; use Symfony\Component\Process\Process; use Symfony\Component\HttpKernel\KernelInterface; use Symfony\Component\HttpFoundation\File\File; +use Symfony\Component\Routing\Generator\UrlGeneratorInterface; +use App\Service\Frontend\ListmonkMailerService; #[AsMessageHandler] class DownloaderVideoHandler @@ -18,7 +20,9 @@ class DownloaderVideoHandler public function __construct( private EntityManagerInterface $entityManager, - private KernelInterface $kernel + private KernelInterface $kernel, + private UrlGeneratorInterface $urlGenerator, + private readonly ListmonkMailerService $mailer, ) { $this->path = $this->kernel->getProjectDir() . '/public/downloader/user/'; } @@ -62,5 +66,20 @@ class DownloaderVideoHandler $this->entityManager->persist($userDownloader); $this->entityManager->flush(); + + + $absoluteURL = $this->urlGenerator->generate( + 'app_frontend_download_user', + ['id' => $userDownloader->getId()], + UrlGeneratorInterface::ABSOLUTE_URL + ); + + $this->mailer->send( + [$user->getEmail()], + 7, + ['name'=> $user->getPseudo(), 'video'=> $userDownloader->getName(), 'date'=> $userDownloader->getDateEnd()->format('d/m/Y H:i:s'), 'url'=> $absoluteURL], + 'external', + ['Content-Type' => 'application/json; charset=utf-8'] + ); } } diff --git a/src/Repository/.gitignore b/src/Repository/.gitignore old mode 100644 new mode 100755 diff --git a/src/Repository/AnonymeDownloaderRepository.php b/src/Repository/AnonymeDownloaderRepository.php old mode 100644 new mode 100755 diff --git a/src/Repository/UserDownloaderRepository.php b/src/Repository/UserDownloaderRepository.php old mode 100644 new mode 100755 diff --git a/src/Repository/UserRepository.php b/src/Repository/UserRepository.php old mode 100644 new mode 100755 diff --git a/src/Security/LoginAuthenticator.php b/src/Security/LoginAuthenticator.php old mode 100644 new mode 100755 diff --git a/src/Service/Frontend/DownloadService.php b/src/Service/Frontend/DownloadService.php old mode 100644 new mode 100755 diff --git a/src/Service/Frontend/ListmonkMailerService.php b/src/Service/Frontend/ListmonkMailerService.php new file mode 100644 index 0000000..2bf1beb --- /dev/null +++ b/src/Service/Frontend/ListmonkMailerService.php @@ -0,0 +1,74 @@ +getContainer(); + $this->baseUrl = $container->getParameter('listmonk.base_url'); + $this->api_user = $container->getParameter('listmonk.api_user'); + $this->token = $container->getParameter('listmonk.token'); + } + + /** + * Envoie un email transactionnel via Listmonk. + * @param string $toEmails Adresse du destinataire + * @param int $templateId ID du template dans Listmonk + * @param array $data Variables injectées dans le template ({{ .Tx.Data.name }}) + * @param string $subscriber external + * @param array $headers Headers mail optionnels (Reply-To, etc.) + */ + public function send( + array $toEmails, + int $templateId, + array $data = [], + string $subscriber = 'external', + array $headers = ['Content-Type' => 'application/json; charset=utf-8'] + ): bool { + + + try { + $response = $this->httpClient->request('POST', $this->baseUrl . '/api/tx', [ + 'auth_basic' => [$this->api_user, $this->token], + 'headers' => $headers, + 'json' => [ // équivalent de --data-binary avec JSON + 'subscriber_mode' => $subscriber, + 'subscriber_emails' => $toEmails, + 'template_id' => $templateId, + 'data' => $data, + 'content_type' => 'html', + ], + ]); + if ($response->getStatusCode() === 200) { + return true; + } + + $this->logger->error('Listmonk TX error', [ + 'status' => $response->getStatusCode(), + 'body' => $response->getContent(false), + ]); + + return false; + + } catch (\Throwable $e) { + $this->logger->error('Listmonk exception: ' . $e->getMessage()); + return false; + } + } + + + +} \ No newline at end of file diff --git a/symfony.lock b/symfony.lock old mode 100644 new mode 100755 index dd935c8..c4b6710 --- a/symfony.lock +++ b/symfony.lock @@ -113,6 +113,18 @@ "config/packages/messenger.yaml" ] }, + "symfony/monolog-bundle": { + "version": "4.0", + "recipe": { + "repo": "github.com/symfony/recipes", + "branch": "main", + "version": "3.7", + "ref": "1b9efb10c54cb51c713a9391c9300ff8bceda459" + }, + "files": [ + "config/packages/monolog.yaml" + ] + }, "symfony/property-info": { "version": "7.4", "recipe": { diff --git a/templates/demo/email-telechargement-termine.html b/templates/demo/email-telechargement-termine.html new file mode 100644 index 0000000..96b6741 --- /dev/null +++ b/templates/demo/email-telechargement-termine.html @@ -0,0 +1,325 @@ + + + + + + Votre vidéo est prête – VideoPowerPME + + + +
+ + +
+ +
Téléchargeur de vidéos professionnel
+
+ + +
+ + +
+
+ Téléchargement terminé +
+
+ + +
+ Bonjour, {{ .Tx.Data.name }} 👋 +
+

+ Bonne nouvelle ! Votre vidéo a été téléchargée avec succès et est maintenant prête à être récupérée. +

+ + +
+
Détails du téléchargement
+ +
+
👤
+
+
Utilisateur
+
{{ .Tx.Data.name }}
+
+
+ +
+
🎬
+
+
Vidéo téléchargée
+
{{ .Tx.Data.video }}
+
+
+ +
+
🕐
+
+
Fin du téléchargement
+
{{ .Tx.Data.date }}
+
+
+
+ + +
+ + ⬇️   Télécharger ma vidéo + +

Le lien est valable pendant 24 heures

+
+ +
+ + +
+ ⚠️ Important : Assurez-vous de télécharger votre fichier avant expiration du lien. + Passé ce délai, vous devrez relancer une nouvelle demande. Si vous rencontrez un problème, + contactez notre support à video@powerpme.com. +
+ +
+ + + + +
+ + diff --git a/templates/frontend/history.html.twig b/templates/frontend/history.html.twig old mode 100644 new mode 100755 diff --git a/templates/frontend/index.html.twig b/templates/frontend/index.html.twig old mode 100644 new mode 100755 diff --git a/templates/frontend/login.html.twig b/templates/frontend/login.html.twig old mode 100644 new mode 100755 diff --git a/templates/frontend/register.html.twig b/templates/frontend/register.html.twig old mode 100644 new mode 100755 diff --git a/templates/frontend/test.html.twig b/templates/frontend/test.html.twig old mode 100644 new mode 100755 diff --git a/translations/.gitignore b/translations/.gitignore old mode 100644 new mode 100755 diff --git a/translations/history.ar.yaml b/translations/history.ar.yaml old mode 100644 new mode 100755 diff --git a/translations/history.en.yaml b/translations/history.en.yaml old mode 100644 new mode 100755 diff --git a/translations/history.fr.yaml b/translations/history.fr.yaml old mode 100644 new mode 100755 diff --git a/translations/home.ar.yaml b/translations/home.ar.yaml old mode 100644 new mode 100755 diff --git a/translations/home.en.yaml b/translations/home.en.yaml old mode 100644 new mode 100755 diff --git a/translations/home.fr.yaml b/translations/home.fr.yaml old mode 100644 new mode 100755 diff --git a/translations/sign-in.ar.yaml b/translations/sign-in.ar.yaml old mode 100644 new mode 100755 diff --git a/translations/sign-in.en.yaml b/translations/sign-in.en.yaml old mode 100644 new mode 100755 diff --git a/translations/sign-in.fr.yaml b/translations/sign-in.fr.yaml old mode 100644 new mode 100755 diff --git a/translations/sign-up.ar.yaml b/translations/sign-up.ar.yaml old mode 100644 new mode 100755 diff --git a/translations/sign-up.en.yaml b/translations/sign-up.en.yaml old mode 100644 new mode 100755 diff --git a/translations/sign-up.fr.yaml b/translations/sign-up.fr.yaml old mode 100644 new mode 100755